Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Payment Service entities and commands #25

Merged
merged 30 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d1c5de9
Intialize payments service and postgreSQL database
AhmedNasserG Mar 24, 2024
15785c1
Added wallet model entity, repository, service and controller
AhmedNasserG Mar 24, 2024
18a5dfa
Added payment request model entity, repository, service, and controller
AhmedNasserG Mar 24, 2024
56afa98
Merge branch 'main' into payments-add-wallet-model
AhmedNasserG Mar 24, 2024
521d0f7
Added `GetWallet` request and response
AhmedNasserG Mar 4, 2024
5133540
Added walletTransaction model entity, repository, service and controller
Abdullah204 Mar 24, 2024
4edf922
completed wallet withdraw method by adding transaction to wallettrans…
Abdullah204 Mar 24, 2024
7fe047b
Changed transactiontype to enum and removed useless check
Abdullah204 Mar 24, 2024
6dccc85
Merge branch 'main' into payments-add-wallet-model
Abdulaziz-Hassan Apr 19, 2024
4c80838
Add Command pattern setup
Abdulaziz-Hassan Apr 19, 2024
f036054
Add RabbitMQ setup
Abdulaziz-Hassan Apr 19, 2024
ac83e16
Add PaymentRequest commands
Abdulaziz-Hassan Apr 19, 2024
e6eca6d
Add PaymentTransaction commands
Abdulaziz-Hassan Apr 19, 2024
122225d
Add Wallet commands
Abdulaziz-Hassan Apr 19, 2024
cf44528
Add WalletTransaction commands
Abdulaziz-Hassan Apr 19, 2024
cce2483
Delete docker compose and use the main one in the top hierarchy
Abdulaziz-Hassan Apr 19, 2024
9996f9c
Fix WithdrawFromWallet command
Abdulaziz-Hassan Apr 19, 2024
20e99a7
Fix Wallet and WalletTransaction models
Abdulaziz-Hassan Apr 19, 2024
c2f57b1
Fix Custom Queries in PaymentTransaction and WalletTransaction reposi…
Abdulaziz-Hassan Apr 21, 2024
357b53b
Merge branch 'main' into payments-add-wallet-model
Abdulaziz-Hassan Apr 21, 2024
f534fc1
Fix Command Response return arguments to using HTTP status codes
Abdulaziz-Hassan Apr 21, 2024
0e24bc8
Add linting to payments service
AhmedNasserG Apr 21, 2024
94d5697
fix payments pom.xml file
AhmedNasserG Apr 21, 2024
f81fbe0
clean payments code
AhmedNasserG Apr 21, 2024
1eaa72c
fix linting issues
AhmedNasserG Apr 21, 2024
b14162e
fix linting issues
AhmedNasserG Apr 21, 2024
e946744
Update shared/src/main/java/com/workup/shared/commands/payments/dto/P…
Abdulaziz-Hassan Apr 21, 2024
1adeec3
Update shared/src/main/java/com/workup/shared/commands/payments/dto/W…
Abdulaziz-Hassan Apr 21, 2024
c2a3be0
Add some validation to some commands
Abdulaziz-Hassan Apr 21, 2024
a39aa76
Fix linting issues
Abdulaziz-Hassan Apr 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.workup.payments.paymentrequest;

import com.workup.payments.paymentrequest.enums.PaymentRequestStatus;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;

import javax.validation.constraints.DecimalMin;
import java.util.Date;

@Entity
@Data
@NoArgsConstructor
//@EnableJpaAuditing
public class PaymentRequest {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
@Column(name = "id", updatable = false, nullable = false)
private String id;

@Column(name = "freelancer_id", nullable = false)
private String freelancerId;

@Column(name = "client_id", nullable = false)
private String clientId;

@Column(name = "amount", nullable = false, columnDefinition = "decimal default 0.00")
@DecimalMin(value = "0.00", message = "Amount must be greater than 0.00")
private double amount;

@Column(name = "description")
private String description;

@Column(name = "status", nullable = false)
@Enumerated(EnumType.STRING)
private PaymentRequestStatus status = PaymentRequestStatus.PENDING;

@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
private Date createdAt;

@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at", nullable = false)
private Date updatedAt;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.workup.payments.paymentrequest;


import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(path = "api/v1/payments/request")
@AllArgsConstructor
public class PaymentRequestController {
private final PaymentRequestService paymentRequestService;

@GetMapping("/{payment_request_id}")
public PaymentRequest getPaymentRequest(@PathVariable("payment_request_id") String paymentRequestId) {
return paymentRequestService.getPaymentRequest(paymentRequestId);
}

@PostMapping
public void createPaymentRequest(@RequestBody PaymentRequest paymentRequest) {
paymentRequestService.createPaymentRequest(paymentRequest);
}

@GetMapping("/freelancer/{freelancer_id}")
public List<PaymentRequest> findAllPaymentRequestsByFreelancerId(@PathVariable("freelancer_id") String freelancerId) {
return paymentRequestService.findAllPaymentRequestsByFreelancerId(freelancerId);
}

@GetMapping("/client/{client_id}")
public List<PaymentRequest> findAllPaymentRequestsByClientId(@PathVariable("client_id") String clientId) {
return paymentRequestService.findAllPaymentRequestsByClientId(clientId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.workup.payments.paymentrequest;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PaymentRequestRepository extends JpaRepository<PaymentRequest, String> {
List<PaymentRequest> findAllByFreelancerId(String freelancerId);

List<PaymentRequest> findAllByClientId(String clientId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.workup.payments.paymentrequest;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@AllArgsConstructor
public class PaymentRequestService {
private final PaymentRequestRepository paymentRequestRepository;

public PaymentRequest getPaymentRequest(String paymentRequestId) {
return paymentRequestRepository.findById(paymentRequestId).orElse(null);
}

public void createPaymentRequest(PaymentRequest paymentRequest) {
paymentRequestRepository.save(paymentRequest);
}

public List<PaymentRequest> findAllPaymentRequestsByFreelancerId(String freelancerId) {
return paymentRequestRepository.findAllByFreelancerId(freelancerId);
}

public List<PaymentRequest> findAllPaymentRequestsByClientId(String clientId) {
return paymentRequestRepository.findAllByClientId(clientId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.workup.payments.paymentrequest.enums;

public enum PaymentRequestStatus {
PENDING, PAID, CANCELLED
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.workup.payments.wallet;

import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.validation.constraints.DecimalMin;
import java.util.Date;

@Entity
@Data
@NoArgsConstructor
public class Wallet {
@Id
private String freelancerId;

@Column(name = "balance", nullable = false, columnDefinition = "decimal default 0.00")
@DecimalMin(value = "0.00", message = "Balance must be greater than 0.00")
private double balance;

@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at", nullable = false, updatable = false)
private Date createdAt;

@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "updated_at", nullable = false)
private Date updatedAt;

public Wallet(String freelancerId) {
this.freelancerId = freelancerId;
this.balance = 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.workup.payments.wallet;

import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(path = "api/v1/payments/wallet")
@AllArgsConstructor
public class WalletController {
private final WalletService walletService;

@GetMapping("/{freelancer_id}")
public Wallet getWallet(@PathVariable("freelancer_id") String freelancerId) {
return walletService.getWallet(freelancerId);
}

@PostMapping
public void createWallet(@RequestBody Wallet wallet) {
walletService.createWallet(wallet);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.workup.payments.wallet;

import org.springframework.data.jpa.repository.JpaRepository;

public interface WalletRepository extends JpaRepository<Wallet, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.workup.payments.wallet;

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.workup.payments.wallettransaction.WalletTransaction;
@Service
@AllArgsConstructor
public class WalletService {
private final WalletRepository walletRepository;
private final WalletTransactionRepository walletTransactionRepository;

public Wallet getWallet(String freelancerId) {
return walletRepository.findById(freelancerId).orElse(null);
}

public void createWallet(Wallet wallet) {
if (walletRepository.existsById(wallet.getFreelancerId())) {
throw new IllegalStateException("Wallet already exists");
}
walletRepository.save(wallet);
}

@Transactional
public void withdraw(String freelancerId, double amount) {
if (amount <= 0) {
throw new IllegalStateException("Amount must be greater than 0");
}
Wallet wallet = walletRepository.findById(freelancerId)
.orElseThrow(() -> new IllegalStateException("Wallet not found"));
if (wallet.getBalance() < amount) {
throw new IllegalStateException("Insufficient balance");
}
wallet.setBalance(wallet.getBalance() - amount);
walletRepository.save(wallet);

WalletTransaction walletTransaction = new WalletTransaction(freelancerId, amount, null, "Withdraw", "DEBIT");
walletTransactionRepository.save(walletTransaction);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.workup.payments.wallet;

import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.validation.constraints.DecimalMin;
import java.util.Date;

@Entity
@Data
@NoArgsConstructor
public class WalletTransaction {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(
name = "UUID",
strategy = "org.hibernate.id.UUIDGenerator"
)
@Column(name = "id", updatable = false, nullable = false)
private String id;
@Column(name = "wallet_id", nullable = false)
private String walletId;
@Column(name = "amount", nullable = false, columnDefinition = "decimal default 0.00")
@DecimalMin(value = "0.00", message = "Amount must be greater than 0.00")
private double amount;
@Column(name = "payment_transaction_id")
private String paymentTransactionId;
@Column(name = "description")
private String description;
@CreationTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@Column(name = "transaction_type")
private String transactionType;

public WalletTransaction(String walletId, double amount, String paymentTransactionId, String description, String transactionType) {
this.walletId = walletId;
this.amount = amount;
this.paymentTransactionId = paymentTransactionId;
this.description = description;
this.transactionType = transactionType;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.workup.payments.wallettransaction;


import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(path = "api/v1/payments/wallettransaction")
@AllArgsConstructor
public class WalletTransactionController {
private final WalletTransactionService walletTransactionService;

@GetMapping("/{wallet_transaction_id}")
public WalletTransaction getWalletTransaction(@PathVariable("wallet_transaction_id") String walletTransactionId) {
return walletTransactionService.getWalletTransaction(walletTransactionId);
}

@PostMapping
public void createWalletTransaction(@RequestBody WalletTransaction walletTransaction) {
walletTransactionService.createWalletTransaction(walletTransaction);
}

@GetMapping("/{wallet_id}")
public List<WalletTransaction> getWalletTransactions(@PathVariable("wallet_id") String walletId) {
return walletTransactionService.getWalletTransactions(walletId);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.workup.payments.wallettransaction;

import org.springframework.data.jpa.repository.JpaRepository;

public interface WalletTransactionRepository extends JpaRepository<WalletTransaction, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.workup.payments.wallettransaction;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@AllArgsConstructor
public class WalletTransactionService {
private final WalletTransactionRepository walletTransactionRepository;

public WalletTransaction getWalletTransaction(String walletTransactionId) {
return walletTransactionRepository.findById(walletTransactionId).orElse(null);
}


public void createWalletTransaction(WalletTransaction walletTransaction) {
if (walletRepository.existsById(walletTransaction.getFreelancerId())) {
throw new IllegalStateException("Wallet already exists");
}
walletRepository.save(walletTransaction);
}

public void getWalletTransactions(String walletId) {
return walletTransactionRepository.findAllByWalletId(walletId);
}





}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import lombok.Builder;
import lombok.Getter;


@Getter
@Builder(setterPrefix = "with")
@JsonDeserialize(builder = GetWalletResponse.GetWalletResponseBuilder.class)
Expand Down
Loading