feat(business): exclude intercompany transfer orders
Allow operators to configure internal company names and identifiers, then apply the filter consistently across business templates and query routing. Preserve direct external-customer orders and provide explicit CLI and environment overrides for internal-flow audits. Validation: python -m unittest tests.test_business_facts tests.test_wiki_skills tests.test_user_ops -v (25 tests)
This commit is contained in:
+54
-1
@@ -29,6 +29,7 @@ from obsidian_wiki.business_facts import (
|
||||
query_business_question,
|
||||
sync_kingdee_orders,
|
||||
)
|
||||
from obsidian_wiki.config import load_config
|
||||
from obsidian_wiki.file_assets import (
|
||||
clean_config_value,
|
||||
db_path_for_vault,
|
||||
@@ -603,6 +604,7 @@ def cmd_business_query(args: argparse.Namespace) -> int:
|
||||
db_path=_resolve_business_db(args, vault_path),
|
||||
all_staff=args.all_staff,
|
||||
fallback_sql=args.fallback_sql,
|
||||
business_params=_business_internal_params(args),
|
||||
)
|
||||
if args.json:
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
@@ -666,7 +668,32 @@ def _business_template_params(args: argparse.Namespace) -> dict[str, object]:
|
||||
"closestatus",
|
||||
"currency",
|
||||
)
|
||||
return {key: getattr(args, key) for key in keys if getattr(args, key, None) not in (None, "")}
|
||||
params = {key: getattr(args, key) for key in keys if getattr(args, key, None) not in (None, "", [])}
|
||||
params.update({key: value for key, value in _business_internal_params(args).items() if key not in params})
|
||||
return params
|
||||
|
||||
|
||||
def _business_internal_params(args: argparse.Namespace) -> dict[str, object]:
|
||||
params: dict[str, object] = {}
|
||||
if getattr(args, "internal_parties", None):
|
||||
params["internal_parties"] = getattr(args, "internal_parties")
|
||||
if getattr(args, "internal_party_ids", None):
|
||||
params["internal_party_ids"] = getattr(args, "internal_party_ids")
|
||||
if getattr(args, "include_internal_orders", False):
|
||||
params["include_internal_orders"] = True
|
||||
config = load_config(Path.cwd())
|
||||
if not params.get("internal_parties"):
|
||||
parties = os.environ.get("OBSIDIAN_BUSINESS_INTERNAL_PARTIES") or config.get("OBSIDIAN_BUSINESS_INTERNAL_PARTIES")
|
||||
if parties:
|
||||
params["internal_parties"] = parties
|
||||
if not params.get("internal_party_ids"):
|
||||
party_ids = os.environ.get("OBSIDIAN_BUSINESS_INTERNAL_PARTY_IDS") or config.get("OBSIDIAN_BUSINESS_INTERNAL_PARTY_IDS")
|
||||
if party_ids:
|
||||
params["internal_party_ids"] = party_ids
|
||||
include_internal = os.environ.get("OBSIDIAN_BUSINESS_INCLUDE_INTERNAL_ORDERS") or config.get("OBSIDIAN_BUSINESS_INCLUDE_INTERNAL_ORDERS")
|
||||
if include_internal and not params.get("include_internal_orders"):
|
||||
params["include_internal_orders"] = include_internal
|
||||
return params
|
||||
|
||||
|
||||
def cmd_business_sql(args: argparse.Namespace) -> int:
|
||||
@@ -859,6 +886,19 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
bqp.add_argument("--db", metavar="PATH", help="SQLite DB path (defaults to <vault>/_meta/business-facts.sqlite)")
|
||||
bqp.add_argument("--all-staff", action="store_true", help="include secondary sales and follow-up roles in staff queries")
|
||||
bqp.add_argument("--fallback-sql", help="guarded read-only SQL to run only when no fixed template matches")
|
||||
bqp.add_argument(
|
||||
"--internal-party",
|
||||
dest="internal_parties",
|
||||
action="append",
|
||||
help="internal company name substring to exclude intercompany transfer orders; repeat or comma-separate",
|
||||
)
|
||||
bqp.add_argument(
|
||||
"--internal-party-id",
|
||||
dest="internal_party_ids",
|
||||
action="append",
|
||||
help="internal org/customer code to exclude intercompany transfer orders; repeat or comma-separate",
|
||||
)
|
||||
bqp.add_argument("--include-internal-orders", action="store_true", help="include configured internal transfer orders")
|
||||
bqp.add_argument("--json", action="store_true", help="print machine-readable query result")
|
||||
bqp.add_argument("question", nargs="+", help="question, e.g. '2026-06 order count'")
|
||||
bqp.set_defaults(func=cmd_business_query)
|
||||
@@ -894,6 +934,19 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
btp.add_argument("--orderstatus", help="Kingdee orderstatus filter")
|
||||
btp.add_argument("--closestatus", help="Kingdee closestatus filter")
|
||||
btp.add_argument("--currency", help="currency code filter")
|
||||
btp.add_argument(
|
||||
"--internal-party",
|
||||
dest="internal_parties",
|
||||
action="append",
|
||||
help="internal company name substring to exclude intercompany transfer orders; repeat or comma-separate",
|
||||
)
|
||||
btp.add_argument(
|
||||
"--internal-party-id",
|
||||
dest="internal_party_ids",
|
||||
action="append",
|
||||
help="internal org/customer code to exclude intercompany transfer orders; repeat or comma-separate",
|
||||
)
|
||||
btp.add_argument("--include-internal-orders", action="store_true", help="include configured internal transfer orders")
|
||||
btp.add_argument("--json", action="store_true", help="print machine-readable template result")
|
||||
btp.add_argument("template_name", help="template name from `business schema`")
|
||||
btp.set_defaults(func=cmd_business_template)
|
||||
|
||||
Reference in New Issue
Block a user