一、为什么要把CRM和ERP数据打通?
畅捷通是用友的龙头产品,占有ERP市场的很大规模,如果公司同时在使用纷享销客CRM和畅捷通,把两套系统数据打通,绝对是非常明智的决策!这样做的优势有以下几个方面:
1、极大的降低数据维护成本
集成以后,基础数据像客户、供应商、存货、仓库等这些信息,不需要在两套系统维护,一端维护,多端共享;
2、保证数据的及时性、准确性、完整性
无感触发,实时同步,按照约定的同步方向,数据会自动流转,减少人为操作错误,异常数据实时提醒;
3、优化业务流程
CRM端可实时了解ERP相关进度数据,生产进度、预计交货日期、物料信息、库存信息,销售人员可以第一时间了解到ERP完整信息。
二、如何打通CRM和ERP系统?
纷享销客CRM和畅捷通都是迭代了很多年的优秀产品,产品生态非常完善,各自都有自己的开放平台,企业可以自行或者或者委托纷享以及用友ISV服务商进行数据同步项目的开发,一般有两种形式。
1、高代码开发
第一种方式:基于中间件服务,定时轮询查询增量数据的方式,按照约定的同步方向,由同步程序按照一定的频率去执行查询,如果查询到增量数据,则向目标系统进行写入;
第二种方式:基于事件回调服务,纷享销客和畅捷通T+,都具有事件消息订阅能力,即:当CRM、ERP相关模型对象发生增删改时,可以把这种操作的消息推送给第三方程序,然后由第三方程序执行相应的逻辑处理。
2、低代码插件开发
目前市场上有很多低代码或零代码集成插件,只需要进行相应的配置或者简单的脚步处理,就可以完成数据集成,并且带有可视化的操作界面,非常简单,纷享销客CRM官方也推出了同步插件程序,供客户选择。
具体应该选择哪种方式,需要根据实际使用场景、业务需求、预算等因素综合考虑评估。
三、相关参考资料
1、纷享销客CRM开放平台文档:纷享销客开放平台
2、用友畅捷通开放平台文档:畅捷通开放平台
四、相关代码参考
1、Python调用纷享销客开放平台
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:wangzhifeng@tongdog.com.cn
import requests
import json
import pymysql
import time
class fxiaoke():
# 构造方法
def __init__(self):
self.AppID = ""
self.APPSecret = ""
self.permanentCode = ""
self.currentOpenUserId = ""
self.headers = {"Content-Type": "application/json; charset=utf-8"}
self.getCorpAccessToken()
# 获取CorpAccessToken
def getCorpAccessToken(self):
connect = pymysql.connect(
host='127.0.0.1', user='', password='', database='')
cursor = connect.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from fx_fxtoken where type = 'corpAccessToken';"
cursor.execute(sql)
result = cursor.fetchone() # 取一条
# print(result)
self.corpId = result['corpid']
self.corpAccessToken = result['value']
expires_time = result['expire']
if int(time.time()) > int(expires_time):
url = "https://open.fxiaoke.com/cgi/corpAccessToken/get/V2"
# 请求参数
postdata = {
"appId": self.AppID,
"appSecret": self.APPSecret,
"permanentCode": self.permanentCode
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
print(result)
self.corpAccessToken = result["corpAccessToken"]
self.corpId = result["corpId"]
self.expire = int(time.time()) + result["expiresIn"] - 300
cursor.execute("update fx_fxtoken set expire = {0} , value = '{1}',corpId = '{2}' where type = 'corpAccessToken';".format(
self.expire, self.corpAccessToken, self.corpId))
cursor.close()
connect.close()
# 根据手机号获取人员信息
def getByMobile(self, mobile):
url = "https://open.fxiaoke.com/cgi/user/getByMobile"
# 请求参数
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"mobile": mobile
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 查询对象列表
def getObjList(self, data):
url = "https://open.fxiaoke.com/cgi/crm/v2/data/query"
# 请求参数
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"currentOpenUserId": self.currentOpenUserId,
"data": data
}
print(json.dumps(postdata))
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 获取对象描述
def getDescribe(self, objname):
url = "https://open.fxiaoke.com/cgi/crm/v2/object/describe"
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"currentOpenUserId": self.currentOpenUserId,
"apiName": objname
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 获取部门下全员列表
def getUserList(self, departmentId):
url = "https://open.fxiaoke.com/cgi/user/list"
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"departmentId": departmentId
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 获取纷享服务器IP地址
def getApiDomainIp(self):
url = "https://open.fxiaoke.com/cgi/crm/v2/special/getApiDomainIp"
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"currentOpenUserId": self.currentOpenUserId
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 获取审批类型列表
def getApprovalTypeForms(self):
url = "https://open.fxiaoke.com/cgi/approvalTypeForms/get"
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
# 分类处理
def editProductCategory(self, data):
url = "https://open.fxiaoke.com/cgi/crm/data/editProductCategory"
postdata = {
"corpId": self.corpId,
"corpAccessToken": self.corpAccessToken,
"currentOpenUserId": self.currentOpenUserId,
"data": data
}
result = requests.post(url, data=json.dumps(
postdata), headers=self.headers).json()
return result
if __name__ == '__main__':
fxiaoke = fxiaoke()
'''
data = {
"dataObjectApiName": "PersonnelObj",
"search_query_info": {
"limit": 3,
"offset": 0,
"filters": [
{
"field_name": "full_name",
"field_values": [""],
"operator":"EQ"
}
],
"orders": [
{
"fieldName": "create_time",
"isAsc": "false"
}
]
}
}
'''
# 获取用户ID
print(json.dumps(fxiaoke.getByMobile("189"),
ensure_ascii=False, sort_keys=True, indent=4, separators=(',', ': ')))
# print(json.dumps(fxiaoke.getApprovalTypeForms(),
# sort_keys=True, indent=4, separators=(',', ': ')))
#account = fxiaoke.getObjList(data)
# print(json.dumps(account, sort_keys=True,
# ensure_ascii=False, indent=4, separators=(',', ': ')))
'''
data = {
"editFlag": 2,
"name": "白菜",
"id": "63984bbb17a7cf0001ca857c",
"pid": "63984b4717a7cf0001ca5a03",
"category_code": "102",
"orderField": 1
}
category = fxiaoke.editProductCategory(data)
print(json.dumps(category, sort_keys=True,
ensure_ascii=False, indent=4, separators=(',', ': ')))
'''
2、Python调用畅捷通开放平台
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:wangzhifeng@tongdog.com.cn
import requests
import json
import pymysql
import time
class chanjt():
# 构造方法
def __init__(self):
pass
def test(self):
url = "http://www.fxiaoke.com/erp/syncdata/open/objdata/asyncpush"
headers = {
"token":"",
"tenantId":"",
"objectApiName":"",
"version":"v1",
"dataCenterId":"",
"Content-Type":"application/json"
}
postdata = {
"objAPIName": "token",
"masterFieldVal": {
"token": "token",
"id": "11"
},"detailFieldVals": {}
}
result = requests.post(url, data=json.dumps(
postdata), headers=headers).json()
print(result)
if __name__ == '__main__':
chanjt = chanjt()
chanjt.test()
纷享销客CRM与畅捷通T+Cloud集成讨论咨询:
Email:wangzhifeng@tongdog.com.cn