Files
LWLT-AI/mappings/orders_add.mapping.json
2026-07-13 19:57:46 +08:00

494 lines
15 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-07-07.team_order_create.orders_add.v0.1",
"status": "draft_dry_run",
"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": "data.route.name",
"required": true,
"description": "专线名称"
},
{
"target": "TianShu",
"source": "data.trip.label",
"fallback": "derive_trip_label(data.trip.days, data.trip.nights)",
"required": true,
"description": "行程天数,例如 4D3N"
},
{
"target": "zutuanshe",
"source": "data.customer.name",
"required": true,
"description": "预订客户"
},
{
"target": "chanpinming",
"source": "data.product.name",
"required": true,
"description": "产品名称"
},
{
"target": "gendanren",
"source": "data.op_user.name",
"required": true,
"description": "跟单人"
},
{
"target": "xiaoshouren",
"source": "data.sales_user.name",
"required": true,
"description": "销售人"
},
{
"target": "tuanxuhao1",
"source": "data.order_number.prefix",
"required": true,
"description": "团号前缀,通常由专线 lookup 回填"
},
{
"target": "tuanxuhao2",
"source": "data.order_number.suffix",
"required": true,
"description": "团号后缀"
},
{
"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",
"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",
"submit_blocker_if_unresolved": true
},
{
"name": "route",
"source": "data.route",
"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
},
{
"name": "op_user",
"source": "data.op_user",
"display_target": "gendanren",
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProDanwei_Yuangong&fabudanwei=${fabudanwei}",
"match_rule": "exact_staff_name",
"submit_blocker_if_unresolved": true
},
{
"name": "sales_user",
"source": "data.sales_user",
"display_target": "xiaoshouren",
"endpoint_hint": "../dat/AjaxPublicFun.asp?Act=ProDanwei_Yuangong&fabudanwei=${fabudanwei}",
"match_rule": "exact_staff_name",
"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"
],
"clear_and_rebuild_from_standard_operation": [
"receivable_rows"
],
"overwrite_after_product_effect": [
"departure date",
"passenger counts",
"room counts",
"staff fields",
"order suffix",
"notes",
"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": "data.prices.items",
"fallback_strategy": "derive_rows_from_passenger_counts_and_category_prices",
"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.",
"customer, route, product, op_user, and sales_user must be marked resolved by deterministic lookup before submit.",
"customer, route, product, op_user, and sales_user must each match exactly one existing LTJT SelectBox row at runtime; 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 match the standard operation for product, trip, route, route prefix, customer, and customer id.",
"Product-generated receivable rows must be deliberately preserved or cleared/rebuilt from standard operation prices; this mapping currently clears and rebuilds them.",
"customer.ltjt_id is required before submit because it maps to zutuansheid and receivable unit ids.",
"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 browser_order_add_preflight.mjs against a real standard operation whose customer/product/route/staff names exist in LTJT.",
"Compare product-template output with standard operation and block mismatches instead of overwriting them.",
"Decide whether resource defaults from product templates are always preserved or whether upstream resource rows must become explicit standard data.",
"Classify DoInfoJH response scripts on an approved test order before enabling submit mode."
]
}