# 英国VAT相关字段说明

## 新增字段

### 1. is_uk_company (BIT)
- **用途**: 标识是否为英国公司
- **逻辑**: 根据 `bc.Country` 字段，通过 `CountryService::getCountryEnglishName()` 方法判断是否为 "United Kingdom"
- **值**: 
  - `1` (true): 英国公司
  - `0` (false): 非英国公司

### 2. uk_postcode (NVARCHAR(20))
- **用途**: 存储英国公司的邮编
- **逻辑**: 当 `is_uk_company = 1` 时，保存 `bc.CompanyAddressPostcode` 的值
- **值**: 
  - 英国公司: 保存实际邮编值
  - 非英国公司: `NULL`

### 3. vat_number (NVARCHAR(50))
- **用途**: VAT注册税号
- **说明**: RPA 下号后写入（`python/rpa_step2_mtdbind_save.py` / `python/rpa_step3_eori_save.py`）

### 4. mtd_account (NVARCHAR(100))
- **用途**: MTD (Making Tax Digital) 账号
- **说明**: 用于英国税务数字化申报系统；由 RPA 保存步骤（`python/rpa_step1_save.py` / `python/rpa_step2_mtdbind_save.py`）写入

### 5. mtd_password (NVARCHAR(100))
- **用途**: MTD密码
- **说明**: 用于英国税务数字化申报系统认证；由 RPA 保存步骤（`python/rpa_step1_save.py` / `python/rpa_step2_mtdbind_save.py`）写入

### 6. mtd_key (NVARCHAR(500))
- **用途**: MTD密钥
- **说明**: 用于英国税务数字化申报API认证；由 RPA 保存步骤（`python/rpa_step1_save.py` / `python/rpa_step2_mtdbind_save.py`）写入

### 7. DataSource (NVARCHAR(20)，`source`/`api`)
- **用途**: 数据来源标识（API 接口新增）
- **值**：`source`=sync 流程写入（默认值）；`api`=api.php 接口写入
- **说明**：source/API 两侧按「DataSource + source_record_id」联合查重互不干扰；`DataSource='api'` 行上建有过滤唯一索引（见 `sql/add_data_source_and_api_fields.sql`）。**API 行 `source_record_id = API:{bizParam.BusinessId}`**（businessId 缺省时降级 `API:{BusinessSerialNumber}`），防重等值查询并由唯一索引兜底，旧格式行另经 `biz_param` JSON 兼容查重（详见 `docs/API.md`「防重与状态语义」）
- **⚠ 部署顺序**：先执行该迁移脚本（rpa）再部署/重启 sync.php 与 api.php，旧库直接运行会报错

### 8. biz_param (NVARCHAR(MAX))
- **用途**: API 受理时 `bizParam` 原样 JSON 落库
- **说明**: 供 RPA（`python/rpa_step1_save.py` / `rpa_step2_mtdbind_save.py` / `rpa_step3_eori_save.py` / `rpa_step1_get.py`）组装 delivery 统一异步结果通知信封时原样回传；source 行为 NULL

### 9. delivery_notify_log (NVARCHAR(MAX))
- **用途**: 仅 API 行（`DataSource='api'`）delivery 统一异步结果通知的请求参数与投递结果追溯日志
- **说明**: 由 RPA（`python/rpa_step1_save.py` / `rpa_step2_mtdbind_save.py` / `rpa_step3_eori_save.py` 两轮通知、`python/rpa_step1_get.py` 重试达上限通知）投递后写入；JSON 结构 `{url, status: success|failed, http_code, attempts, request, response}`；source 行及未产生通知的 API 行为 NULL。迁移脚本 `sql/add_delivery_notify_fields.sql`（正式库 rpa / 测试库 rpa_test 均可直接执行，幂等；测试库也可随 `rebuild_rpa_test_uk_vat_register.sql` 重建继承）。旧库未迁移时 Python 侧仅告警不中断主流程

### 10. Notify1* / Notify2* 两套列（每轮一套，共 10 列）
- **用途**: 仅 API 行 delivery 统一异步结果通知的请求参数与投递结果（列式结构化，**每轮独立保存、互不覆盖**）
- **类型**: `Notify1Request`/`Notify2Request` NVARCHAR(MAX)（通知请求体）/ `Notify1Response`/`Notify2Response` NVARCHAR(MAX)（响应体）/ `Notify1Status`/`Notify2Status` NVARCHAR(20)（`success`/`failed`）/ `Notify1Attempts`/`Notify2Attempts` INT（投递尝试次数）/ `Notify1Time`/`Notify2Time` DATETIME（GETDATE）
- **说明**: 轮1（`REGISTER_INFO`）由 `python/rpa_step1_save.py` 写 `Notify1*`；轮2（`ISSUED_INFO`）由 `python/rpa_step2_mtdbind_save.py` / `python/rpa_step3_eori_save.py` 写 `Notify2*`。迁移脚本 `sql/add_notify_fields.sql`（正式库 rpa / 测试库 rpa_test 均可直接执行，幂等；测试库也可随 `rebuild_rpa_test_uk_vat_register.sql` 重建继承）。旧库未迁移时 Python 侧仅告警不中断主流程

### 11. code (NVARCHAR(100)) — API 行承载受理流水号
- **用途**: API 行（`DataSource='api'`）存储 `bizParam.BusinessSerialNumber`（受理流水号）。**2026-09-01 起**；此前写 `Data.Code`（已废弃，不再写入任何列）
- **说明**: INSERT/UPDATE 均写当前请求的流水号（随 `biz_param` 列一起刷新）；RPA 四脚本（`rpa_step1_get.py` / `rpa_step1_save.py` / `rpa_step2_mtdbind_save.py` / `rpa_step3_eori_save.py`）`parse_biz_param()` 在 `biz_param` 列缺失/损坏时按 `code` 列回取 `BusinessSerialNumber` 兜底；source 行 `code` 列仍为源库字段值，不受本变更影响

## 实现逻辑

### 国家判断逻辑
```php
// 获取公司国家的英文名
$companyCountryEnglish = $this->countryService->getCountryEnglishName($record->Country);

// 判断是否为英国公司
$isUkCompany = ($companyCountryEnglish === 'United Kingdom');

// 如果是英国公司，保存邮编
$ukPostcode = $isUkCompany ? $record->CompanyAddressPostcode : null;
```

### 支持的国家输入格式
CountryService 支持以下格式的国家输入：
- 二字码: `GB`, `UK`
- 中文名: `英国`
- 英文名: `United Kingdom`

### 数据库更新
- **INSERT**: 新记录会自动计算并设置这些字段
- **UPDATE**: 更新现有记录时会重新计算这些字段

## 文件说明

### SQL脚本
- `sql/add_uk_vat_fields.sql`: 添加新字段的SQL脚本

### 代码更新
- `src/Services/DataSyncService.php`: 
  - `insertToTargetDatabase()`: 新增记录时处理英国字段
  - `updateTargetDatabase()`: 更新记录时处理英国字段

### 测试
- `test/test_uk_fields.php`: 测试国家判断和邮编逻辑的脚本

## 使用说明

1. **执行SQL脚本**:
   ```sql
   -- 在目标数据库中执行
   sql/add_uk_vat_fields.sql
   ```

2. **测试功能**:
   ```bash
   php test/test_uk_fields.php
   ```

3. **运行同步**:
   ```bash
   php bin/sync.php
   ```

## 注意事项

1. `vat_number`, `mtd_account`, `mtd_password`, `mtd_key` 字段为预留字段，后续会补充具体的更新逻辑
2. 英国判断基于 CountryService 的国家映射，确保数据库中的国家数据准确
3. 所有新字段都允许 NULL 值，向后兼容现有数据