Files
LWLT-AIBOT/mappings/orders_add.mapping.json
2026-08-25 10:33:29 +08:00

499 lines
18 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"$schema": "https://local.lwltapi/schemas/ltjt_form_mapping.schema.json",
"mapping_version": "2026-08-11.team_order_create.orders_add.v0.2",
"status": "live_create_and_suffix_override_repeatedly_validated_0.5.81_candidate",
"source": {
"schema": "schemas/standard_system_operation.schema.json",
"action": "team_order_create"
},
"target": {
"form_schema": "schemas/orders_add_form_schema.json",
"page": "/System/Business/orders_add.asp",
"form_id": "ListForm",
"submit_endpoint": "/System/DAT/orders.asp",
"submit_action": "DoInfoJH",
"payload_prefix": "Act=DoInfoJH&",
"response_type": "script"
},
"limits": {
"departure_dates": {
"min": 1,
"max": 1
},
"receivable_rows": {
"max": 10
},
"attachments": {
"max": 2
},
"transport_rows": {
"max": 4
},
"itinerary_days": {
"max": 15
}
},
"required_target_fields": [
"chufa_ri",
"zhuanxianming",
"TianShu",
"zutuanshe",
"chanpinming",
"gendanren",
"tuanxuhao1",
"tuanxuhao2",
"darenshu",
"xiaorenshu",
"ertrenshu",
"yingrenshu",
"quanrenshu",
"xiaoshouren"
],
"direct_fields": [
{
"target": "chufa_ri",
"source": "data.departure_dates[0]",
"transform": "date_yyyy_m_d",
"required": true,
"description": "出发日期"
},
{
"target": "zhuanxianming",
"source": "product/GetProduct-derived route / data.route.name (legacy override)",
"required": false,
"description": "专线名称;产品联动后必须在 ERP 表单中唯一落地"
},
{
"target": "TianShu",
"source": "product/GetProduct-derived trip / data.trip.label (legacy override)",
"fallback": "derive_trip_label(data.trip.days, data.trip.nights) when explicitly supplied",
"required": false,
"description": "行程天数;产品联动后必须在 ERP 表单中唯一落地"
},
{
"target": "zutuanshe",
"source": "data.customer.name (product/GetProduct-derived value is only a post-selection comparison)",
"required": true,
"description": "预订客户;必须由业务请求唯一选定,产品与客户分别解析,来源地不作为跨字段强制匹配"
},
{
"target": "chanpinming",
"source": "data.product.name",
"required": true,
"description": "产品名称"
},
{
"target": "gendanren",
"source": "ERP login default / data.op_user.name (legacy override)",
"required": false,
"description": "跟单人;生产 Skill 不要求用户输入,优先使用当前登录账号默认值"
},
{
"target": "xiaoshouren",
"source": "ERP login default / data.sales_user.name (legacy override)",
"required": false,
"description": "销售人;生产 Skill 不要求用户输入,优先使用当前登录账号默认值"
},
{
"target": "tuanxuhao1",
"source": "product/route-derived order prefix / data.order_number.prefix (legacy override)",
"required": false,
"description": "团号前缀,由产品或线路联动回填"
},
{
"target": "tuanxuhao2",
"source": "ERP/product-generated order suffix; optional data.order_number.suffix is applied only after GetProduct and customer restoration",
"required": false,
"description": "团号后缀;普通 Agent 不生成。若宿主或业务系统明确提供 suffix插件在产品联动后精确覆盖并复核最终空值或覆盖后不一致均阻断提交"
},
{
"target": "darenshu",
"source": "data.passenger_counts.adult",
"transform": "integer_string",
"required": true,
"description": "成人数"
},
{
"target": "xiaorenshu",
"source": "data.passenger_counts.child_bed",
"transform": "integer_string",
"required": true,
"description": "小童占床"
},
{
"target": "ertrenshu",
"source": "data.passenger_counts.child_no_bed",
"transform": "integer_string",
"required": true,
"description": "小童不占床"
},
{
"target": "yingrenshu",
"source": "data.passenger_counts.infant",
"transform": "integer_string",
"required": true,
"description": "婴儿"
},
{
"target": "quanrenshu",
"source": "data.passenger_counts.leader",
"transform": "integer_string",
"required": true,
"description": "领队"
},
{
"target": "danzhuangtai",
"source": "data.system_defaults.business_status",
"default": "预订",
"description": "订单状态 radio"
},
{
"target": "yaobeian",
"source": "data.system_defaults.filing_required",
"default": true,
"transform": "checkbox_yaobeian",
"description": "备案 checkbox真实页面默认序列化为 yaobeian=要备案"
},
{
"target": "fabudanwei",
"source": "data.system_defaults.fabudanwei",
"description": "发布单位,由页面入口和 session 决定;本地 dry-run 可预填"
},
{
"target": "bizhong",
"source": "data.prices.currency",
"fallback": "data.system_defaults.currency",
"description": "客户/价格币种"
},
{
"target": "xiadanbeizhu",
"source": "data.special_requests",
"description": "下单备注"
}
],
"lookup_fields": [
{
"name": "customer",
"source": "data.customer (current product/GetProduct-derived form value is checked but not authoritative)",
"display_target": "zutuanshe",
"id_target": "zutuansheid",
"optional_targets": {
"contact_target": "zutuanshegzr",
"currency_target": "bizhong"
},
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProTravel&fabudanwei=${fabudanwei}",
"match_rule": "exact_name_or_configured_alias",
"required": true,
"submit_blocker_if_unresolved": true,
"source_region_rule": "optional source-region context is report-only; product and customer candidates are resolved independently and a mismatch never blocks DoInfoJH"
},
{
"name": "route",
"source": "data.route or current product/GetProduct-derived form value",
"display_target": "zhuanxianming",
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=GetInformation&fl=3&fls=1&fabudanwei=${fabudanwei}",
"match_rule": "exact_name_or_configured_alias",
"notes": "The LTJT page uses this lookup to set zhuanxianming and tuanxuhao1.",
"submit_blocker_if_unresolved": true
},
{
"name": "product",
"source": "data.product",
"display_target": "chanpinming",
"optional_targets": {
"pricing_metadata_target": "baojia"
},
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProGetProductname&fls=1&fabudanwei=${fabudanwei}; ../dat/AjaxPublicFun.asp?Act=GetProduct&cpm=${chanpinming}",
"match_rule": "exact_name_or_configured_alias",
"submit_blocker_if_unresolved": true,
"source_region_rule": "derive for diagnostics only; never compare product and customer source-region tokens as a write gate"
},
{
"name": "op_user",
"source": "data.op_user or current ERP login default",
"display_target": "gendanren",
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProDanwei_Yuangong&fabudanwei=${fabudanwei}",
"match_rule": "exact_staff_name_or_current_login_default",
"submit_blocker_if_unresolved": true
},
{
"name": "sales_user",
"source": "data.sales_user or current ERP login default",
"display_target": "xiaoshouren",
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProDanwei_Yuangong&fabudanwei=${fabudanwei}",
"match_rule": "exact_staff_name_or_current_login_default",
"submit_blocker_if_unresolved": true
}
],
"selectbox_contract": {
"row_delimiter": "◇",
"column_delimiter": "◆",
"strict_rule": "For SelectBox-bound fields, direct text assignment is not sufficient for production. Runtime must resolve exactly one existing row and apply the page's SetVal mapping.",
"critical_selectboxes": [
{
"name": "trip_days",
"target": "TianShu",
"data_source": "static options",
"match_column": 0,
"set_values": {
"TianShu": 0
}
},
{
"name": "route",
"target": "zhuanxianming",
"endpoint": "../dat/AjaxPublicFun.asp?Act=GetInformation&fl=3&fls=1&fabudanwei=${fabudanwei}",
"observed_row_count": 16,
"observed_column_count": 11,
"match_column": 1,
"set_values": {
"zhuanxianming": 1,
"tuanxuhao1": 3
}
},
{
"name": "product",
"target": "chanpinming",
"endpoint": "../dat/AjaxPublicFun.asp?Act=ProGetProductname&fls=1&fabudanwei=${fabudanwei}",
"observed_row_count": 160,
"observed_column_count": 2,
"match_column": 1,
"set_values": {
"chanpinming": 1
},
"side_effect": "../dat/AjaxPublicFun.asp?Act=GetProduct&cpm=${chanpinming}"
},
{
"name": "customer",
"target": "zutuanshe",
"endpoint": "../dat/AjaxPublicFun.asp?Act=ProTravel&fabudanwei=${fabudanwei}",
"observed_row_count": 93,
"observed_column_count": 6,
"match_column": 2,
"set_values": {
"bizhong": 0,
"zutuansheid": 1,
"zutuanshe": 2,
"lianxiren": 3,
"zutuanshegzr": 4
}
},
{
"name": "staff",
"targets": ["gendanren", "xiaoshouren"],
"endpoint": "../dat/AjaxPublicFun.asp?Act=ProDanwei_Yuangong&fabudanwei=${fabudanwei}",
"observed_row_count": 33,
"observed_column_count": 2,
"match_column": 0,
"set_values": {
"gendanren": 0,
"xiaoshouren": 0
}
}
],
"resource_selectboxes": [
{
"name": "flight",
"target_pattern": "banhao{n}",
"set_values": {
"banhao{n}": 1,
"bancheng{n}": 4,
"banchengs{n}": 5,
"banchang{n}": 6,
"banchangs{n}": 7,
"banshi{n}": 8,
"banshis{n}": 9,
"guankou{n}": 10
}
},
{
"name": "hotel",
"target_pattern": "zhusus{day}",
"observed_row_count": 572,
"observed_column_count": 5,
"set_values": {
"zhusus{day}": 1,
"zhususs{day}": 2
}
},
{
"name": "restaurant",
"target_patterns": ["zaos{day}", "zhongs{day}", "wans{day}"],
"observed_row_count": 199,
"observed_column_count": 5,
"set_values": {
"selected_restaurant_field": 1,
"meal_standard_field": 2,
"settlement_field": 3
}
},
{
"name": "attraction",
"target_pattern": "jingdian{day}_{slot}",
"observed_row_count": 190,
"observed_column_count": 5,
"set_values": {
"jingdian{day}_{slot}": 1,
"jingdians{day}_{slot}": 2,
"jingdianss{day}_{slot}": 3
}
},
{
"name": "receivable_item",
"target_pattern": "ys_xiangmu{n}",
"observed_row_count": 20,
"observed_column_count": 1
},
{
"name": "receivable_detail_or_reserved_resource",
"target_pattern": "ys_shuoming{n}",
"observed_row_count": 54,
"observed_column_count": 3,
"set_values": {
"ys_shuoming{n}": 2
}
}
],
"product_side_effect_contract": {
"trigger_function": "Find_product()",
"endpoint": "../dat/AjaxPublicFun.asp?Act=GetProduct&cpm=${chanpinming}",
"response_type": "script",
"observed_redacted_sample": {
"changed_field_count": 135,
"changed_field_groups": {
"itinerary_text": 9,
"core": 7,
"pricing_receivable": 21,
"resources": 96,
"other": 2
}
},
"must_run_before_final_serialize": true,
"must_block_on_mismatch_fields": [
"chanpinming",
"TianShu",
"zhuanxianming",
"tuanxuhao1",
"zutuanshe",
"zutuansheid"
],
"post_effect_overwrite_policy": {
"preserve_product_template_groups": [
"itinerary_text",
"resources",
"pricing_receivable_metadata"
],
"preserve_product_template_prices_and_rows": true,
"overwrite_after_product_effect": [
"departure date",
"passenger counts",
"room counts",
"staff fields",
"order suffix when explicitly supplied",
"notes when explicitly supplied",
"attachments"
]
}
}
},
"room_count_fields": {
"frenshu0": "data.room_counts.SGL",
"frenshu1": "data.room_counts.TWN",
"frenshu2": "data.room_counts.TRP",
"frenshu3": "data.room_counts.DBL",
"frenshu4": "data.room_counts.HNM",
"frenshu5": "data.room_counts.TL",
"frenshu6": "derive_room_total(data.room_counts)"
},
"receivable_rows": {
"source": "product_template_rows_after_GetProduct",
"fallback_strategy": "use data.prices only for legacy operations when the product template did not populate a category price",
"max_rows": 10,
"targets": {
"unit_name": "ys_danwei{n}",
"unit_id": "ys_danweiid{n}",
"placeholder": "ys_zhanwei{n}",
"item_name": "ys_xiangmu{n}",
"item_detail": "ys_shuoming{n}",
"settlement_method": "ys_fangshi{n}",
"currency": "ys_bizhong{n}",
"quantity": "ys_shuliang{n}",
"unit_price": "ys_danjia{n}",
"amount": "ys_jine{n}",
"paid_amount": "ys_yishoufu{n}",
"remark": "ys_beizhu{n}",
"row_id": "ys_id{n}",
"payment_type": "ys_shoufulei{n}",
"operator": "ys_caozuoren{n}",
"reviewer": "ys_shenheren{n}"
},
"defaults": {
"unit_name": "data.customer.name",
"unit_id": "data.customer.ltjt_id",
"settlement_method": "",
"paid_amount": "0",
"row_id": "",
"payment_type": "0",
"operator": "data.source.operator",
"reviewer": ""
},
"amount_formula": "quantity * unit_price"
},
"attachments": {
"source": "data.attachments",
"target_pattern": "PicFile{n}",
"requires": "ltjt_file_ref",
"max": 2,
"notes": "Local path attachments must be uploaded through LTJT's upload helper before this form payload can reference them."
},
"passenger_list": {
"text_target": "youkexinxis",
"supported_operations_in_this_mapping": [
"none"
],
"notes": "The real passenger-list import/edit workflow has not been captured yet. Do not treat PicFile0/PicFile1 as passenger-list import."
},
"unmapped_or_page_generated_fields": [
"baojia",
"zutuanshegzr",
"caozuoren",
"ddid",
"tdid",
"quanxian",
"session_id",
"ys_shenhe",
"yingfu_jing",
"yingfu_can",
"zhusuanpai",
"daoyoujiesuan",
"youyingshoukuan",
"itinerary day/service rows",
"transport lookup hidden metadata"
],
"validation_rules": [
"submit_mode must be dry_run for this local serializer.",
"action must be team_order_create.",
"departure_dates must contain exactly one date.",
"adult + child_bed + child_no_bed + infant + leader must be greater than zero.",
"expected_total, when provided, must equal the computed passenger total.",
"product must match exactly one existing LTJT product row; customer and route may be resolved by the product template and must then match exactly one existing LTJT row.",
"OP and sales must match exactly one existing LTJT staff row, using the operation override only when present and otherwise the current login default; upstream resolved=true is not enough by itself.",
"Product Find_product/GetProduct side effects must run in the browser before final serialization.",
"Product template output must be nonempty and deterministic; when the standard operation explicitly supplies trip, route, route prefix, customer, or customer id, the product template output must match it.",
"product and customer candidates must each resolve uniquely; source-region context is report-only and never blocks before DoInfoJH",
"data.order_number.suffix is optional and reserved for an explicit host/business-system override; when supplied it is applied after GetProduct and customer restoration, must remain byte-for-byte equal in tuanxuhao2, and is included in the approved payload hash",
"Product-generated receivable rows and prices must be preserved; runtime may update only passenger quantities and derived amounts, with explicit prices used only as a legacy fallback.",
"The operation does not need customer/op/sales price values when the product template and login defaults resolve them; unresolved ERP fields still block before submit.",
"receivable rows must not exceed 10.",
"attachments must already have ltjt_file_ref values.",
"passenger_list.operation must be none for this mapping version."
],
"next_browser_context_work": [
"Run the extension preflight against a formal standard operation whose product and passenger/room facts exist in LTJT; verify customer/route/price/staff values come from product and login defaults.",
"Compare product-template output with standard operation and block mismatches instead of overwriting them.",
"Replay an explicit host-injected order_number.suffix on a newly created September 2026 test object and retain the final tuanxuhao2, server response, and fresh list requery evidence.",
"Reverify product-template price-row positions if LTJT changes its product response shape.",
"Keep DoInfoJH approval hash, execution ID, write-started state, and ERP receipt re-query enabled for formal saves."
]
}