Authoritative Tutorial on the Kingdee Cloud Sales Order Attachment Query API (BOS_Attachment)
What Problem This API Solves
In supply chain integration between Weaver OA-E9Http and Kingdee Cloud, sales orders typically come with contracts, quotations, signed receipts, and other attachments. These attachments live in Kingdee by default, yet approvals happen in OA—approvers need to view and click through them, and finance needs a unified archive. By pulling attachment metadata via the BOS_Attachment query API into OA, you get traceable approvals, single-source storage, and cross-system visibility.
API Capability Overview
- Authentication: For on-prem Kingdee Cloud, OAuth2 / tenant credentials are exchanged for a token; all calls must carry a Bearer Token in headers.
- Request Structure: HTTP POST; the body follows Kingdee's generic query convention.
FormId:BOS_AttachmentFieldKeys: a curated field set such asFID, FInterID, FAttachmentName, FFileId, FFileStorage, ...FilterString:FInterID='{Id}' and FBillType='{FFormId}'(sales order FormId is typicallySAL_SaleOrder)Limit(page size, default 100),StartRow(starting row, default 0),TopRowCount(cap on rows returned)
- Response Structure: a two-dimensional array; each row is an attachment, the first row is the column header; non-query fields ride on
otherResponse. - Pagination & Incremental: Generic query pages with
StartRow + Limit; for incremental pulls, append aFCreateTimeorFModifyTimewindow toFilterString.
Typical Field Mapping
| Field | Type | Meaning | Practical Notes |
|---|---|---|---|
| FID | string | Attachment PK; metadata id and number both point here | Cross-system unique key—store as OA attachment's custom PK |
| FInterID | string | Master ID of the related sales order | FilterString input; fetched from sales order API first |
| FBillType | string | Business object code | Sales order → SAL_SaleOrder; never mix across objects |
| FBillNo | string | Related sales order number | For human reconciliation and OA flow mapping |
| FAttachmentName | string | Original file name | Includes extension; used for OA display and download |
| FaliasFileName | string | Alias / display name | May differ from original; prefer for display |
| FExtName | string | File extension | Drives icon and type judgment on OA |
| FAttachmentSize | string | Size in KB | Unit is KB—convert when showing on OA |
| FFileStorage | string | Storage location | Database or FileServer; decides download path |
| FFileId | string | File-server file identifier | Core field when FFileStorage = FileServer |
| FAttachment | string | Database-stored content reference | Used when FFileStorage = Database |
| FIsAllowDownLoad | string | Download prohibited flag | Mirrors to OA permission; grey out the button if true |
| FThumbnailId | string | Thumbnail code | For image preview in OA |
| FCreateTime / FModifyTime | string | Create / modify time | Anchor fields for incremental sync |
| FCreateMen / FModifyMen | string | Creator / modifier | Mind encoding differences vs OA users |
| FBillStatus | string | Order status | OA may hide attachments before audit |
| FSourceId | string | Source record ID | Trace attachment origin (e.g., uploaded from a line) |
How to Configure It on Qeasy (Qingyi Cloud)
In the Qeasy Data Integration Platform, Kingdee Cloud is wrapped as the "Kingdee Adapter". A typical rollout looks like this:
- Datasource Setup: Pick the Kingdee Cloud on-prem adapter, fill in tenant URL, tenant ID, third-party account, Secret, etc. Qeasy auto-manages the token lifecycle.
- API Selector: Search
executeBillQuery, set FormId toBOS_Attachment, method POST. The platform ships a generic query template. - Field Mapper: In Qeasy's field mapper, drag fields from the table above into target outputs—FID → OA attachment PK by default; FAttachmentName → attachment name; FFileStorage and FFileId drive the download branch.
- Filter Conditions: Express the filter with placeholders, e.g.,
FInterID='${SalesOrder.FInterID}' and FBillType='${SalesOrder.FFormId}', feeding upstream sales order results in as inputs. - Pagination & Throttling: Qeasy pages with Limit/StartRow automatically and ships rate-limit guards to avoid overloading Kingdee.
- Download Branch: When
FFileStorageis FileServer andFIsAllowDownLoadis false, Qeasy's download handler skips that row; otherwise it calls Kingdee's attachment download endpoint usingFFileIdand pushes the binary stream into the OA attachment service. - Target Configuration: This strategy writes a "no-op" target—it's pure query mode, persisting only metadata to Qeasy's transit store or forwarding it downstream.
Cross-Scenario Practical Tips
- FInterID must be ready first: BOS_Attachment is a child table with no business meaning on its own—you need the sales order ID first. This is a classic "header-then-line" chained query pattern.
- FBillType is mandatory: Omitting or mis-typing it pulls attachments from unrelated business objects, causing data pollution—the most common pitfall on this API.
- Storage mode drives the download path: Database →
FAttachment; FileServer →FFileId. Build a conditional branch in the mapper, or downloads will 404. - FID is the stable correlation key: OID and number can be empty for legacy data; FID is the most reliable cross-system PK.
- Use FModifyTime for incremental sync: Attachments can be uploaded after the fact; using
FCreateTimewill miss them. A rolling window onFModifyTimeis safer. - Mind large files and QPS: Don't crank up
Limittoo high (100 is reasonable), and respect the on-prem Kingdee instance's QPS ceiling—Qeasy's rate-limit policy is worth enabling.
Pitfall Review
- Forgot FBillType in FilterString: Filtering only by
FInterID='{Id}'pulled attachments of every type linked to that order, producing duplicates or mismatches in OA. - FAttachmentSize unit confusion: Kingdee uses KB, OA defaults to bytes—a 1 MB file displayed as 1 KB misled approvers into thinking the wrong file was attached.
- Force-downloading when FFileId is empty: In FileServer mode, some legacy attachments have an empty
FFileId. Skipping a null check caused a 500 from Kingdee that failed the whole batch. Best practice: only download when bothFFileStorageandFFileIdare valid. - Wrong sales order FormId: A customer accidentally used a downstream doc's FormId, so FilterString returned an empty set with no error—hard to spot until you trace the input.
- Wrong incremental anchor: Syncing on
FCreateTimemissed attachments uploaded after the approval step; switching toFModifyTimesolved it.
When to Use It
Apply when OA must be integrated with on-prem Kingdee Cloud and approval flows or portals need to view/download ERP attachments. Not suitable for: plain text-only scenarios without attachment needs, or cases where Kingdee attachments have fully migrated to object storage and no longer pass through BOS_Attachment—direct object-storage integration is cheaper there.