|
@@ -13,10 +13,27 @@ from services.auth_client import AuthClient
|
|
|
from services.gateway_session_store import GatewaySessionStore
|
|
from services.gateway_session_store import GatewaySessionStore
|
|
|
from services.scoped_api_client import ScopedApiClient
|
|
from services.scoped_api_client import ScopedApiClient
|
|
|
from services.token_store import FileTokenStore, RedisSocketClient, RedisTokenStore
|
|
from services.token_store import FileTokenStore, RedisSocketClient, RedisTokenStore
|
|
|
|
|
+from tools.list_order_filter_options import ListOrderFilterOptionsTool
|
|
|
from tools.query_order import QueryOrderTool
|
|
from tools.query_order import QueryOrderTool
|
|
|
|
|
+from tools.query_order_exact import QueryOrderExactTool
|
|
|
from tools.query_track import QueryTrackTool
|
|
from tools.query_track import QueryTrackTool
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def parse_int_list(value):
|
|
|
|
|
+ if not value:
|
|
|
|
|
+ return []
|
|
|
|
|
+ return [int(item.strip()) for item in value.split(',') if item.strip()]
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def parse_string_list(value):
|
|
|
|
|
+ result = []
|
|
|
|
|
+ for item in (value or '').split(','):
|
|
|
|
|
+ item = item.strip()
|
|
|
|
|
+ if item and item not in result:
|
|
|
|
|
+ result.append(item)
|
|
|
|
|
+ return result
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
class GatewayApp:
|
|
class GatewayApp:
|
|
|
def __init__(self, auth_client=None, api_client=None, token_store=None):
|
|
def __init__(self, auth_client=None, api_client=None, token_store=None):
|
|
|
self.auth_client = auth_client
|
|
self.auth_client = auth_client
|
|
@@ -25,6 +42,10 @@ class GatewayApp:
|
|
|
self._tools = {
|
|
self._tools = {
|
|
|
'query_order': QueryOrderTool(api_client=api_client),
|
|
'query_order': QueryOrderTool(api_client=api_client),
|
|
|
'query_track': QueryTrackTool(api_client=api_client),
|
|
'query_track': QueryTrackTool(api_client=api_client),
|
|
|
|
|
+ 'query_order_exact': QueryOrderExactTool(api_client=api_client),
|
|
|
|
|
+ 'list_order_filter_options': ListOrderFilterOptionsTool(
|
|
|
|
|
+ api_client=api_client
|
|
|
|
|
+ ),
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@classmethod
|
|
@classmethod
|
|
@@ -65,8 +86,36 @@ class GatewayApp:
|
|
|
)
|
|
)
|
|
|
return cls(auth_client=auth_client, api_client=api_client, token_store=token_store)
|
|
return cls(auth_client=auth_client, api_client=api_client, token_store=token_store)
|
|
|
|
|
|
|
|
|
|
+ def registered_tool_names(self):
|
|
|
|
|
+ return tuple(self._tools.keys())
|
|
|
|
|
+
|
|
|
|
|
+ def _enabled_tool_names(self, response):
|
|
|
|
|
+ if not isinstance(response, dict):
|
|
|
|
|
+ raise RuntimeError('invalid enabled tool response')
|
|
|
|
|
+ if response.get('code') != 'MCP_0000':
|
|
|
|
|
+ raise RuntimeError(response.get('msg') or 'list enabled tools failed')
|
|
|
|
|
+ data = response.get('data')
|
|
|
|
|
+ codes = data.get('tool_codes') if isinstance(data, dict) else None
|
|
|
|
|
+ if not isinstance(codes, list):
|
|
|
|
|
+ raise RuntimeError('invalid enabled tool response')
|
|
|
|
|
+ return {
|
|
|
|
|
+ code.strip().lower()
|
|
|
|
|
+ for code in codes
|
|
|
|
|
+ if isinstance(code, str) and code.strip()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ def _load_enabled_tool_names(self):
|
|
|
|
|
+ if self.api_client is None or not hasattr(self.api_client, 'list_enabled_tools'):
|
|
|
|
|
+ raise RuntimeError('enabled tool client unavailable')
|
|
|
|
|
+ return self._enabled_tool_names(self.api_client.list_enabled_tools())
|
|
|
|
|
+
|
|
|
def list_tools(self):
|
|
def list_tools(self):
|
|
|
- return [tool.metadata() for tool in self._tools.values()]
|
|
|
|
|
|
|
+ enabled = self._load_enabled_tool_names()
|
|
|
|
|
+ return [
|
|
|
|
|
+ tool.metadata()
|
|
|
|
|
+ for name, tool in self._tools.items()
|
|
|
|
|
+ if name in enabled
|
|
|
|
|
+ ]
|
|
|
|
|
|
|
|
def build_request_id(self, request_id=''):
|
|
def build_request_id(self, request_id=''):
|
|
|
request_id = str(request_id or '').strip()
|
|
request_id = str(request_id or '').strip()
|
|
@@ -91,6 +140,8 @@ class GatewayApp:
|
|
|
tool = self._tools[name]
|
|
tool = self._tools[name]
|
|
|
if getattr(tool, 'requires_session', True):
|
|
if getattr(tool, 'requires_session', True):
|
|
|
self.ensure_session()
|
|
self.ensure_session()
|
|
|
|
|
+ if name not in self._load_enabled_tool_names():
|
|
|
|
|
+ raise RuntimeError('tool disabled: {0}'.format(name))
|
|
|
arguments = arguments or {}
|
|
arguments = arguments or {}
|
|
|
request_id = self.build_request_id(request_id)
|
|
request_id = self.build_request_id(request_id)
|
|
|
return tool.call(request_id=request_id, **arguments)
|
|
return tool.call(request_id=request_id, **arguments)
|
|
@@ -116,7 +167,29 @@ class GatewayApp:
|
|
|
call_parser.add_argument('--keyword', default='')
|
|
call_parser.add_argument('--keyword', default='')
|
|
|
call_parser.add_argument('--order-id', type=int, default=0)
|
|
call_parser.add_argument('--order-id', type=int, default=0)
|
|
|
call_parser.add_argument('--order-number', default='')
|
|
call_parser.add_argument('--order-number', default='')
|
|
|
|
|
+ call_parser.add_argument('--order-numbers', default='')
|
|
|
call_parser.add_argument('--tracking-number', default='')
|
|
call_parser.add_argument('--tracking-number', default='')
|
|
|
|
|
+ call_parser.add_argument('--tracking-numbers', default='')
|
|
|
|
|
+ call_parser.add_argument('--reference-number', default='')
|
|
|
|
|
+ call_parser.add_argument('--reference-numbers', default='')
|
|
|
|
|
+ call_parser.add_argument('--outbound-number', default='')
|
|
|
|
|
+ call_parser.add_argument('--outbound-numbers', default='')
|
|
|
|
|
+ call_parser.add_argument('--container-code', default='')
|
|
|
|
|
+ call_parser.add_argument('--container-codes', default='')
|
|
|
|
|
+ call_parser.add_argument('--so-number', default='')
|
|
|
|
|
+ call_parser.add_argument('--so-numbers', default='')
|
|
|
|
|
+ call_parser.add_argument('--shipment-id', default='')
|
|
|
|
|
+ call_parser.add_argument('--receiver-country', default='')
|
|
|
|
|
+ call_parser.add_argument('--product-ids', default='')
|
|
|
|
|
+ call_parser.add_argument('--customer-ids', default='')
|
|
|
|
|
+ call_parser.add_argument('--sales-id', type=int, default=0)
|
|
|
|
|
+ call_parser.add_argument('--warehouse-ids', default='')
|
|
|
|
|
+ call_parser.add_argument('--department-id', type=int, default=0)
|
|
|
|
|
+ call_parser.add_argument('--inbound-date-start', default='')
|
|
|
|
|
+ call_parser.add_argument('--inbound-date-end', default='')
|
|
|
|
|
+ call_parser.add_argument('--outbound-date-start', default='')
|
|
|
|
|
+ call_parser.add_argument('--outbound-date-end', default='')
|
|
|
|
|
+ call_parser.add_argument('--filter-type', default='')
|
|
|
call_parser.add_argument('--page', type=int, default=1)
|
|
call_parser.add_argument('--page', type=int, default=1)
|
|
|
call_parser.add_argument('--limit', type=int, default=20)
|
|
call_parser.add_argument('--limit', type=int, default=20)
|
|
|
call_parser.add_argument('--request-id', default='')
|
|
call_parser.add_argument('--request-id', default='')
|
|
@@ -172,6 +245,55 @@ class GatewayApp:
|
|
|
tool_args['tracking_number'] = args.tracking_number
|
|
tool_args['tracking_number'] = args.tracking_number
|
|
|
if args.order_id <= 0 and not args.order_number and not args.tracking_number:
|
|
if args.order_id <= 0 and not args.order_number and not args.tracking_number:
|
|
|
raise ValueError('--order-id, --order-number or --tracking-number is required for query_track')
|
|
raise ValueError('--order-id, --order-number or --tracking-number is required for query_track')
|
|
|
|
|
+ elif args.tool == 'query_order_exact':
|
|
|
|
|
+ exact_strings = {
|
|
|
|
|
+ 'order_number': args.order_number,
|
|
|
|
|
+ 'reference_number': args.reference_number,
|
|
|
|
|
+ 'tracking_number': args.tracking_number,
|
|
|
|
|
+ 'outbound_number': args.outbound_number,
|
|
|
|
|
+ 'container_code': args.container_code,
|
|
|
|
|
+ 'so_number': args.so_number,
|
|
|
|
|
+ 'shipment_id': args.shipment_id,
|
|
|
|
|
+ 'receiver_country': args.receiver_country,
|
|
|
|
|
+ 'inbound_date_start': args.inbound_date_start,
|
|
|
|
|
+ 'inbound_date_end': args.inbound_date_end,
|
|
|
|
|
+ 'outbound_date_start': args.outbound_date_start,
|
|
|
|
|
+ 'outbound_date_end': args.outbound_date_end,
|
|
|
|
|
+ }
|
|
|
|
|
+ for field, value in exact_strings.items():
|
|
|
|
|
+ if value:
|
|
|
|
|
+ tool_args[field] = value
|
|
|
|
|
+ exact_number_lists = {
|
|
|
|
|
+ 'order_numbers': args.order_numbers,
|
|
|
|
|
+ 'reference_numbers': args.reference_numbers,
|
|
|
|
|
+ 'tracking_numbers': args.tracking_numbers,
|
|
|
|
|
+ 'outbound_numbers': args.outbound_numbers,
|
|
|
|
|
+ 'container_codes': args.container_codes,
|
|
|
|
|
+ 'so_numbers': args.so_numbers,
|
|
|
|
|
+ }
|
|
|
|
|
+ for field, value in exact_number_lists.items():
|
|
|
|
|
+ if value:
|
|
|
|
|
+ tool_args[field] = parse_string_list(value)
|
|
|
|
|
+ exact_lists = {
|
|
|
|
|
+ 'product_ids': args.product_ids,
|
|
|
|
|
+ 'customer_ids': args.customer_ids,
|
|
|
|
|
+ 'warehouse_ids': args.warehouse_ids,
|
|
|
|
|
+ }
|
|
|
|
|
+ for field, value in exact_lists.items():
|
|
|
|
|
+ if value:
|
|
|
|
|
+ tool_args[field] = parse_int_list(value)
|
|
|
|
|
+ if args.sales_id > 0:
|
|
|
|
|
+ tool_args['sales_id'] = args.sales_id
|
|
|
|
|
+ if args.department_id > 0:
|
|
|
|
|
+ tool_args['department_id'] = args.department_id
|
|
|
|
|
+ elif args.tool == 'list_order_filter_options':
|
|
|
|
|
+ if not args.filter_type:
|
|
|
|
|
+ raise ValueError(
|
|
|
|
|
+ '--filter-type is required for '
|
|
|
|
|
+ 'list_order_filter_options'
|
|
|
|
|
+ )
|
|
|
|
|
+ tool_args['filter_type'] = args.filter_type
|
|
|
|
|
+ tool_args['keyword'] = args.keyword
|
|
|
else:
|
|
else:
|
|
|
if args.keyword:
|
|
if args.keyword:
|
|
|
tool_args['keyword'] = args.keyword
|
|
tool_args['keyword'] = args.keyword
|
|
@@ -195,4 +317,4 @@ def main(argv=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if __name__ == '__main__':
|
|
|
- raise SystemExit(main(sys.argv[1:]))
|
|
|
|
|
|
|
+ raise SystemExit(main(sys.argv[1:]))
|