Qeasy Cloud
Get Started

Return Document Two-Way Sync in Practice: Breaking Down the Strategy of Querying Returns from a Source ERP and Writing Back to a Service Desk on Qeasy

· 系统管理员· Integration Solutions· 17 views· 5 min read
吉客云班牛轻易云轻易云Qeasy退货同步供应链集成增量策略私有化部署

What This Strategy Solves (Scenario and Value)

On a real engagement with a retail company that had just upgraded its ERP, the after-sales team was still tracking return progress in a separate service desk system. Each system owned its own slice of the work: the ERP issued return documents, while the service desk tracked progress, chased logistics, and handled customer follow-ups. The leadership had a very down-to-earth ask—the moment the ERP produced a new return, a corresponding ticket should appear in the service desk automatically. No more manual re-keying.

The problem is that the source ERP exposes a returns API keyed on a modification-time window, while the target service desk accepts updates against an existing ticket ID. The translation between "pull a time window" and "locate a ticket and back-fill progress" is exactly what this strategy on the Qeasy data integration platform is designed to handle. Its value is not flashy—it is about semantic alignment between two heterogeneous systems, mapping ERP return fields into the statuses and notes the service desk can understand.

Data Flow and Field Mapping

The overall direction of the strategy is Source → Middle Layer → Target: pull return details from the source system, perform field conversion inside Qeasy, and write the result back to the target system.

The source side is a POST endpoint that accepts a time window or an online order number and returns paginated return records. The target side is another POST endpoint that accepts a ticket ID and a contents object—essentially an update-by-ticket operation.

SemanticSource (returns query)Qeasy middle layerTarget (ticket update)
Window entrymodified_begin / modified_endInjected by scheduler
Document numbertradeNoJoin key
Return noteBusiness field (custom)substring_index('{{buyerMemo}}', ':', -1) extracts ticket IDtask_id
Progress / statusReturn processing stageNormalized mappingcontents (object)
PaginationpageSize / pageNoAutomatically managed by Qeasy

A note on that task_id: it is not a direct read of any source field. Instead, it is extracted from the last segment of the source system's buyer memo using substring_index(..., ':', -1). This is a very common pattern we encounter in customer engagements—there is no dedicated association table between the two systems, so a soft association is built on a convention embedded in a text field. It looks rough, but it works in practice.

How to Configure It in Qeasy

Inside Qeasy's strategy configuration page, pick the source ERP connector on the source side and the target service desk platform on the target side, and supply the platform identifier and credentials. In an on-premises deployment, traffic stays on the internal network and credentials never traverse the public internet.

Key points for the source metadata:

  • type=QUERY, effect=QUERY, method=POST.
  • Use tradeNo as the business number field and tradeId as the primary key, with idCheck=true to ensure deduplication.
  • Set autoFillResponse=true so the response structure is auto-registered into Qeasy's data model.
  • Leave the time-window fields modified_begin / modified_end empty for the scheduler to inject.

Key points for the target metadata:

  • type=WebAPI, effect=EXECUTE, method=POST.
  • app_id and project_id are required and have fixed values; write them in directly.
  • The task_id is computed via the expression _function substring_index('{{buyerMemo}}', ':', -1), deriving the soft-associated ticket ID.
  • contents is an object type and is populated by the mapping rules.

Both buildModel flags are set to false on this strategy—the source side is read-only, and the target side updates existing tickets rather than creating new ones, so neither side needs a generated table.

Implementation Steps

We split the rollout into three phases, each visible to the customer's business side.

Phase 1: Align the incremental starting point. After deployment, reconcile by hand with the source system's last-modified time to determine an "incremental starting point." Hard-code this into the scheduler's initial parameters so the first run neither misses historical data nor re-pulls it.

Phase 2: Trigger a full-volume safety net. Once the starting point is agreed, manually trigger a full sync. The source endpoint restricts the window to seven days, so cut historical returns into seven-day slices and process them in multiple rounds. A common pattern we see in the field is "incremental during the day, full-volume safety net at night," giving you a two-track operation.

Phase 3: Scheduling frequency and time window. The crontab is set to */10 8-23 * * *, meaning a run every 10 minutes during working hours. This frequency comes from experience: faster than that and the source endpoint's pagination pressure spikes; slower and the "to-do" in the service desk lags visibly, and the after-sales team will come asking why nothing has shown up.

Lessons Learned From the Field

  1. Boundary semantics differ between systems. Whether the modification-time window is half-open or fully closed is interpreted differently by the two systems. We worked with the customer's business side and compared actual source responses three times to settle this. The safe approach inside Qeasy is to add a one-second "overlap window" on the source side and deduplicate by primary key on the target side—it is better to query one extra second than to miss a record.

  2. Soft-association fields broke overnight when copy was changed. Because task_id is derived from a memo field, an operations copy change to the "return reason" wording wiped out everything after the : separator. In the post-mortem, we recommended the customer codify this convention in their operations SOP, and we added an exception fallback in Qeasy—when the ticket ID cannot be extracted, the original memo is written into contents for traceability.

  3. Do not guess a pagination size. The source endpoint allows a fairly large pageSize, but during a full-volume run a too-large page will blow up memory. Inside Qeasy, we capped pageSize at a moderate value and ran with a "time window first, pagination as fallback" pattern. It is far more stable.

  4. Do not skip idCheck. The idCheck=true setting on the source side looks redundant, but it is the last line of defense for deduplication. If any upstream stage double-posts, the target ticket will be updated twice, and the business side will see the bizarre report of "I just updated this ticket and it was overwritten."

  5. Centralize encoding mappings. Return status and return reason are named differently in the two systems. Do not scatter these mappings across every strategy. In Qeasy we maintain a single central mapping table so that when a new return type is added later, only one place changes and all strategies pick it up.

When This Pattern Fits and When It Does Not

It fits when: the two systems have no existing direct connection, return volume is moderate but timeliness matters, and a soft association with minimal change to either side is acceptable. It does not fit when: return volume is large enough to require streaming, both systems already offer an official direct connector, or the customer explicitly rejects soft-association approaches that rely on convention strings embedded in text fields.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-p2ea595-p887249-5254-qeasy-8ec67d37

Comments