partial void DeleteLoanPenalty(LoanPenalty instance);
 partial void UpdateLoanPenalty(LoanPenalty instance);
 partial void InsertLoanPenalty(LoanPenalty instance);
		private void detach_LoanPenalties(LoanPenalty entity)
		{
			this.SendPropertyChanging();
			entity.Loan = null;
		}
		private void attach_LoanPenalties(LoanPenalty entity)
		{
			this.SendPropertyChanging();
			entity.Loan = this;
		}
    static void calculatePenaltyForEachLoan(FinanceManagerDataContext dataContext, CompanyProfile cProfile)
    {
        //set grace period to zero if null
        if (cProfile.GracePeriodDays == null)
            cProfile.GracePeriodDays = 0;

        //select loans that have not been paid up and thier expected repayment dates are due. Given a grace period

        DateTime TodayPlusGracePeriod = DateTime.Today.Date.AddDays(cProfile.GracePeriodDays.Value);

        foreach (Loan Loanitem in dataContext.Loans.Where(l => l.IsPaidup.Value == false && TodayPlusGracePeriod >= l.ExpectedRepaymentEndDate.Value.Date)) //iterate through unpaid loans
        {

            LoanPenalty _loanPenalty = null;
            //get most recent penalty for current loan (Last penalty calculates)
            try
            {
                _loanPenalty = dataContext.LoanPenalties.Where<LoanPenalty>(l => l.LoanID == Loanitem.LoanID).OrderBy(lp => lp.CreatedDate).LastOrDefault();
            }
            catch (Exception)
            {

            }

            //get the frequency of calculation of penalty eg. every 30days
            int? _PenaltyCalculationFrequencyDays = cProfile.PenaltyCalculationFrequencyDays.Value;
            if (_PenaltyCalculationFrequencyDays == null)
                _PenaltyCalculationFrequencyDays = 0;

            if (_loanPenalty != null)
            {
                int numberOfTimesToRunPenalty = (DateTime.Today.Date - _loanPenalty.CreatedDate.Value.Date).Days / _PenaltyCalculationFrequencyDays.Value;
                if (numberOfTimesToRunPenalty > 0)
                    for (int i = 0; i < numberOfTimesToRunPenalty; i++)
                    {
                        decimal totalPenalty2;
                        try
                        {
                            totalPenalty2 = Loanitem.LoanPenalties.Sum(p => p.PenaltyAmount).Value;
                        }
                        catch (Exception)
                        {
                            totalPenalty2 = 0;
                        }

                        decimal balance2 = Loanitem.Amount.Value + totalPenalty2 - Loanitem.Repayments.Sum(r => r.RepaymentAmount).Value;
                        decimal penaltyInsterst2 = (cProfile.DefaultersInteresty.Value / 100) * balance2;

                        LoanPenalty _newLoanPenalty = new LoanPenalty();
                        _newLoanPenalty.CreatedDate = DateTime.Now;
                        _newLoanPenalty.LoanID = Loanitem.LoanID;
                        _newLoanPenalty.PenaltyAmount = penaltyInsterst2;
                        _newLoanPenalty.IsReleived = false;
                        _newLoanPenalty.PenaltyRate = cProfile.DefaultersInteresty.Value;
                        dataContext.LoanPenalties.InsertOnSubmit(_newLoanPenalty);

                        //audit
                        Utils.logAction("Insert", _newLoanPenalty);
                    }
            }
            else
            {
                //get the number of days between the lastRundate and today.
                int numberOfTimesToRunPenalty = (DateTime.Today.Date - cProfile.EndOfDayLastRunDate.Value).Days / _PenaltyCalculationFrequencyDays.Value;
                if (numberOfTimesToRunPenalty > 0)
                    for (int i = 0; i < numberOfTimesToRunPenalty; i++)
                    {
                        decimal totalPenalty2 = 0;

                        decimal balance2 = Loanitem.Amount.Value + totalPenalty2 - Loanitem.Repayments.Sum(r => r.RepaymentAmount).Value;
                        decimal penaltyInsterst2 = (cProfile.DefaultersInteresty.Value / 100) * balance2;

                        LoanPenalty _newLoanPenalty = new LoanPenalty();
                        _newLoanPenalty.CreatedDate = DateTime.Now;
                        _newLoanPenalty.LoanID = Loanitem.LoanID;
                        _newLoanPenalty.PenaltyAmount = penaltyInsterst2;
                        _newLoanPenalty.IsReleived = false;
                        _newLoanPenalty.PenaltyRate = cProfile.DefaultersInteresty.Value;
                        dataContext.LoanPenalties.InsertOnSubmit(_newLoanPenalty);

                        try
                        {
                            //test if this bit of the code works
                            totalPenalty2 = Loanitem.LoanPenalties.Sum(p => p.PenaltyAmount).Value;
                        }
                        catch (Exception)
                        {
                            totalPenalty2 = 0;
                        }
                        //audit
                        Utils.logAction("Insert", _newLoanPenalty);
                    }
            }
        }
    }