1
0
forked from erp-dev/erp
Files
erpnew/docs/2026-06-12_business_red_flush_api.md
2026-06-22 22:27:28 +08:00

89 lines
3.5 KiB
Markdown

# 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
```json
{
"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:
```json
{
"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:
```bash
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.