cli-dolibarr 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. cli_anything/dolibarr/README.md +410 -0
  2. cli_anything/dolibarr/__init__.py +1 -0
  3. cli_anything/dolibarr/commands/__init__.py +0 -0
  4. cli_anything/dolibarr/commands/_template.py +118 -0
  5. cli_anything/dolibarr/commands/accountancy.py +130 -0
  6. cli_anything/dolibarr/commands/agendaevents.py +127 -0
  7. cli_anything/dolibarr/commands/apibridge.py +86 -0
  8. cli_anything/dolibarr/commands/bankaccounts.py +148 -0
  9. cli_anything/dolibarr/commands/boms.py +211 -0
  10. cli_anything/dolibarr/commands/categories.py +178 -0
  11. cli_anything/dolibarr/commands/config.py +129 -0
  12. cli_anything/dolibarr/commands/contacts.py +130 -0
  13. cli_anything/dolibarr/commands/contracts.py +221 -0
  14. cli_anything/dolibarr/commands/delivery.py +287 -0
  15. cli_anything/dolibarr/commands/documents.py +118 -0
  16. cli_anything/dolibarr/commands/donations.py +121 -0
  17. cli_anything/dolibarr/commands/expensereports.py +135 -0
  18. cli_anything/dolibarr/commands/interventions.py +135 -0
  19. cli_anything/dolibarr/commands/invoices.py +265 -0
  20. cli_anything/dolibarr/commands/knowledge.py +118 -0
  21. cli_anything/dolibarr/commands/login.py +26 -0
  22. cli_anything/dolibarr/commands/member_types.py +118 -0
  23. cli_anything/dolibarr/commands/members.py +141 -0
  24. cli_anything/dolibarr/commands/mobilehub.py +284 -0
  25. cli_anything/dolibarr/commands/mobilehubapi.py +81 -0
  26. cli_anything/dolibarr/commands/mos.py +211 -0
  27. cli_anything/dolibarr/commands/multicurrencies.py +142 -0
  28. cli_anything/dolibarr/commands/orderprocessor.py +275 -0
  29. cli_anything/dolibarr/commands/orders.py +299 -0
  30. cli_anything/dolibarr/commands/partnerships.py +124 -0
  31. cli_anything/dolibarr/commands/pdfa.py +115 -0
  32. cli_anything/dolibarr/commands/products.py +167 -0
  33. cli_anything/dolibarr/commands/projects.py +252 -0
  34. cli_anything/dolibarr/commands/proposals.py +249 -0
  35. cli_anything/dolibarr/commands/quickprint.py +130 -0
  36. cli_anything/dolibarr/commands/receptions.py +216 -0
  37. cli_anything/dolibarr/commands/recruitments.py +124 -0
  38. cli_anything/dolibarr/commands/salaries.py +138 -0
  39. cli_anything/dolibarr/commands/schema.py +270 -0
  40. cli_anything/dolibarr/commands/setup.py +52 -0
  41. cli_anything/dolibarr/commands/shipments.py +116 -0
  42. cli_anything/dolibarr/commands/status.py +42 -0
  43. cli_anything/dolibarr/commands/stock.py +198 -0
  44. cli_anything/dolibarr/commands/stockmodule.py +204 -0
  45. cli_anything/dolibarr/commands/stockmovements.py +86 -0
  46. cli_anything/dolibarr/commands/subscriptions.py +124 -0
  47. cli_anything/dolibarr/commands/supplier_invoices.py +265 -0
  48. cli_anything/dolibarr/commands/supplier_orders.py +259 -0
  49. cli_anything/dolibarr/commands/supplier_proposals.py +249 -0
  50. cli_anything/dolibarr/commands/supplierinvoices.py +263 -0
  51. cli_anything/dolibarr/commands/supplierorders.py +268 -0
  52. cli_anything/dolibarr/commands/supplierproposals.py +122 -0
  53. cli_anything/dolibarr/commands/system.py +59 -0
  54. cli_anything/dolibarr/commands/tasks.py +221 -0
  55. cli_anything/dolibarr/commands/thirdparties.py +165 -0
  56. cli_anything/dolibarr/commands/tickets.py +153 -0
  57. cli_anything/dolibarr/commands/users.py +152 -0
  58. cli_anything/dolibarr/commands/warehouses.py +122 -0
  59. cli_anything/dolibarr/commands/webhook.py +94 -0
  60. cli_anything/dolibarr/commands/workstations.py +121 -0
  61. cli_anything/dolibarr/commands/zapier.py +46 -0
  62. cli_anything/dolibarr/core/__init__.py +0 -0
  63. cli_anything/dolibarr/core/client.py +111 -0
  64. cli_anything/dolibarr/core/config.py +70 -0
  65. cli_anything/dolibarr/core/output.py +127 -0
  66. cli_anything/dolibarr/core/schema_agents.py +247 -0
  67. cli_anything/dolibarr/core/schema_generator.py +593 -0
  68. cli_anything/dolibarr/core/schema_manager.py +270 -0
  69. cli_anything/dolibarr/core/session_client.py +127 -0
  70. cli_anything/dolibarr/dolibarr_cli.py +119 -0
  71. cli_anything/dolibarr/schema.json +10832 -0
  72. cli_anything/dolibarr/tests/__init__.py +0 -0
  73. cli_anything/dolibarr/tests/test_core.py +311 -0
  74. cli_anything/dolibarr/tests/test_full_e2e.py +248 -0
  75. cli_anything/dolibarr/utils/__init__.py +0 -0
  76. cli_dolibarr-2.0.0.dist-info/METADATA +434 -0
  77. cli_dolibarr-2.0.0.dist-info/RECORD +81 -0
  78. cli_dolibarr-2.0.0.dist-info/WHEEL +5 -0
  79. cli_dolibarr-2.0.0.dist-info/entry_points.txt +2 -0
  80. cli_dolibarr-2.0.0.dist-info/licenses/LICENSE +21 -0
  81. cli_dolibarr-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,410 @@
1
+ # cli-dolibarr
2
+
3
+ A stateful command-line interface for managing Dolibarr ERP/CRM via its REST API. Supports third parties, products, invoices, orders, proposals, stock movements, warehouses, projects, tasks, and more.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install cli-dolibarr
9
+ ```
10
+
11
+ Or install from GitHub:
12
+
13
+ ```bash
14
+ pip install git+https://github.com/zswll2/cli-dolibarr.git
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ ```bash
20
+ cli-dolibarr config init
21
+ ```
22
+
23
+ Or set environment variables:
24
+
25
+ ```bash
26
+ export DOLIBARR_URL="https://your-dolibarr.example.com/api/index.php"
27
+ export DOLIBARR_API_KEY="your_api_key"
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Third Parties (Customers/Companies)
33
+
34
+ ```bash
35
+ # List all third parties
36
+ cli-dolibarr thirdparties list
37
+
38
+ # Get a specific third party
39
+ cli-dolibarr thirdparties get 42
40
+
41
+ # Create a third party (required: name)
42
+ cli-dolibarr thirdparties create --name "Acme Corp"
43
+
44
+ # Update a third party
45
+ cli-dolibarr thirdparties update 42 --town "New York" --phone "+1234567890"
46
+
47
+ # Delete a third party
48
+ cli-dolibarr thirdparties delete 42
49
+ ```
50
+
51
+ ### Products
52
+
53
+ ```bash
54
+ # List products
55
+ cli-dolibarr products list
56
+
57
+ # Get a specific product
58
+ cli-dolibarr products get 7
59
+
60
+ # Create a product (required: ref, label)
61
+ cli-dolibarr products create --ref "PROD-001" --label "Widget A"
62
+
63
+ # Update a product
64
+ cli-dolibarr products update 7 --description "Updated description"
65
+
66
+ # Delete a product
67
+ cli-dolibarr products delete 7
68
+ ```
69
+
70
+ ### Invoices
71
+
72
+ ```bash
73
+ # List invoices
74
+ cli-dolibarr invoices list
75
+
76
+ # Get a specific invoice
77
+ cli-dolibarr invoices get 15
78
+
79
+ # Create an invoice (required: socid)
80
+ cli-dolibarr invoices create --socid 42
81
+
82
+ # Update an invoice
83
+ cli-dolibarr invoices update 15 --note "Payment pending"
84
+
85
+ # Delete an invoice
86
+ cli-dolibarr invoices delete 15
87
+ ```
88
+
89
+ ### Orders
90
+
91
+ ```bash
92
+ # List orders
93
+ cli-dolibarr orders list
94
+
95
+ # Get a specific order
96
+ cli-dolibarr orders get 23
97
+
98
+ # Create an order (required: socid, date)
99
+ cli-dolibarr orders create --socid 42 --date "2026-01-15"
100
+
101
+ # Update an order
102
+ cli-dolibarr orders update 23 --note "Expedited shipping"
103
+
104
+ # Delete an order
105
+ cli-dolibarr orders delete 23
106
+ ```
107
+
108
+ ### Proposals
109
+
110
+ ```bash
111
+ # List proposals
112
+ cli-dolibarr proposals list
113
+
114
+ # Get a specific proposal
115
+ cli-dolibarr proposals get 31
116
+
117
+ # Create a proposal (required: socid)
118
+ cli-dolibarr proposals create --socid 42
119
+
120
+ # Update a proposal
121
+ cli-dolibarr proposals update 31 --note "Revised terms"
122
+
123
+ # Delete a proposal
124
+ cli-dolibarr proposals delete 31
125
+ ```
126
+
127
+ ### Stock Movements
128
+
129
+ ```bash
130
+ # List stock movements
131
+ cli-dolibarr stockmovements list
132
+
133
+ # Stock in (type=3, positive qty)
134
+ cli-dolibarr stockmovements create --product-id 7 --warehouse-id 1 --qty 50
135
+
136
+ # Stock out (type=2, negative qty)
137
+ cli-dolibarr stockmovements create --product-id 7 --warehouse-id 1 --qty -10
138
+ ```
139
+
140
+ ### Warehouses
141
+
142
+ ```bash
143
+ # List warehouses
144
+ cli-dolibarr warehouses list
145
+
146
+ # Get a specific warehouse
147
+ cli-dolibarr warehouses get 1
148
+
149
+ # Create a warehouse (required: label)
150
+ cli-dolibarr warehouses create --label "Main Warehouse"
151
+
152
+ # Update a warehouse
153
+ cli-dolibarr warehouses update 1 --town "Shanghai"
154
+
155
+ # Delete a warehouse
156
+ cli-dolibarr warehouses delete 1
157
+ ```
158
+
159
+ ### Projects
160
+
161
+ ```bash
162
+ # List projects
163
+ cli-dolibarr projects list
164
+
165
+ # Get a specific project
166
+ cli-dolibarr projects get 5
167
+
168
+ # Create a project (required: title)
169
+ cli-dolibarr projects create --title "Website Redesign"
170
+
171
+ # Update a project
172
+ cli-dolibarr projects update 5 --description "Phase 2 started"
173
+
174
+ # Delete a project
175
+ cli-dolibarr projects delete 5
176
+ ```
177
+
178
+ ### Tasks
179
+
180
+ ```bash
181
+ # List tasks
182
+ cli-dolibarr tasks list
183
+
184
+ # Get a specific task
185
+ cli-dolibarr tasks get 12
186
+
187
+ # Create a task (requires project context)
188
+ cli-dolibarr tasks create --title "Design mockups" --project-id 5
189
+
190
+ # Update a task
191
+ cli-dolibarr tasks update 12 --progress 75
192
+
193
+ # Delete a task
194
+ cli-dolibarr tasks delete 12
195
+ ```
196
+
197
+ ## Global Options
198
+
199
+ | Option | Description |
200
+ |-----------------|------------------------------------|
201
+ | `--json` | Output in JSON format |
202
+ | `--csv` | Output in CSV format |
203
+ | `--url` | Override Dolibarr API URL |
204
+ | `--api-key` | Override API key |
205
+ | `--limit N` | Limit results to N items |
206
+ | `--verify` | Enable SSL certificate verification|
207
+
208
+ ```bash
209
+ # Example: JSON output with limit
210
+ cli-dolibarr products list --json --limit 5
211
+
212
+ # Example: CSV output
213
+ cli-dolibarr invoices list --csv
214
+
215
+ # Example: Override URL and API key
216
+ cli-dolibarr thirdparties list --url "https://your-dolibarr.example.com/api/index.php" --api-key "your_api_key"
217
+ ```
218
+
219
+ ## REPL Mode
220
+
221
+ Start an interactive session for repeated commands without re-authenticating:
222
+
223
+ ```bash
224
+ cli-dolibarr repl
225
+ ```
226
+
227
+ Inside the REPL, use commands directly:
228
+
229
+ ```
230
+ dolibarr> thirdparties list
231
+ dolibarr> products get 7
232
+ dolibarr> exit
233
+ ```
234
+
235
+ ## Environment Variables
236
+
237
+ | Variable | Description |
238
+ |---------------------|--------------------------------------|
239
+ | `DOLIBARR_URL` | Full API URL (e.g., `https://your-dolibarr.example.com/api/index.php`) |
240
+ | `DOLIBARR_API_KEY` | API key from Dolibarr user settings |
241
+ | `DOLIBARR_VERIFY_SSL`| Set to `1` or `true` to verify SSL |
242
+
243
+ ## SQL Filters
244
+
245
+ Use the `--sql-filter` option to apply advanced filters on list commands:
246
+
247
+ ```bash
248
+ # Filter by name pattern
249
+ cli-dolibarr thirdparties list --sql-filter "(t.name:like:'Acme%')"
250
+
251
+ # Filter by date range
252
+ cli-dolibarr invoices list --sql-filter "(t.datec:>=:'2026-01-01')"
253
+
254
+ # Combined filters
255
+ cli-dolibarr products list --sql-filter "(t.toselect:=:1) and (t.status:=:1)"
256
+
257
+ # IN operator
258
+ cli-dolibarr orders list --sql-filter "(t.status:IN:1,2,3)"
259
+ ```
260
+
261
+ Operators: `:=`, `:like:`, `:<`, `:>`, `:<=`, `:>=`, `:!=`, `:IN:`, `:NOTIN:`
262
+
263
+ ## SSL Verification
264
+
265
+ By default, SSL verification is **disabled** (`--no-verify`) to support self-signed certificates common in self-hosted Dolibarr installations. To enable verification:
266
+
267
+ ```bash
268
+ cli-dolibarr --verify thirdparties list
269
+ ```
270
+
271
+ Or set the environment variable:
272
+
273
+ ```bash
274
+ export DOLIBARR_VERIFY_SSL="true"
275
+ ```
276
+
277
+ ## Schema Management
278
+
279
+ Built-in schema-driven API discovery system for keeping CLI commands in sync with Dolibarr API changes.
280
+
281
+ ```bash
282
+ # Fetch latest API spec from Dolibarr
283
+ cli-dolibarr schema sync
284
+
285
+ # Check coverage (which endpoints have CLI commands)
286
+ cli-dolibarr schema diff
287
+
288
+ # Auto-generate CLI commands for uncovered endpoints
289
+ cli-dolibarr schema generate --all
290
+
291
+ # Preview without writing files
292
+ cli-dolibarr schema generate --all --dry-run
293
+
294
+ # Generate AI code map (AGENTS.md)
295
+ cli-dolibarr schema agents
296
+
297
+ # Export endpoint data for AI fine-tuning
298
+ cli-dolibarr schema export --format jsonl --output data.jsonl
299
+ ```
300
+
301
+ ## Available Commands
302
+
303
+ 49 command groups covering all Dolibarr REST API resources: thirdparties, products, invoices, orders, proposals, shipments, projects, tasks, warehouses, stockmovements, contacts, bankaccounts, categories, users, tickets, webhooks, and more. Run `cli-dolibarr --help` for the full list.
304
+
305
+ ---
306
+
307
+ ## 中文说明
308
+
309
+ Dolibarr ERP/CRM REST API 的命令行管理工具。支持客户、产品、发票、订单、报价、库存、仓库、项目、任务等 49 个模块。
310
+
311
+ ### 安装
312
+
313
+ ```bash
314
+ pip install cli-dolibarr
315
+ ```
316
+
317
+ 或从 GitHub 安装:
318
+
319
+ ```bash
320
+ pip install git+https://github.com/zswll2/cli-dolibarr.git
321
+ ```
322
+
323
+ ### 配置
324
+
325
+ ```bash
326
+ # 交互式配置(输入 URL 和 API Key)
327
+ cli-dolibarr config init
328
+
329
+ # 或使用环境变量
330
+ export DOLIBARR_URL="https://your-dolibarr.example.com/api/index.php"
331
+ export DOLIBARR_API_KEY="your_api_key"
332
+ ```
333
+
334
+ ### 常用命令
335
+
336
+ ```bash
337
+ # 客户管理
338
+ cli-dolibarr thirdparties list # 列出所有客户
339
+ cli-dolibarr thirdparties get 42 # 查看客户详情
340
+ cli-dolibarr thirdparties create --name "Acme Corp" # 创建客户
341
+
342
+ # 产品管理
343
+ cli-dolibarr products list # 列出产品
344
+ cli-dolibarr products create --ref "P001" --label "产品A" # 创建产品
345
+
346
+ # 发票管理
347
+ cli-dolibarr invoices list # 列出发票
348
+ cli-dolibarr invoices create --socid 42 # 创建发票
349
+
350
+ # 订单管理
351
+ cli-dolibarr orders list # 列出订单
352
+ cli-dolibarr orders create --socid 42 --date "2026-01-15" # 创建订单
353
+
354
+ # 库存管理
355
+ cli-dolibarr stockmovements create --product-id 7 --warehouse-id 1 --qty 50 # 入库
356
+ cli-dolibarr stockmovements create --product-id 7 --warehouse-id 1 --qty -10 # 出库
357
+
358
+ # 项目与任务
359
+ cli-dolibarr projects list # 列出项目
360
+ cli-dolibarr tasks list # 列出任务
361
+ ```
362
+
363
+ ### Schema 管理系统
364
+
365
+ 内置 API 自动发现系统,Dolibarr 升级后可自动同步新端点:
366
+
367
+ ```bash
368
+ cli-dolibarr schema sync # 从 Dolibarr 拉取最新 API 定义
369
+ cli-dolibarr schema diff # 查看覆盖情况(哪些有命令、哪些没有)
370
+ cli-dolibarr schema generate --all # 自动生成缺失的 CLI 命令
371
+ cli-dolibarr schema agents # 生成 AI 代码地图 (AGENTS.md)
372
+ cli-dolibarr schema export --format jsonl --output data.jsonl # 导出微调数据
373
+ ```
374
+
375
+ ### 输出格式
376
+
377
+ ```bash
378
+ cli-dolibarr --json products list # JSON 格式
379
+ cli-dolibarr --csv invoices list # CSV 格式(可导入 Excel)
380
+ ```
381
+
382
+ ### 全局选项
383
+
384
+ | 选项 | 说明 |
385
+ |------|------|
386
+ | `--json` | JSON 格式输出 |
387
+ | `--csv` | CSV 格式输出 |
388
+ | `--url` | 覆盖 API URL |
389
+ | `--api-key` | 覆盖 API Key |
390
+ | `--limit N` | 限制返回条数 |
391
+ | `--verify` | 启用 SSL 证书验证 |
392
+
393
+ ### 交互模式
394
+
395
+ ```bash
396
+ cli-dolibarr repl
397
+ # 进入后可直接输入命令:
398
+ # doli> thirdparties list
399
+ # doli> products get 7
400
+ # doli> exit
401
+ ```
402
+
403
+ ### SQL 过滤器
404
+
405
+ ```bash
406
+ cli-dolibarr thirdparties list --sql-filter "(t.name:like:'Acme%')" # 按名称筛选
407
+ cli-dolibarr invoices list --sql-filter "(t.datec:>=:'2026-01-01')" # 按日期筛选
408
+ ```
409
+
410
+ 支持的操作符:`:=`, `:like:`, `:<`, `:>`, `:<=`, `:>=`, `:!=`, `:IN:`, `:NOTIN:`
@@ -0,0 +1 @@
1
+ __version__ = "2.0.0"
File without changes
@@ -0,0 +1,118 @@
1
+ """
2
+ Command template for Dolibarr CLI.
3
+
4
+ Copy this file to create a new command. Name it after your resource
5
+ (e.g. warehouses.py) and rename the group function to match.
6
+
7
+ Registration is automatic — any .py file in this directory (not starting
8
+ with _) that exposes a click.Group or click.Command matching the filename
9
+ will be discovered at startup.
10
+ """
11
+
12
+ import sys
13
+ import click
14
+ import json
15
+ from cli_anything.dolibarr.core.client import DolibarrClient, DolibarrAPIError
16
+ from cli_anything.dolibarr.core.output import OutputFormatter
17
+
18
+
19
+ def _get_client(ctx) -> DolibarrClient:
20
+ return ctx.obj['client']
21
+
22
+
23
+ def _get_formatter(ctx) -> OutputFormatter:
24
+ return ctx.obj['formatter']
25
+
26
+
27
+ # The function name MUST match the filename (without .py).
28
+ # e.g. file "warehouses.py" → function "warehouses".
29
+ @click.group()
30
+ def template(): # ← rename to match your filename
31
+ pass
32
+
33
+
34
+ @template.command('list')
35
+ @click.option('--sortfield', default='t.rowid', help='Sort field')
36
+ @click.option('--sortorder', default='ASC', type=click.Choice(['ASC', 'DESC']))
37
+ @click.option('--limit', default=100, type=int, help='Items per page')
38
+ @click.option('--page', default=0, type=int, help='Page number')
39
+ @click.option('--filter', 'sqlfilters', default=None, help='SQL filter')
40
+ @click.pass_context
41
+ def list_items(ctx, sortfield, sortorder, limit, page, sqlfilters):
42
+ client = _get_client(ctx)
43
+ formatter = _get_formatter(ctx)
44
+ try:
45
+ result = client.list('template', sortfield=sortfield, sortorder=sortorder,
46
+ limit=limit, page=page, sqlfilters=sqlfilters)
47
+ formatter.output(result)
48
+ except DolibarrAPIError as e:
49
+ click.echo(f"Error: {e.message}", err=True)
50
+ sys.exit(1)
51
+
52
+
53
+ @template.command('get')
54
+ @click.argument('id', type=int)
55
+ @click.pass_context
56
+ def get_item(ctx, id):
57
+ client = _get_client(ctx)
58
+ formatter = _get_formatter(ctx)
59
+ try:
60
+ result = client.get('template', resource_id=id)
61
+ formatter.output(result)
62
+ except DolibarrAPIError as e:
63
+ click.echo(f"Error: {e.message}", err=True)
64
+ sys.exit(1)
65
+
66
+
67
+ @template.command('create')
68
+ @click.option('--data', default=None, help='JSON string with all fields')
69
+ @click.pass_context
70
+ def create_item(ctx, data):
71
+ client = _get_client(ctx)
72
+ formatter = _get_formatter(ctx)
73
+ try:
74
+ payload = json.loads(data) if data else {}
75
+ result = client.post('template', data=payload)
76
+ formatter.output(result)
77
+ except DolibarrAPIError as e:
78
+ click.echo(f"Error: {e.message}", err=True)
79
+ sys.exit(1)
80
+
81
+
82
+ @template.command('update')
83
+ @click.argument('id', type=int)
84
+ @click.option('--data', default=None, help='JSON string with all fields')
85
+ @click.option('--set', 'set_fields', multiple=True, help='Key=value pairs')
86
+ @click.pass_context
87
+ def update_item(ctx, id, data, set_fields):
88
+ client = _get_client(ctx)
89
+ formatter = _get_formatter(ctx)
90
+ try:
91
+ if data:
92
+ payload = json.loads(data)
93
+ else:
94
+ existing = client.get('template', resource_id=id)
95
+ payload = existing if isinstance(existing, dict) else {}
96
+ for sf in set_fields:
97
+ if '=' in sf:
98
+ k, v = sf.split('=', 1)
99
+ payload[k] = v
100
+ result = client.put('template', resource_id=id, data=payload)
101
+ formatter.output(result)
102
+ except DolibarrAPIError as e:
103
+ click.echo(f"Error: {e.message}", err=True)
104
+ sys.exit(1)
105
+
106
+
107
+ @template.command('delete')
108
+ @click.argument('id', type=int)
109
+ @click.pass_context
110
+ def delete_item(ctx, id):
111
+ client = _get_client(ctx)
112
+ formatter = _get_formatter(ctx)
113
+ try:
114
+ result = client.delete('template', resource_id=id)
115
+ formatter.output(result)
116
+ except DolibarrAPIError as e:
117
+ click.echo(f"Error: {e.message}", err=True)
118
+ sys.exit(1)
@@ -0,0 +1,130 @@
1
+ import sys
2
+ import click
3
+ import json
4
+ from cli_anything.dolibarr.core.client import DolibarrClient, DolibarrAPIError
5
+ from cli_anything.dolibarr.core.output import OutputFormatter
6
+
7
+
8
+ def _get_client(ctx) -> DolibarrClient:
9
+ return ctx.obj['client']
10
+
11
+
12
+ def _get_formatter(ctx) -> OutputFormatter:
13
+ return ctx.obj['formatter']
14
+
15
+
16
+ @click.group()
17
+ def accountancy():
18
+ """Manage Dolibarr accountancy (会计) entries."""
19
+ pass
20
+
21
+
22
+ @accountancy.command('list')
23
+ @click.option('--sortfield', default='t.rowid', help='Sort field')
24
+ @click.option('--sortorder', default='ASC', type=click.Choice(['ASC', 'DESC']))
25
+ @click.option('--limit', default=100, type=int, help='Items per page')
26
+ @click.option('--page', default=0, type=int, help='Page number')
27
+ @click.option('--filter', 'sqlfilters', default=None, help='SQL filter')
28
+ @click.option('--properties', default=None, help='Fields to return')
29
+ @click.pass_context
30
+ def list_accountancy(ctx, sortfield, sortorder, limit, page, sqlfilters, properties):
31
+ """List accountancy entries."""
32
+ client = _get_client(ctx)
33
+ formatter = _get_formatter(ctx)
34
+ try:
35
+ result = client.list('accountancy', sortfield=sortfield, sortorder=sortorder,
36
+ limit=limit, page=page, sqlfilters=sqlfilters,
37
+ properties=properties)
38
+ formatter.output(result)
39
+ except DolibarrAPIError as e:
40
+ click.echo(f"Error: {e.message}", err=True)
41
+ sys.exit(1)
42
+
43
+
44
+ @accountancy.command('get')
45
+ @click.argument('id', type=int)
46
+ @click.pass_context
47
+ def get_accountancy(ctx, id):
48
+ """Get a single accountancy entry by ID."""
49
+ client = _get_client(ctx)
50
+ formatter = _get_formatter(ctx)
51
+ try:
52
+ result = client.get('accountancy', resource_id=id)
53
+ formatter.output(result)
54
+ except DolibarrAPIError as e:
55
+ click.echo(f"Error: {e.message}", err=True)
56
+ sys.exit(1)
57
+
58
+
59
+ @accountancy.command('create')
60
+ @click.option('--data', default=None, help='JSON string with all fields')
61
+ @click.option('--doc_type', default=None, help='Document type')
62
+ @click.option('--doc_ref', default=None, help='Document reference')
63
+ @click.option('--numero_compte', default=None, help='Account number')
64
+ @click.option('--label_operation', default=None, help='Label of the operation')
65
+ @click.pass_context
66
+ def create_accountancy(ctx, data, doc_type, doc_ref, numero_compte, label_operation):
67
+ """Create a new accountancy entry."""
68
+ client = _get_client(ctx)
69
+ formatter = _get_formatter(ctx)
70
+ try:
71
+ if data:
72
+ payload = json.loads(data)
73
+ else:
74
+ payload = {}
75
+ if doc_type is not None:
76
+ payload['doc_type'] = doc_type
77
+ if doc_ref is not None:
78
+ payload['doc_ref'] = doc_ref
79
+ if numero_compte is not None:
80
+ payload['numero_compte'] = numero_compte
81
+ if label_operation is not None:
82
+ payload['label_operation'] = label_operation
83
+ result = client.post('accountancy', data=payload)
84
+ formatter.output(result)
85
+ except DolibarrAPIError as e:
86
+ click.echo(f"Error: {e.message}", err=True)
87
+ sys.exit(1)
88
+
89
+
90
+ @accountancy.command('update')
91
+ @click.argument('id', type=int)
92
+ @click.option('--data', default=None, help='JSON string with all fields')
93
+ @click.option('--set', 'set_fields', multiple=True, help='Key=value pairs')
94
+ @click.pass_context
95
+ def update_accountancy(ctx, id, data, set_fields):
96
+ """Update an existing accountancy entry."""
97
+ client = _get_client(ctx)
98
+ formatter = _get_formatter(ctx)
99
+ try:
100
+ if data:
101
+ payload = json.loads(data)
102
+ else:
103
+ existing = client.get('accountancy', resource_id=id)
104
+ payload = {}
105
+ if isinstance(existing, dict):
106
+ payload = existing
107
+ for sf in set_fields:
108
+ if '=' in sf:
109
+ k, v = sf.split('=', 1)
110
+ payload[k] = v
111
+ result = client.put('accountancy', resource_id=id, data=payload)
112
+ formatter.output(result)
113
+ except DolibarrAPIError as e:
114
+ click.echo(f"Error: {e.message}", err=True)
115
+ sys.exit(1)
116
+
117
+
118
+ @accountancy.command('delete')
119
+ @click.argument('id', type=int)
120
+ @click.pass_context
121
+ def delete_accountancy(ctx, id):
122
+ """Delete an accountancy entry by ID."""
123
+ client = _get_client(ctx)
124
+ formatter = _get_formatter(ctx)
125
+ try:
126
+ result = client.delete('accountancy', resource_id=id)
127
+ formatter.output(result)
128
+ except DolibarrAPIError as e:
129
+ click.echo(f"Error: {e.message}", err=True)
130
+ sys.exit(1)