Pairing exercise: Let merchant to notify shipment of an order #31
Pairing exercise: Let merchant to notify shipment of an order #31nikhilJasani wants to merge 4 commits intoozean12:mainfrom
Conversation
| if (shipmentTotal.compareTo(orderAmount.amount) > 0) | ||
| throw ShipmentAmountExceedOrderTotalException(ShipmentAmount(shipmentTotal), orderId!!) |
There was a problem hiding this comment.
Order domain keeps track of the business rule where total amount of all shipments don't exceed order amount.
| */ | ||
| data class OrderAmount(val amount: BigDecimal) { | ||
| init { | ||
| require(amount.compareTo(BigDecimal.ZERO) > 0) { "Order amount must be positive" } |
There was a problem hiding this comment.
Order amount and also shipment amount domain objects ensure that it always receives positive value
| private fun mapToDtos(orders: List<Order>): List<OrderDto> { | ||
| return orders.stream() | ||
| .map(this::mapToDto) | ||
| .collect(Collectors.toList()) | ||
| } | ||
|
|
||
| private fun mapToDto(order: Order): OrderDto { | ||
| return OrderDto(order.orderId!!.id, order.organisationId.id, order.orderAmount.amount) | ||
| } | ||
|
|
||
| private fun mapToDomain(organisationId: UUID, orderRequest: OrderRequest): Order { | ||
| return Order(null, Entity(organisationId), OrderAmount(orderRequest.amount), mutableSetOf()) | ||
| } | ||
|
|
||
| private fun mapToDomain(orderId: UUID, shipmentRequest: ShipmentRequest): Shipment { | ||
| return Shipment(null, OrderId(orderId), ShipmentAmount(shipmentRequest.amount)) | ||
| } |
There was a problem hiding this comment.
I prefer to use separate domain and dto objects which allow control over what internal domain information is exposed outside domain and it also helps to transform or convert some information at times.
| @Service | ||
| class OrderService(val repository: OrderRepository) { | ||
|
|
||
| @Transactional(readOnly = true) |
There was a problem hiding this comment.
Order service which offers method to create, fetch orders and notifying shipment for an order
| @@ -0,0 +1,6 @@ | |||
| CREATE TABLE IF NOT EXISTS organisations_schema.shipments | |||
| ( | |||
| id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, | |||
There was a problem hiding this comment.
Intentionally kept the schema simple - just to demonstrate for exercise requirement. Same is applicable to Order table.
This PR is developed as pairing exercise with the aim to implement following business requirement.
Merchant can let the customers pay with Billie payment method, when it happens merchant is not paid straight away. But merchant needs to inform Billie about shipment the product. One order can have multiple products and hence it is possible order is fulfilled by merchant in different shipments. Merchant is only paid when Billie is notified about the shipment amount.
To ensure merchant is not paid more than order amount, shipment amount is summed up and notification attempt is rejected if it violets this rule.
Technically this PR adds few APIs to let merchant application/admin portal sends order request with total order amount, query all the orders belong to it and finally notifies shipment with shipment amount.