public static Salary Create(PayrollItem payrollItem, DateTime payoutDate) { // Load the existing adjustments. PayrollAdjustments adjustments = PayrollAdjustments.ForPayrollItem(payrollItem); Int64 payCents = payrollItem.BaseSalaryCents; // Apply all before-tax adjustments foreach (PayrollAdjustment adjustment in adjustments) { if (adjustment.Type == PayrollAdjustmentType.GrossAdjustment) { payCents += adjustment.AmountCents; } } Int64 subtractiveTaxCents = 0; Int64 additiveTaxCents = 0; if (!payrollItem.IsContractor) { // calculate tax Money grossInOrgCurrency = new Money { Cents = payCents, Currency = payrollItem.Organization.Currency, ValuationDateTime = DateTime.UtcNow }; Money grossInTaxCurrency = grossInOrgCurrency.ToCurrency(payrollItem.Country.Currency); Money subtractiveTax = TaxLevels.GetTax(payrollItem.Country, payrollItem.SubtractiveTaxLevelId, grossInTaxCurrency); Money subtractiveTaxInOrgCurrency = subtractiveTax.ToCurrency(payrollItem.Organization.Currency); subtractiveTaxCents = (Int64)(subtractiveTaxInOrgCurrency.Cents); additiveTaxCents = (Int64)(payCents * payrollItem.AdditiveTaxLevel); payCents -= subtractiveTaxCents; } // Apply all after-tax adjustments foreach (PayrollAdjustment adjustment in adjustments) { if (adjustment.Type == PayrollAdjustmentType.NetAdjustment) { payCents += adjustment.AmountCents; } } // If net is negative, create rollover adjustment PayrollAdjustment rolloverAdjustment = null; if (payCents < 0) { rolloverAdjustment = PayrollAdjustment.Create(payrollItem, PayrollAdjustmentType.NetAdjustment, -payCents, "Deficit rolls over to next salary"); PayrollAdjustment.Create(payrollItem, PayrollAdjustmentType.NetAdjustment, payCents, "Deficit rolled over from " + payoutDate.ToString("yyyy-MM-dd")); // keep second rollover open, so the deficit from this salary is carried to the next payCents = 0; } // Create salary, close adjustments Salary salary = Create(payrollItem, payoutDate, payCents, subtractiveTaxCents, additiveTaxCents); // For each adjustment, close and bind to salary foreach (PayrollAdjustment adjustment in adjustments) { adjustment.Close(salary); } if (rolloverAdjustment != null) { rolloverAdjustment.Close(salary); } // Add the financial transaction FinancialTransaction transaction = FinancialTransaction.Create(payrollItem.OrganizationId, DateTime.Now, "Salary #" + salary.Identity + ": " + payrollItem.PersonCanonical + " " + salary.PayoutDate.ToString("yyyy-MMM", CultureInfo.InvariantCulture)); transaction.AddRow(payrollItem.Budget, salary.CostTotalCents, null); transaction.AddRow(payrollItem.Organization.FinancialAccounts.DebtsSalary, -salary.NetSalaryCents, null); if (salary.TaxTotalCents != 0) { transaction.AddRow(payrollItem.Organization.FinancialAccounts.DebtsTax, -salary.TaxTotalCents, null); } transaction.Dependency = salary; // Finally, check if net and/or tax are zero, and if so, mark them as already-paid (i.e. not due for payment) if (salary.NetSalaryCents == 0) { salary.NetPaid = true; } if (salary.TaxTotalCents == 0) { salary.TaxPaid = true; } // Clear a cache FinancialAccount.ClearAttestationAdjustmentsCache(payrollItem.Organization); return(salary); }
public static Salary Create(PayrollItem payrollItem, DateTime payoutDate) { // Load the existing adjustments. PayrollAdjustments adjustments = PayrollAdjustments.ForPayrollItem(payrollItem); Int64 payCents = payrollItem.BaseSalaryCents; // Apply all before-tax adjustments foreach (PayrollAdjustment adjustment in adjustments) { if (adjustment.Type == PayrollAdjustmentType.GrossAdjustment) { payCents += adjustment.AmountCents; } } // calculate tax double subtractiveTax = TaxLevels.GetTax(payrollItem.Country, payrollItem.SubtractiveTaxLevelId, payCents / 100.0); if (subtractiveTax < 1.0) { // this is a percentage and not an absolute number subtractiveTax = payCents * subtractiveTax; } Int64 subtractiveTaxCents = (Int64)(subtractiveTax * 100); Int64 additiveTaxCents = (Int64)(payCents * payrollItem.AdditiveTaxLevel); payCents -= subtractiveTaxCents; // Apply all after-tax adjustments foreach (PayrollAdjustment adjustment in adjustments) { if (adjustment.Type == PayrollAdjustmentType.NetAdjustment) { payCents += adjustment.AmountCents; } } // Create salary, close adjustments Salary salary = Create(payrollItem, payoutDate, payCents, subtractiveTaxCents, additiveTaxCents); // For each adjustment, close and bind to salary foreach (PayrollAdjustment adjustment in adjustments) { adjustment.Close(salary); } // If net is negative, create rollover adjustment if (payCents < 0) { PayrollAdjustment rollover1 = PayrollAdjustment.Create(payrollItem, PayrollAdjustmentType.NetAdjustment, -payCents, "Deficit rolls over to next salary"); rollover1.Close(salary); PayrollAdjustment rollover2 = PayrollAdjustment.Create(payrollItem, PayrollAdjustmentType.NetAdjustment, payCents, "Deficit rolled over from " + payoutDate.ToString("yyyy-MM-dd")); // keep rollover2 open, so the deficit from this salary is carried to the next salary.NetSalaryCents = 0; } // Add the financial transaction FinancialTransaction transaction = FinancialTransaction.Create(payrollItem.OrganizationId, DateTime.Now, "Salary #" + salary.Identity + ": " + payrollItem.PersonCanonical + " " + salary.PayoutDate.ToString("yyyy-MMM", CultureInfo.InvariantCulture)); transaction.AddRow(payrollItem.Budget, salary.CostTotalCents, null); transaction.AddRow(payrollItem.Organization.FinancialAccounts.DebtsSalary, -salary.NetSalaryCents, null); transaction.AddRow(payrollItem.Organization.FinancialAccounts.DebtsTax, -salary.TaxTotalCents, null); transaction.Dependency = salary; // Finally, check if net and/or tax are zero, and if so, mark them as already-paid (i.e. not due for payment) if (salary.NetSalaryCents == 0) { salary.NetPaid = true; } if (salary.TaxTotalCents == 0) { salary.TaxPaid = true; } return(salary); }
public void CreateAdjustment(PayrollAdjustmentType type, double amount, string description) { PayrollAdjustment.Create(this, type, amount, description); }