payrolla-mcp 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +7 -3
  2. package/dist/index.js +97 -22
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -55,15 +55,19 @@ Calculate payroll for a single employee.
55
55
  - `month` - Starting month (1-12)
56
56
  - `periodCount` - Number of months (optional, default: 1)
57
57
  - `ssiType` - SSI type: 'S4A', 'S4B', or 'S4C' (optional, default: 'S4A')
58
- - `extraPayments` - Array of extra payments (optional)
58
+ - `extraPayments` - Array of extra payments (optional, supports `paymentType` = RegularPayment/Overtime/SocialAid/ExtraPay)
59
59
  - `customParams` - Custom global parameters (optional)
60
+ - `cumulativeIncomeTaxBase` - Starting income tax base to carry over
61
+ - `cumulativeMinWageIncomeTaxBase` - Starting minimum wage income tax base to carry over
62
+ - `transferredSSIBase1` - Starting transferred SSI base 1
63
+ - `transferredSSIBase2` - Starting transferred SSI base 2
60
64
 
61
65
  ### calculate_bulk_payroll
62
66
 
63
67
  Calculate payroll for multiple employees with shared parameters.
64
68
 
65
69
  **Input:**
66
- - `employees` - Array of employee objects
70
+ - `employees` - Array of employee objects (each can include extra payments with `paymentType` and starting cumulative/transfer bases)
67
71
  - `year` - Calculation year
68
72
  - `month` - Starting month
69
73
  - `periodCount` - Number of months (use 12 for yearly)
@@ -120,4 +124,4 @@ Plan yearly payroll considering potential changes.
120
124
 
121
125
  ```
122
126
  User: I have 3 employees: Ali 35k net, Ayse 45k net, Mehmet 60k gross.
123
- What's my yearly budget if I give 10% raise and minimum wage becomes 30k?
127
+ What's my yearly budget if I give 10% raise and minimum wage becomes 30k?
package/dist/index.js CHANGED
@@ -30,11 +30,27 @@ function mapSSIType(ssiType) {
30
30
  function mapCalculationType(calcType) {
31
31
  return calcType === "Gross" ? CalculationType.Gross : CalculationType.Net;
32
32
  }
33
+ function mapPaymentType(paymentType) {
34
+ switch (paymentType) {
35
+ case 1:
36
+ case "RegularPayment":
37
+ return PaymentType.RegularPayment;
38
+ case 2:
39
+ case "Overtime":
40
+ return PaymentType.Overtime;
41
+ case 3:
42
+ case "SocialAid":
43
+ return PaymentType.SocialAid;
44
+ case 4:
45
+ case "ExtraPay":
46
+ default:
47
+ return PaymentType.ExtraPay;
48
+ }
49
+ }
33
50
  function buildCustomGlobalParams(customParams) {
34
51
  if (!customParams) return void 0;
35
52
  return {
36
53
  minWage: customParams.minWage,
37
- minWageNet: customParams.minWageNet,
38
54
  ssi_LowerLimit: customParams.ssiLowerLimit,
39
55
  ssi_UpperLimit: customParams.ssiUpperLimit,
40
56
  stampTaxRatio: customParams.stampTaxRatio,
@@ -51,7 +67,11 @@ async function calculatePayroll(client, input) {
51
67
  month,
52
68
  periodCount = 1,
53
69
  extraPayments,
54
- customParams
70
+ customParams,
71
+ cumulativeIncomeTaxBase = 0,
72
+ cumulativeMinWageIncomeTaxBase = 0,
73
+ transferredSSIBase1 = 0,
74
+ transferredSSIBase2 = 0
55
75
  } = input;
56
76
  const payments = [
57
77
  {
@@ -67,21 +87,17 @@ async function calculatePayroll(client, input) {
67
87
  payments.push({
68
88
  paymentAmount: extra.amount,
69
89
  paymentName: extra.name,
70
- paymentType: PaymentType.ExtraPay,
90
+ paymentType: mapPaymentType(extra.paymentType),
71
91
  paymentRef: `extra_${i + 2}`,
72
92
  calculationType: extra.type === "Net" ? CalculationType.Net : CalculationType.Gross
73
93
  });
74
94
  }
75
95
  }
76
- const model = {
77
- calcDate: `${year}-${String(month).padStart(2, "0")}-01`,
96
+ const baseModel = {
78
97
  wageAmount: wage,
79
- cumulativeIncomeTaxBase: 0,
80
- cumulativeMinWageIncomeTaxBase: 0,
81
98
  ssiType: mapSSIType(ssiType),
82
99
  wageCalculationType: mapCalculationType(calculationType),
83
100
  wagePeriodType: PaymentPeriodType.Monthly,
84
- periodCount,
85
101
  periodLengthType: PeriodLengthType.Month,
86
102
  payments,
87
103
  calculationParams: {
@@ -89,16 +105,40 @@ async function calculatePayroll(client, input) {
89
105
  customGlobalParams: buildCustomGlobalParams(customParams)
90
106
  }
91
107
  };
92
- const result = await client.calculate(model);
93
108
  let totalCost = 0;
94
109
  let totalNet = 0;
95
110
  let totalGross = 0;
96
111
  const periods = [];
97
- for (const payroll of result.payrolls) {
112
+ let incomeTaxBase = cumulativeIncomeTaxBase;
113
+ let minWageIncomeTaxBase = cumulativeMinWageIncomeTaxBase;
114
+ let transferredBase1 = transferredSSIBase1;
115
+ let transferredBase2 = transferredSSIBase2;
116
+ for (let i = 0; i < periodCount; i++) {
117
+ const calcDate = new Date(year, month - 1 + i, 1);
118
+ const calcYear = calcDate.getFullYear();
119
+ const calcMonth = calcDate.getMonth() + 1;
120
+ const model = {
121
+ ...baseModel,
122
+ calcDate: `${calcYear}-${String(calcMonth).padStart(2, "0")}-01`,
123
+ cumulativeIncomeTaxBase: incomeTaxBase,
124
+ cumulativeMinWageIncomeTaxBase: minWageIncomeTaxBase,
125
+ transferredSSIBase1: transferredBase1,
126
+ transferredSSIBase2: transferredBase2,
127
+ periodCount: 1
128
+ };
129
+ const result = await client.calculate(model);
130
+ const payroll = result.payrolls?.[0];
131
+ if (!payroll) {
132
+ throw new Error("Payrolla calculation returned no payroll data");
133
+ }
98
134
  const pr = payroll.payrollResult;
99
135
  totalCost += payroll.totalCost;
100
136
  totalNet += pr.totalNet;
101
137
  totalGross += pr.totalGross;
138
+ const nextIncomeTaxBase = incomeTaxBase + pr.totalIncomeTaxBase;
139
+ const nextMinWageIncomeTaxBase = pr.totalMinWageIncomeTaxExemptionBase;
140
+ const nextTransferredBase1 = pr.transferredSSIBase1 ?? transferredBase1;
141
+ const nextTransferredBase2 = pr.transferredSSIBase2 ?? transferredBase2;
102
142
  periods.push({
103
143
  year: payroll.year,
104
144
  month: payroll.month,
@@ -108,8 +148,16 @@ async function calculatePayroll(client, input) {
108
148
  incomeTax: pr.totalIncomeTax,
109
149
  stampTax: pr.totalStampTax,
110
150
  employeeSSI: pr.totalSSIWorkerPrem,
111
- employerSSI: pr.totalSSIEmployerPrem
151
+ employerSSI: pr.totalSSIEmployerPrem,
152
+ cumulativeIncomeTaxBase: nextIncomeTaxBase,
153
+ cumulativeMinWageIncomeTaxBase: nextMinWageIncomeTaxBase,
154
+ transferredSSIBase1: nextTransferredBase1,
155
+ transferredSSIBase2: nextTransferredBase2
112
156
  });
157
+ incomeTaxBase = nextIncomeTaxBase;
158
+ minWageIncomeTaxBase = nextMinWageIncomeTaxBase;
159
+ transferredBase1 = nextTransferredBase1;
160
+ transferredBase2 = nextTransferredBase2;
113
161
  }
114
162
  return {
115
163
  employee: name,
@@ -135,7 +183,11 @@ async function calculateBulkPayroll(client, input) {
135
183
  month,
136
184
  periodCount,
137
185
  extraPayments: emp.extraPayments,
138
- customParams
186
+ customParams,
187
+ cumulativeIncomeTaxBase: emp.cumulativeIncomeTaxBase,
188
+ cumulativeMinWageIncomeTaxBase: emp.cumulativeMinWageIncomeTaxBase,
189
+ transferredSSIBase1: emp.transferredSSIBase1,
190
+ transferredSSIBase2: emp.transferredSSIBase2
139
191
  });
140
192
  employeeResults.push({
141
193
  name: result.employee,
@@ -170,9 +222,21 @@ var DEFAULT_PARAMS_2025 = {
170
222
  incomeTaxBrackets: [
171
223
  { limit: 158e3, rate: 0.15, description: "158,000 TL'ye kadar %15" },
172
224
  { limit: 33e4, rate: 0.2, description: "158,000-330,000 TL aras\u0131 %20" },
173
- { limit: 12e5, rate: 0.27, description: "330,000-1,200,000 TL aras\u0131 %27" },
174
- { limit: 43e5, rate: 0.35, description: "1,200,000-4,300,000 TL aras\u0131 %35" },
175
- { limit: Number.MAX_SAFE_INTEGER, rate: 0.4, description: "4,300,000 TL'den fazlas\u0131 %40" }
225
+ {
226
+ limit: 12e5,
227
+ rate: 0.27,
228
+ description: "330,000-1,200,000 TL aras\u0131 %27"
229
+ },
230
+ {
231
+ limit: 43e5,
232
+ rate: 0.35,
233
+ description: "1,200,000-4,300,000 TL aras\u0131 %35"
234
+ },
235
+ {
236
+ limit: Number.MAX_SAFE_INTEGER,
237
+ rate: 0.4,
238
+ description: "4,300,000 TL'den fazlas\u0131 %40"
239
+ }
176
240
  ]
177
241
  };
178
242
 
@@ -191,9 +255,6 @@ function applyScenario(defaults, scenario) {
191
255
  if (scenario.minWage !== void 0) {
192
256
  result.minWage = scenario.minWage;
193
257
  }
194
- if (scenario.minWageNet !== void 0) {
195
- result.minWageNet = scenario.minWageNet;
196
- }
197
258
  if (scenario.ssiLimitIncreasePercent !== void 0) {
198
259
  const multiplier = 1 + scenario.ssiLimitIncreasePercent / 100;
199
260
  result.ssiLowerLimit = defaults.ssiLowerLimit * multiplier;
@@ -256,7 +317,6 @@ async function simulateBudget(client, input) {
256
317
  scenarioApplied: {
257
318
  salaryRaisePercent: scenario.salaryRaisePercent || 0,
258
319
  effectiveMinWage: customParams.minWage || defaults.minWage,
259
- effectiveMinWageNet: customParams.minWageNet || defaults.minWageNet,
260
320
  effectiveTaxBrackets
261
321
  },
262
322
  summary: {
@@ -485,7 +545,14 @@ function registerPrompts(server) {
485
545
  var ExtraPaymentSchema = z2.object({
486
546
  name: z2.string().describe("Name of the extra payment"),
487
547
  amount: z2.number().describe("Payment amount"),
488
- type: z2.enum(["Net", "Gross"]).describe("Payment type")
548
+ type: z2.enum(["Net", "Gross"]).describe("Payment type"),
549
+ paymentType: z2.union([
550
+ z2.literal(1),
551
+ z2.literal(2),
552
+ z2.literal(3),
553
+ z2.literal(4),
554
+ z2.enum(["RegularPayment", "Overtime", "SocialAid", "ExtraPay"])
555
+ ]).optional().describe("Payment type (1: RegularPayment, 2: Overtime, 3: SocialAid, 4: ExtraPay)")
489
556
  });
490
557
  var CustomParamsSchema = z2.object({
491
558
  minWage: z2.number().optional().describe("Custom minimum wage (gross)"),
@@ -503,7 +570,11 @@ var EmployeeInputSchema = z2.object({
503
570
  wage: z2.number().describe("Wage amount"),
504
571
  calculationType: z2.enum(["Gross", "Net"]).describe("Whether wage is gross or net"),
505
572
  ssiType: z2.enum(["S4A", "S4B", "S4C"]).optional().describe("SSI type (default: S4A)"),
506
- extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses")
573
+ extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses"),
574
+ cumulativeIncomeTaxBase: z2.number().optional().describe("Starting cumulative income tax base"),
575
+ cumulativeMinWageIncomeTaxBase: z2.number().optional().describe("Starting cumulative minimum wage income tax base"),
576
+ transferredSSIBase1: z2.number().optional().describe("Starting transferred SSI base 1"),
577
+ transferredSSIBase2: z2.number().optional().describe("Starting transferred SSI base 2")
507
578
  });
508
579
  var ScenarioConfigSchema = z2.object({
509
580
  name: z2.string().optional().describe("Scenario name for comparison"),
@@ -549,7 +620,11 @@ function registerTools(server, client) {
549
620
  month: z2.number().min(1).max(12).describe("Starting month (1-12)"),
550
621
  periodCount: z2.number().min(1).max(12).optional().describe("Number of months to calculate (default: 1)"),
551
622
  extraPayments: z2.array(ExtraPaymentSchema).optional().describe("Extra payments like bonuses"),
552
- customParams: CustomParamsSchema.optional().describe("Custom global parameters to override defaults")
623
+ customParams: CustomParamsSchema.optional().describe("Custom global parameters to override defaults"),
624
+ cumulativeIncomeTaxBase: z2.number().optional().describe("Starting cumulative income tax base to carry from previous months"),
625
+ cumulativeMinWageIncomeTaxBase: z2.number().optional().describe("Starting cumulative minimum wage income tax base"),
626
+ transferredSSIBase1: z2.number().optional().describe("Starting transferred SSI base 1"),
627
+ transferredSSIBase2: z2.number().optional().describe("Starting transferred SSI base 2")
553
628
  },
554
629
  async (params) => {
555
630
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payrolla-mcp",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "MCP server for Payrolla payroll budget simulations - enables LLMs to calculate Turkish payroll and simulate budget scenarios",
5
5
  "author": "Payrolla",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@modelcontextprotocol/sdk": "^1.0.0",
50
- "payrolla": "^0.2.2",
50
+ "payrolla": "^0.2.4",
51
51
  "zod": "^3.25.0"
52
52
  },
53
53
  "devDependencies": {