| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000 |
- import argparse
- import json
- import sys
- import uuid
- from config import GatewayConfig
- from constants import DEVICE_INVALID_MESSAGE
- from mcp_protocol import McpProtocolHandler
- from public_gateway import PublicGatewayApp
- from public_server import serve_public
- from services.api_client import ApiClient
- from services.auth_client import AuthClient
- from services.gateway_session_store import GatewaySessionStore
- from services.diagnostic_reporter import (
- NullDiagnosticReporter,
- diagnostic_reporter_from_config,
- )
- from services.scoped_api_client import ScopedApiClient
- from services.token_store import FileTokenStore, RedisSocketClient, RedisTokenStore
- from tools.list_order_filter_options import ListOrderFilterOptionsTool
- from tools.list_customer_filter_options import ListCustomerFilterOptionsTool
- from tools.list_receivable_cost_filter_options import (
- ListReceivableCostFilterOptionsTool,
- )
- from tools.list_outbound_filter_options import ListOutboundFilterOptionsTool
- from tools.export_pending_outbound_orders import ExportPendingOutboundOrdersTool
- from tools.export_out_of_province_port_data import (
- ExportOutOfProvincePortDataTool,
- )
- from tools.export_receivable_cost_list import ExportReceivableCostListTool
- from tools.list_pending_outbound_export_filter_options import (
- ListPendingOutboundExportFilterOptionsTool,
- )
- from tools.query_order import QueryOrderTool
- from tools.query_customs_declaration_files import (
- QueryCustomsDeclarationFilesTool,
- )
- from tools.query_order_exact import QueryOrderExactTool
- from tools.query_order_detail import QueryOrderDetailTool
- from tools.query_export_task import QueryExportTaskTool
- from tools.query_outbound_detail import QueryOutboundDetailTool
- from tools.query_outbound_list import QueryOutboundListTool
- from tools.query_track import QueryTrackTool
- from tools.query_customer_list import QueryCustomerListTool
- from tools.query_customer_payment_followup import QueryCustomerPaymentFollowupTool
- from tools.query_customer_unverified_bill_details import QueryCustomerUnverifiedBillDetailsTool
- from tools.query_customer_payment_records import QueryCustomerPaymentRecordsTool
- from tools.query_order_receivable_cost_details import (
- QueryOrderReceivableCostDetailsTool,
- )
- from tools.query_receivable_cost_list import QueryReceivableCostListTool
- from tools.query_payable_cost_list import QueryPayableCostListTool
- from tools.list_payable_cost_filter_options import ListPayableCostFilterOptionsTool
- from tools.export_payable_cost_list import ExportPayableCostListTool
- from tools.export_pallet_data import ExportPalletDataTool
- from tools.query_destination_trailer_list import QueryDestinationTrailerListTool
- from tools.arrange_destination_trailer import ArrangeDestinationTrailerTool
- from tools.list_destination_trailer_filter_options import (
- ListDestinationTrailerFilterOptionsTool,
- )
- from tools.query_order_abnormal_list import QueryOrderAbnormalListTool
- from tools.list_order_abnormal_filter_options import (
- ListOrderAbnormalFilterOptionsTool,
- )
- from tools.query_receive_volume_list import QueryReceiveVolumeListTool
- from tools.list_receive_volume_filter_options import (
- ListReceiveVolumeFilterOptionsTool,
- )
- from tools.query_goods_info import QueryGoodsInfoTool
- from tools.trial_goods_tax import TrialGoodsTaxTool
- from tools.query_container_timeliness_list import QueryContainerTimelinessListTool
- from tools.export_container_timeliness_report import (
- ExportContainerTimelinessReportTool,
- )
- from tools.query_headhaul_document_list import QueryHeadhaulDocumentListTool
- from tools.list_headhaul_document_filter_options import (
- ListHeadhaulDocumentFilterOptionsTool,
- )
- from tools.prepare_headhaul_document_upload import (
- PrepareHeadhaulDocumentUploadTool,
- )
- from tools.save_headhaul_document import SaveHeadhaulDocumentTool
- from tools.delete_headhaul_document import DeleteHeadhaulDocumentTool
- from tools.list_inbound_receipt_templates import ListInboundReceiptTemplatesTool
- from tools.export_inbound_receipt import ExportInboundReceiptTool
- from tools.query_freightower_track import QueryFreightowerTrackTool
- 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:
- def __init__(
- self,
- auth_client=None,
- api_client=None,
- token_store=None,
- reporter=None,
- ):
- self.auth_client = auth_client
- self.api_client = api_client
- self.token_store = token_store
- self.reporter = reporter or NullDiagnosticReporter()
- from services.headhaul_document_app import HeadhaulSlotMemory
- self._headhaul_slots = HeadhaulSlotMemory()
- self._tools = {
- 'query_order': QueryOrderTool(api_client=api_client),
- 'query_track': QueryTrackTool(api_client=api_client),
- 'query_order_exact': QueryOrderExactTool(api_client=api_client),
- 'query_order_detail': QueryOrderDetailTool(api_client=api_client),
- 'query_customs_declaration_files':
- QueryCustomsDeclarationFilesTool(api_client=api_client),
- 'query_outbound_list': QueryOutboundListTool(api_client=api_client),
- 'query_outbound_detail': QueryOutboundDetailTool(api_client=api_client),
- 'query_customer_list': QueryCustomerListTool(api_client=api_client),
- 'query_customer_payment_followup': QueryCustomerPaymentFollowupTool(
- api_client=api_client
- ),
- 'query_customer_unverified_bill_details':
- QueryCustomerUnverifiedBillDetailsTool(api_client=api_client),
- 'query_customer_payment_records': QueryCustomerPaymentRecordsTool(
- api_client=api_client
- ),
- 'query_order_receivable_cost_details':
- QueryOrderReceivableCostDetailsTool(api_client=api_client),
- 'query_receivable_cost_list':
- QueryReceivableCostListTool(api_client=api_client),
- 'query_payable_cost_list':
- QueryPayableCostListTool(api_client=api_client),
- 'list_outbound_filter_options': ListOutboundFilterOptionsTool(
- api_client=api_client
- ),
- 'list_order_filter_options': ListOrderFilterOptionsTool(
- api_client=api_client
- ),
- 'list_customer_filter_options': ListCustomerFilterOptionsTool(
- api_client=api_client
- ),
- 'list_receivable_cost_filter_options':
- ListReceivableCostFilterOptionsTool(api_client=api_client),
- 'list_payable_cost_filter_options':
- ListPayableCostFilterOptionsTool(api_client=api_client),
- 'export_pending_outbound_orders': ExportPendingOutboundOrdersTool(
- api_client=api_client
- ),
- 'export_out_of_province_port_data':
- ExportOutOfProvincePortDataTool(api_client=api_client),
- 'export_receivable_cost_list': ExportReceivableCostListTool(
- api_client=api_client
- ),
- 'export_payable_cost_list': ExportPayableCostListTool(
- api_client=api_client
- ),
- 'export_pallet_data': ExportPalletDataTool(
- api_client=api_client
- ),
- 'query_export_task': QueryExportTaskTool(api_client=api_client),
- 'list_pending_outbound_export_filter_options':
- ListPendingOutboundExportFilterOptionsTool(api_client=api_client),
- 'query_destination_trailer_list': QueryDestinationTrailerListTool(
- api_client=api_client
- ),
- 'arrange_destination_trailer': ArrangeDestinationTrailerTool(
- api_client=api_client
- ),
- 'list_destination_trailer_filter_options':
- ListDestinationTrailerFilterOptionsTool(api_client=api_client),
- 'query_order_abnormal_list': QueryOrderAbnormalListTool(
- api_client=api_client
- ),
- 'list_order_abnormal_filter_options':
- ListOrderAbnormalFilterOptionsTool(api_client=api_client),
- 'query_receive_volume_list': QueryReceiveVolumeListTool(
- api_client=api_client
- ),
- 'query_goods_info': QueryGoodsInfoTool(api_client=api_client),
- 'trial_goods_tax': TrialGoodsTaxTool(api_client=api_client),
- 'list_receive_volume_filter_options':
- ListReceiveVolumeFilterOptionsTool(api_client=api_client),
- 'query_container_timeliness_list': QueryContainerTimelinessListTool(
- api_client=api_client
- ),
- 'export_container_timeliness_report':
- ExportContainerTimelinessReportTool(api_client=api_client),
- 'query_headhaul_document_list': QueryHeadhaulDocumentListTool(
- api_client=api_client
- ),
- 'list_headhaul_document_filter_options':
- ListHeadhaulDocumentFilterOptionsTool(api_client=api_client),
- 'prepare_headhaul_document_upload':
- PrepareHeadhaulDocumentUploadTool(api_client=api_client),
- 'save_headhaul_document': SaveHeadhaulDocumentTool(
- api_client=api_client
- ),
- 'delete_headhaul_document': DeleteHeadhaulDocumentTool(
- api_client=api_client
- ),
- 'list_inbound_receipt_templates': ListInboundReceiptTemplatesTool(
- api_client=api_client
- ),
- 'export_inbound_receipt': ExportInboundReceiptTool(
- api_client=api_client
- ),
- 'query_freightower_track': QueryFreightowerTrackTool(
- api_client=api_client
- ),
- }
- @classmethod
- def from_config(cls, config, redis_client=None):
- if config.token_store_type == 'redis':
- redis = redis_client or RedisSocketClient(
- host=config.redis_host,
- port=config.redis_port,
- db=config.redis_db,
- password=config.redis_password,
- timeout=config.timeout_seconds,
- )
- token_store = RedisTokenStore(
- redis,
- prefix=config.redis_prefix,
- session_key=config.session_key,
- refresh_skew_seconds=config.refresh_skew_seconds,
- )
- elif config.token_store_type == 'file':
- token_store = FileTokenStore(
- config.token_store_path,
- refresh_skew_seconds=config.refresh_skew_seconds,
- )
- else:
- raise ValueError('unsupported token store type: {0}'.format(config.token_store_type))
- auth_client = AuthClient(
- base_url=config.auth_base_url,
- client_type=config.client_type,
- token_store=token_store,
- timeout=config.timeout_seconds,
- session_key=config.session_key,
- )
- api_client = ApiClient(
- base_url=config.tools_base_url,
- token_store=token_store,
- timeout=config.timeout_seconds,
- )
- return cls(
- auth_client=auth_client,
- api_client=api_client,
- token_store=token_store,
- reporter=diagnostic_reporter_from_config(config),
- )
- 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, request_id=''):
- 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(request_id=request_id)
- )
- def list_tools(self, request_id=''):
- request_id = self.build_request_id(request_id)
- enabled = self._load_enabled_tool_names(request_id)
- return [
- tool.metadata()
- for name, tool in self._tools.items()
- if name in enabled
- ]
- def list_resources(self):
- return []
- def read_resource(self, uri, gateway_session_id='local'):
- return None
- def session_for_headhaul_token(self, token):
- return self._headhaul_slots.session_for_token(token)
- def build_request_id(self, request_id=''):
- request_id = str(request_id or '').strip()
- if request_id:
- return request_id
- return 'rq_{0}'.format(uuid.uuid4().hex[:16])
- def ensure_session(self):
- if self.token_store is None:
- return
- session = self.token_store.get()
- if not session or not session.get('token'):
- raise RuntimeError(DEVICE_INVALID_MESSAGE)
- if self.token_store.is_expiring():
- if self.auth_client is None:
- raise RuntimeError('mcp token expiring but auth client missing')
- self.auth_client.refresh(session['token'])
- def call_tool(self, name, arguments=None, request_id=''):
- if name not in self._tools:
- raise KeyError('tool not registered: {0}'.format(name))
- tool = self._tools[name]
- if getattr(tool, 'requires_session', True):
- self.ensure_session()
- request_id = self.build_request_id(request_id)
- if name not in self._load_enabled_tool_names(request_id):
- raise RuntimeError('tool disabled: {0}'.format(name))
- arguments = arguments or {}
- result = tool.call(request_id=request_id, **arguments)
- if name == 'prepare_headhaul_document_upload' and isinstance(result, dict):
- data = result.get('data')
- token = ''
- if isinstance(data, dict):
- token = str(data.get('upload_token') or '').strip()
- if token:
- self._headhaul_slots.remember('local', token)
- return result
- def create_protocol_handler(self):
- return McpProtocolHandler(self, reporter=self.reporter)
- def run_cli(self, argv=None, stdin=None, stdout=None):
- stdin = stdin or sys.stdin
- stdout = stdout or sys.stdout
- parser = argparse.ArgumentParser(prog='mcp-gateway')
- subparsers = parser.add_subparsers(dest='command', required=True)
- subparsers.add_parser('list-tools')
- subparsers.add_parser('serve-stdio')
- public_parser = subparsers.add_parser('serve-public')
- public_parser.add_argument('--host', default='0.0.0.0')
- public_parser.add_argument('--port', type=int, default=8765)
- call_parser = subparsers.add_parser('call')
- call_parser.add_argument('--tool', required=True)
- call_parser.add_argument('--keyword', default='')
- call_parser.add_argument('--sku', default='')
- call_parser.add_argument('--cn-name', default='')
- call_parser.add_argument('--departure-country', default='')
- call_parser.add_argument('--destination-country', default='')
- call_parser.add_argument('--price', type=float, default=0)
- call_parser.add_argument('--qty', type=float, default=0)
- call_parser.add_argument('--gross-weight', type=float, default=0)
- call_parser.add_argument('--box', type=float, default=0)
- call_parser.add_argument('--order-id', type=int, default=0)
- call_parser.add_argument('--order-number', default='')
- call_parser.add_argument('--business-type', type=int, default=0)
- call_parser.add_argument('--section', default='全部')
- call_parser.add_argument('--order-numbers', 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('--bl-number', default='')
- call_parser.add_argument('--bl-numbers', default='')
- call_parser.add_argument('--container-code', default='')
- call_parser.add_argument('--container-codes', default='')
- call_parser.add_argument('--template-code', 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('--customer-id', type=int, default=0)
- call_parser.add_argument('--sub-customer-id', type=int, default=0)
- call_parser.add_argument('--bill-numbers', default='')
- call_parser.add_argument('--business-date-start', default='')
- call_parser.add_argument('--business-date-end', default='')
- call_parser.add_argument('--cost-date-start', default='')
- call_parser.add_argument('--cost-date-end', default='')
- call_parser.add_argument('--operation-date-start', default='')
- call_parser.add_argument('--operation-date-end', default='')
- call_parser.add_argument('--business-node-id', type=int, default=0)
- call_parser.add_argument('--provider-id', type=int, default=0)
- call_parser.add_argument('--cost-type-ids', default='')
- call_parser.add_argument('--billing-status', type=int, default=None)
- call_parser.add_argument('--payment-status', type=int, default=None)
- call_parser.add_argument('--verification-status', type=int, default=None)
- call_parser.add_argument('--document-type', type=int, default=None)
- call_parser.add_argument('--cost-type-id', type=int, default=0)
- call_parser.add_argument('--receive-date-start', default='')
- call_parser.add_argument('--receive-date-end', default='')
- call_parser.add_argument('--sales-id', type=int, default=0)
- call_parser.add_argument('--merchandiser-id', type=int, default=0)
- call_parser.add_argument(
- '--has-unverified-receivable-only',
- choices=('true', 'false'),
- default='true',
- )
- call_parser.add_argument('--warehouse-ids', default='')
- call_parser.add_argument('--warehouse-id', type=int, default=0)
- call_parser.add_argument('--department-id', type=int, default=0)
- call_parser.add_argument('--outbound-status', type=int, default=0)
- call_parser.add_argument('--shipping-method', type=int, default=0)
- call_parser.add_argument('--is-direct-send', type=int, default=None)
- call_parser.add_argument('--trailer-types', default='')
- call_parser.add_argument('--declaration-types', default='')
- call_parser.add_argument('--clearance-types', default='')
- call_parser.add_argument('--closing-time-start', default='')
- call_parser.add_argument('--closing-time-end', default='')
- call_parser.add_argument('--est-loading-time-start', default='')
- call_parser.add_argument('--est-loading-time-end', default='')
- call_parser.add_argument('--create-date-start', default='')
- call_parser.add_argument('--create-date-end', default='')
- call_parser.add_argument('--loading-time-start', default='')
- call_parser.add_argument('--loading-time-end', default='')
- call_parser.add_argument('--inbound-date-start', default='')
- call_parser.add_argument('--inbound-date-end', default='')
- call_parser.add_argument('--inbound-time-start', default='')
- call_parser.add_argument('--inbound-time-end', default='')
- call_parser.add_argument('--departure-time-start', default='')
- call_parser.add_argument('--departure-time-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('--trailer-stage', default='')
- call_parser.add_argument('--abnormal-status', default='')
- call_parser.add_argument('--sales-ids', default='')
- call_parser.add_argument('--merchandiser-ids', default='')
- call_parser.add_argument('--packing-types', default='')
- call_parser.add_argument('--providers-id', type=int, default=0)
- call_parser.add_argument('--bill-status', type=int, default=None)
- call_parser.add_argument('--cabinet-type', type=int, default=0)
- call_parser.add_argument('--eta-start', default='')
- call_parser.add_argument('--eta-end', default='')
- call_parser.add_argument('--pickup-time-start', default='')
- call_parser.add_argument('--pickup-time-end', default='')
- call_parser.add_argument('--container-return-time-start', default='')
- call_parser.add_argument('--container-return-time-end', default='')
- call_parser.add_argument('--task-ref', default='')
- call_parser.add_argument('--page', type=int, default=1)
- call_parser.add_argument('--limit', type=int, default=20)
- call_parser.add_argument('--request-id', default='')
- args = parser.parse_args(argv or [])
- if args.command == 'list-tools':
- payload = self.list_tools()
- elif args.command == 'serve-stdio':
- try:
- return self.create_protocol_handler().run_stdio(
- stdin=stdin,
- stdout=stdout,
- )
- finally:
- self.reporter.close()
- elif args.command == 'serve-public':
- config = GatewayConfig.from_env()
- reporter = self.reporter
- if isinstance(reporter, NullDiagnosticReporter):
- reporter = diagnostic_reporter_from_config(config)
- redis = RedisSocketClient(
- host=config.redis_host,
- port=config.redis_port,
- db=config.redis_db,
- password=config.redis_password,
- timeout=config.timeout_seconds,
- )
- session_store = GatewaySessionStore(
- redis,
- prefix=config.redis_prefix,
- ttl_seconds=config.gateway_session_ttl_seconds,
- )
- public_app = PublicGatewayApp(
- session_store=session_store,
- api_client=ScopedApiClient(config.tools_base_url, timeout=config.timeout_seconds),
- )
- try:
- return serve_public(
- public_app,
- host=args.host,
- port=args.port,
- enable_rate_limit=config.rate_limit_enabled,
- rate_limit_max_requests=config.rate_limit_max_requests,
- rate_limit_window_seconds=config.rate_limit_window_seconds,
- max_in_flight_per_tool=config.max_in_flight_per_tool,
- reporter=reporter,
- )
- finally:
- reporter.close()
- elif args.command == 'call':
- tool_args = {
- 'page': args.page,
- 'limit': args.limit,
- }
- if args.tool == 'query_order':
- if not args.keyword:
- raise ValueError('--keyword is required for query_order')
- tool_args['keyword'] = args.keyword
- elif args.tool == 'query_track':
- if args.order_id > 0:
- tool_args['order_id'] = args.order_id
- if args.order_number:
- tool_args['order_number'] = args.order_number
- if 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:
- 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 == 'query_order_detail':
- if not args.order_number:
- raise ValueError('--order-number is required for query_order_detail')
- tool_args['order_number'] = args.order_number
- tool_args['section'] = args.section
- elif args.tool == 'query_customer_list':
- for field, value in (
- ('customer_id', args.customer_id),
- ('department_id', args.department_id),
- ('sales_id', args.sales_id),
- ('merchandiser_id', args.merchandiser_id),
- ):
- if value > 0:
- tool_args[field] = value
- elif args.tool == 'query_customer_payment_followup':
- for field, value in (
- ('customer_id', args.customer_id),
- ('department_id', args.department_id),
- ('sales_id', args.sales_id),
- ('merchandiser_id', args.merchandiser_id),
- ):
- if value > 0:
- tool_args[field] = value
- tool_args['has_unverified_receivable_only'] = (
- args.has_unverified_receivable_only == 'true'
- )
- elif args.tool == 'query_customer_unverified_bill_details':
- if args.customer_id <= 0:
- raise ValueError(
- '--customer-id is required for query_customer_unverified_bill_details'
- )
- tool_args['customer_id'] = args.customer_id
- elif args.tool == 'query_customer_payment_records':
- if args.customer_id <= 0:
- raise ValueError(
- '--customer-id is required for query_customer_payment_records'
- )
- tool_args['customer_id'] = args.customer_id
- if args.receive_date_start:
- tool_args['receive_date_start'] = args.receive_date_start
- if args.receive_date_end:
- tool_args['receive_date_end'] = args.receive_date_end
- elif args.tool == 'query_order_receivable_cost_details':
- if not args.order_number:
- raise ValueError(
- '--order-number is required for query_order_receivable_cost_details'
- )
- tool_args['order_number'] = args.order_number
- elif args.tool in (
- 'query_payable_cost_list', 'export_payable_cost_list'
- ):
- if args.business_type <= 0:
- raise ValueError(
- '--business-type is required for ' + args.tool
- )
- tool_args['business_type'] = args.business_type
- payable_number_lists = {
- 'order_numbers': args.order_numbers,
- 'tracking_numbers': args.tracking_numbers,
- 'container_codes': args.container_codes,
- 'bl_numbers': args.bl_numbers,
- 'so_numbers': args.so_numbers,
- }
- for field, value in payable_number_lists.items():
- if value:
- tool_args[field] = parse_string_list(value)
- payable_dates = {
- 'business_date_start': args.business_date_start,
- 'business_date_end': args.business_date_end,
- 'cost_date_start': args.cost_date_start,
- 'cost_date_end': args.cost_date_end,
- 'operation_date_start': args.operation_date_start,
- 'operation_date_end': args.operation_date_end,
- }
- for field, value in payable_dates.items():
- if value:
- tool_args[field] = value
- for field, value in (
- ('business_node_id', args.business_node_id),
- ('provider_id', args.provider_id),
- ):
- if value > 0:
- tool_args[field] = value
- if args.cost_type_ids:
- tool_args['cost_type_ids'] = parse_int_list(
- args.cost_type_ids
- )
- for field, value in (
- ('billing_status', args.billing_status),
- ('payment_status', args.payment_status),
- ('verification_status', args.verification_status),
- ('document_type', args.document_type),
- ):
- if value is not None:
- tool_args[field] = value
- if args.tool == 'export_payable_cost_list':
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- elif args.tool == 'query_receivable_cost_list':
- for field, value in (
- ('reference_numbers', args.reference_numbers),
- ('tracking_numbers', args.tracking_numbers),
- ('order_numbers', args.order_numbers),
- ('bill_numbers', args.bill_numbers),
- ):
- if value:
- tool_args[field] = parse_string_list(value)
- for field, value in (
- ('business_date_start', args.business_date_start),
- ('business_date_end', args.business_date_end),
- ):
- if value:
- tool_args[field] = value
- for field, value in (
- ('customer_id', args.customer_id),
- ('sub_customer_id', args.sub_customer_id),
- ('cost_type_id', args.cost_type_id),
- ):
- if value > 0:
- tool_args[field] = value
- for field, value in (
- ('billing_status', args.billing_status),
- ('verification_status', args.verification_status),
- ('document_type', args.document_type),
- ):
- if value is not None:
- tool_args[field] = value
- elif args.tool == 'export_receivable_cost_list':
- for field, value in (
- ('reference_numbers', args.reference_numbers),
- ('tracking_numbers', args.tracking_numbers),
- ('order_numbers', args.order_numbers),
- ('bill_numbers', args.bill_numbers),
- ):
- if value:
- tool_args[field] = parse_string_list(value)
- for field, value in (
- ('business_date_start', args.business_date_start),
- ('business_date_end', args.business_date_end),
- ):
- if value:
- tool_args[field] = value
- for field, value in (
- ('customer_id', args.customer_id),
- ('sub_customer_id', args.sub_customer_id),
- ('cost_type_id', args.cost_type_id),
- ):
- if value > 0:
- tool_args[field] = value
- for field, value in (
- ('billing_status', args.billing_status),
- ('verification_status', args.verification_status),
- ('document_type', args.document_type),
- ):
- if value is not None:
- tool_args[field] = value
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- elif args.tool == 'query_customs_declaration_files':
- if args.outbound_numbers:
- tool_args['outbound_numbers'] = parse_string_list(
- args.outbound_numbers
- )
- if args.order_numbers:
- tool_args['order_numbers'] = parse_string_list(
- args.order_numbers
- )
- elif args.tool == 'query_outbound_list':
- outbound_number_lists = {
- 'outbound_numbers': args.outbound_numbers,
- 'order_numbers': args.order_numbers,
- 'container_codes': args.container_codes,
- 'so_numbers': args.so_numbers,
- 'bl_numbers': args.bl_numbers,
- }
- for field, value in outbound_number_lists.items():
- if value:
- tool_args[field] = parse_string_list(value)
- outbound_mode_lists = {
- 'trailer_types': args.trailer_types,
- 'declaration_types': args.declaration_types,
- 'clearance_types': args.clearance_types,
- }
- for field, value in outbound_mode_lists.items():
- if value:
- tool_args[field] = parse_int_list(value)
- outbound_dates = {
- 'closing_time_start': args.closing_time_start,
- 'closing_time_end': args.closing_time_end,
- 'est_loading_time_start': args.est_loading_time_start,
- 'est_loading_time_end': args.est_loading_time_end,
- 'create_date_start': args.create_date_start,
- 'create_date_end': args.create_date_end,
- 'loading_time_start': args.loading_time_start,
- 'loading_time_end': args.loading_time_end,
- }
- for field, value in outbound_dates.items():
- if value:
- tool_args[field] = value
- if args.outbound_status > 0:
- tool_args['outbound_status'] = args.outbound_status
- if args.shipping_method > 0:
- tool_args['shipping_method'] = args.shipping_method
- if args.warehouse_id == -1 or args.warehouse_id > 0:
- tool_args['warehouse_id'] = args.warehouse_id
- if args.is_direct_send is not None:
- tool_args['is_direct_send'] = args.is_direct_send
- elif args.tool == 'query_outbound_detail':
- if not args.outbound_number:
- raise ValueError(
- '--outbound-number is required for '
- 'query_outbound_detail'
- )
- tool_args['outbound_number'] = args.outbound_number
- elif args.tool == 'export_pallet_data':
- if args.container_codes:
- tool_args['container_codes'] = parse_string_list(
- args.container_codes
- )
- if args.bl_numbers:
- tool_args['bl_numbers'] = parse_string_list(
- args.bl_numbers
- )
- if args.inbound_time_start:
- tool_args['inbound_time_start'] = args.inbound_time_start
- if args.inbound_time_end:
- tool_args['inbound_time_end'] = args.inbound_time_end
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- elif args.tool == 'query_export_task':
- if not args.task_ref:
- raise ValueError(
- '--task-ref is required for query_export_task'
- )
- tool_args = {'task_ref': args.task_ref}
- elif args.tool == 'list_payable_cost_filter_options':
- if not args.filter_type:
- raise ValueError(
- '--filter-type is required for '
- 'list_payable_cost_filter_options'
- )
- tool_args['filter_type'] = args.filter_type
- tool_args['keyword'] = args.keyword
- if args.business_type > 0:
- tool_args['business_type'] = args.business_type
- elif args.tool == 'list_receivable_cost_filter_options':
- if not args.filter_type:
- raise ValueError(
- '--filter-type is required for '
- 'list_receivable_cost_filter_options'
- )
- tool_args['filter_type'] = args.filter_type
- tool_args['keyword'] = args.keyword
- if args.customer_id > 0:
- tool_args['customer_id'] = args.customer_id
- elif args.tool == 'query_destination_trailer_list':
- if not args.trailer_stage:
- raise ValueError(
- '--trailer-stage is required for '
- 'query_destination_trailer_list'
- )
- tool_args['trailer_stage'] = args.trailer_stage
- if args.bl_numbers:
- tool_args['bl_numbers'] = parse_string_list(args.bl_numbers)
- if args.container_codes:
- tool_args['container_codes'] = parse_string_list(
- args.container_codes
- )
- if args.providers_id > 0:
- tool_args['providers_id'] = args.providers_id
- if args.warehouse_id > 0:
- tool_args['warehouse_id'] = args.warehouse_id
- if args.is_direct_send is not None:
- tool_args['is_direct_send'] = args.is_direct_send
- if args.bill_status is not None:
- tool_args['bill_status'] = args.bill_status
- if args.cabinet_type > 0:
- tool_args['cabinet_type'] = args.cabinet_type
- if args.shipping_method > 0:
- tool_args['shipping_method'] = args.shipping_method
- trailer_dates = {
- 'eta_start': args.eta_start,
- 'eta_end': args.eta_end,
- 'pickup_time_start': args.pickup_time_start,
- 'pickup_time_end': args.pickup_time_end,
- 'container_return_time_start':
- args.container_return_time_start,
- 'container_return_time_end':
- args.container_return_time_end,
- }
- for field, value in trailer_dates.items():
- if value:
- tool_args[field] = value
- elif args.tool == 'query_order_abnormal_list':
- if not args.abnormal_status:
- raise ValueError(
- '--abnormal-status is required for '
- 'query_order_abnormal_list'
- )
- tool_args['abnormal_status'] = args.abnormal_status
- if args.order_numbers:
- tool_args['order_numbers'] = parse_string_list(
- args.order_numbers
- )
- elif args.tool == 'trial_goods_tax':
- tool_args['sku'] = args.sku
- tool_args['departure_country'] = args.departure_country
- tool_args['destination_country'] = args.destination_country
- tool_args['price'] = args.price
- tool_args['qty'] = args.qty
- tool_args['gross_weight'] = args.gross_weight
- tool_args['box'] = args.box
- elif args.tool == 'query_goods_info':
- if args.sku:
- tool_args['sku'] = args.sku
- if args.cn_name:
- tool_args['cn_name'] = args.cn_name
- if not args.sku and not args.cn_name:
- raise ValueError(
- '--sku or --cn-name is required for query_goods_info'
- )
- elif args.tool == 'query_receive_volume_list':
- if not args.inbound_date_start or not args.inbound_date_end:
- raise ValueError(
- '--inbound-date-start and --inbound-date-end are '
- 'required for query_receive_volume_list'
- )
- tool_args['inbound_date_start'] = args.inbound_date_start
- tool_args['inbound_date_end'] = args.inbound_date_end
- if args.customer_ids:
- tool_args['customer_ids'] = parse_int_list(args.customer_ids)
- if args.sales_ids:
- tool_args['sales_ids'] = parse_int_list(args.sales_ids)
- if args.merchandiser_ids:
- tool_args['merchandiser_ids'] = parse_int_list(
- args.merchandiser_ids
- )
- if args.packing_types:
- tool_args['packing_types'] = parse_string_list(
- args.packing_types
- )
- if args.product_ids:
- tool_args['product_ids'] = parse_int_list(args.product_ids)
- elif args.tool in (
- 'query_container_timeliness_list',
- 'export_container_timeliness_report',
- ):
- if args.container_codes:
- tool_args['container_codes'] = parse_string_list(
- args.container_codes
- )
- if args.bl_numbers:
- tool_args['bl_numbers'] = parse_string_list(args.bl_numbers)
- if args.departure_time_start:
- tool_args['departure_time_start'] = args.departure_time_start
- if args.departure_time_end:
- tool_args['departure_time_end'] = args.departure_time_end
- if args.tool == 'export_container_timeliness_report':
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- elif args.tool in (
- 'list_inbound_receipt_templates',
- 'export_inbound_receipt',
- ):
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- if not args.container_codes:
- raise ValueError(
- '--container-codes is required for ' + args.tool
- )
- tool_args['container_codes'] = parse_string_list(
- args.container_codes
- )
- if args.tool == 'export_inbound_receipt':
- if not args.template_code:
- raise ValueError(
- '--template-code is required for export_inbound_receipt'
- )
- tool_args['template_code'] = args.template_code
- elif args.tool == 'query_freightower_track':
- tool_args.pop('page', None)
- tool_args.pop('limit', None)
- if args.bl_number:
- tool_args['bl_number'] = args.bl_number
- if args.container_code:
- tool_args['container_code'] = args.container_code
- if not tool_args.get('bl_number') and not tool_args.get('container_code'):
- raise ValueError(
- '--bl-number or --container-code is required for '
- 'query_freightower_track'
- )
- elif args.tool in (
- 'list_order_filter_options', 'list_outbound_filter_options',
- 'list_customer_filter_options',
- 'list_destination_trailer_filter_options',
- 'list_order_abnormal_filter_options',
- 'list_receive_volume_filter_options',
- 'list_headhaul_document_filter_options',
- ):
- if not args.filter_type:
- raise ValueError(
- '--filter-type is required for '
- + args.tool
- )
- tool_args['filter_type'] = args.filter_type
- tool_args['keyword'] = args.keyword
- else:
- if args.keyword:
- tool_args['keyword'] = args.keyword
- payload = self.call_tool(
- args.tool,
- tool_args,
- request_id=args.request_id,
- )
- else:
- raise RuntimeError('unsupported command')
- stdout.write(json.dumps(payload, ensure_ascii=False))
- return 0
- def main(argv=None):
- config = GatewayConfig.from_env()
- app = GatewayApp.from_config(config)
- return app.run_cli(argv=argv)
- if __name__ == '__main__':
- raise SystemExit(main(sys.argv[1:]))
|