实现销售出库数据在聚水潭与金蝶云的自动化同步

  • 轻易云集成顾问-曹润
### 聚水潭·奇门数据集成到金蝶云星空的技术实现 在本文中,我们将深入探讨如何利用轻易云数据集成平台,成功实现聚水潭·奇门与金蝶云星空之间的数据对接。本次案例涉及[自动]-03销售出库同步(潮流1、2、美妆店)方案,通过API接口jushuitan.saleout.list.query获取聚水潭·奇门的销售出库数据,并通过batchSave接口将这些数据写入到金蝶云星空。 #### 数据抓取及处理 首先,确保从聚水潭·奇门系统定时可靠地抓取销售出库数据是至关重要的一步。我们采用了jushuitan.saleout.list.query接口,以分页方式逐批拉取数据。在实际操作中,为解决限流问题,每次请求后会根据响应头中的Retry-After字段动态调整请求频率,从而避免超出API调用限制。 ```python def fetch_data_from_qimen(page_no): response = requests.get(f"{qimen_url}?page_no={page_no}&page_size=50") if response.status_code == 200: return response.json() elif response.status_code == 429: # Too Many Requests time.sleep(int(response.headers['Retry-After'])) return fetch_data_from_qimen(page_no) ``` #### 数据格式转换与映射 聚水潭·奇门和金蝶云星空之间的数据格式存在显著差异,因此在对接过程中必须进行必要的转换和映射。例如,聚水潭返回的JSON结构需要转化为符合金蝶规范XML文档。一些常见的数据字段如订单号、商品ID等直接一一对应,但也有部分需要自定义映射以契合业务需求。 ```python def transform_data_to_kingdee_format(qimen_data): kingdee_data = [] for item in qimen_data: kingdee_item = { "OrderNumber": item["order_id"], "ProductCode": item["item_code"], "Quantity": item["quantity"] # 更多字段映射... } kingdee_data.append(kingdee_item) return kingdee_data ``` #### 批量写入与错误重试机制 为了保证大量的数据能够快速且高效地写入到金蝶云星空,我们使用了batchSave接口,同时配合错误重试机制,当遇到网络波动或系统异常时,可以自动进行重新提交,有效提高稳定性。 ```python def batch_save_to_kingdee(data_list): try: payload = json.dumps({"data": data_list}) headers = {'Content-Type': 'application/json'} response = requests.post(kingdee_url, headers=headers, data=payload) if not ![用友与MES系统接口开发配置](https://pic.qeasy.cloud/D21.png~tplv-syqr462i7n-qeasy.image) ### 调用聚水潭·奇门接口jushuitan.saleout.list.query获取并加工数据 在数据集成的生命周期中,调用源系统接口是至关重要的一步。本文将深入探讨如何使用轻易云数据集成平台调用聚水潭·奇门接口`jushuitan.saleout.list.query`,并对获取的数据进行加工处理。 #### 接口配置与请求参数 首先,我们需要配置接口及其请求参数。根据元数据配置,接口为`jushuitan.saleout.list.query`,请求方法为POST。以下是具体的请求参数: - `page_index`: 页数,从第一页开始,默认值为1。 - `page_size`: 每页行数,默认25,最大25。 - `start_time`: 修改开始时间,与结束时间必须同时存在,时间间隔不能超过七天。 - `end_time`: 修改结束时间,与起始时间必须同时存在。 - `status`: 单据状态,此处设置为"Confirmed"(已出库)。 - `shop_id`: 店铺ID,此处包含多个店铺ID,如12393644,12698110,12934323。 这些参数确保了我们能够准确地获取到所需的销售出库数据。 #### 请求参数示例 ```json { "page_index": "1", "page_size": "25", "start_time": "{{LAST_SYNC_TIME|datetime}}", "end_time": "{{CURRENT_TIME|datetime}}", "status": "Confirmed", "shop_id": "12393644,12698110,12934323" } ``` #### 数据获取与清洗 在发送请求后,我们将接收到一批销售出库数据。为了确保数据的完整性和准确性,需要对数据进行清洗和预处理。这一步骤包括但不限于以下操作: 1. **去重**:检查并移除重复记录。 2. **格式转换**:将日期、金额等字段转换为标准格式。 3. **缺失值处理**:填补或删除缺失值,以保证数据质量。 例如,对于日期字段,可以使用以下代码进行格式转换: ```python from datetime import datetime def convert_date(date_str): return datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S') data['start_time'] = data['start_time'].apply(convert_date) data['end_time'] = data['end_time'].apply(convert_date) ``` #### 数据转换与写入 清洗后的数据需要进行进一步的转换,以适应目标系统的要求。这可能包括字段映射、单位转换等操作。例如,将销售数量从“件”转换为“箱”: ```python def convert_units(quantity_pieces): return quantity_pieces / 10 # 假设每箱包含10件商品 data['quantity_boxes'] = data['quantity_pieces'].apply(convert_units) ``` 最后,将处理好的数据写入目标系统。这一步骤通常通过API或数据库连接实现。确保在写入前进行必要的验证和日志记录,以便追踪和排查潜在问题。 #### 异常处理与补救措施 在实际操作中,不可避免地会遇到各种异常情况,如网络超时、接口返回错误等。为了提高系统的健壮性,需要设计合理的异常处理机制。例如,当接口调用失败时,可以自动重试或记录错误日志,并在下一次调度任务中补救。 元数据配置中的`omissionRemedy`部分提供了一个示例,通过定时任务(crontab)来自动补救遗漏的数据请求: ```json { "crontab": "2 0 * * *", "takeOverRequest": [ { "id": "start_timeYrXph", "field": "start_time", "label": "修改开始时间", "type": "string", "value": "{{DAYS_AGO_3|datetime}}" } ] } ``` 该配置表示每天凌晨0点2分执行一次任务,将起始时间设置为三天前,以确保没有遗漏的数据被及时补充。 通过以上步骤,我们可以高效地调用聚水潭·奇门接口`jushuitan.saleout.list.query`,并对获取的数据进行全面的清洗和加工,为后续的数据集成奠定坚实基础。 ![打通金蝶云星空数据接口](https://pic.qeasy.cloud/S16.png~tplv-syqr462i7n-qeasy.image) ### 使用轻易云数据集成平台实现销售出库数据同步至金蝶云星空 在数据集成生命周期的第二步,我们需要将已经集成的源平台数据进行ETL转换,并转为目标平台金蝶云星空API接口所能够接收的格式,最终写入目标平台。以下是详细的技术步骤和实现过程。 #### API 接口配置 根据提供的元数据配置,我们使用金蝶云星空的 `batchSave` API 接口,通过POST方法进行数据写入。以下是具体配置细节: ```json { "api": "batchSave", "method": "POST", "idCheck": true, "operation": { "rowsKey": "array", "rows": 1, "method": "batchArraySave" }, "request": [ {"field":"FBillTypeID","label":"单据类型","type":"string","describe":"单据类型","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"XSCKD01_SYS"}, {"field":"FBillNo","label":"单据编号","type":"string","describe":"单据编号","value":"{io_id}"}, {"field":"FDate","label":"日期","type":"string","describe":"日期","value":"{io_date}"}, {"field":"FSaleOrgId","label":"销售组织","type":"string","describe":"组织","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"_function case '{shop_id}' when '10593320' then '100' else '101' end"}, {"field":"FCustomerID","label":"客户","type":"string","describe":"基础资料","parser":{"name":"ConvertObjectParser","params":"FNumber"},"value":"{shop_id}"}, {"field":"FSaleDeptID","label":"销售部门","type":"string","value":"'LJ006' if '{{items.sku_id}}' like 'A%' or '{{items.sku_id}}' like 'M%' or '{{items.sku_id}}' like 'X%' or '{{items.sku_id}}' like 'D%' or '{{items.sku_id}}' like 'T%' else 'LJ011'", "parser":{"name": "ConvertObjectParser", "params": "FNumber"}}, {"field": "F_TLWD_Text", "label": "平台单号", "type": "string", "value": "{so_id}"}, {"field": "F_TLWD_Assistant", "label": "店铺", "type": "string", "value": "{shop_id}", "parser":{"name": "ConvertObjectParser", "params": "FNumber"}}, {"label": "备注", "field": "FNote", "type": "string"}, { "field" : "FEntity", "label" : "明细信息", "type" : "array", "children":[ { "field" : "FMaterialID", "label" : "物料编码", "type" : "string", "value" : "{{items.sku_id}}", "parser":{"name": "ConvertObjectParser", "params": "FNumber"} }, { "parent" : "FEntity", "type" : "string", "value" : "{{items.sale_price}}" }, { ... } ], ... } ... ] } ``` #### 数据字段解析与转换 1. **单据类型 (FBillTypeID)**: - 固定值 `XSCKD01_SYS`,通过 `ConvertObjectParser` 转换为金蝶云星空所需格式。 2. **单据编号 (FBillNo)**: - 动态值 `{io_id}`,直接映射源数据中的出库单号。 3. **日期 (FDate)**: - 动态值 `{io_date}`,直接映射源数据中的出库日期。 4. **销售组织 (FSaleOrgId)**: - 根据 `shop_id` 的不同值进行条件判断,使用 `_function case` 实现动态映射。例如,当 `shop_id` 为 `10593320` 时,映射为 `100`;否则映射为 `101`。 5. **客户 (FCustomerID)**: - 动态值 `{shop_id}`,通过 `ConvertObjectParser` 转换为金蝶云星空所需格式,并进行正向映射。 6. **销售部门 (FSaleDeptID)**: - 根据 SKU 编码前缀进行条件判断,例如,当 SKU 编码以 `A`, `M`, `X`, `D`, 或者 `T` 开头时,映射为 `LJ006`;否则映射为 `LJ011`。 7. **平台单号 (F_TLWD_Text)**: - 动态值 `{so_id}`,直接映射源数据中的平台订单号。 8. **店铺 (F_TLWD_Assistant)**: - 动态值 `{shop_id}`,通过 `ConvertObjectParser` 转换并进行正向映射。 9. **备注 (FNote)**: - 可选字段,根据业务需求填写备注信息。 #### 明细信息处理 明细信息字段 (`FEntity`) 是一个数组,需要逐条处理每个子项: 1. **物料编码 (FMaterialID)**: - 动态值 `{{items.sku_id}}`,通过 `ConvertObjectParser` 转换为金蝶云星空所需格式。 2. **含税单价 (FTaxPrice)**: - 动态值 `{{items.sale_price}}`,直接映射源数据中的销售价格。 3. **实发数量 (FRealQty)**: - 动态值 `{{items.qty}}`,直接映射源数据中的实际发货数量。 4. **是否赠品 (FIsFree)**: - 根据销售价格判断是否为赠品,例如,当销售价格为0时,设置为true;否则设置为false。 5. **仓库 (FStockID)**: - 动态值 `{wms_co_id}`,通过 `ConvertObjectParser` 转换为金蝶云星空所需格式。 6. **金额 (FAmount)**: - 动态值 `{{items.sale_amount}}`,直接映射源数据中的销售金额。 7. **库存单位 (FUnitID)**: - 固定值 `'Pcs'`, 表示库存单位,通过 `ConvertObjectParser` 转换为金蝶云星空所需格式。 8. **货主ID (FOwnerTypeID, FOwnerID)**: - 固定值 `'BD_OwnerOrg'`, 表示货主类型。 - 根据店铺 ID 判断货主 ID,例如,当店铺 ID 为 `'10593320'` 时,设置货主 ID 为 `'100'`; 否则设置为 `'101'`. #### 财务信息处理 财务信息字段 (`SubHeadEntity`) 是一个对象,需要逐条处理每个子项: 1. **整单折扣额 (FAllDisCount)**: - 动态值 `{free_amount}`, 映射源数据中的整单折扣金额. #### 最终请求结构 在完成上述字段解析与转换后,我们将生成最终的请求结构,并调用金蝶云星空的API接口进行数据写入。确保所有字段均已正确解析并符合目标平台要求,以保证数据准确无误地传输和存储。 ![用友与CRM系统接口开发配置](https://pic.qeasy.cloud/T23.png~tplv-syqr462i7n-qeasy.image)