@dazitech/cli 3.0.8 → 3.1.0

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 (79) hide show
  1. package/README.md +1 -1
  2. package/dist/clis/dazi-app.js +1 -1
  3. package/dist/clis/dazi-flow.js +1 -1
  4. package/dist/clis/dazi-onto.js +7 -2
  5. package/dist/clis/dazi.js +1 -1
  6. package/dist/docs/flow/flow-project-guide.md +1 -1
  7. package/dist/docs/guides/troubleshooting.md +12 -1
  8. package/dist/docs/index.json +21 -2
  9. package/dist/docs/onto/dazi_script_sdk_reference.md +246 -178
  10. package/dist/docs/onto/function-guide.md +123 -95
  11. package/dist/docs/onto//346/234/254/344/275/223/345/210/206/347/261/273/350/247/204/345/210/222/344/270/216SDK/346/211/251/345/261/225/346/226/271/346/241/210.md +169 -0
  12. package/dist/docs/onto//346/234/254/344/275/223/345/221/275/345/220/215/350/247/204/350/214/203_/347/211/251/347/220/206/350/241/250Cube/344/270/216/345/257/271/350/261/241.md +402 -0
  13. package/dist/docs/onto//346/234/254/344/275/223/345/274/200/345/217/221/344/274/230/345/214/226/346/200/273/347/273/223.md +242 -0
  14. 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 +339 -249
  15. package/dist/docs/onto//346/234/254/344/275/223/350/247/204/345/210/222/346/214/207/345/215/227.md +304 -173
  16. package/dist/docs/onto//350/204/232/346/234/254/350/277/220/350/241/214/345/270/270/350/247/201/351/224/231/350/257/257/345/244/204/347/220/206.md +242 -0
  17. 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 +361 -238
  18. 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 +385 -300
  19. package/dist/examples/index.json +22 -16
  20. package/dist/examples/onto/README.md +13 -5
  21. package/dist/examples/onto/_templates/ontology_function_template.py +50 -0
  22. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_account_breakdown.py +62 -0
  23. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_budget_vs_actual.py +69 -0
  24. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_cost_center_profit.py +64 -0
  25. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_get_summary.py +61 -0
  26. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_mom_analysis.py +82 -0
  27. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_top_accounts.py +61 -0
  28. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/profit_fn_yoy_analysis.py +79 -0
  29. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/save_test_arguments.ps1 +38 -0
  30. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.account_breakdown.json +1 -0
  31. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.budget_vs_actual.json +1 -0
  32. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.cost_center_profit.json +1 -0
  33. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.get_summary.json +1 -0
  34. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.mom_analysis.json +1 -0
  35. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.top_accounts.json +1 -0
  36. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/functions/test_arguments/profit.fn.yoy_analysis.json +1 -0
  37. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_category_mount.py +85 -0
  38. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_ontology_init.py +169 -74
  39. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/setup/profit_seed_data.py +16 -13
  40. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_channel_mix.py +19 -16
  41. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_customer_segmentation.py +48 -50
  42. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_get_summary.py +3 -6
  43. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_mom_analysis.py +11 -12
  44. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_region_breakdown.py +6 -7
  45. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_top_products.py +5 -8
  46. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/sales_fn_yoy_analysis.py +3 -6
  47. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/save_test_arguments.ps1 +32 -19
  48. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.channel_mix.json +3 -6
  49. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.customer_segmentation.json +2 -7
  50. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.get_summary.json +2 -5
  51. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.mom_analysis.json +2 -5
  52. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.region_breakdown.json +2 -5
  53. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.top_products.json +2 -7
  54. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/test_arguments/sales.fn.yoy_analysis.json +2 -5
  55. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_category_mount.py +82 -0
  56. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_ontology_init.py +240 -155
  57. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/sales_seed_data.py +59 -20
  58. package/dist/prompts/index.json +8 -1
  59. package/dist/prompts/onto/function-design.md +73 -53
  60. package/dist/prompts/onto/planning-design.md +104 -0
  61. package/dist/prompts/onto/script-publish-run.md +229 -194
  62. package/package.json +1 -1
  63. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_account_breakdown.py +0 -99
  64. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_budget_vs_actual.py +0 -116
  65. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_cost_center_profit.py +0 -85
  66. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_get_summary.py +0 -76
  67. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_mom_analysis.py +0 -86
  68. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_top_accounts.py +0 -103
  69. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/profit_fn_yoy_analysis.py +0 -86
  70. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/save_test_arguments.ps1 +0 -27
  71. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.account_breakdown.json +0 -10
  72. 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 +0 -10
  73. 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 +0 -9
  74. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.get_summary.json +0 -9
  75. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.mom_analysis.json +0 -9
  76. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.top_accounts.json +0 -11
  77. package/dist/examples/onto//345/210/251/346/266/246/347/244/272/344/276/213/function/test_arguments/profit.fn.yoy_analysis.json +0 -9
  78. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/functions/README.md +0 -25
  79. package/dist/examples/onto//351/224/200/345/224/256/347/244/272/344/276/213/setup/README.md +0 -5
@@ -1,85 +0,0 @@
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)
@@ -1,76 +0,0 @@
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)
@@ -1,86 +0,0 @@
1
- """环比分析函数 profit.fn.mom_analysis
2
-
3
- 参数:start_date, end_date, pl_category(可选)
4
- 返回:按月度的收入、成本、费用、营业利润、利润率及环比增长率
5
-
6
- 发布:
7
- dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_mom_analysis.py \\
8
- --space space__zlj --register-function-id profit.fn.mom_analysis
9
- """
10
-
11
- TEST_ARGUMENTS = {
12
- "v": 1,
13
- "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30", "pl_category": ""},
14
- "object_type_code": "ProfitAnalysis",
15
- }
16
-
17
-
18
- def _build_where(start_date, end_date, 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 pl_category:
23
- clauses.append(f"pl_category = '{pl_category}'")
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("pl_category", ""),
33
- )
34
-
35
- sql = f"""
36
- SELECT
37
- formatDateTime(posting_date, '%Y-%m') AS year_month,
38
- sum(if(account_type = '收入', amount_signed, 0)) AS revenue,
39
- sum(if(account_type = '成本', amount_signed, 0)) AS cost,
40
- sum(if(account_type = '费用', amount_signed, 0)) AS expense
41
- FROM actual_journal_entry
42
- {where_clause}
43
- GROUP BY year_month
44
- ORDER BY year_month
45
- """
46
-
47
- rows = p.sql.query(sql)
48
- data = []
49
- prev_profit = None
50
- for row in rows:
51
- rev = float(row.get("revenue", 0) or 0)
52
- cost = float(row.get("cost", 0) or 0)
53
- exp = float(row.get("expense", 0) or 0)
54
- profit = rev - cost - exp
55
- margin = profit / rev if rev > 0 else 0.0
56
- if prev_profit is not None and prev_profit != 0:
57
- mom = (profit - prev_profit) / abs(prev_profit)
58
- else:
59
- mom = 0.0
60
- data.append({
61
- "year_month": str(row.get("year_month", "")),
62
- "revenue": round(rev, 2),
63
- "cost": round(cost, 2),
64
- "expense": round(exp, 2),
65
- "profit": round(profit, 2),
66
- "profit_margin": round(margin, 4),
67
- "mom_growth": round(mom, 4),
68
- })
69
- prev_profit = profit
70
-
71
- return p.function_result(
72
- columns=["year_month", "revenue", "cost", "expense", "profit", "profit_margin", "mom_growth"],
73
- data=data,
74
- row_count=len(data),
75
- )
76
-
77
-
78
- def main():
79
- s = space.get(ctx.space_id or "")
80
- _Ports = type("_Ports", (), {
81
- "get_params": lambda self: dict(ctx.params or {}),
82
- "function_result": lambda self, **kw: onto.function_result(**kw),
83
- })
84
- p = _Ports()
85
- p.sql = s.sql
86
- return _ontology_fn_body(p)
@@ -1,103 +0,0 @@
1
- """科目 Top N 函数 profit.fn.top_accounts
2
-
3
- 参数:limit, metric(net_impact/revenue/cost/expense), start_date, end_date, account_type(可选)
4
- 返回:按指标排序的 Top N 科目
5
-
6
- 发布:
7
- dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_top_accounts.py \\
8
- --space space__zlj --register-function-id profit.fn.top_accounts
9
- """
10
-
11
- TEST_ARGUMENTS = {
12
- "v": 1,
13
- "arguments": {
14
- "limit": 10,
15
- "metric": "net_impact",
16
- "start_date": "2025-01-01",
17
- "end_date": "2026-06-30",
18
- "account_type": "",
19
- },
20
- "object_type_code": "ProfitAnalysis",
21
- }
22
-
23
-
24
- def _build_where(start_date, end_date, account_type):
25
- clauses = ["account_type IN ('收入','成本','费用')"]
26
- if start_date and end_date:
27
- clauses.append(f"posting_date >= '{start_date}' AND posting_date <= '{end_date}'")
28
- if account_type:
29
- clauses.append(f"account_type = '{account_type}'")
30
- return "WHERE " + " AND ".join(clauses)
31
-
32
-
33
- def _ontology_fn_body(p):
34
- params = dict(p.get_params() or {})
35
- limit = int(params.get("limit", 10) or 10)
36
- metric = params.get("metric", "net_impact")
37
- where_clause = _build_where(
38
- params.get("start_date", ""),
39
- params.get("end_date", ""),
40
- params.get("account_type", ""),
41
- )
42
-
43
- order_map = {
44
- "revenue": "revenue DESC",
45
- "cost": "cost DESC",
46
- "expense": "expense DESC",
47
- "net_impact": "abs(net_impact) DESC",
48
- }
49
- order_by = order_map.get(metric, "abs(net_impact) DESC")
50
-
51
- sql = f"""
52
- SELECT
53
- account_code,
54
- account_name,
55
- account_type,
56
- pl_category,
57
- sum(if(account_type = '收入', amount_signed, 0)) AS revenue,
58
- sum(if(account_type = '成本', amount_signed, 0)) AS cost,
59
- sum(if(account_type = '费用', amount_signed, 0)) AS expense,
60
- sum(
61
- if(account_type = '收入', amount_signed,
62
- if(account_type IN ('成本','费用'), -amount_signed, 0))
63
- ) AS net_impact
64
- FROM actual_journal_entry
65
- {where_clause}
66
- GROUP BY account_code, account_name, account_type, pl_category
67
- ORDER BY {order_by}
68
- LIMIT {limit}
69
- """
70
-
71
- rows = p.sql.query(sql)
72
- data = []
73
- rank = 1
74
- for row in rows:
75
- data.append({
76
- "rank": rank,
77
- "account_code": row.get("account_code", ""),
78
- "account_name": row.get("account_name", ""),
79
- "account_type": row.get("account_type", ""),
80
- "pl_category": row.get("pl_category", ""),
81
- "revenue": round(float(row.get("revenue", 0) or 0), 2),
82
- "cost": round(float(row.get("cost", 0) or 0), 2),
83
- "expense": round(float(row.get("expense", 0) or 0), 2),
84
- "net_impact": round(float(row.get("net_impact", 0) or 0), 2),
85
- })
86
- rank += 1
87
-
88
- return p.function_result(
89
- columns=["rank", "account_code", "account_name", "account_type", "pl_category", "revenue", "cost", "expense", "net_impact"],
90
- data=data,
91
- row_count=len(data),
92
- )
93
-
94
-
95
- def main():
96
- s = space.get(ctx.space_id or "")
97
- _Ports = type("_Ports", (), {
98
- "get_params": lambda self: dict(ctx.params or {}),
99
- "function_result": lambda self, **kw: onto.function_result(**kw),
100
- })
101
- p = _Ports()
102
- p.sql = s.sql
103
- return _ontology_fn_body(p)
@@ -1,86 +0,0 @@
1
- """同比分析函数 profit.fn.yoy_analysis
2
-
3
- 参数:start_date, end_date, pl_category(可选)
4
- 返回:按年度的收入、成本、费用、营业利润、利润率及同比增长率
5
-
6
- 发布:
7
- dazi onto script publish 项目/潘达石化/本体/ontos/利润分析本体方案/functions/profit_fn_yoy_analysis.py \\
8
- --space space__zlj --register-function-id profit.fn.yoy_analysis
9
- """
10
-
11
- TEST_ARGUMENTS = {
12
- "v": 1,
13
- "arguments": {"start_date": "2025-01-01", "end_date": "2026-06-30", "pl_category": ""},
14
- "object_type_code": "ProfitAnalysis",
15
- }
16
-
17
-
18
- def _build_where(start_date, end_date, 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 pl_category:
23
- clauses.append(f"pl_category = '{pl_category}'")
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("pl_category", ""),
33
- )
34
-
35
- sql = f"""
36
- SELECT
37
- fiscal_year AS year,
38
- sum(if(account_type = '收入', amount_signed, 0)) AS revenue,
39
- sum(if(account_type = '成本', amount_signed, 0)) AS cost,
40
- sum(if(account_type = '费用', amount_signed, 0)) AS expense
41
- FROM actual_journal_entry
42
- {where_clause}
43
- GROUP BY fiscal_year
44
- ORDER BY year
45
- """
46
-
47
- rows = p.sql.query(sql)
48
- data = []
49
- prev_profit = None
50
- for row in rows:
51
- rev = float(row.get("revenue", 0) or 0)
52
- cost = float(row.get("cost", 0) or 0)
53
- exp = float(row.get("expense", 0) or 0)
54
- profit = rev - cost - exp
55
- margin = profit / rev if rev > 0 else 0.0
56
- if prev_profit is not None and prev_profit != 0:
57
- yoy = (profit - prev_profit) / abs(prev_profit)
58
- else:
59
- yoy = 0.0
60
- data.append({
61
- "year": int(row.get("year", 0) or 0),
62
- "revenue": round(rev, 2),
63
- "cost": round(cost, 2),
64
- "expense": round(exp, 2),
65
- "profit": round(profit, 2),
66
- "profit_margin": round(margin, 4),
67
- "yoy_growth": round(yoy, 4),
68
- })
69
- prev_profit = profit
70
-
71
- return p.function_result(
72
- columns=["year", "revenue", "cost", "expense", "profit", "profit_margin", "yoy_growth"],
73
- data=data,
74
- row_count=len(data),
75
- )
76
-
77
-
78
- def main():
79
- s = space.get(ctx.space_id or "")
80
- _Ports = type("_Ports", (), {
81
- "get_params": lambda self: dict(ctx.params or {}),
82
- "function_result": lambda self, **kw: onto.function_result(**kw),
83
- })
84
- p = _Ports()
85
- p.sql = s.sql
86
- return _ontology_fn_body(p)
@@ -1,27 +0,0 @@
1
- # 批量保存函数 test_arguments 到平台(space__zlj)
2
- # 用法:在 dazi-work 根目录执行 .\项目\潘达石化\本体\ontos\利润分析本体方案\functions\save_test_arguments.ps1
3
-
4
- $ErrorActionPreference = "Stop"
5
- $space = "space__zlj"
6
- $base = Join-Path $PSScriptRoot "test_arguments"
7
-
8
- $raw = dazi onto function list --space $space 2>&1 | Out-String
9
- $jsonPart = ($raw -split '__JSON_SUMMARY__')[-1].Trim()
10
- $data = $jsonPart | ConvertFrom-Json
11
-
12
- foreach ($fn in $data.data.functions) {
13
- $fid = $fn.function_id
14
- $ofn = $fn.id
15
- if (-not $fid.StartsWith("profit.fn.")) {
16
- continue
17
- }
18
- $file = Join-Path $base "$fid.json"
19
- if (-not (Test-Path $file)) {
20
- Write-Host "SKIP no JSON: $fid ($file)"
21
- continue
22
- }
23
- Write-Host "save $fid ..."
24
- dazi onto function save-test-arguments $ofn --space $space --arguments-json-file $file
25
- }
26
-
27
- Write-Host "Done."
@@ -1,10 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "start_date": "2025-01-01",
5
- "end_date": "2026-06-30",
6
- "account_level": 2,
7
- "pl_category": ""
8
- },
9
- "object_type_code": "ProfitAnalysis"
10
- }
@@ -1,10 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "fiscal_year": 2026,
5
- "fiscal_period": 0,
6
- "budget_version": "2026年度预算",
7
- "cost_center_id": ""
8
- },
9
- "object_type_code": "BudgetAnalysis"
10
- }
@@ -1,9 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "start_date": "2025-01-01",
5
- "end_date": "2026-06-30",
6
- "department": ""
7
- },
8
- "object_type_code": "ProfitAnalysis"
9
- }
@@ -1,9 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "start_date": "2025-01-01",
5
- "end_date": "2026-06-30",
6
- "cost_center_id": ""
7
- },
8
- "object_type_code": "ProfitAnalysis"
9
- }
@@ -1,9 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "start_date": "2025-01-01",
5
- "end_date": "2026-06-30",
6
- "pl_category": ""
7
- },
8
- "object_type_code": "ProfitAnalysis"
9
- }
@@ -1,11 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "limit": 10,
5
- "metric": "net_impact",
6
- "start_date": "2025-01-01",
7
- "end_date": "2026-06-30",
8
- "account_type": ""
9
- },
10
- "object_type_code": "ProfitAnalysis"
11
- }
@@ -1,9 +0,0 @@
1
- {
2
- "v": 1,
3
- "arguments": {
4
- "start_date": "2025-01-01",
5
- "end_date": "2026-06-30",
6
- "pl_category": ""
7
- },
8
- "object_type_code": "ProfitAnalysis"
9
- }
@@ -1,25 +0,0 @@
1
- # functions
2
-
3
- 本体函数脚本。发布须带 `--register-function-id`,与 `plans/` 规划文档中的 function_id 一致。
4
-
5
- ## 测试参数(test_arguments)
6
-
7
- 函数测试完成后,须将默认入参写入平台函数定义,侧栏 **Onto → 运行函数** 才会预填参数。
8
-
9
- 1. 每个函数对应 `test_arguments/<function_id>.json`(与脚本内 `TEST_ARGUMENTS` 保持一致)
10
- 2. 在 **dazi-work 根**批量入库(推荐):
11
-
12
- ```powershell
13
- .\项目\潘达石化\本体\ontos\产品销售本体方案\functions\save_test_arguments.ps1
14
- ```
15
-
16
- 或手动单条(**须用平台内部 id `ofn_xxx`**,可先 `dazi onto function list --space space__zlj` 查看):
17
-
18
- ```powershell
19
- dazi onto function save-test-arguments ofn_156a399fbe0e4636 --space space__zlj `
20
- --arguments-json-file 项目/潘达石化/本体/ontos/产品销售本体方案/functions/test_arguments/sales.fn.get_summary.json
21
- ```
22
-
23
- > CLI 的 `save-test-arguments` 当前 PATCH 路径使用内部 id,直接传 `sales.fn.get_summary` 会 404。
24
-
25
- **注意**:`arguments` 字段中的键名须与函数 `ctx.params` 读取一致;日期范围与 `sales_seed_data.py` 演示数据一致(2025-01-01 ~ 2026-06-30)。
@@ -1,5 +0,0 @@
1
- # setup
2
-
3
- 初始化(`ontology_init`)与灌数(`seed`)脚本。
4
-
5
- 发布示例:`dazi onto script publish 项目/<业务>/本体/ontos/<实现名>/setup/<file>.py --space <space_id> --type setup|data`