4.7.2. Loading the Invoice Data
The following method loads the invoice headers:
public void LoadInvoicesData() {var dbContext = AppVariables.getDbContext();var invoices =from invoice in dbContext.INVOICESwhere (invoice.INVOICE_DATE >= AppVariables.StartDate) &&(invoice.INVOICE_DATE <= AppVariables.FinishDate)orderby invoice.INVOICE_DATE descendingselect new InvoiceView{Id = invoice.INVOICE_ID,Cusomer_Id = invoice.CUSTOMER_ID,Customer = invoice.CUSTOMER.NAME,Date = invoice.INVOICE_DATE,Amount = invoice.TOTAL_SALE,Payed = (invoice.PAYED == 1) ? "Yes" : "No"};masterBinding.DataSource = invoices.ToBindingList();}
To simplify type casting, we define an InvoiceView class, rather than use some anonymous type. The definition is as follows:
public class InvoiceView {public int Id { get; set; }public int Cusomer_Id { get; set; }public string Customer { get; set; }public DateTime? Date { get; set; }public decimal? Amount { get; set; }public string Payed { get; set; }public void Load(int Id) {var dbContext = AppVariables.getDbContext();var invoices =from invoice in dbContext.INVOICESwhere invoice.INVOICE_ID == Idselect new InvoiceView{Id = invoice.INVOICE_ID,Cusomer_Id = invoice.CUSTOMER_ID,Customer = invoice.CUSTOMER.NAME,Date = invoice.INVOICE_DATE,Amount = invoice.TOTAL_SALE,Payed = (invoice.PAYED == 1) ? "Yes" : "No"};InvoiceView invoiceView = invoices.ToList().First();this.Id = invoiceView.Id;this.Cusomer_Id = invoiceView.Cusomer_Id;this.Customer = invoiceView.Customer;this.Date = invoiceView.Date;this.Amount = invoiceView.Amount;this.Payed = invoiceView.Payed;}}
The Load method allows us to update one added or updated record in the grid quickly, instead of completely reloading all records. Here is the code of the event handler for clicking the Add button:
private void btnAddInvoice_Click(object sender, EventArgs e) {var dbContext = AppVariables.getDbContext();var invoice = dbContext.INVOICES.Create();using (InvoiceEditorForm editor = new InvoiceEditorForm()) {editor.Text = "Add invoice";editor.Invoice = invoice;// Form Close Handlereditor.FormClosing += delegate (object fSender, FormClosingEventArgs fe) {if (editor.DialogResult == DialogResult.OK) {try {// get next sequence valueinvoice.INVOICE_ID = dbContext.NextValueFor("GEN_INVOICE_ID");// add a recorddbContext.INVOICES.Add(invoice);// trying to save the changesdbContext.SaveChanges();// add the projection to the grid list((InvoiceView)masterBinding.AddNew()).Load(invoice.INVOICE_ID);}catch (Exception ex) {// display errorMessageBox.Show(ex.Message, "Error");// Do not close the form to correct the errorfe.Cancel = true;}}};// show the modal formeditor.ShowDialog(this);}}
In our primary modules, the similarly-named method called dbContext.Refresh but, here, a record is updated by by calling the Load method of the InvoiceView class. The reason for the difference is that dbContext.Refresh is used to update entity objects, not the objects that can be produced by complex LINQ queries.
The code of the event handler for clicking the Edit button:
private void btnEditInvoice_Click(object sender, EventArgs e) {var dbContext = AppVariables.getDbContext();// find entity by idvar invoice = dbContext.INVOICES.Find(this.CurrentInvoice.Id);if (invoice.PAYED == 1) {MessageBox.Show("The change is not possible, the invoice has already been paid.","Error");return;}using (InvoiceEditorForm editor = new InvoiceEditorForm()) {editor.Text = "Edit invoice";editor.Invoice = invoice;// Form Close Handlereditor.FormClosing += delegate (object fSender, FormClosingEventArgs fe) {if (editor.DialogResult == DialogResult.OK) {try {// trying to save the changesdbContext.SaveChanges();// refreshCurrentInvoice.Load(invoice.INVOICE_ID);masterBinding.ResetCurrentItem();}catch (Exception ex) {// display errorMessageBox.Show(ex.Message, "Error");// Do not close the form to correct the errorfe.Cancel = true;}}};editor.ShowDialog(this);}}
Here we needed to find an entity by the identifier provided in the current record. The CurrentInvoice is used to retrieve the invoice selected in the grid. This is how we code it:
public InvoiceView CurrentInvoice {get {return (InvoiceView)masterBinding.Current;}}
Using the same approach, you can implement deleting the invoice header yourself.
Paying an Invoice
Besides adding, editing and deleting, we want one more operation for invoices: payment. Here is code for a method implementing this operation:
private void btnInvoicePay_Click(object sender, EventArgs e) {var dbContext = AppVariables.getDbContext();var invoice = dbContext.INVOICES.Find(this.CurrentInvoice.Id);try {if (invoice.PAYED == 1)throw new Exception("The change is not possible, the invoice has already been paid.");invoice.PAYED = 1;// trying to save the changesdbContext.SaveChanges();// refresh recordCurrentInvoice.Load(invoice.INVOICE_ID);masterBinding.ResetCurrentItem();}catch (Exception ex) {// display errorMessageBox.Show(ex.Message, "Error");}}
