该文本是一个Python脚本,旨在通过API与K3Cloud(一种企业管理软件)交互。脚本首先设置了日志格式和文件,然后定义了一个名为`K3CloudWebAPI`的类,用于处理与K3Cloud服务器的通信。这个类包含多个方法:`__init__`用于初始化实例并登录到K3Cloud;`query`用于查询单据数据;`save`用于保存或修改单据数据;`operate`用于对单据执行提交、审核、反审核或删除等操作;`push`用于单据的下推操作。这些方法通过构建HTTP请求并使用`requests`库与K3Cloud服务器交互,通过解析`config.ini`配置文件获取必要的认证和服务器信息。此外,还使用了`json`库来处理JSON数据,以及`logging`库来记录日志。
# coding = utf-8
# By TangRuCheng 2020-12-02
import json
import logging, time, os
import requests
from configparser import ConfigParser
# 格式化日志
log_format = '%(levelname)s %(asctime)s %(message)s'
date_format = '%Y-%m-%d %H:%M:%S'
date = time.strftime('%Y-%m-%d', time.localtime())
file_name = rf'log\{date}.log'
if 'log' not in os.listdir():
os.mkdir('log')
else:
logging.basicConfig(level=logging.INFO,
format=log_format,
datefmt=date_format,
filename=file_name)
class K3CloudWebAPI(object):
def __init__(self):
#读取数据中心的配置参数
config = ConfigParser()
config.read('config.ini')
self.server_ip = config['k3cloud_server']['server_ip']
self. acctid = config['k3cloud_server']['acctid']
self.username = config['k3cloud_server']['username']
self.password = config['k3cloud_server']['password']
self.lcid = config['k3cloud_server']['lcid']
# 构建登录请求参数
login_url = f'http://{self.server_ip}/k3cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc'
login_data = {
'acctId': self.acctid,
'username': self.username,
'password': self.password,
'lcid': self.lcid
}
# 登录k3cloud,并返回cookies;登录超时设置为1分钟
login_response = requests.post(url=login_url, data=login_data, timeout=1000*60*1)
login_text = json.loads(login_response.text)
self.cookies = login_response.cookies
# 判断登录状态
if login_text['IsSuccessByAPI'] is True:
self.login_result = '登录成功'
logging.info('登录成功') # 记录登录日志
else:
self.login_result = '登录失败'
logging.warning(login_text) # 记录登录日志
def query(self, form_id, field_keys='', filter_strings='', order_string='', start_row=0, limit=0):
"""
查询单据
:param form_id:业务对象表单Id(必录)
:param field_keys:需查询的字段key集合,字符串类型,格式:"key1,key2,..."(必录) 注(查询单据体内码,需加单据体Key和下划线,如:FEntryKey_FEntryId)
:param filter_strings:过滤条件,字符串类型(非必录),内容格式参照sql语法的where子句
:param order_string:排序字段,字符串类型(非必录),内容格式参照sql语法的order子句
:param start_row:开始行索引,整型(非必录)
:param limit:最大行数,整型,不能超过2000(非必录)
:return:返回结果单据数据
"""
# 构建查询请求的参数
query_url = f'http://{self.server_ip}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc'
data = json.dumps({
'FormId': form_id,
'FieldKeys': field_keys,
'FilterString': filter_strings,
'OrderString': order_string,
'StartRow': start_row,
'Limit': limit
}) # 编码json对象
post_data = {'data': data}
# 查询数据,并返回查询结果
query_response = json.loads(requests.post(url=query_url, data=post_data, cookies=self.cookies).text)
return query_response
def save(self, form_id, bill_head, body_name='', body_data=[{}], need_return_fields=[],
is_delete_entry=False, interation_flags='', is_auto_adjust_field=True, is_auto_submit_and_audit=True, is_draft=False):
"""
1、开发接口过程中先构建表头;然后指定表体名称,构建表体数据;然后调用该方法,就可以保存数据
2、如果是修改数据,那么body_data明细行数据里的字段指定下行内码
:param form_id:业务对象表单Id
:param bill_head:表头名称
:param body_name:表体名称
:param body_data:表体明细行数据
:param need_return_fields:需返回结果的字段集合,数组类型,格式:[key,entitykey.key,...](非必录) 注(返回单据体字段格式:entitykey.key)
:param is_delete_entry:是否删除已存在的分录,布尔类型,默认True(非必录
:param interation_flags:交互标志集合,字符串类型,分号分隔,格式:"flag1;flag2;..."(非必录) 例如(允许负库存标识:STK_InvCheckResult)
:param is_auto_adjust_field: 是否自动调整JSON字段顺序,设置成True
:param is_auto_submit_and_audit:是否自动提交、审核,这里传值默认是True
:param is_draft:是否暂存,用于判断接口地址
:return:
"""
# 默认是保存接口地址,如果is_Draft为True则为暂存接口地址
operate = 'Save'
if is_draft:
operate = 'Draft'
save_url = f'http://{self.server_ip}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.{operate}.common.kdsvc' # 默认是保存接口地址,Draft是暂存
# 构建表单数据
model = bill_head # 先赋值给Model
model.update({body_name: body_data})
data = json.dumps({
'NeedReturnFields': need_return_fields,
'IsDeleteEntry': is_delete_entry,
'InterationFlags': interation_flags,
'IsAutoAdjustField': is_auto_adjust_field,
'IsAutoSubmitAndAudit': is_auto_submit_and_audit,
'Model': model
}) # 编码json对象
post_data = {
'formid': form_id,
'data': data
} # 构建请求data参数
# 保存数据,接受返回信息
save_response = json.loads(requests.post(url=save_url, data=post_data, cookies=self.cookies).text)
return save_response
def operate(self, form_id, numbers, operate_type):
"""
根据operate_type传递的值,判断是提交、审核、反审核、删除中的哪一个操作类型;并且操作单据,
:param form_id:单据类型
:param numbers:单据编号,传列表
:param operate_type:传参:'提交'、'审核'、'反审核'、'删除'
:return:
"""
operate_dict = {
'提交': 'Submit',
'审核': 'Audit',
'反审核': 'UnAudit',
'删除': 'Delete'
}
operate_url = f'http://{self.server_ip}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.{operate_dict[operate_type]}.common.kdsvc' # 操作类型对应的服务地址
data = json.dumps({'Numbers': numbers})
post_data = {
'formid': form_id,
'data': data
}
# 操作数据
operate_response = json.loads(requests.post(url=operate_url, data=post_data, cookies=self.cookies).text)
return operate_response
def push(self, form_id, numbers=[], entry_ids='', rule_id='',
target_bill_type_id='', farget_form_id='', is_enable_default_rule=True, is_draft_when_save_fail=True):
"""
单据下推
:param form_id:业务对象表单Id,字符串类型(必录)
:param numbers:单据编码集合,数组类型,格式:[No1,No2,...](使用编码时必录)
:param entry_ids:分录内码集合,逗号分隔(分录下推时必录) 注(按分录下推时,单据内码和编码不需要填,否则按整单下推)
:param rule_id:转换规则内码,字符串类型(未启用默认转换规则时,则必录)
:param target_bill_type_id:目标单据类型内码,字符串类型(非必录)
:param farget_form_id:目标单据FormId,字符串类型,(启用默认转换规则时,则必录)
:param is_enable_default_rule:是否启用默认转换规则,布尔类型,默认传值是启用的
:param is_draft_when_save_fail:保存失败时是否暂存,布尔类型
:return:
"""
push_url = f'http://{self.server_ip}/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Push.common.kdsvc'
# 构建JSON数据
data = json.dumps(
{
'Ids': '',
'Numbers': numbers,
'EntryIds': entry_ids,
'RuleId': rule_id,
'TargetBillTypeId': target_bill_type_id,
'TargetOrgId': 0,
'TargetFormId': farget_form_id,
'IsEnableDefaultRule': is_enable_default_rule,
'IsDraftWhenSaveFail': is_draft_when_save_fail,
'CustomParams': {}
}
)
push_data = {
'formid': form_id,
'data': data
}
# 进行下推
push_response = json.loads(requests.post(url=push_url, data=push_data, cookies=self.cookies).text)
# 返回下推保存成功之后的明细数据
return push_response