From 81ed0260b1d56713088c1c338a2e8f77aea270b5 Mon Sep 17 00:00:00 2001 From: viktorpavlenko Date: Tue, 11 Feb 2025 18:08:55 +0200 Subject: [PATCH] FINERACT-2169: Refactor api to concrete types and add validation; --- .../teller/api/TellerApiResource.java | 196 ++++++------------ .../domain/model/CashiersForTeller.java | 28 +++ .../domain/model/request/CashierRequest.java | 44 ++++ .../request/CashierTransactionRequest.java | 40 ++++ .../domain/model/request/TellerRequest.java | 41 ++++ .../TellerCommandFromApiJsonDeserializer.java | 5 +- ...llerManagementReadPlatformServiceImpl.java | 6 + .../OrganisationTellerConfiguration.java | 6 +- 8 files changed, 231 insertions(+), 135 deletions(-) create mode 100644 fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/CashiersForTeller.java create mode 100644 fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierRequest.java create mode 100644 fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierTransactionRequest.java create mode 100644 fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/TellerRequest.java diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java index f91020457..d6e83baaf 100644 --- a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/api/TellerApiResource.java @@ -49,14 +49,16 @@ import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSer import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.Page; import org.apache.fineract.infrastructure.core.service.SearchParameters; -import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; -import org.apache.fineract.infrastructure.security.service.SqlValidator; import org.apache.fineract.organisation.teller.data.CashierData; import org.apache.fineract.organisation.teller.data.CashierTransactionData; import org.apache.fineract.organisation.teller.data.CashierTransactionsWithSummaryData; import org.apache.fineract.organisation.teller.data.TellerData; import org.apache.fineract.organisation.teller.data.TellerJournalData; import org.apache.fineract.organisation.teller.data.TellerTransactionData; +import org.apache.fineract.organisation.teller.domain.model.CashiersForTeller; +import org.apache.fineract.organisation.teller.domain.model.request.CashierRequest; +import org.apache.fineract.organisation.teller.domain.model.request.CashierTransactionRequest; +import org.apache.fineract.organisation.teller.domain.model.request.TellerRequest; import org.apache.fineract.organisation.teller.service.TellerManagementReadPlatformService; import org.apache.fineract.organisation.teller.util.DateRange; import org.springframework.stereotype.Component; @@ -67,11 +69,9 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class TellerApiResource { - private final PlatformSecurityContext securityContext; - private final DefaultToApiJsonSerializer jsonSerializer; private final TellerManagementReadPlatformService readPlatformService; private final PortfolioCommandSourceWritePlatformService commandWritePlatformService; - private final SqlValidator sqlValidator; + private final DefaultToApiJsonSerializer apiJsonSerializer; @GET @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @@ -79,10 +79,8 @@ public class TellerApiResource { @Operation(summary = "List all tellers", description = "Retrieves list tellers") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(array = @ArraySchema(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersResponse.class)))) }) - public String getTellerData(@QueryParam("officeId") @Parameter(description = "officeId") final Long officeId) { - final Collection foundTellers = this.readPlatformService.getTellers(officeId); - - return this.jsonSerializer.serialize(foundTellers); + public Collection getTellerData(@QueryParam("officeId") @Parameter(description = "officeId") final Long officeId) { + return readPlatformService.getTellers(officeId); } @GET @@ -92,10 +90,8 @@ public class TellerApiResource { @Operation(summary = "Retrieve tellers", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersResponse.class))) }) - public String findTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { - final TellerData teller = this.readPlatformService.findTeller(tellerId); - - return this.jsonSerializer.serialize(teller); + public TellerData findTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { + return readPlatformService.findTeller(tellerId); } @POST @@ -106,12 +102,10 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersResponse.class))) }) - public String createTeller(@Parameter(hidden = true) final String tellerData) { - final CommandWrapper request = new CommandWrapperBuilder().createTeller().withJson(tellerData).build(); + public CommandProcessingResult createTeller(@Parameter(hidden = true) TellerRequest tellerData) { + final CommandWrapper request = new CommandWrapperBuilder().createTeller().withJson(apiJsonSerializer.serialize(tellerData)).build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + return this.commandWritePlatformService.logCommandSource(request); } @PUT @@ -122,25 +116,21 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PutTellersRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PutTellersResponse.class))) }) - public String updateTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, - @Parameter(hidden = true) final String tellerData) { - final CommandWrapper request = new CommandWrapperBuilder().updateTeller(tellerId).withJson(tellerData).build(); + public CommandProcessingResult updateTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + @Parameter(hidden = true) TellerRequest tellerData) { + final CommandWrapper request = new CommandWrapperBuilder().updateTeller(tellerId).withJson(apiJsonSerializer.serialize(tellerData)) + .build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + return this.commandWritePlatformService.logCommandSource(request); } @DELETE @Path("{tellerId}") @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Produces(MediaType.APPLICATION_JSON) - public String deleteTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { + public CommandProcessingResult deleteTeller(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { final CommandWrapper request = new CommandWrapperBuilder().deleteTeller(tellerId).build(); - - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + return this.commandWritePlatformService.logCommandSource(request); } @GET @@ -150,7 +140,7 @@ public class TellerApiResource { @Operation(summary = "List Cashiers", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersResponse.class))) }) - public String getCashierData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CashiersForTeller getCashierData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @QueryParam("fromdate") @Parameter(description = "fromdate") final String fromDateStr, @QueryParam("todate") @Parameter(description = "todate") final String toDateStr) { final DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; @@ -161,14 +151,7 @@ public class TellerApiResource { final TellerData teller = this.readPlatformService.findTeller(tellerId); final Collection cashiers = this.readPlatformService.getCashiersForTeller(tellerId, fromDate, toDate); - CashiersForTeller cashiersForTeller = new CashiersForTeller(); - cashiersForTeller.cashiers = cashiers; - cashiersForTeller.tellerId = tellerId; - cashiersForTeller.tellerName = teller.getName(); - cashiersForTeller.officeId = teller.getOfficeId(); - cashiersForTeller.officeName = teller.getOfficeName(); - - return this.jsonSerializer.serialize(cashiersForTeller); + return new CashiersForTeller(tellerId, teller.getName(), teller.getOfficeId(), teller.getOfficeName(), cashiers); } @GET @@ -178,11 +161,9 @@ public class TellerApiResource { @Operation(summary = "Retrieve a cashier", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersCashierIdResponse.class))) }) - public String findCashierData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CashierData findCashierData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId) { - final CashierData cashier = this.readPlatformService.findCashier(cashierId); - - return this.jsonSerializer.serialize(cashier); + return readPlatformService.findCashier(cashierId); } @GET @@ -192,14 +173,12 @@ public class TellerApiResource { @Operation(summary = "Find Cashiers", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersTemplateResponse.class))) }) - public String getCashierTemplate(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { + public CashierData getCashierTemplate(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId) { final TellerData teller = this.readPlatformService.findTeller(tellerId); Long officeId = teller.getOfficeId(); - final CashierData cashier = this.readPlatformService.retrieveCashierTemplate(officeId, tellerId, true); - - return this.jsonSerializer.serialize(cashier); + return this.readPlatformService.retrieveCashierTemplate(officeId, tellerId, true); } @POST @@ -212,13 +191,12 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersResponse.class))) }) - public String createCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, - @Parameter(hidden = true) final String cashierData) { - final CommandWrapper request = new CommandWrapperBuilder().allocateTeller(tellerId).withJson(cashierData).build(); + public CommandProcessingResult createCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + @Parameter(hidden = true) final CashierRequest cashierData) { + final CommandWrapper request = new CommandWrapperBuilder().allocateTeller(tellerId) + .withJson(apiJsonSerializer.serialize(cashierData)).build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + return this.commandWritePlatformService.logCommandSource(request); } @PUT @@ -229,15 +207,14 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PutTellersTellerIdCashiersCashierIdRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PutTellersTellerIdCashiersCashierIdResponse.class))) }) - public String updateCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CommandProcessingResult updateCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId, - @Parameter(hidden = true) final String cashierDate) { - final CommandWrapper request = new CommandWrapperBuilder().updateAllocationTeller(tellerId, cashierId).withJson(cashierDate) - .build(); + @Parameter(hidden = true) final CashierRequest cashierDate) { + final CommandWrapper request = new CommandWrapperBuilder().updateAllocationTeller(tellerId, cashierId) + .withJson(apiJsonSerializer.serialize(cashierDate)).build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); + return this.commandWritePlatformService.logCommandSource(request); - return this.jsonSerializer.serialize(result); } @DELETE @@ -247,13 +224,12 @@ public class TellerApiResource { @Operation(summary = "Delete Cashier", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.DeleteTellersTellerIdCashiersCashierIdResponse.class))) }) - public String deleteCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CommandProcessingResult deleteCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId) { final CommandWrapper request = new CommandWrapperBuilder().deleteAllocationTeller(tellerId, cashierId).build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); + return this.commandWritePlatformService.logCommandSource(request); - return this.jsonSerializer.serialize(result); } @POST @@ -264,15 +240,13 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersCashierIdAllocateRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersCashierIdAllocateResponse.class))) }) - public String allocateCashToCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CommandProcessingResult allocateCashToCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId, - @Parameter(hidden = true) final String cashierTxnData) { - final CommandWrapper request = new CommandWrapperBuilder().allocateCashToCashier(tellerId, cashierId).withJson(cashierTxnData) - .build(); + @Parameter(hidden = true) CashierTransactionRequest cashierTxnData) { + final CommandWrapper request = new CommandWrapperBuilder().allocateCashToCashier(tellerId, cashierId) + .withJson(apiJsonSerializer.serialize(cashierTxnData)).build(); - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + return this.commandWritePlatformService.logCommandSource(request); } @@ -284,16 +258,13 @@ public class TellerApiResource { @RequestBody(required = true, content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersCashierIdSettleRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.PostTellersTellerIdCashiersCashierIdSettleResponse.class))) }) - public String settleCashFromCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CommandProcessingResult settleCashFromCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId, - @Parameter(hidden = true) final String cashierTxnData) { - final CommandWrapper request = new CommandWrapperBuilder().settleCashFromCashier(tellerId, cashierId).withJson(cashierTxnData) - .build(); - - final CommandProcessingResult result = this.commandWritePlatformService.logCommandSource(request); - - return this.jsonSerializer.serialize(result); + @Parameter(hidden = true) CashierTransactionRequest cashierTxnData) { + final CommandWrapper request = new CommandWrapperBuilder().settleCashFromCashier(tellerId, cashierId) + .withJson(apiJsonSerializer.serialize(cashierTxnData)).build(); + return this.commandWritePlatformService.logCommandSource(request); } @GET @@ -303,28 +274,18 @@ public class TellerApiResource { @Operation(summary = "Retrieve Cashier Transactions", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersCashiersIdTransactionsResponse.class))) }) - public String getTransactionsForCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public Page getTransactionsForCashier( + @PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId, @QueryParam("currencyCode") @Parameter(description = "currencyCode") final String currencyCode, @QueryParam("offset") @Parameter(description = "offset") final Integer offset, @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy, @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) { - // TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in - // the functions - this.readPlatformService.findTeller(tellerId); - this.readPlatformService.findCashier(cashierId); - final LocalDate fromDate = null; - final LocalDate toDate = null; - sqlValidator.validate(orderBy); - sqlValidator.validate(sortOrder); final SearchParameters searchParameters = SearchParameters.builder().limit(limit).offset(offset).orderBy(orderBy) .sortOrder(sortOrder).build(); - final Page cashierTxns = this.readPlatformService.retrieveCashierTransactions(cashierId, false, fromDate, - toDate, currencyCode, searchParameters); - - return this.jsonSerializer.serialize(cashierTxns); + return this.readPlatformService.retrieveCashierTransactions(cashierId, false, null, null, currencyCode, searchParameters); } @GET @@ -334,30 +295,20 @@ public class TellerApiResource { @Operation(summary = "Retrieve Transactions With Summary For Cashier", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersCashiersIdSummaryAndTransactionsResponse.class))) }) - public String getTransactionsWithSummaryForCashier(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CashierTransactionsWithSummaryData getTransactionsWithSummaryForCashier( + @PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId, @QueryParam("currencyCode") @Parameter(description = "currencyCode") final String currencyCode, @QueryParam("offset") @Parameter(description = "offset") final Integer offset, @QueryParam("limit") @Parameter(description = "limit") final Integer limit, @QueryParam("orderBy") @Parameter(description = "orderBy") final String orderBy, @QueryParam("sortOrder") @Parameter(description = "sortOrder") final String sortOrder) { - // TODO: can we remove these 2 calls? we don't use the results, but left it here in case something is done in - // the functions - this.readPlatformService.findTeller(tellerId); - this.readPlatformService.findCashier(cashierId); - final LocalDate fromDate = null; - final LocalDate toDate = null; - - sqlValidator.validate(orderBy); - sqlValidator.validate(sortOrder); final SearchParameters searchParameters = SearchParameters.builder().limit(limit).offset(offset).orderBy(orderBy) .sortOrder(sortOrder).build(); - final CashierTransactionsWithSummaryData cashierTxnWithSummary = this.readPlatformService - .retrieveCashierTransactionsWithSummary(cashierId, false, fromDate, toDate, currencyCode, searchParameters); - - return this.jsonSerializer.serialize(cashierTxnWithSummary); + return this.readPlatformService.retrieveCashierTransactionsWithSummary(cashierId, false, null, null, currencyCode, + searchParameters); } @GET @@ -367,61 +318,44 @@ public class TellerApiResource { @Operation(summary = "Retrieve Cashier Transaction Template", description = "") @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = TellerApiResourceSwagger.GetTellersTellerIdCashiersCashiersIdTransactionsTemplateResponse.class))) }) - public String getCashierTxnTemplate(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public CashierTransactionData getCashierTxnTemplate(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @PathParam("cashierId") @Parameter(description = "cashierId") final Long cashierId) { - final CashierTransactionData cashierTxnTemplate = this.readPlatformService.retrieveCashierTxnTemplate(cashierId); - - return this.jsonSerializer.serialize(cashierTxnTemplate); + return this.readPlatformService.retrieveCashierTxnTemplate(cashierId); } @GET @Path("{tellerId}/transactions") @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Produces(MediaType.APPLICATION_JSON) - public String getTransactionData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public Collection getTransactionData( + @PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @QueryParam("dateRange") @Parameter(description = "dateRange") final String dateRange) { final DateRange dateRangeHolder = DateRange.fromString(dateRange); - final Collection transactions = this.readPlatformService.fetchTellerTransactionsByTellerId(tellerId, - dateRangeHolder.getStartDate(), dateRangeHolder.getEndDate()); - - return this.jsonSerializer.serialize(transactions); + return this.readPlatformService.fetchTellerTransactionsByTellerId(tellerId, dateRangeHolder.getStartDate(), + dateRangeHolder.getEndDate()); } @GET @Path("{tellerId}/transactions/{transactionId}") @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Produces(MediaType.APPLICATION_JSON) - public String findTransactionData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerid, + public TellerTransactionData findTransactionData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerid, @PathParam("transactionId") @Parameter(description = "transactionId") final Long transactionId) { - final TellerTransactionData transaction = this.readPlatformService.findTellerTransaction(transactionId); - - return this.jsonSerializer.serialize(transaction); + return this.readPlatformService.findTellerTransaction(transactionId); } @GET @Path("{tellerId}/journals") @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Produces(MediaType.APPLICATION_JSON) - public String getJournalData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, + public Collection getJournalData(@PathParam("tellerId") @Parameter(description = "tellerId") final Long tellerId, @QueryParam("cashierId") @Parameter(description = "cashierId") final Long cashierDate, @QueryParam("dateRange") @Parameter(description = "dateRange") final String dateRange) { final DateRange dateRangeHolder = DateRange.fromString(dateRange); - final Collection journals = this.readPlatformService.fetchTellerJournals(tellerId, cashierDate, - dateRangeHolder.getStartDate(), dateRangeHolder.getEndDate()); - - return this.jsonSerializer.serialize(journals); - } - - private static final class CashiersForTeller { - - public Long tellerId; - public String tellerName; - public Long officeId; - public String officeName; - public Collection cashiers; - + return this.readPlatformService.fetchTellerJournals(tellerId, cashierDate, dateRangeHolder.getStartDate(), + dateRangeHolder.getEndDate()); } } diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/CashiersForTeller.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/CashiersForTeller.java new file mode 100644 index 000000000..bc855cb4d --- /dev/null +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/CashiersForTeller.java @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fineract.organisation.teller.domain.model; + +import java.io.Serializable; +import java.util.Collection; +import org.apache.fineract.organisation.teller.data.CashierData; + +public record CashiersForTeller(Long tellerId, String tellerName, Long officeId, String officeName, + Collection cashiers) implements Serializable { +} diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierRequest.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierRequest.java new file mode 100644 index 000000000..a7eedd218 --- /dev/null +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierRequest.java @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.organisation.teller.domain.model.request; + +import java.io.Serial; +import java.io.Serializable; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class CashierRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private String description; + private Boolean isFullDay; + private Long staffId; + private String dateFormat; + private String startDate; + private String endDate; + private String locale; + private String hourStartTime; + private String minStartTime; + private String hourEndTime; + private String minEndTime; +} diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierTransactionRequest.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierTransactionRequest.java new file mode 100644 index 000000000..bb2309bf5 --- /dev/null +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/CashierTransactionRequest.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.organisation.teller.domain.model.request; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class CashierTransactionRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + public String currencyCode; + public BigDecimal txnAmount; + public String txnNote; + public String locale; + public String dateFormat; + public String txnDate; +} diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/TellerRequest.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/TellerRequest.java new file mode 100644 index 000000000..fae097766 --- /dev/null +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/domain/model/request/TellerRequest.java @@ -0,0 +1,41 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.organisation.teller.domain.model.request; + +import java.io.Serial; +import java.io.Serializable; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class TellerRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private Integer officeId; + private String name; + private String description; + private String startDate; + private String endDate; + private Integer status; + private String dateFormat; + private String locale; +} diff --git a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/serialization/TellerCommandFromApiJsonDeserializer.java b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/serialization/TellerCommandFromApiJsonDeserializer.java index bf045239f..5123699c1 100644 --- a/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/serialization/TellerCommandFromApiJsonDeserializer.java +++ b/fineract-branch/src/main/java/org/apache/fineract/organisation/teller/serialization/TellerCommandFromApiJsonDeserializer.java @@ -68,6 +68,7 @@ public final class TellerCommandFromApiJsonDeserializer { public static final String TXN_DATE = "txnDate"; public static final String TXN_NOTE = "txnNote"; public static final String TELLER = "teller"; + private static final String START_TIME = "startTime"; /** * The parameters supported for this command. */ @@ -159,9 +160,9 @@ public final class TellerCommandFromApiJsonDeserializer { if (!isFullDay) { final String hourStartTime = this.fromApiJsonHelper.extractStringNamed(HOUR_START_TIME, element); - baseDataValidator.reset().parameter("startTime").value(hourStartTime).notBlank(); + baseDataValidator.reset().parameter(START_TIME).value(hourStartTime).notBlank(); final String minStartTime = this.fromApiJsonHelper.extractStringNamed(MIN_START_TIME, element); - baseDataValidator.reset().parameter("startTime").value(minStartTime).notBlank(); + baseDataValidator.reset().parameter(START_TIME).value(minStartTime).notBlank(); final String hourEndTime = this.fromApiJsonHelper.extractStringNamed(HOUR_END_TIME, element); baseDataValidator.reset().parameter(HOUR_END_TIME).value(hourEndTime).notBlank(); final String minEndTime = this.fromApiJsonHelper.extractStringNamed(MIN_END_TIME, element); diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java index f0fb0ff28..c21b751e8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java @@ -34,6 +34,7 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper; import org.apache.fineract.infrastructure.core.service.SearchParameters; import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.infrastructure.security.service.SqlValidator; import org.apache.fineract.infrastructure.security.utils.ColumnValidator; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService; @@ -70,6 +71,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement private final DatabaseSpecificSQLGenerator sqlGenerator; private final PaginationHelper paginationHelper; private final ColumnValidator columnValidator; + private final SqlValidator sqlValidator; private static final class TellerMapper implements RowMapper { @@ -399,6 +401,8 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement public CashierTransactionsWithSummaryData retrieveCashierTransactionsWithSummary(final Long cashierId, final boolean includeAllTellers, final LocalDate fromDate, final LocalDate toDate, final String currencyCode, final SearchParameters searchParameters) { + sqlValidator.validate(searchParameters.getOrderBy()); + sqlValidator.validate(searchParameters.getSortOrder()); final String nextDay = sqlGenerator.incrementDateByOneDay("c.end_date"); final CashierTransactionSummaryMapper ctsm = new CashierTransactionSummaryMapper(); @@ -442,6 +446,8 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement public Page retrieveCashierTransactions(final Long cashierId, final boolean includeAllTellers, final LocalDate fromDate, final LocalDate toDate, final String currencyCode, final SearchParameters searchParameters) { + sqlValidator.validate(searchParameters.getOrderBy()); + sqlValidator.validate(searchParameters.getSortOrder()); final String nextDay = sqlGenerator.incrementDateByOneDay("c.end_date"); final CashierTransactionMapper ctm = new CashierTransactionMapper(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/starter/OrganisationTellerConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/starter/OrganisationTellerConfiguration.java index fab742fdb..5fa3ee675 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/starter/OrganisationTellerConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/starter/OrganisationTellerConfiguration.java @@ -23,6 +23,7 @@ import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository import org.apache.fineract.infrastructure.core.service.PaginationHelper; import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; +import org.apache.fineract.infrastructure.security.service.SqlValidator; import org.apache.fineract.infrastructure.security.utils.ColumnValidator; import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService; import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper; @@ -51,9 +52,10 @@ public class OrganisationTellerConfiguration { public TellerManagementReadPlatformService tellerManagementReadPlatformService(JdbcTemplate jdbcTemplate, PlatformSecurityContext context, OfficeReadPlatformService officeReadPlatformService, StaffReadPlatformService staffReadPlatformService, CurrencyReadPlatformService currencyReadPlatformService, - DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper, ColumnValidator columnValidator) { + DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper, ColumnValidator columnValidator, + SqlValidator sqlValidator) { return new TellerManagementReadPlatformServiceImpl(jdbcTemplate, context, officeReadPlatformService, staffReadPlatformService, - currencyReadPlatformService, sqlGenerator, paginationHelper, columnValidator); + currencyReadPlatformService, sqlGenerator, paginationHelper, columnValidator, sqlValidator); } @Bean