Bulk Database Entries - Calculate Commission
I am writing an MVC 3 project and I'm using entity framework. I've written a method that generates bulk database entries, and this is for client's Invoices. The system is for a college and each student is enrolled with a specific tutor in the Enrollments class. The monthly fee of this enrollment is stored in Enrollments. The invoice method works correctly for generating invoices, but now I am looking to generate database entries for commission slips for the tutors of the college. The method would need to find all the students enrolled with each tutor (through the Enrollments class) and accumulate this amount. This total amount would then be multiplied by the Commission percentage the tutors receive. This would then be CommissionAmount. I am unsure how to write the code for this. These are the relevant model classes:
public class Enrollment
{
[Key]
[Display(Name = "Enrollment ID Number")]
public long EnrollmentIDNumber { get; set; }
[Display(Name = "Client ID Number")]
public long ClientNumberID { get; set; }
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
[Display(Name = "Course Name")]
public string CourseName { get; set; }
[Display(Name = "Lesson Time")]
public string LessonTime { get; set; }
[Display(Name = "Lesson Day")]
public string LessonDay { get; set; }
[Display(Name = "Lesson Location")]
public string LessonLocation { get; set; }
[Display(Name = "Lesson Type")]
public string LessonType { get; set; }
[Display(Name = "Lesson Level")]
public string LessonLevel { get; set; }
[Display(Name = "Monthly Fee")]
public long MonthlyFee { get; set; }
public virtual Client Client { get; set; }
public virtual Tutor Tutor { get; set; }
}
public class TutorCommission
{
[Key]
[Display(Name = "Commission ID")]
public long CommissionID { get; set; }
[Display(Name = "Commission Month")]
public string CommissionMonth {get; set;}
[Display(Name = "Commission Amount")]
public long CommissionAmount { get; set; }
[Display(Name = "Commission Status")]
public string CommissionStatus { get; set; }
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
public virtual Tutor Tutor { get; set; }
public virtual ICollection<CommissionPayments> CommissionPayments { get; set; }
}
public class TutorCommissionPercentage
{
[Key]
public int TutorCommissionID { get; set; }
public long TutorNoID { get; set; }
[Range(0, 100, ErrorMessage="Percentage must be between 0 and 100")]
[Display(Name="Commission Percentage")]
public decimal CommissionPercentage { get; set; }
public virtual Tutor Tutor { get; set; }
}
The code for the generate Invoices is the following:
public ActionResult CreateBulkInvoices()
{
var month = DateTime.Now.ToString("MMMM");
var enrolments = db.Enrollments.ToList();
var newInvoices = from enrolment in enrolments
select new Invoices()
{
InvoiceAmount = enrolment.Month开发者_运维技巧lyFee,
InvoiceMonth = month, // string constant
InvoiceStatus = "Unpaid",
ClientNumberID = enrolment.ClientNumberID
};
foreach (var newInvoice in newInvoices)
{
db.Invoice.Add(newInvoice);
db.SaveChanges();
}
return RedirectToAction("Index");
}
public class Tutor
{
[Key]
[Display(Name = "Tutor ID Number")]
public long TutorNoID { get; set; }
[Required]
[StringLength(50, ErrorMessage="First name must be less than 50 characters")]
[Display(Name = "First Name")]
public string TutorFirstName { get; set; }
[StringLength(50, ErrorMessage = "Last name must be less than 50 characters")]
[Display(Name = "Last Name")]
public string TutorLastName { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Display(Name = "Birth Date")]
public DateTime? TutorBirthDate { get; set; }
[Display(Name = "Cellphone Number")]
public string TutorCellphoneNumber { get; set; }
[Display(Name = "Home Number")]
public string TutorHomeNumber { get; set; }
[RegularExpression("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$", ErrorMessage = "Not a valid email address")]
[Display(Name = "Email Address")]
public string TutorEmailAddress { get; set; }
[Display(Name = "Street Address")]
public string TutorStreetAddress { get; set; }
[Display(Name = "Suburb")]
public string TutorSuburb { get; set; }
[Display(Name = "City")]
public string TutorCity { get; set; }
[Display(Name = "Postal Code")]
public string TutorPostalCode { get; set; }
[Display(Name="Full Name")]
public string FullName
{
get
{
return TutorFirstName + " " + TutorLastName;
}
}
[Display(Name="Commission Percentage")]
[Required]
public double TutorCommissionPercentage { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<TutorCommission> TutorCommissions { get; set; }
}
The purpose of these bulk database entry methods is so that the manager can click one link and generate Invoices and Commission Slips for all clients and tutors in the database.
Thanks Amy
To get it all done in one statement you need to join Enrollments and Commissions and then group by the Tutor.
This first example uses Query Syntax like you are using:
IEnumerable<TutorCommission> tutorsCommissions =
from enrollment in enrollments // Take the enrollments
join tutorsCommissionPercentage in tutorCommissionPercentages // Join with the tutor's commission percentages.
on enrollment.TutorNoID equals tutorsCommissionPercentage.TutorNoID
group enrollment by new { enrollment.TutorNoID, tutorsCommissionPercentage.CommissionPercentage } into enrollmentsAndCommissionByTutor // group enrollments and commission by the tutor
select new TutorCommission
{
TutorNoID = enrollmentsAndCommissionByTutor.Key.TutorNoID, // the grouping which is the tutor
CommissionAmount = (long) enrollmentsAndCommissionByTutor.Sum(e => e.MonthlyFee * enrollmentsAndCommissionByTutor.Key.CommissionPercentage)
};
This second example uses Method Syntax which is a little more intuitive for this operation
IEnumerable<TutorCommission> tutorsCommissionsAlt = enrollments // Take the enrollments
.GroupJoin( // This will group enrollments by the tutor
tutorCommissionPercentages, // Join with the tutor's commission percentages.
e => e.TutorNoID, // Use tutorNoID for left Key
tcp => tcp.TutorNoID, // ... and right key
(e, tcp) => new TutorCommission // Create entry which is the tutor and his total commission
{
TutorNoID = e.TutorNoID,
CommissionAmount = (long) tcp.Sum(c => c.CommissionPercentage * e.MonthlyFee)
});
精彩评论