feat(accounting): add Shayegan as fixed boursecu provider

Wire outbound Invoice/Document sync after confirmed ops, store sync status with timeout lock, and keep SQL credentials out of frontend responses.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-05 17:12:43 +03:30
co-authored by Cursor
parent 698fbed805
commit a42261c06e
20 changed files with 1485 additions and 18 deletions
+7
View File
@@ -0,0 +1,7 @@
shayegan.pdf
Sample_Shygun.postman_collection.json
pdf_*.txt
put_endpoints.txt
node_modules/
package.json
package-lock.json
+84
View File
@@ -0,0 +1,84 @@
# Shayegan webservice notes (PDF + Sample_Shygun Postman)
Do not store real credentials in this file or in Git.
## Known for boursecu (operator, 2026-10-05)
Store panel (`app.boursemes.com`) is the **Laravel API**, not Shayegan:
- Shop domain: `app.boursemes.com`
- `node_server`: `https://app.boursemes.com/server`
- Listed LAN IP on that panel: `192.168.70.189` — different from Shayegan host; do not use as WsServer unless confirmed.
Shayegan webservice hosts (operator):
- Public/static (Mashhad office): `2.180.4.172`
- Internal LAN: `192.168.109.222`
- Port: `2030`
- Candidate `shayegan_base_url` (no `/api` suffix):
- From internet / remote app server: `http://2.180.4.172:2030`
- From same LAN as حسابگر: `http://192.168.109.222:2030`
- If 404, retry with `/WsServer` appended (Postman samples).
SQL Config for Shayegan Put/Get (inside JSON `Config`, not HTTP host):
- `Server`: `P-SERVER`
- `DataBaseName`: `CYPRSD04`
- `DBUserName`: `sa`
- Password: set only in DB `settings.shayegan_db_password` (never commit).
Still useful from operator: Auth*, ItemNumber, STNumber, bank account, amount/weight scales, metal wallet mode.
## Base URL (PDF)
`http://{host}[:port]{optionalBasePath}/api/{Endpoint}`
PDF example: `http://192.168.1.1/api/Document/Put`
Postman often inserts `/WsServer` or `/WsServer-3.13` before `/api`.
Operator port hint: `2030`. SQL Server name is **not** the HTTP host.
## Request shape
Every call body includes `Config`.
Get calls also include `Domain` (+ `RowStart`/`RowCount` query).
Put calls include `PutObject` array at the **same level** as `Config` (raw HTTP / Postman). PDF C# wrapper is named `Put`.
### Config fields
`Server`, `AllowRowSecurity`, `Level`, `DBUserName`, `DBPassword`, `DataBaseName`, `AuthUser`, `AuthPassword`, `Language`
Auth: Shayegan cloud / Hesabgar / none (empty Auth*).
## Endpoints used
| Op | Method path |
|----|-------------|
| Health (read) | `POST .../api/Account/Get?RowStart=0&RowCount=1` |
| Trade | `POST .../api/Invoice/Put` |
| Rial ledger | `POST .../api/Document/Put` |
| Customer account | `POST .../api/Account/Put` |
## Put response (check even on HTTP 200)
```json
{
"Result": [{ "ErrorMessage": "", "Number": "6572", "GuId": "..." }],
"ErrorMessage": "",
"TokenString": ""
}
```
Treat non-empty top-level or per-row `ErrorMessage` as failure.
## InvTyp (company)
1 تولید | 2 فروش | 3 خرید | 4 حواله | 5 رسید انبار | 6 برگشت فروش | 7 برگشت خرید | 8/9 تعدیل | 10 انتقال انبار | 11/12 سفارش | 13 پیش‌فاکتور
Customer **buy** copper → company **فروش** → `InvTyp=2`
Customer **sell** copper → company **خرید** → `InvTyp=3`
## Document body (PDF)
Prefer `AmountBed` / `AmountBes` (also `RialBed` / `RialBes` exist).
Header: `DocDescription`, `DocDate` (`yyyyMMdd`), `DocReference`, `GuId`.
## Invoice required (PDF)
`AccountNumber`, `InvTyp`, `InvDate`; line: item + `STNumber` + `Quan` + `Price`.
Ignore Postman keys with trailing spaces — PDF field names are authoritative.