Add store loan methods with public website calculate API.

Supports dashboard CRUD and tenant list/get/calculate so storefronts can offer installments, requiring a method pick when several exist.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-24 23:17:51 +03:30
co-authored by Cursor
parent 2a01873c95
commit 4a9e10e614
11 changed files with 1209 additions and 5 deletions
+42
View File
@@ -214,6 +214,8 @@ StoreItem 1──* StoreItemVariant (purchasable SKUs: price, stock, variation c
StoreItemVariant 1──* StoreItemVariantSelection → CategoryVariationOption
Product 1──* ProductTechnicalFieldValue → CategoryTechnicalFormField
Business 1──* StoreLoanMethod (installments / facilities; module `store_installments`)
UserProduct *── Category (via CategoryAssignment, entityType user_product → product categories)
UserProduct 1──* UserProductTechnicalFieldValue → CategoryTechnicalFormField
UserProduct → City (country, city, optional district)
@@ -284,6 +286,9 @@ All routes are prefixed with `/api/v1`.
| GET | `/tenants/:host/portfolios/by-id/:portfolioId` | Public portfolio by id |
| POST | `/businesses/:id/website/sitemap/sync` | Import manifest from `GET https://{domain}/meshkee/sitemap-config.json` |
| GET | `/tenants/:host/store-specials` | Active store specials (`source` is `product` or `store_item`) |
| GET | `/tenants/:host/store-loan-methods` | Active installment/credit methods (`enabled` + `items[]`; needs `store` + `store_installments`) |
| GET | `/tenants/:host/store-loan-methods/:methodId` | One active method |
| POST | `/tenants/:host/store-loan-methods/calculate` | Installment plan — body requires `methodId` (pick method first if multiple) |
| GET | `/tenants/:host/website/category-groups` | Homepage category rows |
| GET | `/tenants/:host/website/brand-groups` | Homepage brand rows |
| GET | `/tenants/:host/website/sliders` | Homepage sliders with slides |
@@ -518,6 +523,42 @@ Stored in `businesses.settings.website.specialProductsSource` (`product` | `stor
- Dashboard: `PATCH /businesses/:id/settings` with `{ website: { specialProductsSource } }`.
- Public: `GET /tenants/:host` includes `specialProductsSource`; `GET /tenants/:host/store-specials` includes top-level `source`.
### Store loan methods (installments & facilities)
Requires modules `store` + `store_installments` (opt-in). Dashboard: Store → اقساط و تسهیلات.
| Field | Notes |
|-------|-------|
| `nameFa` / `nameEn` | Display names |
| `minShoppingAmount` | Minimum purchase total to use this method |
| `minAmount` / `maxAmount` | Allowed credit range |
| `interest` | Flat annual %; fee = credit × (interest/100) × (months/12) |
| `returnMonthsMin` / `Max` / `Step` | Term options (step ∈ 2,3,4,6,12) |
| `imageMediaId` / `imageAspectRatio` | Optional image (`1:1` or `3:2`) |
**Dashboard (auth, `products.read` / `products.update`):**
- `GET/POST /businesses/:businessId/store-loan-methods`
- `GET/PATCH/DELETE /businesses/:businessId/store-loan-methods/:methodId`
**Public website:**
- `GET /tenants/:host/store-loan-methods` → `{ enabled, items[] }` (`enabled: false` + empty when module off)
- `GET /tenants/:host/store-loan-methods/:methodId` → `{ method }` (active only)
- `POST /tenants/:host/store-loan-methods/calculate` → `{ method, plan }` — **always requires `methodId`**
Calculator UX when a site has multiple methods: list first → if `items.length > 1`, ask the shopper which method → then collect purchase total / credit / months → `POST .../calculate`. If exactly one method, auto-select it. Never calculate without a chosen `methodId`.
```json
POST /tenants/:host/store-loan-methods/calculate
{
"methodId": "1",
"totalValue": 5000000,
"creditAmount": 2000000,
"months": 12
}
```
`plan` includes `cashPayment`, `interestFee`, `totalRepay`, and monthly `installments[]` (`index`, `dueDate`, `amount`). Public items also include `returnMonthOptions[]`.
**Example — batch create variants for a product:**
```json
@@ -667,6 +708,7 @@ See `.env.example` for the full list. Key groups:
- Products CRUD
- Product variation values (which options a product offers)
- Store items / product variants (price, stock, SKU)
- Store loan methods / installments (`store_installments`): dashboard CRUD + public list/get/calculate
- Torob Product API v3 (`POST /tenants/:host/torob_api/v3/products`) for store-module websites; nginx proxies `/torob_api/v3/products` on the shop apex
- Shopping cart + checkout + orders (customer + admin)
- Online e-payment (Mellat + ZarinPal; stubs for SEP / Snapp Pay / DigiPay)