There may be something funky going on with the various checkboxes for the salary components. I believe CPP would be pretty close in concept to FICA in the US, aka “social security”. It is not considered to be, strictly speaking, part of income tax.
For my FICA deduction, I have no boxes checked at all except for “Remove if Zero Valued.” You may want to try removing “Is Income Tax Component” and see if that makes any difference in your testing. Also, test what happens when only CPP is in your salary structure, without CPP2 or any other deductions. That could possibly give a clue to what’s going on and help you to narrow things down.
EDIT: Also, I think, as @volkswagner said, there is a good reason to use “B” or a custom “BS” in your formulas AND your salary structure instead of “base”. Your case may be an example of what the difference is.
I will try removing some of these check boxes and see what happens.
Currently I’m using base in my formulas, and my earning comes in as expected.
I’ve removed cpp2 also just to test with a single deduction.
And yes Canadian CPP is similar to US Social Security.
Something I did notice, when I start a salary slip, add the employee, some fields are populated and my earnings show up, and I get a message “Added tax components from the Salary Component master as the salary structure didn’t have any tax component.” And disappears.
If I change the start date the message appears again.
But still no deductions.
When I hit save, still no deductions.
But after a Save and if I change or update the form by changing the start date again, presto! Deductions appear, and the message no longer pops up.
So I wonder why this appears
“Added tax components from the Salary Component master as the salary structure didn’t have any tax component.”
I’ll look at this more closely in the morning.
I do find it extremely frustrating, it just should not be this difficult to get deductions to appears on slip.
Let me go over my set up one more time in case I missed something.
Salary Component
1- Basic, earning, is taxable, based on formula “base”
2- CPP, deduction, based on formula base * 0.0595
Salary Structure
1- weekly, etc…
2- basic earning, CPP deductions, these come in with default values from salary component.
Salary Structure Assignment
1- add employee
2- frequency weekly, add salary structure from above
Salary slip
1- create a slip, add name and frequency and date
2- get message about tax components…
3- no deductions only earnings
4- save, get warning again, gross year to date calculated.
5- submit, deductions appear
Seems to be the default workflow for me.
I’ve deleted all payroll data in the database, started over like 10 times and still getting the same result, I’m not sure what else to try.
I wasn’t sure, but as @trustedcomputer pointed out checking the boxes related to taxes may be the issue. The description may be too vague “for showing components in tax reports“. I have a feeling you’re expecting use tax slaps when checking the box.
I have several earnings components and several deductions. None of them have the checkbox selected for tax related info.
FYI the is a tool for previewing a salary slip. In the tools menu of both Salary Structure Assignment and Salary Structure, you can simulate a new salary slip. One of them runs as the “first pay period” while the other runs for the current period (I forget which one does which).
The problem here is that you’ve got a cyclical definition. The gross_year_to_date field depends on component amounts for its value, and one of your components depends on gross_year_to_date. Both have to be defined first.
It is logically possible to use gross_year_to_date in a deduction without having a cyclical definition, but there’s still a sequencing problem. In the Salary Slip’s validate method, components are calculated before the gross_year_to_date field is. Likewise, when your formula is getting run for the first time, gross_year_to_date is still zero. When you run it a second time (while submitting), it suddenly has a value.
If you need gross_year_to_date in a deduction component, you’ll likely need to run validate a second time before submitting. You could automate this with a server script or simply save the document an additional time. This should get the year to date fields populated, at which point they should work in your formulas.
@jroyDC I think you will drive yourself crazy trying to understand the calculations without submitting the salary slip. This is the only thing that matters (results after submit). It can be baffling if you look at the results after save.
EDIT: Additionally, I’ve found the gross_year_to_date is calculated after all earnings components are calculated (at least those which are included in total).
Yep, exactly. That’s part of what makes it a cyclical definition. Did you understand me to be saying that it didn’t include the current slip’s gross pay? Because that definitely wasn’t what I was trying to say.
Thanks for taking the time with testing and probing these calculations and formulas, but without accurate data on save, our bean counters will not Submit and “hope” for the right results. Again, I’ll argue a Submit action should post the screen data without any more changes, running calculations between save and submit that can potentially have impact on your Journal is a Red flag in my opinion.
This will be a no go zone for us. Scratch Payroll from the list of working modules for us until things can be straightened out.
As much as I really like ERPNext, these types of issues can be very frustrating, and probably keeps valid customers from taking the plunge into the framework.
Frappe calls validate methods on submit as well as save. If that’s a non-starter for you, it’s not just Payroll that you should scrap but probably the whole framework.
Here, you’re only seeing changing values between save and submit because you’ve got a tautology in your formula. Frappe gives a lot of power to end users, including the power to build things that don’t work correctly.
If you have a better way to formulate some of our calculation, I’m all ears. Using the gross_year_to_date in a formula to build our deductions seems reasonable and seeing the result on Save also seems reasonable.
@peterg I understand the importance of validate before_save and on_submit. This is the only doctype I’ve encountered where the actual calculations differ from those saved and submitted. Do you have any other examples where this is true?
In my humble opinion, validation does not equal calculation.
I’m tempted to submit a bug report, save != submit on Salary Slip.
Do you think that would be a valid bug report?
EDIT:
I understand submit needs to recalculate (for things that may have changed), it shouldn’t be the cause of a change.
The simplest solution would probably be what I described above, which is to re-trigger component calculations after save. This should only be necessary in circumstances like this where a document is depending on data that it is also creating.
It’s only happening here because something did change: the value of gross_pay and gross_year_to_date. They were undefined/zero when the components were calculated for the first time and positive values when they are calculated for a second time.
There are many other places where this can happen, either because of user scripting like here or because of dependencies on externally defined values. It can happen if exchange rates change, for example.
I can appreciate why it might be better in many circumstances if submit operated on frozen data, but for better or for worse that’s not how Frappe works. It is possible to make any arbitrary change in the data model during a submit event.
I don’t think it’s a bug so much as a limitation. We’ve talked a bit about this in other threads, I think. The HRMS payroll module just isn’t really set up for North American salary structures, which tend to have multiple bracket-based components and a lot that depends on projected gross pay.
I commend you all trying to figure out how to do it with formulas, but honestly it seems a bit masochistic For self-referential calculations like this, I just use an empty component and calculate the correct value in an before_save hook.
Is there any possibility (or future possibility) to add multiple Income Tax Slabs to a Salary Structure? In Canada we have Federal Income Tax, Provincial Income Tax, etc… all are bracket style deductions.