EBS API Patterns for Uploads Copy link
Plugin: Blitz Report Development (
upload-api-patterns)Works with: Claude Code
Type: Rules loaded automatically when a task needs them
Oracle EBS module API specifics for Blitz Uploads (ONT, PO, INV, WIP, CST, AP, AR, HR, FA, CE, EAM, OPM, PA, QA and more).
When to use it
- Use when an upload package calls an Oracle public API.
Claude Code
- Add the Enginatics marketplace in Claude Code.
/plugin marketplace add enginatics/ai-skills - Install the plugin.
/plugin install blitz-report-ai-skills@enginatics - Run the environment setup once; it describes your EBS development instance (never production).
/blitz-report-ai-skills:blitz-environment-setup - Nothing to run: Claude loads these rules automatically when a task needs them.
- Keep it current: enable auto-update for the enginatics marketplace, or update manually.
/plugin marketplace update enginatics
Requirements: Blitz Report installed on your Oracle EBS development instance, and database access from Claude Code to that instance (Oracle SQLcl MCP server, SQLcl or SQL*Plus). Never point the skills at production.
Module-specific API facts. General rules are in upload-development skill.
General
- Never direct DML on application base tables; interface tables are the exception. Highest-level public API first (
*_PUB/*_API/*_GRP→ interface + concurrent program →*_PKG); supplement with targeted updates only for fields the API cannot set. - Value→id mapping belongs in the LOV/
VALUE_TO_ID_QUERY, never in PL/SQL. - Combine entities the user enters together into one upload; process a repeating parent once (uploads run top-down).
ONT Order (XXEN_ONT_UPLOAD, + _11I)
A line split goes through oe_order_pub.process_order in one call: the original line as an update and each new shipment as a create with split_from_line_id, all carrying split_action_code='SPLIT' and split_by='USER'. OE_SPLIT_UTIL.Check_split_Course rejects the call unless the original's new quantity plus the new shipments equal its current quantity (OE_INVALID_SPLIT_QTY), and a split needs no change reason on a booked line although a plain quantity decrease does. OE_SPLIT_UTIL.Default_Attributes rebuilds each new shipment from the original line and keeps only its quantity, plus request date, warehouse and ship to when split_request_date/split_ship_from/split_ship_to are 'Y'; those three flags exist on every R12 level but not on 11i, where a new shipment takes only its quantity. The upload maps returned line ids back to rows by table index, never through orig_sys_line_ref, which the api copies from the original line onto a split and which is the order's own source reference.
A line price adjustment is passed to oe_order_pub.process_order through line_adj_tbl. A record left at oe_order_pub.g_miss_line_adj_rec because the modifier lookup found nothing is rejected by OE_VALIDATE_LINE_ADJ with OE_ATTRIBUTE_REQUIRED / token List_header (list_line_type_code not in ('COST','TAX') and list_header_id is null) — resolve the modifier line before building the record and error the row yourself when it does not resolve. Take list_line_type_code from qp_list_lines, never hardcode 'DIS': the Discount Modifier LOV offers surcharge lists (list_type_code in ('DLT','SLT')), whose lines are SUR, and the download subqueries read adjustments back with the same set. Back-calculating a % operand from a typed selling price divides by the unit list price, so a zero list price is a validation error, not a guard.
The customer contact (sold_to_contact_id) is a contact record (hz_cust_account_roles), not a person: a person who is a contact at account level and at a site has two records sharing one name and one hz_org_contacts.contact_number, and the contact number can be null. header_val_rec.sold_to_contact resolves the name with rownum=1 and is converted only when <> fnd_api.g_miss_char (OE_HEADER_UTIL.Get_Ids), so a blank never clears it: set sold_to_contact_id directly. line_rec.override_atp_date_code ('Y' or null) needs profile OM: Authorized To Override ATP (OE_SCH_OVER_ATP_NO_AUTH), a schedule ship date or scheduling action on the line (OE_SCH_OVER_ATP_NO_SCH_ACT), and is refused on service, return, drop-ship and quote lines; clearing it reschedules the line with an availability check, which can move the schedule ship date. Both exist on 11i.
oe_order_pub.process_order returns S with warnings left on its message list, among them the duplicate customer PO check (OE_VAL_DUP_PO_NUMBER, profile ONT_ENFORCE_DUP_PO) and credit check holds, so the upload appends that list to its success message; the message type cannot separate warnings from notes (the duplicate PO message has none, credit holds are NOTE like "Order has been booked."). Call it with p_init_msg_list true: the list is not cleared between calls, so every later order of an upload would otherwise report the earlier orders' messages too.
A salesperson is valid for an order when it is date-effective in the operating unit: the Sales Order form's list (ra_salesreps) and OE_VALIDATE.salesrep test start_date_active/end_date_active and ignore jtf_rs_salesreps.status, which is null or I on many records. Filter salesperson lists by the dates, never by status. Names repeat (an end-dated and an active record can share one); oe_value_to_id.salesrep then takes the date-effective one.
OTL Timecard (XXEN_OTL_UPLOAD)
hxc_time_building_blocks is one versioned self-referencing table (TIMECARD→DAY→DETAIL, latest = date_to=31-DEC-4712); attributes via hxc_time_attribute_usages (Projects: category PROJECTS, a1 project_id, a2 task_id, a3 expenditure type NAME; Payroll: category ELEMENT - <element_type_id>); never author SECURITY attributes. Status = hxc_timecard_summary.approval_status (HXC_APPROVAL_STATUS, view_application_id 3). Transferred = hxc_transactions/_details SUCCESS rows. Create: hxc_timestore_deposit.create_time_entry → create_attribute ('Dummy Element Context' = 'ELEMENT - '||id) → execute_deposit_process('SAVE'|'SUBMIT','OTL Deposit Process') (no commit, clears collections). Update: get_timecard_tables → update_building_block/update_attribute; never delete_detail_bb when batching (it reloads from DB, wiping pending edits) — mark date_to/new='N'/changed='Y' on the loaded collection. delete_timecard is immediate. Errors via translate_message_table(convert_to_dpwr_messages(p_messages)). Projects validation uses the SESSION OU; time-entry rules fire at SUBMIT. Eligibility hxc_preference_evaluation.resource_preferences(...,'TS_PER_APPLICATION_SET',...). full_name can be ambiguous — require employee number. Write ids back to _chr shadow columns.
FND Responsibility (XXEN_FND_UPLOAD.create_update_responsibility)
Row types: Responsibility (FND_RESPONSIBILITY_PKG.INSERT_ROW/UPDATE_ROW, then resp_synch; UPDATE_ROW is a full-row write — gate on a real change) and Menu/Function Exclusion (FND_RESP_FUNCTIONS_PKG, key app+resp+rule_type+action_id, add idempotent). Business key = Application + Responsibility Key. VERSION 4/W/M (labels hardcoded, no lookup). Request Group needs request_group_id+group_application_id (id alone not unique). No delete — end-date. Multi-entity UNION filters: primary row on 1=1 + sub-row on 2=2. Assignment FND_FNDSCRSP. Linter I7 flags only non-Function assignment levels.
FND Profile Option Values (XXEN_FND_UPLOAD.upload_profile_option_value)
xxen_util.profile_option_value_sqlturnsfnd_profile_options.sql_validationinto a select ofprofile_option_valueandvisible_option_value; the display function, the upload list of values (profile_option_value_lov) and the value resolution all use it. Validations needing the profile form's context (:PROFILE_QF.*,:LEVEL_CONTEXT.*) or binding the entered value (format checks) yield no list, so the value is saved as entered.- Id-list validations return the stored value as a NUMBER (
MO: Operating Unitselectsorganization_id): compareto_char(x.profile_option_value)with a text value, or the comparison raisesORA-01722. fnd_profile.savereturns false for a level the profile's hierarchy type or enabled flags do not allow, and a null value deletes the row. The server and responsibility hierarchy (SERVRESP) stores both levels at 10007: a responsibility value withlevel_value2-1 or the server node, a server value withlevel_valueandlevel_value_application_id-1.
HR
- Assignment update:
update_emp_asg→ re-query the object version number (OVN) →update_emp_asg_criteria.primary_flagnot updatable.hr_positions_f(not_vl). Person queries datetracked onsysdate. - Organisation:
create_hr_organization,update_organization,create_org_class_internal(notcreate_org_classification),enable/disable_org_classification,create/update_org_information(update blocked for Business Group Information etc.). - Person EIT (
XXEN_PER_UPLOAD.create_update_person_eit): APIhr_person_extra_info_api; types/segments live under DFFExtra Person Info DDF(context columnPEI_INFORMATION_CATEGORY,pei_information1..30), notPER_PEOPLE_EXTRA_INFO. Segment columns callxxen_util.dff_attribute_lov(800,'Extra Person Info DDF',:$column$.information_type,'PEI_INFORMATIONn',...)directly;validate_dff_attributes('PER','Extra Person Info DDF','V','I'). COMMENTS bounded to the filtered context (the all-contextslistaggoverflows at 176 contexts).employee_numberunique only per business group. An EIT invisible in the People form is responsibility security (per_info_type_security), not a bug. - Person Extra Information LOV context:
l_context_codedeclareddescriptive_flex_context_name%type(an unresolved >30-byte context aborted the whole upload withORA-06502). - A person's types are the rows of
per_person_type_usages_f;per_all_people_f.person_type_idof a contingent worker is the genericOTHERtype (External), so a filter or display on it drops or mislabels every contingent worker. Pick one usage per person by system type priority (EMP, CWK, APL, EX_EMP, EX_CWK, EX_APL), asXXEN_PER_UPLOAD.create_update_persondoes. hr_assignment_api.update_emp_asg(12.1.3) ignoresp_concat_segments: the soft coded flexfield change is silently dropped while the call succeeds. Select or create the combination withhr_kflex_utility.ins_or_sel_keyflex_comb('PER','SCL',<pay_legislation_rules rule_type 'S'>,p_concat_segments_in=>...)and passp_soft_coding_keyflex_id.update_emp_asg_criteriadoes honourp_concat_segmentsfor the people group.- Concatenated key flexfield values passed to the HR apis (
'V'mode) hold the DISPLAYED segments only.pay_people_groups.group_nameandhr_soft_coding_keyflex.concatenated_segmentsare written when a combination is created and go stale when the structure changes later (most Vision people groups), so re-sending a stored string can fail withFLEX-MISSING CONCAT VALUES. - HR flexfield errors raise
ORA-20001: FLEX-<NAME>: N, <token>, ..., N, ERRMSG, <text>withhr_utility.get_messageempty; the row message is the text afterERRMSG,.
PO
- Receiving interface:
pie.interface_line_id=rti.interface_transaction_id;org_idrequired on both interface tables (else RVCTP silently skips);RVCTPargs('BATCH',group_id,org_id);auto_transact_code='DELIVER'; receiving subinventory/deliver-to come frompo_distributions_all. - Purchasing Document (
XXEN_PO_UPLOAD): new lines → PDOI; existing Standard PO edits/splits/header-only →po_document_update_grp.update_document, gated onl_interface_line_id is null(notl_po_line_id). "Cannot be changed" checks usevalue_changed(a copy-pasted split flags every cell), falling back tovalue_modifiedwhen the distribution cannot be resolved. Seeded object types (po_pub_*_rec_type) gain attributes across patch levels: construct an empty instance dynamically from theall_type_attrscount (pub_null_args) and set fields by name; never positional constructors. - Ship-to and deliver-to location LOVs filtered by inventory organization must keep the shared locations (
hr_locations.inventory_organization_idnull, the majority on most sites): the PO form and PDOI accept a location whennvl(inventory_organization_id,ship_to_org)=ship_to_org. Ship-to additionally requiresship_to_site_flag='Y'and lists every ship-to location while the ship-to organization is blank; deliver-to has no flag check and lists nothing without an organization. Both exclude inactive locations. Reference: the two LOVs of the PO Purchasing Document Upload andPO Requisition Deliver To Location (active). - Requisition Import writes
SQL Error In Account Generator wfintopo_interface_errors(with a follow-onPO_RI_INVALID_CHARGE_ACC_ID, "Charge account is invalid") whenever the PO Requisition Account Generator raises anything at all:POR_UTIL_PKG.req_imp_act_up_frm_wfholds the generator's message in avarchar2(50)local, andinterface_start_workflowassigns the decoded FND message into thatin out nocopyformal, so any message over 50 bytes dies as ORA-06502 in the samewhen others. The real reason is only recoverable by replaying the interface row throughpor_util_pkg.interface_start_workflowwith a widefb_error_msg, or by keying the line in the Requisition form, which reaches the same workflow throughPO_ACCOUNT_HELPER.req_build_accountswith avarchar2(2000)buffer and shows the message. The generator only runs for interface rows whose charge account segments are ALL null, so supplying the segment columns bypasses it. por_util_pkg.interface_start_workflowtakes 102 arguments on 12.1.3 and 103 on 12.2 (P_MISC_LOA, no default), so a static call compiles on one release only. Build the call dynamically and appendp_misc_loa=>nullwhenuser_argumentsreports it; declare thein outformals inside the dynamic block and bind only the inputs and the outputs you read.po_headers_interface.supply_agreement_flagdoes not exist on 12.2.4 (po_headers_allhas it). Set it only through the dynamic update after the header insert, which errors the row on-904. Never add it to the static insert or to the Error SQL.
WIP (XXEN_WIP_UPLOAD)
wip_interface_errors.error (type 1 = error); load_type 1/4/3 encodes job type; lookups WIP_DISCRETE_JOB/WIP_JOB_STATUS app 700; numeric flags via BOM_SYS_YES_NO (1/2). Mass Load update null handling: most columns nvl(new,old) (cannot clear); schedule_group_id, build_sequence, completion sub/locator, attribute1-15 accept g_miss_* to clear; project/task gated on project. On create they must never receive g_miss_*: Mass Load stores the sentinel literally (9.99e125 lands in wip_discrete_jobs.schedule_group_id/build_sequence) and the ASCP Memory-Based Snapshot then fails with ORA-01455: converting column overflows integer datatype in mslsnj_snp_jobs, whose log blames an unrelated msc_plan_buckets statement. Non-standard jobs without assembly/routing cannot be updated (reexplodeJob returns U). allow_explosion='N' on updates; for creates detect routing/BOM existence to choose substitution_type 3 vs 2, default 'Y' only for header-only creates. Change records on routing-derived operations are dropped on Create+explosion. Pre-validate resource–department. Post-procedure cascades errors per job, cleans interface rows, allocates group_id from wip_job_schedule_interface_s per org (g_miss_num placeholder + request_id scope), stamps source_code='BLITZ:'||request_id/source_line_id=upload_row for post-WICMLP linkage, updates xu.job_name for all creates; request_id_ = the upload request. Phantoms excluded (wip_supply_type<>6).
CST cost import (XXEN_CST_UPLOAD)
CSTPCIMP selects by GROUP ID only and stamps its cost-type parameter on every row — one group per (run, cost type): row proc stamps group_id=conc_request_id, post proc re-stamps cst_lists_s.nextval per cost type; skip the import when nothing was staged. Delete-successful-rows leaves errors with error_flag='E'; hidden in/out ROW_ID joins the error result and updates in place on re-upload. Org LOVs filter cost_organization_id=organization_id and non-process orgs. BASED_ON_ROLLUP defaults Yes when shrinkage ≠ 0 (import rule). Mode 1 insert / 2 replace per item. DFF via validate_dff_attributes('BOM',...). Resource rates: cost_element_id in (3,4), functional_currency_flag<>1; overhead (option 3) serves both dept and resource interfaces, dept duplicate key excludes basis; associations cost_element_id 3/4 with overhead 5 or 2. Deletes are direct (cst_resource_costs) or table handlers (CST_DEPARTMENT_OVERHEADS_PKG/CST_RESOURCE_OVERHEADS_PKG.Delete_Row), resolved by natural key, refused for frozen/non-updateable cost types; Success SQL restores per-row delete messages (case when xu.delete_col is not null) and null-safes the interface-error exclusion. Zoom assignments target the launching form function (never _UPDATE test functions), only cost-type-bearing blocks, mapping the form's cost type to BOTH Target and Source Cost Type. RESOURCE is reserved (RESOURCE_CODE). Cost migration: point the rollup cost type's Default Cost Type at itself while purging/re-uploading, or the rollup back-fills from the default.
INV
- Stock Locator:
inv_loc_wms_pub.create/update/delete_locator; buildl_disabled_datecase-by-case (g_miss_datetrips the disable check).process_kff_combination_1('ALL')returns the escaped concat (\→\\, delimiter →\delim),'<N>'the raw segment;_kfv.concatenated_segmentsis raw; decode withkff_segment_dsp. PJM projects viapjm_projects_all_v+pjm_project_parameters. - Item revisions: stage in
mtl_item_revisions_interface(same INCOIN run); clear with'!', null = no change (API and interface); localvalue_changedhonoursp_upd_on_cre_null_mode; a revision recurring across cross-product rows is processed once (g_item_tbl('R:...')); Success SQL sources baremir.col(custom Error SQL, no delete). Revision DFFMTL_ITEM_REVISIONS(app 401, 15 attrs) viamtl_item_revisions_vl. Never use the mode-blind packageget_new_valuefor the revision merge. - Cross Reference:
MTL_CROSS_REFERENCES_PUB.PROCESS_XREF(CREATE/UPDATE/DELETE, id mandatory for update/delete); NULL clears on update (new_valuecontract fits exactly — no nvl guard); read old description from_vl(_bgoes stale). Field applicability mirrored invalidate_item_xref_row(org vs applicable-to-all, UOM only for the GTIN type, revision needs org). Resolve the item at its master org.ORA-01416in a Success SQL = self outer join from mechanical(+). AssignmentsINV_INVIDXRT,ENG_INVIDXRT,INV_INVIDITM,INV_INVIDITM_ORG. - Item categories in an assigned organization: Item Import copies the master organization's assignment into a newly assigned organization only for default category sets (
mtl_default_category_sets), and as a point-in-time copy of the master's category at that moment, never refreshed afterwards. A user-defined set is never propagated, soAssign To Organizationsstages its ownmtl_item_categories_interfaceCREATE row per organization for org control level sets (mtl_category_sets.control_level=2); a master controlled set is held once on the master organization and needs none. An explicit row for an org controlled default set does not collide with Item Import's own defaulting in the same process set. - Transaction Upload: for source type 3 (Account issue/receipt)
mtl_transactions_interface.transaction_source_idis the distribution account ccid and the transaction manager rejects segments without it (Invalid transaction source segments); Account Alias is a GL shorthand alias (fnd_shorthand_flex_aliases) that only defaults the Distribution Account, so validate the Distribution Account, not the alias. Source type 6 (Account alias issue/receipt) takes its alias (mtl_generic_dispositions) through Transaction Source. - Transaction Upload quantity sign:
mtl_transactions_interface.transaction_quantitymust be negative for issue from stores (transaction_action_id1) and for Intransit Shipment (21), andupload_inv_trxwrites-abs(...)for both on the transaction and on the lot line, so the user may enter either sign. Every other action reaches the interface as entered; a wrong sign there surfaces asTransaction quantity has an incorrect sign for the given transaction action. A Transportation Account that is not the freight code's ownorg_enabled_freight_val_v.distribution_accountis rejected withThe transportation account is not valid for the given freight code, and most Vision freight codes have none. - Locator control is a three-level hierarchy, never an item attribute on its own:
decode(mtl_parameters.stock_locator_control_code,4,decode(mtl_secondary_inventories.locator_type,5,mtl_system_items_b.location_control_code,mtl_secondary_inventories.locator_type),mtl_parameters.stock_locator_control_code). Org holds 1/2/3/4 (4 = defer to subinventory), subinventory 1/2/3/5 (5 = defer to item), item 1/2/3; effective 2 or 3 means a locator is required, 1 means the field is disabled. So a prespecified-locator item in a subinventory with no locator control needs NO locator, and testing only the item'slocation_control_coderejects rows the form accepts. Oracle's own copies of the rule:inv_material_status_grp.get_locator_control(p_org_id,p_inventory_item_id,p_sub_code)(R12 only, absent on 11i, and itswhen othersreturns 1 so a bad subinventory silently reads as "no control") andmtl_inv_validate_grp.locator_control, which additionally collapses 3 to 2 underno_neg_balance- irrelevant when the question is only whether a locator is required.XXEN_INV_UPLOAD.locator_controlis the in-package helper; evaluate the To-Locator of a transfer against the DESTINATION organization and subinventory, not the source. - Item Upload: an item attribute whose control level is Master (Item) is silently dropped when the row targets a CHILD organization -
set_item_attreturns false, so the value never reaches the interface andg_entity_changed_flagstays unset; a row changing only such attributes reports no change rather than an error. Updates only: a create with a non-null value is always taken. The master-controlled set is built at runtime bypopulate_master_attribs_tablefrom each column's COMMENTS query overmtl_item_attributes.control_level, so it follows the site's Item Attribute Controls setup - the same attribute can be org-controlled on one instance and master-controlled on another, and a fixed list must never be assumed. - Item Upload automatic numbering: a blank Item takes its number from
XXEN_UPLOAD_CUSTOM_EXTENSIONS.inv_next_item_numberfirst, then (R12 only) fromEGO_ITEM_PVT.Get_Seq_Gen_Item_Numswhen the nearest catalog up the hierarchy whoseitem_num_gen_methodis notIisS(sequence generated: prefix || sequence || suffix, skipping numbers already used). INCOIN never generates these itself: Product Hub numbers items only in its own import, whereEGO_IMPORT_UTIL_PVT.Preprocess_Importruns the item interface withdefault_flag2 (INVPAGI2.assign_item_header_recs), and that step matches rows onsource_system_id, which upload rows leave blank. Function generated (F) numbers run in the Java import program from Product Hub user-defined attributes, so the upload cannot support them. A master-org create in a catalog whose inheritednew_item_request_reqdresolves toYis rejected first (R12 only): Item Import (INVNIRIS.mtl_validate_nir_item) would create it unapproved as a Pending engineering item that Master Items cannot query, failing its category and child-org assignments with nomtl_interface_errorsrows. 11i Item Import has no such step. - Lot Upload (
upload_lot): decision: create throughinv_lot_api_pub.create_inv_lotand update through the table handlermtl_lot_numbers_pkg.update_row, as the Lot Numbers form (INVTDILT) does.update_inv_lotomitsdescription,curl_wrinkle_foldandvendor_id, skips the global lot attribute propagation (profileINV_GLOBAL_LOT_ATTRIBUTES) and appliesexpiration_dateonly for shelf life codes 2 and 4 with null meaning keep; the handler writes the status and grade history itself, so the upload performs the form's validations before calling it. create_inv_lotwithp_source=>inv_lot_api_pub.invand full validation rejects every shelf life days item whose derived expiry is notsysdate+shelf_life_days(INV_EXP_DATE_NOT_CONSIDER), i.e. any lot with an origination date other than today. The OSFM sources skip that check;osfm_form_validatekeeps thePopulate_Lot_Recordsitem and parent defaulting and the remaining validation.- The
Lot Attributesflexfield (application 401, contextLOT_ATTRIBUTE_CATEGORY) maps segments to namedmtl_lot_numberscolumns (COLOR,VOLUME_UOM,DESCRIPTION, ...) as well asC_/N_/D_ATTRIBUTEn.xxen_util.dff_attribute_value_to_idresolves only the numbered columns;inv_lot_api_pub.wms_lot_attr_validatevalidates the stored values of all of them.
WSH Pick Confirm (XXEN_WSH_UPLOAD)
Rows are pick allocations (mtl_material_transactions_temp keyed by transaction_temp_id), one per lot (mtl_transaction_lots_temp), joined to the delivery line by move_order_line_id. No Create mode: a Yes parameter pre-flags downloaded rows (:confirm_all), a second one (:ship_confirm) rides along as a hidden column into the post procedure. The row procedure only validates, creates a new LPN (wms_container_pub.create_lpn, context pregenerated; existing LPNs accepted only in context 5 or 11) and stages the row's values in a package-global table keyed by task; the post procedure runs once per task over those globals, so a sibling lot row in error blocks the whole task. Confirm sequence: inv_mo_line_detail_util.query_rows(p_line_detail_id) -> set quantities, subinventory, locator, staging location and transfer_lpn_id -> inv_mo_line_detail_util.update_row; lots replaced wholesale with inv_trx_util_pub.delete_lot_ser_trx + insert_lot_trx (a function returning the row id, error text in x_proc_msg); then inv_pick_wave_pick_confirm_pub.pick_confirm (move order type inv_globals.g_move_order_pick_wave, transaction mode 1, inv_trolin_util.query_rows(p_line_id) for the line table). Serial controlled items (control codes 2 and 5) are rejected. Pick confirm splits the delivery detail per lot and keeps the short-pick remainder on the ORIGINAL detail id as backordered; the confirmed material transactions get NEW ids (an issue/receipt pair, transaction_action_id=28, quantities negative on the issue side), so the Success SQL joins the latest negative row by move_order_line_id + source subinventory + locator (mtl_material_transactions_n17) and lots via mtl_transaction_lot_numbers. Ship confirm wsh_deliveries_pub.delivery_action('CONFIRM') only when no line of the delivery is still in R, S or N (backordered B lines are unassigned and do not block); action flag S (ship unspecified quantities): a non-WMS pick leaves shipped_quantity null and flag B backorders the staged line, while a WMS pick fills it. The API returns W for the OTM outbound-interface notice on Vision; treat W as success and append the text. pick_confirm accepts an over-pick (6 of 5) and ship confirm then fails on the over-ship tolerance with the line stuck as over-picked, so reject a picked total above mtl_txn_request_lines.quantity-quantity_delivered before touching the allocation. A row pre-flagged by the Confirm All parameter is processed only once its status is Valid (the add-in validates on upload); a programmatic test file must set Status/Message itself.
WSH Container Items (XXEN_WSH_UPLOAD.upload_container_item)
- No API or table handler writes
wsh_container_items; the form WSHFCNIR writes it directly, so the upload does too (decision).master_organization_idis the organization chosen in the form (child organizations included),master_location_idis always -1. wsh_details_validations.check_decimal_quantitysets its E/W text withfnd_messageonly (wrapped with line feeds), never on thefnd_msg_pubstack, sowsh_util_core.get_messagesreturns nothing; the buffer survives into the next call, so readfnd_message.geton status E or W only.- The
CONTAINER_TYPElookup is view application 3:xxen_util.meaning(code,'CONTAINER_TYPE',3); 401 returns null. - One preferred container per organization and load item: saving a preferred row sets the other row's flag to N without WHO columns, as the form does after asking.
AP
- Invoice Hold:
AP_HOLDS_PKG.UPDATE_ROWis a full-column overwrite by rowid (read the row, pass everything back incl.wf_status);INSERT_SINGLE_HOLDsilently inserts 0 rows when the hold exists (pre-check, re-query id); neverRELEASE_SINGLE_HOLD(ORA-01422 on multiple rows). Resolve holds to a ROWID by PO/line/shipment or invoice line; refuse non-releasable (user_releaseable_flag='N') and invoices under validation. Release Name LOV per hold type/matching. HiddenHOLD_IDguards: already-released → message; visible discriminators override a stale id. 11i twin: 31-argUPDATE_ROW, ROWID handle,po_vendors,fnd_client_info.set_org_contextbefore both calls, passx_held_byexplicitly. ap_vendor_pub_pkg.update_vendor_publicupdates the supplier's organization party (name, alternate name, taxpayer id, tax registration, CEO) only whenp_vendor_rec.employee_idis null, sofnd_api.g_miss_numthere silently skips it while the call returns S. Pass the unchanged employee id or null, never the clear sentinel.- Invoice Payment (
upload_invoice_payment): no public api pays an installment partially or several invoices on one payment, andAP_PAY_SINGLE_INVOICE_PKG.ap_pay_invoice_in_full(one invoice in full) validatesp_internal_bank_acct_idas a bank account id but stores it asap_checks_all.ce_bank_acct_use_id. The upload calls what the Payments window (APXPAWKB) calls:AP_CHECKS_PKG.insert_row->AP_RECONCILIATION_PKG.insert_payment_history(PAYMENT CREATED event) ->AP_PAY_INVOICE_PKG.ap_pay_invoiceper installment (mode PAY; updates the org striped schedule and invoice views, somo_global.set_policy_context('S',org)first) ->ap_pay_update_check_amount->IBY_DISBURSE_SINGLE_PMT_PKG.submit_single_payment, then writes backpayment_idand the IBY number withxla_events_pub_pkg.update_transaction_number. Never insert the invoice payments or update the schedules directly. Void:AP_VOID_PKG.ap_reverse_check(...,p_calling_module=>'SQLAP')(it voids the IBY payment) followed bystatus_lookup_code='VOIDED'/void_date, which the form sets itself.iby_payment_methods_vl.inactive_date. - Commit after each
submit_single_payment: IBY keeps the documents of a payment in the transaction temporary tableiby_docs_in_pmt_gtand never clears it, so a second single payment in the same transaction fails in the post hook withDocument count mismatch after hook operation(row messageException occured when performing payment creation.). xla_accounting_pub_pkg.accounting_program_documentreturns retcode 2 on the development instance for every payment, form-created ones included; check accounting readiness from the unprocessedxla_eventsrow instead.- Distribution Sets (
upload_distribution_set): no API or table handler exists; the form APXSUMDS writesap_distribution_sets_all/ap_distribution_set_lines_alldirectly, so the upload does too (decision). The line percentages must total 0 (Skeleton) or 100 (Full) per set, stored in the header'stotal_percent_distribution;project_accounting_contextholds the literalYes/No(untranslated form parameters); a project line's account comes frompa_acc_gen_wf_pkg.ap_inv_generate_accountand is read-only in the form. - AR/AP bank APIs (
ce_bank_pub,iby_ext_bankacct_pub): NULL = no change,g_miss_char= clear — assign params raw (nonvl(p,stored)); do not switch bank identity columns tovalue_modified(read-only columns are never flagged). Bank/branch update blocks run only when an instrument payment use exists. Japan requires alternate bank/branch names (bank_alt_name,alternate_branch_name). The external bank account's own dates are the exception to NULL = no change:update_ext_bank_acctwritesSTART_DATE=nvl(trunc(p.start_date),sysdate)andEND_DATE=trunc(p.end_date)unconditionally, so a null start date is stamped with sysdate INCLUDING its time and a null end date reactivates an end dated account.iby_disbursement_comp_pub.get_applicable_payee_acc_listteststrunc(sysdate) between start_date and nvl(end_date-1,trunc(sysdate)), so that stamp silently drops the account from payment defaulting and from the unpaid invoice propagation below for the rest of the day. Read the stored dates and pass them back (coalesce(p_start,stored,trunc(sysdate)),nvl(p_end,stored)); the api truncs what it is given, so a stored value that already carries a time is repaired on the next update. The create path truncs correctly, so only updates are affected. - Preserving an UNCHANGED bank account attribute: take the stored value from the
iby_ext_bank_accountsrow, never fromiby_ext_bankacct_pub.get_ext_bank_acct. Called without a security key that getter returnsbank_account_numMASKED and does not return the iban at all, so feeding its record back as the unchanged value storesXXXXXXXXXXXas the number, whichupdate_ext_bank_acctthen rehashes, and blanks the iban; both fail silently and the real number is unrecoverable from the row. Contrary to the bullet above,update_ext_bank_acctassigns most attributes straight from the record (DESCRIPTION = p_rec.description, the contacts, account type, suffix, check digits, secondary reference, andIBANthrough ag_miss_chardecode), so for those a NULL CLEARS rather than meaning no change - onlyBANK_ACCOUNT_NUMand its two hashes arenvlguarded.iby_ext_bank_accountshas nomulti_currency_allowed_flagcolumn and the update does not write it, so a%rowtyperead cannot supply it. The update also re-formats the number through CE country validation: an Italian account keyed1223/03/93comes back001223/03/93, so an api round trip is not value preserving and is the wrong tool for restoring an exact value. - Supplier bank assignment end date → unpaid invoices: only the Supplier page's Update End Date dialog (
IBY_UPDATE_END_DATE_WARNING) repoints them, throughAP_AUTOMATIC_PROPAGATION_PKG.Update_Payment_Schedules; no API, concurrent program or business event does (oracle.apps.iby.bankaccount.assignment_inactivatedis never raised). The routine ignoresp_to_bank_account_idand takes, per schedule, the first accountIBY_DISBURSEMENT_COMP_PUB.Get_Applicable_Payee_Acc_listreturns for the invoice currency (effective today, site → address/OU → address → supplier, then priority). It keeps the old account while that is still applicable, so a future end date changes nothing. It writes NULL to the schedule and invoice header when no account applies, skips schedules with acheckrun_id, swallows every error and does not commit. Passp_party_id: when it is null every lookup fails and the accounts are blanked. Scope follows the ids passed: none = supplier, party site = address, plus org = address/OU. The site page also passes the supplier site, which lands in the address/OU branch.
AR
- Transaction Upload uses
ar_invoice_api_pub.create_invoicesynchronously (not AutoInvoice); returnSdoes not mean success — checkar_trx_errors_gt.ar_trx_header_gt.customer_trx_idis taken fromra_customer_trx_s.nextvalwhen the row goes INTO the GT, before validation, so a header the api rejected still carries an id and has nora_customer_trx_allrow: every post-creation step drives from a join tora_customer_trx_all, never from the GT id alone. Aselect ... intoon it raisesORA-01403that escapessubmit_ar_inv_importand replaces the row's real AR message with a raw stack for the whole batch; a tolerant cursor instead hands the table handler an empty record and updates nothing. Multi-header + explicit sales credits → pass empty and post-processra_cust_trx_line_salesreps_all; "No Sales Credit" = salesrep_id -3. - AutoAccounting (
upload_autoaccounting): no API or table handler writesra_account_defaults_all/ra_account_default_segments(checked on 12.2.15); the form RAXSUAGL writes them directly, so the upload does too (decision). Changing the Revenue or Receivable balancing segment overwrites the balancing segment of the TAX, FREIGHT, UNBILL, UNEARN and SUSPENSE types, as the form does. ra_cust_trx_types_all/ra_batch_sources_allids repeat across OUs: every join carriesorg_id(defaults, LOVs, Success SQL AND validation cursors).ra_customer_trx_allhas one unique key,customer_trx_id.trx_numberrepeats across batch sources, within a source, and within an operating unit (auto-numbering sources each run their own sequence, so overlap is structural), andra_customer_trx_lines_allhas no unique key on (customer_trx_id,line_number,line_type) either — so neither number identifies a row. An id/value LOV on one of them must qualify the colliding values (seeupload-developmentskill § LOVs); the Excel row validator (validate_ar_inv_excel_row: flow-gated, LOV-context-scoped,count(distinct pk), new paramsdefault null) reports what is still unresolvable, it does not make the value unique.ra_batch_sources_allis keyed on (batch_source_id,org_id) — the id alone repeats per OU — andnameis unique per OU, which makes the name the discriminator for a transaction-number list. Outer-join it: transactions referencing a source row that no longer exists are present in Vision.- The Reference field (
ra_customer_trx_all.ct_reference) has exactly ONE writer in the standard table handler:arp_ct_pkg.insert_p/update_prundecode(ra_batch_sources.default_reference,'1',interface_header_attribute1,...,'15',...,null,p_trx_rec.ct_reference,null)against the transaction's own batch source and overwrite the column with the result.generic_updatedoes not carry the column, and the corrective statement is skipped whenbatch_source_idarrives as the no-change sentinel, so the column is then not written at all. Consequences: with a Reference Field Default Value the interface header attribute is the only channel, which is what the Transactions form itself does (typing in Reference changes the matching attribute); without one,arp_process_header_updte_cover.update_header_cover(p_ct_reference=>...)sets it and it survives.ar_invoice_api_pub.trx_header_rec_type.reference_numberis a dead field - nothing on the invoice-create path reads it, so a Reference passed there is silently dropped. Leaveinterface_header_contextnull: the form does,RA_INTERFACE_HEADERhas only seeded contexts (a batch source name is not one, though AutoInvoice writes one into the column without validating it), and bothxxen_fnd_upload.validate_dff_attributesand Oracle's ownValidate_int_Desc_Flexreject an undefined context. On 11iupdate_header_coveris the R12 signature minusp_ct_reference,p_legal_entity_id,p_payment_trxn_extension_idandp_billing_date, so the direct route does not exist and a source without a Reference Field Default Value cannot carry a Reference at all. ar_credit_memo_api_pub.create_requestcopies the credited invoice'sinterface_header_contextAND all 15 interface header attributes whenever the caller's context is null - unconditional assignment, so attribute values the caller passes are discarded; a non-null context suppresses the copy entirely and sends the record through DFF validation instead.ra_batch_sources.copy_inv_tidff_to_cm_flagreads like the control for this and is not: it governs the other flexfield (RA_CUSTOMER_TRXattribute1-15, and only when the caller'sattribute_categoryis null). A credit memo whose batch source has nodefault_referencetherefore comes out with the invoice's attribute copied and a BLANK Reference - not a rare setup, 161 of 1355 invoice-to-credit-memo source links on the development instance, includingManual->MANUAL-OTHER. Set the Reference on the created credit memo withupdate_header_coverrather than trying to pass it in.ar_payment_schedules_allholds one row per INSTALLMENT, so every per-transaction read ofamount_due_remaining/amount_line_items_remaining/tax_remaining/freight_remainingmust aggregate. A scalar subquery over it raisesORA-01427on a split-terms invoice and a top-level select silently returns one arbitrary installment; both pass every test until someone credits an invoice with split payment terms.- "A rule start date must be provided" fires on a MISMATCH with the derived date (Advance = transaction date, Arrears =
trunc(sysdate)), and needs agl_periodsrow of type = accounting rulefrequency; replay theIFin SQL. Please correct the revenue account assignment (<partial account>)(AR message 1360; 1350 receivable, 1370 freight) isarp_auto_accountingreporting that a source named in the operating unit's AutoAccounting definition (ra_account_defaults_all+ra_account_default_segments) carries no account: Standard Lines with neither item nor memo line, a memo line without revenue account or an item without sales account, a salesperson (No Sales Credit, -3, when none is entered) or transaction type without one.AR_INAPI_RULE_INFO_UNNECESSARY= accounting rule id or duration on a line whose header has no invoicing rule.autoaccounting_messagepre-checks the REV and REC sources from the Excel row validator and insubmit_ar_inv_import; keep it a read-only check, never derive the account. Whole-transaction checks belong in the post procedure: a line's distributions may follow on later rows, so a per-row check misfires. The batch API returns its errors inar_trx_errors_gt; the(x)suffix is itsinvalid_value, and on a non-success return the post procedure stages nothing and every still-successful row carries the batch message.get_applied_cm_message_is the first choice in the result SQL's coalesce and answers only for applied credit memo indexes (aboveg_applied_cm_trx_offset); for invoices a header placeholder there would hide every line message, whichget_ar_inv_upload_message_composes.- 11i
create_invoicecompletes only the last transaction of a batch (Oracle bug):XXEN_AR_UPLOAD_11I.submit_ar_inv_importcompletes stragglers fromar_trx_header_gt(replayingpost_commit→complete_flag='Y'→post_commit); never callcreate_invoiceper invoice (clean_gtwipes the GTTs); result Success SQL outer-joinsar_payment_schedules_alland surfacescomplete_flag. - 11i
create_invoicerejects aLOCATIONtax code: leave the line tax code blank underSALES_TAX; a tax-code default helper nulls a LOCATION winner; the LOV excludestax_type='LOCATION'; never make the line tax code required. - Result status is decided at render by getters that DELETE their input (
xxen_ar_upload_results_11i): read the result XLSM, and seed synthetic state to test the getters. Pass the LINE index toget_ar_inv_upload_status_from the message getter. - Customer Upload: party fields via
hz_party_v2pub.update_organization/person(which re-validates the storedcreated_by_module— add orphaned codes toHZ_CREATED_BY_MODULES);provincevsstateby address style (Province/Contact Province columns; contact block cannot clear fields — pre-existing); never add new location columns to the site-matching predicate; address columns blank =Update Level(a USER-level saved default overrides the template's) — read the run's stored parameters. TemplateREQUIREDflags follow the package's "is required" checks, never OR-alternative or auto-generated fields. - Declare every API OUT variable as
<table>.<column>%type. AnumberOUT receiving a varchar2 column (x_party_site_number) works while the value is numeric and fails on the first alphanumeric one withORA-06502 character to number conversion errorat the call line,ORA-06512: at line 0and no API frame: the API succeeded, the copy-back failed. Site, party and account numbers are alphanumeric wherever the customer disables their automatic generation (HZ_GENERATE_PARTY_SITE_NUMBER,HZ_GENERATE_PARTY_NUMBER, AR system optiongenerate_customer_number), which the development instance has enabled; set the profile toNat user level to test a supplied number. - On the development instance every new account fails in
create_cust_accountwith "Provide a positive integer for minimum customer balance amount or percent when balance amount overdue type is amount or percent" because the Vision DEFAULT profile class amounts (hz_cust_prof_class_amts,profile_class_id=0) carrymin_fc_balance_percent=5with a nullmin_fc_balance_overdue_type. For a create E2E set the type toPERCENTon those rows and restore null afterwards. hz_location_v2pub.get_location_recreturnsfnd_api.g_miss_charfor every column that is NULL in the database, EXCEPTsales_tax_geocode, which comes back as a true NULL. Never pass those values on tofnd_flex_descval: the flexfield engine treats the marker as a real value and validates it against the segment's value set, so an untouched US address whosestateis null fails withValue <blank> for the flexfield segment State does not exist in the value set HZ_US_STATESeven though a null state is valid (the segment is not required in the seededPOSTAL_ADDR_USstyle). Strip withnullif(v,fnd_api.g_miss_char)before validating and put the marker back on the way out, so the api still clears the column; any g_miss-vs-null comparison must normalise BOTH sides or thesales_tax_geocodeasymmetry alone reports a change on every row.- Decide whether a location changed by comparing the resolved record against the one
get_location_recreturned, never byg_parameter_tbl.exists('p_l_country'): that only says the Country column is in the template, and Country isREAD_ONLYso it is in every site template. Validating and callingupdate_locationon column presence re-validates and rewrites an address the user never touched. hz_cust_account_site_v2pub.update_cust_acct_sitere-deriveshz_locations.stateandcountyfrom the location's resolved geography, and writes them WITHOUT touching the location'sobject_version_numberor WHO columns. So an unchangedlast_update_dateonhz_locationsdoes NOT prove the row was left alone, and a state that reappears after an upload is not evidence that the location update ran: bisect by calling the apis individually.update_location(only when an address field actually changes),update_party_siteandupdate_cust_site_usedo not do this. It fires only where the geography resolves - a location withgeometry_status_code='DIRTY'never re-derives, so an invented test address cannot reproduce it and a test fixture has to be a real one that already carries a resolved geography.
IEX Collections notes (XXEN_IEX_UPLOAD)
The Unpaid Reason on the Collections notes window is stored on the transaction's DELINQUENCY (iex_delinquencies_all.unpaid_reason_code, one row per payment schedule - unique index IEX_DELINQUENCIES_ALL_U2), never on the note: it applies to every note on that transaction and exists only at IEX_INVOICES (Transaction) level. IEXNTDTL.pll enables the item only for a NEW note record, and populate_unpaid_reason disables it again right after querying it, so the UPDATE_ROW call to set_unpaid_reason is unreachable - the reason is create-only.
IEX_DELINQUENCY_PUB.Create_Ind_Delinquency DISCARDS its own insert unless p_commit is true (ELSE ROLLBACK TO IEX_IND_DEL), which is why the form passes 'T'. Its WHEN OTHERS handler rolls back, COMMITs, and neither re-raises nor sets x_return_status (initialised to S), so a failure returns SUCCESS with an empty x_del_id_tbl - test x_del_id_tbl.count as well as the status, or x_del_id_tbl(1) raises NO_DATA_FOUND. Its p_object_code is IEX_INVOICE, singular, unlike the note's IEX_INVOICES.
IEX_TRX_GRID_PVT.SET_UNPAID_REASON is a bare update iex_delinquencies_all set unpaid_reason_code=... assembled with dbms_sql, with no check against IEX_UNPAID_REASON - validate the code before calling it.
NOTE_CONTROL.UNPAID_REASON_FLAG ('Y' mandatory, 'W' warn, anything else optional) is never assigned by the shipped forms, so a reason is optional out of the box; it is a Forms Personalization hook, not a profile option.
PIM item UDA (XXEN_EGO_UPLOAD.upload_item_uda, + _11I)
ego_item_pub.process_user_attrs_for_item per attribute-group row instance (SYNC/DELETE; keys by unique_key_flag); pass attr_disp_value for value-set attrs; metadata ego_attr_groups_v/ego_attrs_v joined by type+name+application; F-type value sets translate id→value from fnd_flex_validation_tables (neutralise EGO bind comparisons to 1=1); exclude the seeded ItemDetailDesc/ItemDetailImage groups; org LOV "INV Organization Code (including master)" (0B22DF18E239D64AE0630100007FBD85); resolve group display names within the association scope; capture upload_rowid before first-row validation; numeric attrs with a uom_class need a UOM; errors via error_handler.get_message_list (also when status S but count>0). No Function assignment (OAF only). 11i: no data-level model, revision in data_level_1, mtl_item_revisions.
CE Bank Statement (XXEN_CE_UPLOAD)
CE_AUTO_BANK_IMPORT.import_process after setting CE_AUTO_BANK_REC.G_* (G_intra_day_flag='N', G_option='ZALL' + match_process for AutoReconciliation, G_gl_date set or every match errors CE_INVALID_AP_PERIOD); one call per branch (package-global done set); set_policy_context('S',owner org); correction re-upload keys error deletes off the OLD row's account/statement; bank_account_num not unique; ce_transaction_codes has date-effective duplicates; amounts positive, direction from trx_type; Success SQL timestamp-gated (csl.creation_date>=fcr.actual_start_date). Bank/branch: ce_bank_pub, p_country = territory_code, BANK_BRANCH_TYPE lookup, OVNs from hz_organization_profiles/hz_code_assignments/hz_contact_points.
EAM
Assets are CSI instances (EAM_ASSETNUMBER_PUB), linked to FA via csi_i_assets; asset groups/activities/rebuildables are mtl_system_items_b with eam_item_type (use INV Item Upload); asset BOMs via BOM Bill of Materials Upload. EAM_PMDef_Pub.Create_PM_Def needs current_cycle/seq/wo_seq; Update_PM_Def REPLACES all rules; users run XMLSG after. INV org context via fnd_profile.put('MFG_ORGANIZATION_ID',...). csi_counters_tl for names; mtl_eam_locations.start_date/end_date; failure code tables have no org_id; no Delete_FailureSet/Delete_ItemActivity (end-date). Asset Number Upload: read-only context columns from mtl_eam_asset_numbers_all_v (maintenance_object_id). The parent asset is a mtl_object_genealogy link of genealogy type 5 between the assets' mtl_serial_numbers.gen_object_id (the view's gen_object_id and parent_gen_object_id); the asset APIs have no parent argument, so maintain it with inv_genealogy_pub (object type 2, origin 3): update_genealogy end-dates the open link (name p_org_id to select that overload) and insert_genealogy adds the new one with a start date later than that end date, which the API otherwise rejects as an overlap; it also rejects the asset itself or one of its descendants as parent (INV_EAM_GENEALOGY_LOOP). csi_ii_relationships is not involved, and the standard hierarchy page writes no asset log entry. Asset attribute values (the attribute groups of an asset or rebuildable number; DFF MTL_EAM_ASSET_ATTR_VALUES, application 401, columns C_ATTRIBUTE1-20, N_ATTRIBUTE1-10, D_ATTRIBUTE1-10) go through eam_assetattr_value_pub.insert_assetattr_value/update_assetattr_value, identical 57 arguments on 11i: pass item, serial and p_creation_organization_id (no maintenance object) plus the association_id from mtl_eam_asset_attr_groups (item, org, context). The API validates the segments in id mode, so translate the character display values with xxen_util.dff_attribute_value_to_id first and pass number and date columns typed. There is no delete API. On 11i the API additionally checks the organization through eam_common_utilities_pvt.verify_org against the hard-coded responsibility 20539 (Oracle Inventory, application 401) and wip_eam_parameters; without that organization access every row fails with Creation organization Id invalid.
OPM (XXEN_OPM_UPLOAD)
Upper-case document numbers. Per-procedure api_version (formula/recipe header 1; formula detail, recipe vr/routing steps/orgn ops/resources 2). gmd_recipe_detail.recipe_dtl fields: usage_uom, process_um, oprn_line_id, routingstep_id. Operation line = gmd_operation_activities.oprn_line_id by routing step + activity. create_recipe_mtl is insert-only — step/material association edits are base DML (documented). Token names in GMD messages can be misleading — read the IF above the SET_TOKEN. Routing updates need an OPM responsibility with org access (GMD_ROUTING_INVALID/"does not have access to organization" is security, not a bug); dependency inserts need routingstep_no_uom from the dependent step's operation. 12.2.4 lacks fm_rout_dtl.oprn_yield/recipe_yield (accepted drop).
BOM Standard Operations (XXEN_BOM_UPLOAD.upload_std_op)
Table handlers only (bom_std_op_pkg/bom_std_op_res_pkg, direct DML for substitutes); row-by-row with g_last_* cache. Bucket from (line_id presence, operation_type): STD (standard routing operation, no line) / FLE (flow line event) / FLP (flow line process) / FLL (flow line operation). Existence id-first; three hidden rowid round-trips; two savepoints. Applicability gate validate_std_op_excel_row (client + server backstop; accumulates failures space-joined): Value Added/Critical → FLE; Count Point/Autocharge/Backflush/Check Skill → STD; Display Sequence editable FLP/FLL; resources not FLP/FLL, substitutes not FLE; Replacement Group required for substitutes, forbidden on primaries; subinventory/locator, yield, mandatory flags, track dates → STD + WSM org; Shutdown → STD + eAM; Task Type → WMS installed (mfg_lookups WMS_TASK_TYPES, never a value set). The five WSM flags (Operation Yield Enabled, Use Org Settings, Show Next Op, Show Scrap Codes, Show Lot Attributes) default Yes for all types and are editable only in a WSM org (applicable_flag_code); standard-op flags default Yes, editable only in their bucket; count_point_type composed from Count Point+Autocharge. Department read-only except FLP/FLL; Operation Type null = Event (nvl(...,1)); rename detection explicit; Schedule defaults No; substitute-group delete cascades only when no other primary uses the group. Download params: Organization Code (bind), Manufacturing Mode (matching value), Operation Type, Operation Code (grouped LOV), Department, Contains Resource (operation-level in (select ...), still multi-select).
FA
- Mass Additions (
XXEN_FA_UPLOAD.create_update_mass_addition): targetedUPDATE fa_mass_additions SET <changed cols>(neverFA_MASSADD_PREPARE_PKG.update_mass_additions— full-rowSET ROWreplace); Split/Unsplit viaSPLIT_MASS_ADDITIONS_PKG; Create = controlled insert (FA_MASS_ADDITIONS_S,feeder_system_name='BLITZ UPLOAD') then UPDATE the trigger-createdfa_massadd_distributionsrow (never insert a second); Merge Group + Primary Line + Sum Units (order-independent); match by hidden id else business key, ambiguity errors; Split/Merge/Add-to-Asset only on NEW/POST/ON HOLD; Queue =fa_lookups QUEUE NAME; Asset Type meaning fromfa_lookups. fa_mass_additions.depreciate_flag/amortize_flagholdYES/NO(fa_lookups YESNO), notY/N: Post Mass Additions rejects aYwithDepreciate flag &DEPRECIATE_FLAG must be YES or NO.- The mass addition
attribute_category_code/attribute1-30are the asset DFFFA_ADDITIONS(not theFA_MASS_ADDITIONSDFF onCONTEXT). Its context is the category's concatenated segments (context not user-overridable);FA_ADDITION_PVTdefaults it from the category when null and nothing on the post path validates the values, so the upload derives the context from the category and validates withvalidate_dff_attributes('OFA','FA_ADDITIONS','V','I').display_flexfield_valuemust get the value viap_value, since the DFF's table isFA_ADDITIONS_B. - The Queue column displays blank on the development instance (
xxen_util.meaningfinds noQUEUE NAMErows) and that is what keeps unchanged rows uploadable: the Queue list offers only Post/On Hold/Delete/On-Review, so a displayedNewfails id translation (Queue is invalid) on every downloaded row. The 11i twin shows thefa_lookupsmeaning and has that failure. - Asset Upload: DFF via
asset_cat_rec.desc_flex(neverglobal_desc_flex, varchar2(30));update_descreplaces both flex records wholesale (pass current values for uncarried attributes);depreciate_flagchange is its owndo_adjustment; danglinglease_idfails every update (data corruption); tax-book download returns zero rows (open gap — joinfdhviadistribution_source_book).fa_adjustment_pub.do_adjustmentdefaultstransaction_subtypeto EXPENSED — set'AMORTIZED'whenfa_asset_val_pvt.validate_exp_after_amort(asset_id,book)is false (Oracle rejects expensed once a prior amortized adjustment exists) or the user entered an Amortization Start Date; pass that date only whenvalue_modified(the downloaded value is the LAST adjustment's date and would amortize retroactively — unmodified, FA defaults the current period). Assignment changes (expense account/location/employee) go throughfa_transfer_pub.do_transferon the single active distribution; rows of multi-distribution assets carry no distribution identifier, so a changed assignment there is refused. Asset key combinations are created on the fly viafnd_flex_ext.get_ccid('OFA','KEY#',fa_system_controls.asset_key_flex_structure,...); the ASSET_KEY column LOV is value-only for that reason. Category-driven LIFE/PRORATE defaults are guarded withnot existsonfa_additions_bso a category edit does not re-default an existing asset's life.
Discoverer selection upload (XXEN_DIS_UPLOAD)
Post procedure with WORKBOOK_ID among the IN params for per-workbook results; echo pattern for the no-submit path; submit_discoverer_import fences both dedup view levels with /*+ no_merge */ and calls helper_sheet per distinct sheet.
PA Event (XXEN_PA_UPLOAD)
pa_event_pub.create_event populates its out table at index 0 on 11i and 1 on r12 — read l_out.first. A row missing from the result with API status S = empty hidden id column.
MRP/MSC Sourcing Rule Assignment (XXEN_MRP_UPLOAD, XXEN_MSC_UPLOAD, + _11I)
mrp_src_assignment_pub.process_assignment on UPDATE keeps a G_MISS field and clears a NULL one, and rewrites every column with fresh who columns without comparing: send an unchanged set with operation mrp_globals.g_opr_none (no write, the id passes through) and leave an unchanged assignment out of the table. The API validates no DFF segment and stores what it is given. The MSC planning tables have no API or table handler (the forms use direct DML), so the upload merges into the fetched %rowtype and skips the update when nothing changed. msc_sr_assignments.item_type_value is NULL on form-created rows and means Usable (1): compare it as nvl(col,1), like the key cursor and msc_sr_assignments_v. The set columns repeated on every row are applied by the first row of that set in the file only; a Delete Option 'Assignment Set' on a later row is rejected with a message, and decision: a set-level edit on a later row stays silently ignored, as in every other upload with a repeated parent.
QA collection results (XXEN_QA_UPLOAD.collection_result)
- One procedure serves every collection plan: a plan's upload names each column after its element as Oracle names the
Q_<plan>_Vcolumns (upper(translate(qa_chars.name,' ''*{}','_____'))) and maps it to a typed slot (p_char1..40,p_number1..20,p_date1..10); the procedure reads that mapping fromxxen_upload_parametersforxxen_upload.run_id. A new plan needs only an upload XML; the download and Success SQL read the plan view. - Write through
qa_results_pub.insert_row/update_rowwithp_commit=>fnd_api.g_falseandp_enabled_flag=>2; status 1 stores a pending result that the plan views do not show. Passp_who_last_update_login=>fnd_global.login_id(the default is the user id). - The API checks a mandatory element only when it is in the element array, so an insert passes every enabled plan element; an element that is not enabled in the plan ends the call with status U and
ORA-01403. update_rowwrites aqa_results_update_historyrow for every element passed, unchanged ones included: pass only values that differ from the stored ones. A dependent element (qa_chars.dependent_element='Y': Lot, Revision, Serial, UOM, Locator, ...) is validated against package globals set while its parent (Item, Subinventory, ...) is validated in the same array, so a changed dependent element must travel with its parents.- Pass dates as
'YYYY/MM/DD'and numbers throughfnd_number.number_to_canonical. The API rounds numbers silently to the plan or element precision and cuts text at 150 bytes without checking the display length, so text columns takeDATA_LENGTH150. - The API does not check plan effective dates, collection plan security (
qa_web_txn_api.allowed_for_plan('QA_RESULTS_ENTER'|'QA_RESULTS_UPDATE',plan_id)), e-signatures or element defaults, and leaves background actions (QLTACTWB, submitted only withp_committrue), sequence generation (qa_sequence_api.generate_seq_for_txn) and datetime timezone conversion to its other callers. The upload refuses plans with actions and with Sequence or Date and Time elements. fnd_msg_pubholds the API's errors with a(CHAR_ID=n)suffix; build row messages fromx_error_arraywithqa_validation_api.get_error_messageand&CHAR_PROMPTreplaced byqa_plan_element_api.get_prompt.x_message_arrayis indexed from 0.- Assign the uploads to
QARSMDF(Enter Quality Results) andQARSUPD(Update Quality Results);QARSINFis view only.
OKC/OKL contract records
Fields default to OKC_API.G_MISS_*: G_MISS = keep, NULL = set null. Never rec := null (nulls every column); a sparse record is safe; a cleared cell (fnd_api.g_miss_num = okc_api.g_miss_num) reads as keep — detect and refuse explicitly.