示例#1
0
        private void LoadDependencies()
        {
            this.DependentExpenseClaims       = new ExpenseClaims();
            this.DependentInvoices            = new InboundInvoices();
            this.DependentSalariesNet         = new Salaries();
            this.DependentSalariesTax         = new Salaries();
            this.DependentCashAdvancesPayout  = new CashAdvances();
            this.DependentCashAdvancesPayback = new CashAdvances();

            BasicFinancialDependency[] dependencies = SwarmDb.GetDatabaseForReading().GetPayoutDependencies(Identity);

            foreach (BasicFinancialDependency dependency in dependencies)
            {
                switch (dependency.DependencyType)
                {
                case FinancialDependencyType.ExpenseClaim:
                    this.DependentExpenseClaims.Add(ExpenseClaim.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.InboundInvoice:
                    this.DependentInvoices.Add(InboundInvoice.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.Salary:
                    Salary salary = Salary.FromIdentity(dependency.ForeignId);
                    if (salary.NetSalaryCents == AmountCents)     // HACK: Assumes that tax total is not identical
                    {
                        this.DependentSalariesNet.Add(salary);
                    }
                    else
                    {
                        this.DependentSalariesTax.Add(salary);
                    }
                    break;

                case FinancialDependencyType.CashAdvance:
                    this.DependentCashAdvancesPayout.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.CashAdvancePayback:
                    this.DependentCashAdvancesPayback.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                    break;

                default:
                    throw new NotImplementedException(
                              "Unknown financial dependency type in Payout.LoadDependencies(): " + dependency);
                }
            }
        }
示例#2
0
        private static void AddUnpaidSalaries(Payouts payoutList, Organization organization)
        {
            Int64 taxTotalCents = 0;

            Salaries   salaries     = Salaries.ForOrganization(organization);
            List <int> identityList = new List <int>();
            DateTime   payDay       = Constants.DateTimeHigh;

            foreach (Salary salary in salaries)
            {
                if (!salary.Attested)
                {
                    continue;
                }

                if (!salary.NetPaid)
                {
                    PayrollItem payrollItem = salary.PayrollItem;
                    Person      employee    = payrollItem.Person;

                    BasicPayout basicPayout = new BasicPayout(0, organization.Identity, employee.BankName,
                                                              employee.BankClearing + " / " + employee.BankAccount,
                                                              "[Loc]Financial_SalarySpecification|[Date]" +
                                                              salary.PayoutDate.ToString(CultureInfo.InvariantCulture),
                                                              salary.NetSalaryCents, salary.PayoutDate, false, DateTime.Now, 0);
                    Payout payout = Payout.FromBasic(basicPayout);
                    payout.RecipientPerson = employee;

                    payout.DependentSalariesNet.Add(salary);

                    payoutList.Add(payout);

                    if (payDay > salary.PayoutDate)
                    {
                        payDay = salary.PayoutDate;
                    }
                }

                if (!salary.TaxPaid)
                {
                    taxTotalCents += salary.TaxTotalCents;
                    identityList.Add(salary.Identity);

                    if (payDay > salary.PayoutDate)
                    {
                        payDay = salary.PayoutDate;
                    }
                }
            }

            if (taxTotalCents > 0)
            {
                // Add the summarized tax line, too

                BasicPayout basicPayout = new BasicPayout(0, organization.Identity, "[Loc]Financial_TheTaxMan", "SEBG 5050-1055",  // HACK: Get tax account from something
                                                          organization.TaxPaymentOcr, taxTotalCents, payDay, false, DateTime.Now, 0);
                Payout payout = Payout.FromBasic(basicPayout);

                foreach (int salaryId in identityList)
                {
                    payout.DependentSalariesTax.Add(Salary.FromIdentity(salaryId));
                }

                payoutList.Add(payout);
            }
        }
示例#3
0
        private static void AddUnpaidSalaries(Payouts payoutList, int organizationId)
        {
            Int64 taxTotalCents = 0;

            Salaries   salaries     = Salaries.ForOrganization(Organization.FromIdentity(organizationId));
            List <int> identityList = new List <int>();
            DateTime   payDay       = DateTime.MaxValue;

            foreach (Salary salary in salaries)
            {
                if (!salary.Attested)
                {
                    continue;
                }

                if (!salary.NetPaid)
                {
                    PayrollItem payrollItem = salary.PayrollItem;
                    Person      employee    = payrollItem.Person;

                    BasicPayout basicPayout = new BasicPayout(0, organizationId, employee.BankName,
                                                              employee.BankClearing + " / " + employee.BankAccount, "[Loc]Financial_SalarySpecification|[Date]" + salary.PayoutDate.ToString(CultureInfo.InvariantCulture),
                                                              salary.NetSalaryCents, salary.PayoutDate, false, DateTime.Now, 0);
                    Payout payout = Payout.FromBasic(basicPayout);

                    payout.DependentSalariesNet.Add(salary);

                    payoutList.Add(payout);

                    if (payDay > salary.PayoutDate)
                    {
                        payDay = salary.PayoutDate;
                    }
                }

                if (!salary.TaxPaid)
                {
                    taxTotalCents += salary.TaxTotalCents;
                    identityList.Add(salary.Identity);

                    if (payDay > salary.PayoutDate)
                    {
                        payDay = salary.PayoutDate;
                    }
                }
            }

            if (taxTotalCents > 0)
            {
                // Add the summarized tax line, too

                string referenceString = string.Empty;

                if (identityList.Count == 1)
                {
                    referenceString = "[Loc]Financial_TaxSpecification|" + identityList[0].ToString();
                }
                else
                {
                    identityList.Sort();
                    referenceString = "[Loc]Financial_TaxesSpecification|" + Formatting.GenerateRangeString(identityList);
                }


                BasicPayout basicPayout = new BasicPayout(0, organizationId, "[Loc]Financial_TheTaxMan",
                                                          string.Empty, referenceString,
                                                          taxTotalCents, payDay, false, DateTime.Now, 0);
                Payout payout = Payout.FromBasic(basicPayout);

                foreach (int salaryId in identityList)
                {
                    payout.DependentSalariesTax.Add(Salary.FromIdentity(salaryId));
                }

                payoutList.Add(payout);
            }
        }
示例#4
0
        private void LoadDependencies()
        {
            if (this.DependentCashAdvancesPayback != null && Identity == 0)
            {
                return; // if inited and identity zero, return
            }

            this.DependentExpenseClaims       = new ExpenseClaims();
            this.DependentInvoices            = new InboundInvoices();
            this.DependentSalariesNet         = new Salaries();
            this.DependentSalariesTax         = new Salaries();
            this.DependentCashAdvancesPayout  = new CashAdvances();
            this.DependentCashAdvancesPayback = new CashAdvances();

            if (Identity == 0)
            {
                return; // never progress past here if identity zero
            }

            BasicFinancialDependency[] dependencies = SwarmDb.GetDatabaseForReading().GetPayoutDependencies(Identity);

            foreach (BasicFinancialDependency dependency in dependencies)
            {
                switch (dependency.DependencyType)
                {
                case FinancialDependencyType.ExpenseClaim:
                    this.DependentExpenseClaims.Add(ExpenseClaim.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.InboundInvoice:
                    this.DependentInvoices.Add(InboundInvoice.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.Salary:
                    Salary salary = Salary.FromIdentity(dependency.ForeignId);
                    if (salary.NetSalaryCents == AmountCents || this.CreatedDateTime > new DateTime(2015, 11, 1))
                    {
                        this.DependentSalariesNet.Add(salary);
                    }
                    else     // LEGACY
                    {
                        this.DependentSalariesTax.Add(salary);
                    }
                    break;

                case FinancialDependencyType.SalaryTax:
                    Salary salaryTax = Salary.FromIdentity(dependency.ForeignId);
                    this.DependentSalariesTax.Add(salaryTax);
                    break;

                case FinancialDependencyType.CashAdvance:
                    this.DependentCashAdvancesPayout.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                    break;

                case FinancialDependencyType.CashAdvancePayback:
                    this.DependentCashAdvancesPayback.Add(CashAdvance.FromIdentity(dependency.ForeignId));
                    break;

                default:
                    throw new NotImplementedException(
                              "Unknown financial dependency type in Payout.LoadDependencies(): " + dependency);
                }
            }
        }
示例#5
0
        public static Payout CreateFromProtoIdentity(Person creator, string protoIdentity)
        {
            string[] components = protoIdentity.Split('|');
            int      payoutId   = 0;

            // The components can EITHER be a series of expense claims OR a single invoice.

            if (components.Length == 0)
            {
                // nothing to construct. Exception or return null?

                return(null);
            }
            if (components[0][0] == 'A')
            {
                // Cash advance(s) to be paid out.

                string     bank           = string.Empty;
                string     account        = string.Empty;
                List <int> identityList   = new List <int>();
                Int64      amountCents    = 0;
                int        organizationId = 0;

                foreach (string component in components)
                {
                    int         advanceId = Int32.Parse(component.Substring(1));
                    CashAdvance advance   = CashAdvance.FromIdentity(advanceId);
                    identityList.Add(advanceId);
                    organizationId = advance.OrganizationId;
                    Organization organization = Organization.FromIdentity(advance.OrganizationId);

                    if (bank.Length < 1)
                    {
                        Person asker = advance.Person;
                        bank    = asker.BankName;
                        account = asker.BankAccount;
                    }

                    amountCents += advance.AmountCents;

                    advance.PaidOut = true;
                    // advance.Open remains true until the advance is repaid

                    SwarmopsLogEntry.Create(creator,
                                            new PayoutCreatedLogEntry(creator, advance.Person, organization,
                                                                      organization.Currency, amountCents / 100.0,
                                                                      "Cash Advance Paid Out"),
                                            advance.Person, advance);


                    OutboundComm.CreateNotificationOfFinancialValidation(advance.Budget, advance.Person,
                                                                         advance.AmountCents / 100.0, advance.Description, NotificationResource.CashAdvance_PaidOut);
                }

                string referenceString = string.Empty;

                if (identityList.Count == 1)
                {
                    referenceString = "Cash Advance #" + identityList[0].ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    identityList.Sort();
                    referenceString = "Cash Advances " + Formatting.GenerateRangeString(identityList);
                }

                payoutId = SwarmDb.GetDatabaseForWriting().CreatePayout(organizationId, bank, account,
                                                                        referenceString, amountCents, DateTime.Today.AddDays(1),
                                                                        creator.Identity);

                foreach (int advanceId in identityList)
                {
                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.CashAdvance,
                                            advanceId);
                }
            }
            else if (components[0][0] == 'C')
            {
                // Expense claims, possibly followed up by cash advance paybacks

                Person       beneficiaryPerson = null;
                Organization organization      = null;
                string       bank                       = string.Empty;
                string       account                    = string.Empty;
                List <int>   claimIdentityList          = new List <int>();
                List <int>   advancePaybackIdentityList = new List <int>();
                Int64        amountCents                = 0;
                int          organizationId             = 0;

                foreach (string component in components)
                {
                    int foreignId = Int32.Parse(component.Substring(1));

                    if (component[0] == 'C')
                    {
                        ExpenseClaim claim = ExpenseClaim.FromIdentity(foreignId);
                        claimIdentityList.Add(foreignId);

                        if (bank.Length < 1)
                        {
                            Person claimer = claim.Claimer;
                            bank           = claimer.BankName;
                            account        = claimer.BankAccount;
                            organizationId = claim.OrganizationId;
                        }

                        beneficiaryPerson = claim.Claimer;
                        organization      = claim.Organization;
                        amountCents      += claim.AmountCents;

                        claim.Repaid = true;
                        claim.Close();

                        OutboundComm.CreateNotificationOfFinancialValidation(claim.Budget, claim.Claimer,
                                                                             claim.AmountCents / 100.0, claim.Description, NotificationResource.ExpenseClaim_PaidOut);
                    }
                    else if (component[0] == 'a')
                    {
                        CashAdvance advancePayback = CashAdvance.FromIdentity(foreignId);
                        advancePaybackIdentityList.Add(foreignId);

                        amountCents        -= advancePayback.AmountCents;
                        advancePayback.Open = false;
                    }
                }

                string referenceString = string.Empty;

                if (claimIdentityList.Count == 1)
                {
                    referenceString = "Expense Claim #" + claimIdentityList[0].ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    claimIdentityList.Sort();
                    referenceString = "Expense Claims " + Formatting.GenerateRangeString(claimIdentityList);
                }

                SwarmopsLogEntry.Create(creator,
                                        new PayoutCreatedLogEntry(creator, beneficiaryPerson, organization,
                                                                  organization.Currency, amountCents / 100.0,
                                                                  referenceString),
                                        beneficiaryPerson);

                payoutId = SwarmDb.GetDatabaseForWriting().CreatePayout(organizationId, bank, account,
                                                                        referenceString, amountCents, DateTime.Today.AddDays(1),
                                                                        creator.Identity);

                foreach (int claimId in claimIdentityList)
                {
                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.ExpenseClaim,
                                            claimId);
                }

                foreach (int advancePaybackId in advancePaybackIdentityList)
                {
                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.CashAdvancePayback,
                                            advancePaybackId);
                }
            }
            else if (components[0][0] == 'I')
            {
                // There is just one invoice per payout

                InboundInvoice invoice = InboundInvoice.FromIdentity(Int32.Parse(components[0].Substring(1)));

                DateTime expectedPayment = invoice.DueDate;

                if (expectedPayment < DateTime.Today)
                {
                    expectedPayment = DateTime.Today;
                }

                payoutId = SwarmDb.GetDatabaseForWriting()
                           .CreatePayout(invoice.OrganizationId, string.Empty, invoice.PayToAccount,
                                         invoice.Ocr.Length > 0 ? "OCR " + invoice.Ocr : "Ref# " + invoice.InvoiceReference,
                                         invoice.AmountCents, expectedPayment,
                                         creator.Identity);

                SwarmDb.GetDatabaseForWriting()
                .CreatePayoutDependency(payoutId, FinancialDependencyType.InboundInvoice,
                                        invoice.Identity);

                invoice.Open = false;
            }
            else if (components[0][0] == 'S')
            {
                // Salary, net payment

                Salary salary = Salary.FromIdentity(Int32.Parse(components[0].Substring(1)));

                payoutId = SwarmDb.GetDatabaseForWriting()
                           .CreatePayout(salary.PayrollItem.OrganizationId, salary.PayrollItem.Person.BankName,
                                         salary.PayrollItem.Person.BankAccount,
                                         "Salary " + salary.PayoutDate.ToString("yyyy-MMM"),
                                         salary.NetSalaryCents, salary.PayoutDate,
                                         creator.Identity);

                SwarmDb.GetDatabaseForWriting().CreatePayoutDependency(payoutId, FinancialDependencyType.Salary,
                                                                       salary.Identity);

                salary.NetPaid = true;
            }
            else if (components[0][0] == 'T')
            {
                // Tax payment for multiple salaries.

                List <int> identityList   = new List <int>();
                Int64      amountCents    = 0;
                int        organizationId = 0;
                DateTime   payDay         = DateTime.Today.AddDays(1);

                foreach (string component in components)
                {
                    int    salaryId = Int32.Parse(component.Substring(1));
                    Salary salary   = Salary.FromIdentity(salaryId);
                    identityList.Add(salaryId);

                    if (organizationId == 0)
                    {
                        organizationId = salary.PayrollItem.OrganizationId;
                        payDay         = salary.PayoutDate;
                    }

                    amountCents += salary.TaxTotalCents;

                    salary.TaxPaid = true;
                }


                Organization organization = Organization.FromIdentity(organizationId);
                identityList.Sort();

                payoutId = SwarmDb.GetDatabaseForWriting()
                           .CreatePayout(organization.Identity, "The Tax Man", organization.Parameters.TaxAccount,
                                         organization.Parameters.TaxOcr,
                                         amountCents, payDay, creator.Identity);

                foreach (int salaryId in identityList)
                {
                    SwarmDb.GetDatabaseForWriting().CreatePayoutDependency(payoutId, FinancialDependencyType.SalaryTax,
                                                                           salaryId);
                }
            }
            else
            {
                throw new NotImplementedException();
            }

            return(FromIdentity(payoutId));
        }
示例#6
0
        public static Payout CreateBitcoinPayoutFromPrototype(Organization organization, Payout prototype, string transactionHash)
        {
            string[] components = prototype.ProtoIdentity.Split('|');
            int      payoutId   = 0;

            // This function is made for complex bitcoin payouts and will typically take many different types of payouts to many people at once.

            if (components.Length == 0)
            {
                // nothing to construct. Exception or return null?

                return(null);
            }

            payoutId = SwarmDb.GetDatabaseForWriting().CreatePayout(organization.Identity, "Bitcoin network", "Multiple",
                                                                    transactionHash, prototype.AmountCents, DateTime.UtcNow, 0);

            foreach (string component in components)
            {
                int foreignId = Int32.Parse(component.Substring(1));

                switch (component[0])
                {
                case 'A':
                    // Cash advance
                    CashAdvance advance = CashAdvance.FromIdentity(foreignId);
                    advance.PaidOut = true;

                    SwarmopsLogEntry.Create(null,
                                            new PayoutCreatedLogEntry(null, advance.Person, organization,
                                                                      organization.Currency, advance.AmountCents / 100.0,
                                                                      "Cash Advance Paid Out"),
                                            advance.Person, advance);

                    OutboundComm.CreateNotificationOfFinancialValidation(advance.Budget, advance.Person,
                                                                         advance.AmountCents / 100.0, advance.Description, NotificationResource.CashAdvance_PaidOut);
                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.CashAdvance,
                                            foreignId);
                    break;

                case 'a':
                    // This is a negative record - payback of cash advance
                    CashAdvance advancePayback = CashAdvance.FromIdentity(foreignId);
                    advancePayback.Open = false;

                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.CashAdvancePayback,
                                            foreignId);

                    break;

                case 'C':
                    // Expense claim
                    ExpenseClaim claim = ExpenseClaim.FromIdentity(foreignId);
                    claim.Repaid = true;
                    claim.Close();

                    OutboundComm.CreateNotificationOfFinancialValidation(claim.Budget, claim.Claimer,
                                                                         claim.AmountCents / 100.0, claim.Description, NotificationResource.ExpenseClaim_PaidOut);
                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.ExpenseClaim,
                                            foreignId);

                    break;

                case 'I':
                    // Invoice
                    InboundInvoice invoice         = InboundInvoice.FromIdentity(foreignId);
                    DateTime       expectedPayment = invoice.DueDate;

                    if (expectedPayment < DateTime.Today)
                    {
                        expectedPayment = DateTime.Today;
                    }

                    SwarmDb.GetDatabaseForWriting()
                    .CreatePayoutDependency(payoutId, FinancialDependencyType.InboundInvoice,
                                            invoice.Identity);

                    // TODO: NOTIFY PAID?

                    invoice.Open = false;
                    break;

                case 'S':
                    // Salary net

                    Salary salaryNet = Salary.FromIdentity(foreignId);
                    SwarmDb.GetDatabaseForWriting().CreatePayoutDependency(payoutId, FinancialDependencyType.Salary,
                                                                           salaryNet.Identity);
                    salaryNet.NetPaid = true;
                    break;

                case 'T':
                    // Tax payout, typically for multiple salaries

                    Salary salaryTax = Salary.FromIdentity(foreignId);
                    SwarmDb.GetDatabaseForWriting().CreatePayoutDependency(payoutId, FinancialDependencyType.SalaryTax,
                                                                           salaryTax.Identity);
                    salaryTax.TaxPaid = true;

                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            // Return the new object by reloading it from database

            return(Payout.FromIdentity(payoutId));
        }