Example #1
0
        public static InboundInvoice Create(Organization organization, DateTime dueDate, Int64 amountCents,
                                            Int64 vatCents, FinancialAccount budget, string supplier, string description, string payToAccount, string ocr,
                                            string invoiceReference, Person creatingPerson)
        {
            InboundInvoice newInvoice = FromIdentity(SwarmDb.GetDatabaseForWriting().
                                                     CreateInboundInvoice(organization.Identity, dueDate, budget.Identity,
                                                                          supplier, payToAccount, ocr,
                                                                          invoiceReference, amountCents, creatingPerson.Identity));

            newInvoice.Description = description; // Not in original schema; not cause for schema update

            if (vatCents > 0)
            {
                newInvoice.VatCents = vatCents;
            }

            // Create a corresponding financial transaction with rows

            FinancialTransaction transaction =
                FinancialTransaction.Create(organization.Identity, DateTime.UtcNow,
                                            "Invoice #" + newInvoice.OrganizationSequenceId + " from " + supplier);

            transaction.AddRow(organization.FinancialAccounts.DebtsInboundInvoices, -amountCents, creatingPerson);
            if (vatCents > 0)
            {
                transaction.AddRow(organization.FinancialAccounts.AssetsVatInboundUnreported, vatCents,
                                   creatingPerson);
                transaction.AddRow(budget, amountCents - vatCents, creatingPerson);
            }
            else
            {
                transaction.AddRow(budget, amountCents, creatingPerson);
            }


            // Make the transaction dependent on the inbound invoice

            transaction.Dependency = newInvoice;

            // Create notification (slightly misplaced logic, but this is failsafest place)

            OutboundComm.CreateNotificationApprovalNeeded(budget, creatingPerson, supplier, (amountCents - vatCents) / 100.0,
                                                          description, NotificationResource.InboundInvoice_Created);
            // Slightly misplaced logic, but failsafer here
            SwarmopsLogEntry.Create(creatingPerson,
                                    new InboundInvoiceCreatedLogEntry(creatingPerson, supplier, description, amountCents / 100.0, budget),
                                    newInvoice);

            // Clear a cache
            FinancialAccount.ClearApprovalAdjustmentsCache(organization);

            return(newInvoice);
        }
Example #2
0
        public static CashAdvance Create(Organization organization, Person forPerson, Person createdByPerson,
                                         Int64 amountCents, FinancialAccount budget, string description)
        {
            CashAdvance newAdvance =
                FromIdentityAggressive(SwarmDb.GetDatabaseForWriting().CreateCashAdvance(forPerson.Identity,
                                                                                         createdByPerson.Identity,
                                                                                         organization.Identity,
                                                                                         budget.Identity, amountCents,
                                                                                         description));

            OutboundComm.CreateNotificationApprovalNeeded(budget, forPerson, string.Empty, amountCents / 100.0,
                                                          description, NotificationResource.CashAdvance_Requested);
            // Slightly misplaced logic, but failsafer here
            SwarmopsLogEntry.Create(forPerson,
                                    new CashAdvanceRequestedLogEntry(createdByPerson, forPerson, amountCents / 100.0, budget, description),
                                    newAdvance);

            // Clear a cache
            FinancialAccount.ClearApprovalAdjustmentsCache(organization);

            return(newAdvance);
        }
Example #3
0
        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.UtcNow,
                                            "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.ClearApprovalAdjustmentsCache(payrollItem.Organization);



            return(salary);
        }
Example #4
0
        public static ExpenseClaim Create(Person claimer, Organization organization, FinancialAccount budget,
                                          DateTime expenseDate, string description, Int64 amountCents, Int64 vatCents, ExpenseClaimGroup group = null)
        {
            ExpenseClaim newClaim =
                FromIdentityAggressive(SwarmDb.GetDatabaseForWriting()
                                       .CreateExpenseClaim(claimer.Identity, organization?.Identity ?? 0,
                                                           budget?.Identity ?? 0, expenseDate, description, amountCents)); // budget can be 0 initially if created with a group

            if (vatCents > 0)
            {
                newClaim.VatCents = vatCents;
            }

            if (group != null)
            {
                newClaim.Group = group;
            }

            if (budget != null && organization != null)
            {
                // Create the financial transaction with rows

                string transactionDescription = "Expense #" + newClaim.OrganizationSequenceId + ": " + description;
                // TODO: Localize

                if (transactionDescription.Length > 64)
                {
                    transactionDescription = transactionDescription.Substring(0, 61) + "...";
                }


                DateTime expenseTxDate      = expenseDate;
                int      ledgersClosedUntil = organization.Parameters.FiscalBooksClosedUntilYear;

                if (ledgersClosedUntil >= expenseDate.Year)
                {
                    expenseTxDate = DateTime.UtcNow; // If ledgers are closed for the actual expense time, account now
                }

                FinancialTransaction transaction =
                    FinancialTransaction.Create(organization.Identity, expenseTxDate,
                                                transactionDescription);

                transaction.AddRow(organization.FinancialAccounts.DebtsExpenseClaims, -amountCents, claimer);
                if (vatCents > 0)
                {
                    transaction.AddRow(budget, amountCents - vatCents, claimer);
                    transaction.AddRow(organization.FinancialAccounts.AssetsVatInboundUnreported, vatCents, claimer);
                }
                else
                {
                    transaction.AddRow(budget, amountCents, claimer);
                }

                // Make the transaction dependent on the expense claim

                transaction.Dependency = newClaim;

                // Create notifications

                OutboundComm.CreateNotificationApprovalNeeded(budget, claimer, string.Empty,
                                                              newClaim.BudgetAmountCents / 100.0,
                                                              description, NotificationResource.ExpenseClaim_Created);
                // Slightly misplaced logic, but failsafer here
                OutboundComm.CreateNotificationFinancialValidationNeeded(organization, newClaim.AmountCents / 100.0,
                                                                         NotificationResource.Receipts_Filed);
                SwarmopsLogEntry.Create(claimer,
                                        new ExpenseClaimFiledLogEntry(claimer /*filing person*/, claimer /*beneficiary*/,
                                                                      newClaim.BudgetAmountCents / 100.0,
                                                                      vatCents / 100.0, budget, description), newClaim);

                // Clear a cache
                FinancialAccount.ClearApprovalAdjustmentsCache(organization);
            }

            return(newClaim);
        }