Challenge: format a payslip
Payroll is one of the oldest COBOL workloads, and one of the most unforgiving: every figure on a payslip must be exactly right and laid out the same way every month. In this challenge you'll take one record from a payroll master file and format it as a payslip.
Everything from this module comes together:
- a record layout with group and elementary items and level numbers,
including a nested date group and a
FILLERfor bytes you don't use - implied decimals: the money fields in the record have no decimal point, just digits
- print-line groups built from
FILLERtext and named fields - MOVE rules: field-by-field moves to rearrange the date
- edited pictures for the money columns, including check protection
VALUE ALLfor the ruled lines
The input record
The whole record arrives as one fixed-width line of 62 characters, exactly
as it would sit in a mainframe dataset. Read it with a single
ACCEPT IN-PAY-REC, and the layout you declare does the splitting:
E00123MURPHY, SEAN 20260930032500000487500276250S1L0D04
| | | | | | | |
ID NAME DATE GROSS TAX NET ??? DEPT
0325000 in a PIC 9(5)V99 field is 3,250.00. The four characters marked
??? hold a tax code this program doesn't need: skip them with FILLER.
Planning the print lines
Before writing any code, count the bytes. A layout table on paper (or in a comment) saves a lot of time:
* POS LEN CONTENT
* 1 12 "PAYSLIP FOR "
* 13 6 EMPLOYEE ID
* 19 1 SPACE
* 20 20 NAME
Every heading, separator and gap is a FILLER with a VALUE whose
length matches its PIC.
On the job
Payroll changes go through parallel runs: the new program and the old one process the same month's data and the outputs are compared line by line. A single misplaced space fails the comparison, which is why this course checks your output exactly.
Your task
Format a payslip from one payroll master record.
Input (one 62-character line, read with ACCEPT IN-PAY-REC):
| Pos | Len | Field | Content |
|---|---|---|---|
| 1 | 6 | IN-EMP-ID |
employee ID, text |
| 7 | 20 | IN-EMP-NAME |
name, text |
| 27 | 8 | IN-PAY-DATE |
pay date YYYYMMDD (a group: year, month, day) |
| 35 | 7 | IN-GROSS |
gross pay, 5 digits + 2 implied decimals |
| 42 | 7 | IN-TAX |
tax, 5 digits + 2 implied decimals |
| 49 | 7 | IN-NET |
net pay, 5 digits + 2 implied decimals |
| 56 | 4 | FILLER |
tax code, not used |
| 60 | 3 | IN-DEPT |
department code |
Output for the record
E00123MURPHY, SEAN 20260930032500000487500276250S1L0D04:
============================================================
PAYSLIP FOR E00123 MURPHY, SEAN DEPT D04 PAID 30/09/2026
GROSS 3,250.00 TAX 487.50 NET $*2,762.50
============================================================
- The ruled lines are 60
=characters, from one field withVALUE ALL. - Line 2:
PAYSLIP FOR, the ID, a space, the name (all 20 characters),DEPT, the department,PAIDand the date asDD/MM/YYYY. - Line 3:
GROSS, gross pay,TAX, tax,NET, net pay. Gross and tax use zero suppression with a thousands comma and always show0.00at least (9 characters each). Net pay is 10 characters: a fixed$then*check protection with a thousands comma. - Build lines 2 and 3 as groups with
FILLERitems, andDISPLAYeach group.