Adding folder for forms for cleanup
This commit is contained in:
344
C969Project/Forms/AddOrUpdateAppointmentForm.Designer.cs
generated
Normal file
344
C969Project/Forms/AddOrUpdateAppointmentForm.Designer.cs
generated
Normal file
@@ -0,0 +1,344 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class AddOrUpdateAppointmentForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
cancelButton = new Button();
|
||||
saveButton = new Button();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
titleTextBox = new TextBox();
|
||||
descriptionTextBox = new TextBox();
|
||||
label3 = new Label();
|
||||
locationTextBox = new TextBox();
|
||||
label4 = new Label();
|
||||
contactTextBox = new TextBox();
|
||||
label5 = new Label();
|
||||
textBoxUrl = new TextBox();
|
||||
urlTextBox = new Label();
|
||||
label6 = new Label();
|
||||
typeComboBox = new ComboBox();
|
||||
customerComboBox = new ComboBox();
|
||||
customerLabel = new Label();
|
||||
startPickerDate = new DateTimePicker();
|
||||
label7 = new Label();
|
||||
label8 = new Label();
|
||||
endPickerDate = new DateTimePicker();
|
||||
startPickerTime = new DateTimePicker();
|
||||
endPickerTime = new DateTimePicker();
|
||||
SuspendLayout();
|
||||
//
|
||||
// cancelButton
|
||||
//
|
||||
cancelButton.Location = new Point(856, 761);
|
||||
cancelButton.Name = "cancelButton";
|
||||
cancelButton.Size = new Size(75, 23);
|
||||
cancelButton.TabIndex = 0;
|
||||
cancelButton.Text = "Cancel";
|
||||
cancelButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// saveButton
|
||||
//
|
||||
saveButton.Location = new Point(775, 761);
|
||||
saveButton.Name = "saveButton";
|
||||
saveButton.Size = new Size(75, 23);
|
||||
saveButton.TabIndex = 1;
|
||||
saveButton.Text = "Save";
|
||||
saveButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 0);
|
||||
label1.Location = new Point(12, 9);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(159, 23);
|
||||
label1.TabIndex = 2;
|
||||
label1.Text = "Update Appointment";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label2.Location = new Point(12, 69);
|
||||
label2.Name = "label2";
|
||||
label2.RightToLeft = RightToLeft.No;
|
||||
label2.Size = new Size(100, 23);
|
||||
label2.TabIndex = 3;
|
||||
label2.Text = "Title";
|
||||
label2.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// titleTextBox
|
||||
//
|
||||
titleTextBox.Location = new Point(12, 95);
|
||||
titleTextBox.Name = "titleTextBox";
|
||||
titleTextBox.Size = new Size(520, 23);
|
||||
titleTextBox.TabIndex = 4;
|
||||
//
|
||||
// descriptionTextBox
|
||||
//
|
||||
descriptionTextBox.Location = new Point(12, 147);
|
||||
descriptionTextBox.Multiline = true;
|
||||
descriptionTextBox.Name = "descriptionTextBox";
|
||||
descriptionTextBox.Size = new Size(520, 100);
|
||||
descriptionTextBox.TabIndex = 6;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label3.Location = new Point(12, 121);
|
||||
label3.Name = "label3";
|
||||
label3.RightToLeft = RightToLeft.No;
|
||||
label3.Size = new Size(100, 23);
|
||||
label3.TabIndex = 5;
|
||||
label3.Text = "Description";
|
||||
label3.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// locationTextBox
|
||||
//
|
||||
locationTextBox.Location = new Point(12, 276);
|
||||
locationTextBox.Name = "locationTextBox";
|
||||
locationTextBox.Size = new Size(520, 23);
|
||||
locationTextBox.TabIndex = 8;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label4.Location = new Point(12, 250);
|
||||
label4.Name = "label4";
|
||||
label4.RightToLeft = RightToLeft.No;
|
||||
label4.Size = new Size(100, 23);
|
||||
label4.TabIndex = 7;
|
||||
label4.Text = "Location";
|
||||
label4.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// contactTextBox
|
||||
//
|
||||
contactTextBox.Location = new Point(12, 328);
|
||||
contactTextBox.Name = "contactTextBox";
|
||||
contactTextBox.Size = new Size(520, 23);
|
||||
contactTextBox.TabIndex = 10;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
label5.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label5.Location = new Point(12, 302);
|
||||
label5.Name = "label5";
|
||||
label5.RightToLeft = RightToLeft.No;
|
||||
label5.Size = new Size(100, 23);
|
||||
label5.TabIndex = 9;
|
||||
label5.Text = "Contact";
|
||||
label5.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// textBoxUrl
|
||||
//
|
||||
textBoxUrl.Location = new Point(12, 380);
|
||||
textBoxUrl.Name = "textBoxUrl";
|
||||
textBoxUrl.Size = new Size(520, 23);
|
||||
textBoxUrl.TabIndex = 12;
|
||||
//
|
||||
// urlTextBox
|
||||
//
|
||||
urlTextBox.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
urlTextBox.Location = new Point(12, 354);
|
||||
urlTextBox.Name = "urlTextBox";
|
||||
urlTextBox.RightToLeft = RightToLeft.No;
|
||||
urlTextBox.Size = new Size(100, 23);
|
||||
urlTextBox.TabIndex = 11;
|
||||
urlTextBox.Text = "Url";
|
||||
urlTextBox.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
label6.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label6.Location = new Point(12, 406);
|
||||
label6.Name = "label6";
|
||||
label6.RightToLeft = RightToLeft.No;
|
||||
label6.Size = new Size(100, 23);
|
||||
label6.TabIndex = 13;
|
||||
label6.Text = "Type";
|
||||
label6.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// typeComboBox
|
||||
//
|
||||
typeComboBox.FormattingEnabled = true;
|
||||
typeComboBox.Location = new Point(12, 432);
|
||||
typeComboBox.Name = "typeComboBox";
|
||||
typeComboBox.Size = new Size(324, 23);
|
||||
typeComboBox.TabIndex = 14;
|
||||
//
|
||||
// customerComboBox
|
||||
//
|
||||
customerComboBox.FormattingEnabled = true;
|
||||
customerComboBox.Location = new Point(12, 484);
|
||||
customerComboBox.Name = "customerComboBox";
|
||||
customerComboBox.Size = new Size(324, 23);
|
||||
customerComboBox.TabIndex = 16;
|
||||
//
|
||||
// customerLabel
|
||||
//
|
||||
customerLabel.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
customerLabel.Location = new Point(12, 458);
|
||||
customerLabel.Name = "customerLabel";
|
||||
customerLabel.RightToLeft = RightToLeft.No;
|
||||
customerLabel.Size = new Size(100, 23);
|
||||
customerLabel.TabIndex = 15;
|
||||
customerLabel.Text = "Customer";
|
||||
customerLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// startPickerDate
|
||||
//
|
||||
startPickerDate.CustomFormat = "dddd MMMM dd @ hh:mm tt";
|
||||
startPickerDate.Format = DateTimePickerFormat.Short;
|
||||
startPickerDate.Location = new Point(12, 536);
|
||||
startPickerDate.Name = "startPickerDate";
|
||||
startPickerDate.Size = new Size(159, 23);
|
||||
startPickerDate.TabIndex = 17;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
label7.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label7.Location = new Point(12, 510);
|
||||
label7.Name = "label7";
|
||||
label7.RightToLeft = RightToLeft.No;
|
||||
label7.Size = new Size(100, 23);
|
||||
label7.TabIndex = 18;
|
||||
label7.Text = "Start Time";
|
||||
label7.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
label8.Font = new Font("Segoe UI Semibold", 9.75F, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Point, 0);
|
||||
label8.Location = new Point(12, 562);
|
||||
label8.Name = "label8";
|
||||
label8.RightToLeft = RightToLeft.No;
|
||||
label8.Size = new Size(100, 23);
|
||||
label8.TabIndex = 20;
|
||||
label8.Text = "End Time";
|
||||
label8.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// endPickerDate
|
||||
//
|
||||
endPickerDate.CustomFormat = "dddd MMMM dd @ hh:mm tt";
|
||||
endPickerDate.Format = DateTimePickerFormat.Short;
|
||||
endPickerDate.Location = new Point(12, 588);
|
||||
endPickerDate.Name = "endPickerDate";
|
||||
endPickerDate.Size = new Size(159, 23);
|
||||
endPickerDate.TabIndex = 19;
|
||||
//
|
||||
// startPickerTime
|
||||
//
|
||||
startPickerTime.CustomFormat = "dddd MMMM dd @ hh:mm tt";
|
||||
startPickerTime.Format = DateTimePickerFormat.Time;
|
||||
startPickerTime.Location = new Point(177, 536);
|
||||
startPickerTime.Name = "startPickerTime";
|
||||
startPickerTime.ShowUpDown = true;
|
||||
startPickerTime.Size = new Size(159, 23);
|
||||
startPickerTime.TabIndex = 21;
|
||||
//
|
||||
// endPickerTime
|
||||
//
|
||||
endPickerTime.CustomFormat = "dddd MMMM dd @ hh:mm tt";
|
||||
endPickerTime.Format = DateTimePickerFormat.Time;
|
||||
endPickerTime.Location = new Point(177, 588);
|
||||
endPickerTime.Name = "endPickerTime";
|
||||
endPickerTime.ShowUpDown = true;
|
||||
endPickerTime.Size = new Size(159, 23);
|
||||
endPickerTime.TabIndex = 22;
|
||||
//
|
||||
// AddOrUpdateAppointmentForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(943, 796);
|
||||
Controls.Add(endPickerTime);
|
||||
Controls.Add(startPickerTime);
|
||||
Controls.Add(label8);
|
||||
Controls.Add(endPickerDate);
|
||||
Controls.Add(label7);
|
||||
Controls.Add(startPickerDate);
|
||||
Controls.Add(customerComboBox);
|
||||
Controls.Add(customerLabel);
|
||||
Controls.Add(typeComboBox);
|
||||
Controls.Add(label6);
|
||||
Controls.Add(textBoxUrl);
|
||||
Controls.Add(urlTextBox);
|
||||
Controls.Add(contactTextBox);
|
||||
Controls.Add(label5);
|
||||
Controls.Add(locationTextBox);
|
||||
Controls.Add(label4);
|
||||
Controls.Add(descriptionTextBox);
|
||||
Controls.Add(label3);
|
||||
Controls.Add(titleTextBox);
|
||||
Controls.Add(label2);
|
||||
Controls.Add(label1);
|
||||
Controls.Add(saveButton);
|
||||
Controls.Add(cancelButton);
|
||||
Name = "AddOrUpdateAppointmentForm";
|
||||
Text = "Update Appointment";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
private System.Windows.Forms.DateTimePicker startPickerDate;
|
||||
private System.Windows.Forms.DateTimePicker endPickerDate;
|
||||
|
||||
private System.Windows.Forms.DateTimePicker dateTimePicker1;
|
||||
private System.Windows.Forms.DateTimePicker dateTimePicker2;
|
||||
|
||||
private System.Windows.Forms.ComboBox customerComboBox;
|
||||
private System.Windows.Forms.Label customerLabel;
|
||||
private System.Windows.Forms.DateTimePicker startPickerTime;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.DateTimePicker endPickerTime;
|
||||
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.ComboBox typeComboBox;
|
||||
|
||||
private System.Windows.Forms.TextBox locationTextBox;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox contactTextBox;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.TextBox textBoxUrl;
|
||||
private System.Windows.Forms.Label urlTextBox;
|
||||
|
||||
private System.Windows.Forms.TextBox descriptionTextBox;
|
||||
private System.Windows.Forms.Label label3;
|
||||
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox titleTextBox;
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
|
||||
private System.Windows.Forms.Button cancelButton;
|
||||
private System.Windows.Forms.Button saveButton;
|
||||
|
||||
#endregion
|
||||
}
|
||||
182
C969Project/Forms/AddOrUpdateAppointmentForm.cs
Normal file
182
C969Project/Forms/AddOrUpdateAppointmentForm.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
public partial class AddOrUpdateAppointmentForm : Form
|
||||
{
|
||||
public event EventHandler UpdateAppointmentsList;
|
||||
|
||||
private Appointment? _currentAppointment;
|
||||
|
||||
private List<string> _appointmentTypes = new ()
|
||||
{
|
||||
"Scrum",
|
||||
"Presentation",
|
||||
"Other"
|
||||
};
|
||||
|
||||
private List<Customer> _customers = new();
|
||||
|
||||
public AddOrUpdateAppointmentForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
RefreshCustomersList();
|
||||
|
||||
typeComboBox.DataSource = _appointmentTypes;
|
||||
saveButton.Click += SaveButton_Click;
|
||||
cancelButton.Click += (s, e) => Close();
|
||||
}
|
||||
|
||||
private void RefreshCustomersList()
|
||||
{
|
||||
customerComboBox.DataSource = null;
|
||||
_customers.Clear();
|
||||
_customers.AddRange(DatabaseHelper.RetrieveCustomers());
|
||||
customerComboBox.DataSource = _customers;
|
||||
}
|
||||
|
||||
public void InitAdd()
|
||||
{
|
||||
RefreshCustomersList();
|
||||
|
||||
label1.Text = "Add New Appointment";
|
||||
_currentAppointment = null;
|
||||
|
||||
titleTextBox.Text = string.Empty;
|
||||
descriptionTextBox.Text = string.Empty;
|
||||
locationTextBox.Text = string.Empty;
|
||||
contactTextBox.Text = string.Empty;
|
||||
textBoxUrl.Text = string.Empty;
|
||||
typeComboBox.SelectedIndex = -1;
|
||||
customerComboBox.SelectedIndex = -1;
|
||||
startPickerDate.Value = DateTime.Now.Date;
|
||||
startPickerTime.Value = DateTime.Now;
|
||||
endPickerDate.Value = DateTime.Now.Date;
|
||||
endPickerTime.Value = DateTime.Now.AddHours(1);
|
||||
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
public void InitUpdate(Appointment appointment)
|
||||
{
|
||||
RefreshCustomersList();
|
||||
|
||||
label1.Text = "Update Appointment";
|
||||
_currentAppointment = appointment;
|
||||
|
||||
titleTextBox.Text = appointment.Title;
|
||||
descriptionTextBox.Text = appointment.Description;
|
||||
locationTextBox.Text = appointment.Location;
|
||||
contactTextBox.Text = appointment.Contact;
|
||||
textBoxUrl.Text = appointment.Url;
|
||||
|
||||
typeComboBox.SelectedItem = appointment.AppointmentType;
|
||||
customerComboBox.SelectedItem = _customers.FirstOrDefault(c => c.CustomerId == appointment.CustomerId);
|
||||
|
||||
startPickerDate.Value = appointment.Start.ToLocalTime().Date;
|
||||
startPickerTime.Value = appointment.Start.ToLocalTime();
|
||||
endPickerDate.Value = appointment.End.ToLocalTime().Date;
|
||||
endPickerTime.Value = appointment.End.ToLocalTime();
|
||||
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
private bool ValidateForm()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(titleTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(descriptionTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(locationTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(contactTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(textBoxUrl.Text) ||
|
||||
typeComboBox.SelectedIndex == -1 ||
|
||||
customerComboBox.SelectedIndex == -1)
|
||||
{
|
||||
MessageBox.Show("All fields must be filled out.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
DateTime start = startPickerDate.Value.Date.Add(startPickerTime.Value.TimeOfDay).ToUniversalTime();
|
||||
DateTime end = endPickerDate.Value.Date.Add(endPickerTime.Value.TimeOfDay).ToUniversalTime();
|
||||
|
||||
if (start >= end)
|
||||
{
|
||||
MessageBox.Show("Start time must be before end time.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
TimeZoneInfo estZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||
DateTime startEST = TimeZoneInfo.ConvertTimeFromUtc(start, estZone);
|
||||
DateTime endEST = TimeZoneInfo.ConvertTimeFromUtc(end, estZone);
|
||||
|
||||
if (startEST.Hour < 9 || endEST.Hour > 17 || startEST.DayOfWeek == DayOfWeek.Saturday || startEST.DayOfWeek == DayOfWeek.Sunday)
|
||||
{
|
||||
MessageBox.Show("Appointments must be scheduled during business hours (9:00 AM - 5:00 PM EST, Monday-Friday).", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
var appointments = DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId);
|
||||
foreach (var appt in appointments)
|
||||
{
|
||||
if (_currentAppointment == null || appt.AppointmentId != _currentAppointment.AppointmentId)
|
||||
{
|
||||
if (start < appt.End && end > appt.Start)
|
||||
{
|
||||
MessageBox.Show("Appointment times cannot overlap with existing appointments.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SaveButton_Click(object? sender, EventArgs e)
|
||||
{
|
||||
if (!ValidateForm())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var selectedCustomer = (Customer)customerComboBox.SelectedItem!;
|
||||
var appointment = new Appointment
|
||||
{
|
||||
AppointmentId = _currentAppointment?.AppointmentId ?? 0,
|
||||
CustomerId = selectedCustomer.CustomerId,
|
||||
UserId = AppState.CurrentUser.UserId,
|
||||
Title = titleTextBox.Text.Trim(),
|
||||
Description = descriptionTextBox.Text.Trim(),
|
||||
Location = locationTextBox.Text.Trim(),
|
||||
Contact = contactTextBox.Text.Trim(),
|
||||
AppointmentType = typeComboBox.SelectedItem!.ToString()!,
|
||||
Url = textBoxUrl.Text.Trim(),
|
||||
Start = startPickerDate.Value.Date.Add(startPickerTime.Value.TimeOfDay).ToUniversalTime(),
|
||||
End = endPickerDate.Value.Date.Add(endPickerTime.Value.TimeOfDay).ToUniversalTime(),
|
||||
CreateDate = DateTime.UtcNow,
|
||||
CreatedBy = AppState.CurrentUser.Username,
|
||||
LastUpdate = DateTime.UtcNow,
|
||||
LastUpdateBy = AppState.CurrentUser.Username
|
||||
};
|
||||
|
||||
if (_currentAppointment == null)
|
||||
{
|
||||
DatabaseHelper.AddAppointment(appointment);
|
||||
MessageBox.Show("Appointment added successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
DatabaseHelper.UpdateAppointment(appointment);
|
||||
MessageBox.Show("Appointment updated successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
UpdateAppointmentsList?.Invoke(this, EventArgs.Empty);
|
||||
Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"An error occurred while saving the appointment:\n{ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
123
C969Project/Forms/AddOrUpdateAppointmentForm.resx
Normal file
123
C969Project/Forms/AddOrUpdateAppointmentForm.resx
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
244
C969Project/Forms/AddUpdateCustomerForm.Designer.cs
generated
Normal file
244
C969Project/Forms/AddUpdateCustomerForm.Designer.cs
generated
Normal file
@@ -0,0 +1,244 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class AddUpdateCustomerForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
saveButton = new System.Windows.Forms.Button();
|
||||
cancelButton = new System.Windows.Forms.Button();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
nameTextBox = new System.Windows.Forms.TextBox();
|
||||
phoneTextBox = new System.Windows.Forms.TextBox();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
addressTextBox = new System.Windows.Forms.TextBox();
|
||||
label4 = new System.Windows.Forms.Label();
|
||||
label5 = new System.Windows.Forms.Label();
|
||||
label6 = new System.Windows.Forms.Label();
|
||||
cityTextBox = new System.Windows.Forms.TextBox();
|
||||
label7 = new System.Windows.Forms.Label();
|
||||
zipTextBox = new System.Windows.Forms.TextBox();
|
||||
label8 = new System.Windows.Forms.Label();
|
||||
countryTextBox = new System.Windows.Forms.TextBox();
|
||||
SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label1.Location = new System.Drawing.Point(12, 9);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(776, 23);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "Add Customer";
|
||||
label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// saveButton
|
||||
//
|
||||
saveButton.Location = new System.Drawing.Point(632, 415);
|
||||
saveButton.Name = "saveButton";
|
||||
saveButton.Size = new System.Drawing.Size(75, 23);
|
||||
saveButton.TabIndex = 1;
|
||||
saveButton.Text = "Save";
|
||||
saveButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cancelButton
|
||||
//
|
||||
cancelButton.Location = new System.Drawing.Point(713, 415);
|
||||
cancelButton.Name = "cancelButton";
|
||||
cancelButton.Size = new System.Drawing.Size(75, 23);
|
||||
cancelButton.TabIndex = 2;
|
||||
cancelButton.Text = "Cancel";
|
||||
cancelButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, ((System.Drawing.FontStyle)(System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)), System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label2.Location = new System.Drawing.Point(12, 61);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(332, 23);
|
||||
label2.TabIndex = 3;
|
||||
label2.Text = "Name";
|
||||
label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
nameTextBox.Location = new System.Drawing.Point(12, 87);
|
||||
nameTextBox.Name = "nameTextBox";
|
||||
nameTextBox.Size = new System.Drawing.Size(332, 23);
|
||||
nameTextBox.TabIndex = 4;
|
||||
//
|
||||
// phoneTextBox
|
||||
//
|
||||
phoneTextBox.Location = new System.Drawing.Point(12, 144);
|
||||
phoneTextBox.Name = "phoneTextBox";
|
||||
phoneTextBox.Size = new System.Drawing.Size(332, 23);
|
||||
phoneTextBox.TabIndex = 6;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, ((System.Drawing.FontStyle)(System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)), System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label3.Location = new System.Drawing.Point(12, 118);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(332, 23);
|
||||
label3.TabIndex = 5;
|
||||
label3.Text = "Phone";
|
||||
label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// addressTextBox
|
||||
//
|
||||
addressTextBox.Location = new System.Drawing.Point(12, 212);
|
||||
addressTextBox.Name = "addressTextBox";
|
||||
addressTextBox.Size = new System.Drawing.Size(218, 23);
|
||||
addressTextBox.TabIndex = 8;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, ((System.Drawing.FontStyle)(System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Italic)), System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label4.Location = new System.Drawing.Point(12, 186);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new System.Drawing.Size(332, 23);
|
||||
label4.TabIndex = 7;
|
||||
label4.Text = "Address";
|
||||
label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
label5.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label5.Location = new System.Drawing.Point(236, 212);
|
||||
label5.Name = "label5";
|
||||
label5.Size = new System.Drawing.Size(63, 23);
|
||||
label5.TabIndex = 9;
|
||||
label5.Text = "Address";
|
||||
label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
label6.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label6.Location = new System.Drawing.Point(236, 241);
|
||||
label6.Name = "label6";
|
||||
label6.Size = new System.Drawing.Size(63, 23);
|
||||
label6.TabIndex = 11;
|
||||
label6.Text = "City";
|
||||
label6.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// cityTextBox
|
||||
//
|
||||
cityTextBox.Location = new System.Drawing.Point(12, 241);
|
||||
cityTextBox.Name = "cityTextBox";
|
||||
cityTextBox.Size = new System.Drawing.Size(218, 23);
|
||||
cityTextBox.TabIndex = 10;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
label7.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label7.Location = new System.Drawing.Point(236, 270);
|
||||
label7.Name = "label7";
|
||||
label7.Size = new System.Drawing.Size(63, 23);
|
||||
label7.TabIndex = 13;
|
||||
label7.Text = "Zip code";
|
||||
label7.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// zipTextBox
|
||||
//
|
||||
zipTextBox.Location = new System.Drawing.Point(12, 270);
|
||||
zipTextBox.Name = "zipTextBox";
|
||||
zipTextBox.Size = new System.Drawing.Size(218, 23);
|
||||
zipTextBox.TabIndex = 12;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
label8.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)0));
|
||||
label8.Location = new System.Drawing.Point(236, 299);
|
||||
label8.Name = "label8";
|
||||
label8.Size = new System.Drawing.Size(63, 23);
|
||||
label8.TabIndex = 15;
|
||||
label8.Text = "Country";
|
||||
label8.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// countryTextBox
|
||||
//
|
||||
countryTextBox.Location = new System.Drawing.Point(12, 299);
|
||||
countryTextBox.Name = "countryTextBox";
|
||||
countryTextBox.Size = new System.Drawing.Size(218, 23);
|
||||
countryTextBox.TabIndex = 14;
|
||||
countryTextBox.Text = "US";
|
||||
//
|
||||
// AddUpdateCustomerForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
BackColor = System.Drawing.SystemColors.Control;
|
||||
ClientSize = new System.Drawing.Size(800, 450);
|
||||
Controls.Add(label8);
|
||||
Controls.Add(countryTextBox);
|
||||
Controls.Add(label7);
|
||||
Controls.Add(zipTextBox);
|
||||
Controls.Add(label6);
|
||||
Controls.Add(cityTextBox);
|
||||
Controls.Add(label5);
|
||||
Controls.Add(addressTextBox);
|
||||
Controls.Add(label4);
|
||||
Controls.Add(phoneTextBox);
|
||||
Controls.Add(label3);
|
||||
Controls.Add(nameTextBox);
|
||||
Controls.Add(label2);
|
||||
Controls.Add(cancelButton);
|
||||
Controls.Add(saveButton);
|
||||
Controls.Add(label1);
|
||||
Location = new System.Drawing.Point(15, 15);
|
||||
Text = "Add Customer";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.TextBox countryTextBox;
|
||||
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.TextBox cityTextBox;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.TextBox zipTextBox;
|
||||
|
||||
private System.Windows.Forms.Label label5;
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.TextBox phoneTextBox;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox addressTextBox;
|
||||
private System.Windows.Forms.Label label4;
|
||||
|
||||
private System.Windows.Forms.Button saveButton;
|
||||
private System.Windows.Forms.Button cancelButton;
|
||||
private System.Windows.Forms.Label label2;
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
|
||||
#endregion
|
||||
}
|
||||
197
C969Project/Forms/AddUpdateCustomerForm.cs
Normal file
197
C969Project/Forms/AddUpdateCustomerForm.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project
|
||||
{
|
||||
public partial class AddUpdateCustomerForm : Form
|
||||
{
|
||||
private Customer? _currentCustomer;
|
||||
|
||||
public event EventHandler UpdateCustomersList;
|
||||
|
||||
public AddUpdateCustomerForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
saveButton.Click += SaveButton_Click;
|
||||
cancelButton.Click += CancelButton_Click;
|
||||
}
|
||||
|
||||
public void InitAdd()
|
||||
{
|
||||
Text = "Add Customer";
|
||||
label1.Text = "Add Customer";
|
||||
|
||||
nameTextBox.Text = string.Empty;
|
||||
addressTextBox.Text = string.Empty;
|
||||
cityTextBox.Text = string.Empty;
|
||||
zipTextBox.Text = string.Empty;
|
||||
phoneTextBox.Text = string.Empty;
|
||||
_currentCustomer = null;
|
||||
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
public void InitUpdate(Customer customer)
|
||||
{
|
||||
Text = "Update Customer";
|
||||
label1.Text = "Update Customer";
|
||||
|
||||
_currentCustomer = customer;
|
||||
|
||||
nameTextBox.Text = customer.CustomerName;
|
||||
var addr = DatabaseHelper.RetrieveAddress(customer.AddressId);
|
||||
if (addr != null)
|
||||
{
|
||||
addressTextBox.Text = addr.Address1;
|
||||
var city = DatabaseHelper.RetrieveCity(addr.CityId);
|
||||
if (city != null)
|
||||
{
|
||||
cityTextBox.Text = city.CityName;
|
||||
}
|
||||
zipTextBox.Text = addr.PostalCode;
|
||||
phoneTextBox.Text = addr.Phone;
|
||||
}
|
||||
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
private void SaveButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(nameTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(addressTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(cityTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(zipTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(phoneTextBox.Text) ||
|
||||
string.IsNullOrWhiteSpace(countryTextBox.Text))
|
||||
{
|
||||
MessageBox.Show("All fields must be filled out.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!System.Text.RegularExpressions.Regex.IsMatch(phoneTextBox.Text.Trim(), @"^[\d-]+$"))
|
||||
{
|
||||
MessageBox.Show("Phone number can only contain digits and dashes.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
string currentUser = AppState.CurrentUser.Username;
|
||||
|
||||
try
|
||||
{
|
||||
string countryName = countryTextBox.Text;
|
||||
int currentCountryId = DatabaseHelper.GetCountryId(countryName);
|
||||
if (currentCountryId == 0)
|
||||
{
|
||||
Country newCountry = new Country
|
||||
{
|
||||
CountryName = countryName,
|
||||
CreateDate = DateTime.UtcNow,
|
||||
CreatedBy = currentUser,
|
||||
LastUpdate = DateTime.UtcNow,
|
||||
LastUpdateBy = currentUser
|
||||
};
|
||||
currentCountryId = DatabaseHelper.AddCountry(newCountry);
|
||||
}
|
||||
|
||||
int currentCityId = DatabaseHelper.GetCityId(cityTextBox.Text.Trim(), currentCountryId);
|
||||
if (currentCityId == 0)
|
||||
{
|
||||
City newCity = new City
|
||||
{
|
||||
CityName = cityTextBox.Text.Trim(),
|
||||
CountryID = currentCountryId,
|
||||
CreateDate = DateTime.UtcNow,
|
||||
CreatedBy = currentUser,
|
||||
LastUpdate = DateTime.UtcNow,
|
||||
LastUpdateBy = currentUser
|
||||
};
|
||||
currentCityId = DatabaseHelper.AddCity(newCity);
|
||||
}
|
||||
|
||||
Address addressToSave;
|
||||
int finalAddressId;
|
||||
|
||||
if (Text == "Add Customer")
|
||||
{
|
||||
addressToSave = new Address
|
||||
{
|
||||
Address1 = addressTextBox.Text.Trim(),
|
||||
Address2 = "",
|
||||
CityId = currentCityId,
|
||||
PostalCode = zipTextBox.Text.Trim(),
|
||||
Phone = phoneTextBox.Text.Trim(),
|
||||
CreateDate = DateTime.UtcNow,
|
||||
CreatedBy = currentUser,
|
||||
LastUpdate = DateTime.UtcNow,
|
||||
LastUpdateBy = currentUser
|
||||
};
|
||||
finalAddressId = DatabaseHelper.AddAddress(addressToSave);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address? existingAddress = DatabaseHelper.RetrieveAddress(_currentCustomer.AddressId);
|
||||
if (existingAddress == null)
|
||||
{
|
||||
MessageBox.Show("Could not find existing address for update.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
addressToSave = existingAddress;
|
||||
addressToSave.Address1 = addressTextBox.Text.Trim();
|
||||
addressToSave.Address2 = "";
|
||||
addressToSave.CityId = currentCityId;
|
||||
addressToSave.PostalCode = zipTextBox.Text.Trim();
|
||||
addressToSave.Phone = phoneTextBox.Text.Trim();
|
||||
addressToSave.LastUpdateBy = currentUser;
|
||||
|
||||
DatabaseHelper.UpdateAddress(addressToSave);
|
||||
finalAddressId = addressToSave.Id;
|
||||
}
|
||||
|
||||
Customer customerToSave;
|
||||
if (Text == "Add Customer")
|
||||
{
|
||||
customerToSave = new Customer
|
||||
{
|
||||
CustomerName = nameTextBox.Text.Trim(),
|
||||
AddressId = finalAddressId,
|
||||
Active = 1,
|
||||
CreateDate = DateTime.UtcNow,
|
||||
CreatedBy = currentUser,
|
||||
LastUpdate = DateTime.UtcNow,
|
||||
LastUpdateBy = currentUser
|
||||
};
|
||||
DatabaseHelper.AddCustomer(customerToSave);
|
||||
}
|
||||
else
|
||||
{
|
||||
customerToSave = _currentCustomer;
|
||||
customerToSave.CustomerName = nameTextBox.Text.Trim();
|
||||
customerToSave.AddressId = finalAddressId;
|
||||
customerToSave.LastUpdateBy = currentUser;
|
||||
|
||||
DatabaseHelper.UpdateCustomer(customerToSave);
|
||||
}
|
||||
|
||||
MessageBox.Show("Customer saved successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// TODO: Implement robust exception handling, logging, and user notification as per assignment A2b
|
||||
MessageBox.Show($"An error occurred while saving the customer: {ex.Message}", "Database Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
UpdateCustomersList?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void CancelButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
201
C969Project/Forms/AppointmentsForm.Designer.cs
generated
Normal file
201
C969Project/Forms/AppointmentsForm.Designer.cs
generated
Normal file
@@ -0,0 +1,201 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class AppointmentsForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
appointmentDataView = new System.Windows.Forms.DataGridView();
|
||||
calendar = new System.Windows.Forms.MonthCalendar();
|
||||
addButton = new System.Windows.Forms.Button();
|
||||
modifyButton = new System.Windows.Forms.Button();
|
||||
deleteButton = new System.Windows.Forms.Button();
|
||||
showAllButton = new System.Windows.Forms.Button();
|
||||
appointmentDetails = new System.Windows.Forms.GroupBox();
|
||||
endTimeLabel = new System.Windows.Forms.Label();
|
||||
startTimeLabel = new System.Windows.Forms.Label();
|
||||
withLabel = new System.Windows.Forms.Label();
|
||||
apptTypeLabel = new System.Windows.Forms.Label();
|
||||
apptTitleLabel = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)appointmentDataView).BeginInit();
|
||||
appointmentDetails.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// appointmentDataView
|
||||
//
|
||||
appointmentDataView.AllowUserToAddRows = false;
|
||||
appointmentDataView.AllowUserToDeleteRows = false;
|
||||
appointmentDataView.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right));
|
||||
appointmentDataView.Location = new System.Drawing.Point(12, 11);
|
||||
appointmentDataView.Name = "appointmentDataView";
|
||||
appointmentDataView.ReadOnly = true;
|
||||
appointmentDataView.Size = new System.Drawing.Size(739, 523);
|
||||
appointmentDataView.TabIndex = 0;
|
||||
//
|
||||
// calendar
|
||||
//
|
||||
calendar.Anchor = ((System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
|
||||
calendar.Location = new System.Drawing.Point(773, 11);
|
||||
calendar.Name = "calendar";
|
||||
calendar.TabIndex = 1;
|
||||
//
|
||||
// addButton
|
||||
//
|
||||
addButton.Location = new System.Drawing.Point(12, 540);
|
||||
addButton.Name = "addButton";
|
||||
addButton.Size = new System.Drawing.Size(75, 23);
|
||||
addButton.TabIndex = 2;
|
||||
addButton.Text = "Add";
|
||||
addButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// modifyButton
|
||||
//
|
||||
modifyButton.Location = new System.Drawing.Point(93, 540);
|
||||
modifyButton.Name = "modifyButton";
|
||||
modifyButton.Size = new System.Drawing.Size(75, 23);
|
||||
modifyButton.TabIndex = 3;
|
||||
modifyButton.Text = "Modify";
|
||||
modifyButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// deleteButton
|
||||
//
|
||||
deleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
|
||||
deleteButton.Location = new System.Drawing.Point(676, 540);
|
||||
deleteButton.Name = "deleteButton";
|
||||
deleteButton.Size = new System.Drawing.Size(75, 23);
|
||||
deleteButton.TabIndex = 4;
|
||||
deleteButton.Text = "Delete";
|
||||
deleteButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// showAllButton
|
||||
//
|
||||
showAllButton.Anchor = ((System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right));
|
||||
showAllButton.Location = new System.Drawing.Point(773, 185);
|
||||
showAllButton.Name = "showAllButton";
|
||||
showAllButton.Size = new System.Drawing.Size(227, 23);
|
||||
showAllButton.TabIndex = 5;
|
||||
showAllButton.Text = "Show All Appointments";
|
||||
showAllButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// appointmentDetails
|
||||
//
|
||||
appointmentDetails.Controls.Add(endTimeLabel);
|
||||
appointmentDetails.Controls.Add(startTimeLabel);
|
||||
appointmentDetails.Controls.Add(withLabel);
|
||||
appointmentDetails.Controls.Add(apptTypeLabel);
|
||||
appointmentDetails.Controls.Add(apptTitleLabel);
|
||||
appointmentDetails.Location = new System.Drawing.Point(773, 214);
|
||||
appointmentDetails.Name = "appointmentDetails";
|
||||
appointmentDetails.Size = new System.Drawing.Size(223, 320);
|
||||
appointmentDetails.TabIndex = 6;
|
||||
appointmentDetails.TabStop = false;
|
||||
appointmentDetails.Text = "Details";
|
||||
//
|
||||
// endTimeLabel
|
||||
//
|
||||
endTimeLabel.Location = new System.Drawing.Point(6, 111);
|
||||
endTimeLabel.Name = "endTimeLabel";
|
||||
endTimeLabel.Size = new System.Drawing.Size(211, 23);
|
||||
endTimeLabel.TabIndex = 4;
|
||||
endTimeLabel.Text = "End: ";
|
||||
endTimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// startTimeLabel
|
||||
//
|
||||
startTimeLabel.Location = new System.Drawing.Point(6, 88);
|
||||
startTimeLabel.Name = "startTimeLabel";
|
||||
startTimeLabel.Size = new System.Drawing.Size(211, 23);
|
||||
startTimeLabel.TabIndex = 3;
|
||||
startTimeLabel.Text = "Start: ";
|
||||
startTimeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// withLabel
|
||||
//
|
||||
withLabel.Location = new System.Drawing.Point(6, 65);
|
||||
withLabel.Name = "withLabel";
|
||||
withLabel.Size = new System.Drawing.Size(211, 23);
|
||||
withLabel.TabIndex = 2;
|
||||
withLabel.Text = "With: ";
|
||||
withLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// apptTypeLabel
|
||||
//
|
||||
apptTypeLabel.Location = new System.Drawing.Point(6, 42);
|
||||
apptTypeLabel.Name = "apptTypeLabel";
|
||||
apptTypeLabel.Size = new System.Drawing.Size(211, 23);
|
||||
apptTypeLabel.TabIndex = 1;
|
||||
apptTypeLabel.Text = "Type: ";
|
||||
apptTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// apptTitleLabel
|
||||
//
|
||||
apptTitleLabel.Location = new System.Drawing.Point(6, 19);
|
||||
apptTitleLabel.Name = "apptTitleLabel";
|
||||
apptTitleLabel.Size = new System.Drawing.Size(211, 23);
|
||||
apptTitleLabel.TabIndex = 0;
|
||||
apptTitleLabel.Text = "Title: ";
|
||||
apptTitleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// AppointmentsForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(1008, 575);
|
||||
Controls.Add(appointmentDetails);
|
||||
Controls.Add(showAllButton);
|
||||
Controls.Add(deleteButton);
|
||||
Controls.Add(modifyButton);
|
||||
Controls.Add(addButton);
|
||||
Controls.Add(calendar);
|
||||
Controls.Add(appointmentDataView);
|
||||
Text = "AppointmentsForm";
|
||||
((System.ComponentModel.ISupportInitialize)appointmentDataView).EndInit();
|
||||
appointmentDetails.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label apptTypeLabel;
|
||||
private System.Windows.Forms.Label withLabel;
|
||||
private System.Windows.Forms.Label startTimeLabel;
|
||||
private System.Windows.Forms.Label endTimeLabel;
|
||||
|
||||
private System.Windows.Forms.Label apptTitleLabel;
|
||||
|
||||
private System.Windows.Forms.GroupBox appointmentDetails;
|
||||
|
||||
private System.Windows.Forms.Button showAllButton;
|
||||
|
||||
private System.Windows.Forms.DataGridView appointmentDataView;
|
||||
private System.Windows.Forms.MonthCalendar calendar;
|
||||
private System.Windows.Forms.Button addButton;
|
||||
private System.Windows.Forms.Button modifyButton;
|
||||
private System.Windows.Forms.Button deleteButton;
|
||||
|
||||
#endregion
|
||||
}
|
||||
93
C969Project/Forms/AppointmentsForm.cs
Normal file
93
C969Project/Forms/AppointmentsForm.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
public partial class AppointmentsForm : Form
|
||||
{
|
||||
private List<Appointment> _appointments = new();
|
||||
private AddOrUpdateAppointmentForm _addOrUpdateAppointmentForm = new();
|
||||
|
||||
public AppointmentsForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
UpdateAppointmentsList(null, EventArgs.Empty);
|
||||
|
||||
Shown += UpdateAppointmentsList;
|
||||
_addOrUpdateAppointmentForm.UpdateAppointmentsList += UpdateAppointmentsList;
|
||||
|
||||
calendar.DateSelected += ShowAppointmentsFromSelectedDay;
|
||||
showAllButton.Click += UpdateAppointmentsList;
|
||||
deleteButton.Click += DeleteButtonOnClick;
|
||||
addButton.Click += AddButtonOnClick;
|
||||
modifyButton.Click += ModifyButtonOnClick;
|
||||
|
||||
appointmentDataView.SelectionChanged += UpdateAppointmentDetails;
|
||||
}
|
||||
|
||||
private void ModifyButtonOnClick(object? sender, EventArgs e)
|
||||
{
|
||||
if (appointmentDataView.CurrentRow?.DataBoundItem is Appointment selectedAppointment)
|
||||
{
|
||||
_addOrUpdateAppointmentForm.InitUpdate(selectedAppointment);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Error while trying to modify appointment");
|
||||
}
|
||||
}
|
||||
|
||||
private void AddButtonOnClick(object? sender, EventArgs e)
|
||||
{
|
||||
_addOrUpdateAppointmentForm.InitAdd();
|
||||
}
|
||||
|
||||
private void DeleteButtonOnClick(object? sender, EventArgs e)
|
||||
{
|
||||
Appointment? selectedAppointment;
|
||||
if (appointmentDataView.CurrentRow?.DataBoundItem is Appointment appointment)
|
||||
{
|
||||
selectedAppointment = appointment;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Error while trying to delete appointment");
|
||||
return;
|
||||
}
|
||||
|
||||
var result = MessageBox.Show("Are you sure you want to delete this appointment?", "Delete Appointment?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
DatabaseHelper.DeleteAppointment(selectedAppointment);
|
||||
UpdateAppointmentsList(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAppointmentsList(object? sender, EventArgs e)
|
||||
{
|
||||
appointmentDataView.DataSource = null;
|
||||
_appointments.Clear();
|
||||
_appointments.AddRange(DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId));
|
||||
appointmentDataView.DataSource = _appointments;
|
||||
}
|
||||
|
||||
private void ShowAppointmentsFromSelectedDay(object? sender, EventArgs e)
|
||||
{
|
||||
var startDate = calendar.SelectionStart.ToUniversalTime();
|
||||
var selectedDate = startDate.Date;
|
||||
List<Appointment>? selectedAppointments = _appointments.Where(a => a.Start.Date == selectedDate).ToList();
|
||||
appointmentDataView.DataSource = selectedAppointments?.Count > 0 ? selectedAppointments : null;
|
||||
}
|
||||
|
||||
private void UpdateAppointmentDetails(object? sender, EventArgs e)
|
||||
{
|
||||
if (appointmentDataView.CurrentRow?.DataBoundItem is Appointment appointment)
|
||||
{
|
||||
apptTitleLabel.Text = $"Title: {appointment.Title}";
|
||||
apptTypeLabel.Text = $"Type: {appointment.AppointmentType}";
|
||||
withLabel.Text = $"With: {DatabaseHelper.RetrieveCustomer(appointment.CustomerId)?.CustomerName ?? "Unknown"}";
|
||||
startTimeLabel.Text = $"Start: {appointment.Start.ToLocalTime():MM/dd/yyyy hh:mm tt} {TimeZoneInfo.Local.Id}";
|
||||
endTimeLabel.Text = $"End: {appointment.End.ToLocalTime():MM/dd/yyyy hh:mm tt} {TimeZoneInfo.Local.Id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
101
C969Project/Forms/CustomersForm.Designer.cs
generated
Normal file
101
C969Project/Forms/CustomersForm.Designer.cs
generated
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class CustomersForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
CustomersDataGrid = new System.Windows.Forms.DataGridView();
|
||||
AddButton = new System.Windows.Forms.Button();
|
||||
ModifyButton = new System.Windows.Forms.Button();
|
||||
DeleteButton = new System.Windows.Forms.Button();
|
||||
((System.ComponentModel.ISupportInitialize)CustomersDataGrid).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// CustomersDataGrid
|
||||
//
|
||||
CustomersDataGrid.AllowUserToAddRows = false;
|
||||
CustomersDataGrid.AllowUserToDeleteRows = false;
|
||||
CustomersDataGrid.AllowUserToOrderColumns = true;
|
||||
CustomersDataGrid.Location = new System.Drawing.Point(12, 12);
|
||||
CustomersDataGrid.Name = "CustomersDataGrid";
|
||||
CustomersDataGrid.ReadOnly = true;
|
||||
CustomersDataGrid.Size = new System.Drawing.Size(873, 430);
|
||||
CustomersDataGrid.TabIndex = 0;
|
||||
//
|
||||
// AddButton
|
||||
//
|
||||
AddButton.Location = new System.Drawing.Point(12, 448);
|
||||
AddButton.Name = "AddButton";
|
||||
AddButton.Size = new System.Drawing.Size(75, 23);
|
||||
AddButton.TabIndex = 1;
|
||||
AddButton.Text = "Add";
|
||||
AddButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ModifyButton
|
||||
//
|
||||
ModifyButton.Location = new System.Drawing.Point(93, 448);
|
||||
ModifyButton.Name = "ModifyButton";
|
||||
ModifyButton.Size = new System.Drawing.Size(75, 23);
|
||||
ModifyButton.TabIndex = 2;
|
||||
ModifyButton.Text = "Modify";
|
||||
ModifyButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DeleteButton
|
||||
//
|
||||
DeleteButton.Location = new System.Drawing.Point(810, 448);
|
||||
DeleteButton.Name = "DeleteButton";
|
||||
DeleteButton.Size = new System.Drawing.Size(75, 23);
|
||||
DeleteButton.TabIndex = 3;
|
||||
DeleteButton.Text = "Delete";
|
||||
DeleteButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RecordsForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(897, 569);
|
||||
Controls.Add(DeleteButton);
|
||||
Controls.Add(ModifyButton);
|
||||
Controls.Add(AddButton);
|
||||
Controls.Add(CustomersDataGrid);
|
||||
Text = "Records";
|
||||
((System.ComponentModel.ISupportInitialize)CustomersDataGrid).EndInit();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Button ModifyButton;
|
||||
private System.Windows.Forms.Button DeleteButton;
|
||||
|
||||
private System.Windows.Forms.Button AddButton;
|
||||
|
||||
private System.Windows.Forms.DataGridView CustomersDataGrid;
|
||||
|
||||
#endregion
|
||||
}
|
||||
58
C969Project/Forms/CustomersForm.cs
Normal file
58
C969Project/Forms/CustomersForm.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
public partial class CustomersForm : Form
|
||||
{
|
||||
private List<Customer>? _customers;
|
||||
private AddUpdateCustomerForm _form = new();
|
||||
|
||||
public CustomersForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
UpdateCustomersList(null, EventArgs.Empty);
|
||||
|
||||
Shown += UpdateCustomersList;
|
||||
|
||||
_form.UpdateCustomersList += UpdateCustomersList;
|
||||
|
||||
AddButton.Click += (sender, args) =>
|
||||
{
|
||||
_form.InitAdd();
|
||||
};
|
||||
|
||||
ModifyButton.Click += (sender, args) =>
|
||||
{
|
||||
if (_customers is null) return;
|
||||
var selectedCustomer = _customers[CustomersDataGrid.CurrentCell.RowIndex];
|
||||
_form.InitUpdate(selectedCustomer);
|
||||
};
|
||||
|
||||
DeleteButton.Click += (sender, args) =>
|
||||
{
|
||||
if (CustomersDataGrid.CurrentCell is null || CustomersDataGrid.CurrentCell.RowIndex > _customers?.Count)
|
||||
{
|
||||
MessageBox.Show("Please select a customer to delete");
|
||||
return;
|
||||
}
|
||||
|
||||
var selectedCustomer = _customers?[CustomersDataGrid.CurrentCell.RowIndex];
|
||||
|
||||
var result = MessageBox.Show("Are you sure you want to delete this record?", "Delete Record", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
_customers.Remove(selectedCustomer);
|
||||
DatabaseHelper.DeleteCustomer(selectedCustomer);
|
||||
UpdateCustomersList(null, EventArgs.Empty);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateCustomersList(object? sender, EventArgs args)
|
||||
{
|
||||
if (_customers != null && _customers.Count > 0) _customers.Clear();
|
||||
_customers = DatabaseHelper.RetrieveCustomers();
|
||||
CustomersDataGrid.DataSource = _customers;
|
||||
}
|
||||
}
|
||||
64
C969Project/Forms/CustomersForm.resx
Normal file
64
C969Project/Forms/CustomersForm.resx
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.Locked" type="System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
97
C969Project/Forms/DashboardForm.Designer.cs
generated
Normal file
97
C969Project/Forms/DashboardForm.Designer.cs
generated
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class DashboardForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
CustomersButton = new System.Windows.Forms.Button();
|
||||
AppointmentsButton = new System.Windows.Forms.Button();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
ReportsButton = new System.Windows.Forms.Button();
|
||||
SuspendLayout();
|
||||
//
|
||||
// CustomersButton
|
||||
//
|
||||
CustomersButton.Location = new System.Drawing.Point(339, 185);
|
||||
CustomersButton.Name = "CustomersButton";
|
||||
CustomersButton.Size = new System.Drawing.Size(100, 100);
|
||||
CustomersButton.TabIndex = 0;
|
||||
CustomersButton.Text = "Customers";
|
||||
CustomersButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// AppointmentsButton
|
||||
//
|
||||
AppointmentsButton.Location = new System.Drawing.Point(445, 185);
|
||||
AppointmentsButton.Name = "AppointmentsButton";
|
||||
AppointmentsButton.Size = new System.Drawing.Size(100, 100);
|
||||
AppointmentsButton.TabIndex = 1;
|
||||
AppointmentsButton.Text = "Appointments";
|
||||
AppointmentsButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Font = new System.Drawing.Font("Segoe UI", 15F);
|
||||
label1.Location = new System.Drawing.Point(332, 116);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(113, 40);
|
||||
label1.TabIndex = 4;
|
||||
label1.Text = "Dashboard";
|
||||
label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// ReportsButton
|
||||
//
|
||||
ReportsButton.Location = new System.Drawing.Point(233, 185);
|
||||
ReportsButton.Name = "ReportsButton";
|
||||
ReportsButton.Size = new System.Drawing.Size(100, 100);
|
||||
ReportsButton.TabIndex = 2;
|
||||
ReportsButton.Text = "Reports";
|
||||
ReportsButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// DashboardForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(800, 450);
|
||||
Controls.Add(label1);
|
||||
Controls.Add(CustomersButton);
|
||||
Controls.Add(AppointmentsButton);
|
||||
Controls.Add(ReportsButton);
|
||||
Text = "DashboardForm";
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
|
||||
private System.Windows.Forms.Button CustomersButton;
|
||||
private System.Windows.Forms.Button AppointmentsButton;
|
||||
private System.Windows.Forms.Button ReportsButton;
|
||||
|
||||
#endregion
|
||||
}
|
||||
29
C969Project/Forms/DashboardForm.cs
Normal file
29
C969Project/Forms/DashboardForm.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace C969Project;
|
||||
|
||||
public partial class DashboardForm : Form
|
||||
{
|
||||
private CustomersForm _customersForm = new();
|
||||
private AppointmentsForm _appointmentsForm = new();
|
||||
private ReportsForm _reportsForm = new();
|
||||
|
||||
public DashboardForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
CustomersButton.Click += (sender, args) =>
|
||||
{
|
||||
_customersForm.ShowDialog();
|
||||
_customersForm.UpdateCustomersList(null, EventArgs.Empty);
|
||||
};
|
||||
|
||||
AppointmentsButton.Click += (sender, args) =>
|
||||
{
|
||||
_appointmentsForm.ShowDialog();
|
||||
};
|
||||
|
||||
ReportsButton.Click += (sender, args) =>
|
||||
{
|
||||
_reportsForm.ShowDialog();
|
||||
};
|
||||
}
|
||||
}
|
||||
64
C969Project/Forms/DashboardForm.resx
Normal file
64
C969Project/Forms/DashboardForm.resx
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.Locked" type="System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
107
C969Project/Forms/LoginForm.Designer.cs
generated
Normal file
107
C969Project/Forms/LoginForm.Designer.cs
generated
Normal file
@@ -0,0 +1,107 @@
|
||||
namespace C969Project
|
||||
{
|
||||
partial class LoginForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
usernameTextBox = new System.Windows.Forms.TextBox();
|
||||
passwordTextBox = new System.Windows.Forms.TextBox();
|
||||
loginButton = new System.Windows.Forms.Button();
|
||||
panel1 = new System.Windows.Forms.Panel();
|
||||
loginLabel = new System.Windows.Forms.Label();
|
||||
panel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// usernameTextBox
|
||||
//
|
||||
usernameTextBox.Location = new System.Drawing.Point(241, 147);
|
||||
usernameTextBox.Name = "usernameTextBox";
|
||||
usernameTextBox.PlaceholderText = "Username";
|
||||
usernameTextBox.Size = new System.Drawing.Size(228, 23);
|
||||
usernameTextBox.TabIndex = 1;
|
||||
//
|
||||
// passwordTextBox
|
||||
//
|
||||
passwordTextBox.Location = new System.Drawing.Point(241, 205);
|
||||
passwordTextBox.Name = "passwordTextBox";
|
||||
passwordTextBox.PlaceholderText = "Password";
|
||||
passwordTextBox.Size = new System.Drawing.Size(228, 23);
|
||||
passwordTextBox.TabIndex = 2;
|
||||
//
|
||||
// loginButton
|
||||
//
|
||||
loginButton.Location = new System.Drawing.Point(241, 259);
|
||||
loginButton.Name = "loginButton";
|
||||
loginButton.Size = new System.Drawing.Size(228, 23);
|
||||
loginButton.TabIndex = 3;
|
||||
loginButton.Text = "Login";
|
||||
loginButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(loginLabel);
|
||||
panel1.Controls.Add(loginButton);
|
||||
panel1.Controls.Add(passwordTextBox);
|
||||
panel1.Controls.Add(usernameTextBox);
|
||||
panel1.Location = new System.Drawing.Point(12, 12);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Size = new System.Drawing.Size(776, 426);
|
||||
panel1.TabIndex = 0;
|
||||
//
|
||||
// loginLabel
|
||||
//
|
||||
loginLabel.Font = new System.Drawing.Font("Segoe UI", 10F);
|
||||
loginLabel.Location = new System.Drawing.Point(241, 99);
|
||||
loginLabel.Name = "loginLabel";
|
||||
loginLabel.Size = new System.Drawing.Size(228, 40);
|
||||
loginLabel.TabIndex = 4;
|
||||
loginLabel.Text = "Login";
|
||||
loginLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// LoginForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(800, 450);
|
||||
Controls.Add(panel1);
|
||||
Text = "Login";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label loginLabel;
|
||||
|
||||
private System.Windows.Forms.TextBox usernameTextBox;
|
||||
private System.Windows.Forms.TextBox passwordTextBox;
|
||||
private System.Windows.Forms.Button loginButton;
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
94
C969Project/Forms/LoginForm.cs
Normal file
94
C969Project/Forms/LoginForm.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project
|
||||
{
|
||||
public partial class LoginForm : Form
|
||||
{
|
||||
public LoginForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
loginLabel.Text = Localization.GetLocalization("login_text");
|
||||
usernameTextBox.PlaceholderText = Localization.GetLocalization("username_text");
|
||||
passwordTextBox.PlaceholderText = Localization.GetLocalization("password_text");
|
||||
loginButton.Text = Localization.GetLocalization("login_text");
|
||||
|
||||
loginButton.Enabled = false;
|
||||
usernameTextBox.TextChanged += (sender, args) => {UpdateLoginButtonState();};
|
||||
passwordTextBox.TextChanged += (sender, args) => {UpdateLoginButtonState();};
|
||||
loginButton.Click += LoginButtonOnClick;
|
||||
}
|
||||
|
||||
private void LoginButtonOnClick(object? sender, EventArgs e)
|
||||
{
|
||||
var usr = DatabaseHelper.Login(usernameTextBox.Text, passwordTextBox.Text);
|
||||
|
||||
if (usr is null)
|
||||
{
|
||||
MessageBox.Show(Localization.GetLocalization("login_error_message"), "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
LogHistory(usr);
|
||||
Console.WriteLine($"Login successful, {usr.Username}");
|
||||
AppState.CurrentUser = usr;
|
||||
|
||||
CheckForAppointments();
|
||||
|
||||
var dash = new DashboardForm();
|
||||
dash.FormClosing += (o, args) => { Close(); };
|
||||
dash.Show();
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void CheckForAppointments()
|
||||
{
|
||||
if (AppState.CurrentUser is null)
|
||||
{
|
||||
MessageBox.Show("A problem occured retrieving appointments.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
var appointments = DatabaseHelper.RetrieveAppointments(AppState.CurrentUser.UserId);
|
||||
|
||||
DateTime nowUtc = DateTime.UtcNow;
|
||||
DateTime fifteenMinutesFromNowUtc = nowUtc.AddMinutes(15);
|
||||
|
||||
var upcoming = appointments
|
||||
.Where(a => a.Start >= nowUtc && a.Start <= fifteenMinutesFromNowUtc)
|
||||
.OrderBy(a => a.Start)
|
||||
.ToList();
|
||||
|
||||
if (upcoming.Any())
|
||||
{
|
||||
var appt = upcoming.First();
|
||||
DateTime localStart = appt.Start.ToLocalTime();
|
||||
MessageBox.Show(
|
||||
$"You have an upcoming {appt.AppointmentType} appointment '{appt.Title}' at {localStart}.",
|
||||
"Upcoming Appointment",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLoginButtonState()
|
||||
{
|
||||
if (string.IsNullOrEmpty(usernameTextBox.Text) || string.IsNullOrEmpty(passwordTextBox.Text))
|
||||
{
|
||||
loginButton.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
loginButton.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void LogHistory(User user)
|
||||
{
|
||||
string text = $"{DateTime.UtcNow} UTC : {user.Username}";
|
||||
using StreamWriter sw = new StreamWriter("Login_History.txt", true);
|
||||
sw.WriteLine(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
C969Project/Forms/LoginForm.resx
Normal file
64
C969Project/Forms/LoginForm.resx
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.Locked" type="System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
195
C969Project/Forms/ReportsForm.Designer.cs
generated
Normal file
195
C969Project/Forms/ReportsForm.Designer.cs
generated
Normal file
@@ -0,0 +1,195 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
partial class ReportsForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
tabControl1 = new System.Windows.Forms.TabControl();
|
||||
apptByMothTabPage = new System.Windows.Forms.TabPage();
|
||||
refreshButton1 = new System.Windows.Forms.Button();
|
||||
apptByMonthDataGrid = new System.Windows.Forms.DataGridView();
|
||||
userSchedulesTabPage = new System.Windows.Forms.TabPage();
|
||||
userScheduleDataGrid = new System.Windows.Forms.DataGridView();
|
||||
userComboBox = new System.Windows.Forms.ComboBox();
|
||||
refreshButton2 = new System.Windows.Forms.Button();
|
||||
customersByCityTabPage = new System.Windows.Forms.TabPage();
|
||||
refreshButton3 = new System.Windows.Forms.Button();
|
||||
customersByCityDataGrid = new System.Windows.Forms.DataGridView();
|
||||
tabControl1.SuspendLayout();
|
||||
apptByMothTabPage.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)apptByMonthDataGrid).BeginInit();
|
||||
userSchedulesTabPage.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)userScheduleDataGrid).BeginInit();
|
||||
customersByCityTabPage.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)customersByCityDataGrid).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
tabControl1.Controls.Add(apptByMothTabPage);
|
||||
tabControl1.Controls.Add(userSchedulesTabPage);
|
||||
tabControl1.Controls.Add(customersByCityTabPage);
|
||||
tabControl1.Location = new System.Drawing.Point(12, 12);
|
||||
tabControl1.Name = "tabControl1";
|
||||
tabControl1.SelectedIndex = 0;
|
||||
tabControl1.Size = new System.Drawing.Size(776, 426);
|
||||
tabControl1.TabIndex = 0;
|
||||
//
|
||||
// apptByMothTabPage
|
||||
//
|
||||
apptByMothTabPage.Controls.Add(refreshButton1);
|
||||
apptByMothTabPage.Controls.Add(apptByMonthDataGrid);
|
||||
apptByMothTabPage.Location = new System.Drawing.Point(4, 24);
|
||||
apptByMothTabPage.Name = "apptByMothTabPage";
|
||||
apptByMothTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
apptByMothTabPage.Size = new System.Drawing.Size(768, 398);
|
||||
apptByMothTabPage.TabIndex = 0;
|
||||
apptByMothTabPage.Text = "Appts By Month";
|
||||
apptByMothTabPage.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// refreshButton1
|
||||
//
|
||||
refreshButton1.Location = new System.Drawing.Point(672, 369);
|
||||
refreshButton1.Name = "refreshButton1";
|
||||
refreshButton1.Size = new System.Drawing.Size(90, 23);
|
||||
refreshButton1.TabIndex = 2;
|
||||
refreshButton1.Text = "Refresh";
|
||||
refreshButton1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// apptByMonthDataGrid
|
||||
//
|
||||
apptByMonthDataGrid.Location = new System.Drawing.Point(6, 6);
|
||||
apptByMonthDataGrid.Name = "apptByMonthDataGrid";
|
||||
apptByMonthDataGrid.ReadOnly = true;
|
||||
apptByMonthDataGrid.Size = new System.Drawing.Size(756, 357);
|
||||
apptByMonthDataGrid.TabIndex = 1;
|
||||
//
|
||||
// userSchedulesTabPage
|
||||
//
|
||||
userSchedulesTabPage.Controls.Add(userScheduleDataGrid);
|
||||
userSchedulesTabPage.Controls.Add(userComboBox);
|
||||
userSchedulesTabPage.Controls.Add(refreshButton2);
|
||||
userSchedulesTabPage.Location = new System.Drawing.Point(4, 24);
|
||||
userSchedulesTabPage.Name = "userSchedulesTabPage";
|
||||
userSchedulesTabPage.Padding = new System.Windows.Forms.Padding(3);
|
||||
userSchedulesTabPage.Size = new System.Drawing.Size(768, 398);
|
||||
userSchedulesTabPage.TabIndex = 1;
|
||||
userSchedulesTabPage.Text = "User Schedules";
|
||||
userSchedulesTabPage.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// userScheduleDataGrid
|
||||
//
|
||||
userScheduleDataGrid.Location = new System.Drawing.Point(6, 35);
|
||||
userScheduleDataGrid.Name = "userScheduleDataGrid";
|
||||
userScheduleDataGrid.Size = new System.Drawing.Size(756, 357);
|
||||
userScheduleDataGrid.TabIndex = 5;
|
||||
//
|
||||
// userComboBox
|
||||
//
|
||||
userComboBox.FormattingEnabled = true;
|
||||
userComboBox.Location = new System.Drawing.Point(6, 6);
|
||||
userComboBox.Name = "userComboBox";
|
||||
userComboBox.Size = new System.Drawing.Size(660, 23);
|
||||
userComboBox.TabIndex = 4;
|
||||
//
|
||||
// refreshButton2
|
||||
//
|
||||
refreshButton2.Location = new System.Drawing.Point(672, 6);
|
||||
refreshButton2.Name = "refreshButton2";
|
||||
refreshButton2.Size = new System.Drawing.Size(90, 23);
|
||||
refreshButton2.TabIndex = 3;
|
||||
refreshButton2.Text = "Refresh";
|
||||
refreshButton2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// customersByCityTabPage
|
||||
//
|
||||
customersByCityTabPage.Controls.Add(refreshButton3);
|
||||
customersByCityTabPage.Controls.Add(customersByCityDataGrid);
|
||||
customersByCityTabPage.Location = new System.Drawing.Point(4, 24);
|
||||
customersByCityTabPage.Name = "customersByCityTabPage";
|
||||
customersByCityTabPage.Size = new System.Drawing.Size(768, 398);
|
||||
customersByCityTabPage.TabIndex = 2;
|
||||
customersByCityTabPage.Text = "Customers By City";
|
||||
customersByCityTabPage.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// refreshButton3
|
||||
//
|
||||
refreshButton3.Location = new System.Drawing.Point(675, 372);
|
||||
refreshButton3.Name = "refreshButton3";
|
||||
refreshButton3.Size = new System.Drawing.Size(90, 23);
|
||||
refreshButton3.TabIndex = 3;
|
||||
refreshButton3.Text = "Refresh";
|
||||
refreshButton3.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// customersByCityDataGrid
|
||||
//
|
||||
customersByCityDataGrid.Location = new System.Drawing.Point(3, 3);
|
||||
customersByCityDataGrid.Name = "customersByCityDataGrid";
|
||||
customersByCityDataGrid.ReadOnly = true;
|
||||
customersByCityDataGrid.Size = new System.Drawing.Size(762, 363);
|
||||
customersByCityDataGrid.TabIndex = 2;
|
||||
//
|
||||
// ReportsForm
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
ClientSize = new System.Drawing.Size(800, 450);
|
||||
Controls.Add(tabControl1);
|
||||
Text = "ReportsForm";
|
||||
tabControl1.ResumeLayout(false);
|
||||
apptByMothTabPage.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)apptByMonthDataGrid).EndInit();
|
||||
userSchedulesTabPage.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)userScheduleDataGrid).EndInit();
|
||||
customersByCityTabPage.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)customersByCityDataGrid).EndInit();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.DataGridView customersByCityDataGrid;
|
||||
private System.Windows.Forms.Button refreshButton3;
|
||||
|
||||
private System.Windows.Forms.DataGridView userScheduleDataGrid;
|
||||
|
||||
private System.Windows.Forms.ComboBox userComboBox;
|
||||
|
||||
private System.Windows.Forms.Button refreshButton2;
|
||||
|
||||
private System.Windows.Forms.Button refreshButton1;
|
||||
|
||||
private System.Windows.Forms.TabPage customersByCityTabPage;
|
||||
private System.Windows.Forms.DataGridView apptByMonthDataGrid;
|
||||
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.TabPage apptByMothTabPage;
|
||||
private System.Windows.Forms.TabPage userSchedulesTabPage;
|
||||
|
||||
#endregion
|
||||
}
|
||||
172
C969Project/Forms/ReportsForm.cs
Normal file
172
C969Project/Forms/ReportsForm.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
using C969Project.Data;
|
||||
using C969Project.Data.Models;
|
||||
|
||||
namespace C969Project;
|
||||
|
||||
public partial class ReportsForm : Form
|
||||
{
|
||||
private string[] _months =
|
||||
[
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
];
|
||||
|
||||
private string[] _appointmentTypes =
|
||||
[
|
||||
"Scrum", "Presentation", "Other"
|
||||
];
|
||||
|
||||
public ReportsForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ApptTypeByMonth_GenerateReport();
|
||||
refreshButton1.Click += (sender, args) => { ApptTypeByMonth_GenerateReport(); };
|
||||
|
||||
UserSchedule_UpdateUsers();
|
||||
userComboBox.SelectedIndexChanged += (sender, args) => { UserSchedule_GenerateReport(); };
|
||||
userComboBox.SelectedIndex = -1;
|
||||
refreshButton2.Click += (sender, args) =>
|
||||
{
|
||||
UserSchedule_UpdateUsers();
|
||||
UserSchedule_GenerateReport();
|
||||
};
|
||||
|
||||
CustomersByCity_GenerateReport();
|
||||
refreshButton3.Click += (sender, args) => { CustomersByCity_GenerateReport(); };
|
||||
}
|
||||
|
||||
#region Apptointments types by Month
|
||||
|
||||
private void ApptTypeByMonth_GenerateReport()
|
||||
{
|
||||
apptByMonthDataGrid.DataSource = null;
|
||||
|
||||
List<AppointmentTypeByMonth> appointmentTypes = new();
|
||||
var appointments = DatabaseHelper.RetrieveAppointments();
|
||||
foreach (var month in _months)
|
||||
{
|
||||
foreach (var type in _appointmentTypes)
|
||||
{
|
||||
int count = appointments.Count(a => a.Start.ToString("MMMM") == month && a.AppointmentType == type);
|
||||
appointmentTypes.Add(new AppointmentTypeByMonth(month, type, count));
|
||||
}
|
||||
}
|
||||
|
||||
apptByMonthDataGrid.DataSource = appointmentTypes;
|
||||
}
|
||||
|
||||
private class AppointmentTypeByMonth
|
||||
{
|
||||
public string Month { get; set; }
|
||||
public string AppointmentType { get; set; }
|
||||
public int Count { get; set; }
|
||||
|
||||
public AppointmentTypeByMonth(string month, string appointmentType, int count)
|
||||
{
|
||||
Month = month;
|
||||
AppointmentType = appointmentType;
|
||||
Count = count;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region User Schedule
|
||||
|
||||
private void UserSchedule_GenerateReport()
|
||||
{
|
||||
userScheduleDataGrid.DataSource = null;
|
||||
|
||||
User? selectedUser = (User?)userComboBox.SelectedItem;
|
||||
|
||||
List<UserSchedule> userSchedules = new();
|
||||
var appointments = DatabaseHelper.RetrieveAppointments();
|
||||
|
||||
var usersAppointments = appointments
|
||||
.FindAll(a => a.UserId == selectedUser.UserId)
|
||||
.ToList();
|
||||
|
||||
if (usersAppointments.Count == 0)
|
||||
{
|
||||
MessageBox.Show("No appointments found for the selected user.", "No Appointments", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var appointment in usersAppointments)
|
||||
{
|
||||
userSchedules.Add(new UserSchedule(
|
||||
selectedUser.Username,
|
||||
appointment.Title,
|
||||
appointment.AppointmentType,
|
||||
appointment.Start.ToLocalTime().ToString("MM/dd/yyyy hh:mm ") + TimeZoneInfo.Local.Id,
|
||||
appointment.End.ToLocalTime().ToString("MM/dd/yyyy hh:mm ") + TimeZoneInfo.Local.Id
|
||||
));
|
||||
}
|
||||
|
||||
userScheduleDataGrid.DataSource = userSchedules;
|
||||
}
|
||||
|
||||
private void UserSchedule_UpdateUsers()
|
||||
{
|
||||
userComboBox.DataSource = null;
|
||||
userComboBox.DataSource = DatabaseHelper.RetrieveUsers();
|
||||
userComboBox.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
private class UserSchedule
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string AppointmentName { get; set; }
|
||||
public string AppointmentType { get; set; }
|
||||
public string StartDate { get; set; }
|
||||
public string EndDate { get; set; }
|
||||
|
||||
public UserSchedule(string username, string appointmentName, string appointmentType, string startDate, string endDate)
|
||||
{
|
||||
Username = username;
|
||||
AppointmentName = appointmentType;
|
||||
AppointmentType = appointmentType;
|
||||
StartDate = startDate;
|
||||
EndDate = endDate;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Number of Users by City
|
||||
|
||||
private void CustomersByCity_GenerateReport()
|
||||
{
|
||||
customersByCityDataGrid.DataSource = null;
|
||||
|
||||
var customers = DatabaseHelper.RetrieveCustomers();
|
||||
var cityCounts = customers
|
||||
.Select(c =>
|
||||
{
|
||||
var addr = DatabaseHelper.RetrieveAddress(c.AddressId);
|
||||
var city = addr != null ? DatabaseHelper.RetrieveCity(addr.CityId) : null;
|
||||
return city?.CityName;
|
||||
})
|
||||
.Where(cityName => !string.IsNullOrEmpty(cityName))
|
||||
.GroupBy(cityName => cityName)
|
||||
.Select(g => new CustomersByCity(g.Key, g.Count()))
|
||||
.ToList();
|
||||
|
||||
customersByCityDataGrid.DataSource = cityCounts;
|
||||
}
|
||||
|
||||
private class CustomersByCity
|
||||
{
|
||||
public string? City { get; set; }
|
||||
public int Count { get; set; }
|
||||
|
||||
public CustomersByCity(string? city, int count)
|
||||
{
|
||||
City = city;
|
||||
Count = count;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
64
C969Project/Forms/ReportsForm.resx
Normal file
64
C969Project/Forms/ReportsForm.resx
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="$this.Locked" type="System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
Reference in New Issue
Block a user