From ccc594cb4d0765ffc9588b55d4dbb727bf99cf46 Mon Sep 17 00:00:00 2001 From: Jaewon Yun Date: Thu, 18 Jul 2024 17:37:59 +0900 Subject: [PATCH] Refactor using ViewModel and add today check box --- MemoGenerator/MainWindow.xaml | 60 +++- MemoGenerator/MainWindow.xaml.cs | 110 +------ MemoGenerator/Model/BusinessInfo.cs | 33 ++ MemoGenerator/Model/GlobalSettings.cs | 24 ++ .../Model/MemoGenerating/PaymentProofModel.cs | 298 ++++++++++++++++++ .../TaxCalculatingModel.cs | 0 6 files changed, 406 insertions(+), 119 deletions(-) create mode 100644 MemoGenerator/Model/BusinessInfo.cs create mode 100644 MemoGenerator/Model/GlobalSettings.cs create mode 100644 MemoGenerator/Model/MemoGenerating/PaymentProofModel.cs rename MemoGenerator/Model/{ => TaxCalculating}/TaxCalculatingModel.cs (100%) diff --git a/MemoGenerator/MainWindow.xaml b/MemoGenerator/MainWindow.xaml index 7c1a659..02a6938 100644 --- a/MemoGenerator/MainWindow.xaml +++ b/MemoGenerator/MainWindow.xaml @@ -37,10 +37,12 @@ - + - + 계산서 카드 @@ -48,25 +50,57 @@ - - + + + + + - - + + 세금계산서 면세계산서 - - - + + + + 미지정 + 일이삼사 + 대미기프트 + - - 비씨카드 결제 - 나이스페이 결제 + + + 비씨카드 결제 + 나이스페이 결제 + diff --git a/MemoGenerator/MainWindow.xaml.cs b/MemoGenerator/MainWindow.xaml.cs index 1237aff..0dcba87 100644 --- a/MemoGenerator/MainWindow.xaml.cs +++ b/MemoGenerator/MainWindow.xaml.cs @@ -1,3 +1,4 @@ +using MemoGenerator.Model.MemoGenerating; using Microsoft.UI; using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; @@ -36,6 +37,7 @@ public sealed partial class MainWindow : Window private string emailComponent = ""; private TaxCalculatingModel taxCalculatingModel = new TaxCalculatingModel(); + private PaymentProofModel paymentProofModel = new PaymentProofModel(); public MainWindow() { @@ -65,6 +67,7 @@ public MainWindow() this.AppWindow.SetIcon("C:\\Users\\y\\Desktop\\Visual Studio\\Projects\\MemoGenerator\\MemoGenerator\\Assets\\default-icon.ico"); taxCalculatorPanel.DataContext = taxCalculatingModel; + paymentProofStackPanel.DataContext = paymentProofModel; disableDeductionGroup(); } @@ -151,115 +154,10 @@ private void updatePaymentProofMethodComponent(object sender, RoutedEventArgs e) // 함께사는 세상 옵션 추가 // 분할 발행 기능 - List invoicePanelControls = new List(); - List cardPanelControls = new List(); - - retrieveAllChildControls(invoicePanel, invoicePanelControls); - retrieveAllChildControls(cardPanel, cardPanelControls); - - switch (paymentProofTypeRadioButton.SelectedIndex) - { - case 0: - foreach (var control in invoicePanelControls) { control.IsEnabled = true; } - foreach (var control in cardPanelControls) { control.IsEnabled = false; } - updatePaymentProofMethodComponentForInvoice(); - break; - case 1: - foreach (var control in invoicePanelControls) { control.IsEnabled = false; } - foreach (var control in cardPanelControls) { control.IsEnabled = true; } - updatePaymentProofMethodComponentForCard(); - break; - } - + paymentProofMethodComponent = paymentProofModel.memoComponent; updateMemoTextBlock(); } - private void updatePaymentProofMethodComponentForInvoice() - { - invoiceDateErrorTextBox.Visibility = Visibility.Collapsed; - List elements = new List(); - - if (DateTime.TryParseExact(invoiceDateTextBox.Text, "MMdd", null, System.Globalization.DateTimeStyles.None, out var date)) - { - elements.Add($"{date.ToString("MM'/'dd")}일자"); - } - else if (!String.IsNullOrEmpty(invoiceDateTextBox.Text)) - { - invoiceDateErrorTextBox.Visibility = Visibility.Visible; - } - - if (companyCheckBox.IsChecked == true) - { - elements.Add("대미"); - } - - if (taxInvoiceCheckBox.IsChecked == true && transactionStatementCheckBox.IsChecked == true) - { - invoiceTypeRadioButtons.IsEnabled = true; - switch (invoiceTypeRadioButtons.SelectedIndex) - { - case 0: - elements.Add("세금계산서/명세서"); - break; - case 1: - elements.Add("면세계산서/명세서"); - break; - } - } - else if (taxInvoiceCheckBox.IsChecked == true) - { - invoiceTypeRadioButtons.IsEnabled = true; - switch (invoiceTypeRadioButtons.SelectedIndex) - { - case 0: - elements.Add("세금계산서"); - break; - case 1: - elements.Add("면세계산서"); - break; - } - } - else if (transactionStatementCheckBox.IsChecked == true) - { - invoiceTypeRadioButtons.IsEnabled = false; - elements.Add("명세서"); - } - else - { - invoiceTypeRadioButtons.IsEnabled = false; - elements.Clear(); - } - - if (elements.Count > 0) - { - elements.Add("발행"); - } - - paymentProofMethodComponent = String.Join(" ", elements); - } - - private void updatePaymentProofMethodComponentForCard() - { - List elements = new List(); - - switch (cardRadioButtons.SelectedIndex) - { - case 0: - elements.Add("비씨카드"); - break; - case 1: - elements.Add("나이스페이"); - break; - } - - if (elements.Count > 0) - { - elements.Add("결제"); - } - - paymentProofMethodComponent = String.Join(" ", elements); - } - private void updateDocumentsDeliveryRouteComponent(object sender, RoutedEventArgs e) { List elements = new List(); diff --git a/MemoGenerator/Model/BusinessInfo.cs b/MemoGenerator/Model/BusinessInfo.cs new file mode 100644 index 0000000..f0ca88a --- /dev/null +++ b/MemoGenerator/Model/BusinessInfo.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MemoGenerator.Model +{ +#nullable enable + + class BusinessInfo + { + internal BusinessInfo(string name, string? memoText) + { + this.name = name; + this.memoText = memoText; + } + + string name; + internal string? memoText; + + internal static List defaults() + { + return new List(new BusinessInfo[] { + new BusinessInfo("미지정", null), + new BusinessInfo("일이삼사", null), + new BusinessInfo("대미기프트", "대미"), + }); + } + } + +#nullable disable +} diff --git a/MemoGenerator/Model/GlobalSettings.cs b/MemoGenerator/Model/GlobalSettings.cs new file mode 100644 index 0000000..a0052a0 --- /dev/null +++ b/MemoGenerator/Model/GlobalSettings.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MemoGenerator.Model +{ + class GlobalSettings + { + private static readonly Lazy lazyInstance = new Lazy(() => new GlobalSettings()); + + public static GlobalSettings Instance + { + get => lazyInstance.Value; + } + + private GlobalSettings() { + businessInfos = BusinessInfo.defaults(); + } + + internal List businessInfos; + } +} diff --git a/MemoGenerator/Model/MemoGenerating/PaymentProofModel.cs b/MemoGenerator/Model/MemoGenerating/PaymentProofModel.cs new file mode 100644 index 0000000..b67e434 --- /dev/null +++ b/MemoGenerator/Model/MemoGenerating/PaymentProofModel.cs @@ -0,0 +1,298 @@ +using Microsoft.UI; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MemoGenerator.Model.MemoGenerating +{ + enum PaymentProofType + { + invoice, + card, + } + + enum InvoiceType + { + taxable, // 과세 + taxFree, // 면세 + } + + sealed class InvoiceInfo : BaseINotifyPropertyChanged + { + internal WeakReference owner; + + internal DateTime? date; + private bool isToday + { + get + { + if (date is DateTime unwrapped) { return (DateTime.Today.Day == unwrapped.Day) && DateTime.Today.Month== unwrapped.Month; } + else { return false; } + } + } + internal bool includesInvoice; + internal InvoiceType selectedInvoiceType; + internal bool includesTransactionSpecification; + private readonly List businessList; + internal BusinessInfo selectedBusiness; + + internal InvoiceInfo() + { + this.date = DateTime.Today; + this.includesInvoice = false; + this.selectedInvoiceType = InvoiceType.taxable; + this.includesTransactionSpecification = false; + this.businessList = GlobalSettings.Instance.businessInfos; + this.selectedBusiness = businessList.First(); + } + + // Binding + + public string Date + { + get + { + if (date is DateTime unwrapped) { return unwrapped.ToString("MMdd"); } + else { return ""; } + } + set + { + if (DateTime.TryParseExact(value, "MMdd", null, System.Globalization.DateTimeStyles.None, out var date)) + { + this.date = date; + } + else + { + this.date = null; + } + propertyChanged("IsToday"); + } + } + + public Visibility IsVisibleDateError + { + get => (date == null) ? Visibility.Visible : Visibility.Collapsed; + } + + public bool IsToday + { + get => isToday; + set + { + if (value == true) + { + date = DateTime.Today; + } + propertyChanged("Date"); + } + } + + public bool IncludesInvoice + { + get => includesInvoice; + set { + includesInvoice = value; + if (owner.TryGetTarget(out var target)) + { + target.propertyChanged("EnableInvoiceTypeRadioButtons"); + } + } + } + + public int SelectedInvoiceTypeIndex + { + get => (int)selectedInvoiceType; + set { selectedInvoiceType = (InvoiceType)value; } + } + + public bool IncludesTransactionSpecification + { + get => includesTransactionSpecification; + set { includesTransactionSpecification = value; } + } + + public int SelectedBusinessIndex + { + get => businessList.IndexOf(selectedBusiness); + set { selectedBusiness = businessList[value]; } + } + } + + enum CardType + { + bc, + nicepay, + } + + static class CardTypeExtensions + { + internal static string name(this CardType card) + { + switch (card) + { + case CardType.bc: + return "BC카드"; + case CardType.nicepay: + return "나이스페이"; + default: + return ""; // 바인딩 과정에서 -1값이 들어오는 현상이 있음 + } + } + } + + sealed class CardInfo : BaseINotifyPropertyChanged + { + private CardType[] cardTypes; + internal CardType selectedCardType; + + internal CardInfo() + { + this.cardTypes = Enum.GetValues(); + this.selectedCardType = cardTypes.First(); + } + + // Binding + + public int SelectedCardTypeIndex + { + get => (int)selectedCardType; + set + { + selectedCardType = (CardType)value; + } + } + } + + sealed class PaymentProofModel : BaseINotifyPropertyChanged + { + private PaymentProofType paymentProofType; + private InvoiceInfo invoiceInfo; + private CardInfo cardInfo; + internal string memoComponent + { + get + { + List elements = new List(); + + switch (paymentProofType) + { + case PaymentProofType.invoice: + if (invoiceInfo.date is DateTime date) + { + elements.Add($"{date.ToString("MM'/'dd")}일자"); + } + + if (invoiceInfo.selectedBusiness.memoText is string businessName) + { + elements.Add(businessName); + } + + if (invoiceInfo.includesInvoice && invoiceInfo.includesTransactionSpecification) + { + switch (invoiceInfo.selectedInvoiceType) + { + case InvoiceType.taxable: + elements.Add("세금계산서/명세서"); + break; + case InvoiceType.taxFree: + elements.Add("면세계산서/명세서"); + break; + } + } + else if (invoiceInfo.includesInvoice) + { + switch (invoiceInfo.selectedInvoiceType) + { + case InvoiceType.taxable: + elements.Add("세금계산서"); + break; + case InvoiceType.taxFree: + elements.Add("면세계산서"); + break; + } + } + else if (invoiceInfo.includesTransactionSpecification) + { + elements.Add("거래명세서"); + } + else + { + elements.Clear(); + } + + if (elements.Count > 0) { elements.Add("발행"); } + break; + case PaymentProofType.card: + elements.Add(cardInfo.selectedCardType.name()); + elements.Add("결제"); + break; + } + + return String.Join(" ", elements); + } + } + + internal PaymentProofModel() + { + this.paymentProofType = PaymentProofType.invoice; + this.invoiceInfo = new InvoiceInfo(); + invoiceInfo.owner = new WeakReference(this); + this.cardInfo = new CardInfo(); + } + + // Binding + + public InvoiceInfo InvoiceInfo { get => invoiceInfo; } + + public CardInfo CardInfo { get => cardInfo; } + + public int SelectedPaymentProofTypeIndex + { + get => (int)paymentProofType; + set { + paymentProofType = (PaymentProofType)value; + propertyChanged("EnableInvoice"); + propertyChanged("EnableInvoiceTypeRadioButtons"); + propertyChanged("EnableCard"); + propertyChanged("InvoiceHeaderColor"); + } + } + + public bool EnableInvoice + { + get => paymentProofType == PaymentProofType.invoice; + } + + public bool EnableCard + { + get => paymentProofType == PaymentProofType.card; + } + + public SolidColorBrush InvoiceHeaderColor + { + get + { + switch (paymentProofType) { + case PaymentProofType.invoice: + return new SolidColorBrush(Colors.Black); + case PaymentProofType.card: + return new SolidColorBrush(Colors.LightGray); + default: + return new SolidColorBrush(Colors.Black); + } + } + } + + public bool EnableInvoiceTypeRadioButtons + { + get + { + return invoiceInfo.includesInvoice && EnableInvoice; + } + } + } +} diff --git a/MemoGenerator/Model/TaxCalculatingModel.cs b/MemoGenerator/Model/TaxCalculating/TaxCalculatingModel.cs similarity index 100% rename from MemoGenerator/Model/TaxCalculatingModel.cs rename to MemoGenerator/Model/TaxCalculating/TaxCalculatingModel.cs