最新代码


谢田波
阿里波波 发布于 2025-01-24 / 20 阅读 / 0 评论 /
import os import requests import json import math import time import sqlite3 import hashlib from datetime import datetime from json im
import os  
import requests  
import json  
import math  
import time  
import sqlite3  
import hashlib  
from datetime import datetime  
from json import dumps, loads  
from urllib.parse import urlencode  
from k3cloud_webapi_sdk.main import K3CloudApiSdk  
  
  
# 客如云常量  
BASE_URL = "https://openapi.keruyun.com"  
APP_KEY = '45c9f979da976e5f63af39f70a24ff00'  
APP_SECRET = 'd9871c47632948c11587b4203f496f24'  
BRAN_ID = '34812143'  
TOKEN = '5c61d3a18a713b008ff123f06e087315'  
DB_FILE = r'E:\项目工程\始运-办公自动化\客如云_数据同步\数据文件\kry_sync_data.db'  
  
  
# 税账  
api_sdk_sz = K3CloudApiSdk()  
api_sdk_sz.InitConfig('6453905b9418d9',  
                   'demo1',  
                   '272565_ScaN1csJ4nlUW9wK0dXtUYyE5M6b2KkO',  
                   '92d7536dafd14faaad5d26452ccecbda',  
                   'http://8.134.13.55:8090/k3cloud',       # 私有云填写  
                   2052,                                    # 私有云填写  
                   100)                                     # 私有云填写  
  
  
# 经营  
api_sdk_jy = K3CloudApiSdk()  
api_sdk_jy.InitConfig('627b29a99c6162',  
                   'demo1',  
                   '229496_XZ6N4ZsL4Jk+3VTu53RAUY8t0qxVxBoI',  
                   '81d9155cf1a647f6b62173b14efb2f04',  
                   'http://8.134.13.55:8090/k3cloud',       # 私有云填写  
                   2052,                                    # 私有云填写  
                   100)       
  
  
# 客如云访问处理  
def create_sign(appKey, shopIdenty=None, brandId=None, timestamp=None, version='2.0', body=None):  
    """创建签名"""  
    # 准备参数  
    # if body is None:  
    params = {  
        'appKey': appKey,  
        'brandId': BRAN_ID,  
        'version': version,  
        'timestamp': timestamp,  
    }  
      
    # 根据情况添加shopIdenty或brandId  
    if shopIdenty:  
        params['shopIdenty'] = str(shopIdenty)  
    elif brandId:  
        params['brandId'] = str(brandId)  
      
    # 排序并拼接公共参数  
    sorted_params = ''.join([f"{k}{params[k]}" for k in sorted(params)])  
      
    # 拼接body(如果有)  
    body_str = ''  
    if body:  
        body_str = json.dumps(body, separators=(',', ':'))  
      
        # 最终拼接字符串  
        sign_str = f"{sorted_params}body{body_str}{TOKEN}"  
    else:  
        sign_str = f"{sorted_params}{body_str}{TOKEN}"  
 # SHA-256加密  
    sign = hashlib.sha256(sign_str.encode()).hexdigest()  
  
    return sign  
  
  
def call_api(endpoint, appKey, shopIdenty=None, brandId=None, body=None):  
    """调用API"""  
    timestamp = int(time.time() * 1000)  
    sign = create_sign(appKey, shopIdenty, brandId, timestamp, body=body)  
      
    # 构建请求URL  
    url = f"{BASE_URL}{endpoint}?appKey={appKey}"  
    if shopIdenty:  
        url += f"&shopIdenty={shopIdenty}"  
    elif brandId:  
        url += f"&brandId={brandId}"  
        url += f"&version=2.0&timestamp={timestamp}&sign={sign}"  
    # 发送POST请求  
    response = requests.post(  
        url=url,  
        headers={'Content-Type': 'application/json'},  
        data=json.dumps(body, separators=(',', ':')) if body else None  
    )  
    return response.json()  
  
  
def create_sign_shop(appKey, shopIdenty=None, token=None, timestamp=None, version='2.0', body=None):  
    params = {  
        'appKey': appKey,  
        'shopIdenty': shopIdenty,  
        'version': version,  
        'timestamp': timestamp,  
    }  
    # 排序并拼接公共参数  
    sorted_params = ''.join([f"{k}{params[k]}" for k in sorted(params)])  
    body_str = ''  
    if body:  
        body_str = json.dumps(body, separators=(',', ':'))  
        sign_str = f"{sorted_params}body{body_str}{token}"  
    else:  
        sign_str = f"{sorted_params}{body_str}{token}"  
    sign = hashlib.sha256(sign_str.encode()).hexdigest()  
    return sign  
  
  
def call_api_shop(endpoint, appKey, shopIdenty=None, body=None):  
    """调用API"""  
    timestamp = int(time.time() * 1000)  
    token = get_token(shopIdenty)  
    sign = create_sign_shop(appKey, shopIdenty, token, timestamp, body=body)  
      
    # 构建请求URL  
    url = f"{BASE_URL}{endpoint}?appKey={appKey}"  
    url += f"&shopIdenty={shopIdenty}"  
    url += f"&version=2.0&timestamp={timestamp}&sign={sign}"  
    # 发送POST请求  
    response = requests.post(  
        url=url,  
        headers={'Content-Type': 'application/json'},  
        data=json.dumps(body, separators=(',', ':')) if body else None  
    )  
    return response.json()  
  
  
def get_token(shop_id):  
    appKey = APP_KEY  
    shopIdenty = shop_id       # 门店ID  
    version = '2.0'               # 版本号  
    timestamp = int(time.time())  # 当前时间戳(单位:秒)  
    token = APP_SECRET            # 令牌  
  
    # 拼接字符串  
    sign_string = f"appKey{appKey}shopIdenty{shopIdenty}timestamp{timestamp}version{version}{token}"  
    # 计算SHA256哈希值  
    sign = hashlib.sha256(sign_string.encode()).hexdigest()  
  
    # 构建查询字符串  
    params = {  
        'appKey': appKey,  
        'shopIdenty': shopIdenty,  
        'version': version,  
        'timestamp': timestamp,  
        'sign': sign  
    }  
    query_string = urlencode(params)  
    # 完整的请求URL  
    uri = '/open/v1/token/get'  
    request_url = f'{BASE_URL}{uri}?{query_string}'  
    # 发送GET请求  
    response = requests.get(request_url)  
  
    req = loads(response.text)  
    shop_token = req['result']['token']  
    return shop_token  
  
  
def get_pay_info(shop_no, bill_id):  
    uri = '/open/standard/order/queryDetail'  
    body = {  
        "orderId": bill_id  
    }  
    pay_types = []  
    # 获取支付成功、退款成功的数据  
    try:  
        response = call_api_shop(uri, APP_KEY, shopIdenty=shop_no, body=body)  
        payments = response['result']['data']['openPaymentDetailVoList']  
        if len(payments) == 1:  
            if 'PAY_SUCCESS' in payments[0]['payDetailStatus']:  
                pay_types = [payments[0]['payMethodName']]  
                flag = 0  
            if 'REFUND_SUCCESS' in payments[0]['payDetailStatus']:  
                pay_types = [payments[0]['payMethodName']]  
                flag = 1  
        else:  
            for payment in payments:  
                if 'PAY_SUCCESS' in payment['payDetailStatus']:  
                    pay_type = payment['payMethodName'] + ':' + str(float(payment['actualReceiveAmt']) / 100)  
                    pay_types.append(pay_type)  
                elif 'REFUND_SUCCESS' in payment['payDetailStatus']:  
                    pay_type = payment['payMethodName'] + ':' + str(-1*float(payment['actualReceiveAmt']) / 100)  
                    pay_types.append(pay_type)  
                else:  
                    continue  
            pay_types = [','.join(pay_types)]  
            flag = 0  
    except Exception as e:  
        pay_types = ['无支付方式']  
        flag = 0  
    return flag, pay_types[0]  
  
  
# 消息通知  
def wx_notice(message):  
    wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=2fcb776f-5216-4381-a03a-683fdc8d4270'  
    data = {  
        "msgtype": "text",  
        "text": {  
            "content": message,  
            "mentioned_list": [],  # 需@人的姓名  
            "mentioned_mobile_list": []  # 需@人的手机号  
        }  
    }  
    requests.post(url=wx_url, json=data)  
  
  
# 金蝶单据处理  
def add_bill(flag, doctpye, table, save_data):  
    """  
    :param doctpye:     业务名称  
    :param table:       表名  
    :param save_data:   json数据  
    :return:            单据内码、单据编号  
    """    # 保存  
    if flag == 'SZ':  
        api_sdk = api_sdk_sz  
    else:  
        api_sdk = api_sdk_jy  
          
    dataPara = api_sdk.Save(table, save_data)  
    dataPara = json.loads(dataPara)  
    retInfo = list(list(dataPara.values())[0].values())[0]  
    respcode = retInfo['IsSuccess']  
    if respcode:  
        billNo = retInfo['SuccessEntitys'][0]["Number"]  
        ret_info = "E0000-【{}】-单号[{}]创建成功!".format(doctpye, billNo)  
        # # 暂不提交和审核  
        # # 提交  
        # res_data = api_sdk.Submit(table, {"Numbers": [billNo]})  
        # res_data = json.loads(res_data)        # info = list(list(res_data.values())[0].values())[0]        # respcode = info['IsSuccess']        # if respcode:        #     ret_info = "E0000-【{}】-单号[{}]提交成功!".format(doctpye, billNo)  
        #     # 审核  
        #     res_data = api_sdk.Audit(table, {"Numbers": [billNo]})  
        #     res_data = json.loads(res_data)        #     info = list(list(res_data.values())[0].values())[0]        #     respcode = info['IsSuccess']        #     if respcode:        #         ret_info = "E0000-【{}】-单号[{}]已审核!".format(doctpye, billNo)  
    else:  
        respdesc = retInfo['Errors'][0]['Message']  
        ret_info = "E0009-同步{}失败,失败原因:{}".format(doctpye, respdesc)  
        if '唯一' in ret_info:  
            pass  
        else:  
            msg_info = '金蝶云星空:{}'.format(ret_info)  
            wx_notice(msg_info)  
    return ret_info  
  
  
def get_kingdee_supply(flag, org_id, supply_name):  
    """  
    :param org_id:    :param cust_name:    :return:  
    """    if flag == 'SZ':  
        api_sdk = api_sdk_sz  
    else:  
        api_sdk = api_sdk_jy  
  
    table = "BD_Supplier"  # 供应商资料  
    data = {  
        "FormId": table,  
        "FieldKeys": "FNumber, FName",  
        "FilterString": [{"Left": "(", "FieldName": "FName", "Compare": "=", "Value": supply_name, "Right": ")",  
                          "Logic": "AND"},  
                         {"Left": "(", "FieldName": "FUseOrgId.FNumber", "Compare": "=", "Value": org_id, "Right": ")",  
                          "Logic": ""}],  
        "OrderString": "",  
        "TopRowCount": 0,  
        "StartRow": 0,  
        "Limit": 10,  
        "SubSystemId": ""  
    }  
    dataPara = api_sdk.ExecuteBillQuery(data)  
    dataPara = json.loads(dataPara)  
  
    if len(dataPara) == 0:  
        supply_info = {}  
    else:  
        supply_info = {  
            'supply_no': dataPara[0][0],  
            'supply_name': dataPara[0][1],  
        }  
    return supply_info  
  
  
def get_kingdee_wl(flag, org_id, wl_name):  
    """  
    :param org_id:    :param cust_name:    :return:  
    """    if flag == 'SZ':  
        api_sdk = api_sdk_sz  
    else:  
        api_sdk = api_sdk_jy  
  
    table = "BD_MATERIAL"  # 物料  
  
    data = {  
        "FormId": table,  
        "FieldKeys": "FNumber, FName",  
        "FilterString": [{"Left": "(", "FieldName": "FName", "Compare": "=", "Value": wl_name, "Right": ")",  
                          "Logic": "AND"},  
                         {"Left": "(", "FieldName": "FUseOrgId.FNumber", "Compare": "=", "Value": org_id, "Right": ")",  
                          "Logic": ""}],  
        "OrderString": "",  
        "TopRowCount": 0,  
        "StartRow": 0,  
        "Limit": 10,  
        "SubSystemId": ""  
    }  
    dataPara = api_sdk.ExecuteBillQuery(data)  
    dataPara = json.loads(dataPara)  
  
    if len(dataPara) == 0:  
        wl_info = {}  
    else:  
        wl_info = {  
            'wl_no': dataPara[0][0],  
            'wl_name': dataPara[0][1],  
        }  
    return wl_info  
  
  
def save_ysd(flag, org_id, bill_no, bill_date, cust_no, remark, details):  
    """  
    :param bill_no:    :param org_id:    :param cust_no:    :param bill_date:    :param remark:    :param details:    :return:  
    """    post_data = {  
        "Model": {  
            "FBillTypeID": {  
                "FNUMBER": "YSD01_SYS"  
            },  
            "FBillNo": bill_no,  
            "FDATE": bill_date,  
            "FCUSTOMERID": {  
                "FNumber": cust_no  # 客户代码  
            },  
            "FCURRENCYID": {  
                "FNumber": "PRE001"  
            },  
            "FSETTLEORGID": {  
                "FNumber": org_id  
            },  
            "FPAYORGID": {  
                "FNumber": org_id  
            },  
            "FSALEORGID": {  
                "FNumber": org_id  
            },  
  
            "F_TLWD_Assistant": {  
                "FNumber": cust_no  
            },  
            "F_TLWD_Text": bill_no,  
            "FISTAX": True,  
            "FCancelStatus": "A",  
            "FSetAccountType": "3",  
            "FAR_Remark": remark,  
            "FEntityDetail": details  
        }  
    }  
    # 保存单据  
    ret_info = add_bill(flag, "应收单", "AR_receivable", post_data)  
    return ret_info  
  
  
# 应付单  
def save_yfd(flag, org_id, bill_no, bill_date, supply_no, remark, details):  
    post_data = {  
        "Model": {  
            "FID": 0,  
            "FBillTypeID": {  
                "FNUMBER": "YFD01_SYS"  
            },  
            "FBillNo": bill_no,  
            "FISINIT": False,  
            "FDATE": bill_date,  
            "FDOCUMENTSTATUS": "Z",  
            "FSUPPLIERID": {  
                "FNumber": supply_no  
            },  
            "FCURRENCYID": {  
                "FNumber": "PRE001"  
            },  
            "FISPRICEEXCLUDETAX": True,  
            "FBUSINESSTYPE": "CG",  
            "FISTAX": True,  
            "FSETTLEORGID": {  
                "FNumber": org_id  
            },  
            "FPAYORGID": {  
                "FNumber": org_id  
            },  
            "FSetAccountType": "1",  
            "FISTAXINCOST": False,  
            "FISHookMatch": False,  
            "FCancelStatus": "A",  
            "FISBYIV": False,  
            "FISGENHSADJ": False,  
            "FISINVOICEARLIER": False,  
            "FWBOPENQTY": False,  
            "FIsGeneratePlanByCostItem": False,  
            "FsubHeadSuppiler": {  
                "FORDERID": {  
                    "FNumber": supply_no  
                },  
                "FTRANSFERID": {  
                    "FNumber": supply_no  
                },  
                "FChargeId": {  
                    "FNumber": supply_no  
                },  
            },  
            "FEntityDetail": details  
        }  
    }  
    # 保存单据  
    ret_info = add_bill(flag, "应付单", "AP_Payable", post_data)  
    return ret_info  
  
  
# 数据库处理  
def insert_cgrk_data(curr_obj, ins_data):  
    """  
    :param curr_obj:    :param ins_data:    :return:  
    """    bill_no = ins_data['bill_no']  
    bill_status = ins_data['bill_status']  
    shop_no = ins_data['shop_no']  
    shop_name = ins_data['shop_name']  
    org_id = ins_data['org_id']  
    org_name = ins_data['org_name']  
    supply_no = ins_data['supply_no']  
    supply_name = ins_data['supply_name']  
    bill_type= ins_data['bill_type']  
    buss_date= ins_data['buss_date']  
    purchase_date = ins_data['purchase_date']  
    total_amt= ins_data['total_amt']  
    total_amt_notax  = ins_data['total_amt_notax']  
    remarks = ins_data['remarks']  
    created_time = time.strftime('%Y-%m-%d', time.localtime())  
    updated_time = time.strftime('%Y-%m-%d', time.localtime())  
    sz_data_status = 'E0000'  
    sz_data_status_desc = '待同步'  
    jy_data_status = 'E0000'  
    jy_data_status_desc = '待同步'  
  
    entities = (bill_no,bill_status,shop_no,shop_name,org_id, org_name, supply_no, supply_name,bill_type,buss_date,  
                purchase_date,total_amt,total_amt_notax,remarks,created_time,  
                updated_time,sz_data_status,sz_data_status_desc, jy_data_status, jy_data_status_desc)  
      
    try:  
        curr_obj.execute("""INSERT INTO kry_cgdd (bill_no,bill_status,shop_no,shop_name,org_id,org_name,supply_no,supply_name,bill_type,   
                         buss_date,purchase_date,total_amt,total_amt_notax,remarks,created_time,updated_time,sz_data_status,  
                         sz_data_status_desc, jy_data_status, jy_data_status_desc) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", entities)  
    except BaseException as e:  
        if 'UNIQUE constraint' in str(e):  
            print("有重复数据:[{}] {}".format(e, bill_no))  
        else:  
            print("登记数据异常:[{}]".format(e))  
        return False  
    return True  
  
def modify_cgdd_data(curr_obj, flag, bill_no, order_status, order_status_desc):  
    """  
    :param curr_obj:    :param order_no:    :param order_status:    :param order_status_desc:    :return:  
    """    try:  
        if flag == 'SZ':  
            curr_obj.execute("UPDATE kry_cgdd SET sz_data_status=?, sz_data_status_desc=? WHERE bill_no=?",  
                             (order_status, order_status_desc, bill_no))  
        else:  
            curr_obj.execute("UPDATE kry_cgdd SET jy_data_status=?, jy_data_status_desc=? WHERE bill_no=?",  
                             (order_status, order_status_desc, bill_no))  
    except BaseException as e:  
        print("更新数据失败:{} ".format(e))  
        return False  
    return True  
  
def insert_xsdd_data(curr_obj, ins_data):  
    """  
    :param curr_obj:    :param ins_data:    :return:  
    """    shop_no = ins_data['shop_no']  
    shop_name = ins_data['shop_name']  
    org_id = ins_data['org_id']  
    org_name = ins_data['org_name']  
    cust_no = ins_data['cust_no']  
    order_id = ins_data['order_id']  
    busi_order_no = ins_data['busi_order_no']  
    order_status = ins_data['order_status']  
    order_type = ins_data['order_type']  
    pay_type = ins_data['pay_type']  
    order_amt = ins_data['order_amt']  
    promo_amt = ins_data['promo_amt']  
    order_received_amt = ins_data['order_received_amt']  
    open_time = ins_data['open_time']  
    finish_time = ins_data['finish_time']  
    third_order_no = ins_data['third_order_no']  
    serial_no = ins_data['serial_no']  
    third_serial_no = ins_data['third_serial_no']  
    created_time = time.strftime('%Y-%m-%d', time.localtime())  
    updated_time = time.strftime('%Y-%m-%d', time.localtime())  
  
    if pay_type == '无支付方式':  
        sz_data_status = 'E0003'  
        sz_data_status_desc = '不同步'  
        jy_data_status = 'E00003'  
        jy_data_status_desc = '不同步'  
    else:  
        sz_data_status = 'E0000'  
        sz_data_status_desc = '待同步'  
        jy_data_status = 'E0000'  
        jy_data_status_desc = '待同步'  
  
    entities = (shop_no,shop_name,org_id,org_name,cust_no,order_id,busi_order_no,  
                order_status,order_type,pay_type, order_amt,promo_amt,order_received_amt,  
                open_time,finish_time,third_order_no,serial_no,third_serial_no,created_time,updated_time,   
                sz_data_status, sz_data_status_desc,   
                jy_data_status, jy_data_status_desc)  
      
    try:  
        curr_obj.execute("""INSERT INTO kry_xsdd (shop_no,shop_name,org_id,org_name,cust_no,order_id,busi_order_no,order_status,  
                         order_type,pay_type, order_amt,promo_amt,order_received_amt,open_time,finish_time,                         third_order_no,serial_no,third_serial_no,created_time,updated_time, sz_data_status,                         sz_data_status_desc, jy_data_status, jy_data_status_desc)                         VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""", entities)  
    except BaseException as e:  
        if 'UNIQUE constraint' in str(e):  
            print("有重复数据:[{}] {}".format(e, order_id))  
        else:  
            print("登记数据异常:[{}]".format(e))  
        return False  
    return True  
  
def modify_xsdd_data(curr_obj, flag, bill_no, order_status, order_status_desc):  
    """  
    :param curr_obj:    :param order_no:    :param order_status:    :param order_status_desc:    :return:  
    """    try:  
        if flag == 'SZ':  
            curr_obj.execute("UPDATE kry_xsdd SET sz_data_status=?, sz_data_status_desc=? WHERE busi_order_no=?",  
                             (order_status, order_status_desc, bill_no))  
        else:  
            curr_obj.execute("UPDATE kry_xsdd SET jy_data_status=?, jy_data_status_desc=? WHERE busi_order_no=?",  
                             (order_status, order_status_desc, bill_no))  
    except BaseException as e:  
        print("更新数据失败:{} ".format(e))  
        return False  
    return True  
  
def get_shop_info(shop_no):  
    conn = sqlite3.connect(DB_FILE)  
    curr = conn.cursor()  
    query = """ SELECT shop_name, kingdee_org_code, kingdee_org_name FROM shop_para WHERE shop_id = ? """   
val = (shop_no,)  
    curr.execute(query, val)  
    # 获取查询结果  
    rows = curr.fetchall()  
    shop_info = {"shop_name": rows[0][0], "org_id": rows[0][1], "org_name": rows[0][2]}  
    curr.close()  
    conn.close()  
    return shop_info  
      
  
# 采购入库查询  
def get_cgrk_data(shop_no, start_date, end_date):  
    shop = get_shop_info(shop_no)  
    shop_name = shop['shop_name']  
    org_id = shop['org_id']  
    org_name = shop['org_name']  
      
    ## 获取总记录数  
    body = {  
        "orgType": 2,  
        "orgId": shop_no,  
        "page": 1,  
        "rows": 100,  
        "billType": 912,  
        "billStatusList": [  
            962  
        ],  
        "updateTimeStart": start_date,  
        "updateTimeEnd": end_date,  
    }  
      
    uri = '/open/standard/procurement/supply/purchase/open/standard/purchase/in/list'  
    response = call_api(uri, APP_KEY, brandId=BRAN_ID, body=body)  
    res_code = response['result']['serverCode']  
    res_msg = response['result']['messageId']  
  
    if res_code != 10000:  
        msg = f'【客如云[{shop_name}]】:[{start_date}~{end_date}]没有采购入库数据!'  
        wx_notice(msg)  
        return   
      
total = response['result']['data']['total']  
    total_row = math.ceil(total/100)  
    conn = sqlite3.connect(DB_FILE)  
    curr_obj = conn.cursor()  
      
    # 循环读取数据  
    page = 1  
    while page < total_row:    
        body = {  
            "orgType": 2,  
            "orgId": shop_no,  
            "bizDateStart": start_date,  
            "bizDateEnd": end_date,  
            "page": page,  
            "rows": 100,  
            "billType": 912,  
            "billStatusList": [  
                962  
            ]  
        }  
        # 调用API  
        response = call_api(uri, APP_KEY, brandId=BRAN_ID, body=body)  
        res_code = response['result']['serverCode']  
        res_msg = response['result']['messageId']  
        total = response['result']['data']['total']  
        total_row = math.ceil(total/100)  
        if res_code != 10000:  
            break  
  
        page += 1  
        lists = response['result']['data']['list']  
        if len(lists) == 0:  
            break  
  
        for list in lists:  
            bill_no = list['billNo']  
            bill_status = list['billStatus']  
            supply_name = list['supplyName']  
            bill_type = list['billType']  
            buss_date = list['bussDate']  
            purchase_date = list['purchaseDate']  
            total_amt = list['totalAmt']  
            total_amt_notax = list['totalAmtNotax']  
            remarks = list['remarks']  
              
             
            ins_data = {  
                'bill_no': bill_no,  
                'bill_status': bill_status,  
                "shop_no": shop_no,                         # 门店ID  
                "shop_name": shop_name,                     # 门店名称  
                "org_id": org_id,                           # 组织ID  
                "org_name": org_name,                       # 组织名称  
                "supply_no": '',  
                'supply_name': supply_name,  
                'bill_type': bill_type,  
                'buss_date': buss_date,  
                'purchase_date': purchase_date,  
                'total_amt': total_amt,  
                'total_amt_notax': total_amt_notax,  
                'remarks': remarks,  
            }  
            # 插入数据到数据库  
            insert_cgrk_data(curr_obj, ins_data)  
            conn.commit()       
        conn.commit()  
    curr_obj.close()  
    conn.close()  
      
    # 通知客户企业微信群  
    msg = f'【客如云[{shop_name}]】:[{start_date}~{end_date}]采购入库获取完成!'  
  
    wx_notice(msg)  
  
  
def tokd_cgdd_sync(flag, shop_no, start_date, end_date):  
    """  
    :return:  
    """    conn = sqlite3.connect(DB_FILE)  
    curr = conn.cursor()  
    if flag == 'SZ':  
        query = """ select org_id, bill_no, supply_name, buss_date, total_amt, remarks from kry_cgdd   
                where shop_no=? and buss_date>=? and buss_date<=? and sz_data_status in ('E0000', 'E0009') """  
    else:  
        query = """ select org_id, bill_no, supply_name, buss_date, total_amt, remarks from kry_cgdd   
                where shop_no=? and buss_date>=? and buss_date<=? and jy_data_status in ('E0000', 'E0009') """  
  
    val = (shop_no, start_date, end_date,)  
    curr.execute(query, val)  
  
    # 获取查询结果  
    rows = curr.fetchall()  
  
    # 打印查询结果  
    cnt = 0  
    if 0 == len(rows):  
        wx_notice(f"客如云[{shop}]->金蝶[{flag}]账套:应付处理[{start_date}至{end_date}]-未查询到需要同步的异常数据!!")  
        curr.close()  
        conn.close()  
        return  
    for row in rows:  
        org_id = row[0]  
        bill_no = row[1]  
        supply_name = row[2]  
        bill_date = row[3]  
        total_amt = row[4]  
        remarks = row[5]  
          
        try:  
            supply_info = get_kingdee_supply(flag, org_id, supply_name)  
            supply_no = supply_info['supply_no']  
        except BaseException as e:  
            supply_no = ""         
          
details = []  
          
        detail = {  
            "FMATERIALID": {  
                "FNumber": "kry-yf001"  
            },  
            "FCOSTID": {  
                "FNumber": "FYXM46_SYS"  
            },  
            "FPRICEUNITID": {  
                "FNumber": "Pcs"  
            },  
            "FPriceQty": 1.0,  
            "FTaxPrice": total_amt,  
            "FEntryTaxRate": 0,  
            'FINCLUDECOST': False,  
            "FComment": remarks,  
            "FTAILDIFFFLAG": False,  
        }  
  
        details.append(detail)  
  
        try:  
            res_info = save_yfd(flag, org_id, bill_no, bill_date, supply_no, "", details)  
            if 'E0000' in res_info:  
                modify_cgdd_data(curr, flag,  bill_no, "E0001", '同步成功')  
            elif 'E0009' in res_info:  
                if '唯一' in res_info:  
                    modify_cgdd_data(curr, flag,  bill_no, "E0002", '同步成功[已同步过')  
                else:  
                    modify_cgdd_data(curr, flag,  bill_no, "E0009", res_info)  
                    wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应付处理-数据同步失败[{res_info}]!")  
        except BaseException as e:  
            res_info = "订单【{}】, 同步失败:{}".format(bill_no, e)  
            modify_cgdd_data(curr, flag,  bill_no, "E0009", res_info)  
            wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应付处理-数据同步失败[{res_info}]!")  
        cnt += 1  
        # 关闭游标和连接  
    conn.commit()   
    curr.close()  
    conn.close()  
    wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应付处理[{start_date}至{end_date}]-同步完成,记录数[{cnt}]!!")  
  
  
# 消费订单查询  
def get_xsdd_data(shop_no, start_date, end_date):  
    # 查询店铺名称,对应金蝶组织  
    shop = get_shop_info(shop_no)  
    shop_name = shop['shop_name']  
    org_id = shop['org_id']  
    org_name = shop['org_name']  
      
    body = {  
        "dateType": "FINISH_TIME",  
        "startDate": start_date,  
        "endDate": end_date,  
        "orderStatusList": [  
            "SETTLED",  
            "SUCCESS"  
        ],  
        "pageBean": {  
            "pageNum": 1,  
            "pageSize": 1  
        },  
    }  
    uri = '/open/standard/order/queryList'  
    response = call_api_shop(uri, APP_KEY, shopIdenty=shop_no, body=body)  
    res_code = response['result']['success']  
    if not res_code:  
        msg = f'【客如云[{shop_name}]】:[{start_date}~{end_date}]没有消费订单数据!'  
        wx_notice(msg)  
        return   
    total_page = int(response['result']['data']['totalPage'])  
    conn = sqlite3.connect(DB_FILE)  
    curr_obj = conn.cursor()  
      
    page = 1  
    while page < total_page:    
        body = {  
            "dateType": "FINISH_TIME",  
            "startDate": start_date,  
            "endDate": end_date,  
            "orderStatusList": [  
                "SETTLED",  
                "SUCCESS"  
            ],  
            "pageBean": {  
                "pageNum": page,  
                "pageSize": 100  
            },  
        }  
          
        response = call_api_shop(uri, APP_KEY, shopIdenty=shop_no, body=body)  
        res_code = response['result']['success']  
  
        if not res_code:  
            break  
  
        page += 1  
        lists = response['result']['data']['list']  
        if len(lists) == 0:  
            break  
  
        for list in lists:  
            order_id = list['orderId']  
            busi_order_no = list['busiOrderNo']  
              
            order_types = {  
                "FOR_HERE": "堂食",  
                "TAKE_OUT": "外带",  
                "PLATFORM_TAKE_OUT": "平台外卖",  
                "SELF_TAKE_OUT": "自营外卖",  
                "OPEN_PLATFORM_TAKE_OUT": "开放平台外卖",  
                "SELF_TAKE": "自提",  
                "NO_ORDER_CASHIER": "无单收银",  
                "MEMBER_STORE": "会员充值",  
                "MEMBER_CARD_SALE": "会员售卡并储值",  
                "MEMBER_MANUAL_STORE": "会员补录",  
                "REPAYMENT_ORDER": "销账订单",  
                "PRIVATE_PAY_MEMBER_SALE": "权益卡售卡订单",  
                "COUPON_PACKAGE_SALE": "券包售卖订单",  
                "ONLINE_PAY_BILL": "在线买单",  
                "STATIC_CODE": "客如云收款码",  
                "DEPOSIT": "订金订单",  
                "EARNEST_MONEY": "定金订单",  
                "CASH_PLEDGE": "押金订单",  
                "GIFT_CARD_SALE": "礼品卡订单",  
                "GIFT_PACKAGE_SALE": "礼包订单",  
                "GIFT_CARD_STORE": "礼品卡储值订单",  
                "GROUP_PURCHASING": "拼团订单",  
                "POINTS_MALL": "积分商城订单",  
                "BARGAIN": "砍价订单",  
                "SEC_KILL": "秒杀订单",  
                "COUPON_SALE": "团购券售卖"  
            }  
              
            order_status = {  
                "WAIT_PROCESSED": "待处理",  
                "WAIT_SETTLED": "待结账",  
                "SETTLED": "已结账",  
                "REFUND": "已退单",  
                "INVALID": "已作废",  
                "CANCELLED": "已取消",  
                "REJECTED": "已拒绝",  
                "SUCCESS": "已完成"  
            }  
  
            order_status_desc = order_status.get(list['orderStatus'])  
            order_status = list['orderStatus'] + '-' + order_status_desc  
  
            order_type = order_types.get(list['orderType'])  
            try:  
                if "会员充值" in order_type:  
                    org_id = '103'  
            except:  
                print(f"orderType=[{list['orderType']}]")  
  
            payment_flag, pay_type = get_pay_info(shop_no, order_id)  
            if payment_flag:  
                order_amt = -1*float(list['orderAmt'])/100  
                promo_amt = -1*float(list['promoAmt'])/100  
                try:  
                    order_received_amt = -1*float(list['orderReceivedAmt'])/100  
                    third_order_no = ''  
                except:  
                    msg = f"【客如云[{shop_name}]】:[orderReceivedAmt={list['orderReceivedAmt']}]订单数据异常!"  
                    third_order_no = msg  
                    wx_notice(msg)  
                    order_received_amt = 0  
            else:  
                order_amt = float(list['orderAmt']) / 100  
                promo_amt = float(list['promoAmt']) / 100  
                try:  
                    order_received_amt = float(list['orderReceivedAmt']) / 100  
                    third_order_no = ''  
                except:  
                    msg = f"【客如云[{shop_name}]】:[orderReceivedAmt={list['orderReceivedAmt']}]订单数据异常!"  
                    third_order_no = msg  
                    wx_notice(msg)  
                    order_received_amt = 0  
  
            open_time = list['openTime']  
            finish_time = list['finishTime']  
            # third_order_no = list['thirdOrderNo']  
            serial_no = list['serialNo']  
            third_serial_no = list['thirdSerialNo']  
  
              
            ins_data = {  
                "shop_no": shop_no,                         # 门店ID  
                "shop_name": shop_name,                     # 门店名称  
                "org_id": org_id,                           # 组织ID  
                "org_name": org_name,                       # 组织名称  
                "cust_no": "KRY-0001",                      # 客如云  
                "order_id": order_id,                       # 订单ID  
                "busi_order_no": busi_order_no,             # 业务订单号  
                "order_status": order_status,               # 订单状态  
                "order_type": order_type,                   # 订单类型  
                "pay_type": pay_type,                       # 支付方式  
                "order_amt": order_amt,                     # 订单金额(单位/分)  
                "promo_amt": promo_amt,                     # 优惠金额(单位/分)  
                "order_received_amt": order_received_amt,   # 订单收入/订单实收(单位/分)  
                "open_time": open_time,                     # 下单时间  
                "finish_time": finish_time,                 # 完结时间  
                "third_order_no": third_order_no,          # 第三方订单号  
                "serial_no": serial_no,                     # 订单流水号  
                "third_serial_no": ""                  # 第三方流水号  
            }  
            # 插入数据到数据库  
            insert_xsdd_data(curr_obj, ins_data)  
            conn.commit()  
  
    curr_obj.close()  
    conn.close()  
    # # 通知客户企业微信群  
    msg = msg = f'【客如云[{shop_name}]】:[{start_date}~{end_date}]订单数据获取完成!'  
    wx_notice(msg)  
  
  
## 同步金蝶处理  
def tokd_xsdd_sync(flag, shop_no, start_date, end_date):  
    """  
    :return:  
    """    conn = sqlite3.connect(DB_FILE)  
    curr = conn.cursor()  
    if flag == 'SZ':  
        query = """ select org_id, cust_no, finish_time, busi_order_no, order_type, pay_type, order_received_amt   
                    from kry_xsdd where shop_no=? and SUBSTR(finish_time,1,10)>=? and SUBSTR(finish_time,1,10)<=?   
                    and sz_data_status in ('E0000', 'E0009') """  
    else:  
        query = """ select org_id, cust_no, finish_time, busi_order_no, order_type, pay_type, order_received_amt   
                    from kry_xsdd where shop_no=? and SUBSTR(finish_time,1,10)>=? and SUBSTR(finish_time,1,10)<=?   
                    and jy_data_status in ('E0000', 'E0009') """  
    val = (shop_no, start_date, end_date,)  
    curr.execute(query, val)  
  
    # 获取查询结果  
    rows = curr.fetchall()  
  
    # 打印查询结果  
    cnt = 0  
    if 0 == len(rows):  
        wx_notice(f"客如云[{shop}]->金蝶[{flag}]账套:应收处理[{start_date}至{end_date}]-未查询到需要同步的异常数据!!")  
        curr.close()  
        conn.close()  
        return  
    for row in rows:  
        org_id = row[0]  
        cust_no = row[1]  
        bill_date = row[2]  
        bill_no = row[3]  
        order_type = row[4]  
        pay_type = row[5]  
        ys_amt = row[6]  
        details = []  
  
        if ',' in pay_type:  
            pay_types = pay_type.split(',')  
            for pay_info in pay_types:  
                pay_type = pay_info.split(':')[0]  
                ys_amt = float(pay_info.split(':')[1])  
                if ys_amt < 0:  
                    qty = -1  
                    ys_amt = abs(ys_amt)  
                else:  
                    qty = 1  
                try:  
                    wl_info = get_kingdee_wl(flag, org_id, pay_type)  
                    wl_code = wl_info['wl_no']  
                except:  
                    wl_code = ""  
  
                detail = {  
                    "FMATERIALID": {  
                        "FNumber": wl_code  
                    },  
                    "FTaxPrice": ys_amt,  
                    # "FEntryTaxRate": 13,  
                    "FPriceQty": qty,  
                    "FComment": "",  
                }  
                details.append(detail)  
        else:  
            if ":" in pay_type:  
                pay_type = pay_type.split(':')[0]  
  
            try:  
                wl_info = get_kingdee_wl(flag, org_id, pay_type)  
                wl_code = wl_info['wl_no']  
            except:  
                wl_code = ""  
  
            if ys_amt < 0:  
                qty = -1  
            else:  
                qty = 1  
            detail = {  
                "FMATERIALID": {  
                    "FNumber": wl_code  
                },  
                "FTaxPrice": ys_amt,  
                # "FEntryTaxRate": 13,  
                "FPriceQty": qty,  
                "FComment": "",  
            }  
            details.append(detail)  
  
        try:  
            res_info = save_ysd(flag, org_id, bill_no, bill_date, cust_no, order_type, details)  
            if 'E0000' in res_info:  
                modify_xsdd_data(curr, flag,  bill_no, "E0001", '同步成功')  
            elif 'E0009' in res_info:  
                if '唯一' in res_info:  
                    modify_xsdd_data(curr, flag,  bill_no, "E0002", '同步成功[已同步过]')  
                else:  
                    modify_xsdd_data(curr, flag,  bill_no, "E0009", res_info)  
                    wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应收处理-数据同步失败[{res_info}]!")  
        except BaseException as e:  
            res_info = "订单【{}】, 同步失败:{}".format(bill_no, e)  
            modify_xsdd_data(curr, flag,  bill_no, "E0009", res_info)  
            wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应收处理-数据同步失败[{res_info}]!")  
        cnt += 1  
  
    # 关闭游标和连接  
    conn.commit()  
    curr.close()  
    conn.close()  
    wx_notice(f"客如云[{shop_no}]->金蝶[{flag}]账套:应收处理[{start_date}至{end_date}]-同步完成,记录数[{cnt}]!!")  
  
  
  
def get_shoplist():  
    uri = '/open/standard/shop/MerchantOrgReadService.queryBrandStores'  
  
    # 调用API  
    response = call_api(uri, APP_KEY, brandId=34812143, body=None)  
  
    # 打印响应内容  
    shops = response['result']['shops']  
    for shop in shops:  
        print(shop['shopId'], shop['name'])  
      
  
if __name__ == '__main__':  
    # 业务数据  
    # get_shoplist()  
  
    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""  
    | shop_id   |  shop_name            | kd_code |    kd_name                          |    ---------------------------------------------------------------------------------------    35170196    名古屋日料烤肉(新翼广场店)   103.04     佛山市起翼餐饮服务有限公司顺德第一分公司  
    35114097    啡同凡享(新翼广场店)         103.07    佛山市起翼餐饮服务有限公司顺德第四分公司  
    35082103    喜翼楼(赤坎店)           106        湛江市喜翼楼餐饮服务有限公司  
    35172137    喜翼港式茶餐厅(新翼广场店)   103        佛山市起翼餐饮服务有限公司  
    34994157    喜翼港式茶餐厅(豪庭店)       103.02     佛山市起翼餐饮服务有限公司湛江豪庭分公司  
    34830154    喜翼港式茶餐厅(鼎盛店)       103.01     佛山市起翼餐饮服务有限公司湛江鼎盛分公司  
    35142115    对面粥粉面(新翼广场店)       103.06     佛山市起翼餐饮服务有限公司顺德第三分公司  
    ---------------------------------------------------------------------------------------    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""    # shops = [34830154]  
    # 采购数据同步测试  
    shops = [35170196, 35114097, 35082103, 35172137, 34994157, 34830154, 35142115]  
  
    # for shop in shops:  
    #     get_cgrk_data(shop, '2025-01-01 00:00:00', '2025-01-22 00:00:00')    #     tokd_cgdd_sync('SZ', shop, '2025-01-01', '2025-01-22')    #     tokd_cgdd_sync('JY', shop, '2025-01-01', '2025-01-21')  
    # sync_dates = ["2025-01-01", "2025-01-02", "2025-01-03", "2025-01-04", "2025-01-05",    #      "2025-01-06",  "2025-01-07", "2025-01-08", "2025-01-09", "2025-01-10",    #      "2025-01-11", "2025-01-12", "2025-01-13", "2025-01-14", "2025-01-15", "2025-01-16",    #      "2025-01-17","2025-01-18","2025-01-19", "2025-01-20", "2025-01-21"]    #    sync_dates = ["2025-01-22"]  
  
    for sync_date in sync_dates:  
        s_date = sync_date + " 00:00:00"  
        e_date = sync_date + " 23:59:59"  
        # for shop in shops:  
        #     # get_cgrk_data(shop, s_date, e_date)        #     # tokd_cgdd_sync('SZ', shop, sync_date, sync_date)        #     # tokd_cgdd_sync('JY', shop, sync_date, sync_date)  
        # 销售数据同步测试  
        for shop in shops:  
            get_xsdd_data(shop, s_date, e_date)  
            # tokd_xsdd_sync('SZ', shop, sync_date, sync_date)  
            # tokd_xsdd_sync('JY', shop, sync_date, sync_date)



是否对你有帮助?

评论