今回は、第6回の決算処理の損益計算が間違っていたので、修正します。
tomo-mana.hatenablog.com
また、次回からの仕入単価の変動に対応するに先立って、第6回では一緒くたにしていた入力と処理を分離します。
入力と処理の分離
第6回で作成した入力は「仕入」「売上」「決算」の3つのボタンで成り立っていて、それぞれ仕入処理、売上処理、決算処理をしていました。仕入・売上処理は試算表を更新して、決算処理は棚卸して、損益計算書と貸借対照表を作成しました。
ちょうど、仕入処理、売上処理、決算処理が入力と処理の分断ポイントになるため、ここでファイルを分けます。
ここでは修正コードは省略します。リファクタリングとしては割と取り組みやすい、移植元ファイルの関数が移植先ファイルの同名の関数をコールするように修正します。
(修正前)ファイルAで入力と処理を実施
// ファイルA void ButtonClicked() { ExecuteXx(); } void ExecuteXx() { // 処理 }
(修正後)ExecuteXx() 関数で入力と処理を分離し、ファイルAはファイルBクラスの同名の関数を呼びます。ファイルB内のクラスはファイルAの処理を切り取ってきたものです。
// ファイルA ファイルB b; void ButtonClicked() { b.ExecuteXx(); // ファイルBの同名の関数をコールするだけ } // ファイルB void ExecuteXx() { // 処理(ファイルAで行っていた処理) }
損益計算書の修正
第6回で作った決算処理は、仕入の決算仕訳(損益計算書への反映方法)が間違っていました。以下の図のように修正を入れます。
修正後のコードは以下の通りです。
処理部(SalesTransaction.cs)
using System.Collections; using System.Collections.Generic; using UnityEngine; // 試算表 public class TrialBalance { public int cash; // 現金 public int purchase; // 仕入 public int sales; // 売上 public int q_remain; // 在庫残 public int q_total; // 在庫総購入量 public void Initialize(int c, int p, int s, int qr, int qt){ cash = c; purchase = p; sales = s; q_remain = qr; q_total = qt; } } // 棚卸 public class InventoryDB { public int q_purchase; // 仕入個数 public int q_sales; // 売上個数 public int q_initial; // 繰越個数 public void Initialize(int p, int s, int i) { q_purchase = p; q_sales = s; q_initial = i; } } // 貸借対照表 public class BalanceSheetDB { public int inventory; // 繰越商品 public int flexLiability; // 流動資産 } // 損益計算書 public class ProfitAndLossDB { public int expenses; // 費用 public int revenue; // 収益 public int netIncome; // 利益 } public class SalesTransaction : MonoBehaviour { TrialBalance tb = new TrialBalance(); InventoryDB iv = new InventoryDB(); BalanceSheetDB bs = new BalanceSheetDB(); ProfitAndLossDB pl = new ProfitAndLossDB(); // 資本 int firstCash = 10000; // 販売物の仕入単価(現在は固定) int unitPrice = 1000; // 販売物の売価(現在は固定) int unitSales = 1500; // ログ用の文字 string[] msg_e = new string[]{ "SUCCEED!", "LACK OF CASH!", "LACK OF REMAINS!", "START!" }; public TrialBalance GetTrialBalance() { return tb; } public InventoryDB GetInventory() { return iv; } public BalanceSheetDB GetBalanceSheet() { return bs; } public ProfitAndLossDB GetProfitAndLoss() { return pl; } public void InitializeJournal() { tb.Initialize(firstCash, 0, 0, 0, 0); } public int ExecutePurchase() { int e = 0; if( tb.cash >= unitPrice ){ tb.cash -= unitPrice; tb.purchase += unitPrice; tb.q_remain++; tb.q_total++; iv.q_purchase++; } else { e = 1; } return e; } public int ExecuteSale() { int e = 0; if( tb.q_remain > 0 ){ tb.cash += unitSales; tb.sales += unitSales; tb.q_remain--; iv.q_sales++; } else { e = 2; } return e; } public void ExecuteReset() { InitializeJournal(); } public void ExecuteSettle() { // 棚卸 iv.q_initial = iv.q_purchase - iv.q_sales; // 損益計算 pl.expenses = iv.q_sales * unitPrice; pl.revenue = tb.sales; //売上個数 * 売価; pl.netIncome = pl.revenue - pl.expenses; // 貸借(繰越商品) bs.inventory = iv.q_initial * unitPrice; // 年度をまたぐ(初期化) tb.Initialize( tb.cash, bs.inventory, 0, tb.q_remain, 0 ); // 繰越商品を仕入に再計上 iv.Initialize( iv.q_initial, 0, 0 ); } }
入力部(InputWindow2.cs)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class InputWindow2 : MonoBehaviour, ILangSwitchHandler { enum BUTTON_NAME { BUTTON_PURCHASED = 0, BUTTON_SALED, BUTTON_SETTLE, BUTTON_RESET, }; [SerializeField] BalanceSheet bs = default; [SerializeField] ProfitAndLoss pl = default; [SerializeField] GameObject journalButtons = default; [SerializeField] TextMeshProUGUI log = default; [SerializeField] SalesTransaction ts = default; string[] msg_j = new string[]{ "成功!", "現金不足!", "在庫不足!", "START!" }; string[] msg_e = new string[]{ "SUCCEED!", "LACK OF CASH!", "LACK OF REMAINS!", "START!" }; LANG selected; int error_hold; void UpdateLog(int error) { TrialBalance tb = default; if( !ReferenceEquals(ts, null) ){ tb = ts.GetTrialBalance(); } if( !ReferenceEquals(tb, null) ){ if( error == -1 ){ error = error_hold; } else { error_hold = error; } if( !ReferenceEquals(log, null) ){ //現金:xxxx/仕入:xxxx/売上:xxxx/在庫:xx/xx(@100) if( selected == LANG.LANG_ENG ){ log.text = msg_e[error] + "\nCash:" + tb.cash + "\nPurchases:" + tb.purchase + "\nSales:" + tb.sales + "\nRemain:" + tb.q_remain + "/" + tb.q_total + "(@1000)"; } else { log.text = msg_j[error] + "\n現金:" + tb.cash + "\n仕入:" + tb.purchase + "\n売上:" + tb.sales + "\n在庫:" + tb.q_remain + "/" + tb.q_total + "(@1000)"; } } } } void InitializeJournal() { if( !ReferenceEquals(ts, null) ){ ts.InitializeJournal(); } UpdateLog( 3 ); } void ExecutePurchase() { int e = 0; if( !ReferenceEquals(ts, null) ){ e = ts.ExecutePurchase(); } UpdateLog( e ); } void ExecuteSale() { int e = 0; if( !ReferenceEquals(ts, null) ){ e = ts.ExecuteSale(); } UpdateLog( e ); } void ExecuteReset() { if( !ReferenceEquals(ts, null) ){ ts.ExecuteReset(); } if( !ReferenceEquals(bs, null) ){ bs.ChangeAreaValues( 10000, 0, 0, 0, 0 ); pl.ChangeAreaValues( 0, 0 ); } } void ExecuteSettle() { TrialBalance tb = default; BalanceSheetDB bsdb = default; ProfitAndLossDB pldb = default; if( !ReferenceEquals(ts, null) ){ ts.ExecuteSettle(); tb = ts.GetTrialBalance(); bsdb = ts.GetBalanceSheet(); pldb = ts.GetProfitAndLoss(); } if( !ReferenceEquals(tb, null) ){ if( !ReferenceEquals(bs, null) ){ if( !ReferenceEquals(bsdb, null) ){ // bs.ChangeAreaValues( tb.cash, tb.q_remain * unitPrice, 0, 0, 0 ); // #6 計算は間違ってはいないが… bs.ChangeAreaValues( tb.cash, bsdb.inventory, 0, 0, 0 ); } } if( !ReferenceEquals(pl, null) ){ if( !ReferenceEquals(pldb, null) ){ // pl.ChangeAreaValues( tb.purchase, tb.sales ); // #6 費用が多く計算されてしまう pl.ChangeAreaValues( pldb.expenses, pldb.revenue ); } } } } void ButtonClicked(int buttonNo) { switch( buttonNo ){ case (int)BUTTON_NAME.BUTTON_PURCHASED: ExecutePurchase(); break; case (int)BUTTON_NAME.BUTTON_SALED: ExecuteSale(); break; case (int)BUTTON_NAME.BUTTON_SETTLE: ExecuteSettle(); break; case (int)BUTTON_NAME.BUTTON_RESET: ExecuteReset(); break; } } public void LangSelected(LANG selectedLang) { // 省略 } // Start is called before the first frame update void Start() { // 省略 } }