class QueryCustomerPaymentFollowupTool: name = 'query_customer_payment_followup' route_path = '/mcp/tools/queryCustomerPaymentFollowup' def __init__(self, api_client=None): self.api_client = api_client def metadata(self): positive_id = {'type': 'integer', 'minimum': 1} return { 'name': self.name, 'description': ( '查询当前员工有权查看的客户回款跟进数据,包括已出账未核销、未出账、' '逾期、坏账、收款单未核销、余额、信用额度和按应收月份聚合的未回款汇总。客户、事业部、' '商务经理和客户经理ID必须先调用list_customer_filter_options取得。公司、员工、' '菜单权限和数据范围由当前设备会话确定,调用方不得覆盖。用户要求展开某客户时,' '使用同一客户ID调用query_customer_unverified_bill_details并跟随分页。最终回复必须逐条完整' '展示所有客户、全部字段和月份汇总,不得摘要、隐藏、重命名或省略。' ), 'input_schema': { 'type': 'object', 'properties': { 'customer_id': dict(positive_id), 'department_id': dict(positive_id), 'sales_id': dict(positive_id), 'merchandiser_id': dict(positive_id), 'has_unverified_receivable_only': { 'type': 'boolean', 'default': True, }, 'page': { 'type': 'integer', 'minimum': 1, 'maximum': 100, 'default': 1, }, 'limit': { 'type': 'integer', 'minimum': 1, 'maximum': 100, 'default': 20, }, }, 'required': [], 'additionalProperties': False, }, } def call( self, customer_id=None, department_id=None, sales_id=None, merchandiser_id=None, has_unverified_receivable_only=True, page=1, limit=20, request_id='rq_query_customer_payment_followup', ): if self.api_client is None: raise RuntimeError( 'api client is required for query_customer_payment_followup' ) payload = { 'page': self._bounded_integer(page, 'page'), 'limit': self._bounded_integer(limit, 'limit'), 'has_unverified_receivable_only': self._strict_boolean( has_unverified_receivable_only, 'has_unverified_receivable_only', ), } for field, value in ( ('customer_id', customer_id), ('department_id', department_id), ('sales_id', sales_id), ('merchandiser_id', merchandiser_id), ): if value is not None: payload[field] = self._positive_integer(value, field) return self.api_client.call_tool( self.name, self.route_path, payload, request_id ) @staticmethod def _positive_integer(value, field): if isinstance(value, bool) or not isinstance(value, int) or value < 1: raise ValueError('{0} is invalid'.format(field)) return value @classmethod def _bounded_integer(cls, value, field): value = cls._positive_integer(value, field) if value > 100: raise ValueError('{0} is invalid'.format(field)) return value @staticmethod def _strict_boolean(value, field): if not isinstance(value, bool): raise ValueError('{0} is invalid'.format(field)) return value