Skip to content

Commit

Permalink
Support account sort order
Browse files Browse the repository at this point in the history
  • Loading branch information
ystxn committed Nov 30, 2024
1 parent 0133865 commit 0590721
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 10 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ java {
repositories { mavenCentral() }

tasks.withType(JavaCompile).configureEach {
options.compilerArgs.add("-parameters")
options.compilerArgs << "-parameters" // << "-Xlint:unchecked" << "-Werror"
}

def testContainersVersion = "1.20.4"
Expand Down
27 changes: 20 additions & 7 deletions src/main/java/tech/sledger/endpoints/AccountEndpoints.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import tech.sledger.model.account.Account;
Expand All @@ -26,6 +27,7 @@
import tech.sledger.service.CacheService;
import tech.sledger.service.UserService;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
Expand Down Expand Up @@ -82,9 +84,17 @@ public Account addAccount(Authentication auth, @RequestBody NewAccount newAccoun

@PutMapping("/{accountId}")
public Account updateAccount(
Authentication auth, @PathVariable("accountId") long accountId, @RequestBody NewAccount editAccount
Authentication auth,
@PathVariable("accountId") long accountId,
@RequestBody(required = false) NewAccount editAccount,
@RequestParam(required = false) Boolean visible
) {
Account account = userService.authorise(auth, accountId);
if (visible != null) {
account.setVisible(visible);
return accountService.edit(account);
}

AccountIssuer issuer = accountIssuerService.get(editAccount.getIssuerId());
if (issuer == null) {
throw new ResponseStatusException(BAD_REQUEST, "No such issuer");
Expand All @@ -111,12 +121,15 @@ public Account updateAccount(
return accountService.edit(account);
}

@PutMapping("/{accountId}/{visible}")
public Account updateAccountVisibility(Authentication auth, @PathVariable("accountId") long accountId, @PathVariable("visible") boolean visible) {
Account account = accountService.get(accountId);
userService.authorise(auth, account.getId());
account.setVisible(visible);
return accountService.edit(account);
public enum SortDirection { up, down }
@PutMapping("/{accountId}/sort/{direction}")
public Map<Long, Integer> updateAccountSort(
Authentication auth,
@PathVariable("accountId") long accountId,
@PathVariable("direction") SortDirection direction
) {
Account account = userService.authorise(auth, accountId);
return accountService.updateAccountSort(account, direction);
}

@DeleteMapping("/{accountId}")
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/tech/sledger/model/account/Account.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.Id;
Expand All @@ -17,8 +18,10 @@
@NoArgsConstructor
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIgnoreProperties(ignoreUnknown = true)
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Account {
@Id
@EqualsAndHashCode.Include
private long id;
@DBRef
@JsonIdentityReference(alwaysAsId = true)
Expand All @@ -29,4 +32,5 @@ public class Account {
private String name;
@Builder.Default
private boolean visible = true;
private int sortOrder;
}
1 change: 1 addition & 0 deletions src/main/java/tech/sledger/model/dto/AccountDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class AccountDTO {
private long id;
private long issuerId;
private AccountType type;
private int sortOrder;
private String name;
private boolean visible;
private BigDecimal balance;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/tech/sledger/repo/AccountOpsRepoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public List<AccountDTO> getAccountsWithMetrics(long ownerId) {
stage("{ $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ \"$transactionLookup\", 0 ] }, \"$$ROOT\" ] } } }"),
lookup("accountIssuer", "issuer.$id", "_id", "issuerLookup"),
unwind("$issuerLookup"),
sort(ASC, "type", "issuerLookup.name", "name"),
sort(ASC, "type", "sortOrder", "issuerLookup.name", "name"),
stage("{ $addFields: { issuerId: \"$issuerLookup._id\" } }"),
stage("{ $project: { transactionLookup: 0, issuerLookup: 0, owner: 0, issuer: 0 } }")
);
Expand Down
1 change: 1 addition & 0 deletions src/main/java/tech/sledger/repo/AccountRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ public interface AccountRepo extends MongoRepository<Account, Long>, AccountOpsR
Account findFirstByOrderByIdDesc();
List<Account> findAllByIssuer(AccountIssuer issuer);
List<Account> findAllByOwnerAndTypeIn(User user, List<AccountType> type);
List<Account> findAllByOwnerAndTypeOrderBySortOrder(User user, AccountType type);
}
27 changes: 27 additions & 0 deletions src/main/java/tech/sledger/service/AccountService.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
package tech.sledger.service;

import static tech.sledger.endpoints.AccountEndpoints.SortDirection.down;
import static tech.sledger.endpoints.AccountEndpoints.SortDirection.up;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;
import tech.sledger.endpoints.AccountEndpoints;
import tech.sledger.model.account.Account;
import tech.sledger.model.account.CreditAccount;
import tech.sledger.model.dto.AccountDTO;
import tech.sledger.model.user.User;
import tech.sledger.repo.AccountRepo;
import tech.sledger.repo.TransactionRepo;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand All @@ -23,6 +29,7 @@ public Account add(Account account) {
Account previous = accountRepo.findFirstByOrderByIdDesc();
long id = (previous == null) ? 1 : previous.getId() + 1;
account.setId(id);
account.setSortOrder((previous == null) ? 0 : previous.getSortOrder() + 1);

if (account instanceof CreditAccount creditAccount && creditAccount.getPaymentAccountId() > 0) {
Account paymentAccount = get(creditAccount.getPaymentAccountId());
Expand Down Expand Up @@ -50,4 +57,24 @@ public void delete(Account account) {
cache.clearTxCache(account.getId());
accountRepo.delete(account);
}

public Map<Long, Integer> updateAccountSort(Account account, AccountEndpoints.SortDirection direction) {
List<Account> accounts = accountRepo.findAllByOwnerAndTypeOrderBySortOrder(account.getOwner(), account.getType());
int index = accounts.indexOf(account);
if ((direction == up && index == 0) || (direction == down && index == accounts.size() -1)) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid sort instruction");
}
Account affected = accounts.get(direction == up ? index - 1 : index + 1);
int temp = accounts.get(index).getSortOrder();
accounts.get(index).setSortOrder(affected.getSortOrder());
affected.setSortOrder(temp);

accounts.sort(Comparator.comparingInt(Account::getSortOrder));
for (int i = 0; i < accounts.size(); i++) {
accounts.get(i).setSortOrder(i);
}
accountRepo.saveAll(accounts);

return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getSortOrder));
}
}
13 changes: 12 additions & 1 deletion src/test/java/tech/sledger/AccountTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,24 @@ public void addAccounts() throws Exception {
@WithUserDetails("[email protected]")
public void updateAccounts() throws Exception {
for (Map<String, Object> account : newAccounts) {
mvc.perform(put("/api/account/" + account.get("id") + "/false"))
mvc.perform(put("/api/account/" + account.get("id") + "?visible=false"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.visible").value(false));

mvc.perform(request(PUT, "/api/account/" + account.get("id"), account))
.andExpect(status().isOk());
}

mvc.perform(put("/api/account/" + newAccounts.get(0).get("id") + "/sort/down"))
.andExpect(status().isBadRequest());
mvc.perform(put("/api/account/" + newAccounts.get(0).get("id") + "/sort/up"))
.andExpect(status().isOk())
.andExpect(jsonPath("$." + newAccounts.get(0).get("id")).value(0));
mvc.perform(put("/api/account/" + newAccounts.get(0).get("id") + "/sort/up"))
.andExpect(status().isBadRequest());
mvc.perform(put("/api/account/" + newAccounts.get(0).get("id") + "/sort/down"))
.andExpect(status().isOk())
.andExpect(jsonPath("$." + newAccounts.get(0).get("id")).value(1));
}

@Test
Expand Down

0 comments on commit 0590721

Please sign in to comment.