TSTT 專案核心功能調查(登入 / 稅表 / 備份)

| Work Notes | 15 Reads

登入介面程式碼

登入功能由 COM510Action 類別實作。它的 login() 方法會先驗證使用者輸入,然後將驗證請求交給服務層(Service Layer)處理。
這個登入畫面的 HTML 介面位於 src/main/webapp/WEB-INF/view/COM510/com510.jsp,該 JSP 表單會收集 userIdpassword,並將它們提交到登入動作(login action)。

使用者憑證驗證

COM510Service 透過 COM510SearchLoginUser.sql 查詢資料庫以驗證使用者。
這個 SQL 語句會從 M_PASSWORD 表中查詢,匹配 USER_IDPASSWORD,同時排除已刪除的使用者(DEL_FLG = '0' 才會通過)。


資料庫連線字串的位置與修改方式

專案採用 Seasar2dicon 設定檔。
src/main/resources/jdbc.dicon(以及對應的 src/main/webapp/WEB-INF/classes/jdbc.dicon)裡可以找到各種資料庫連線範例,預設啟用的是 PostgreSQL

<!-- for PostgreSQL -->
<component name="xaDataSource"
          class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
    <property name="driverClassName">
        "org.postgresql.Driver"
    </property>
    <property name="URL">
        "jdbc:postgresql://localhost/tsttpg"
    </property>
    <property name="user">"tstt"</property>
    <property name="password">"tstt"</property>
</component>

若要連線到不同主機或資料庫,請在上述 URL 中將 localhost 或資料庫名稱 (tsttpg) 改成您需要的值,並同步調整 user / password
完成後重新部署或重啟服務即可套用。


DB 備份的輸出位置

COM520Action#execDBbackup 會讀取設定檔 settings.propertiessetting.dbbackup.batchPath,並執行 tstt_exp.bat 來取得備份。

tstt_exp.bat 中,輸出目錄固定為 D:\TSTT\EXPORT,檔名為日期時間格式。
日誌檔案名稱格式:tstt_exp_YYYYMMDDHHmmss.log
轉儲檔案名稱格式:tstt_exp_YYYYMMDDHHmmss.dmp

set prefix=tstt_exp_%datetime%
set dir=D:\TSTT\EXPORT
set dmpfile=%dir%\%prefix%.dmp
set logfile=%dir%\%prefix%.log

因此,執行後的備份檔案會在 Windows 的 D:\TSTT\EXPORT 目錄下生成。
若要更改輸出路徑,請修改 tstt_exp.bat 中的 set dir=...,或編輯 settings.properties 中的 setting.dbmp.dir


tstt_exp.bat 只是將匯出目錄設定為 D:\TSTT\EXPORT,並在建立匯出檔與日誌檔檔名時使用該路徑;它本身並不會建立該目錄。
因此,如果 D:\TSTT\EXPORT 尚未存在,pg_dump 無法建立 .dmp.log 檔,批次檔會因「找不到路徑」而失敗。
解決方法是手動先建立 D:\TSTT\EXPORT 目錄,或修改批次檔在執行前先用 mkdir 建立目錄。


PAY221 的所得稅計算流程


為什麼有「甲」「乙」「丙」三種稅表?

日本的所得稅法對「給与所得」的源泉徴収方式做了分類,以便依照不同情況採用不同的稅額表:


「甲」稅表

  • 適用於員工已向雇主提交「扶養控除等申告書」,視為主要工作。

  • 計算時可扣除扶養親屬等各種所得控除。


「乙」稅表

  • 員工未提交「扶養控除等申告書」,通常用於兼職或副業。

  • 不適用扣除額,故稅率較高。


「丙」稅表

  • 專為臨時、一次性或日雇性質的報酬設計。

  • 計算方式最簡化,通常不參照扶養人數或其他申報資料。


這三種分類是為了在源泉徵收階段就能根據報酬性質與員工申報狀況,套用適合的稅率或扣除方式,避免一次性、兼職和常設薪資混淆造成計算差異。


Tstt的本Project并沒有DailyAccountCalcService這種東西

丙的計算全寫到了MonthlyAccountCalcService.java裏面,因此推測T_WITHHOLDING_TAX_TABLE裏面日額表和月額表似乎是混在一起的,所以沒有單獨的日額表テーブル這種東西。我不知道對不對。


另外我發現,當從T_WITHHOLDING_TAX_TABLE查不到對應年份的記錄的時候,這份SQL:
\src\main\webapp\WEB-INF\classes\sql\ADM410InsertTWithholdingTaxTable.sql
專案提供了 ADM410InsertTWithholdingTaxTable.sql,用來從上一年度複製稅額表,以補齊缺漏年度。


ADM410InsertTWithholdingTaxTable.sql 是由 Java 調用的。
管理員的「次年度更新」服務(ADM410Service)會在更新流程中,透過 updateBySqlFile 明確執行這個 SQL,將當前年份的源泉徵收稅額資料複製到次年度。
它並不會在平常的稅額計算中自動執行;只有在管理畫面的「次年度更新」操作時才會觸發。


DB 備份

DB 備份功能是由 COM520Action.execDbBackup 觸發,會執行設定檔 (settings.properties) 中指定的批次檔 WEB-INF/classes/tstt_exp.bat
該批次檔內已將輸出路徑寫死為 D:\TSTT\EXPORT,並依時間戳產生檔名,例如:

D:\TSTT\EXPORT\tstt_exp_YYYYMMDDHHMMSS.dmp  
D:\TSTT\EXPORT\tstt_exp_YYYYMMDDHHMMSS.log

因此,DB 備份檔預設會被存放在伺服器的 D:\TSTT\EXPORT 目錄下;找不到的話請確認該路徑是否存在、權限是否允許寫入,或批次檔是否執行成功。

顯示「DBバックアップ処理を実行しました」只代表系統已經呼叫了備份批次檔,並不保證備份一定成功產生。

目前 tstt_exp.bat 內寫死輸出路徑為 D:\TSTT\EXPORT,如果該機器沒有 D 槽或該目錄不存在:

  • 批次檔會因找不到路徑而失敗,產生不了 .dmp.log 檔。

  • 畫面仍可能顯示「已執行」,但實際上備份檔沒產生,需檢查 tstt_exp.bat 的執行結果或 log。

若沒有 D 槽,請修改 settings.propertieststt_exp.bat 將輸出路徑改到存在且可寫入的磁碟,例如 C:\TSTT\EXPORT,並確保該路徑有權限與空間後再重新執行備份。


總結:訊息只表示命令已觸發,並不等同於備份成功;請確認實際的輸出路徑與執行狀態。

 

 if (selectDto.oneoffResearchKbn.equals(ONEOFF_RESEARCH_KBN_ONE) && selectDto.countOffResearch == 0) 只根據「單發調查」與「無非單發調查」判斷,與現有稅表區分(甲 / 乙)無關;條件成立就會進入該分支。進入後,程式會把稅表區分設為丙,因此無論原本是甲或乙都會被覆蓋。

 


為什麼同一筆資料會計算兩次源泉稅?

整體流程由 calcMonthlyAccount 主導,共分成三個階段:


  1. 單筆實績計算
    先取得目標調查實績並呼叫 calcForResearchRecord,在此階段就會計算第一次源泉稅,結果寫入 incomeTaxTake

  2. 合併所有實績再算一次
    withholdingTaxDeduct 需要把同月同調查員所有調查實績的報酬加總後,重新計算一次總源泉稅,這是透過 calcTotalWithHoldingTax 內部再次呼叫 calcTaxWithholding 完成的。

  3. 稅額分配
    得到合計源泉稅後,再把稅額按報酬比例分配回每一筆實績;分配的結果會覆蓋第一次計算的 incomeTaxTake


由於 calcTaxWithholding 在上述第 1、2 步都會被呼叫一次,而實際計算邏輯(如 2020 年以後的稅表判斷)位於 calcTaxWithholdingOver2020,其中的 if (StringUtils.equals(selectDto.taxTableCode, TAX_CODE_HEI)) 自然也會被評估兩次。


總結:
第一次計算是為了得到各筆調查的暫時稅額,第二次則是合計後再進行最終分配,這是業務流程需求,不是為了驗證前一次結果。

This article was last edited at