[報表程式 - 3] 多個觸發點+多種資料來源 => ViewModel

承上題 [報表程式 - 2] 多個觸發點 => 繼承

上題雖然有兩個觸發點 (出站+進站) 但都來自同一張LOT_TXN 過站記錄

那假設我們今天有第三種事件 卻來自另一張表 (SNAP 快照 指的是只有每個貨批當下最新的一筆資料)

但其實三個事件間邏輯都是類似的 我們該怎麼處理呢

 

這個例子我會分成四種情境講解

剛好對應到寫報告程式時 最常見的四種型態

這篇是3. 兩事件 (ViewModel)

完整程式碼請見 https://gitlab.com/jesperlai/Report

 

因為觸發點有可能是LOT_TXN 或 SNAP,但其實事後處理邏輯又是差不多的

=> 建造一層ViewModel來達成統一介面的目標 

 

BaseEvent.cs

原本為LOT_TXN相關的函式簽章皆改為TriggerPointVM

public abstract List<TriggerPointVM> GetTriggerPoint();


public virtual List<Result> GetData(List<TriggerPointVM> triggerPoints)
{
    //裡面都不變故省略
    return result;
}

 

Event_Snap.cs

需將觸發點SNAP => 自行組裝為TriggerPointVM

using Sample_3.Models;
using Sample_3.ViewModels;
using System.Collections.Generic;

namespace Sample_3.Event
{
    public class Event_Snap : BaseEvent
    {
        public Event_Snap(BuildEventParam param) : base(param)
        {

        }

        public override List<TriggerPointVM> GetTriggerPoint()
        {
            var snaps = repo.GetSnap();

            var triggerPoints = new List<TriggerPointVM>();
            foreach (var snap in snaps)
            {
                var item = new TriggerPointVM
                {
                    Lot_No = snap.Lot_No,
                    Stage_Id = snap.Stage_Id,
                    Qty = snap.Qty
                };

                triggerPoints.Add(item);
            }

            return triggerPoints;
        }

        public override List<Report> GetData(List<TriggerPointVM> triggerPoints)
        {
            var result = base.GetData(triggerPoints);

            //處理一些該 event 特別不同於 base event 的地方
            foreach (var item in result)
            {
                item.Qty += 1;   //隨便舉例 假設進站數量都固定要 + 1 

                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
            }

            return result;
        }
    }
}

 

Txn1_MoveIn.cs

需將觸發點LOT_TXN => 自行組裝為TriggerPointVM

public override List<TriggerPointVM> GetTriggerPoint()
{
    var txns = repo.GetTxn(builderParam.STime, builderParam.ETime, "進站");

    var triggerPoints = from data in txns
                        group data by new { data.LOT_NO } into g
                        let firstOne = g.OrderBy(q => q.TXN_DT).First()  //假設進站要報最早
                        select new TriggerPointVM
                        {
                            LOT_NO = g.Key.LOT_NO,
                            STAGE_ID = firstOne.STAGE_ID,
                            QTY = firstOne.QTY,
                        };

    return triggerPoints.ToList();
}

 

Event_MoveOut.cs

需將觸發點LOT_TXN => 自行組裝為TriggerPointVM

using Sample_3.Models;
using Sample_3.ViewModels;
using System.Collections.Generic;
using System.Linq;

namespace Sample_3.Event
{
    public class Event_MoveOut : BaseEvent
    {
        public Event_MoveOut(BuildEventParam param) : base(param)
        {

        }

        public override List<TriggerPointVM> GetTriggerPoint()
        {
            var txns = repo.GetTxn(builderParam.STime, builderParam.ETime, "進站");

            var triggerPoints = from data in txns
                                group data by new { data.Lot_No } into g
                                let firstOne = g.OrderBy(q => q.Txn_Dt).First()  //假設進站要報最早
                                select new TriggerPointVM
                                {
                                    Lot_No = g.Key.Lot_No,
                                    Stage_Id = firstOne.Stage_Id,
                                    Qty = firstOne.Qty,
                                };

            return triggerPoints.ToList();
        }

        public override List<Report> GetData(List<TriggerPointVM> triggerPoints)
        {
            var result = base.GetData(triggerPoints);

            //處理一些該 event 特別不同於 base event 的地方
            foreach (var item in result)
            {
                item.Qty -= 1;   //隨便舉例 假設進站數量都固定要 - 1 

                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
                //通常還會有更多更多相異處
            }

            return result;
        }
    }
}

 

其他的程式碼都是跟上題一樣的 詳見 [報表程式 - 2] 多個觸發點 => 繼承