实现自动化:通过轻易云同步调拨出库单至金蝶云星空

  • 轻易云集成顾问-曾平安
### 调拨出库单同步:旺店通·旗舰奇门数据集成到金蝶云星空 在一次实际的系统对接项目中,我们成功实现了将旺店通·旗舰奇门(以下简称“旺店通”)的数据集成到金蝶云星空,具体任务是同步调拨出库单。本文将详细介绍如何通过轻易云数据集成平台解决这一复杂而关键的业务需求,以及面临的一些技术挑战和应对措施。 首先,对于数据获取环节,我们需要调用旺店通提供的API接口`wdt.wms.stockout.transfer.querywithdetail`来抓取调拨出库单数据。该接口支持分页查询,但限流机制要求我们在请求频率上进行控制。同时,还要确保对每一条返回的数据进行完备性校验,以避免漏单问题。这部分工作不仅涉及到准确性,更关乎高效性,因为我们需要处理大量的数据并快速写入到目标系统——金蝶云星空。 为此,在数据写入至金蝶云星空时,使用其批量操作API `batchSave` 是一个关键步骤。这有助于我们提升整体性能,并保证大规模数据处理的稳定性。在这个过程中,我们尤其注重以下几点: 1. **定时可靠地抓取旺店通接口数据**:通过设置合适的时间间隔和触发条件,使得整个流程自动化且高效运行。 2. **处理分页及限流问题**:采用智能算法管理分页请求,同时监控API调用频率,确保满足服务端限制条件。 3. **解决数据格式差异**:根据两套系统的数据模型,对获取的数据进行预处理和转换,以符合金蝶云星空的要求。 4. **异常处理与错误重试机制**:万一遇到了网络故障或其他不可预测的问题,可以通过重试策略最大程度降低影响。 此外,为了增强透明度并便于后续维护管理,我们还构建了实时监控与日志记录功能,对每一次任务执行过程中的所有操作步骤都进行了详尽记录。当出现异常情况时,这些日志信息可以帮助迅速定位问题根源,从而有效减少停机时间,提高整体系统稳定性。 最后,通过上述技术手段,我们顺利完成了从旺店通到金蝶云星空调拨出库单同步任务,实现业务流程无缝衔接和高效运转。下面,将进一步深入探讨各个具体实现细节以及配置方案。 ![如何对接用友BIP接口](https://pic.qeasy.cloud/D7.png~tplv-syqr462i7n-qeasy.image) ### 调用旺店通·旗舰奇门接口获取并加工数据 在数据集成生命周期的第一步,我们需要调用源系统旺店通·旗舰奇门接口`wdt.wms.stockout.transfer.querywithdetail`来获取调拨出库单的数据,并进行初步加工。以下是详细的技术实现过程。 #### 接口调用配置 首先,我们需要配置接口调用的元数据。根据提供的元数据配置,我们可以看到该接口采用POST方法,主要参数包括查询参数和分页信息。 ```json { "api": "wdt.wms.stockout.transfer.querywithdetail", "method": "POST", "number": "order_no", "id": "stockout_id", "idCheck": true, "beatFlat": ["detail_list"], "request": [ { "field": "params", "label": "查询参数", "type": "object", "describe": "查询参数", "children": [ {"field": "start_time", "label": "开始时间", "type": "string", "describe": "起始时间,若无出库单号或调拨单号,则为必填。", "value":"{{LAST_SYNC_TIME|datetime}}", "parent":"params"}, {"field": "end_time", "label": "结束时间", "type":"string", "describe":"结束时间,上同开始时间", "value":"{{CURRENT_TIME|datetime}}", "parent":"params"}, {"field":"warehouse_no","label":"仓库编号","type":"string","describe":"仓库编号","parent":"params"}, {"field":"src_order_no","label":"调拨单号","type":"string","describe":"调拨单号","parent":"params"}, {"field":"stockout_no","label":"出库单号","type":"string","describe":"出库单号","parent":"params"}, {"field":"position","label":"是否按照货位分组","type":"string","describe":"0: 否 不传也为否","parent":"params"}, {"field":"status","label":"出库单状态","type":"string", "describe": `由逗号隔开的整数字符串出库单状态: 5已取消,48未确认,50待审核,77拣货中,PDA拣货后110已完成`, value:"110", parent:"params"} ] }, { field: 'pager', label: '分页', type: 'object', describe: '分页', children: [ { field: 'page_size', label: '分页大小', type: 'string', describe: '分页大小', value: '50', parent: 'pager' }, { field: 'page_no', label: '页号', type: 'string', describe: '从0开始', value: '1', parent: 'pager' } ] } ] } ``` #### 请求参数解析 在调用接口时,需要构建请求体。请求体由两个主要部分组成:查询参数(`params`)和分页信息(`pager`)。 - **查询参数**: - `start_time` 和 `end_time`:分别表示数据同步的起始和结束时间。这两个字段通常使用上次同步时间和当前时间。 - `warehouse_no`:仓库编号,用于指定要查询的仓库。 - `src_order_no` 和 `stockout_no`:分别表示调拨单号和出库单号,如果没有这些编号,则需要提供时间范围。 - `position`:是否按照货位分组,默认为否。 - `status`:出库单状态,这里默认值为110,表示已完成。 - **分页信息**: - `page_size`:每页返回的数据条数,这里设置为50。 - `page_no`:页码,从0开始。 #### 数据请求与清洗 通过上述配置,我们可以构建一个完整的请求体,并发送POST请求到指定API。以下是一个示例代码片段: ```python import requests import datetime # 获取当前时间和上次同步时间 current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') last_sync_time = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S') # 构建请求体 payload = { 'params': { 'start_time': last_sync_time, 'end_time': current_time, 'warehouse_no': '', 'src_order_no': '', 'stockout_no': '', 'position': '', 'status': '110' }, 'pager': { 'page_size': '50', 'page_no': '1' } } # 发起POST请求 response = requests.post('https://api.example.com/wdt.wms.stockout.transfer.querywithdetail', json=payload) # 检查响应状态码并处理数据 if response.status_code == 200: data = response.json() # 数据清洗与转换逻辑 # ... else: print(f"Error occurred: {response.status_code}") ``` #### 数据清洗与转换 在获取到原始数据后,需要对数据进行清洗和转换,以便后续处理。具体步骤包括: 1. **字段提取**:从响应中提取所需字段,如订单编号、仓库编号、商品详情等。 2. **格式转换**:将日期、金额等字段转换为标准格式。 3. **去重与校验**:根据订单编号或其他唯一标识符去重,并校验数据完整性。 以下是一个示例代码片段: ```python def clean_data(raw_data): cleaned_data = [] for item in raw_data['data']: cleaned_item = { 'order_no': item['order_no'], 'warehouse_no': item['warehouse_no'], # 提取并格式化其他字段... # ... # 展平 detail_list 字段 detail_list = item.get('detail_list', []) for detail in detail_list: cleaned_item.update({ f"detail_{key}": value for key, value in detail.items() }) cleaned_data.append(cleaned_item) return cleaned_data # 调用清洗函数 cleaned_data = clean_data(data) ``` 通过以上步骤,我们成功地从旺店通·旗舰奇门接口获取了调拨出库单的数据,并进行了初步的清洗和转换,为后续的数据处理奠定了基础。 ![数据集成平台可视化配置API接口](https://pic.qeasy.cloud/S18.png~tplv-syqr462i7n-qeasy.image) ### 调拨出库单同步至金蝶云星空的ETL转换与写入 在数据集成过程中,将源平台的数据转换为目标平台所能接收的格式是关键的一步。本文将详细探讨如何使用轻易云数据集成平台,将调拨出库单的数据进行ETL转换,并通过金蝶云星空API接口实现数据的写入。 #### 元数据配置解析 元数据配置是实现数据转换和写入的核心。以下是我们将使用的元数据配置: ```json { "api": "batchSave", "method": "POST", "idCheck": true, "operation": { "rowsKey": "array", "rows": 1, "method": "batchArraySave" }, "groupCalculate": { "headerGroup": ["order_no", "consign_time", "detail_list_spec_code"], "bodyGroup": ["detail_list_spec_no", "warehouse_no", "detail_list_defect"], "bodyName": "detail_list", "targetBodyName": "FEntity", "bodyMaxLine": 50, "calculate": { "detail_list_goods_count": "$sum" } }, ... } ``` 该配置文件定义了如何将源数据映射到金蝶云星空API所需的数据结构。以下将逐步解析和应用这些配置。 #### 数据请求与清洗 在ETL过程的第一步,我们需要从源平台请求调拨出库单的数据,并对其进行必要的清洗和预处理。这一步通常包括字段的映射、格式转换以及数据验证等操作。 例如,我们需要将源平台中的`order_no`、`consign_time`等字段提取出来,并根据业务逻辑进行处理,如日期格式化等。 #### 数据转换 接下来,我们将清洗后的数据按照金蝶云星空API接口要求进行转换。以下是关键字段的映射和处理: - **单据编号 (FBillNo)**: 使用`order_no`和`detail_list_spec_code`组合生成。 - **单据类型 (FBillTypeID)**: 固定值为"DBCKD"。 - **库存组织 (FStockOrgId)**: 使用`detail_list_spec_code`。 - **领用组织 (FPickOrgId)**: 同样使用`detail_list_spec_code`。 - **库存方向 (FStockDirect)**: 固定值为"1"。 - **日期 (FDate)**: 使用`consign_time`,并进行日期格式化。 - **领料部门 (FDeptId)**: 固定值为"HY1018"。 - **货主类型 (FOwnerTypeIdHead)**: 固定值为"BD_OwnerOrg"。 - **货主 (FOwnerIdHead)**: 使用`detail_list_spec_code`。 - **备注 (FNote)**: 固定值为"调拨出库单"。 对于明细信息(FEntity),我们需要对每一行明细进行如下映射: - **物料编码 (FMaterialId)**: 使用 `detail_list.detail_list_spec_no`。 - **实发数量 (FQty)**: 使用 `detail_list.detail_list_goods_count` 并进行求和计算。 - **发货仓库 (FStockId)**: 使用 `detail_list.warehouse_no`。 - **库存状态 (FSTOCKSTATUSID)**: 根据 `detail_list.detail_list_defect` 判断,若为真则设为 'KCZT08_SYS',否则设为 'KCZT01_SYS'。 #### 数据写入 完成数据转换后,我们通过调用金蝶云星空API接口,将处理好的数据写入目标平台。以下是具体的请求示例: ```json { "FormId": "STK_MisDelivery", "IsAutoSubmitAndAudit": false, "IsVerifyBaseDataField": true, "Operation": "Save", ... } ``` 在实际操作中,我们会构建一个包含所有必要字段和明细信息的JSON对象,然后通过HTTP POST方法发送至金蝶云星空API接口。 #### 实际案例 假设我们有如下源数据: ```json { "order_no": "ORD12345", ... } ``` 经过上述步骤处理后,生成的目标数据格式如下: ```json { ... } ``` 然后,通过HTTP POST请求将其发送至金蝶云星空API接口,实现调拨出库单的同步。 通过以上步骤,我们成功地将源平台的数据进行了ETL转换,并写入到金蝶云星空系统中。这不仅确保了数据的一致性,还提高了业务流程的自动化程度。 ![数据集成平台可视化配置API接口](https://pic.qeasy.cloud/T28.png~tplv-syqr462i7n-qeasy.image)