---
# System prepended metadata

title: 權益移回相關工作盤點

---

# 權益移回相關工作盤點


### 將過期的會員主檔改為 斷訂戶2/贈閱結束5

1. subscribeStatus: 1:現訂戶 2:斷訂戶 3:止寄 4:贈閱 5:贈閱結束


- [ ] 數位產品要過期七天(寬限期)才改嗎？
- [ ] 

```sql
SELECT * FROM CustomerSubscribe WHERE rightDueDate < now()
AND subscribeStatus IN ('1','4');
-- 將過期的會員主檔改為 斷訂戶2/贈閱結束5
UPDATE MemberSubscribe SET subscribeStatus = '2' WHERE rightDueDate < now()
AND subscribeStatus = '1';
UPDATE MemberSubscribe SET subscribeStatus = '5' WHERE rightDueDate < now()
AND subscribeStatus = '4';

```




### 續訂單邏輯

1. 根據訂單提供的方案代碼建立續訂單。
2. 續定日期依據方案內容的商品，以收件人權益到期日(數位商品)或是到期雜誌出刊日(雜誌)，先到的日期的**前一天**為續訂單扣款日。
3. 扣款日前七天發送扣款通知信件給(客戶)付款人，月訂制商品只發送第一次。
4. 扣款日當天續訂單會依據設定自動建立一張新的訂單，並啟動金流請款，若是數位商品，會設定七天的臨時權益。
5. 若能成功請款，就會開始計算權益，並產生下一張續訂單；若無法成功請款，會發出扣款失敗通知信給客戶(付款人)。信中提供修改信用卡號的連結，客戶可以修改卡號，並能在會員中心看見扣款失敗的訂單，重新請求扣款，便能完成訂單交易。

### 續訂單後蓋前邏輯

1. 建立續訂單之前，如果該客戶已經有續訂中的續訂單，則取出續訂單中的方案內容與新訂單中的方案進行比較。
2. 若新的續訂方案包含的產品無法完全包含原本續訂單的內容，則會建立新的續訂單，不影響原本的續訂單，客戶會看見兩張續訂中的續訂單。
3. 若新的續訂方案包含的產品完全包含原本續訂單的內容，則會採用新的續訂方案進行續訂，將原本的續訂單狀態改為過期。
4. 若新的續訂方案包含的產品屬於原本的續訂單，則會更新原本續訂單日期，不建立新的續訂單。

|原續訂單產品|新訂單續訂產品|續訂結果|
|--|--|--|
|天下+全閱讀|天下+全閱讀|建立新的續訂單；將原本續訂單過期|
|天下|天下+全閱讀|建立新的續訂單；將原本續訂單過期|
|天下+全閱讀|天下+全閱讀+換日線|建立新的續訂單；將原本續訂單過期|
|天下+全閱讀+換日線|天下+全閱讀+微笑季刊|建立新的續訂單；根據權益到期日調整原本續訂單扣款日|
|天下+全閱讀|全閱讀|根據權益到期日調整原本續訂單扣款日|




### 現訂戶的權益可以先更新

贈閱單是否會列入權益計算

10/21 到期

|item|action|data from|time|duration|
|--|--|--|--|--|
|關貿臨時權益匯入|1500筆匯入MemberProfile|SQL dump CSV|約10分|可提前|
|APP權益現訂戶|8000筆|SQL CSV|約150分|當天匯入|
|APP權益斷訂戶|140000筆|SQL CSV|約3000分|事後匯入，不建續訂單|
|ERP權益檔的Customer資料|80萬筆| |1小時5萬筆,約16小時|
|ERP權益檔 11/2之後有效的權益|8萬筆| |1.5小時|
|關貿資料匯出| | |約30分|
|關貿全閱讀權益現訂戶|26000筆|SQL CSV|約90分|
|關貿全閱讀權益斷訂戶|37000筆|SQL CSV|約150分|
|ERP雜誌權益||spreadsheet|約120分||
|ERP雜誌客戶狀態||spreadsheet|約120分||
|ERP續訂單||spreadsheet|約30分||
|ERP續訂單repay token|||-|待綠界回覆|
|關貿會員、訂戶關聯|30萬筆|SQL CSV|約360分||



## 開帳當天

### 建立Customer

匯入localCustomer.csv

```sql
-- 建立差異化資料
INSERT INTO Customer(id, customerNo, `name`, email, phone, createdAt, updatedAt, parent, address, customerID)
SELECT lc.* FROM localCustomer lc LEFT JOIN Customer c ON lc.customerNo = c.customerNo WHERE c.customerNo IS NULL AND lc.customerID IS NULL

```


#### 全閱讀權益匯入

全閱讀現訂：25662 / 90min
全閱讀斷訂：36897 / 150min

```console
python3 spreadsheet.py -s csv -m upsertMemberSubscribe -c 1
```
### 3. 開帳，更新MemberSubscribeInfoes

```sql
INSERT INTO MemberSubscribeInfo(id, endVolume, endVolumeDate, `status`, createdAt, updatedAt, customerSubscribe)
SELECT cs.id, cs.endVolume, cs.endVolumeDate, "1" AS `status`, cs.createdAt AS createdAt, cs.updatedAt AS updatedAt, cs.id AS customerSubscribe 
FROM CustomerSubscribe cs LEFT JOIN CustomerSubscribeInfo csi ON cs.id = csi.customerSubscribe WHERE csi.id IS NULL
```
更新ERP匯入的權益資料
### 0. 執行ETL跑權益檔，更新雜誌訂戶權益

前置：Vivi提供excel，存成customer.csv
這個動作會先將customer建立起來，再依據權益，寫入customerSubscribe
如果現訂戶，訂戶狀態為"2"，續訂狀態一律為"0"，由續訂單寫入時變更
```console
# 約 2hrs
> python3 spreadsheet.py -s csv -m subscribe -c 30
```
### 最後執行：訂戶/會員關聯 358274

根據關貿MEMBERSUBNO, 建立會員/訂戶關聯，共358274筆，大約6hr

```console
python3 spreadsheet.py -s csv -m memberRelatedCustomer -c 1
```

## 雜誌權益匯入中台
### 0. 將Vivi提供的權益轉入中台 - 本機到測試機約2hr

1. 整理csv
2. 更新Owen給的檔案（訂戶身份)
```console
python3 spreadsheet.py -s csv -m subscribe_1023 -c 30      
```

### 1. 更新ERP匯入的權益資料CustomerSubscribe.endVolumeDate & CustomerSubscribe.rightDueDate - 測試機 30 mins
```sql
-- 重複12個產品
DELETE  FROM CustomerSubscribe WHERE endVolume = 0;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '天下' AND cs.productCode = 'GCV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '天下' AND cs.productCode = 'GCV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '康健' AND cs.productCode = 'GHV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '康健' AND cs.productCode = 'GHV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = 'Cheers' AND cs.productCode = 'GJV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = 'Cheers' AND cs.productCode = 'GJV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '親子天下' AND cs.productCode = 'GKV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '親子天下' AND cs.productCode = 'GKV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;


UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '天下電子' AND cs.productCode = 'FCV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '天下電子' AND cs.productCode = 'FCV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '康健電子' AND cs.productCode = 'FHV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '康健電子' AND cs.productCode = 'FHV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = 'Cheers電子' AND cs.productCode = 'FJV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = 'Cheers電子' AND cs.productCode = 'FJV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '親子天下電子' AND cs.productCode = 'FKV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '親子天下電子' AND cs.productCode = 'FKV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

-- # ,"GRV" // (換日線)
-- # ,"GMV" // (微笑季刊)
-- # ,"GSV" // (小行星幼兒誌)
-- # ,"FRV" // (換日線電子)
-- # ,"FMV" // (微笑台灣電子)   

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '換日線' AND cs.productCode = 'GRV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '換日線' AND cs.productCode = 'GRV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '微笑季刊' AND cs.productCode = 'GMV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '微笑季刊' AND cs.productCode = 'GMV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '小行星幼兒誌' AND cs.productCode = 'GSV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '小行星幼兒誌' AND cs.productCode = 'GSV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '換日線電子' AND cs.productCode = 'FRV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '換日線電子' AND cs.productCode = 'FRV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = cs.endVolume
AND i.category = '雜誌' AND i.subCategory = '微笑台灣電子' AND cs.productCode = 'FMV'
AND i.itemStatus = 'Active' SET cs.endVolumeDate = i.publishDate;
UPDATE CustomerSubscribe cs INNER JOIN Item i ON i.mzVolume = (cs.endVolume+1)
AND i.category = '雜誌' AND i.subCategory = '微笑台灣電子' AND cs.productCode = 'FMV'
AND i.itemStatus = 'Active' SET cs.rightDueDate = i.publishDate;

```
### 3. 開帳，更新CustomerSubscribeInfoes - 測試機 15s

```sql
INSERT INTO CustomerSubscribeInfo(id, endVolume, endVolumeDate, `status`, createdAt, updatedAt, customerSubscribe)
SELECT cs.id, cs.endVolume, cs.endVolumeDate, "1" AS `status`, cs.createdAt AS createdAt, cs.updatedAt AS updatedAt, cs.id AS customerSubscribe 
FROM CustomerSubscribe cs LEFT JOIN CustomerSubscribeInfo csi ON cs.id = csi.customerSubscribe WHERE csi.id IS NULL;
```

### 4. 執行ETL跑續訂單，更新renewStatus

1. 會建立upsertCustomer假檔



```console
# 約 2hrs
> python3 spreadsheet.py -m upsertRenew -c 30 -j 5000 -t 6000
> python3 spreadsheet.py -m upsertRenew -c 30
```
### 5. 回補customerStatus: null
```sql
UPDATE CustomerSubscribe SET subscribeStatus = "1"
WHERE subscribeStatus IS NULL
AND endVolumeDate >= '2020-11-01 16:00:00';

UPDATE CustomerSubscribe SET subscribeStatus = "2"
WHERE subscribeStatus IS NULL
AND endVolumeDate < '2020-11-01 16:00:00';

UPDATE CustomerSubscribe SET subscribeStatus = "5"
WHERE subscribeStatus IS NULL
AND endVolumeDate IS NULL;
```

### 6. 更新ValidDate到MemberProfile 大約10m

1. output
```sql
SELECT M.[SERNO]
      ,CONVERT(VARCHAR(MAX), CAST('' AS XML).value('xs:base64Binary(sql:column("EMAIL"))', 'VARBINARY(MAX)')) AS EMAIL
      ,[MEMBERID]
      ,[USERID]
      ,[CVALIDDAYS]
      ,[HVALIDDAYS]
      ,[JVALIDDAYS]
      ,[KVALIDDAYS]
      ,[CVALIDDATE]
      ,[HVALIDDATE]
      ,[JVALIDDATE]
      ,[KVALIDDATE]
      ,[WVALIDDATE]
      ,[MARKETINGYN]
      ,[VERIFYSTATUS]
      ,[CONTENTYN]
      ,[UUID]
  FROM [PCWMMCS].[sche_pcwmmcsmgr].[MEMBER] M 
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORHT] S ON M.EMAIL = S.RCVEMAIL
  WHERE (CVALIDDATE >= GETDATE() OR  HVALIDDATE >= GETDATE() OR JVALIDDATE >= GETDATE() OR KVALIDDATE >= GETDATE() OR WVALIDDATE >= GETDATE())
```
2. python3 spreadsheet.py -s csv -m upsertMemberProfile -c 30 

### 7. 更新訂戶與會員關聯，30萬筆，大約5hr

1. download csv to memberRelatedCustomer.csv
```sql
SELECT [SERNO]
      ,[USERID]
      ,[SUBNO]
      ,[KNOWLEDGEYN]
      ,[CREATEUSER]
      ,[CREATETIME]
      ,[UPDATEUSER]
      ,[UPDATETIME]
      ,[SYSMEMO]
  FROM [PCWMMCS].[sche_pcwmmcsmgr].[MEMBERSUBNO]
```

2. python3 spreadsheet.py -s csv -m memberRelatedCustomer -c 30







## 訂閱單

數位產品：
1. 數次產品建立完整/待更新訂單
2. 數位產品建立新會員
3. 更新待更新訂單

訂單中台
1. 完整訂單可計算權益
2. 訂單更新可計算權益

訂閱中台
1. 更新訂單資料重新取訂戶資料


## APP

IAP Server backlogs:

1. 建立訂單時如果綁定會員，建立APP訂單
2. 綁定會員時，將所有訂單送出
3. 到期日檢查APP扣款成功時，建立APP訂單
4. APP取消續訂時，通知中台更新權益主檔的狀態


```mermaid
sequenceDiagram
  title: APP 訂閱單開通流程
  APP->>+APP Store: 購買訂閱商品
  APP Store-->>-APP: 購買成功
  opt 會員綁定
  APP->>+IAP Server: Request
  IAP Server->>訂單平台: Async建立訂單
  IAP Server->>-APP: Done
  note over 訂閱平台: 開通權益<br>更新訂閱、續訂狀態
  訂單平台->>訂閱平台: Async開通權益
  訂閱平台->>訂單平台: Webhook權益開通完成
  訂單平台->>訂單平台: 建立續訂單
  end
```

```mermaid
sequenceDiagram
  title: APP 續訂單開通流程
  IAP Server->>APP Store: Daily 到期訂單查詢
  APP Store->>IAP Server: result
  alt APP新訂單建立成功
      IAP Server->>訂單中台: Async 建立APP訂單流程
  else APP無新建訂單
      IAP Server->>訂單中台: Async 訂閱權限取消
  end
```



- 天下
- 每日報
    - 須申請新的料號、ProductCode, 續訂型商品




## 關貿會員資料檔

1. 轉移VALIDDATE > GETDATE()大約1700筆。
2. 建立spreedsheet同步機制
3. 客服後台新增會員臨時權益異動機制，Webhook給數位產品即時開通權益
4. member-api 調整權益查詢範圍

```sql


SELECT TOP (1000) 
      SD.*
      ,M.[SERNO]
      ,CONVERT(VARCHAR(MAX), CAST('' AS XML).value('xs:base64Binary(sql:column("EMAIL"))', 'VARBINARY(MAX)')) AS EMAIL
      ,[MEMBERID]
    --   ,[USERID]
      ,[CVALIDDAYS]
      ,[HVALIDDAYS]
      ,[JVALIDDAYS]
      ,[KVALIDDAYS]
      ,[CVALIDDATE]
      ,[HVALIDDATE]
      ,[JVALIDDATE]
      ,[KVALIDDATE]
      ,[WVALIDDATE]
      ,[MARKETINGYN]
      ,[VERIFYSTATUS]
      ,[CONTENTYN]
      ,[UUID]
      ,MS.SUBNO
  FROM [PCWMMCS].[sche_pcwmmcsmgr].[MEMBER] M 
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[APPSUBSCRIPTOR] A ON M.USERID = A.USERID
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[MEMBERSUBNO] MS ON M.USERID = MS.USERID
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORHT] S ON MS.SUBNO = S.SUBNO
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORDL] SD ON S.SERNO = SD.SUBSCRIPTOR_SERNO
  LEFT OUTER JOIN [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORDLHIS] SH ON S.SERNO =SH.SUBSCRIPTORDL_SERNO
--   WHERE (CVALIDDAYS+HVALIDDAYS+JVALIDDAYS+KVALIDDAYS) > 4
  WHERE 1 = 1
--   AND USERID = 'tn1658@yahoo.com.tw'
  AND M.MEMBERID = '37743'
--   AND EMAIL = 'dG4xNjU4QHlhaG9vLmNvbS50dw=='
  ORDER BY M.USERID DESC


```

## ERP客戶資料檔

不轉

## ERP 客戶>-<會員關聯檔

這個是找關貿嗎？


## ERP 自動續訂單 - 約兩小時

- [x] 1. 建立現訂戶資料customer(權益檔後匯)
- [x] 2. 建立空訂單order+orderCustomer for 訂單編號
- [x] 3. 建立續訂單
- [ ] 4. 信用卡號轉檔寫回paymentToken
- [x] 5. 確認信用卡到期日？
- [x] 6. (新)productName 用來區分不同通路的續訂單


|說明|欄位|資料|中台處理方式
|--|--|--|--|
|續訂單編號|undefined||renew.id|
|ERP客戶編號|CUSTOMER_NUMBER|368548|customer.customerNo|
|ERP客戶ID|CUSTOMER_ID|406249|customer.customerID|
|同意續訂訂單編號|GC_ORDER_NUMBER|601038327|需要同步該訂單到中台|
|產品|PROD_TYPE|P+E|productName|
|原訂單購買料號|SEGMENT1|KCW000015|undefined|
|續訂方案|PROMOTION|GC18080026|renew.promotionCode|
|信用卡|CREDIT_CARD_NUMBER|570224|需要請綠界轉換成Token|
|信用卡到期日|C_CARD_EXP_DATE|2022/9/1|undefined|
|出貨客戶手機|SH_MOBILE|0910588882|receiver.mobile|
|出貨客戶email|SH_EMAIL|kuo88888@gmail.com|receiver.email|
|雜誌到期日|GC_SUB_END_DATE|2021/11/17|deductDate
|雜誌到期期數|GC_SUB_END_VOLUMN|736|undefined
|全閱讀到期日|KC_SUB_END_DATE|2021/11/30|deductDate
|雜誌寄送人(收件人)|CUSTOMER_NAME||orderReceiver.name
|雜誌寄送地址|COUNTRY	POSTAL_CODE	TOWN_OR_CITY	SHIP_ADDRESS||orderReceiver.address{}
|雜誌寄送電話|SH_MOBILE||orderReceiver.phone
|續訂金額|default(方案金額)||deductPrice
|運費|FREIGHT_CHARGE||shippingFee
|ERP認列收入方式|default("信用卡")||payment
|續訂單狀態|default("1":待執行)||renewStatus
|發票抬頭|default: receiver.name||invoiceTitle
|發票類型|default("1":紙本)||invoiceType
|發票開立方式|default(null)||invoiceIssueType
|發票統編|default(null)||invoiceVat
|發票載具類型|default(null)||deviceType
|發票載具碼|default(null)||deviceCode
|捐贈碼|default(null)||donationCode
|<font color="red">寄送方式|default(null)||shipping
|<font color="red">來源別|default("AUTO")||source
|<font color="red">來源代碼|default(null)||sourceCode


    deductDate: DateTime    # 續訂時間
    deductPrice: Int        # 續訂價格
    shippingFee: Int        # 運費

    payment: String         # ERP認列收入方式
    paymentMethod: String   # 付款方式
    paymentCard: String     # 信用卡後四碼
    paymentToken: String    # 續訂repay token
    renewStatus: String     # 續訂單狀態 0=停訂 1=待執行 2=已執行 3=執行失敗 4=不執行（因為有更新的續訂單）5=APP續訂單
    invoiceTitle: String    # 發票抬頭
    invoiceType: String     # 發票類型 1紙本 2會員載具 3手機條碼載具 4自然人憑證載具 5公司戶電子發票 6捐贈發票
    invoiceIssueType: String # 發票開立方式
    invoiceVat: String      # 發票統編
    deviceType: String      # 發票載具類型
    deviceCode: String      # 發票載具碼
    donationCode: String    # 捐贈碼

## ERP 雜誌權益檔


|說明|欄位|資料|中台處理方式
|--|--|--|--|
|ERP客戶ID|CUSTOMER_ID|220588|customerID
|<font color="red">ERP客戶No|required|null|customerNo
|天下截訂日|GC_SUB_END_DATE|2023/4/19|**ProductCode:GCV**<br/>endVolumeDate
|天下截訂期|GC_SUB_END_VOLUMN|771|endVolume
|訂閱天下年資|GC_ACC_SENIORITY|20.842|seniority
|產品代碼||GCV|productCode
|<font color="orange">權益起期|default(null)|null|startVolume
|<font color="orange">權益起日|default(null)|null|startVolumeDate
|<font color="red">續訂狀態|required|null|renewStatus
|<font color="red">權益狀態|default("1":現訂戶)|null|subscribeStatus
|康健截訂日|GH_SUB_END_DATE|2014/7/1|GHV
|康健截訂期|GH_SUB_END_VOLUMN|188|
|康健訂閱年資|GH_ACC_SENIORITY|1.747|
|Cheers截訂日|GJ_SUB_END_DATE||GJV
|Cheers截訂期|GJ_SUB_END_VOLUMN||
|Cheers訂閱年資|GJ_ACC_SENIORTY||
|親子天下截訂日|GK_SUB_END_DATE||GKV
|親子天下截訂期|GK_SUB_END_VOLUMN||
|親子天下訂閱年資|GK_ACC_SENIORITY||
|小行星截訂日|GS_SUB_END_DATE||GSV
|小行星截訂期|GS_SUB_END_VOLUMN|
|小行星訂閱年資|GS_ACC_SENIORITY||
|親子寶寶截訂日|GB_SUB_END_DATE||x
|親子寶寶截訂期|GB_SUB_END_VOLUMN||
|親子寶寶訂閱年資|GB_ACC_SENIORITY||
|微笑截訂日|GM_SUB_END_DATE||GMV
|微笑截訂期|GM_SUB_END_VOLUMN||
|微笑訂閱年資|GM_ACC_SENIORITY||
|換日線截訂日|GR_SUB_END_DATE||GRV
|換日線截訂期|GR_SUB_END_VOLUMN||
|換日線訂閱年資|GR_ACC_SENIORITY||
|寶寶電子截訂日|FB_SUB_END_DATE||X
|寶寶電子截訂期|FB_SUB_END_VOLUMN|
|寶寶電子訂閱年資|FB_ACC_SENIORITY||
|天下電子截訂日|FC_SUB_END_DATE||FCV
|天下電子截訂期|FC_SUB_END_VOLUMN||
|天下電子訂閱年資|FC_ACC_SENIORITY||
|康健電子截訂日|FH_SUB_END_DATE||FHV
|康健電子截訂期|FH_SUB_END_VOLUMN||
|康健電子訂閱年資|FH_ACC_SENIORITY||
|Cheers電子截訂日|FJ_SUB_END_DATE||FJV
|Cheers電子截訂期|FJ_SUB_END_VOLUMN||
|Cheers電子訂閱年資|FJ_ACC_SENIORITY||
|微笑電子截訂日|FM_SUB_END_DATE||FMV
|微笑電子截訂期|FM_SUB_END_VOLUMN||
|微笑電子訂閱年資|FM_ACC_SENIORITY||
|換日線電子截訂日|FR_SUB_END_DATE||FRV
|換日線電子截訂期|FR_SUB_END_VOLUMN||
|換日線電子訂閱年資|FR_ACC_SENIORITY||
|小行星電子截訂日|FS_SUB_END_DATE||X
|小行星電子截訂期|FS_SUB_END_VOLUMN||
|小行星電子訂閱年資|FS_ACC_SENIORITY||
|天下ipad子截訂日|PC_SUB_END_DATE||X
|天下ipad截訂期|PC_SUB_END_VOLUMN||
|天下ipad訂閱年資|PC_ACC_SENIORITY||
|全閱讀截訂日|KC_SUB_END_DATE||KCW<br/>memberSubscribe<br/>rightDueDate
|全閱讀訂閱年資|KC_ACC_SENIORITY||seniority


## 關貿數位權益檔

續訂 SUBSCRIPTIONHTHIS.AUTOSUB = 'Y'
PAYTYPE =?
SALEPRICE=3480
SUBSCRIPTIONHT.PID = PromotionCode

全閱讀的開通依據是來自 ORDERHT.PAYSTATUS='Y' and h.ORDSTATUS='2'
開通要靠天下拋 D09 續訂訂單資料檔匯入進來，系統開通權益的，這部分可以請教布蘭登

|說明|欄位|資料|中台處理方式
|--|--|--|--|
|ERP客戶ID|CUSTOMER_ID|220588|customerID
|天下截訂日|GC_SUB_END_DATE|2023/4/19|**ProductCode:GCV**<br/>endVolumeDate
|天下截訂期|GC_SUB_END_VOLUMN|771|endVolume
|訂閱天下年資|GC_ACC_SENIORITY|20.842|seniority
|權益起期|default(null)
|權益起日|default(null)
|續訂狀態|required
|權益狀態|default("1":現訂戶)

```sql

SELECT HT.*, DL.[MAGNAME],DL.[SUBBEGINDATE] ,DL.[SUBENDDATE] ,DL.[magcode] ,DL.[ORDER_NUMBER] ,DL.[EXTEND_STATUS] ,DL.[LAST_UPDATE]
 FROM(
SELECT 
    [SERNO], [SUBNO], RCVNAME
    , CONVERT(
    VARCHAR(MAX), 
    CAST('' AS XML).value('xs:base64Binary(sql:column("RCVEMAIL"))', 'VARBINARY(MAX)')
    ) AS RCVEMAIL
      , [CUSTOMER_ID], [NATIONNAME], [CITYNAME], [AREANAME], [ZIPCODE], [RCVADDR]
    , CONVERT(
    VARCHAR(MAX), 
    CAST('' AS XML).value('xs:base64Binary(sql:column("RCVMOBILE"))', 'VARBINARY(MAX)')
    ) AS RCVMOBILE
FROM [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORHT]
WHERE 1=1
AND SUBNO In('CW2644120','CW0473766','CW2910880','CW2313920')
) AS HT INNER JOIN [PCWM].[sche_pcwmmngmgr].[SUBSCRIPTORDL] AS DL 
ON HT.SERNO = DL.SUBSCRIPTOR_SERNO
WHERE 1=1
ORDER BY DL.[SERNO] DESC
--  AND RCVMOBILE = 'sun1229@gmail.com'



```
## 其他


- 雜誌權益檔移回-ERP
  - 0820跟ERP確認流程，準備估計工時
- 全閱讀權益移回-關貿(SUBSCRIPTORDL)
  - 0820請紹謙向關貿詢問權益計算與存放方式
- VIP贈閱相關資料-關貿
  - VIP閱讀權益異動流程？
  - 計算與存放方式？
- APP權益檔移回-中台
  - APP申請新料號，用來給APP訂閱商品計算權益
- 客戶主檔-ERP API同步
  - 開發API
- 訂戶編號-建立訂單前，ERP 發出 Webhook更新
  - 訂單中台修改
- 待確認事項：
  - 續訂單是否要增加paymentBank, cardType?

0824版本 - 中台可以接受方案代碼作為商品料號
1. 整理orderProduct的時候，檢查itemNo是否為方案或是料號，如果是方案的話，將方案新增為料號：

0831版本 - 訂單中台收到方案時，從中台取得方案
```gql
query{
  promotion(promotionCode: "itemNo"){
    totalAmount
    protmotionItems{
      sellingPrice
      item{
        itemNo
        name
        category
        subCategory
      }
    }
  }
}
```

拆單

1. 依據商品訂單的方案金額來換算單一商品的金額
```
    折扣比例 = TS商品折扣後金額/totalAmount
    單一商品的金額 = int (折扣我我比例 * sellingPrice)
    尾數 = TS商品折扣後金額 - sum(單一商品金額)
    最後一筆商品金額 += 尾數
```
2. 出貨倉庫 subinventory 改為A01

3. 處理商品類別，定義商品狀態

- 雜誌 - 立即 Confirm
- 數位 - 立即 Confirm
- 書 - 立即 Confirm
- 活動（票）- 立即 Confirm
- 贈品或是聯賣 - 立即 Confirm

4. ERP回傳配送狀態
只要有書、活動類型商品，這張ts單就是ERP回傳任一商品出貨，就回打91 ts訂單出貨。
退貨單，任一商品退貨，回打91 ts退貨。







文件要求
---

1. 91欄位對應到中台的規則書(TGCode/TSCode如何對應)
2. 中台補寫91訂單明細資料(1:1)。
3. 資料的轉換邏輯應該讓ERP來提供，定義在規格書裡。
4. 中台資料集中蒐集後、經過適度運算，擔任跨系統資料整合串接的角色。
5. 以後跨系統的SA要共用一份文件，最高指導原則為business(商業邏輯)，依據商業邏輯進行討論。
6. 規格書需要描述傳給東拓資料轉換的方式。
7. 會員資料轉移也需要一份文件


91銷售全閱讀開通方式
---
全閱讀開通需要有EMAIL，目前打算是用91APP的會員EMAIL作為全閱讀的帳號

但：
1. 91APP訂單內容沒有提供EMAIL
2. 91APP結帳流程中的EMAIL欄位會同步到91會員資訊，但不會發出API修改中台資料
3. 91APP會員資料中，沒有會員地址

問題：
1. 結帳流程中的EMAIL無法檢核，EMAIL有可能跟會員本人不同。
2. 91APP的全閱讀無法贈送他人，是否需調整說明？

結論：
1. 91訂單開通全閱讀一律送天下會員account
2. 91訂單不接受全閱讀轉贈，如有需要請到secant
3. 91全閱讀商品說明請提供天下會員查詢account功能

```gql
{
  "data": {
    "member": [
      {
        "account": "sun1229@gmail.com",
        "email": "sun1229@gmail.com",
        "nineOneMemberInfo": {
          "profession": "FinanceOrInsurance",
          "jobPosition": "企業負責人",
          "interest": "商業財經",
          "knowFrom": "LINE官方帳號",
          "email": "sun1229+91app@gmail.com",
          "address": null
        }
      }
    ]
  }
}

```





---

請搭配：https://docs.google.com/spreadsheets/d/18OnAlo69hSDxgbvl4V9FrfWeH2mLvXEG9kNJOgESBKo/edit?pli=1#gid=1718424954

EC 索取UUID循序圖
---
```sequence
title:Request UUID

EC->MemberAPI:索取uuid
MemberAPI-->EC:取得uuid
```

訂單平台 下訂循序圖
---
```sequence
title:Order a Order

Note over EC,MemberAPI:Alt-If 使用綠界付款

    Note over EC,MemberAPI:**索取UUID流程**

Note over EC,MemberAPI:Alt End

EC->Order:建立訂單
Order->Order:建立訂單主檔
Order->graphQL:建立訂單
graphQL-->Order:建立訂單成功
Order-->EC:回應訂單編號
EC->Payment:建立付款交易

Payment->Payment:建立付款主檔
Payment->第三方金流:導向第三方金流
第三方金流->第三方金流:使用者付款
第三方金流->Payment:回應付款成功/失敗
Payment->EC:Redirect 付款成功/失敗
Payment-->EC:Webhook 付款成功/失敗
Payment-->Order:Callback 付款成功/失敗
Order->graphQL:更新訂單付款成功/失敗
graphQL-->Order:更新成功
Note over EC,Order:Alt-If Secant

    Note over EC,Order:**訂單綁定會員流程**

Note over EC,Order:Alt End

Note over EC,ERP:**付款成功後流程**
```


訂單平台 訂單綁定會員循序圖
---
```sequence
title:Create Member and Bind Order

EC->MemberAPI:建立會員 with UUID
MemberAPI-->EC:建立會員成功
EC->Order:更新訂單會員 with 帳號
Order->graphQL:訂單綁定會員

graphQL-->Order:訂單綁定會員結果
Order-->EC:訂單綁定會員結果
```

訂單平台 付款成功後循序圖
---
```sequence
title: Process After Paid

Note over Order,graphQL:Alt—If 尚有訂單商品權益待計算，且訂單已綁定會員

    Note over Order,graphQL:**權益計算流程**

Note over Order,graphQL:Alt—Else

Order->ERP:T02 API
ERP-->Order:拋轉成功
Order-->EC:Webhook 訂單已成立

Note over Order,graphQL:Alt End
```

訂單平台 權益計算循序圖
---
```sequence
title: Calculate Subscriptions

Note over Order,graphQL:Loop Queue 訂單商品權益計算 Begin

    Order->graphQL:發送權益新增計算請求

Note over Order,graphQL:Loop Queue 訂單商品權益計算 End
```

訂單平台 權益計算Webhook循序圖
---
```sequence
title: Calculate Subscriptions

graphQL-->Order:Webhook 權益新增計算結果

Note over Order,EC:Alt—If 權益新增計算成功 Begin
    
    Order-->EC:Webhook 權益新增計算成功

Note over Order,EC:Alt—If 權益新增計算失敗 Begin

    Order-->EC:Webhook 權益新增計算失敗

Note over Order,EC:Alt End

Note over graphQL,EC:Alt—If 訂單商品權益皆計算完成，且訂單含有續訂方案或續訂料號資訊 Begin

    Note over graphQL,EC:**續訂單建立流程**

Note over graphQL,EC:Alt End

```

訂單平台 續訂單建立循序圖
---
```sequence
title: Create Renew After Transfered T02

Order->Order:每5分鐘指令撈出已綁會員 && 權益皆成功算畢 && 續訂單未建之訂單

Note over Order,graphQL:Loop 續訂單建立 Begin

    Order->graphQL:建立續訂單
    graphQL-->Order:建立續訂單成功
    Order-->EC:Webhook 續訂單建立成功

Note over Order,graphQL:Loop 續訂單建立 End
```

訂單平台 續訂循序圖
---
```sequence
title: Renew

Order->graphQL:索取到期續訂單清單
graphQL-->Order:回應清單

Note over Order:Loop 續訂單續訂 Begin

    Order->Order:建立續訂訂單
    Order->graphQL:建立續訂訂單
    graphQL-->Order:建立續訂訂單成功
    Order->Payment:API請求付款
    Payment->第三方金流:請求付款授權
    第三方金流->Payment:回應付款結果
    Payment->Order:回應付款結果
    Payment-->EC:Webhook 續訂付款成功/失敗
    Order->Order:更新訂單付款狀態
    Order->graphQL:更新訂單付款狀態
    graphQL-->Order:更新成功

Note over Order:Loop 續訂單續訂 End

Note over Order,EC:**付款成功後流程**

Note over Order,ERP:**續訂單建立流程**
```

權益平台 循序圖
---
```flow
st=>start: 開始
e=>end: 結束
ckuuid=>condition: 提供uuid


st->ckuuid
ckuuid

```



```sequence
title: createMember

flow->memberAPI: 依據account取得註冊資料
note right of memberAPI: uuid\nemail\nname
memberAPI->flow: 註冊資料

```

member API 循序圖
---

```sequence
Title: ssoQryMember
數位產品->memberAPI: ssoQryMember API
memberAPI->memberAPI: 0901前: 呼叫關貿會員資料API\n0901後: 查詢gql.member.tradeVanMemberInfo
memberAPI->graphQL: create/updateMember
memberAPI-->數位產品: 會員資料
```
```sequence
Title: ssoUpdMember
數位產品->memberAPI: ssoUpdMember API
memberAPI->memberAPI: 0901前: 呼叫關貿會員資料API\n0901後: 更新gql.member.tradeVanMemberInfo
memberAPI->graphQL: create/updateMember
memberAPI-->數位產品: 會員資料
```



91APP 循序圖
---





```sequence
Title: 91APP退貨（含補收款)
User->91APP:後台商品退貨
Order.cwg->91APP:取得商品退貨單
91APP-->Order.cwg:商品退貨單內容
Order.cwg->graphQL: 91商品退貨單寫入graphQL
graphQL-->Order.cwg: graphQL商品資訊
Order.cwg->Order.cwg: 修改中台商品狀態
Order.cwg->graphQL: 修改graphQL商品狀態
Order.cwg->91APP:取得補收款單
91APP-->Order.cwg:補收款單內容
Order.cwg->graphQL: 91補收款單內容寫入graphQL
Order.cwg->ERP: Next scheduled 退貨單資料(含補收款單)
```

```sequence
Title: 91APP退運費
客服->91APP:後台設定退運費
Order.cwg->91APP:取得退運費單
91APP-->Order.cwg:退運費單內容
Order.cwg->graphQL: 退運費單寫入graphQL
graphQL-->Order.cwg: 訂單資料(含退運費單)
Order.cwg->graphQL: 更新退運費資料
graphQL-->Order.cwg: 訂單資料(含退運費單)
Order.cwg->ERP: 拋轉91退運費單
```


```sequence
Title: 91APP東拓標籤
Order.cwg->graphQL: 00:30 取得可出貨的超取訂單資料
graphQL-->Order.cwg: 訂單資料
Order.cwg->Order.cwg: 產生xml
Order.cwg->東拓: FTP 拋轉xml, 1 record per time/1s
```

## Issue List:
```graphviz
digraph hierarchy {
                ERP客戶主檔->{聯絡人 地址}
                聯絡人->{聯絡人1 聯絡人2}
                地址->{地址1 地址2}
                聯絡人1->{地址A 電話或emailA 電話或emailB}
                {rank=same;地址A, 地址1 地址2}  // Put them on the same level
}
```

```graphviz
digraph hierarchy {
                客制訂單主檔Header->{line}
                line->{產品A 產品B 產品C}
                產品A->收件客戶->收件人->Email
                {rank=same;}  // Put them on the same level
}
```

```graphviz
digraph hierarchy {
                標準訂單Header->{line}
                line->{產品A 產品B 產品C}
                產品A->出貨客戶->收件人->Email
                {rank=same;}  // Put them on the same level
}
```

<style>
.blue {
  color: blue;
}
</style>