I presume it is calculated in function get_leave_balance_on() in frappe-bench/apps/erpnext/erpnext/hr/doctype/leave_application/leave_application.py, but it’s not easy to understand.
I just didn’t bother and ignore the Expired Leave. It’s just sad that “Leave Balance Before Application” in “Leave Application” is filled with “Total Allocated Leave - Expired Leave - …”.
You can customize your Form View to hide the confusing field.
I have a theory about this. Since the leave allocated was from 1 Jan to 27 Jul, and there are 10 days of leave. When you apply for leave on let’s say 20 Jul, there are only 8 days between 20 Jul to 27 Jul, making 2 leave days expire. This is what I get after messing around trying to fix it, only to realize the number of days left.
However, I’m not sure if the expired leave will be carried over once the next cycle starts.
I believe it’s based on your leave period and the date you applied for leave. Easiest example would be if the leave period is from 1st of Jan till 31st of Dec. If you have an annual leave of 14 days and decided to take a leave on 28th of Dec, you would only have 4 days available leave, while the other 10 days become expired. I believe these expired leave will be carried over to the next leave period based on how many days are set to be carried over.