Stellar Water Point - JSON Serialization
Stellar Water Point - JSON Serialization
Application Setup
Introduction
In this exercise, we will create a semi-small graphical application for a water distribution company that provides water for various types of customers, including residential families, private businesses, government buildings, etc. The application uses a text-based database that processes records using collection classes. The records are saved in JSON files.
Practical Learning: Introducing the Application
namespace StellarWaterPoint2.Models
{
public enum Answer { No = 0, Yes = 1, Cancel = 2, Unknown = 3 }
internal static class MsgBox
{
public static void Show(string message)
{
MessageBox.Show(message,
"Stellar Water Point",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
public static Answer Question(string message)
{
DialogResult result = MessageBox.Show(message,
"Stellar Water Point",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question);
switch (result)
{
case DialogResult.Yes:
return Answer.Yes;
case DialogResult.No:
return Answer.No;
case DialogResult.Cancel:
return Answer.Cancel;
default:
return Answer.Unknown;
}
}
}
}The Main Form of the Application
Our application will use a central form acting as a switchboard from which other section-based forms can be accessed.
Practical Learning: Preparing the Main Form of the Application
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
public WaterDistribution()
{
InitializeComponent();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
}
}Water Meters
Introduction
The company of our application uses water meters to monitor the amount of water its customers consume. To start, the application needs a list of water meters that are available.
Practical Learning: Displaying Water Meters
namespace StellarWaterPoint2.Models
{
internal record WaterMeter
{
public int WaterMeterId { get; set; }
public string? MeterNumber { get; set; }
public string? Make { get; set; }
public string? Model { get; set; }
public string? MeterSize { get; set; }
}
}Displaying Water Meters
To let the user see a list of the water meters in the database, we will use a form equipped with a list view.
Practical Learning: Displaying Water Meters
| (Name) | Text | Width | TextAlign |
| colWaterMeterId | Water Meter Id | 150 | |
| colMeterNumber | Meter # | 150 | Center |
| colMake | Make | 300 | |
| colModel | Model | 150 | |
| colMeterSize | Meter Size | 150 |
| Control | (Name) | Other Properties | |
| ListView | lvwWaterMeters | FullRowSelect: True GridLines: True View: Details |
|
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterMeters()
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
lvwWaterMeters.Items.Clear();
foreach (WaterMeter wm in waterMeters)
{
ListViewItem lviWaterMeter = new ListViewItem(wm.WaterMeterId.ToString());
lviWaterMeter.SubItems.Add(wm.MeterNumber);
lviWaterMeter.SubItems.Add(wm.Make);
lviWaterMeter.SubItems.Add(wm.Model);
lviWaterMeter.SubItems.Add(wm.MeterSize);
lvwWaterMeters.Items.Add(lviWaterMeter);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterMeters();
}
}
}| Control | (Name) | Text | Font | |
| Button | btnWaterMeters | &Water Meters... | Times New Roman, 24pt, style=Bold | |
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
public WaterDistribution()
{
InitializeComponent();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new WaterMeters.Central();
central.Show();
}
}
}A Water Meter Record
A water meter must be installed in the location where water is consumed. We will create a form that allows a user to create a new record for a water meter.
Practical Learning: Creating a Water Meter Record

| Control | (Name) | Text | Other Properties | |
| Label | &Meter #: | |||
| MaskedTextBox | mtbMeterNumber | Masked: 000-000-000 Modifiers: Public |
||
| Label | &Water Meter Id: | |||
| TextBox | txtWaterMeterId | Modifiers: Public | ||
| Label | M&ake: | |||
| TextBox | txtMake | Modifiers: Public | ||
| Label | M&odel: | |||
| TextBox | txtModel | Modifiers: Public | ||
| Label | Me&ter Size: | |||
| TextBox | txtMeterSize | Modifiers: Public | ||
| Button | btnOK | &OK | DialogResult: OK | |
| Button | btnCancel | &Cancel | DialogResult: Cancel | |
FormBorderStyle: FixedDialog Text: Stellar Water Point - Create Water Meter StartPosition: CenterScreen AcceptButton: btnOK CancelButton: btnCancel
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void Create_Load(object sender, EventArgs e)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
int waterMeterId = 0;
if (fiWaterMeters.Exists == true)
{
using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter wm in waterMeters)
{
waterMeterId = wm.WaterMeterId;
}
}
}
txtWaterMeterId.Text = (waterMeterId + 1).ToString();
}
}
}| Control | (Name) | Text | |
| ListView | No Change | No Change | |
| Button | btnNewWaterMeter | &New Water Meter... | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterMeters()
{
. . .
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterMeters();
}
private void btnNewWaterMeter_Click(object sender, EventArgs e)
{
Create create = new();
if (create.ShowDialog() == DialogResult.OK)
{
if(create.mtbMeterNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a meter number. " +
"Otherwise, the water meter cannot be set up.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
}
WaterMeter wm = new WaterMeter()
{
WaterMeterId = create.txtWaterMeterId.Text == "" ? 1 : int.Parse(create.txtWaterMeterId.Text),
MeterNumber = create.mtbMeterNumber.Text,
Make = create.txtMake.Text,
Model = create.txtModel.Text,
MeterSize = create.txtMeterSize.Text
};
waterMeters.Add(wm);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
}
ShowWaterMeters();
}
}
}

| Meter # | Make | Model | Meter Size |
| 392-494-572 | Constance Technologies | TG-4822 | 5/8 Inches |
| 938-705-869 | Stan Wood | 66-G | 1 Inch |
| 588-279-663 | Estellano | NCF-226 | 3/4 Inches |
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
public WaterDistribution()
{
InitializeComponent();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new();
central.Show();
}
}
}Water Meter Details
When the records of water meters have been created, sometimes, a user may want to view some details about a water meter. We are going to create such a form.
Practical Learning: Creating a Water Meter Record

| Control | (Name) | Text | Enabled | Modifiers | Other Properties | |
| Label | &Meter #: | |||||
| MaskedTextBox | mtbMeterNumber | False | Public | Masked: 000-000-000 | ||
| Button | btnFindWaterMeter | &Find Water Meter | ||||
| Label | Make: | |||||
| TextBox | txtMake | False | Public | |||
| Label | Model: | |||||
| TextBox | txtModel | False | Public | |||
| Label | Meter Size: | |||||
| TextBox | txtMeterSize | False | Public | |||
| Label | Water Meter Id: | |||||
| TextBox | txtWaterMeterId | False | Public | |||
| Button | btnClose | &Close | ||||
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Details : Form
{
public Details()
{
InitializeComponent();
}
private void btnFindWateMeter_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(mtbMeterNumber.Text))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.",
"Stellar Water Point", MessageBoxButtons.OK);
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtMake.Text = meter.Make;
txtModel.Text = meter.Model;
txtMeterSize.Text = meter.MeterSize;
}
}
}
}
}
}private void btnClose_Click(object sender, EventArgs e)
{
Close();
}| Control | (Name) | Other Properties | |
| ListView | No Change | No Change | |
| Button | No Change | No Change | |
| Button | btnViewWaterMeter | &View Water Meter... | |
private void btnViewWaterMeter_Click(object sender, EventArgs e)
{
Details view = new();
view.ShowDialog();
}

Updating a Water Meter Details
One of the routine operations performed on a database is to change the details of a record. To support this operation for a water meter, we will create a form that can be used to update the information of a water meter.
Practical Learning: Updating a Water Meter

| Control | (Name) | Text | Enabled | Other Properties | |
| Label | &Meter #: | ||||
| MaskedTextBox | mtbMeterNumber | False | Masked: 000-000-000 | ||
| Button | btnFindWaterMeter | &Find Water Meter | |||
| Label | Make: | ||||
| TextBox | txtMake | False | |||
| Label | Model: | ||||
| TextBox | txtModel | False | |||
| Label | Meter Size: | ||||
| TextBox | txtMeterSize | False | |||
| Button | btnUpdateWaterMeter | &Update Water Meter | |||
| Button | btnClose | &Close | |||
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Editor : Form
{
public Editor()
{
InitializeComponent();
}
private void btnFindWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("Please provide a meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtWaterMeterId.Text = meter.WaterMeterId.ToString();
txtMake.Text = meter.Make;
txtModel.Text = meter.Model;
txtMeterSize.Text = meter.MeterSize;
}
}
}
}
}
}private void btnUpdateWaterMeter_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(mtbMeterNumber.Text))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
WaterMeter? meter = waterMeters.Find(mtr => mtr.MeterNumber == mtbMeterNumber.Text);
if (meter is not null)
{
meter.WaterMeterId = int.Parse(txtWaterMeterId.Text);
meter.Make = txtMake.Text;
meter.Model = txtModel.Text;
meter.MeterSize = txtMeterSize.Text;
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
}
}
Close();
}private void btnClose_Click(object sender, EventArgs e)
{
Close();
}| Control | (Name) | Other Properties | |
| ListView | No Change | No Change | |
| Button | No Change | No Change | |
| Button | No Change | No Change | |
| Button | btnEditWaterMeter | &Edit Water Meter... | |
private void btnEditWaterMeter_Click(object sender, EventArgs e)
{
Editor editor = new();
editor.ShowDialog();
ShowWaterMeters();
}

| Make: | Stanford Trend | Model: | 266G |
| Meter Size: | 1 1/2 Inches |


Removing a Water Meter from the Database
If a record of a water meter is not necessary anymore, a user can be asked to delete such a record. We are going to create a form for such an operation.
Practical Learning: Deleting a Water Meter Record

| Control | (Name) | Text | Enabled | Other Properties | |
| Label | &Meter #: | ||||
| MaskedTextBox | mtbMeterNumber | False | Masked: 000-000-000 | ||
| Label | Make: | ||||
| TextBox | txtMake | False | |||
| Label | Model: | ||||
| TextBox | txtModel | False | |||
| Label | Meter Size: | ||||
| TextBox | txtMeterSize | False | |||
| Button | btnClose | &Close | |||
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Delete : Form
{
public Delete()
{
InitializeComponent();
}
private void btnFindWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("Please provide a meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtWaterMeterId.Text = meter.WaterMeterId.ToString();
txtMake.Text = meter.Make;
txtModel.Text = meter.Model;
txtMeterSize.Text = meter.MeterSize;
}
}
}
}
}
}private void btnDeleteWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
WaterMeter meter = waterMeters.Find(mtr => mtr.MeterNumber == mtbMeterNumber.Text)!;
if (meter is not null)
{
if (MsgBox.Question("Are you sure you want to delete this water meter " +
"(you cannot undo the action)?") == Answer.Yes)
{
waterMeters.Remove(meter);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
MsgBox.Show("The water meter has been removed from our database.");
}
}
}
Close();
}private void btnClose_Click(object sender, EventArgs e)
{
Close();
}| Control | (Name) | Text | Anchor | |
| ListView | lvwWaterMeters | Top, Bottom, Left, Right | ||
| Button | btnNewWaterMeter | &New Water Meter... | Bottom, Right | |
| Button | btnViewWaterMeter | &View Water Meter... | Bottom, Right | |
| Button | btnEditWaterMeter | &Edit Water Meter... | Bottom, Right | |
| Button | btnDeleteWateMeter | &Delete Water Meter... | Bottom, Right | |
| Button | btnClose | &Close | Bottom, Right | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterMeters()
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
using (TextReader trWaterMeters = new StreamReader(fiWaterMeters.FullName))
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
lvwWaterMeters.Items.Clear();
foreach (WaterMeter wm in waterMeters)
{
ListViewItem lviWaterMeter = new ListViewItem(wm.WaterMeterId.ToString());
lviWaterMeter.SubItems.Add(wm.MeterNumber);
lviWaterMeter.SubItems.Add(wm.Make);
lviWaterMeter.SubItems.Add(wm.Model);
lviWaterMeter.SubItems.Add(wm.MeterSize);
lvwWaterMeters.Items.Add(lviWaterMeter);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterMeters();
}
private void btnNewWaterMeter_Click(object sender, EventArgs e)
{
Create create = new();
if (create.ShowDialog() == DialogResult.OK)
{
if (create.mtbMeterNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a meter number. " +
"Otherwise, the water meter cannot be set up.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
}
WaterMeter wm = new WaterMeter()
{
WaterMeterId = create.txtWaterMeterId.Text == "" ? 1 : int.Parse(create.txtWaterMeterId.Text),
MeterNumber = create.mtbMeterNumber.Text,
Make = create.txtMake.Text,
Model = create.txtModel.Text,
MeterSize = create.txtMeterSize.Text
};
waterMeters.Add(wm);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
}
ShowWaterMeters();
}
private void btnViewWaterMeter_Click(object sender, EventArgs e)
{
Details view = new();
view.Show();
}
private void btnUpdateWaterMeter_Click(object sender, EventArgs e)
{
Editor editor = new();
editor.ShowDialog();
ShowWaterMeters();
}
private void btnDeleteWaterMeter_Click(object sender, EventArgs e)
{
Delete delete = new Delete();
delete.ShowDialog();
ShowWaterMeters();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}




using StellarWaterPoint2.Models;
using System.Reflection.Metadata;
using System.Text.Json;
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
private void CreateWaterMeters()
{
List<WaterMeter> waterMeters = new List<WaterMeter>();
waterMeters!.Add(new WaterMeter() { WaterMeterId = 1, MeterNumber = "392-494-572", Make = "Constance Technologies", Model = "TG-4822", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 2, MeterNumber = "938-725-869", Make = "Stanford Trend", Model = "266G", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 3, MeterNumber = "588-279-663", Make = "Estellano", Model = "NCF-226", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 4, MeterNumber = "186-962-805", Make = "Lansome", Model = "2800", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 5, MeterNumber = "379-386-979", Make = "Planetra", Model = "P-2020", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 6, MeterNumber = "580-742-825", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 7, MeterNumber = "849-351-444", Make = "Raynes Energica", Model = "a1088", MeterSize = "2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 8, MeterNumber = "208-428-308", Make = "Constance Technologies", Model = "808D", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 9, MeterNumber = "738-588-249", Make = "Warrington", Model = "W4242", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 10, MeterNumber = "496-813-794", Make = "Estellano", Model = "NCF-226", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 11, MeterNumber = "862-715-006", Make = "Warrington", Model = "W-4040", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 12, MeterNumber = "649-358-184", Make = "Raynes Energica", Model = "b1700", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 13, MeterNumber = "928-317-924", Make = "Gongola", Model = "GN1000", MeterSize = "2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 14, MeterNumber = "595-753-147", Make = "Grass Grill", Model = "CRC-1000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 15, MeterNumber = "799-528-461", Make = "Kensa Sons", Model = "K-584-L", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 16, MeterNumber = "386-468-057", Make = "Estellano", Model = "NCF-226", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 17, MeterNumber = "938-275-294", Make = "Constance Technologies", Model = "TT-8822", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 18, MeterNumber = "288-427-585", Make = "Planetra", Model = "P-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 19, MeterNumber = "394-835-297", Make = "Raynes Energica", Model = "i2022", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 20, MeterNumber = "847-252-246", Make = "Master Stream", Model = "2000-MS", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 21, MeterNumber = "349-725-848", Make = "Planetra", Model = "P-8000", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 22, MeterNumber = "713-942-058", Make = "Master Stream", Model = "3366-MS", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 23, MeterNumber = "747-581-379", Make = "Warrington", Model = "W4242", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 24, MeterNumber = "582-755-263", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 25, MeterNumber = "827-260-758", Make = "Raynes Energica", Model = "a1088", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 26, MeterNumber = "837-806-836", Make = "Lansome", Model = "7400", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 27, MeterNumber = "207-964-835", Make = "Constance Technologies", Model = "TG-6220", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 28, MeterNumber = "296-837-495", Make = "Raynes Energica", Model = "QG505", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 29, MeterNumber = "468-359-486", Make = "Grass Grill", Model = "KLP-8822", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 30, MeterNumber = "931-486-003", Make = "Planetra", Model = "P-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 31, MeterNumber = "483-770-648", Make = "Warren", Model = "WWW", MeterSize = "0.1 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 32, MeterNumber = "592-824-957", Make = "Kensa Sons", Model = "D-497-H", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 33, MeterNumber = "293-835-704", Make = "Gongola", Model = "GOL1000", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 34, MeterNumber = "739-777-749", Make = "Warrington", Model = "W2200W", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 35, MeterNumber = "374-886-284", Make = "Raynes Energica", Model = "i2022", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 36, MeterNumber = "186-959-757", Make = "Kensa Sons", Model = "M-686-G", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 37, MeterNumber = "594-827-359", Make = "Planetra", Model = "P-8000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 38, MeterNumber = "394-739-242", Make = "Master Stream", Model = "9393-TT", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 39, MeterNumber = "529-283-752", Make = "Constance Technologies", Model = "404T", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 40, MeterNumber = "295-770-695", Make = "Warrington", Model = "W-2286", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 41, MeterNumber = "739-749-737", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 42, MeterNumber = "947-528-317", Make = "Gondola", Model = "GDL-5000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 43, MeterNumber = "630-207-055", Make = "Lansome", Model = "2800", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 44, MeterNumber = "827-508-248", Make = "Standard Trend", Model = "428T", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 45, MeterNumber = "293-924-869", Make = "Grass Grill", Model = "CRC-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 46, MeterNumber = "928-247-580", Make = "Gondola", Model = "GOL2000", MeterSize = "0.34 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 47, MeterNumber = "682-537-380", Make = "Planetra", Model = "P-2020", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 48, MeterNumber = "470-628-850", Make = "Estellano", Model = "WRT-482", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 49, MeterNumber = "649-373-505", Make = "Constance Technologies", Model = "BD-7000", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 50, MeterNumber = "306-842-497", Make = "Lansome", Model = "9000", MeterSize = "3/4 Inches" });
string strWaterMeters = string.Empty;
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
}
private void CreateAccountsTypes()
{
List<AccountType> types = new List<AccountType>()
{
new AccountType() { AccountTypeId = 1, TypeCode = "OTH", TypeDecription = "Other" },
new AccountType() { AccountTypeId = 3, TypeCode = "RES", TypeDecription = "Residential Household" },
new AccountType() { AccountTypeId = 2, TypeCode = "BUS", TypeDecription = "General Business, Commercial, Industrial" },
new AccountType() { AccountTypeId = 5, TypeCode = "UUO", TypeDecription = "Unidentified or Unclassified Type of Organization" },
new AccountType() { AccountTypeId = 4, TypeCode = "SGO", TypeDecription = "Social/Government/Non-Profit Organization, Institutional" },
new AccountType() { AccountTypeId = 6, TypeCode = "WAT", TypeDecription = "Water Intensive Business (Agricultural, Laudromat, Hair Salon, Restaurant, etc" }
};
string strAccountsTypes = string.Empty;
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
string jsAccountsTypes = JsonSerializer.Serialize(types, typeof(List<AccountType>), options);
File.WriteAllText(fiAccountsTypes.FullName, jsAccountsTypes);
}
public WaterDistribution()
{
InitializeComponent();
CreateWaterMeters();
CreateAccountsTypes();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new WaterMeters.Central();
central.Show();
}
}
}using StellarWaterPoint2.Models;
using System.Reflection.Metadata;
using System.Text.Json;
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
private void CreateWaterMeters()
{
. . .
}
private void CreateAccountsTypes()
{
. . .
}
public WaterDistribution()
{
InitializeComponent();
// CreateWaterMeters();
// CreateAccountsTypes();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new WaterMeters.Central();
central.Show();
}
}
}Customers
Introduction
For a water distribution company, a customer is a person, a business, or any entity that consumes water. At a minimum, a computer must keep a list of entities that use its business.
Practical Learning: Introducing Customers
namespace StellarWaterPoint2.Models
{
internal readonly record struct AccountType
{
public readonly int AccountTypeId { get; init; }
public readonly string? TypeCode { get; init; }
public readonly string? TypeDecription { get; init; }
}
}namespace StellarWaterPoint2.Models
{
public class Customer
{
public int CustomerId { get; set; }
public string? AccountNumber { get; set; }
public string? AccountName { get; set; }
public string? MeterNumber { get; set; }
public string? AccountType { get; set; }
public string? Address { get; set; }
public string? City { get; set; }
public string? County { get; set; }
public string? State { get; set; }
public string? ZIPCode { get; set; }
}
}Displaying Customers
In a later section, we will learn how to create a customer record. When those records exist, a user can display them. We are going to make it possible through a form equipped with a list view
Practical Learning: Displaying Customers
| (Name) | Text | TextAlign | Width |
| colCustomerId | Id | 40 | |
| colAccountNumber | Account # | Center | 150 |
| colAccountName | Account Name | 200 | |
| colMeterNumber | Meter # | Center | 100 |
| colAccountType | Account Type | 200 | |
| colAddress | Address | 250 | |
| colCity | City | 125 | |
| colCounty | County | 125 | |
| colState | State | Center | |
| colZIPCode | ZIP-Code | Center | 125 |
| Control | (Name) | Other Properties | |
| ListView | lvwCustomers | FullRowSelect: True GridLines: True View: Details |
|
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowCustomers()
{
string strCustomers = string.Empty;
List<Customer> Customers = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
Customers = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
lvwCustomers.Items.Clear();
foreach (Customer wm in Customers)
{
ListViewItem lviCustomer = new ListViewItem(wm.CustomerId.ToString());
lviCustomer.SubItems.Add(wm.AccountNumber);
lviCustomer.SubItems.Add(wm.AccountName);
lviCustomer.SubItems.Add(wm.MeterNumber);
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (wm.AccountType == at.TypeCode)
{
lviCustomer.SubItems.Add(string.Concat(at.TypeCode, " - ", at.TypeDecription));
}
}
lviCustomer.SubItems.Add(wm.Address);
lviCustomer.SubItems.Add(wm.City);
lviCustomer.SubItems.Add(wm.County);
lviCustomer.SubItems.Add(wm.State);
lviCustomer.SubItems.Add(wm.ZIPCode);
lvwCustomers.Items.Add(lviCustomer);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowCustomers();
}
}
}| Control | (Name) | Text | Font | |
| Button | btnCustomers | C&ustomers... | Times New Roman, 24pt, style=Bold | |
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
public WaterDistribution()
{
InitializeComponent();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
// Repository.CreateAccountsTypes();
// Repository.CreateWaterMeters();
}
private void btnCustomers_Click(object sender, EventArgs e)
{
Customers.Central central = new();
central.Show();
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new();
central.Show();
}
}
}A New Customer Account
To use the services of a water distribution company, a customer must have an account. We are going to create a form that an employee can use to establish an account for a new customer.
Practical Learning: Creating a Customer Account

| Control | (Name) | Text | Other Properties | |
| Label | &Account #: | |||
| MaskedTextBox | mtbAccountNumber | Masked: 0000-000-0000 | ||
| Label | &Account Name: | |||
| TextBox | txtAccountName | |||
| Label | &Meter #: | |||
| MaskedTextBox | mtbMeterNumber | Masked: 000-000-000 | ||
| Button | btnFindWaterMeter | &Find Water Meter | ||
| Label | Meter &Details: | |||
| TextBox | txtMeterDetails | Enabled: False | ||
| Label | &Account Type: | |||
| ComboBox | cbxAccountsTypes | |||
| Label | &Address: | |||
| TextBox | txtAddress | |||
| Label | C&ity: | |||
| TextBox | txtCity | |||
| Label | C&ounty: | |||
| TextBox | txtCounty | |||
| Label | &State: | |||
| TextBox | txtState | |||
| Label | &ZIP-Code: | |||
| MaskedTextBox | mtbZIPCode | Masked: Zip-Code | ||
| Label | Customer Id:& | |||
| TextBox | txtCustomerId | |||
| Button | btnSaveCustomerAccount | S&ave Customer Account | DialogResult: OK | |
| Button | btnClose | &Close | DialogResult: Cancel | |
FormBorderStyle: FixedDialog Text: Stellar Water Point - Create Customer Account StartPosition: CenterScreen AcceptButton: btnSaveCustomerAccount CancelButton: btnCancel
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void SetCustomerId()
{
string strCustomers = string.Empty;
List<Customer> Customers = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
int CustomerId = 0;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
Customers = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
foreach (Customer wm in Customers)
{
CustomerId = wm.CustomerId;
}
}
}
txtCustomerId.Text = (CustomerId + 1).ToString();
}
private void SetAccountsTypes()
{
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType type in types)
{
cbxAccountsTypes.Items.Add(type.TypeCode + " - " + type.TypeDecription);
}
}
}
private void Create_Load(object sender, EventArgs e)
{
SetCustomerId();
SetAccountsTypes();
}
}
}private void btnFindWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtMeterDetails.Text = meter.WaterMeterId.ToString() + " - " +
meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}| Control | (Name) | Other Properties | |
| ListView | lvwCustomers | FullRowSelect: True GridLines: True View: Details |
|
| Button | btnNewCustomerAccount | &New Customer Account... | |
private void btnCreateCustomerAccount_Click(object sender, EventArgs e)
{
Create create = new();
if (create.ShowDialog() == DialogResult.OK)
{
if(create.mtbAccountNumber.Text.Replace("-", "").Trim().Equals(""))
{
MsgBox.Show("You must provide an account number for a new customer. " +
"Otherwise, the account cannot be created.");
return;
}
if (create.mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number to associate " +
"a water meter to a customer's account. After providing " +
"a meter number, click the Find Water Meter button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
}
Customer client = new Customer()
{
CustomerId = int.Parse(create.txtCustomerId.Text),
AccountNumber = create.mtbAccountNumber.Text,
AccountName = create.txtAccountName.Text,
MeterNumber = create.mtbMeterNumber.Text,
AccountType = create.cbxAccountsTypes.Text.Substring(0, 3),
Address = create.txtAddress.Text,
City = create.txtCity.Text,
County = create.txtCounty.Text,
State = create.txtState.Text,
ZIPCode = create.mtbZIPCode.Text
};
clients.Add(client);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
}
ShowCustomers();
}Account #: 9279-570-8394 Account Name: Thomas Stones Meter #: 799-528-461 Account Type: RES - Residential Household Address: 10252 Broward Ave #D4 City: Frederick County: Frederick State: MD ZIP-Code: 21703-4422
| Account # | Account Name | Meter # | Account Type | Address | City | County | State | ZIP-Code |
| 4086-938-4783 | Hernola Dough | 594-827-359 | UUO - Unidentified or Unclassified Type of Organization | 10 10 Hexagonal Drv | Winston | Yoke | Penn | 11402-4411 |
| 7080-583-5947 | Sunny Yard | 827-508-248 | WAT - Water Intensive Business(Laudromat, Hair Salon, Restaurant, etc | 663 Sherry Wood East Street | Shimpstown | Franklin | PA | 17236-2626 |
Customer Account Details
When a customer account has been created, at any time, an employee may want to simply review such an account. Our application needs a form for that.
Practical Learning: Showing Customer Account

| Control | (Name) | Text | Other Properties | |
| Label | &Account #: | |||
| MaskedTextBox | mtbAccountNumber | Masked: 0000-000-0000 | ||
| Button | btnFindCustomerAccount | &Find Customer Account | ||
| Label | &Account Name: | |||
| TextBox | txtAccountName | Enabled: False | ||
| Label | Meter &Details: | |||
| TextBox | txtMeterDetails | Enabled: False | ||
| Label | &Account Type: | |||
| TextBox | txtAccountsTypes | Enabled: False | ||
| Label | &Address: | |||
| TextBox | txtAddress | Enabled: False | ||
| Label | C&ity: | |||
| TextBox | txtCity | Enabled: False | ||
| Label | C&ounty: | |||
| TextBox | txtCounty | Enabled: False | ||
| Label | &State: | |||
| TextBox | txtState | Enabled: False | ||
| Label | &ZIP-Code: | |||
| TextBox | txtZIPCode | Enabled: False | ||
| Label | Customer Id:&: | |||
| TextBox | txtCustomerId | Enabled: False | ||
| Button | btnClose | &Close | ||
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Details : Form
{
public Details()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
string strAccountType = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtCustomerId.Text = client.CustomerId.ToString();
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
strAccountType = client.AccountType!;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
IEnumerable<AccountType> actType = from category
in types
where category.TypeCode == strAccountType
select category;
foreach (AccountType type in types)
{
txtAccountType.Text = $"{type.TypeCode } - {type.TypeDecription}";
}
}
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}private void btnClose_Click(object sender, EventArgs e)
{
Close();
}| Control | (Name) | Other Properties | |
| ListView | lvwCustomers | No Change | |
| Button | No Change | No Change | |
| Button | btnCustomerAccountDetails | Customer Account &Details... | |
using System.Data;
using Microsoft.Data.SqlClient;
namespace StellarWaterPoint2.Customers
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowCustomers()
{
. . .
}
private void Central_Load(object sender, EventArgs e)
{
ShowCustomers();
}
private void btnCreateCustomerAccount_Click(object sender, EventArgs e)
{
. . .
}
private void btnCustomerAccountDetails_Click(object sender, EventArgs e)
{
Details details = new();
details.ShowDialog();
ShowCustomers();
}
}
}

Editing a Customer Account
When a piece of information has changed about a customer, an employee should update the customer account. We will provide a for such an operation.
Practical Learning: Editing a Customer Account

| Control | (Name) | Text | Other Properties | |
| Label | &Account #: | |||
| MaskedTextBox | mtbAccountNumber | Masked: 0000-000-0000 | ||
| Button | btnFindCustomerAccount | &Find Customer Account | ||
| Label | &Account Name: | |||
| TextBox | txtAccountName | |||
| Label | &Meter #: | |||
| MaskedTextBox | mtbMeterNumber | Masked: 000-000-000 | ||
| Button | btnFindWaterMeter | Find &Water Meter | ||
| Label | Meter &Details: | |||
| TextBox | txtMeterDetails | Enabled: False | ||
| Label | &Account Type: | |||
| ComboBox | cbxAccountsTypes | |||
| Label | &Address: | |||
| TextBox | txtAddress | |||
| Label | C&ity: | |||
| TextBox | txtCity | |||
| Label | C&ounty: | |||
| TextBox | txtCounty | |||
| Label | &State: | |||
| TextBox | txtState | |||
| Label | &ZIP-Code: | |||
| MaskedTextBox | mtbZIPCode | Masked: Zip-Code | ||
| Label | Customer Id:&: | |||
| TextBox | txtCustomerId | Enabled: False | ||
| Button | btnUpdateCustomerAccount | &Update Customer Account | DialogResult: OK | |
| Button | btnClose | &Close | DialogResult: Cancel | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Editor : Form
{
public Editor()
{
InitializeComponent();
}
private void Editor_Load(object sender, EventArgs e)
{
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType type in types)
{
cbxAccountsTypes.Items.Add(type.TypeCode + " - " + type.TypeDecription);
}
}
}
}
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Editor : Form
{
public Editor()
{
InitializeComponent();
}
private void Editor_Load(object sender, EventArgs e)
{
. . .
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
string strAccountType = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtCustomerId.Text = client.CustomerId.ToString();
txtAccountName.Text = client.AccountName;
mtbMeterNumber.Text = client.MeterNumber;
strAccountType = client.AccountType!;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
mtbZIPCode.Text = client.ZIPCode;
}
}
}
if (mtbAccountNumber.Text!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == mtbMeterNumber.Text
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
IEnumerable<AccountType> actType = from category
in types
where category.TypeCode == strAccountType
select category;
foreach (AccountType type in types)
{
cbxAccountsTypes.Text = $"{type.TypeCode} - {type.TypeDecription}";
}
}
}
}
}private void btnFindWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}private void btnUpdateCustomerAccount_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(mtbAccountNumber.Text))
{
MsgBox.Show("Please enter an account number for a customer. " +
"You can then click the Find Customer Account button " +
"to indicate the customer whose account you want o update.");
return;
}
if (string.IsNullOrEmpty(mtbMeterNumber.Text))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
Customer? customer = clients.Find(cust => cust.AccountNumber == mtbAccountNumber.Text);
if (customer is not null)
{
customer.CustomerId = int.Parse(txtCustomerId.Text);
customer.AccountNumber = mtbAccountNumber.Text;
customer.AccountName = txtAccountName.Text;
customer.MeterNumber = mtbMeterNumber.Text;
customer.AccountType = cbxAccountsTypes.Text.Substring(0, 3);
customer.Address = txtAddress.Text;
customer.City = txtCity.Text;
customer.County = txtCounty.Text;
customer.State = txtState.Text;
customer.ZIPCode = mtbZIPCode.Text;
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
}
}
Close();
}using StellarWaterPoint2.Models;
using System.Diagnostics.Metrics;
using System.Net;
using System.Reflection.Emit;
using System.Text.Json;
using static System.Windows.Forms.AxHost;
namespace StellarWaterPoint2.Customers
{
public partial class Editor : Form
{
public Editor()
{
InitializeComponent();
}
private void Editor_Load(object sender, EventArgs e)
{
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType type in types)
{
cbxAccountsTypes.Items.Add(type.TypeCode + " - " + type.TypeDecription);
}
}
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
string strAccountType = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtCustomerId.Text = client.CustomerId.ToString();
txtAccountName.Text = client.AccountName;
mtbMeterNumber.Text = client.MeterNumber;
strAccountType = client.AccountType!;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
mtbZIPCode.Text = client.ZIPCode;
}
}
}
if (mtbAccountNumber.Text!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == mtbMeterNumber.Text
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
IEnumerable<AccountType> actType = from category
in types
where category.TypeCode == strAccountType
select category;
foreach (AccountType type in types)
{
cbxAccountsTypes.Text = $"{type.TypeCode} - {type.TypeDecription}";
}
}
}
private void btnFindWaterMeter_Click(object sender, EventArgs e)
{
if (mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
foreach (WaterMeter meter in waterMeters)
{
if (meter.MeterNumber == mtbMeterNumber.Text)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
private void btnUpdateCustomerAccount_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(mtbAccountNumber.Text))
{
MsgBox.Show("Please enter an account number for a customer. " +
"You can then click the Find Customer Account button " +
"to indicate the customer whose account you want o update.");
return;
}
if (string.IsNullOrEmpty(mtbMeterNumber.Text))
{
MsgBox.Show("You must type a valid meter number, " +
"and then click the Find Water Meter button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
Customer? customer = clients.Find(cust => cust.AccountNumber == mtbAccountNumber.Text);
if (customer is not null)
{
customer.CustomerId = int.Parse(txtCustomerId.Text);
customer.AccountNumber = mtbAccountNumber.Text;
customer.AccountName = txtAccountName.Text;
customer.MeterNumber = mtbMeterNumber.Text;
customer.AccountType = cbxAccountsTypes.Text.Substring(0, 3);
customer.Address = txtAddress.Text;
customer.City = txtCity.Text;
customer.County = txtCounty.Text;
customer.State = txtState.Text;
customer.ZIPCode = mtbZIPCode.Text;
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
}
}
Close();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}| Control | (Name) | Other Properties | |
| ListView | lvwCustomers | No Change | |
| Button | btnNewCustomerAccount | No Change | |
| Button | btnCustomerAccountDetails | No Change | |
| Button | btnUpdateCustomerAccount | &Update Customer Account... | |
using System.Data;
using Microsoft.Data.SqlClient;
namespace StellarWaterPoint2.Customers
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowCustomers()
{
. . .
}
private void Central_Load(object sender, EventArgs e)
{
ShowCustomers();
}
private void btnCreateCustomerAccount_Click(object sender, EventArgs e)
{
. . .
}
private void btnCustomerAccountDetails_Click(object sender, EventArgs e)
{
Details details = new();
details.ShowDialog();
ShowCustomers();
}
private void btnEditCustomerAccount_Click(object sender, EventArgs e)
{
Editor editor = new();
editor.ShowDialog();
ShowCustomers();
}
}
}

Account Name: Bernotte Doughnuts Meter #: 580-742-825 and click Find Water Meter Account Type: BUS - General Business, Commercial, Industrial Address: 10103 Hexagon Drive City: Winterstown County: York State: PA ZIP-Code: 17402-8828


Deleting a Customer Account from the Database
If an employee realizes that a customer account must not exist anymore, the employee can delete that account. We will provide a form for such an operation.
Practical Learning: Deleting a Customer Account

| Control | (Name) | Text | Other Properties | |
| Label | &Account #: | |||
| MaskedTextBox | mtbAccountNumber | Masked: 0000-000-0000 | ||
| Button | btnFindCustomerAccount | &Find Customer Account | ||
| Label | &Account Name: | |||
| TextBox | txtAccountName | Enabled: False | ||
| Label | Meter &Details: | |||
| TextBox | txtMeterDetails | Enabled: False | ||
| Label | &Account Type: | |||
| TextBox | txtAccountsTypes | Enabled: False | ||
| Label | &Address: | |||
| TextBox | txtAddress | Enabled: False | ||
| Label | C&ity: | |||
| TextBox | txtCity | Enabled: False | ||
| Label | C&ounty: | |||
| TextBox | txtCounty | Enabled: False | ||
| Label | &State: | |||
| TextBox | txtState | Enabled: False | ||
| Label | &ZIP-Code: | |||
| TextBox | txtZIPCode | Enabled: False | ||
| Button | btnDeleteCustomerAccount | &Delete Customer Account | ||
| Button | btnClose | &Close | ||
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Delete : Form
{
public Delete()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
string strAccountType = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtCustomerId.Text = client.CustomerId.ToString();
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
strAccountType = client.AccountType!;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
IEnumerable<AccountType> actType = from category
in types
where category.TypeCode == strAccountType
select category;
foreach (AccountType type in types)
{
txtAccountType.Text = $"{type.TypeCode} - {type.TypeDecription}";
}
}
}
}
}private void btnDeleteCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button. " +
"Only then can you delete an customer account.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
Customer client = clients.Find(acnt => acnt.AccountNumber == mtbAccountNumber.Text)!;
if (client is not null)
{
if (MsgBox.Question("Are you sure you want to delete this customer's account " +
"(you cannot undo the action)?") == Answer.Yes)
{
clients.Remove(client);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
MsgBox.Show("The customer's account has been deleted from our system.");
}
}
}
Close();
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Delete : Form
{
public Delete()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
string strAccountType = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtCustomerId.Text = client.CustomerId.ToString();
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
strAccountType = client.AccountType!;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
string strAccountsTypes = string.Empty;
List<AccountType> types = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiAccountsTypes.Exists == true)
{
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
types = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
IEnumerable<AccountType> actType = from category
in types
where category.TypeCode == strAccountType
select category;
foreach (AccountType type in types)
{
txtAccountType.Text = $"{type.TypeCode} - {type.TypeDecription}";
}
}
}
private void btnDeleteCustomerAccount_Click(object sender, EventArgs e)
{
if (mtbAccountNumber.Text.Replace("-", "").Trim() == "")
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button. " +
"Only then can you delete an customer account.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
Customer client = clients.Find(acnt => acnt.AccountNumber == mtbAccountNumber.Text)!;
if (client is not null)
{
if (MsgBox.Question("Are you sure you want to delete this customer's account " +
"(you cannot undo the action)?") == Answer.Yes)
{
clients.Remove(client);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
MsgBox.Show("The customer's account has been deleted from our system.");
}
}
}
Close();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}| Control | (Name) | Other Properties | |
| ListView | lvwCustomers | FullRowSelect: True GridLines: True View: Details Anchor: Top, Bottom, Left, Right |
|
| Button | btnCreateCustomerAccount | Create Customer &Account.... Anchor: Bottom, Right |
|
| Button | btnCustomerAccountDetails | Customer Account &Details... Anchor: Bottom, Right |
|
| Button | btnEditCustomerAccount | &Edit Customer Account... Anchor: Bottom, Right |
|
| Button | btnDeleteCustomerAccount | &Delete Customer Account... Anchor: Bottom, Right |
|
| Button | btnClose | &Close Anchor: Bottom, Right |
|
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.Customers
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowCustomers()
{
string strCustomers = string.Empty;
List<Customer> Customers = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
Customers = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
lvwCustomers.Items.Clear();
foreach (Customer wm in Customers)
{
ListViewItem lviCustomer = new ListViewItem(wm.CustomerId.ToString());
lviCustomer.SubItems.Add(wm.AccountNumber);
lviCustomer.SubItems.Add(wm.AccountName);
lviCustomer.SubItems.Add(wm.MeterNumber);
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (wm.AccountType == at.TypeCode)
{
lviCustomer.SubItems.Add(string.Concat(at.TypeCode, " - ", at.TypeDecription));
}
}
lviCustomer.SubItems.Add(wm.Address);
lviCustomer.SubItems.Add(wm.City);
lviCustomer.SubItems.Add(wm.County);
lviCustomer.SubItems.Add(wm.State);
lviCustomer.SubItems.Add(wm.ZIPCode);
lvwCustomers.Items.Add(lviCustomer);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowCustomers();
}
private void btnCreateCustomerAccount_Click(object sender, EventArgs e)
{
Create create = new();
if (create.ShowDialog() == DialogResult.OK)
{
if(create.mtbAccountNumber.Text.Replace("-", "").Trim().Equals(""))
{
MsgBox.Show("You must provide an account number for a new customer. " +
"Otherwise, the account cannot be created.");
return;
}
if (create.mtbMeterNumber.Text.Replace("-", "").Trim().Equals(string.Empty))
{
MsgBox.Show("You must type a valid meter number to associate " +
"a water meter to a customer's account. After providing " +
"a meter number, click the Find Water Meter button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
}
Customer client = new Customer()
{
CustomerId = int.Parse(create.txtCustomerId.Text),
AccountNumber = create.mtbAccountNumber.Text,
AccountName = create.txtAccountName.Text,
MeterNumber = create.mtbMeterNumber.Text,
AccountType = create.cbxAccountsTypes.Text.Substring(0, 3),
Address = create.txtAddress.Text,
City = create.txtCity.Text,
County = create.txtCounty.Text,
State = create.txtState.Text,
ZIPCode = create.mtbZIPCode.Text
};
clients.Add(client);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsCustomers = JsonSerializer.Serialize(clients, typeof(List<Customer>), options);
File.WriteAllText(fiCustomers.FullName, jsCustomers);
}
ShowCustomers();
}
private void btnCustomerAccountDetails_Click(object sender, EventArgs e)
{
Details details = new();
details.Show();
}
private void btnUpdateCustomerAccount_Click(object sender, EventArgs e)
{
Editor editor = new();
editor.ShowDialog();
ShowCustomers();
}
private void btnDeleteCustomerAccount_Click(object sender, EventArgs e)
{
Delete delete = new();
delete.ShowDialog();
ShowCustomers();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}





[
{
"CustomerId": 1,
"AccountNumber": "9279-570-8394",
"AccountName": "Thomas Stones",
"MeterNumber": "799-528-461",
"AccountType": "RES",
"Address": "10252 Broward Ave #D4",
"City": "Frederick",
"County": "Frederick",
"State": "MD",
"ZIPCode": "21703-4422"
},
{
"CustomerId": 2,
"AccountNumber": "4086-938-4783",
"AccountName": "Bernotte Doughnuts",
"MeterNumber": "580-742-825",
"AccountType": "BUS",
"Address": "10103 Hexagon Drv",
"City": "Winterstown",
"County": "York",
"State": "PA",
"ZIPCode": "17402-8818"
},
{
"CustomerId": 3,
"AccountNumber": "2068-258-9486",
"AccountName": "Yollanda Training",
"MeterNumber": "186-962-805",
"AccountType": "UUO",
"Address": "4819 East Munk Street",
"City": "Whitehall",
"County": "Fulton",
"State": "PA",
"ZIPCode": "17340-1188"
},
{
"CustomerId": 4,
"AccountNumber": "6986-829-3741",
"AccountName": "Eyes Wide",
"MeterNumber": "208-428-308",
"AccountType": "BUS",
"Address": "12087 Avencia Court #4D1",
"City": "Silver Spring",
"County": "Montgomery",
"State": "MD",
"ZIPCode": "20910-2288"
},
{
"CustomerId": 5,
"AccountNumber": "9947-374-2648",
"AccountName": "Marianne Harrington",
"MeterNumber": "862-715-006",
"AccountType": "RES",
"Address": "708 Correta Drv",
"City": "Arlington",
"County": "",
"State": "VA",
"ZIPCode": "22222-6060"
},
{
"CustomerId": 6,
"AccountNumber": "4293-802-8506",
"AccountName": "Kelly Davids",
"MeterNumber": "496-813-794",
"AccountType": "RES",
"Address": "938 East Panchot Str",
"City": "Greenwood",
"County": "Sussex",
"State": "DE",
"ZIPCode": "19950-4242"
},
{
"CustomerId": 7,
"AccountNumber": "6240-857-4965",
"AccountName": "First Methodist Congregation",
"MeterNumber": "739-777-749",
"AccountType": "RES",
"Address": "7702 Charles Road",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 8,
"AccountNumber": "7928-131-4850",
"AccountName": "Department of Public Affairs",
"MeterNumber": "",
"AccountType": "SGO",
"Address": "",
"City": "Hyattsville",
"County": "Prince Georges",
"State": "MD",
"ZIPCode": "20783-2277"
},
{
"CustomerId": 9,
"AccountNumber": "1386-949-2058",
"AccountName": "Watson Country Buffet",
"MeterNumber": "296-837-495",
"AccountType": "WAT",
"Address": "4862 Wellington Street",
"City": "Hammonton",
"County": "Atlantic ",
"State": "NJ",
"ZIPCode": "08037-2828"
},
{
"CustomerId": 10,
"AccountNumber": "7943-686-9786",
"AccountName": "Angel Bulzaides",
"MeterNumber": "394-835-297",
"AccountType": "RES",
"Address": "10227 Old Harbor Drv",
"City": "Elkview",
"County": "Kanawha",
"State": "WV",
"ZIPCode": "25071-5858"
},
{
"CustomerId": 11,
"AccountNumber": "4820-375-2842",
"AccountName": "Sun Communal",
"MeterNumber": "392-494-572",
"AccountType": "SGO",
"Address": "748 Red Hills Rd",
"City": "Roanoke",
"County": "",
"State": "VA",
"ZIPCode": "24012-4824"
},
{
"CustomerId": 12,
"AccountNumber": "9618-579-2577",
"AccountName": "Gerald Place",
"MeterNumber": "847-252-246",
"AccountType": "UUO",
"Address": "3666 Hanchor Drv",
"City": "Granville",
"County": "Licking",
"State": "OH",
"ZIPCode": "43023-2777"
},
{
"CustomerId": 13,
"AccountNumber": "",
"AccountName": "",
"MeterNumber": "",
"AccountType": "",
"Address": "",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 14,
"AccountNumber": "2037-495-8528",
"AccountName": "Astral Sequence",
"MeterNumber": "",
"AccountType": "BUS",
"Address": "12715 Eastern Gateway",
"City": "Catonsville",
"County": "Baltimore County",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 15,
"AccountNumber": "6003-386-3955",
"AccountName": "Mandiakandara Marmoudi",
"MeterNumber": "374-886-284",
"AccountType": "OTH",
"Address": "539 Avalon Court",
"City": "Greenwood",
"County": "Sussex",
"State": "DE",
"ZIPCode": "19950-5550"
},
{
"CustomerId": 16,
"AccountNumber": "5294-859-7513",
"AccountName": "Jeannette Schiller",
"MeterNumber": "713-942-058",
"AccountType": "RES",
"Address": "10110 Winslow Ave",
"City": "Mercerville",
"County": "Mercer",
"State": "NJ",
"ZIPCode": "08619-7472"
},
{
"CustomerId": 17,
"AccountNumber": "9249-379-6848",
"AccountName": "Country West Eatery",
"MeterNumber": "588-279-663",
"AccountType": "BUS",
"Address": "8280 Sligo North Way",
"City": "Albright",
"County": "Preston",
"State": "WV",
"ZIPCode": "26519-6620"
},
{
"CustomerId": 18,
"AccountNumber": "5252-757-9595",
"AccountName": "Sathyavanthara Khooni",
"MeterNumber": "379-386-979",
"AccountType": "RES",
"Address": "4992 Preston Street",
"City": "",
"County": "",
"State": "OH",
"ZIPCode": ""
},
{
"CustomerId": 19,
"AccountNumber": "7080-583-5947",
"AccountName": "Sunny Yard",
"MeterNumber": "827-508-248",
"AccountType": "WAT",
"Address": "663 Sherry Wood East Street",
"City": "Shimpstown",
"County": "Franklin",
"State": "PA",
"ZIPCode": "17236-2626"
},
{
"CustomerId": 20,
"AccountNumber": "8027-304-6829",
"AccountName": "Anthony Clarcksons",
"MeterNumber": "837-806-836",
"AccountType": "RES",
"Address": "904 Augusta Drive",
"City": "Blackbird",
"County": "New Castle",
"State": "DE",
"ZIPCode": "19734-8822"
},
{
"CustomerId": 21,
"AccountNumber": "6699-396-2905",
"AccountName": "Spencer Reuter",
"MeterNumber": "649-373-505",
"AccountType": "RES",
"Address": "2850 Burnsweak Avenue",
"City": "Silver Spring",
"County": "Montgomery",
"State": "MD",
"ZIPCode": "20910-4044"
},
{
"CustomerId": 22,
"AccountNumber": "1827-395-0203",
"AccountName": "Watson Country Buffet",
"MeterNumber": "470-628-850",
"AccountType": "WAT",
"Address": "10331 Chryswell Road",
"City": "Washington",
"County": "",
"State": "DC",
"ZIPCode": "20008-2426"
},
{
"CustomerId": 23,
"AccountNumber": "5862-736-9741",
"AccountName": "Eastern Cage",
"MeterNumber": "",
"AccountType": "BUS",
"Address": "2039 Night Stand Court",
"City": "Hammonton",
"County": "",
"State": "NJ",
"ZIPCode": ""
},
{
"CustomerId": 24,
"AccountNumber": "3947-957-4958",
"AccountName": "Patsil Industries",
"MeterNumber": "747-581-379",
"AccountType": "BUS",
"Address": "10348 Larrens Drive",
"City": "Baltimore",
"County": "Baltimore",
"State": "MD",
"ZIPCode": "21215-2222"
},
{
"CustomerId": 25,
"AccountNumber": "2836-485-9699",
"AccountName": "Red Oak High School",
"MeterNumber": "379-386-979",
"AccountType": "SGO",
"Address": "442 Donham Road",
"City": "Silver Spring",
"County": "Montgomery",
"State": "MD",
"ZIPCode": "20910-8822"
},
{
"CustomerId": 26,
"AccountNumber": "5938-074-5293",
"AccountName": "Park and Roll",
"MeterNumber": "592-824-957",
"AccountType": "SGO",
"Address": "582G Dunhill Avenue",
"City": "Lanham",
"County": "Prince Georges",
"State": "MD",
"ZIPCode": "20706-8284"
},
{
"CustomerId": 27,
"AccountNumber": "3028-502-9418",
"AccountName": "Spencer Kershaw",
"MeterNumber": "186-959-757",
"AccountType": "RES",
"Address": "338C Grayson Street",
"City": "Gatchellville",
"County": "York",
"State": "PA",
"ZIPCode": "17352-6464"
},
{
"CustomerId": 28,
"AccountNumber": "9684-759-2227",
"AccountName": "Country West Eatery",
"MeterNumber": "928-317-924",
"AccountType": "BUS",
"Address": "",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 29,
"AccountNumber": "2974-972-8139",
"AccountName": "Paul Arnette",
"MeterNumber": "295-770-695",
"AccountType": "OTH",
"Address": "8127 Bledsoe Str",
"City": "Hyattsville",
"County": "Prince Georges",
"State": "MD",
"ZIPCode": "20783-5858"
},
{
"CustomerId": 30,
"AccountNumber": "2758-493-7249",
"AccountName": "Hervey Smile",
"MeterNumber": "293-924-869",
"AccountType": "WAT",
"Address": "12973 Sonaa Street #E42",
"City": "Silver Spring",
"County": "Montgomery",
"State": "MD",
"ZIPCode": "20910-4488"
},
{
"CustomerId": 31,
"AccountNumber": "9337-947-3664",
"AccountName": "Awesome Aid",
"MeterNumber": "649-358-184",
"AccountType": "SGO",
"Address": "",
"City": "Bellefontaine",
"County": "",
"State": "OH",
"ZIPCode": ""
},
{
"CustomerId": 32,
"AccountNumber": "7518-302-6895",
"AccountName": "Grace Brenner",
"MeterNumber": "207-964-835",
"AccountType": "BUS",
"Address": "4299 Peachtree Court",
"City": "Rockville",
"County": "Montgomery",
"State": "MD",
"ZIPCode": "20853-1888"
},
{
"CustomerId": 33,
"AccountNumber": "2937-947-3008",
"AccountName": "Jeffrey Maney",
"MeterNumber": "",
"AccountType": "RES",
"Address": "",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 34,
"AccountNumber": "7028-405-9381",
"AccountName": "Valley Services",
"MeterNumber": "306-842-497",
"AccountType": "WAT",
"Address": "613 Meadowhill Road",
"City": "Alonzaville",
"County": "Shenandoah",
"State": "VA",
"ZIPCode": "22664-8080"
},
{
"CustomerId": 35,
"AccountNumber": "5293-957-3395",
"AccountName": "Wellway Community Center",
"MeterNumber": "386-468-057",
"AccountType": "RES",
"Address": "10484 Greenway Avenue",
"City": "Mt Storm",
"County": "Grant",
"State": "WV",
"ZIPCode": "26739-7700"
},
{
"CustomerId": 36,
"AccountNumber": "2038-413-9680",
"AccountName": "Eastern Friandise",
"MeterNumber": "938-725-869",
"AccountType": "BUS",
"Address": "2075 Rose Hills Avenue",
"City": "Washington",
"County": "",
"State": "DC",
"ZIPCode": "20004-2626"
},
{
"CustomerId": 37,
"AccountNumber": "7484-744-9708",
"AccountName": "Amidou Gomah",
"MeterNumber": "",
"AccountType": "RES",
"Address": "14118 Yellow Burrough Blvd",
"City": "Philadelphia",
"County": "",
"State": "PA",
"ZIPCode": ""
},
{
"CustomerId": 38,
"AccountNumber": "3792-853-6885",
"AccountName": "Department of Public Affairs",
"MeterNumber": "595-753-147",
"AccountType": "",
"Address": "",
"City": "Upper Marlboro",
"County": "Prince George County",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 39,
"AccountNumber": "8282-777-8282",
"AccountName": "Garland Hotel",
"MeterNumber": "938-275-294",
"AccountType": "BUS",
"Address": "4222 Extell Ave",
"City": "Cambridge",
"County": "",
"State": "MD",
"ZIPCode": "21613-2288"
},
{
"CustomerId": 40,
"AccountNumber": "5975-863-7057",
"AccountName": "Single Connection",
"MeterNumber": "288-427-585",
"AccountType": "BUS",
"Address": "",
"City": "Mansfield",
"County": "",
"State": "OH",
"ZIPCode": "44903-3030"
},
{
"CustomerId": 41,
"AccountNumber": "2499-636-4444",
"AccountName": "Bryanna Spencer",
"MeterNumber": "",
"AccountType": "RES",
"Address": "6282 Sheppherd Str",
"City": "",
"County": "Anne Arundel",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 42,
"AccountNumber": "2842-585-7260",
"AccountName": "District Community Reserves",
"MeterNumber": "349-725-848",
"AccountType": "SGO",
"Address": "3280 Hopewell Street, NE",
"City": "Washington",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 43,
"AccountNumber": "9282-794-7937",
"AccountName": "Yashua Yáñés",
"MeterNumber": "392-494-572",
"AccountType": "RES",
"Address": "10214 Monroe Ave",
"City": "Easton",
"County": "",
"State": "MD",
"ZIPCode": ""
},
{
"CustomerId": 44,
"AccountNumber": "6837-468-4750",
"AccountName": "Miguel Altieri",
"MeterNumber": "",
"AccountType": "RES",
"Address": "10941 Patriot Blvd",
"City": "Crenshaw",
"County": "Jefferson",
"State": "PA",
"ZIPCode": "15824-6628"
},
{
"CustomerId": 45,
"AccountNumber": "2847-597-2829",
"AccountName": "Jameson",
"MeterNumber": "379-386-979",
"AccountType": "WAT",
"Address": "7373 Gold Town Rd",
"City": "",
"County": "",
"State": "WV",
"ZIPCode": ""
},
{
"CustomerId": 46,
"AccountNumber": "6381-748-2222",
"AccountName": "Up Eyes",
"MeterNumber": "",
"AccountType": "BUS",
"Address": "4149 Deerfield Str",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 47,
"AccountNumber": "4968-274-9638",
"AccountName": "Annette Wald",
"MeterNumber": "",
"AccountType": "RES",
"Address": "11441 Eastern Friendshi Rd",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 48,
"AccountNumber": "8384-708-2941",
"AccountName": "Department of Environment Affairs",
"MeterNumber": "",
"AccountType": "SGO",
"Address": "",
"City": "",
"County": "",
"State": "OH",
"ZIPCode": ""
},
{
"CustomerId": 49,
"AccountNumber": "3728-138-2947",
"AccountName": "Marie Rath",
"MeterNumber": "",
"AccountType": "",
"Address": "8802 Atlantic Ave",
"City": "",
"County": "",
"State": "PA",
"ZIPCode": ""
},
{
"CustomerId": 50,
"AccountNumber": "1793-857-9413",
"AccountName": "Body Care",
"MeterNumber": "",
"AccountType": "WAT",
"Address": "",
"City": "Ocean City",
"County": "",
"State": "NJ",
"ZIPCode": ""
},
{
"CustomerId": 51,
"AccountNumber": "6028-695-2068",
"AccountName": "Ronald Glassman",
"MeterNumber": "468-359-486",
"AccountType": "BUS",
"Address": "",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 52,
"AccountNumber": "4069-37-49728",
"AccountName": "Lucette Wash N Dry",
"MeterNumber": "",
"AccountType": "WAT",
"Address": "8812 Lawrence Ave",
"City": "",
"County": "",
"State": "NW",
"ZIPCode": ""
},
{
"CustomerId": 53,
"AccountNumber": "9616-283-7249",
"AccountName": "Department of Public Affairs",
"MeterNumber": "",
"AccountType": "SGO",
"Address": "13006 Blueberry Ave",
"City": "Greenbelt",
"County": "",
"State": "MD",
"ZIPCode": "20770-2040"
},
{
"CustomerId": 54,
"AccountNumber": "2829-516-8353",
"AccountName": "Richard Eghert",
"MeterNumber": "",
"AccountType": "RES",
"Address": "662 Placido Road",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 55,
"AccountNumber": "6296-875-9607",
"AccountName": "Country West Eatery",
"MeterNumber": "",
"AccountType": "BUS",
"Address": "837 Larrenson Drv",
"City": "Cumberland",
"County": "",
"State": "MD",
"ZIPCode": ""
},
{
"CustomerId": 56,
"AccountNumber": "9684-794-6379",
"AccountName": "Eye Care",
"MeterNumber": "",
"AccountType": "BUS",
"Address": "8626 Cameron Str",
"City": "",
"County": "",
"State": "",
"ZIPCode": ""
},
{
"CustomerId": 57,
"AccountNumber": "2405-839-5820",
"AccountName": "Watson Country Buffet",
"MeterNumber": "",
"AccountType": "WAT",
"Address": "",
"City": "Harrisburg",
"County": "",
"State": "PA",
"ZIPCode": ""
}
]Water Bills
Introduction
A water bill is an intermediary document between the water distribution company and a consumer. We will create the classes, forms, and operations to present that information.
Practical Learning: Introducing Water Bills
namespace StellarWaterPoint2.Models
{
public class WaterBill
{
public int BillNumber { get; set; }
public string? AccountNumber { get; set; }
public DateTime MeterReadingStartDate { get; set; }
public DateTime MeterReadingEndDate { get; set; }
public int BillingDays { get; set; }
public int CounterReadingStart { get; set; }
public int CounterReadingEnd { get; set; }
public int TotalHCF { get; set; }
public int TotalGallons { get; set; }
public double FirstTierConsumption { get; set; }
public double SecondTierConsumption { get; set; }
public double LastTierConsumption { get; set; }
public double WaterCharges { get; set; }
public double SewerCharges { get; set; }
public double EnvironmentCharges { get; set; }
public double ServiceCharges { get; set; }
public double TotalCharges { get; set; }
public double LocalTaxes { get; set; }
public double StateTaxes { get; set; }
public DateTime PaymentDueDate { get; set; }
public double AmountDue { get; set; }
public DateTime LatePaymentDueDate { get; set; }
public double LateAmountDue { get; set; }
}
}namespace StellarWaterPoint2.Models
{
internal static class WaterBillManager
{
internal static (double a, double b, double c) CalculateTiers(string acnt, double total)
{
(double tier1, double tier2, double tier3) results = (0.00, 0.00, 0.00);
switch (acnt)
{
case "RES":
results.tier1 = total * 39.35 / 10000.00;
results.tier2 = total * 18.25 / 10000.00;
results.tier3 = total * 11.65 / 10000.00;
break;
case "SGO":
results.tier1 = total * 41.38 / 10000.00;
results.tier2 = total * 15.26 / 10000.00;
results.tier3 = total * 8.13 / 10000.00;
break;
case "BUS":
results.tier1 = total * 51.25 / 10000.00;
results.tier2 = total * 34.65 / 10000.00;
results.tier3 = total * 15.10 / 10000.00;
break;
case "UUO":
results.tier1 = total * 25.00 / 10000.00;
results.tier2 = total * 35.00 / 10000.00;
results.tier3 = total * 40.00 / 10000.00;
break;
case "WAT":
results.tier1 = (total / 6) * 3 * 50.00 / 10000.00;
results.tier2 = (total / 6) * 2 * 35.00 / 10000.00;
results.tier3 = total * 15.00 / 10000.00;
break;
default:
results.tier1 = total * (48.00 / 10000.00);
results.tier2 = total * (32.00 / 10000.00);
results.tier3 = total * (20.00 / 10000.00);
break;
}
return results;
}
internal static double CalculateSewerCharges(string acnt, double total)
{
double result;
if (acnt == "RES")
{
result = total * 1.028641 / 100.00;
}
else if (acnt == "SGO")
{
result = total * 4.162522 / 100.00;
}
else if (acnt == "BUS")
{
result = total * 8.446369 / 100.00;
}
else if (acnt == "UUO")
{
result = total * 10.622471 / 100.00;
}
else if (acnt == "WAT")
{
result = total * 12.053152 / 100.00;
}
else // if (acnt == "OTH)"
{
result = total * 9.206252 / 100.00;
}
return result;
}
internal static double CalculateEnvironmentCharges(string acnt, double total)
{
double result;
switch (acnt)
{
case "RES":
result = total * 0.004524;
break;
case "SGO":
result = total * 0.118242;
break;
case "BUS":
result = total * 0.161369;
break;
case "UUO":
result = total * 0.082477;
break;
case "WAT":
result = total * 0.413574;
break;
default:
result = total * 0.221842;
break;
}
return result;
}
internal static double CalculateServiceCharges(string acnt, double total)
{
switch (acnt)
{
case "RES":
return total * 0.006248;
case "SGO":
return total * 0.102246;
case "BUS":
return total * 0.155227;
case "UUO":
return total * 0.186692;
case "WAT":
return total * 0.412628;
default:
return total * 0.210248;
}
}
internal static double CalculateLocalTaxes(string acnt, double total) => acnt switch
{
"RES" => total * 0.035749,
"SGO" => total * 0.044026,
"BUS" => total * 0.122517,
"UUO" => total * 0.105737,
"WAT" => total * 0.153248,
_ => total * 0.125148
};
internal static double CalculateStateTaxes(string acnt, double total) => acnt switch
{
"RES" => total * 0.007124,
"SGO" => total * 0.008779,
"BUS" => total * 0.042448,
"UUO" => total * 0.067958,
"WAT" => total * 0.081622,
_ => total * 0.013746
};
internal static DateTime SetPaymentDueDate(string acnt, DateTime date)
{
TimeSpan tsPaymentDueDate = new TimeSpan(1, 0, 0, 0);
if (acnt == "RES")
{
tsPaymentDueDate = new TimeSpan(15, 0, 0, 0);
}
else if (acnt == "SGO")
{
tsPaymentDueDate = new TimeSpan(20, 0, 0, 0);
}
else if (acnt == "BUS")
{
tsPaymentDueDate = new TimeSpan(30, 0, 0, 0);
}
else if (acnt == "UUO")
{
tsPaymentDueDate = new TimeSpan(15, 0, 0, 0);
}
else if (acnt == "WAT")
{
tsPaymentDueDate = new TimeSpan(40, 0, 0, 0);
}
else
{
tsPaymentDueDate = new TimeSpan(35, 0, 0, 0);
}
return date + tsPaymentDueDate;
}
internal static DateTime SetLatePaymentDueDate(string acnt, DateTime date)
{
switch (acnt)
{
case "RES":
return date + new TimeSpan(30, 0, 0, 0);
case "SGO":
return date + new TimeSpan(40, 0, 0, 0);
case "BUS":
return date + new TimeSpan(50, 0, 0, 0);
case "UUO":
return date + new TimeSpan(60, 0, 0, 0);
case "WAT":
return date + new TimeSpan(65, 0, 0, 0);
default:
return date + new TimeSpan(45, 0, 0, 0);
}
}
internal static double CalculateLateAmountDue(string acnt, double amt) => acnt switch
{
"RES" => amt + 8.95,
"SGO" => amt + (amt / 4.575),
"BUS" => amt + (amt / 12.315),
"UUO" => amt + (amt / 7.425),
"WAT" => amt + (amt / 15.225),
_ => amt + (amt / 6.735)
};
}
}Showing Water Bills
A water distribution company has many records for water bills, and a typical water bill includes many pieces of information. We will create a form that displays a list of some pieces of information about a water bill.
Practical Learning: Showing Water Bills
| (Name) | Text | TextAlign | Width |
| colWaterBillId | Id | 40 | |
| colBillNumber | Bill # | Center | 80 |
| colAccountSummary | Account Summary | Center | 550 |
| colStartDate | Start Date | Center | 150 |
| colEndDate | End Date | Center | 150 |
| colBillingDays | Days | Center | |
| colCounterStart | Counter Start | Right | 125 |
| colCounterEnd | Counter End | Right | 125 |
| colTotalHCF | Total HCF | Right | 100 |
| colGallons | Gallons | Right | 95 |
| colPaymentDueDate | Pmt Due Date | Center | 125 |
| colAmountDue | Amt Due | Right | 90 |
| Control | (Name) | Other Properties | |
| ListView | lvwWaterBills | FullRowSelect: True GridLines: True View: Details |
|
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterBills()
{
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
}
}
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
lvwWaterBills.Items.Clear();
foreach (WaterBill invoice in bills)
{
ListViewItem lviWaterBill = new ListViewItem(invoice.WaterBillId.ToString());
lviWaterBill.SubItems.Add(invoice.BillNumber.ToString());
IEnumerable<Customer> customer = clients.Where(cust => cust.AccountNumber == invoice.AccountNumber);
foreach (Customer cust in customer)
{
lviWaterBill.SubItems.Add(invoice.AccountNumber + " - " +
cust.AccountName +
", Type: " + cust.AccountType![..3] +
", (Mtr #: " + cust.MeterNumber + ")");
}
lviWaterBill.SubItems.Add(invoice.MeterReadingStartDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.MeterReadingEndDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.BillingDays.ToString());
lviWaterBill.SubItems.Add(invoice.CounterReadingStart.ToString());
lviWaterBill.SubItems.Add(invoice.CounterReadingEnd.ToString());
lviWaterBill.SubItems.Add(invoice.TotalHCF.ToString());
lviWaterBill.SubItems.Add(invoice.TotalGallons.ToString());
lviWaterBill.SubItems.Add(invoice.PaymentDueDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.AmountDue.ToString());
lvwWaterBills.Items.Add(lviWaterBill);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterBills();
}
}
}| Control | (Name) | Text | Font | |
| Button | btnWaterBills | C&Water Bills... | Times New Roman, 24pt, style=Bold | |
| Button | btnClose | &Close | Times New Roman, 24pt, style=Bold | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2
{
public partial class WaterDistribution : Form
{
private void CreateWaterMeters()
{
List<WaterMeter> waterMeters = new List<WaterMeter>();
waterMeters!.Add(new WaterMeter() { WaterMeterId = 1, MeterNumber = "392-494-572", Make = "Constance Technologies", Model = "TG-4822", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 2, MeterNumber = "938-725-869", Make = "Stanford Trend", Model = "266G", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 3, MeterNumber = "588-279-663", Make = "Estellano", Model = "NCF-226", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 4, MeterNumber = "186-962-805", Make = "Lansome", Model = "2800", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 5, MeterNumber = "379-386-979", Make = "Planetra", Model = "P-2020", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 6, MeterNumber = "580-742-825", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 7, MeterNumber = "849-351-444", Make = "Raynes Energica", Model = "a1088", MeterSize = "2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 8, MeterNumber = "208-428-308", Make = "Constance Technologies", Model = "808D", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 9, MeterNumber = "738-588-249", Make = "Warrington", Model = "W4242", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 10, MeterNumber = "496-813-794", Make = "Estellano", Model = "NCF-226", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 11, MeterNumber = "862-715-006", Make = "Warrington", Model = "W-4040", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 12, MeterNumber = "649-358-184", Make = "Raynes Energica", Model = "b1700", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 13, MeterNumber = "928-317-924", Make = "Gongola", Model = "GN1000", MeterSize = "2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 14, MeterNumber = "595-753-147", Make = "Grass Grill", Model = "CRC-1000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 15, MeterNumber = "799-528-461", Make = "Kensa Sons", Model = "K-584-L", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 16, MeterNumber = "386-468-057", Make = "Estellano", Model = "NCF-226", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 17, MeterNumber = "938-275-294", Make = "Constance Technologies", Model = "TT-8822", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 18, MeterNumber = "288-427-585", Make = "Planetra", Model = "P-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 19, MeterNumber = "394-835-297", Make = "Raynes Energica", Model = "i2022", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 20, MeterNumber = "847-252-246", Make = "Master Stream", Model = "2000-MS", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 21, MeterNumber = "349-725-848", Make = "Planetra", Model = "P-8000", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 22, MeterNumber = "713-942-058", Make = "Master Stream", Model = "3366-MS", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 23, MeterNumber = "747-581-379", Make = "Warrington", Model = "W4242", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 24, MeterNumber = "582-755-263", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 25, MeterNumber = "827-260-758", Make = "Raynes Energica", Model = "a1088", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 26, MeterNumber = "837-806-836", Make = "Lansome", Model = "7400", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 27, MeterNumber = "207-964-835", Make = "Constance Technologies", Model = "TG-6220", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 28, MeterNumber = "296-837-495", Make = "Raynes Energica", Model = "QG505", MeterSize = "4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 29, MeterNumber = "468-359-486", Make = "Grass Grill", Model = "KLP-8822", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 30, MeterNumber = "931-486-003", Make = "Planetra", Model = "P-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 31, MeterNumber = "483-770-648", Make = "Warren", Model = "WWW", MeterSize = "0.1 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 32, MeterNumber = "592-824-957", Make = "Kensa Sons", Model = "D-497-H", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 33, MeterNumber = "293-835-704", Make = "Gongola", Model = "GOL1000", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 34, MeterNumber = "739-777-749", Make = "Warrington", Model = "W2200W", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 35, MeterNumber = "374-886-284", Make = "Raynes Energica", Model = "i2022", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 36, MeterNumber = "186-959-757", Make = "Kensa Sons", Model = "M-686-G", MeterSize = "1 1/2 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 37, MeterNumber = "594-827-359", Make = "Planetra", Model = "P-8000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 38, MeterNumber = "394-739-242", Make = "Master Stream", Model = "9393-TT", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 39, MeterNumber = "529-283-752", Make = "Constance Technologies", Model = "404T", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 40, MeterNumber = "295-770-695", Make = "Warrington", Model = "W-2286", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 41, MeterNumber = "739-749-737", Make = "Kensa Sons", Model = "KS2000A", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 42, MeterNumber = "947-528-317", Make = "Gondola", Model = "GDL-5000", MeterSize = "1 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 43, MeterNumber = "630-207-055", Make = "Lansome", Model = "2800", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 44, MeterNumber = "827-508-248", Make = "Standard Trend", Model = "428T", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 45, MeterNumber = "293-924-869", Make = "Grass Grill", Model = "CRC-2020", MeterSize = "1/2 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 46, MeterNumber = "928-247-580", Make = "Gondola", Model = "GOL2000", MeterSize = "0.34 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 47, MeterNumber = "682-537-380", Make = "Planetra", Model = "P-2020", MeterSize = "1-1/4 Inch" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 48, MeterNumber = "470-628-850", Make = "Estellano", Model = "WRT-482", MeterSize = "3/4 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 49, MeterNumber = "649-373-505", Make = "Constance Technologies", Model = "BD-7000", MeterSize = "5/8 Inches" });
waterMeters.Add(new WaterMeter() { WaterMeterId = 50, MeterNumber = "306-842-497", Make = "Lansome", Model = "9000", MeterSize = "3/4 Inches" });
string strWaterMeters = string.Empty;
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
string jsWaterMeters = JsonSerializer.Serialize(waterMeters, typeof(List<WaterMeter>), options);
File.WriteAllText(fiWaterMeters.FullName, jsWaterMeters);
}
private void CreateAccountsTypes()
{
List<AccountType> types = new List<AccountType>()
{
new AccountType() { AccountTypeId = 1, TypeCode = "OTH", TypeDecription = "Other" },
new AccountType() { AccountTypeId = 3, TypeCode = "RES", TypeDecription = "Residential Household" },
new AccountType() { AccountTypeId = 2, TypeCode = "BUS", TypeDecription = "General Business, Commercial, Industrial" },
new AccountType() { AccountTypeId = 5, TypeCode = "UUO", TypeDecription = "Unidentified or Unclassified Type of Organization" },
new AccountType() { AccountTypeId = 4, TypeCode = "SGO", TypeDecription = "Social/Government/Non-Profit Organization, Institutional" },
new AccountType() { AccountTypeId = 6, TypeCode = "WAT", TypeDecription = "Water Intensive Business (Agricultural, Laudromat, Hair Salon, Restaurant, etc" }
};
string strAccountsTypes = string.Empty;
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
string jsAccountsTypes = JsonSerializer.Serialize(types, typeof(List<AccountType>), options);
File.WriteAllText(fiAccountsTypes.FullName, jsAccountsTypes);
}
public WaterDistribution()
{
InitializeComponent();
// CreateWaterMeters();
// CreateAccountsTypes();
}
private void WaterDistribution_Load(object sender, EventArgs e)
{
Directory.CreateDirectory(@"C:\Stellar Water Point2");
}
private void btnWaterBills_Click(object sender, EventArgs e)
{
WaterBills.Central central = new WaterBills.Central();
central.Show();
}
private void btnCustomers_Click(object sender, EventArgs e)
{
Customers.Central central = new Customers.Central();
central.Show();
}
private void btnWaterMeters_Click(object sender, EventArgs e)
{
WaterMeters.Central central = new WaterMeters.Central();
central.Show();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}A New Water Bill
A water is probably the most important aspect of water distribution. We will provide a form that allows an employee to register the information necessary for water consumption. Then we will perform some operations. Finally, we will present the amount the consumer should pay and when.
Practical Learning: Processing a Water Bill

| Control | Text | Name | Other Properties | |
| Label | &Water Bill #: | |||
| TextBox | txtBillNumber | |||
| GroupBox | Customer Information | |||
| Label | &Account #: | |||
| MaskedTextBox | mtbAccountNumber | Mask: 0000-000-0000 | ||
| Button | Find Customer &Account | btnFindCustomerAccount | ||
| Label | Account Name: | |||
| TextBox | txtAccountName | |||
| Label | Account Type: | |||
| TextBox | txtAccountType | |||
| Label | Address: | |||
| TextBox | txtAddress | |||
| TextBox | txtCity | |||
| TextBox | txtCounty | |||
| TextBox | txtState | |||
| TextBox | txtZIPCode | |||
| Label | _________________________________________________ | |||
| Label | Meter Details: | |||
| TextBox | txtMeterDetails | |||
| GroupBox | Meter Reading | |||
| Label | Meter &Reading Start Date: | |||
| Date Time Picker | dtpMeterReadingStartDate | |||
| Label | Meter Reading &End Date: | |||
| Date Time Picker | dtpMeterReadingEndDate | |||
| Label | Coun&ter Reading Start: | |||
| TextBox | txtCounterReadingStart | |||
| Label | Counter Readi&ng End: | |||
| TextBox | txtCounterReadingEnd | |||
| Button | &Evaluate Water Bill | btnEvaluateWaterBill | Times New Roman, 24pt, style=Bold | |
| GroupBox | Meter Result | |||
| Label | Billing Days: | |||
| TextBox | txtBillingDays | |||
| Label | Total HCF: | |||
| TextBox | txtTotalHCF | |||
| Label | Total Gallons: | |||
| TextBox | txtTotalGallons | |||
| Label | First Tier Consumption: | |||
| TextBox | txtFirstTierConsumption | |||
| Label | Second Tier: | |||
| TextBox | txtSecondTierConsumption | |||
| Label | Last Tier: | |||
| TextBox | txtLastTierConsumption | |||
| GroupBox | Consumption Charges | |||
| Label | Water Charges: | |||
| TextBox | txtWaterCharges | |||
| Label | Sewer Charges: | |||
| TextBox | txtSewerCharges | |||
| Label | Environment Charges: | |||
| TextBox | txtEnvironmentCharges | |||
| Label | Service Charges: | |||
| TextBox | txtServiceCharges | |||
| Label | Total Charges: | |||
| TextBox | txtTotalCharges | |||
| GroupBox | Taxes | |||
| Label | Local Taxes: | |||
| TextBox | txtLocalTaxes | |||
| Label | State Taxes: | |||
| TextBox | txtStateTaxes | |||
| GroupBox | Water Bill Payment | |||
| Label | Payment Due Date: | |||
| Date Time Picker | dtpPaymentDueDate | |||
| Label | Amount Due: | |||
| TextBox | txtAmountDue | |||
| Label | Late Payment Due Date: | |||
| Date Time Picker | dtpLatePaymentDueDate | |||
| Label | &Late Amount Due: | |||
| TextBox | txtLateAmountDue | |||
| Label | Water Bill Id:& | |||
| TextBox | txtWaterBillId | |||
| Button | Save Water Bill | btnSaveWaterBill | ||
| Button | &Close | btnClose | ||
Form Properties
| Form Property | Value |
| FormBorderStyle | FixedDialog |
| Text | Stellar Water Point - Water Bill Processing |
| StartPosition | CenterScreen |
| MaximizeBox | False |
| MinimizeBox | False |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterMeters
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void Create_Load(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
List<WaterBill> waterBills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
int waterBillId = 0;
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
waterBills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
foreach (WaterBill wm in waterBills)
{
waterBillId = wm.WaterBillId;
}
}
}
txtWaterBillId.Text = (waterBillId + 1).ToString();
}
}
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
string strAccountNumber = mtbAccountNumber.Text.Replace("-", "").Trim();
if (string.IsNullOrEmpty(strAccountNumber))
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = clients.Where(cust => cust.AccountNumber == mtbAccountNumber.Text);
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = waterMeters.Where(wm => wm.MeterNumber == strMeterNumber);
foreach (WaterMeter meter in meters)
{
txtMeterDetails.Text = meter.WaterMeterId.ToString() + " - " +
meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
}
}using System.Data;
using Microsoft.Data.SqlClient;
namespace StellarWaterPoint21.WaterBills
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
. . .
}
private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
{
TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
txtBillingDays.Text = (tsDays.Days + 1).ToString();
}
}
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
. . .
}
private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
{
TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
txtBillingDays.Text = (tsDays.Days + 1).ToString();
}
private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
{
double counterStart = 0, counterEnd = 0;
try
{
counterStart = double.Parse(txtCounterReadingStart.Text);
}
catch (FormatException feCRStart)
{
MsgBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
"The error produced is: " + feCRStart.Message,
"Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
try
{
counterEnd = double.Parse(txtCounterReadingEnd.Text);
}
catch (FormatException feCREnd)
{
MsgBox.Show("You must enter a valid value in the Counter Reading End text box. " +
"The error produced is: " + feCREnd.Message,
"Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
double consumption = counterEnd - counterStart;
double gallons = consumption * 748.05;
string strAccountType = txtAccountType.Text[..3];
(double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
double waterCharges = tiers.first + tiers.second + tiers.last;
double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
double amtDue = totalCharges + localTaxes + stateTaxes;
txtTotalHCF.Text = consumption.ToString();
txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
txtFirstTierConsumption.Text = tiers.first.ToString("F");
txtSecondTierConsumption.Text = tiers.second.ToString("F");
txtLastTierConsumption.Text = tiers.last.ToString("F");
txtWaterCharges.Text = waterCharges.ToString("F");
txtSewerCharges.Text = sewerCharges.ToString("F");
txtEnvironmentCharges.Text = envCharges.ToString("F");
txtServiceCharges.Text = srvCharges.ToString("F");
txtTotalCharges.Text = totalCharges.ToString("F");
txtLocalTaxes.Text = localTaxes.ToString("F");
txtStateTaxes.Text = stateTaxes.ToString("F");
dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtAmountDue.Text = amtDue.ToString("F");
dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
}
}
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Create : Form
{
public Create()
{
InitializeComponent();
}
private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(mtbAccountNumber.Text))
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.",
"Stellar Water Point", MessageBoxButtons.OK);
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = clients.Where(cust => cust.AccountNumber == mtbAccountNumber.Text);
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
txtAccountType.Text = client.AccountType;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = waterMeters.Where(wm => wm.MeterNumber == strMeterNumber);
foreach (WaterMeter meter in meters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
{
TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
txtBillingDays.Text = (tsDays.Days + 1).ToString();
}
private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
{
double counterStart = 0, counterEnd = 0;
try
{
counterStart = double.Parse(txtCounterReadingStart.Text);
}
catch (FormatException feCRStart)
{
MsgBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
"The error produced is: " + feCRStart.Message,
"Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
try
{
counterEnd = double.Parse(txtCounterReadingEnd.Text);
}
catch (FormatException feCREnd)
{
MsgBox.Show("You must enter a valid value in the Counter Reading End text box. " +
"The error produced is: " + feCREnd.Message,
"Stellar Water Point", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
double consumption = counterEnd - counterStart;
double gallons = consumption * 748.05;
string strAccountType = txtAccountType.Text[..3];
(double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
double waterCharges = tiers.first + tiers.second + tiers.last;
double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
double amtDue = totalCharges + localTaxes + stateTaxes;
txtTotalHCF.Text = consumption.ToString();
txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
txtFirstTierConsumption.Text = tiers.first.ToString("F");
txtSecondTierConsumption.Text = tiers.second.ToString("F");
txtLastTierConsumption.Text = tiers.last.ToString("F");
txtWaterCharges.Text = waterCharges.ToString("F");
txtSewerCharges.Text = sewerCharges.ToString("F");
txtEnvironmentCharges.Text = envCharges.ToString("F");
txtServiceCharges.Text = srvCharges.ToString("F");
txtTotalCharges.Text = totalCharges.ToString("F");
txtLocalTaxes.Text = localTaxes.ToString("F");
txtStateTaxes.Text = stateTaxes.ToString("F");
dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtAmountDue.Text = amtDue.ToString("F");
dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
}
private void btnSaveWaterBill_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtBillNumber.Text))
{
MsgBox.Show("You must type a (unique) bill number for the " +
"water bill you are processing.",
"Stellar Water Point", MessageBoxButtons.OK);
return;
}
if (string.IsNullOrEmpty(mtbAccountNumber.Text))
{
MsgBox.Show("You must specify the account number of the customer " +
"whose water bill you are preparing.",
"Stellar Water Point", MessageBoxButtons.OK);
return;
}
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
if (fiWaterBills.Exists == true)
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
}
WaterBill bill = new()
{
BillNumber = int.Parse(txtBillNumber.Text),
AccountNumber = mtbAccountNumber.Text,
MeterReadingStartDate = dtpMeterReadingStartDate.Value,
MeterReadingEndDate = dtpMeterReadingEndDate.Value,
BillingDays = int.Parse(txtBillingDays.Text),
CounterReadingStart = int.Parse(txtCounterReadingStart.Text),
CounterReadingEnd = int.Parse(txtCounterReadingEnd.Text),
TotalHCF = int.Parse(txtTotalHCF.Text),
TotalGallons = int.Parse(txtTotalGallons.Text),
FirstTierConsumption = double.Parse(txtFirstTierConsumption.Text),
SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text),
LastTierConsumption = double.Parse(txtLastTierConsumption.Text),
WaterCharges = double.Parse(txtWaterCharges.Text),
SewerCharges = double.Parse(txtSewerCharges.Text),
EnvironmentCharges = double.Parse(txtEnvironmentCharges.Text),
ServiceCharges = double.Parse(txtServiceCharges.Text),
TotalCharges = double.Parse(txtTotalCharges.Text),
LocalTaxes = double.Parse(txtLocalTaxes.Text),
StateTaxes = double.Parse(txtStateTaxes.Text),
PaymentDueDate = dtpPaymentDueDate.Value,
AmountDue = double.Parse(txtAmountDue.Text),
LatePaymentDueDate = dtpLatePaymentDueDate.Value,
LateAmountDue = double.Parse(txtLateAmountDue.Text)
};
bills.Add(bill);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterBills = JsonSerializer.Serialize(bills, typeof(List<WaterBill>), options);
File.WriteAllText(fiWaterBills.FullName, jsWaterBills);
Close();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}| Control | (Name) | Other Properties | |
| ListView | lvwWaterBills | No Change | |
| Button | btnProcessWaterBill | &Process Water Bill... | |
using System.Data;
using Microsoft.Data.SqlClient;
namespace StellarWaterPoint21.WaterBills
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterBills()
{
. . .
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterBills();
}
private void btnProcessWaterBill_Click(object sender, EventArgs e)
{
Create create = new();
create.ShowDialog();
ShowWaterBills();
}
}
}| Water Bill # | Account # | Reading Start Date | Reading End Date | Counter Reading Start | Counter Reading End |
| 451474 | 2068-258-9486 | 01/11/2010 | 04/12/2010 | 103943 | 103956 |
| 923633 | 5293-957-3395 | 01/17/2010 | 08/18/2010 | 256945 | 256972 |
| 917829 | 9279-570-8394 | 02/15/2010 | 05/14/2010 | 5205 | 5222 |
| 202666 | 6986-829-3741 | 03/08/2010 | 06/06/2010 | 5679 | 5690 |
Water Bill Details
Sometimes, an employee just wants to view the information that is related to a water bill. We will create a form to make it possible.
Practical Learning: Showing a Water Bill

| Control | Text | Name | Enabled | |
| Label | &Water Bill #: | |||
| TextBox | txtBillNumber | |||
| Button | &Find Water Bill | btnFindWaterBill | ||
| GroupBox | Customer Information | |||
| Label | &Account #: | |||
| TextBox | txtAccountNumber | False | ||
| Label | Account Name: | |||
| TextBox | txtAccountName | False | ||
| Label | Account Type: | |||
| TextBox | txtAccountType | |||
| Label | Address: | False | ||
| TextBox | txtAddress | False | ||
| TextBox | txtCity | |||
| TextBox | txtCounty | False | ||
| TextBox | txtState | False | ||
| TextBox | txtZIPCode | False | ||
| Label | _______________________________ | |||
| Label | Meter Details: | |||
| TextBox | txtMeterDetails | False | ||
| GroupBox | Meter Reading | |||
| Label | Meter &Reading Start Date: | |||
| Text Box | txtMeterReadingStartDate | False | ||
| Label | Meter Reading &End Date: | |||
| Text Box | txtMeterReadingEndDate | False | ||
| Label | Coun&ter Reading Start: | |||
| TextBox | txtCounterReadingStart | False | ||
| Label | Counter Readi&ng End: | |||
| TextBox | txtCounterReadingEnd | False | ||
| GroupBox | Meter Result | |||
| Label | Billing Days: | |||
| TextBox | txtBillingDays | False | ||
| Label | Total HCF: | |||
| TextBox | txtTotalHCF | False | ||
| Label | Total Gallons: | |||
| TextBox | txtTotalGallons | False | ||
| Label | First Tier Consumption: | |||
| TextBox | txtFirstTierConsumption | False | ||
| Label | Second Tier: | |||
| TextBox | txtSecondTierConsumption | False | ||
| Label | Last Tier: | |||
| TextBox | txtLastTierConsumption | False | ||
| GroupBox | Consumption Charges | |||
| Label | Water Charges: | |||
| TextBox | txtWaterCharges | False | ||
| Label | Sewer Charges: | |||
| TextBox | txtSewerCharges | False | ||
| Label | Environment Charges: | |||
| TextBox | txtEnvironmentCharges | False | ||
| Label | Service Charges: | |||
| TextBox | txtServiceCharges | False | ||
| Label | Total Charges: | |||
| TextBox | txtTotalCharges | False | ||
| GroupBox | Taxes | |||
| Label | Local Taxes: | |||
| TextBox | txtLocalTaxes | False | ||
| Label | State Taxes: | |||
| TextBox | txtStateTaxes | False | ||
| GroupBox | Water Bill Payment | |||
| Label | Payment Due Date: | |||
| Date Time Picker | dtpPaymentDueDate | False | ||
| Label | Amount Due: | |||
| TextBox | txtAmountDue | False | ||
| Label | Late Payment Due Date: | |||
| Text Box | txtLatePaymentDueDate | False | ||
| Label | &Late Amount Due: | |||
| TextBox | txtLateAmountDue | |||
| Label | Water Bill Id: | |||
| TextBox | txtWaterBillId | False | ||
| Button | &Close | btnClose | ||
Form Properties
| Form Property | Value |
| FormBorderStyle | FixedDialog |
| Text | Stellar Water Point - Water Bill Details |
| StartPosition | CenterScreen |
| MaximizeBox | False |
| MinimizeBox | False |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Details : Form
{
public Details()
{
InitializeComponent();
}
private void btnFindWaterBill_Click(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
IEnumerable<WaterBill> selected = bills.Where(wb => wb.BillNumber == int.Parse(txtBillNumber.Text));
foreach (var bill in selected)
{
txtWaterBillId.Text = bill.WaterBillId.ToString();
txtAccountNumber.Text = bill.AccountNumber;
txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToLongDateString();
txtBillingDays.Text = bill.BillingDays.ToString();
txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
txtTotalHCF.Text = bill.TotalHCF.ToString();
txtTotalGallons.Text = bill.TotalGallons.ToString();
txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
txtWaterCharges.Text = bill.WaterCharges.ToString();
txtSewerCharges.Text = bill.SewerCharges.ToString();
txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
txtServiceCharges.Text = bill.ServiceCharges.ToString();
txtTotalCharges.Text = bill.TotalCharges.ToString();
txtLocalTaxes.Text = bill.LocalTaxes.ToString();
txtStateTaxes.Text = bill.StateTaxes.ToString();
txtPaymentDueDate.Text = bill.PaymentDueDate.ToLongDateString();
txtAmountDue.Text = bill.AmountDue.ToString();
txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
txtLateAmountDue.Text = bill.LateAmountDue.ToString();
}
}
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
string strAccountType = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == txtAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
}
}using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Details : Form
{
public Details()
{
InitializeComponent();
}
private void btnFindWaterBill_Click(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
// Prepare a bills list to hold the records of water bills
List<WaterBill> bills = new List<WaterBill>();
// Specify the file that holds the records of water bills
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
// Create a FileInfo object for the records of water bills
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
// Find out whether a file that holds the records of water bills exists already
if (fiWaterBills.Exists == true)
{
// If that file exists, create a TextReader object to read the file
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
/* Read the contents of the file that holds the water bills.
* Store the read text in the strWaterBills variable that was declared. */
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
// Get the water bills and store them in the bills list variable
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
IEnumerable<WaterBill> selected = bills.Where(wb => wb.BillNumber == int.Parse(txtBillNumber.Text));
foreach (var bill in selected)
{
txtAccountNumber.Text = bill.AccountNumber;
txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToLongDateString();
txtBillingDays.Text = bill.BillingDays.ToString();
txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
txtTotalHCF.Text = bill.TotalHCF.ToString();
txtTotalGallons.Text = bill.TotalGallons.ToString();
txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
txtWaterCharges.Text = bill.WaterCharges.ToString();
txtSewerCharges.Text = bill.SewerCharges.ToString();
txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
txtServiceCharges.Text = bill.ServiceCharges.ToString();
txtTotalCharges.Text = bill.TotalCharges.ToString();
txtLocalTaxes.Text = bill.LocalTaxes.ToString();
txtStateTaxes.Text = bill.StateTaxes.ToString();
txtPaymentDueDate.Text = bill.PaymentDueDate.ToLongDateString();
txtAmountDue.Text = bill.AmountDue.ToString();
txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
txtLateAmountDue.Text = bill.LateAmountDue.ToString();
}
}
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == txtAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
txtAccountType.Text = client.AccountType;
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}| Control | (Name) | Other Properties | |
| ListView | lvwWaterBills | No Change | |
| Button | No Change | No Change | |
| Button | btnWaterBillDetails | Water Bill &Details... | |
using System.Data;
using Microsoft.Data.SqlClient;
namespace StellarWaterPoint21.WaterBills
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterBills()
{
. . .
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterBills();
}
private void btnProcessWaterBill_Click(object sender, EventArgs e)
{
Create create = new();
create.ShowDialog();
ShowWaterBills();
}
private void btnViewWaterBill_Click(object sender, EventArgs e)
{
Details details = new();
details.Show();
}
}
}
Water Bill Edition
If some aspect of a water bill changes, we will create a form that an employee can use to update the record.
Practical Learning: Creating a Water Bill Editor
| Control | (Name) | Text | |
| Button | btnFindWaterBill | &Find Water Bill | |
| Button | btnUpdateWaterBill | &Update Water Bill | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Editor : Form
{
public Editor()
{
InitializeComponent();
}
private void btnFindWaterBill_Click(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
IEnumerable<WaterBill> selected = bills.Where(wb => wb.BillNumber == int.Parse(txtWaterBillNumber.Text));
foreach (var bill in selected)
{
txtWaterBillId.Text = bill.WaterBillId.ToString();
mtbAccountNumber.Text = bill.AccountNumber;
dtpMeterReadingStartDate.Value = bill.MeterReadingStartDate;
dtpMeterReadingEndDate.Value = bill.MeterReadingEndDate;
txtBillingDays.Text = bill.BillingDays.ToString();
txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
txtTotalHCF.Text = bill.TotalHCF.ToString();
txtTotalGallons.Text = bill.TotalGallons.ToString();
txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
txtWaterCharges.Text = bill.WaterCharges.ToString();
txtSewerCharges.Text = bill.SewerCharges.ToString();
txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
txtServiceCharges.Text = bill.ServiceCharges.ToString();
txtTotalCharges.Text = bill.TotalCharges.ToString();
txtLocalTaxes.Text = bill.LocalTaxes.ToString();
txtStateTaxes.Text = bill.StateTaxes.ToString();
dtpPaymentDueDate.Value = bill.PaymentDueDate;
txtAmountDue.Text = bill.AmountDue.ToString();
dtpLatePaymentDueDate.Value = bill.LatePaymentDueDate;
txtLateAmountDue.Text = bill.LateAmountDue.ToString();
}
}
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
string strAccountType = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == mtbAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
}
}private void btnFindCustomerAccount_Click(object sender, EventArgs e)
{
string strAccountNumber = mtbAccountNumber.Text.Replace("-", "").Trim();
if (string.IsNullOrEmpty(strAccountNumber))
{
MsgBox.Show("You must type a valid account number of a customer, " +
"and then click the Find Customer Account button.");
return;
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
string? strMeterNumber = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = clients.Where(cust => cust.AccountNumber == mtbAccountNumber.Text);
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = waterMeters.Where(wm => wm.MeterNumber == strMeterNumber);
foreach (WaterMeter meter in meters)
{
txtMeterDetails.Text = meter.WaterMeterId.ToString() + " - " +
meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}private void dtpMeterReadingEndDate_ValueChanged(object sender, EventArgs e)
{
TimeSpan tsDays = dtpMeterReadingEndDate.Value - dtpMeterReadingStartDate.Value;
txtBillingDays.Text = (tsDays.Days + 1).ToString();
}private void btnEvaluateWaterBill_Click(object sender, EventArgs e)
{
double counterStart = 0, counterEnd = 0;
try
{
counterStart = double.Parse(txtCounterReadingStart.Text);
}
catch (FormatException feCRStart)
{
MsgBox.Show("You must enter a valid value in the Counter Reading Start text box. " +
"The error produced is: " + feCRStart.Message);
}
try
{
counterEnd = double.Parse(txtCounterReadingEnd.Text);
}
catch (FormatException feCREnd)
{
MsgBox.Show("You must enter a valid value in the Counter Reading End text box. " +
"The error produced is: " + feCREnd.Message);
}
double consumption = counterEnd - counterStart;
double gallons = consumption * 748.05;
string strAccountType = txtAccountType.Text[..3];
(double first, double second, double last) tiers = WaterBillManager.CalculateTiers(strAccountType, gallons);
double waterCharges = tiers.first + tiers.second + tiers.last;
double sewerCharges = WaterBillManager.CalculateSewerCharges(strAccountType, waterCharges);
double envCharges = WaterBillManager.CalculateEnvironmentCharges(strAccountType, waterCharges);
double srvCharges = WaterBillManager.CalculateServiceCharges(strAccountType, waterCharges);
double totalCharges = waterCharges + sewerCharges + envCharges + srvCharges;
double localTaxes = WaterBillManager.CalculateLocalTaxes(strAccountType, waterCharges);
double stateTaxes = WaterBillManager.CalculateStateTaxes(strAccountType, waterCharges);
double amtDue = totalCharges + localTaxes + stateTaxes;
txtTotalHCF.Text = consumption.ToString();
txtTotalGallons.Text = ((int)(Math.Ceiling(gallons))).ToString();
txtFirstTierConsumption.Text = tiers.first.ToString("F");
txtSecondTierConsumption.Text = tiers.second.ToString("F");
txtLastTierConsumption.Text = tiers.last.ToString("F");
txtWaterCharges.Text = waterCharges.ToString("F");
txtSewerCharges.Text = sewerCharges.ToString("F");
txtEnvironmentCharges.Text = envCharges.ToString("F");
txtServiceCharges.Text = srvCharges.ToString("F");
txtTotalCharges.Text = totalCharges.ToString("F");
txtLocalTaxes.Text = localTaxes.ToString("F");
txtStateTaxes.Text = stateTaxes.ToString("F");
dtpPaymentDueDate.Value = WaterBillManager.SetPaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtAmountDue.Text = amtDue.ToString("F");
dtpLatePaymentDueDate.Value = WaterBillManager.SetLatePaymentDueDate(strAccountType, dtpMeterReadingEndDate.Value);
txtLateAmountDue.Text = WaterBillManager.CalculateLateAmountDue(strAccountType, amtDue).ToString("F");
}private void btnUpdateWaterBill_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtWaterBillNumber.Text))
{
MsgBox.Show("You must provide the bill number of the " +
"water bill you are trying to update.");
return;
}
if (string.IsNullOrEmpty(mtbAccountNumber.Text))
{
MsgBox.Show("Please make sure you provide the account number of the customer " +
"associated with the water bill you are trying to update.");
return;
}
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
if (fiWaterBills.Exists == true)
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
WaterBill? bill = bills.Find(invoice => invoice.BillNumber == int.Parse(txtWaterBillNumber.Text));
if (bill is not null)
{
bill.WaterBillId = int.Parse(txtWaterBillId.Text);
bill.BillNumber = int.Parse(txtWaterBillNumber.Text);
bill.AccountNumber = mtbAccountNumber.Text;
bill.MeterReadingStartDate = dtpMeterReadingStartDate.Value;
bill.MeterReadingEndDate = dtpMeterReadingEndDate.Value;
bill.BillingDays = int.Parse(txtBillingDays.Text);
bill.CounterReadingStart = int.Parse(txtCounterReadingStart.Text);
bill.CounterReadingEnd = int.Parse(txtCounterReadingEnd.Text);
bill.TotalHCF = int.Parse(txtTotalHCF.Text);
bill.TotalGallons = int.Parse(txtTotalGallons.Text);
bill.FirstTierConsumption = double.Parse(txtFirstTierConsumption.Text);
bill.SecondTierConsumption = double.Parse(txtSecondTierConsumption.Text);
bill.LastTierConsumption = double.Parse(txtLastTierConsumption.Text);
bill.WaterCharges = double.Parse(txtWaterCharges.Text);
bill.SewerCharges = double.Parse(txtSewerCharges.Text);
bill.EnvironmentCharges = double.Parse(txtEnvironmentCharges.Text);
bill.ServiceCharges = double.Parse(txtServiceCharges.Text);
bill.TotalCharges = double.Parse(txtTotalCharges.Text);
bill.LocalTaxes = double.Parse(txtLocalTaxes.Text);
bill.StateTaxes = double.Parse(txtStateTaxes.Text);
bill.PaymentDueDate = dtpPaymentDueDate.Value;
bill.AmountDue = double.Parse(txtAmountDue.Text);
bill.LatePaymentDueDate = dtpLatePaymentDueDate.Value;
bill.LateAmountDue = double.Parse(txtLateAmountDue.Text);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterBills = JsonSerializer.Serialize(bills, typeof(List<WaterBill>), options);
File.WriteAllText(fiWaterBills.FullName, jsWaterBills);
}
}
Close();
}private void btnClose_Click(object sender, EventArgs e)
{
Close();
}| Control | (Name) | Text | |
| ListView | lvwWaterBills | ||
| Button | btnNewWaterBill | ||
| Button | btnViewWaterBill | ||
| Button | btnEditWaterBill | &Edit Water Bill... | |
private void btnWaterBillEditor_Click(object sender, EventArgs e)
{
Editor update = new Editor();
update.ShowDialog();
ShowWaterBills();
}Account #: 9249-379-6848 and click Find Customer Account Meter Reading Start Date: 1/19/2010 Meter Reading End Date: 4/17/2010 Counter Reading Start: 256953 Counter Reading End: 256966
If a water bill is useless and must not be kept as a record in the system, an employee must be able to delete it. We will create a form that makes it possible to delete a water bill.
Practical Learning: Deleting a Water Bill Record
| Control | (Name) | Text | |
| Button | btnDeleteWaterBill | &Delete Water Bill | |
using System.Data;
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Delete : Form
{
public Delete()
{
InitializeComponent();
}
private void btnFindWaterBill_Click(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
IEnumerable<WaterBill> selected = bills.Where(wb => wb.BillNumber == int.Parse(txtWaterBillNumber.Text));
foreach (var bill in selected)
{
txtWaterBillId.Text = bill.WaterBillId.ToString();
txtAccountNumber.Text = bill.AccountNumber;
txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToLongDateString();
txtBillingDays.Text = bill.BillingDays.ToString();
txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
txtTotalHCF.Text = bill.TotalHCF.ToString();
txtTotalGallons.Text = bill.TotalGallons.ToString();
txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
txtWaterCharges.Text = bill.WaterCharges.ToString();
txtSewerCharges.Text = bill.SewerCharges.ToString();
txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
txtServiceCharges.Text = bill.ServiceCharges.ToString();
txtTotalCharges.Text = bill.TotalCharges.ToString();
txtLocalTaxes.Text = bill.LocalTaxes.ToString();
txtStateTaxes.Text = bill.StateTaxes.ToString();
txtPaymentDueDate.Text = bill.PaymentDueDate.ToLongDateString();
txtAmountDue.Text = bill.AmountDue.ToString();
txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
txtLateAmountDue.Text = bill.LateAmountDue.ToString();
}
}
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
string strAccountType = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == txtAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
}
}using System.Data;
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Delete : Form
{
public Delete()
{
InitializeComponent();
}
private void btnFindWaterBill_Click(object sender, EventArgs e)
{
string strWaterBills = string.Empty;
List<WaterBill> bills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
string strAccountsTypes = string.Empty;
List<AccountType> accountsTypes = new List<AccountType>();
string fileAccountsTypes = @"C:\Stellar Water Point2\AccountsTypes.json";
FileInfo fiAccountsTypes = new FileInfo(fileAccountsTypes);
if (fiWaterBills.Exists == true)
{
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
IEnumerable<WaterBill> selected = bills.Where(wb => wb.BillNumber == int.Parse(txtWaterBillNumber.Text));
foreach (var bill in selected)
{
txtWaterBillId.Text = bill.WaterBillId.ToString();
txtAccountNumber.Text = bill.AccountNumber;
txtMeterReadingStartDate.Text = bill.MeterReadingStartDate.ToLongDateString();
txtMeterReadingEndDate.Text = bill.MeterReadingEndDate.ToLongDateString();
txtBillingDays.Text = bill.BillingDays.ToString();
txtCounterReadingStart.Text = bill.CounterReadingStart.ToString();
txtCounterReadingEnd.Text = bill.CounterReadingEnd.ToString();
txtTotalHCF.Text = bill.TotalHCF.ToString();
txtTotalGallons.Text = bill.TotalGallons.ToString();
txtFirstTierConsumption.Text = bill.FirstTierConsumption.ToString();
txtSecondTierConsumption.Text = bill.SecondTierConsumption.ToString();
txtLastTierConsumption.Text = bill.LastTierConsumption.ToString();
txtWaterCharges.Text = bill.WaterCharges.ToString();
txtSewerCharges.Text = bill.SewerCharges.ToString();
txtEnvironmentCharges.Text = bill.EnvironmentCharges.ToString();
txtServiceCharges.Text = bill.ServiceCharges.ToString();
txtTotalCharges.Text = bill.TotalCharges.ToString();
txtLocalTaxes.Text = bill.LocalTaxes.ToString();
txtStateTaxes.Text = bill.StateTaxes.ToString();
txtPaymentDueDate.Text = bill.PaymentDueDate.ToLongDateString();
txtAmountDue.Text = bill.AmountDue.ToString();
txtLatePaymentDueDate.Text = bill.LatePaymentDueDate.ToLongDateString();
txtLateAmountDue.Text = bill.LateAmountDue.ToString();
}
}
}
string strCustomers = string.Empty;
List<Customer> clients = new List<Customer>();
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
FileInfo fiCustomers = new FileInfo(fileCustomers);
string? strMeterNumber = string.Empty;
string strAccountType = string.Empty;
if (fiCustomers.Exists == true)
{
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
strCustomers = File.ReadAllText(fiCustomers.FullName);
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
IEnumerable<Customer> customers = from consumer
in clients
where consumer.AccountNumber == txtAccountNumber.Text
select consumer;
foreach (Customer client in customers)
{
txtAccountName.Text = client.AccountName;
strMeterNumber = client.MeterNumber;
TextReader trAccountsTypess = new StreamReader(fiAccountsTypes.FullName);
strAccountsTypes = File.ReadAllText(fiAccountsTypes.FullName);
accountsTypes = JsonSerializer.Deserialize<List<AccountType>>(strAccountsTypes)!;
foreach (AccountType at in accountsTypes)
{
if (client.AccountType == at.TypeCode)
{
txtAccountType.Text = string.Concat(at.TypeCode, " - ", at.TypeDecription);
}
}
txtAddress.Text = client.Address;
txtCity.Text = client.City;
txtCounty.Text = client.County;
txtState.Text = client.State;
txtZIPCode.Text = client.ZIPCode;
}
}
}
if (strMeterNumber!.Length > 0)
{
string strWaterMeters = string.Empty;
List<WaterMeter> waterMeters = new List<WaterMeter>();
string fileWaterMeters = @"C:\Stellar Water Point2\WaterMeters.json";
FileInfo fiWaterMeters = new FileInfo(fileWaterMeters);
if (fiWaterMeters.Exists == true)
{
strWaterMeters = File.ReadAllText(fiWaterMeters.FullName);
waterMeters = JsonSerializer.Deserialize<List<WaterMeter>>(strWaterMeters)!;
IEnumerable<WaterMeter> meters = from measure
in waterMeters
where measure.MeterNumber == strMeterNumber
select measure;
foreach (WaterMeter meter in waterMeters)
{
txtMeterDetails.Text = meter.Make + " " +
meter.Model +
" (Meter Size: " + meter.MeterSize + ")";
}
}
}
}
private void btnDeleteWaterBill_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtWaterBillNumber.Text))
{
MsgBox.Show("Please provide the bill number of the water bill you want to delete, " +
"and then click the Find Water Bill button.");
return;
}
string strWaterBills = string.Empty;
List<WaterBill> waterBills = new List<WaterBill>();
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
if (fiWaterBills.Exists == true)
{
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
waterBills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
WaterBill bill = waterBills.Find(bl => bl.BillNumber == int.Parse(txtWaterBillNumber.Text))!;
if (bill is not null)
{
if (MsgBox.Question("Are you sure you want to delete (or remove) or cancel " +
"this water bill from the system (you cannot undo the action)?") == Answer.Yes)
{
waterBills.Remove(bill);
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true;
string jsWaterBills = JsonSerializer.Serialize(waterBills, typeof(List<WaterBill>), options);
File.WriteAllText(fiWaterBills.FullName, jsWaterBills);
MsgBox.Show("The water bill has been deleted (or removed, or cancelled) from our system.");
}
}
}
Close();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}| Control | (Name) | Text | Other Properties | |
| ListView | lvwWaterBills | Anchor: Bottom, Top, Bottom, Left, Right | ||
| Button | btnProcessWaterBill | &Process Water Bill... | Anchor: Bottom, Right | |
| Button | btnViewWaterBill | &View Water Bill... | Anchor: Bottom, Right | |
| Button | btnEditWaterBill | &Edit Water Bill... | Anchor: Bottom, Right | |
| Button | btnDeleteWaterBill | &Delete Water Bill... | Anchor: Bottom, Right | |
| Button | btnClose | &Close | Anchor: Bottom, Right | |
using System.Text.Json;
using StellarWaterPoint2.Models;
namespace StellarWaterPoint2.WaterBills
{
public partial class Central : Form
{
public Central()
{
InitializeComponent();
}
private void ShowWaterBills()
{
// We will need the list of customers to display an account summary in the list view
// Declare a strCustomers variable that will hold the records from the JSON file
string strCustomers = string.Empty;
// Prepare a list to hold the records of customers
List<Customer> clients = new List<Customer>();
// Specify the file that holds the records of customers
string fileCustomers = @"C:\Stellar Water Point2\Customers.json";
// Create a FileInfo object for the records of customers
FileInfo fiCustomers = new FileInfo(fileCustomers);
// Check if a file that holds the records of customers was created already
if (fiCustomers.Exists == true)
{
// If that file exists, create a TextReader object to get those records
using (TextReader trCustomers = new StreamReader(fiCustomers.FullName))
{
// Read the records and store them in the strCustomers variable
strCustomers = File.ReadAllText(fiCustomers.FullName);
// Use JSON deserialization to get the records of customers
clients = JsonSerializer.Deserialize<List<Customer>>(strCustomers)!;
}
}
// Declare a strWaterBills variable that will hold the records from the JSON file
string strWaterBills = string.Empty;
// Prepare a bills list to hold the records of water bills
List<WaterBill> bills = new List<WaterBill>();
// Specify the file that holds the records of water bills
string fileWaterBills = @"C:\Stellar Water Point2\WaterBills.json";
// Create a FileInfo object for the records of water bills
FileInfo fiWaterBills = new FileInfo(fileWaterBills);
// Find out whether a file that holds the records of water bills exists already
if (fiWaterBills.Exists == true)
{
// If that file exists, create a TextReader object to read the file
using (TextReader trWaterBills = new StreamReader(fiWaterBills.FullName))
{
/* Read the contents of the file that holds the water bills.
* Store the read text in the strWaterBills variable that was declared. */
strWaterBills = File.ReadAllText(fiWaterBills.FullName);
// Get the water bills and store them in the bills list variable
bills = JsonSerializer.Deserialize<List<WaterBill>>(strWaterBills)!;
/* We are about to display the water bills records in the list view.
* Before proceeding, first remove any record in the list view. */
lvwWaterBills.Items.Clear();
// Visit each record of the water bills
foreach (WaterBill invoice in bills)
{
/* Prepare a ListViewItem object for each record.
* Display the record counter in the first column of this object. */
ListViewItem lviWaterBill = new ListViewItem(invoice.WaterBillId.ToString());
// Display the water bill number of the current record
lviWaterBill.SubItems.Add(invoice.BillNumber.ToString());
/* Refer to the list of records of the customers (that list was prepared earlier).
* Use LINQ to get the customer whose account number is
* the same as the account number of the current record. */
IEnumerable<Customer> customer = clients.Where(cust => cust.AccountNumber == invoice.AccountNumber);
// Now that we have located the customer record, display some details about it
foreach (Customer cust in customer)
{
lviWaterBill.SubItems.Add(invoice.AccountNumber + " - " +
cust.AccountName +
", Type: " + cust.AccountType![..3] +
", (Mtr #: " + cust.MeterNumber + ")");
}
/* Continue displaying some other parts of the water bill.
* Before there is not enough space for the whole water bill, we display only some values. */
lviWaterBill.SubItems.Add(invoice.MeterReadingStartDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.MeterReadingEndDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.BillingDays.ToString());
lviWaterBill.SubItems.Add(invoice.CounterReadingStart.ToString());
lviWaterBill.SubItems.Add(invoice.CounterReadingEnd.ToString());
lviWaterBill.SubItems.Add(invoice.TotalHCF.ToString());
lviWaterBill.SubItems.Add(invoice.TotalGallons.ToString());
lviWaterBill.SubItems.Add(invoice.PaymentDueDate.ToShortDateString());
lviWaterBill.SubItems.Add(invoice.AmountDue.ToString());
lvwWaterBills.Items.Add(lviWaterBill);
}
}
}
}
private void Central_Load(object sender, EventArgs e)
{
ShowWaterBills();
}
private void btnProcessWaterBill_Click(object sender, EventArgs e)
{
Create create = new Create();
create.ShowDialog();
ShowWaterBills();
}
private void btnWaterBillDetails_Click(object sender, EventArgs e)
{
Details details = new Details();
details.ShowDialog();
}
private void btnWaterBillEditor_Click(object sender, EventArgs e)
{
Editor update = new Editor();
update.ShowDialog();
ShowWaterBills();
}
private void btnDeleteWaterBill_Click(object sender, EventArgs e)
{
Delete delete = new Delete();
delete.ShowDialog();
ShowWaterBills();
}
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
}
}|
|
|||
| Home | Copyright © 2010-2026, FunctionX | Sunday 11 June 2023 | Home |
|
|
|||