# S04 Voucher Received Skill

## 1. Skill Identity

- catalog_code: `S04`
- skill_id: `voucher_received_skill`
- skill_name: `Voucher Received Skill`
- task_type: `Voucher Received`

Supported voucher subtypes:

- `lian_tai_credit_voucher`
- `bank_transfer_slip`

## 2. Purpose

Use this Skill when the current email contains a real voucher / payment evidence image or PDF and the system needs to create a `Voucher Received` task candidate.

S04 only does these things:

- identify voucher evidence in the current email;
- classify `voucher_subtype`;
- bind one task to one `Group Code`;
- require original voucher image / PDF display;
- output department-routing needs;
- pass post-confirmation intent to update Reservation Type to `PD`.

S04 does not confirm actual payment receipt, generate receipt, write Opera, call Reservation Type API, or create a real task card directly. The information system performs final task creation, hard validation, department workflow, and API execution.

## 3. Scope

S04 covers only current email evidence of these two voucher types.

### 3.1 LianTai Credit Voucher

`voucher_subtype = lian_tai_credit_voucher`

Paper `CREDIT VOUCHER` from LianTai / 泰國聯泰旅運集團有限公司 / `LIAN TAI TRAVEL GROUP (THAILAND) CO., LTD.`

Typical visual signals:

- LT / LianTai logo and company name;
- `CREDIT VOUCHER`;
- fixed fields such as `DATE`, `CODE / 團號`, `IN`, `OUT`;
- room type fields such as `SGL`, `TWN`, `TRP`;
- meal fields such as `B`, `L`, `D`;
- handwritten content, stamp, or signature.

### 3.2 Bank Transfer Slip

`voucher_subtype = bank_transfer_slip`

Bank transfer success screenshot, cash deposit receipt, transaction receipt, payment slip, payment confirmation, or similar visible bank payment / deposit evidence.

## 4. Trigger Rule

Only current email voucher evidence can trigger S04.

Allowed evidence forms:

- current attachment image;
- current inline image;
- current PDF;
- downloaded current file reference.

Do not trigger S04 only from:

- body keyword such as `voucher`, `payment slip`, `send voucher`;
- Thai status saying voucher was sent;
- subject such as `FULL PAYMENT`;
- attachment filename or image filename;
- hotel reply such as `Thank you for your voucher`;
- history-only voucher evidence;
- Excel / QBD / LianTai status without current voucher image / PDF.

If the current email has voucher text but no current voucher image / PDF, do not enter S04. Use S10 for pure message notification, or S99 structured `manual_review` if routing is unsafe.

## 5. Allowed Result Types

S04 only outputs:

- `normal_task`
- `manual_review`

S04 must not output:

- `informational_message`
- `no_action`
- `exception_task`

## 6. Key Context Needed

Main Agent should provide:

- `source_message_id`
- `source_event_index`
- current subject and body
- current voucher image / PDF reference
- current voucher event summary
- subtype evidence
- `Group Code` candidates and sources
- reservation no / confirmation number candidates and sources, if any
- LianTai fixed-field OCR candidates, if any
- directly related thread context for target binding, if needed
- routing context for reservation / group block / booking record lookup
- routing context for pending / incomplete New Booking task lookup

`body_thread` can help bind a current voucher to a target, but cannot trigger S04 by itself.

## 7. Splitting Rule

- One current email with multiple voucher images: split by voucher image when possible.
- One `bank_transfer_slip` that clearly covers multiple `Group Code` values: split by `Group Code`.
- Multiple `lian_tai_credit_voucher` images: split by image and read each image's own `CODE / 團號`.
- Each `ai_task_result` binds one and only one `case_keys.group_code`.
- Do not put an array inside `case_keys.group_code`.
- Use `related_group_codes` only for user display when several tasks share the same voucher.

## 8. Common Output Structure

Both subtypes use the same main task identity:

```json
{
  "task_type": "Voucher Received",
  "skill_id": "voucher_received_skill",
  "voucher_subtype": "",
  "case_keys": {},
  "group_code_source": "",
  "voucher_attachment": {
    "display_original": true,
    "file_reference": "original voucher image/PDF reference"
  },
  "requires_department_routing": false,
  "department_routing": []
}
```

`voucher_attachment` is intentionally high-level. Low-level attachment id, content id, preview URL, file path, thumbnail, and storage details are information-system internals.

## 9. Subtype Rules

### 9.1 LianTai Credit Voucher

For `voucher_subtype = lian_tai_credit_voucher`, use only the fixed `CODE / 團號` or `CODE / 团号` field as `Group Code` source.

Rules:

- Read the handwritten value after `CODE / 團號`.
- If clear, complete, and single-valued, use it as `case_keys.group_code`.
- If blank, blurry, cropped, blocked, unreadable, or conflicting, output `manual_review`.
- Do not use image filename or attachment filename.
- Do not use other handwritten content outside the fixed `CODE / 團號` field.

LianTai voucher does not route to Finance or any department:

```json
{
  "requires_department_routing": false,
  "department_routing": []
}
```

Normal task example:

```json
{
  "result_type": "normal_task",
  "task_type": "Voucher Received",
  "skill_id": "voucher_received_skill",
  "voucher_subtype": "lian_tai_credit_voucher",
  "case_keys": {
    "group_code": "LT260417VIPA"
  },
  "group_code_source": "lian_tai_credit_voucher.code_field",
  "voucher_attachment": {
    "display_original": true,
    "file_reference": "original voucher image/PDF reference"
  },
  "voucher_display_fields": {
    "voucher_date": "17/04/26",
    "check_in_date": "17/04/26",
    "check_out_date": "20/04/26",
    "room_type_text": "2 TWN 2 DBL"
  },
  "requires_department_routing": false,
  "department_routing": []
}
```

`voucher_display_fields` are display-only fields. They must not drive room type mapping, Rate Code, room quantity, price, FIT / Group decision, target validation, or automatic booking update.

If these display fields are unreadable, do not block `normal_task` as long as `CODE / 團號` and target validation are safe.

### 9.2 Bank Transfer Slip

For `voucher_subtype = bank_transfer_slip`, find `Group Code` from current email text or directly related current-email context.

Allowed sources:

- current subject;
- current body;
- directly related quoted / historical text that clearly binds the current slip to a business object;
- routing context based on reliable current-email target evidence.

Do not use these as automatic `Group Code` source:

- bank screenshot memo;
- bank screenshot handwritten text;
- bank reference number;
- bank account number;
- payer / payee;
- QR data;
- payment amount;
- payment date;
- image filename;
- attachment filename;
- arbitrary OCR from the image.

Payment slip requires Finance confirmation through the generic department-routing structure:

```json
{
  "requires_department_routing": true,
  "department_routing": [
    {
      "department": "Finance",
      "purpose": "confirm_payment_received",
      "required": true,
      "status": "pending"
    }
  ]
}
```

`department_routing` is not finance-only. Future routing to FO or other departments should append objects to this array.

Normal task example:

```json
{
  "result_type": "normal_task",
  "task_type": "Voucher Received",
  "skill_id": "voucher_received_skill",
  "voucher_subtype": "bank_transfer_slip",
  "case_keys": {
    "group_code": "LVM260617L6"
  },
  "group_code_source": "email_current_body",
  "voucher_attachment": {
    "display_original": true,
    "file_reference": "original voucher image/PDF reference"
  },
  "related_group_codes": ["LVM260617L6", "LVM260619L6"],
  "requires_department_routing": true,
  "department_routing": [
    {
      "department": "Finance",
      "purpose": "confirm_payment_received",
      "required": true,
      "status": "pending"
    }
  ]
}
```

Do not extract amount, date, bank account, payer, payee, reference number, QR, or memo as S04 business fields. Users inspect those through the displayed original voucher.

## 10. Multiple Group Code Rule

Multiple `Group Code` values for one `bank_transfer_slip` are not an exception.

If one slip covers:

```json
["LVM260617L6", "LVM260619L6"]
```

output two `ai_task_result` records:

```json
{
  "case_keys": {
    "group_code": "LVM260617L6"
  },
  "related_group_codes": ["LVM260617L6", "LVM260619L6"]
}
```

```json
{
  "case_keys": {
    "group_code": "LVM260619L6"
  },
  "related_group_codes": ["LVM260617L6", "LVM260619L6"]
}
```

Both records may share the same `voucher_attachment.file_reference`.

## 11. Reservation Number Rule

Reservation no / confirmation number can be retained as auxiliary evidence and used in routing context.

Do not output `normal_task` only because reservation no is found. If no reliable `Group Code` can be bound, output `manual_review` and preserve the reservation no candidate.

If both `Group Code` and reservation no exist, routing context should verify that they point to the same object. If unclear, output `manual_review`.

## 12. Target Validation Rule

After identifying `Group Code`, validate that S04 can attach the task to a business object.

Check:

1. whether a corresponding valid reservation / group block / booking record exists;
2. if not, whether a pending / open / incomplete New Booking task card can accept the voucher.

If either check passes, S04 may output `normal_task`.

If both fail, output `manual_review`.

If multiple possible targets exist, output `manual_review`.

Do not block S04 only because of:

- suspected duplicate Voucher Received;
- split or partial payment possibility;
- active workflow;
- uncertain target-object status.

Those are information-system hard validations after confirmation.

## 13. Post-Confirmation Action

S04 may pass this intent:

```json
{
  "post_confirm_action": {
    "action": "update_reservation_type",
    "reservation_type": "PD",
    "execute_by": "information_system_after_confirmation"
  }
}
```

Execution timing:

- `bank_transfer_slip`: after Finance confirms payment received.
- `lian_tai_credit_voucher`: after user / information-system confirmation; no Finance routing.

S04 does not call the API.

## 14. Normal Task Conditions

Output `normal_task` only when all are true:

- current email has visible supported voucher image / PDF;
- `voucher_subtype` is clear;
- at least one reliable `Group Code` is identified by subtype rules;
- target validation finds a valid object or pending New Booking task;
- original voucher can be displayed.

Minimum normal task fields:

```json
{
  "result_type": "normal_task",
  "task_type": "Voucher Received",
  "skill_id": "voucher_received_skill",
  "current_or_history": "current",
  "case_keys": {
    "group_code": ""
  },
  "voucher_subtype": "",
  "group_code_source": "",
  "voucher_attachment": {
    "display_original": true,
    "file_reference": ""
  },
  "requires_department_routing": false,
  "department_routing": [],
  "post_confirm_action": {
    "action": "update_reservation_type",
    "reservation_type": "PD",
    "execute_by": "information_system_after_confirmation"
  }
}
```

Subtype additions:

- `lian_tai_credit_voucher`: include `voucher_display_fields` when readable.
- `bank_transfer_slip`: include `related_group_codes` when one voucher covers multiple Group Codes.

## 15. Manual Review

Output S04 `manual_review` when current email has supported or suspected voucher evidence but S04 cannot safely create `normal_task`.

Manual review conditions:

- voucher image / PDF cannot be read or displayed;
- subtype cannot be determined;
- LianTai `CODE / 團號` is unreadable, blank, cropped, blocked, or conflicting;
- bank transfer slip context does not provide `Group Code`;
- multiple voucher images and multiple Group Codes cannot be mapped;
- current/history boundary is unclear;
- only reservation no is found;
- `Group Code` and reservation no relationship is unclear;
- target validation finds no valid object and no pending New Booking task;
- target validation finds multiple possible objects.

Preserve known information:

- `voucher_subtype`, if known;
- `Group Code` candidates;
- reservation no / confirmation number candidates;
- `group_code_source`, if known;
- `voucher_attachment`;
- `voucher_display_fields`, if readable;
- target validation candidates or failure reason.

Manual review structure:

```json
{
  "result_type": "manual_review",
  "task_type": "Voucher Received",
  "skill_id": "voucher_received_skill",
  "current_or_history": "current",
  "manual_review": {
    "reason_code": "",
    "missing_fields": [],
    "blocking_points": [],
    "known_fields": {}
  }
}
```

Recommended `reason_code` values:

- `voucher_attachment_unreadable`
- `voucher_subtype_unclear`
- `lian_tai_code_field_unreadable`
- `lian_tai_code_field_conflicting`
- `bank_transfer_group_code_missing_in_email_text`
- `ambiguous_voucher_group_code_mapping`
- `current_history_boundary_unclear`
- `missing_group_code`
- `only_reservation_number_found`
- `unclear_group_code_reservation_link`
- `target_object_not_found`
- `multiple_target_objects_found`

## 16. Task Card Display

Front-end task card should prioritize:

- original voucher image / PDF;
- `voucher_subtype`;
- current task's single `group_code` or reservation key;
- `related_group_codes`, if several tasks share one bank slip;
- LianTai `voucher_display_fields`;
- department routing state for payment slip.

## 17. Tool Placeholder

- tool_status: `TBD`
- suggested_tool_name: `create_task_card` / `TBD`
- tool_purpose: create Voucher Received task card or manual review card through the information system.
- payload_rule: include target key, voucher subtype, simplified `voucher_attachment`, department routing, related group codes, LianTai display fields, target validation result, and post-confirm action intent.

Use the same unified task-card Tool for both subtypes. Do not create subtype-specific Tools. If Tool is unavailable, still output a valid `ai_task_result`; do not fabricate Tool output.

## 18. Conflict And Fallback

- Supported voucher image / PDF plus safe target: output S04 according to subtype and split rules.
- Supported voucher image / PDF but unsafe target or missing Group Code: output S04 `manual_review`.
- Suspected voucher image / PDF but unclear subtype: output S04 `manual_review`.
- Voucher words but no current voucher evidence: do not enter S04.
- Current email also has New / Update / Cancel / Amend Group Code: split events when safe; otherwise use S99 or structured `manual_review`.
- Voucher only in history: do not output S04 `normal_task`.

## 19. Must Not Do

- Do not trigger from body text, subject, status, filename, or historical hotel reply alone.
- Do not use filename as `Group Code`.
- Do not use bank screenshot memo, handwritten text, reference number, account, payer, payee, QR, amount, or date as automatic `Group Code`.
- Do not use LianTai image content outside fixed `CODE / 團號` as `Group Code`.
- Do not guess unclear handwritten `Group Code`.
- Do not use LianTai display fields for business updates or mapping.
- Do not extract bank payment details as S04 business fields.
- Do not put multiple `Group Code` values in `case_keys.group_code`.
- Do not convert clear multi-Group-Code payment slip into `manual_review`; split tasks.
- Do not output `normal_task` only from reservation no.
- Do not block because of possible duplicate Voucher Received, split payment, active workflow, or object status.
- Do not output `informational_message`, `exception_task`, or `no_action`.
- Do not confirm payment receipt, call Reservation Type API, write Opera, generate receipt, or invent Tool results.
