@dazitech/cli 3.0.7 → 3.0.8
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.
- package/README.md +1 -1
- package/dist/clis/dazi-app.js +1 -1
- package/dist/clis/dazi-flow.js +1 -1
- package/dist/clis/dazi-onto.js +73 -22
- package/dist/clis/dazi.js +266 -171
- package/dist/docs/flow/flow-project-guide.md +1 -1
- package/dist/docs/guides/quickstart.md +18 -4
- package/dist/docs/guides/troubleshooting.md +1 -1
- package/dist/docs/guides/workspace-v3.md +43 -23
- package/dist/docs/index.json +9 -3
- package/dist/docs/onto/action-guide.md +3 -3
- package/dist/docs/onto/dazi_script_sdk_reference.md +178 -174
- package/dist/docs/onto/dazi_script_seed_data_guide.md +158 -155
- package/dist/docs/onto/function-guide.md +37 -10
- package/dist/docs/onto/space-management.md +3 -1
- package/dist/docs/onto//346/234/254/344/275/223/350/204/232/346/234/254/347/274/226/345/206/231/346/214/207/345/215/227.md +138 -34
- package/dist/docs/onto//346/234/254/344/275/223/350/247/204/345/210/222/346/214/207/345/215/227.md +73 -31
- package/dist/docs/onto//350/247/204/345/210/222/347/244/272/344/276/213_/344/272/247/345/223/201/351/224/200/345/224/256/346/234/254/344/275/223/350/247/204/345/210/222/346/226/271/346/241/210.md +497 -0
- package/dist/docs/onto//350/247/204/345/210/222/347/244/272/344/276/213_/345/210/251/346/266/246/345/210/206/346/236/220/346/234/254/344/275/223/346/226/271/346/241/210.md +597 -541
- package/dist/examples/index.json +202 -22
- package/dist/examples/onto/README.md +43 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_account_breakdown.py +99 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_budget_vs_actual.py +116 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_cost_center_profit.py +85 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_get_summary.py +76 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_mom_analysis.py +86 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_top_accounts.py +103 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_yoy_analysis.py +86 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/save_test_arguments.ps1 +27 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.account_breakdown.json +10 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.budget_vs_actual.json +10 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.cost_center_profit.json +9 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.get_summary.json +9 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.mom_analysis.json +9 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.top_accounts.json +11 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.yoy_analysis.json +9 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_ontology_init.py +521 -0
- package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_seed_data.py +213 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/README.md +25 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_channel_mix.py +86 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_customer_segmentation.py +123 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_get_summary.py +81 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_mom_analysis.py +90 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_region_breakdown.py +85 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_top_products.py +101 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_yoy_analysis.py +90 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/save_test_arguments.ps1 +25 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.channel_mix.json +8 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.customer_segmentation.json +10 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.get_summary.json +8 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.mom_analysis.json +8 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.region_breakdown.json +8 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.top_products.json +10 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.yoy_analysis.json +8 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/README.md +5 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_ontology_init.py +403 -0
- package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_seed_data.py +124 -0
- package/dist/prompts/index.json +2 -2
- package/dist/prompts/onto/action-design.md +4 -1
- package/dist/prompts/onto/function-design.md +9 -2
- package/dist/prompts/onto/rule-seed.md +5 -1
- package/dist/prompts/onto/script-publish-run.md +72 -24
- package/package.json +1 -1
- package/dist/examples/onto/function/profit_fn_customer_segmentation.py +0 -117
- package/dist/examples/onto/function/profit_fn_mom_analysis.py +0 -89
- package/dist/examples/onto/function/profit_fn_top_products.py +0 -89
- package/dist/examples/onto/function/profit_fn_yoy_analysis.py +0 -89
- package/dist/examples/onto/setup/profit_ontology_init.py +0 -388
package/dist/examples/index.json
CHANGED
|
@@ -1,36 +1,216 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.0
|
|
3
|
-
"updatedAt": "2026-
|
|
2
|
+
"version": "3.1.0",
|
|
3
|
+
"updatedAt": "2026-06-06T12:00:00.000Z",
|
|
4
4
|
"examples": [
|
|
5
5
|
{
|
|
6
|
-
"id": "onto/
|
|
7
|
-
"title": "
|
|
8
|
-
"category": "onto
|
|
9
|
-
"file": "onto/
|
|
6
|
+
"id": "onto/readme",
|
|
7
|
+
"title": "Onto 示例总览(利润 + 销售)",
|
|
8
|
+
"category": "onto",
|
|
9
|
+
"file": "onto/README.md"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
|
-
"id": "onto/
|
|
13
|
-
"title": "
|
|
14
|
-
"category": "onto
|
|
15
|
-
"file": "onto/
|
|
12
|
+
"id": "onto/profit/setup/ontology-init",
|
|
13
|
+
"title": "利润分析 · 本体初始化",
|
|
14
|
+
"category": "onto-利润-初始化",
|
|
15
|
+
"file": "onto/利润示例/setup/profit_ontology_init.py"
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
|
-
"id": "onto/
|
|
19
|
-
"title": "
|
|
20
|
-
"category": "onto
|
|
21
|
-
"file": "onto/
|
|
18
|
+
"id": "onto/profit/setup/seed-data",
|
|
19
|
+
"title": "利润分析 · 演示灌数",
|
|
20
|
+
"category": "onto-利润-初始化",
|
|
21
|
+
"file": "onto/利润示例/setup/profit_seed_data.py"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
"id": "onto/function/
|
|
25
|
-
"title": "
|
|
26
|
-
"category": "onto
|
|
27
|
-
"file": "onto
|
|
24
|
+
"id": "onto/profit/function/get-summary",
|
|
25
|
+
"title": "利润分析 · 利润总览",
|
|
26
|
+
"category": "onto-利润-函数",
|
|
27
|
+
"file": "onto/利润示例/function/profit_fn_get_summary.py"
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
|
-
"id": "onto/function/
|
|
31
|
-
"title": "
|
|
32
|
-
"category": "onto
|
|
33
|
-
"file": "onto
|
|
30
|
+
"id": "onto/profit/function/yoy",
|
|
31
|
+
"title": "利润分析 · 同比 (YoY)",
|
|
32
|
+
"category": "onto-利润-函数",
|
|
33
|
+
"file": "onto/利润示例/function/profit_fn_yoy_analysis.py"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "onto/profit/function/mom",
|
|
37
|
+
"title": "利润分析 · 环比 (MoM)",
|
|
38
|
+
"category": "onto-利润-函数",
|
|
39
|
+
"file": "onto/利润示例/function/profit_fn_mom_analysis.py"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "onto/profit/function/budget-vs-actual",
|
|
43
|
+
"title": "利润分析 · 预实对比",
|
|
44
|
+
"category": "onto-利润-函数",
|
|
45
|
+
"file": "onto/利润示例/function/profit_fn_budget_vs_actual.py"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"id": "onto/profit/function/account-breakdown",
|
|
49
|
+
"title": "利润分析 · 科目结构",
|
|
50
|
+
"category": "onto-利润-函数",
|
|
51
|
+
"file": "onto/利润示例/function/profit_fn_account_breakdown.py"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "onto/profit/function/cost-center-profit",
|
|
55
|
+
"title": "利润分析 · 组织利润",
|
|
56
|
+
"category": "onto-利润-函数",
|
|
57
|
+
"file": "onto/利润示例/function/profit_fn_cost_center_profit.py"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"id": "onto/profit/function/top-accounts",
|
|
61
|
+
"title": "利润分析 · 科目 Top N",
|
|
62
|
+
"category": "onto-利润-函数",
|
|
63
|
+
"file": "onto/利润示例/function/profit_fn_top_accounts.py"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "onto/profit/function/save-test-arguments",
|
|
67
|
+
"title": "利润分析 · 批量保存 test_arguments",
|
|
68
|
+
"category": "onto-利润-工具",
|
|
69
|
+
"file": "onto/利润示例/function/save_test_arguments.ps1"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "onto/profit/test-args/get-summary",
|
|
73
|
+
"title": "test_arguments · profit.fn.get_summary",
|
|
74
|
+
"category": "onto-利润-测试参数",
|
|
75
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.get_summary.json"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "onto/profit/test-args/yoy",
|
|
79
|
+
"title": "test_arguments · profit.fn.yoy_analysis",
|
|
80
|
+
"category": "onto-利润-测试参数",
|
|
81
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.yoy_analysis.json"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "onto/profit/test-args/mom",
|
|
85
|
+
"title": "test_arguments · profit.fn.mom_analysis",
|
|
86
|
+
"category": "onto-利润-测试参数",
|
|
87
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.mom_analysis.json"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "onto/profit/test-args/budget-vs-actual",
|
|
91
|
+
"title": "test_arguments · profit.fn.budget_vs_actual",
|
|
92
|
+
"category": "onto-利润-测试参数",
|
|
93
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.budget_vs_actual.json"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "onto/profit/test-args/account-breakdown",
|
|
97
|
+
"title": "test_arguments · profit.fn.account_breakdown",
|
|
98
|
+
"category": "onto-利润-测试参数",
|
|
99
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.account_breakdown.json"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "onto/profit/test-args/cost-center-profit",
|
|
103
|
+
"title": "test_arguments · profit.fn.cost_center_profit",
|
|
104
|
+
"category": "onto-利润-测试参数",
|
|
105
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.cost_center_profit.json"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "onto/profit/test-args/top-accounts",
|
|
109
|
+
"title": "test_arguments · profit.fn.top_accounts",
|
|
110
|
+
"category": "onto-利润-测试参数",
|
|
111
|
+
"file": "onto/利润示例/function/test_arguments/profit.fn.top_accounts.json"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "onto/sales/setup/ontology-init",
|
|
115
|
+
"title": "产品销售 · 本体初始化",
|
|
116
|
+
"category": "onto-销售-初始化",
|
|
117
|
+
"file": "onto/销售示例/setup/sales_ontology_init.py"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "onto/sales/setup/seed-data",
|
|
121
|
+
"title": "产品销售 · 演示灌数",
|
|
122
|
+
"category": "onto-销售-初始化",
|
|
123
|
+
"file": "onto/销售示例/setup/sales_seed_data.py"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "onto/sales/function/get-summary",
|
|
127
|
+
"title": "产品销售 · 销售概览",
|
|
128
|
+
"category": "onto-销售-函数",
|
|
129
|
+
"file": "onto/销售示例/functions/sales_fn_get_summary.py"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "onto/sales/function/yoy",
|
|
133
|
+
"title": "产品销售 · 同比分析",
|
|
134
|
+
"category": "onto-销售-函数",
|
|
135
|
+
"file": "onto/销售示例/functions/sales_fn_yoy_analysis.py"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "onto/sales/function/mom",
|
|
139
|
+
"title": "产品销售 · 环比分析",
|
|
140
|
+
"category": "onto-销售-函数",
|
|
141
|
+
"file": "onto/销售示例/functions/sales_fn_mom_analysis.py"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "onto/sales/function/top-products",
|
|
145
|
+
"title": "产品销售 · Top 产品",
|
|
146
|
+
"category": "onto-销售-函数",
|
|
147
|
+
"file": "onto/销售示例/functions/sales_fn_top_products.py"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "onto/sales/function/customer-segmentation",
|
|
151
|
+
"title": "产品销售 · 客户分层",
|
|
152
|
+
"category": "onto-销售-函数",
|
|
153
|
+
"file": "onto/销售示例/functions/sales_fn_customer_segmentation.py"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"id": "onto/sales/function/region-breakdown",
|
|
157
|
+
"title": "产品销售 · 区域分布",
|
|
158
|
+
"category": "onto-销售-函数",
|
|
159
|
+
"file": "onto/销售示例/functions/sales_fn_region_breakdown.py"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"id": "onto/sales/function/channel-mix",
|
|
163
|
+
"title": "产品销售 · 渠道结构",
|
|
164
|
+
"category": "onto-销售-函数",
|
|
165
|
+
"file": "onto/销售示例/functions/sales_fn_channel_mix.py"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "onto/sales/function/save-test-arguments",
|
|
169
|
+
"title": "产品销售 · 批量保存 test_arguments",
|
|
170
|
+
"category": "onto-销售-工具",
|
|
171
|
+
"file": "onto/销售示例/functions/save_test_arguments.ps1"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"id": "onto/sales/test-args/get-summary",
|
|
175
|
+
"title": "test_arguments · sales.fn.get_summary",
|
|
176
|
+
"category": "onto-销售-测试参数",
|
|
177
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.get_summary.json"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "onto/sales/test-args/yoy",
|
|
181
|
+
"title": "test_arguments · sales.fn.yoy_analysis",
|
|
182
|
+
"category": "onto-销售-测试参数",
|
|
183
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.yoy_analysis.json"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"id": "onto/sales/test-args/mom",
|
|
187
|
+
"title": "test_arguments · sales.fn.mom_analysis",
|
|
188
|
+
"category": "onto-销售-测试参数",
|
|
189
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.mom_analysis.json"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"id": "onto/sales/test-args/top-products",
|
|
193
|
+
"title": "test_arguments · sales.fn.top_products",
|
|
194
|
+
"category": "onto-销售-测试参数",
|
|
195
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.top_products.json"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": "onto/sales/test-args/customer-segmentation",
|
|
199
|
+
"title": "test_arguments · sales.fn.customer_segmentation",
|
|
200
|
+
"category": "onto-销售-测试参数",
|
|
201
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.customer_segmentation.json"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"id": "onto/sales/test-args/region-breakdown",
|
|
205
|
+
"title": "test_arguments · sales.fn.region_breakdown",
|
|
206
|
+
"category": "onto-销售-测试参数",
|
|
207
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.region_breakdown.json"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"id": "onto/sales/test-args/channel-mix",
|
|
211
|
+
"title": "test_arguments · sales.fn.channel_mix",
|
|
212
|
+
"category": "onto-销售-测试参数",
|
|
213
|
+
"file": "onto/销售示例/functions/test_arguments/sales.fn.channel_mix.json"
|
|
34
214
|
},
|
|
35
215
|
{
|
|
36
216
|
"id": "flow/minimal-excel-python",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Onto 内置示例
|
|
2
|
+
|
|
3
|
+
`dazi examples sync` 后位于 **`资源/examples/onto/`**。复制到业务项目的 **`项目/<业务名>/本体/ontos/<实现名>/`** 对应子目录后再改 `space_id` 与业务字段。
|
|
4
|
+
|
|
5
|
+
## 利润示例(`利润示例/`)
|
|
6
|
+
|
|
7
|
+
| 路径 | 说明 | 规划文档 |
|
|
8
|
+
|------|------|----------|
|
|
9
|
+
| `setup/profit_ontology_init.py` | GL 域 init(科目/分录/预算表、Cube、对象、链接) | [规划示例_利润分析本体方案](../../docs/onto/规划示例_利润分析本体方案.md) |
|
|
10
|
+
| `setup/profit_seed_data.py` | 演示灌数(科目树、成本中心、实际分录、预算) | 同上 |
|
|
11
|
+
| `function/profit_fn_*.py` | 7 个 GL 分析函数(总览/同比/环比/预实/科目/组织/Top 科目) | 同上 |
|
|
12
|
+
| `function/test_arguments/*.json` | 各 `profit.fn.*` 默认测试入参 | 规划 §6.5 |
|
|
13
|
+
| `function/save_test_arguments.ps1` | 批量写入平台 `test_arguments` | 发布函数后执行 |
|
|
14
|
+
|
|
15
|
+
发布后须 **`function run` 验证** → **`save-test-arguments`** 写入默认测试入参(见规划 §6.5)。
|
|
16
|
+
|
|
17
|
+
推荐空间:`space__zlj`(以你的实现单元 README 为准)。
|
|
18
|
+
|
|
19
|
+
## 销售示例(`销售示例/`)
|
|
20
|
+
|
|
21
|
+
| 路径 | 说明 | 规划文档 |
|
|
22
|
+
|------|------|----------|
|
|
23
|
+
| `setup/sales_ontology_init.py` | 产品销售 init(表间关系 + Cube + 本体) | [规划示例_产品销售本体规划方案](../../docs/onto/规划示例_产品销售本体规划方案.md) |
|
|
24
|
+
| `setup/sales_seed_data.py` | 演示灌数(产品/销售/维表) | 同上 |
|
|
25
|
+
| `functions/sales_fn_*.py` | 7 个销售分析函数 | 同上 |
|
|
26
|
+
| `functions/test_arguments/*.json` | 各 `function_id` 默认测试入参 | 与规划 §函数清单一致 |
|
|
27
|
+
| `functions/save_test_arguments.ps1` | 批量写入平台 `test_arguments` | 发布函数后执行 |
|
|
28
|
+
|
|
29
|
+
推荐空间:`space__zlj`(以你的实现单元 README 为准)。
|
|
30
|
+
|
|
31
|
+
## 复制示例
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
资源/examples/onto/利润示例/setup/*.py → 项目/<业务>/本体/ontos/<实现>/setup/
|
|
35
|
+
资源/examples/onto/利润示例/function/*.py → 项目/<业务>/本体/ontos/<实现>/functions/
|
|
36
|
+
资源/examples/onto/利润示例/function/test_arguments/ → .../functions/test_arguments/
|
|
37
|
+
|
|
38
|
+
资源/examples/onto/销售示例/setup/*.py → 项目/<业务>/本体/ontos/<实现>/setup/
|
|
39
|
+
资源/examples/onto/销售示例/functions/*.py → 项目/<业务>/本体/ontos/<实现>/functions/
|
|
40
|
+
资源/examples/onto/销售示例/functions/test_arguments/ → .../functions/test_arguments/
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
侧栏 **帮助 → 示例** 可按分类浏览;`dazi examples list --category onto-利润-函数` 可过滤。
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""科目结构分析函数 profit.fn.account_breakdown
|
|
2
|
+
|
|
3
|
+
参数:start_date, end_date, account_level, pl_category(均可选)
|
|
4
|
+
返回:科目层级的收入、成本、费用、净影响、占比
|
|
5
|
+
|
|
6
|
+
发布:
|
|
7
|
+
dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_account_breakdown.py \\
|
|
8
|
+
--space space__zlj --register-function-id profit.fn.account_breakdown
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
TEST_ARGUMENTS = {
|
|
12
|
+
"v": 1,
|
|
13
|
+
"arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30", "account_level": 2, "pl_category": ""},
|
|
14
|
+
"object_type_code": "ProfitAnalysis",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _build_where(start_date, end_date, account_level, pl_category):
|
|
19
|
+
clauses = ["account_type IN ('收入','成本','费用')"]
|
|
20
|
+
if start_date and end_date:
|
|
21
|
+
clauses.append(f"posting_date >= '{start_date}' AND posting_date <= '{end_date}'")
|
|
22
|
+
if account_level:
|
|
23
|
+
clauses.append(f"account_level = {int(account_level)}")
|
|
24
|
+
if pl_category:
|
|
25
|
+
clauses.append(f"pl_category = '{pl_category}'")
|
|
26
|
+
return "WHERE " + " AND ".join(clauses)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _ontology_fn_body(p):
|
|
30
|
+
params = dict(p.get_params() or {})
|
|
31
|
+
where_clause = _build_where(
|
|
32
|
+
params.get("start_date", ""),
|
|
33
|
+
params.get("end_date", ""),
|
|
34
|
+
params.get("account_level", ""),
|
|
35
|
+
params.get("pl_category", ""),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
sql = f"""
|
|
39
|
+
SELECT
|
|
40
|
+
account_code,
|
|
41
|
+
account_name,
|
|
42
|
+
account_level,
|
|
43
|
+
pl_category,
|
|
44
|
+
account_type,
|
|
45
|
+
sum(if(account_type = '收入', amount_signed, 0)) AS revenue,
|
|
46
|
+
sum(if(account_type = '成本', amount_signed, 0)) AS cost,
|
|
47
|
+
sum(if(account_type = '费用', amount_signed, 0)) AS expense
|
|
48
|
+
FROM actual_journal_entry
|
|
49
|
+
{where_clause}
|
|
50
|
+
GROUP BY account_code, account_name, account_level, pl_category, account_type
|
|
51
|
+
ORDER BY account_code
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
rows = p.sql.query(sql)
|
|
55
|
+
total_impact = 0.0
|
|
56
|
+
parsed = []
|
|
57
|
+
for row in rows:
|
|
58
|
+
rev = float(row.get("revenue", 0) or 0)
|
|
59
|
+
cost = float(row.get("cost", 0) or 0)
|
|
60
|
+
exp = float(row.get("expense", 0) or 0)
|
|
61
|
+
acct_type = row.get("account_type", "")
|
|
62
|
+
if acct_type == "收入":
|
|
63
|
+
net = rev
|
|
64
|
+
else:
|
|
65
|
+
net = -(cost + exp)
|
|
66
|
+
total_impact += abs(net)
|
|
67
|
+
parsed.append((row, rev, cost, exp, net))
|
|
68
|
+
|
|
69
|
+
data = []
|
|
70
|
+
for row, rev, cost, exp, net in parsed:
|
|
71
|
+
share = abs(net) / total_impact * 100 if total_impact > 0 else 0.0
|
|
72
|
+
data.append({
|
|
73
|
+
"account_code": row.get("account_code", ""),
|
|
74
|
+
"account_name": row.get("account_name", ""),
|
|
75
|
+
"account_level": int(row.get("account_level", 0) or 0),
|
|
76
|
+
"pl_category": row.get("pl_category", ""),
|
|
77
|
+
"revenue": round(rev, 2),
|
|
78
|
+
"cost": round(cost, 2),
|
|
79
|
+
"expense": round(exp, 2),
|
|
80
|
+
"net_impact": round(net, 2),
|
|
81
|
+
"share_pct": round(share, 2),
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
return p.function_result(
|
|
85
|
+
columns=["account_code", "account_name", "account_level", "pl_category", "revenue", "cost", "expense", "net_impact", "share_pct"],
|
|
86
|
+
data=data,
|
|
87
|
+
row_count=len(data),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def main():
|
|
92
|
+
s = space.get(ctx.space_id or "")
|
|
93
|
+
_Ports = type("_Ports", (), {
|
|
94
|
+
"get_params": lambda self: dict(ctx.params or {}),
|
|
95
|
+
"function_result": lambda self, **kw: onto.function_result(**kw),
|
|
96
|
+
})
|
|
97
|
+
p = _Ports()
|
|
98
|
+
p.sql = s.sql
|
|
99
|
+
return _ontology_fn_body(p)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""预实对比函数 profit.fn.budget_vs_actual
|
|
2
|
+
|
|
3
|
+
参数:fiscal_year, fiscal_period(0=全年), budget_version, cost_center_id(可选)
|
|
4
|
+
返回:科目×成本中心的预算额、实际额、差异、执行率
|
|
5
|
+
|
|
6
|
+
发布:
|
|
7
|
+
dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_budget_vs_actual.py \\
|
|
8
|
+
--space space__zlj --register-function-id profit.fn.budget_vs_actual
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
TEST_ARGUMENTS = {
|
|
12
|
+
"v": 1,
|
|
13
|
+
"arguments": {
|
|
14
|
+
"fiscal_year": 2026,
|
|
15
|
+
"fiscal_period": 0,
|
|
16
|
+
"budget_version": "2026年度预算",
|
|
17
|
+
"cost_center_id": "",
|
|
18
|
+
},
|
|
19
|
+
"object_type_code": "BudgetAnalysis",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _ontology_fn_body(p):
|
|
24
|
+
params = dict(p.get_params() or {})
|
|
25
|
+
fiscal_year = int(params.get("fiscal_year", 2026) or 2026)
|
|
26
|
+
fiscal_period = int(params.get("fiscal_period", 0) or 0)
|
|
27
|
+
budget_version = params.get("budget_version", "2026年度预算")
|
|
28
|
+
cost_center_id = params.get("cost_center_id", "")
|
|
29
|
+
|
|
30
|
+
period_filter_b = ""
|
|
31
|
+
period_filter_a = ""
|
|
32
|
+
if fiscal_period > 0:
|
|
33
|
+
period_filter_b = f"AND fiscal_period = {fiscal_period}"
|
|
34
|
+
period_filter_a = f"AND fiscal_period = {fiscal_period}"
|
|
35
|
+
|
|
36
|
+
cc_filter_b = f"AND cost_center_id = '{cost_center_id}'" if cost_center_id else ""
|
|
37
|
+
cc_filter_a = cc_filter_b
|
|
38
|
+
|
|
39
|
+
sql = f"""
|
|
40
|
+
SELECT
|
|
41
|
+
coalesce(b.account_code, a.account_code) AS account_code,
|
|
42
|
+
coalesce(b.account_name, a.account_name) AS account_name,
|
|
43
|
+
coalesce(b.pl_category, a.pl_category) AS pl_category,
|
|
44
|
+
coalesce(b.cost_center_name, a.cost_center_name) AS cost_center_name,
|
|
45
|
+
coalesce(b.budget_amount, 0) AS budget_amount,
|
|
46
|
+
coalesce(a.actual_amount, 0) AS actual_amount
|
|
47
|
+
FROM (
|
|
48
|
+
SELECT
|
|
49
|
+
account_id,
|
|
50
|
+
account_code,
|
|
51
|
+
account_name,
|
|
52
|
+
pl_category,
|
|
53
|
+
cost_center_id,
|
|
54
|
+
cost_center_name,
|
|
55
|
+
sum(budget_amount) AS budget_amount
|
|
56
|
+
FROM budget_entry
|
|
57
|
+
WHERE fiscal_year = {fiscal_year}
|
|
58
|
+
AND budget_version = '{budget_version}'
|
|
59
|
+
AND status = '已发布'
|
|
60
|
+
{period_filter_b}
|
|
61
|
+
{cc_filter_b}
|
|
62
|
+
GROUP BY account_id, account_code, account_name, pl_category, cost_center_id, cost_center_name
|
|
63
|
+
) b
|
|
64
|
+
FULL OUTER JOIN (
|
|
65
|
+
SELECT
|
|
66
|
+
account_id,
|
|
67
|
+
account_code,
|
|
68
|
+
account_name,
|
|
69
|
+
pl_category,
|
|
70
|
+
cost_center_id,
|
|
71
|
+
cost_center_name,
|
|
72
|
+
sum(amount_signed) AS actual_amount
|
|
73
|
+
FROM actual_journal_entry
|
|
74
|
+
WHERE fiscal_year = {fiscal_year}
|
|
75
|
+
AND account_type IN ('收入','成本','费用')
|
|
76
|
+
{period_filter_a}
|
|
77
|
+
{cc_filter_a}
|
|
78
|
+
GROUP BY account_id, account_code, account_name, pl_category, cost_center_id, cost_center_name
|
|
79
|
+
) a ON b.account_id = a.account_id AND b.cost_center_id = a.cost_center_id
|
|
80
|
+
ORDER BY abs(coalesce(a.actual_amount, 0) - coalesce(b.budget_amount, 0)) DESC
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
rows = p.sql.query(sql)
|
|
84
|
+
data = []
|
|
85
|
+
for row in rows:
|
|
86
|
+
budget_amt = float(row.get("budget_amount", 0) or 0)
|
|
87
|
+
actual_amt = float(row.get("actual_amount", 0) or 0)
|
|
88
|
+
variance = actual_amt - budget_amt
|
|
89
|
+
exec_rate = actual_amt / budget_amt if budget_amt != 0 else 0.0
|
|
90
|
+
data.append({
|
|
91
|
+
"account_code": row.get("account_code", ""),
|
|
92
|
+
"account_name": row.get("account_name", ""),
|
|
93
|
+
"pl_category": row.get("pl_category", ""),
|
|
94
|
+
"cost_center_name": row.get("cost_center_name", ""),
|
|
95
|
+
"budget_amount": round(budget_amt, 2),
|
|
96
|
+
"actual_amount": round(actual_amt, 2),
|
|
97
|
+
"variance": round(variance, 2),
|
|
98
|
+
"execution_rate": round(exec_rate, 4),
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
return p.function_result(
|
|
102
|
+
columns=["account_code", "account_name", "pl_category", "cost_center_name", "budget_amount", "actual_amount", "variance", "execution_rate"],
|
|
103
|
+
data=data,
|
|
104
|
+
row_count=len(data),
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def main():
|
|
109
|
+
s = space.get(ctx.space_id or "")
|
|
110
|
+
_Ports = type("_Ports", (), {
|
|
111
|
+
"get_params": lambda self: dict(ctx.params or {}),
|
|
112
|
+
"function_result": lambda self, **kw: onto.function_result(**kw),
|
|
113
|
+
})
|
|
114
|
+
p = _Ports()
|
|
115
|
+
p.sql = s.sql
|
|
116
|
+
return _ontology_fn_body(p)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""组织利润分析函数 profit.fn.cost_center_profit
|
|
2
|
+
|
|
3
|
+
参数:start_date, end_date, department(可选)
|
|
4
|
+
返回:各成本中心收入、成本、费用、营业利润、利润率
|
|
5
|
+
|
|
6
|
+
发布:
|
|
7
|
+
dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_cost_center_profit.py \\
|
|
8
|
+
--space space__zlj --register-function-id profit.fn.cost_center_profit
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
TEST_ARGUMENTS = {
|
|
12
|
+
"v": 1,
|
|
13
|
+
"arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30", "department": ""},
|
|
14
|
+
"object_type_code": "ProfitAnalysis",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _build_where(start_date, end_date, department):
|
|
19
|
+
clauses = ["account_type IN ('收入','成本','费用')"]
|
|
20
|
+
if start_date and end_date:
|
|
21
|
+
clauses.append(f"posting_date >= '{start_date}' AND posting_date <= '{end_date}'")
|
|
22
|
+
if department:
|
|
23
|
+
clauses.append(f"department = '{department}'")
|
|
24
|
+
return "WHERE " + " AND ".join(clauses)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _ontology_fn_body(p):
|
|
28
|
+
params = dict(p.get_params() or {})
|
|
29
|
+
where_clause = _build_where(
|
|
30
|
+
params.get("start_date", ""),
|
|
31
|
+
params.get("end_date", ""),
|
|
32
|
+
params.get("department", ""),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
sql = f"""
|
|
36
|
+
SELECT
|
|
37
|
+
cost_center_id,
|
|
38
|
+
cost_center_name,
|
|
39
|
+
department,
|
|
40
|
+
profit_center,
|
|
41
|
+
sum(if(account_type = '收入', amount_signed, 0)) AS revenue,
|
|
42
|
+
sum(if(account_type = '成本', amount_signed, 0)) AS cost,
|
|
43
|
+
sum(if(account_type = '费用', amount_signed, 0)) AS expense
|
|
44
|
+
FROM actual_journal_entry
|
|
45
|
+
{where_clause}
|
|
46
|
+
GROUP BY cost_center_id, cost_center_name, department, profit_center
|
|
47
|
+
ORDER BY revenue - cost - expense DESC
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
rows = p.sql.query(sql)
|
|
51
|
+
data = []
|
|
52
|
+
for row in rows:
|
|
53
|
+
rev = float(row.get("revenue", 0) or 0)
|
|
54
|
+
cost = float(row.get("cost", 0) or 0)
|
|
55
|
+
exp = float(row.get("expense", 0) or 0)
|
|
56
|
+
profit = rev - cost - exp
|
|
57
|
+
margin = profit / rev if rev > 0 else 0.0
|
|
58
|
+
data.append({
|
|
59
|
+
"cost_center_id": row.get("cost_center_id", ""),
|
|
60
|
+
"cost_center_name": row.get("cost_center_name", ""),
|
|
61
|
+
"department": row.get("department", ""),
|
|
62
|
+
"profit_center": row.get("profit_center", ""),
|
|
63
|
+
"revenue": round(rev, 2),
|
|
64
|
+
"cost": round(cost, 2),
|
|
65
|
+
"expense": round(exp, 2),
|
|
66
|
+
"operating_profit": round(profit, 2),
|
|
67
|
+
"profit_margin": round(margin, 4),
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return p.function_result(
|
|
71
|
+
columns=["cost_center_id", "cost_center_name", "department", "profit_center", "revenue", "cost", "expense", "operating_profit", "profit_margin"],
|
|
72
|
+
data=data,
|
|
73
|
+
row_count=len(data),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def main():
|
|
78
|
+
s = space.get(ctx.space_id or "")
|
|
79
|
+
_Ports = type("_Ports", (), {
|
|
80
|
+
"get_params": lambda self: dict(ctx.params or {}),
|
|
81
|
+
"function_result": lambda self, **kw: onto.function_result(**kw),
|
|
82
|
+
})
|
|
83
|
+
p = _Ports()
|
|
84
|
+
p.sql = s.sql
|
|
85
|
+
return _ontology_fn_body(p)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""利润总览函数 profit.fn.get_summary
|
|
2
|
+
|
|
3
|
+
参数:start_date, end_date, cost_center_id(可选)
|
|
4
|
+
返回:总收入、总成本、总费用、营业利润、利润率、分录行数
|
|
5
|
+
|
|
6
|
+
发布:
|
|
7
|
+
dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_get_summary.py \\
|
|
8
|
+
--space space__zlj --register-function-id profit.fn.get_summary
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
TEST_ARGUMENTS = {
|
|
12
|
+
"v": 1,
|
|
13
|
+
"arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30", "cost_center_id": ""},
|
|
14
|
+
"object_type_code": "ProfitAnalysis",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _build_where(start_date, end_date, cost_center_id):
|
|
19
|
+
clauses = ["account_type IN ('收入','成本','费用')"]
|
|
20
|
+
if start_date and end_date:
|
|
21
|
+
clauses.append(f"posting_date >= '{start_date}' AND posting_date <= '{end_date}'")
|
|
22
|
+
if cost_center_id:
|
|
23
|
+
clauses.append(f"cost_center_id = '{cost_center_id}'")
|
|
24
|
+
return "WHERE " + " AND ".join(clauses)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _ontology_fn_body(p):
|
|
28
|
+
params = dict(p.get_params() or {})
|
|
29
|
+
start_date = params.get("start_date", "")
|
|
30
|
+
end_date = params.get("end_date", "")
|
|
31
|
+
cost_center_id = params.get("cost_center_id", "")
|
|
32
|
+
where_clause = _build_where(start_date, end_date, cost_center_id)
|
|
33
|
+
|
|
34
|
+
sql = f"""
|
|
35
|
+
SELECT
|
|
36
|
+
sum(if(account_type = '收入', amount_signed, 0)) AS total_revenue,
|
|
37
|
+
sum(if(account_type = '成本', amount_signed, 0)) AS total_cost,
|
|
38
|
+
sum(if(account_type = '费用', amount_signed, 0)) AS total_expense,
|
|
39
|
+
count(line_id) AS line_count
|
|
40
|
+
FROM actual_journal_entry
|
|
41
|
+
{where_clause}
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
rows = p.sql.query(sql)
|
|
45
|
+
row = rows[0] if rows else {}
|
|
46
|
+
rev = float(row.get("total_revenue", 0) or 0)
|
|
47
|
+
cost = float(row.get("total_cost", 0) or 0)
|
|
48
|
+
exp = float(row.get("total_expense", 0) or 0)
|
|
49
|
+
profit = rev - cost - exp
|
|
50
|
+
margin = profit / rev if rev > 0 else 0.0
|
|
51
|
+
|
|
52
|
+
data = [{
|
|
53
|
+
"total_revenue": round(rev, 2),
|
|
54
|
+
"total_cost": round(cost, 2),
|
|
55
|
+
"total_expense": round(exp, 2),
|
|
56
|
+
"operating_profit": round(profit, 2),
|
|
57
|
+
"profit_margin": round(margin, 4),
|
|
58
|
+
"line_count": int(row.get("line_count", 0) or 0),
|
|
59
|
+
}]
|
|
60
|
+
|
|
61
|
+
return p.function_result(
|
|
62
|
+
columns=["total_revenue", "total_cost", "total_expense", "operating_profit", "profit_margin", "line_count"],
|
|
63
|
+
data=data,
|
|
64
|
+
row_count=1,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def main():
|
|
69
|
+
s = space.get(ctx.space_id or "")
|
|
70
|
+
_Ports = type("_Ports", (), {
|
|
71
|
+
"get_params": lambda self: dict(ctx.params or {}),
|
|
72
|
+
"function_result": lambda self, **kw: onto.function_result(**kw),
|
|
73
|
+
})
|
|
74
|
+
p = _Ports()
|
|
75
|
+
p.sql = s.sql
|
|
76
|
+
return _ontology_fn_body(p)
|