fix: recognize corroborated empty Oracle associations

This commit is contained in:
Wyndham ARR committed 2026-10-08 18:58:18 +08:00
1 parent 4559d5a642
commit de9eb532f2
9 files changed
+735 -28

No files matched your search

+20 -3
View File
@@ -633,6 +633,23 @@
return Array.isArray(item.value) ? item.value.join("\n") : String(item.value ?? "");
}
function arrDataReviewReasonKey(item) {
if (item.confirmed) return "confirmed_value";
const sourceState = String(item.source_state || "").toLowerCase();
const reason = String(item.reason_code || "").toUpperCase();
// Older review snapshots do not expose source_state. Recognize only the
// collector's explicit failure codes; a missing optional field is not a
// failed request and does not make the field required.
const failedReasons = ["HTTP_FAILURE", "HTTP_PERMISSION_DENIED", "TRANSPORT_RETRY_EXHAUSTED",
"REQUEST_LIMIT_EXCEEDED", "RESPONSE_TOO_LARGE", "OPERATION_MISMATCH", "HOTEL_MISMATCH",
"INVALID_DATA_ENVELOPE", "MISSING_ORACLE_REQUEST_ID", "SECRET_IN_RESPONSE", "INVALID_JSON",
"UPSTREAM_WARNING_OR_ERROR"];
if (sourceState === "failed" || failedReasons.includes(reason)) return "fetch_failed";
if (sourceState === "ambiguous" || /(?:^|_)(?:CONFLICT|AMBIGUOUS|MISMATCH|DISAGREEMENT|CHANGED)(?:_|$)/.test(reason)) return "conflict_value";
if (/(?:^|_)(?:INVALID|MALFORMED)(?:_|$)/.test(reason) || ["XML_NEGATIVE_NIGHTS", "DATA_NEGATIVE_NIGHTS"].includes(reason)) return "invalid_value";
return item.can_be_empty ? "source_unconfirmed" : "required_value_missing";
}
function arrDataReviewCanFinalize(review = state.arrDataReview) {
return Boolean(arrDownloadNeedsDataReview() && state.arrDownloadTask.request_id === state.arrDataReviewRequestId
&& !state.arrDownloadBusy && review && review.status === "editing" && review.can_finalize && Number(review.pending_count) === 0
@@ -675,8 +692,8 @@
const labelKey = `data_review.field_${field.toLowerCase()}`;
const translatedLabel = I18N.t(labelKey);
const label = translatedLabel === labelKey ? (item.field_label || field) : translatedLabel;
const reason = String(item.reason_code || "").toUpperCase();
const reasonKey = item.confirmed ? "confirmed_value" : /CONFLICT|AMBIGUOUS/.test(reason) ? "conflict_value" : /INVALID|MALFORMED/.test(reason) ? "invalid_value" : "missing_value";
const reasonKey = arrDataReviewReasonKey(item);
const ruleKey = item.can_be_empty ? "optional_field_rule" : "required_field_rule";
const inputId = `arr-data-review-value-${index}`;
const value = Object.prototype.hasOwnProperty.call(state.arrDataReviewDrafts, item.item_id)
? state.arrDataReviewDrafts[item.item_id] : arrDataReviewInputValue(item);
@@ -687,7 +704,7 @@
: `<input id="${inputId}" data-arr-data-review-value type="text" inputmode="${inputMode}" autocomplete="off" value="${escapeHtml(value)}" placeholder="${escapeHtml(placeholder)}" ${editable ? "" : "disabled"} />`;
return `<tr data-arr-data-review-item-id="${escapeHtml(item.item_id)}" class="${item.confirmed ? "is-complete" : ""}">
<td data-label="${escapeHtml(I18N.t("data_review.reservation"))}"><strong>${escapeHtml(item.confirmation_no || "—")}</strong><small>${escapeHtml(I18N.t("data_review.source_row", { sequence: item.source_sequence }))} · ${escapeHtml(I18N.t("data_review.room", { room: item.room_no || "—" }))}</small><small>${escapeHtml(item.company_name || "—")} · ${escapeHtml(item.rate_code || "—")}</small></td>
<td data-label="${escapeHtml(I18N.t("data_review.field"))}"><label for="${inputId}">${escapeHtml(label)}</label><small>${escapeHtml(I18N.t(`data_review.${reasonKey}`))}</small></td>
<td data-label="${escapeHtml(I18N.t("data_review.field"))}"><label for="${inputId}">${escapeHtml(label)}</label><small>${escapeHtml(I18N.t(`data_review.${ruleKey}`))}</small><small>${escapeHtml(I18N.t(`data_review.${reasonKey}`))}</small></td>
<td data-label="${escapeHtml(I18N.t("data_review.value"))}">${input}</td>
<td class="arr-data-review-row-actions" data-label="${escapeHtml(I18N.t("common.operation"))}"><span class="arr-data-review-item-status">${escapeHtml(I18N.t(item.confirmed ? "data_review.confirmed" : "data_review.pending"))}</span><button type="button" data-arr-data-review-save ${editable ? "" : "disabled"}>${escapeHtml(I18N.t("data_review.save"))}</button>${item.can_be_empty ? `<button type="button" data-arr-data-review-empty ${editable ? "" : "disabled"}>${escapeHtml(I18N.t("data_review.confirm_empty"))}</button>` : ""}</td>
</tr>`;
+8 -4
View File
@@ -146,16 +146,20 @@
"arr_download.retry_unavailable": ["该任务不能继续重试,请查看任务日志", "This task cannot be retried. Check the task log.", "ไม่สามารถลองงานนี้อีกครั้ง โปรดดูบันทึกงาน"],
"arr_download.other_active": ["该日期已有进行中的下载任务", "A download for this date is already in progress", "มีงานดาวน์โหลดสำหรับวันที่นี้กำลังดำเนินการอยู่"],
"data_review.title": ["人工完善报表字段", "Complete report fields", "ตรวจสอบและกรอกข้อมูลรายงาน"],
"data_review.copy": ["请核实并逐项保存缺失或有冲突的字段。允许为空的字段也须明确确认,全部完成后才能生成日报。", "Verify and save each missing or conflicting field. Explicitly confirm any allowed empty values, then generate the daily report when all fields are complete.", "ตรวจสอบและบันทึกข้อมูลที่ขาดหายหรือขัดแย้งทีละรายการ ต้องยืนยันค่าที่เว้นว่างได้อย่างชัดเจน ก่อนสร้างรายงานเมื่อครบทุกช่อง"],
"data_review.copy": ["请按各项提示核实来源与原处理规则。可空字段不必补成有值;核实无此信息后,可明确确认留空。全部确认后可生成日报。", "Check each field's source and original processing requirement. Optional fields need no value when none exists; explicitly confirm this after verification. Generate the daily report after all items are confirmed.", "ตรวจสอบแหล่งข้อมูลและข้อกำหนดเดิมของแต่ละช่อง ช่องที่เว้นว่างได้ไม่จำเป็นต้องกรอกค่า หากตรวจสอบแล้วว่าไม่มีข้อมูล ให้ยืนยันการเว้นว่าง สร้างรายงานรายวันได้เมื่อยืนยันครบทุกช่อง"],
"data_review.progress": ["{date} · 已确认 {completed} / {total} 项", "{date} · {completed} of {total} confirmed", "{date} · ยืนยันแล้ว {completed} / {total} รายการ"],
"data_review.reservation": ["预订信息", "Reservation", "ข้อมูลการจอง"],
"data_review.field": ["待完善字段", "Field to review", "ข้อมูลที่ต้องตรวจสอบ"],
"data_review.value": ["核实后的值", "Verified value", "ค่าที่ตรวจสอบแล้ว"],
"data_review.source_row": ["原始记录 {sequence}", "Source row {sequence}", "รายการต้นฉบับ {sequence}"],
"data_review.room": ["房号 {room}", "Room {room}", "ห้อง {room}"],
"data_review.missing_value": ["来源字段缺失,请核实", "Source value missing. Verify it.", "ไม่มีข้อมูลต้นฉบับ โปรดตรวจสอบ"],
"data_review.conflict_value": ["来源值有冲突,请核实", "Source values conflict. Verify them.", "ข้อมูลต้นฉบับขัดแย้งกัน โปรดตรวจสอบ"],
"data_review.invalid_value": ["来源值格式无效,请核实", "Source value is invalid. Verify it.", "รูปแบบข้อมูลต้นฉบับไม่ถูกต้อง โปรดตรวจสอบ"],
"data_review.required_field_rule": ["原处理规则必填,不可为空。", "Required by the original processing rules; cannot be blank.", "กฎการประมวลผลเดิมกำหนดให้กรอก ห้ามเว้นว่าง"],
"data_review.optional_field_rule": ["原处理规则允许为空。", "The original processing rules allow this field to be blank.", "กฎการประมวลผลเดิมอนุญาตให้เว้นช่องนี้ว่างได้"],
"data_review.required_value_missing": ["本次未取得该值,请填写核实后的值。", "This value was not obtained. Enter the verified value.", "ครั้งนี้ไม่ได้รับค่านี้ โปรดกรอกค่าที่ตรวจสอบแล้ว"],
"data_review.source_unconfirmed": ["来源尚未确认。请核实有无此信息;没有则点击“确认无此信息”。", "The source is unconfirmed. Check whether this information exists; if it does not, choose “Confirm no value”.", "ยังยืนยันข้อมูลจากแหล่งต้นทางไม่ได้ โปรดตรวจสอบว่ามีข้อมูลนี้หรือไม่ หากไม่มี ให้เลือก “ยืนยันว่าไม่มีข้อมูล”"],
"data_review.fetch_failed": ["接口读取未完成,请先核实来源,不能直接认定没有此信息。", "The interface read did not complete. Verify the source before concluding that no information exists.", "การอ่านข้อมูลผ่านอินเทอร์เฟซยังไม่เสร็จ โปรดตรวจสอบแหล่งข้อมูลก่อนสรุปว่าไม่มีข้อมูลนี้"],
"data_review.conflict_value": ["来源值有冲突,请核实后填写正确的值。", "Source values conflict. Verify and enter the correct value.", "ข้อมูลต้นฉบับขัดแย้งกัน โปรดตรวจสอบและกรอกค่าที่ถูกต้อง"],
"data_review.invalid_value": ["来源值格式无效,请核实后填写有效的值。", "The source value is invalid. Verify and enter a valid value.", "รูปแบบข้อมูลต้นฉบับไม่ถูกต้อง โปรดตรวจสอบและกรอกค่าที่ใช้ได้"],
"data_review.confirmed_value": ["已使用人工核实值", "Manually verified value saved", "บันทึกค่าที่ตรวจสอบด้วยตนเองแล้ว"],
"data_review.confirmed": ["已确认", "Confirmed", "ยืนยันแล้ว"],
"data_review.pending": ["待确认", "Awaiting confirmation", "รอยืนยัน"],