花了一整个下午在写这个 script。

因为最近在用 Public Bank 的 online payment 来缴付公司的 pcb,一开始我以为只要填好那个 form CP39 然后 scan 成 pdf 在 upload 就好… 原来我太天真了。不过毕竟是搞 IT 的,我就想 pdf 不接受,那么就是要一种特定格式的档案了。是 excel 吗?又好像不是 (不過,如果使用 excel,也可以 export 成這個格式)。你可以從這網站看 LHDN 要的 format。

如果懶惰去看,這裡也有 screenshots 😁

之後覺得好像只是普通的 txt file 而已。只要遵照它的 format,第一行是 header,接下來每個 employee 一行,就好了。當然,你要確保你 submit 的 text file 遵守它的規格。比如那些 0 和 space 要符合它的要求。

然後嘛,回到重點。IT 的人都很懶 😅,所以我就寫了這個 script 來幫我 generate 這 output file。要不然,每一次 submission 都要 manually 這樣確保所有 0 和 space 都對真的有點考眼力。

不過嘛,這個 script 暫時看來只有我會用到。畢竟多數的公司都有 payroll system 來處理了,哈哈。而且,又需要 shell environment,也不是每個人都懂。所以變成自己爽罷了。

Anyway, 如果你也懂 shell script,也使用著 Linux,Mac 這類可以執行 shell script 的系統,或許會有興趣。我把它放上了 github: http://bit.ly/2CXhl51 可以 download 來試試。

 

以下為 help 的選項:

20:24:17/012 ~/Code/sh/tt ./mypcb.sh -h
mypcb.sh (v2018.1.11)
usage: mypcb.sh [-c config_file] [-d] [-i] [-m] [-o output_file]

  Generate the MTD data file for online PCB submission.

  Options:
    -c	specify a runtime configuration file, else default will be used
    -d	turn on debug mode to display debugging information
    -i	interactive mode, user need to provide all information required
    -m	merge inputs with a configuration file
    -o	specify output file, else default will be used

  Examples:
    mypcb.sh 			run in basic mode, load from default configuration file, and save to default output file
    mypcb.sh -c config		run in basic mode, will load from the specified configuration file, and save to default output file
    mypcb.sh -i			run in interactive mode, default value will be used if left empty/blank
    mypcb.sh -c config -im	run in interactive mode, merge input with configuration file specified (if user left as empty/blank)
    mypcb.sh -o output		save the output in the specified output file

  Variables:
    RECORD_TYPE_H			Record type, enter 'H' for header row
    EMPLOYER_NO_1			Employer number registered (e.g. E12345 = 0000012345), max length = 10
    EMPLOYER_NO_2			Same as above, unless different employer number is registered, max length = 10
    YEAR_OF_DEDUCTION		Year of deduction, max length = 4
    MONTH_OF_DEDUCTION		Month of deduction (e.g. January = 01), max length = 2
    TOTAL_MTD_AMOUNT		Total amount of MTD deduction, remove decimal point (e.g. 1234.50 = 0000123450), max length = 10
    TOTAL_MTD_RECORD		Total number of MTD records, must tally with number of employees subjected to MTD (e.g. 1 = 00001), max length 5
    TOTAL_CP38_AMOUNT		Total amount of CP38 deduction, remove decimal point (e.g. 1234.50 = 0000123450), max length 10
    TOTAL_CP38_RECORD		Total number of CP38 records, must tally with number of employees subjected to CP38 (e.g. 1 = 00001), max length 5
    RECORD_TYPE_D			Record type, enter 'D' for each employee row
    EMPLOYEE_TAX_REFERENCE_NO	Employee tax reference number without SG/OG (e.g. SG 123456-78(0) = 0012345678), max length 10
    EMPLOYEE_WIFE_CODE		For single person, enter 0; for married person, between 1 and 9, max length 1
    EMPLOYEE_NAME			Employee name, max length 60 (left justify, padding with spaces)
    OLD_ID_NO			Old identification number, leave blank if not applicable, max length 12 (left justify, padding with spaces)
    NEW_ID_NO			New identification number, leave blank if not applicable, max length 12 (left justify, padding with spaces)
    PASSPORT_NO			Passport number, leave blank if not applicable, max length 12 (left justify, padding with spaces)
    COUNTRY_CODE			Country code, refer to country code list, max length 2 (left justify, padding with spaces)
    MTD_AMOUNT			MTD deduction amount (e.g. 990.00 = 00099000), max length 8
    CP38_AMOUNT			CP38 deduction amount (e.g. 990.00 = 00099000), max length 8
    EMPLOYEE_NO			Employee number or salary number, max length 10, (left justify, padding with spaces)

  Notes:
    In basic mode, only single employee record is supported in current version.
    Use interactive mode to enter multiple employee records.

    If you are using basic mode, please ensure all the required variables above are entered in the configuration file.
    Each variable has its requirement on the number of characters (so that the LHDN system can parse the data file correctly),
    for numbers 'zero' are require for left padding, and for alphabetic characters, 'space' are required for right padding.

    example:
      TOTAL_MTD_AMOUNT='0000123450' (MYR1234.50)
      PASSPORT_NO='            ' (12 empty spaces)

    Kindly check the example configuration file (pcb_template_config.txt) for complete details.

20:24:21/012 ~/Code/sh/tt

 

可以從這裡下載參考設定檔。

使用上面連結的檔案來產生 output file 的例子:

20:48:58/012 ~/Code/sh/tt ./mypcb.sh -c pcb_template_config.txt -o test.txt
20:49:08/012 ~/Code/sh/tt 
20:49:09/012 ~/Code/sh/tt cat test.txt 
H00000000000000000000201801000012345000001000000000000000
D00000000000UNKNOWN                                                                                           00123450000000001234      
20:49:12/012 ~/Code/sh/tt

 

美中不足的是,現在這個版本,在基本模式里(通過讀取default設定檔,產生output檔)只能設定一個employee的資料。要輸入多名員工資料,只能使用互動模式 (interactive mode)。當然要修改也不是辦不到,需要再寫 parser 來 parse 設定檔就對了 (可是我個人覺得,如果要做成那樣,我乾脆就自己一行一行 manually key in 成那個 format 就好了。反正每個月要修改的也只是那幾個 field)。不過,我是希望寫出普通的 GUI app。這樣就比較有可能其他人也可以使用了。Shell Script 的版本,暫時就告個段落吧。哈哈