3.5 KiB
Business Red-Flush API
Scope
Approved internal business orders can be red-flushed through dedicated endpoints. The first version supports whole-order red flush only.
External-source data must not participate in red flush. If an order has is_external_source=true or a non-empty external_source_id, the service rejects the red-flush operation even when the API request is otherwise valid.
Endpoints
All endpoints require authentication and reuse the existing business order review/cancel employee permission checks.
| Order type | Method | Path |
|---|---|---|
| Purchase order | POST | /api/v1/purchase-orders/{id}/red-flush/ |
| Sales order | POST | /api/v1/sales-orders/{id}/red-flush/ |
| Purchase return order | POST | /api/v1/purchase-return-orders/{id}/red-flush/ |
| Sales return order | POST | /api/v1/sales-return-orders/{id}/red-flush/ |
| Payment order | POST | /api/v1/payment-orders/{id}/red-flush/ |
| Receipt order | POST | /api/v1/receipt-orders/{id}/red-flush/ |
Request Body
{
"reason": "录入错误,需要红冲"
}
reason is required and cannot be blank at the API layer.
Success Response
Returns the refreshed order serializer with HTTP 200.
Important red-flush fields included in responses:
| Field | Description |
|---|---|
is_red_flushed |
Whether the source order has been red-flushed |
red_flush_id |
UUID audit batch ID for this red flush |
red_flushed_at |
Timestamp when the source order was marked red-flushed |
Example:
{
"id": 123,
"status": 2,
"is_red_flushed": true,
"red_flush_id": "1c8e4c7a-6f2a-4d6b-8f8e-674a2d6b67f4",
"red_flushed_at": "2026-06-12T10:00:00Z"
}
The source order status remains approved after red flush.
Error Responses
| Condition | Status | Response shape |
|---|---|---|
Missing or blank reason |
400 | DRF serializer error, keyed by reason |
| Order not found in current merchant | 404 | Existing API not-found response |
| Order is not approved | 400 | { "error": "..." } |
| Order already red-flushed | 400 | { "error": "..." } |
| Order is external-source data | 400 | { "error": "外部来源...不允许红冲" } |
| Service validation failure | 400 | { "error": "..." } |
Merchant Safety
The API first scopes order lookup by request.user.employee.merchant. The service layer also requires merchant and verifies that the order belongs to that merchant.
Audit Notes
red_flush_id is written to the source order and related BalanceChangeRecord rows. It is also written to related StockChangeRecord rows when the source order actually has inventory records. Sales orders may be red-flushed without inventory records; in that case only the balance side is reversed. Existing offset_to/offset_id relationships remain the precise reverse-link mechanism for balance and stock records.
Test Coverage
The dedicated regression suite is:
python manage.py test business.tests.test_red_flush_services api_v1.tests.BusinessRedFlushAPITestCase --settings=flower.settings_test
Coverage expectations:
- Service tests cover all six order types, balance reversal, inventory reversal, duplicate blocking, merchant isolation, missing balance/stock records, transaction rollback, and external payment/receipt rejection.
- API tests cover all six endpoints, required
reason, employee permission rejection, merchant-scoped 404, non-approved orders, duplicate red flush, external payment/receipt rejection, stock-validation error mapping, sales red flush without stock records, and sampled balance/stock side effects.