오늘은 입고/출고 기능에 대해서 이어서 글을 써보고자 한다.
전체 공정을 생각해 보았을 때, 1-2주 정도면 필요한 최소의 기능을 장착할 수 있다고 생각한다.
간단한 기능 구현을 하고,
추후에 어떤 식으로 데이터를 관리할 것인지
csv / txt / access / excel 등등.. DataBase를 사용하지 않더라도 얼마든지 가능하므로 조급 해하지 말자.
우리가 지난번 위의 그림과 같이 시간을 출력하는 기능까지를 구현해두었다.
이제는 이어서 입고 기능 / 출고 기능을 구현할 차례이다.
우선, 첫 번째 생각할 것이
입고 시간 / 출고시간을 버튼 클릭 이벤트와 동시에 어딘가에 보여줘야 한다는 것이다.
코드는 아래와 같이 간단히 구성한다.
/// <summary>
/// 입고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnIn1_Click(object sender, EventArgs e)
{
lblIn1.Text = DateTime.Now.ToString("HH:mm");
}
/// <summary>
/// 출고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOut1_Click(object sender, EventArgs e)
{
lblOut1.Text = DateTime.Now.ToString("HH:mm");
}
단순히 버튼 옆에 lblIn1 / lblOut1이라는 라벨을 만들어두고
그 값으로
입고 버튼 클릭 시에는 lnlIn1의 텍스트 값으로 현재시간의 [시간:분]
출고 버튼 클릭 시에는 lnlOut1의 텍스트 값으로 현재시간의 [시간:분]
을 보여준다.
자.. 실행해서 버튼을 한번 눌러보도록 하자.
1분 경과 후... 50분이 되었을 때~ 출고 버튼 클릭
입고 시간 / 출고시간이 시간:분으로 출력되는 것을 확인할 수 있다.
이제는 둘의 차이가 몇 분이 났으며,
30분당 2,000원으로 보았을 때 결국 계산해야 할 금액이 얼마가 필요한 것인지를
알아보도록 하자
입고와 출고의 DateTime을 보존하여 보다 편하게 계산하기 위해서 전체 코드를 조금 수정하기로 한다.
전체 코드는 다음과 같다.
using System;
using System.Windows.Forms;
namespace ParkingManagement
{
public partial class frmParkingManagement : Form
{
/// <summary>
/// 주차장1의 인/아웃 시간관리
/// </summary>
private DateTime parking1_In;
private DateTime parking1_Out;
/// <summary>
/// 컨스트럭터
/// </summary>
public frmParkingManagement()
{
InitializeComponent();
}
/// <summary>
/// 입고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnIn1_Click(object sender, EventArgs e)
{
parking1_In = DateTime.Now;
lblIn1.Text = parking1_In.ToString("HH:mm");
}
/// <summary>
/// 출고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOut1_Click(object sender, EventArgs e)
{
parking1_Out = DateTime.Now;
lblOut1.Text = parking1_Out.ToString("HH:mm");
// (주차시간 / 단위시간) * 단위금액
TimeSpan ts = parking1_Out - parking1_In;
}
/// <summary>
/// 화면로드이벤트
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmParkingManagement_Load(object sender, EventArgs e)
{
timerMain.Start();
}
/// <summary>
/// Timer Tick 이벤트
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timerMain_Tick(object sender, EventArgs e)
{
lblNowTime.Text = DateTime.Now.ToString("HH:mm:ss");
}
}
}
바뀌는 부분을 설명하자면,
/// <summary>
/// 주차장1의 인/아웃 시간관리
/// </summary>
private DateTime parking1_In;
private DateTime parking1_Out;
주차장 1의 인/아웃 버튼 클릭 시에 사용될 DateTime 즉, 버튼 클릭 이벤트 당시의 시간을 기록하여 담고 있을 공간을 지역변수로 외부 선언하였고
인/아웃의 버튼 클릭이벤트를 아래와 같이 바꾸어주었다.
/// <summary>
/// 입고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnIn1_Click(object sender, EventArgs e)
{
parking1_In = DateTime.Now;
lblIn1.Text = parking1_In.ToString("HH:mm");
}
/// <summary>
/// 출고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOut1_Click(object sender, EventArgs e)
{
parking1_Out = DateTime.Now;
lblOut1.Text = parking1_Out.ToString("HH:mm");
// (주차시간 / 단위시간) * 단위금액
TimeSpan ts = parking1_Out - parking1_In;
}
이유는, 아웃(출고) 이벤트를 수행할 때에 시간을 기록하고 있으므로,
따로 또 다른 형 변환을 시키지 않고, 처음 이벤트가 실행될 때에 값을 그대로 저장해두면 추가로 허튼짓?을 안 해도 되기 때문이다.
※물론, 이렇게 하는 것이 100% 맞다는 것은 아니므로 형 변환을 통해서 값을 계산하여도 좋다.
/// <summary>
/// 출고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOut1_Click(object sender, EventArgs e)
{
parking1_Out = DateTime.Now.AddMinutes(41);
lblOut1.Text = parking1_Out.ToString("HH:mm");
// 주차시간계산
TimeSpan ts = parking1_Out - parking1_In;
CalcSum(ts);
}
/// <summary>
/// 주차요금계산
/// </summary>
/// <param name="ts">시간차</param>
/// <returns>요금계산결과</returns>
private string CalcSum(TimeSpan ts)
{
return (Math.Ceiling(Convert.ToDecimal(ts.Minutes / Convert.ToDecimal(txtBaseTime.Text)))
* Convert.ToInt32(txtBaseMoney.Text)).ToString();
}
내 나름대로 계산 모듈을 구현하면 위와 같이 된다.
출고 버튼 클릭이벤트에서는 지역변수에서 가지고 있던 값을 통해서 시간 차이를 구현하였고,
추차요금계산 메서드에서는 좀 난잡하지만, 시간차에 따른 요금계산을 실시하고 있다.
우선, 요금계산에 대해서 천천히 하나하나 살펴보도록 하자.
/// <summary>
/// 주차요금계산
/// </summary>
/// <param name="ts">시간차</param>
/// <returns>요금계산결과</returns>
private string CalcSum(TimeSpan ts)
{
return (Math.Ceiling(Convert.ToDecimal(ts.Minutes / Convert.ToDecimal(txtBaseTime.Text)))
* Convert.ToInt32(txtBaseMoney.Text)).ToString();
}
Math.Ceiling이라는 녀석은 반올림/올림의 올림이다.
더 자시한 내용은 아래의 링크를 참고하자.
txtBaseTime.Text 베이스타임을 Decimal형태로 바꿔주고 시간차로(분으로 환산) 나누어준다.
시간차 / 베이스타임
의 수식인셈이다.
이것은 소수점을 가지는 값이 되므로(물론, 나누어서 딱 떨어져서. 0 이 될 때도 있다)
Convert.ToDecimal로 전체 값을 형 변환해줄 필요가 있다.
그리고 그 값을 Ceiling으로 올림 처리해준다.
왜, 여기서 올림이냐??
단위 시간이 30분이고 2,000원을 요금으로 받겠다고 하였을 때로 가정하면
1분 ~ 30분까지의 주차요금은 2,000원
31분 ~ 60분까지의 주차요금은 4,000원
이 되어야 하기 때문이다.
여기까지 정리한 최종 소스는 아래와 같다.
using System;
using System.Windows.Forms;
namespace ParkingManagement
{
public partial class frmParkingManagement : Form
{
/// <summary>
/// 주차장1의 인/아웃 시간관리
/// </summary>
private DateTime parking1_In;
private DateTime parking1_Out;
/// <summary>
/// 컨스트럭터
/// </summary>
public frmParkingManagement()
{
InitializeComponent();
}
/// <summary>
/// 입고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnIn1_Click(object sender, EventArgs e)
{
parking1_In = DateTime.Now;
lblIn1.Text = parking1_In.ToString("HH:mm");
}
/// <summary>
/// 출고이벤트_1
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOut1_Click(object sender, EventArgs e)
{
parking1_Out = DateTime.Now.AddMinutes(41);
lblOut1.Text = parking1_Out.ToString("HH:mm");
// 주차시간계산
lblSum1.Text = CalcSum(parking1_Out - parking1_In);
}
/// <summary>
/// 주차요금계산
/// </summary>
/// <param name="ts">시간차</param>
/// <returns>요금계산결과</returns>
private string CalcSum(TimeSpan ts)
{
return (Math.Ceiling(Convert.ToDecimal(ts.Minutes / Convert.ToDecimal(txtBaseTime.Text)))
* Convert.ToInt32(txtBaseMoney.Text)).ToString();
}
/// <summary>
/// 화면로드이벤트
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmParkingManagement_Load(object sender, EventArgs e)
{
timerMain.Start();
}
/// <summary>
/// Timer Tick 이벤트
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timerMain_Tick(object sender, EventArgs e)
{
lblNowTime.Text = DateTime.Now.ToString("HH:mm:ss");
}
}
}
또한 현재 진행 내용에 대해서는
github에 소스를 올려두고, 하나씩 하나씩 기능도 같이 추가해 나아가고자 한다.
github.com/sungmanko/ParkingManagement
소스는 위의 github에서 다운로드할 수 있다.
'후쿠오카 개발자모임 > 주차장 관리시스템' 카테고리의 다른 글
[C#] 주차장 관리시스템 #1 (0) | 2020.11.13 |
---|