Add void print
This commit is contained in:
@@ -0,0 +1,463 @@
|
||||
# Advanced Order Management API Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The Advanced Order Management API provides comprehensive functionality for managing orders beyond basic operations. This includes partial refunds, void operations, and bill splitting capabilities.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Partial Refund**: Refund specific items from paid orders
|
||||
- ✅ **Void Order**: Cancel ongoing orders (per item or entire order)
|
||||
- ✅ **Split Bill**: Split orders by items or amounts
|
||||
- ✅ **Order Status Management**: Support for PARTIAL and VOIDED statuses
|
||||
- ✅ **Transaction Tracking**: Complete audit trail for all operations
|
||||
- ✅ **Validation**: Comprehensive validation for all operations
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Partial Refund
|
||||
|
||||
**POST** `/order/partial-refund`
|
||||
|
||||
Refund specific items from a paid order while keeping the remaining items.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"reason": "Customer returned damaged items",
|
||||
"items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"quantity": 2
|
||||
},
|
||||
{
|
||||
"order_item_id": 789,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|--------------------------------|
|
||||
| order_id | int64 | Yes | ID of the order to refund |
|
||||
| reason | string | Yes | Reason for the partial refund |
|
||||
| items | array | Yes | Array of items to refund |
|
||||
|
||||
#### Item Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|---------------|--------|----------|--------------------------------|
|
||||
| order_item_id | int64 | Yes | ID of the order item to refund |
|
||||
| quantity | int | Yes | Quantity to refund (min: 1) |
|
||||
|
||||
#### Response
|
||||
|
||||
**Success (200 OK)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"status": 200,
|
||||
"data": {
|
||||
"order_id": 123,
|
||||
"status": "PARTIAL",
|
||||
"refunded_amount": 75000,
|
||||
"remaining_amount": 25000,
|
||||
"reason": "Customer returned damaged items",
|
||||
"refunded_at": "2024-01-15T10:30:00Z",
|
||||
"customer_name": "John Doe",
|
||||
"payment_type": "CASH",
|
||||
"refunded_items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"item_name": "Bakso Special",
|
||||
"quantity": 2,
|
||||
"unit_price": 25000,
|
||||
"total_price": 50000
|
||||
},
|
||||
{
|
||||
"order_item_id": 789,
|
||||
"item_name": "Es Teh Manis",
|
||||
"quantity": 1,
|
||||
"unit_price": 25000,
|
||||
"total_price": 25000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Void Order
|
||||
|
||||
**POST** `/order/void`
|
||||
|
||||
Void an ongoing order (NEW or PENDING status) either entirely or by specific items.
|
||||
|
||||
#### Request Body
|
||||
|
||||
**Void Entire Order:**
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"reason": "Customer cancelled order",
|
||||
"type": "ALL"
|
||||
}
|
||||
```
|
||||
|
||||
**Void Specific Items:**
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"reason": "Customer changed mind about some items",
|
||||
"type": "ITEM",
|
||||
"items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|--------------------------------|
|
||||
| order_id | int64 | Yes | ID of the order to void |
|
||||
| reason | string | Yes | Reason for voiding |
|
||||
| type | string | Yes | Type: "ALL" or "ITEM" |
|
||||
| items | array | No | Required if type is "ITEM" |
|
||||
|
||||
#### Response
|
||||
|
||||
**Success (200 OK)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"status": 200,
|
||||
"data": {
|
||||
"order_id": 123,
|
||||
"status": "VOIDED",
|
||||
"reason": "Customer cancelled order",
|
||||
"voided_at": "2024-01-15T10:30:00Z",
|
||||
"customer_name": "John Doe",
|
||||
"voided_items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"item_name": "Bakso Special",
|
||||
"quantity": 1,
|
||||
"unit_price": 25000,
|
||||
"total_price": 25000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Split Bill
|
||||
|
||||
**POST** `/order/split-bill`
|
||||
|
||||
Split an order into a separate order by items or amounts.
|
||||
|
||||
#### Request Body
|
||||
|
||||
**Split by Items:**
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"type": "ITEM",
|
||||
"payment_method": "CASH",
|
||||
"payment_provider": "CASH",
|
||||
"items": [
|
||||
{
|
||||
"order_item_id": 789,
|
||||
"quantity": 2
|
||||
},
|
||||
{
|
||||
"order_item_id": 101,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Split by Amount:**
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"type": "AMOUNT",
|
||||
"payment_method": "CASH",
|
||||
"payment_provider": "CASH",
|
||||
"amount": 50000
|
||||
}
|
||||
```
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|------------------|--------|----------|--------------------------------|
|
||||
| order_id | int64 | Yes | ID of the order to split |
|
||||
| type | string | Yes | Type: "ITEM" or "AMOUNT" |
|
||||
| payment_method | string | Yes | Payment method for split order |
|
||||
| payment_provider | string | No | Payment provider for split order|
|
||||
| items | array | No | Required if type is "ITEM" |
|
||||
| amount | float | No | Required if type is "AMOUNT" (must be less than order total) |
|
||||
|
||||
#### Item Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|---------------|--------|----------|--------------------------------|
|
||||
| order_item_id | int64 | Yes | ID of the order item to split |
|
||||
| quantity | int | Yes | Quantity to split (min: 1) |
|
||||
|
||||
#### Response
|
||||
|
||||
**Success (200 OK)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"status": 200,
|
||||
"data": {
|
||||
"id": 124,
|
||||
"partner_id": 1,
|
||||
"status": "PAID",
|
||||
"amount": 100000,
|
||||
"total": 110000,
|
||||
"tax": 10000,
|
||||
"customer_id": 456,
|
||||
"customer_name": "John Doe",
|
||||
"payment_type": "CASH",
|
||||
"payment_provider": "CASH",
|
||||
"source": "POS",
|
||||
"created_at": "2024-01-15T10:30:00Z",
|
||||
"updated_at": "2024-01-15T10:30:00Z",
|
||||
"order_items": [
|
||||
{
|
||||
"id": 789,
|
||||
"item_id": 1,
|
||||
"item_name": "Bakso Special",
|
||||
"price": 50000,
|
||||
"quantity": 2,
|
||||
"subtotal": 100000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Business Logic
|
||||
|
||||
### Partial Refund Process
|
||||
|
||||
1. **Validation**
|
||||
- Verify order exists and belongs to partner
|
||||
- Ensure order status is "PAID"
|
||||
- Validate refund items exist and quantities are valid
|
||||
|
||||
2. **Item Updates**
|
||||
- Reduce quantities of refunded items
|
||||
- Remove items completely if quantity becomes 0
|
||||
- Recalculate order totals
|
||||
|
||||
3. **Order Status Update**
|
||||
- Set status to "PARTIAL" if items remain
|
||||
- Set status to "REFUNDED" if all items refunded
|
||||
|
||||
4. **Transaction Creation**
|
||||
- Create refund transaction with negative amount
|
||||
- Track refund details
|
||||
|
||||
### Void Order Process
|
||||
|
||||
1. **Validation**
|
||||
- Verify order exists and belongs to partner
|
||||
- Ensure order status is "NEW" or "PENDING"
|
||||
- Validate void items if type is "ITEM"
|
||||
|
||||
2. **Void Operations**
|
||||
- **ALL**: Set order status to "VOIDED"
|
||||
- **ITEM**: Reduce quantities and recalculate totals
|
||||
|
||||
3. **Status Management**
|
||||
- Set status to "PARTIAL" if items remain
|
||||
- Set status to "VOIDED" if all items voided
|
||||
|
||||
### Split Bill Process
|
||||
|
||||
1. **Validation**
|
||||
- Verify order exists and belongs to partner
|
||||
- Ensure order status is "NEW" or "PENDING"
|
||||
- Validate split configuration
|
||||
|
||||
2. **Split Operations**
|
||||
- **ITEM**: Create new PAID order with specified items, reduce quantities in original order
|
||||
- **AMOUNT**: Create new PAID order with specified amount, reduce amount in original order
|
||||
|
||||
3. **Order Management**
|
||||
- Original order remains PENDING with reduced items/amount
|
||||
- New split order becomes PAID with specified payment method
|
||||
- Recalculate totals for both orders
|
||||
|
||||
## Order Status Flow
|
||||
|
||||
```
|
||||
NEW → PENDING → PAID → REFUNDED
|
||||
↓ ↓ ↓
|
||||
VOIDED VOIDED PARTIAL
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Common Error Responses
|
||||
|
||||
**Order Not Found (404)**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": 404,
|
||||
"message": "order not found"
|
||||
}
|
||||
```
|
||||
|
||||
**Invalid Order Status (400)**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": 400,
|
||||
"message": "only paid order can be partially refunded"
|
||||
}
|
||||
```
|
||||
|
||||
**Invalid Quantity (400)**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": 400,
|
||||
"message": "refund quantity 3 exceeds available quantity 2 for item 456"
|
||||
}
|
||||
```
|
||||
|
||||
**Split Amount Mismatch (400)**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": 400,
|
||||
"message": "split amount 95000 must be less than order total 100000"
|
||||
}
|
||||
```
|
||||
|
||||
## Database Schema Updates
|
||||
|
||||
### Orders Table
|
||||
|
||||
```sql
|
||||
-- New statuses supported
|
||||
ALTER TABLE orders ADD CONSTRAINT check_status
|
||||
CHECK (status IN ('NEW', 'PENDING', 'PAID', 'REFUNDED', 'VOIDED', 'PARTIAL'));
|
||||
```
|
||||
|
||||
### Order Items Table
|
||||
|
||||
```sql
|
||||
-- Support for quantity updates
|
||||
ALTER TABLE order_items ADD COLUMN updated_at TIMESTAMP DEFAULT NOW();
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
### Order Status
|
||||
|
||||
```go
|
||||
const (
|
||||
New OrderStatus = "NEW"
|
||||
Paid OrderStatus = "PAID"
|
||||
Cancel OrderStatus = "CANCEL"
|
||||
Pending OrderStatus = "PENDING"
|
||||
Refunded OrderStatus = "REFUNDED"
|
||||
Voided OrderStatus = "VOIDED" // New
|
||||
Partial OrderStatus = "PARTIAL" // New
|
||||
)
|
||||
```
|
||||
|
||||
## Testing Examples
|
||||
|
||||
### cURL Examples
|
||||
|
||||
**Partial Refund:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/order/partial-refund \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"reason": "Customer returned damaged items",
|
||||
"items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"quantity": 2
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
**Void Order:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/order/void \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"reason": "Customer cancelled order",
|
||||
"type": "ALL"
|
||||
}'
|
||||
```
|
||||
|
||||
**Split Bill:**
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/order/split-bill \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"type": "ITEM",
|
||||
"payment_method": "CASH",
|
||||
"payment_provider": "CASH",
|
||||
"items": [
|
||||
{
|
||||
"order_item_id": 456,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"order_item_id": 789,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Authorization**: Only authorized users can perform these operations
|
||||
2. **Audit Trail**: All operations are logged with user and timestamp
|
||||
3. **Validation**: Strict validation prevents invalid operations
|
||||
4. **Data Integrity**: Transaction-based operations ensure consistency
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Bulk Operations**: Support for bulk partial refunds/voids
|
||||
2. **Approval Workflow**: Multi-level approval for large operations
|
||||
3. **Notification System**: Customer notifications for refunds/voids
|
||||
4. **Analytics**: Dashboard for operation trends and analysis
|
||||
5. **Integration**: Integration with inventory management systems
|
||||
|
||||
## Support
|
||||
|
||||
For questions or issues with the Advanced Order Management API, please contact the development team or create an issue in the project repository.
|
||||
@@ -0,0 +1,297 @@
|
||||
# Advanced Order Management Implementation Summary
|
||||
|
||||
## Overview
|
||||
|
||||
This document summarizes the complete implementation of advanced order management features for the Enaklo POS backend system. The implementation includes three major features: **Partial Refund**, **Void Order**, and **Split Bill** functionality.
|
||||
|
||||
## 🎯 Implemented Features
|
||||
|
||||
### 1. Partial Refund System
|
||||
**Purpose**: Allow refunding specific items from paid orders while keeping remaining items.
|
||||
|
||||
**Key Components**:
|
||||
- ✅ **API Endpoint**: `POST /order/partial-refund`
|
||||
- ✅ **Service Method**: `PartialRefundRequest()`
|
||||
- ✅ **Repository Methods**: `UpdateOrderItem()`, `UpdateOrderTotals()`
|
||||
- ✅ **Validation**: Order status, item existence, quantity validation
|
||||
- ✅ **Transaction Tracking**: Creates refund transactions with negative amounts
|
||||
- ✅ **Status Management**: Updates order to "PARTIAL" or "REFUNDED"
|
||||
|
||||
**Business Logic**:
|
||||
```go
|
||||
// Flow: PAID → PARTIAL/REFUNDED
|
||||
// - Validate order is PAID
|
||||
// - Reduce item quantities
|
||||
// - Recalculate totals
|
||||
// - Create refund transaction
|
||||
// - Update order status
|
||||
```
|
||||
|
||||
### 2. Void Order System
|
||||
**Purpose**: Cancel ongoing orders (NEW/PENDING) either entirely or by specific items.
|
||||
|
||||
**Key Components**:
|
||||
- ✅ **API Endpoint**: `POST /order/void`
|
||||
- ✅ **Service Method**: `VoidOrderRequest()`
|
||||
- ✅ **Two Modes**: "ALL" (entire order) or "ITEM" (specific items)
|
||||
- ✅ **Validation**: Order status, item existence, quantity validation
|
||||
- ✅ **Status Management**: Updates order to "VOIDED" or "PARTIAL"
|
||||
|
||||
**Business Logic**:
|
||||
```go
|
||||
// Flow: NEW/PENDING → VOIDED/PARTIAL
|
||||
// - Validate order is NEW or PENDING
|
||||
// - ALL: Set status to VOIDED
|
||||
// - ITEM: Reduce quantities, recalculate totals
|
||||
// - Update order status accordingly
|
||||
```
|
||||
|
||||
### 3. Split Bill System
|
||||
**Purpose**: Split orders into a separate order by items or amounts.
|
||||
|
||||
**Key Components**:
|
||||
- ✅ **API Endpoint**: `POST /order/split-bill`
|
||||
- ✅ **Service Method**: `SplitBillRequest()`
|
||||
- ✅ **Two Modes**: "ITEM" (specify items) or "AMOUNT" (specify amount)
|
||||
- ✅ **Order Creation**: Creates a new order for the split
|
||||
- ✅ **Original Order**: Voids the original order after splitting
|
||||
|
||||
**Business Logic**:
|
||||
```go
|
||||
// Flow: NEW/PENDING → PENDING (reduced) + PAID (split)
|
||||
// - Validate order is NEW or PENDING
|
||||
// - ITEM: Create PAID order with specified items, reduce quantities in original
|
||||
// - AMOUNT: Create PAID order with specified amount, reduce amount in original
|
||||
// - Original order remains PENDING with reduced items/amount
|
||||
// - New split order becomes PAID with specified payment method
|
||||
```
|
||||
|
||||
## 🏗️ Architecture Components
|
||||
|
||||
### 1. Constants & Status Management
|
||||
```go
|
||||
// Added new order statuses
|
||||
const (
|
||||
New OrderStatus = "NEW"
|
||||
Paid OrderStatus = "PAID"
|
||||
Cancel OrderStatus = "CANCEL"
|
||||
Pending OrderStatus = "PENDING"
|
||||
Refunded OrderStatus = "REFUNDED"
|
||||
Voided OrderStatus = "VOIDED" // New
|
||||
Partial OrderStatus = "PARTIAL" // New
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Entity Models
|
||||
```go
|
||||
// New entity types for request/response handling
|
||||
type PartialRefundItem struct {
|
||||
OrderItemID int64 `json:"order_item_id" validate:"required"`
|
||||
Quantity int `json:"quantity" validate:"required,min=1"`
|
||||
}
|
||||
|
||||
type VoidItem struct {
|
||||
OrderItemID int64 `json:"order_item_id" validate:"required"`
|
||||
Quantity int `json:"quantity" validate:"required,min=1"`
|
||||
}
|
||||
|
||||
type SplitBillSplit struct {
|
||||
CustomerName string `json:"customer_name" validate:"required"`
|
||||
CustomerID *int64 `json:"customer_id"`
|
||||
Items []SplitBillItem `json:"items,omitempty"`
|
||||
Amount float64 `json:"amount,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Repository Layer
|
||||
```go
|
||||
// New repository methods
|
||||
type Repository interface {
|
||||
// ... existing methods
|
||||
UpdateOrderItem(ctx mycontext.Context, orderItemID int64, quantity int) error
|
||||
UpdateOrderTotals(ctx mycontext.Context, orderID int64, amount, tax, total float64) error
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Service Layer
|
||||
```go
|
||||
// New service methods
|
||||
type Service interface {
|
||||
// ... existing methods
|
||||
PartialRefundRequest(ctx mycontext.Context, partnerID, orderID int64, reason string, items []entity.PartialRefundItem) error
|
||||
VoidOrderRequest(ctx mycontext.Context, partnerID, orderID int64, reason string, voidType string, items []entity.VoidItem) error
|
||||
SplitBillRequest(ctx mycontext.Context, partnerID, orderID int64, splitType string, splits []entity.SplitBillSplit) ([]*entity.Order, error)
|
||||
}
|
||||
```
|
||||
|
||||
### 5. HTTP Handlers
|
||||
```go
|
||||
// New API endpoints
|
||||
func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) {
|
||||
// ... existing routes
|
||||
route.POST("/partial-refund", jwt, h.PartialRefund)
|
||||
route.POST("/void", jwt, h.VoidOrder)
|
||||
route.POST("/split-bill", jwt, h.SplitBill)
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Order Status Flow
|
||||
|
||||
```
|
||||
NEW → PENDING → PAID → REFUNDED
|
||||
↓ ↓ ↓
|
||||
VOIDED VOIDED PARTIAL
|
||||
```
|
||||
|
||||
**Status Transitions**:
|
||||
- **NEW/PENDING** → **VOIDED**: When entire order is voided
|
||||
- **NEW/PENDING** → **PARTIAL**: When some items are voided
|
||||
- **PAID** → **PARTIAL**: When some items are refunded
|
||||
- **PAID** → **REFUNDED**: When all items are refunded
|
||||
|
||||
## 🔒 Validation & Security
|
||||
|
||||
### Input Validation
|
||||
- ✅ **Order Existence**: Verify order exists and belongs to partner
|
||||
- ✅ **Status Validation**: Ensure appropriate status for operations
|
||||
- ✅ **Item Validation**: Verify items exist and quantities are valid
|
||||
- ✅ **Quantity Validation**: Prevent refunding/voiding more than available
|
||||
- ✅ **Split Validation**: Ensure split amounts match order total
|
||||
|
||||
### Business Rules
|
||||
- ✅ **Partial Refund**: Only PAID orders can be partially refunded
|
||||
- ✅ **Void Order**: Only NEW/PENDING orders can be voided
|
||||
- ✅ **Split Bill**: Only NEW/PENDING orders can be split
|
||||
- ✅ **Transaction Tracking**: All operations create audit trails
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Test Coverage
|
||||
- ✅ **Unit Tests**: Comprehensive test coverage for all service methods
|
||||
- ✅ **Mock Testing**: Uses testify/mock for dependency mocking
|
||||
- ✅ **Edge Cases**: Tests for invalid states and error conditions
|
||||
- ✅ **Success Scenarios**: Tests for successful operations
|
||||
|
||||
### Test Files
|
||||
- `internal/services/v2/order/refund_test.go` - Original refund tests
|
||||
- `internal/services/v2/order/advanced_order_management_test.go` - New feature tests
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
### API Documentation
|
||||
- ✅ **REFUND_API.md**: Complete refund API documentation
|
||||
- ✅ **ADVANCED_ORDER_MANAGEMENT.md**: Comprehensive feature documentation
|
||||
- ✅ **IMPLEMENTATION_SUMMARY.md**: This summary document
|
||||
|
||||
### Documentation Features
|
||||
- ✅ **Request/Response Examples**: Complete JSON examples
|
||||
- ✅ **Error Handling**: Common error scenarios and responses
|
||||
- ✅ **Business Logic**: Detailed process flows
|
||||
- ✅ **cURL Examples**: Ready-to-use API testing commands
|
||||
|
||||
## 🚀 Usage Examples
|
||||
|
||||
### Partial Refund
|
||||
```bash
|
||||
curl -X POST /order/partial-refund \
|
||||
-H "Authorization: Bearer TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"reason": "Customer returned damaged items",
|
||||
"items": [
|
||||
{"order_item_id": 456, "quantity": 2}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
### Void Order
|
||||
```bash
|
||||
curl -X POST /order/void \
|
||||
-H "Authorization: Bearer TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"reason": "Customer cancelled order",
|
||||
"type": "ALL"
|
||||
}'
|
||||
```
|
||||
|
||||
### Split Bill
|
||||
```bash
|
||||
curl -X POST /order/split-bill \
|
||||
-H "Authorization: Bearer TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"type": "ITEM",
|
||||
"payment_method": "CASH",
|
||||
"payment_provider": "CASH",
|
||||
"items": [
|
||||
{"order_item_id": 456, "quantity": 1},
|
||||
{"order_item_id": 789, "quantity": 1}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
## 🔧 Database Considerations
|
||||
|
||||
### Schema Updates
|
||||
```sql
|
||||
-- New statuses supported
|
||||
ALTER TABLE orders ADD CONSTRAINT check_status
|
||||
CHECK (status IN ('NEW', 'PENDING', 'PAID', 'REFUNDED', 'VOIDED', 'PARTIAL'));
|
||||
|
||||
-- Support for quantity updates
|
||||
ALTER TABLE order_items ADD COLUMN updated_at TIMESTAMP DEFAULT NOW();
|
||||
```
|
||||
|
||||
### Transaction Management
|
||||
- ✅ **Atomic Operations**: All operations use database transactions
|
||||
- ✅ **Rollback Support**: Failed operations are properly rolled back
|
||||
- ✅ **Data Consistency**: Ensures order totals match item totals
|
||||
|
||||
## 🎯 Benefits
|
||||
|
||||
### Business Benefits
|
||||
1. **Flexibility**: Support for complex order management scenarios
|
||||
2. **Customer Satisfaction**: Handle partial returns and cancellations
|
||||
3. **Operational Efficiency**: Streamlined bill splitting for groups
|
||||
4. **Audit Trail**: Complete tracking of all order modifications
|
||||
|
||||
### Technical Benefits
|
||||
1. **Scalable Architecture**: Clean separation of concerns
|
||||
2. **Comprehensive Testing**: High test coverage ensures reliability
|
||||
3. **Extensible Design**: Easy to add new order management features
|
||||
4. **Documentation**: Complete API documentation for integration
|
||||
|
||||
## 🔮 Future Enhancements
|
||||
|
||||
### Potential Improvements
|
||||
1. **Bulk Operations**: Support for bulk partial refunds/voids
|
||||
2. **Approval Workflow**: Multi-level approval for large operations
|
||||
3. **Notification System**: Customer notifications for refunds/voids
|
||||
4. **Analytics Dashboard**: Order management trends and analysis
|
||||
5. **Inventory Integration**: Automatic inventory updates for refunds/voids
|
||||
|
||||
### Integration Opportunities
|
||||
1. **Payment Gateway**: Direct refund processing
|
||||
2. **Customer Management**: Customer point adjustments
|
||||
3. **Reporting System**: Enhanced order analytics
|
||||
4. **Mobile App**: Real-time order management
|
||||
|
||||
## 📋 Implementation Checklist
|
||||
|
||||
- ✅ **Core Features**: All three main features implemented
|
||||
- ✅ **API Endpoints**: Complete REST API implementation
|
||||
- ✅ **Service Layer**: Business logic implementation
|
||||
- ✅ **Repository Layer**: Database operations
|
||||
- ✅ **Validation**: Comprehensive input validation
|
||||
- ✅ **Error Handling**: Proper error responses
|
||||
- ✅ **Testing**: Unit test coverage
|
||||
- ✅ **Documentation**: Complete API documentation
|
||||
- ✅ **Status Management**: New order statuses
|
||||
- ✅ **Transaction Tracking**: Audit trail implementation
|
||||
|
||||
## 🎉 Conclusion
|
||||
|
||||
The Advanced Order Management system provides a comprehensive solution for complex order scenarios in the Enaklo POS system. The implementation follows best practices for scalability, maintainability, and reliability, with complete documentation and testing coverage.
|
||||
|
||||
The system is now ready for production use and provides the foundation for future enhancements and integrations.
|
||||
@@ -0,0 +1,271 @@
|
||||
# Refund Order API Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The Refund Order API provides comprehensive functionality to process refunds for paid orders. This includes order status updates, transaction creation, customer voucher reversal, payment gateway refunds, and customer notifications.
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Order Status Management**: Updates order status to "REFUNDED"
|
||||
- ✅ **Transaction Tracking**: Creates refund transactions with negative amounts
|
||||
- ✅ **Customer Voucher Reversal**: Reverses any vouchers/points given for the order
|
||||
- ✅ **Payment Gateway Integration**: Handles refunds for non-cash payments
|
||||
- ✅ **Customer Notifications**: Sends email notifications for refunds
|
||||
- ✅ **Audit Trail**: Tracks who processed the refund and when
|
||||
- ✅ **Refund History**: Provides endpoint to view refund history
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Process Refund
|
||||
|
||||
**POST** `/order/refund`
|
||||
|
||||
Process a refund for a paid order.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"order_id": 123,
|
||||
"reason": "Customer request"
|
||||
}
|
||||
```
|
||||
|
||||
#### Request Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|--------------------------------|
|
||||
| order_id | int64 | Yes | ID of the order to refund |
|
||||
| reason | string | Yes | Reason for the refund |
|
||||
|
||||
#### Response
|
||||
|
||||
**Success (200 OK)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"status": 200,
|
||||
"data": {
|
||||
"order_id": 123,
|
||||
"status": "REFUNDED",
|
||||
"refund_amount": 100000,
|
||||
"reason": "Customer request",
|
||||
"refunded_at": "2024-01-15T10:30:00Z",
|
||||
"customer_name": "John Doe",
|
||||
"payment_type": "CASH"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Error (400 Bad Request)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"status": 400,
|
||||
"message": "only paid order can be refund"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Get Refund History
|
||||
|
||||
**GET** `/order/refund-history`
|
||||
|
||||
Retrieve refund history with filtering and pagination.
|
||||
|
||||
#### Query Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-------------|--------|----------|--------------------------------|
|
||||
| limit | int | No | Number of records (max 100) |
|
||||
| offset | int | No | Number of records to skip |
|
||||
| start_date | string | No | Start date (RFC3339 format) |
|
||||
| end_date | string | No | End date (RFC3339 format) |
|
||||
|
||||
#### Response
|
||||
|
||||
**Success (200 OK)**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"status": 200,
|
||||
"data": [
|
||||
{
|
||||
"order_id": 123,
|
||||
"customer_name": "John Doe",
|
||||
"customer_id": 456,
|
||||
"is_member": true,
|
||||
"status": "REFUNDED",
|
||||
"amount": 95000,
|
||||
"total": 100000,
|
||||
"payment_type": "CASH",
|
||||
"table_number": "A1",
|
||||
"order_type": "DINE_IN",
|
||||
"created_at": "2024-01-15T09:00:00Z",
|
||||
"refunded_at": "2024-01-15T10:30:00Z",
|
||||
"tax": 5000
|
||||
}
|
||||
],
|
||||
"paging_meta": {
|
||||
"page": 1,
|
||||
"total": 25,
|
||||
"limit": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Business Logic
|
||||
|
||||
### Refund Process Flow
|
||||
|
||||
1. **Validation**
|
||||
- Verify order exists and belongs to partner
|
||||
- Ensure order status is "PAID"
|
||||
- Validate refund reason
|
||||
|
||||
2. **Order Update**
|
||||
- Update order status to "REFUNDED"
|
||||
- Store refund reason in order description
|
||||
- Update timestamp
|
||||
|
||||
3. **Transaction Creation**
|
||||
- Create refund transaction with negative amount
|
||||
- Set transaction type to "REFUND"
|
||||
- Track who processed the refund
|
||||
|
||||
4. **Customer Voucher Reversal**
|
||||
- Find vouchers associated with the order
|
||||
- Mark vouchers as reversed/cancelled
|
||||
- Adjust customer points if applicable
|
||||
|
||||
5. **Payment Gateway Refund**
|
||||
- For non-cash payments, call payment gateway refund API
|
||||
- Handle gateway response and errors
|
||||
- Update transaction with gateway details
|
||||
|
||||
6. **Customer Notification**
|
||||
- Send email notification to customer
|
||||
- Include refund details and reason
|
||||
- Provide transaction reference
|
||||
|
||||
### Supported Payment Methods
|
||||
|
||||
| Payment Method | Refund Handling |
|
||||
|----------------|-----------------------------------|
|
||||
| CASH | Manual refund (no gateway call) |
|
||||
| QRIS | Gateway refund via provider API |
|
||||
| CARD | Gateway refund via provider API |
|
||||
| TRANSFER | Gateway refund via provider API |
|
||||
| ONLINE | Gateway refund via provider API |
|
||||
|
||||
### Error Handling
|
||||
|
||||
- **Order not found**: Returns 404 error
|
||||
- **Order not paid**: Returns 400 error with message
|
||||
- **Voucher reversal failure**: Logs warning but continues refund
|
||||
- **Payment gateway failure**: Logs error but continues refund
|
||||
- **Notification failure**: Logs warning but continues refund
|
||||
|
||||
## Database Schema
|
||||
|
||||
### Orders Table
|
||||
|
||||
```sql
|
||||
ALTER TABLE orders ADD COLUMN description TEXT;
|
||||
```
|
||||
|
||||
### Transactions Table
|
||||
|
||||
```sql
|
||||
-- Refund transactions have negative amounts
|
||||
-- Transaction type: "REFUND"
|
||||
-- Status: "REFUND"
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
### Order Status
|
||||
|
||||
```go
|
||||
const (
|
||||
New OrderStatus = "NEW"
|
||||
Paid OrderStatus = "PAID"
|
||||
Cancel OrderStatus = "CANCEL"
|
||||
Pending OrderStatus = "PENDING"
|
||||
Refunded OrderStatus = "REFUNDED" // New status
|
||||
)
|
||||
```
|
||||
|
||||
### Transaction Status
|
||||
|
||||
```go
|
||||
const (
|
||||
New PaymentStatus = "NEW"
|
||||
Paid PaymentStatus = "PAID"
|
||||
Cancel PaymentStatus = "CANCEL"
|
||||
Refund PaymentStatus = "REFUND" // New status
|
||||
)
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Run the refund tests:
|
||||
|
||||
```bash
|
||||
go test ./internal/services/v2/order -v -run TestRefund
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
1. **Authorization**: Only authorized users can process refunds
|
||||
2. **Audit Trail**: All refunds are logged with user and timestamp
|
||||
3. **Validation**: Strict validation prevents invalid refunds
|
||||
4. **Rate Limiting**: Consider implementing rate limiting for refund endpoints
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
1. **Partial Refunds**: Support for refunding specific order items
|
||||
2. **Refund Approval Workflow**: Multi-level approval for large refunds
|
||||
3. **Refund Analytics**: Dashboard for refund trends and analysis
|
||||
4. **Automated Refunds**: Integration with customer service systems
|
||||
5. **Refund Templates**: Predefined refund reasons and templates
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### cURL Example
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/order/refund \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
|
||||
-d '{
|
||||
"order_id": 123,
|
||||
"reason": "Customer request"
|
||||
}'
|
||||
```
|
||||
|
||||
### JavaScript Example
|
||||
|
||||
```javascript
|
||||
const refundOrder = async (orderId, reason) => {
|
||||
const response = await fetch('/api/v1/order/refund', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify({
|
||||
order_id: orderId,
|
||||
reason: reason
|
||||
})
|
||||
});
|
||||
|
||||
return response.json();
|
||||
};
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For questions or issues with the refund API, please contact the development team or create an issue in the project repository.
|
||||
Reference in New Issue
Block a user