using System;
using System.Collections;
//using System.Windows.Forms;

using Cosmos.UserFrame;
using Cosmos.ServiceProvider;
using Cosmos.Common;
using Cosmos.CommonManager;
using System.Text;

/*-----------------------------------------------------------------------------------------------*/
// 설      명 : 현금결제
// 작  성  자 : 
// 변경  이력 : 
/*-----------------------------------------------------------------------------------------------*/
namespace Cosmos.Service
{
    class Cash : IPaymentUs
    {
        private SManager sManager = new SManager();                                 // 이 객체를 통해 업무 Service 호출
        private StateServer StateObject = (StateServer)StateServer.GetInstance();   // StateObject : StateServer Object (객체)
        private PosStatus m_cPosStatus = new PosStatus();                           // 기본정보 참조
        private TranStatus m_cTrnStatus = new TranStatus();                         // 거래정보 참조

        private IDataProcessUs m_cDataSrv = null;                                   // 거래데이터 합계금액 계산 및 관리
        private IDataCommonUs m_cDataCommon = null;                                 // POS 공통함수 인터페이스

        /// <summary>
        /// 현재 등록중인 결제 정보
        /// </summary>
        

        public Cash()
        {
            m_cPosStatus = (PosStatus)StateObject.POS;      // POS 기본정보
            m_cTrnStatus = (TranStatus)StateObject.TRAN;    // POS 거래정보
            m_cDataSrv = (IDataProcessUs)sManager.InitServiceInstance(ServiceLists.ASV_DATA_PROCESS.DLL, ServiceLists.ASV_DATA_PROCESS.DATA_SERVICE);
            m_cDataCommon = (IDataCommonUs)sManager.InitServiceInstance(ServiceLists.ASV_DATA_PROCESS.DLL, ServiceLists.ASV_DATA_PROCESS.DATA_COMMON);
        }

        #region 결제 조회
        /// <summary>
        /// 결제 조회
        /// </summary>
        /// <param name="aParam"></param>
        /// <param name="aRet"></param>
        /// <returns></returns>
        public string SearchPayment(string[] aParam, ref string[] aRet)
        {

            string sRet = UserCom.RST_ERR;

            try
            {
                //수표조회 처리

                string sRecvData = "";

                string sSendData = string.Empty;

                sSendData = MakeCheckBody(aParam);

                // 가맹점 정보 획득(회사승인ID,점포승인ID)
                string sCmpApprID = PosMstManager.GetMstVan(ItemConst.TR_ITEM_ID.CHECK_ITEM, ItemConst.TR_ITEM_ID.CHECK.CHECK_PAY, PosMst.MST_VAN.DATA.CMP_APPR_ID);
                string sApprID = PosMstManager.GetMstVan(ItemConst.TR_ITEM_ID.CHECK_ITEM, ItemConst.TR_ITEM_ID.CHECK.CHECK_PAY, PosMst.MST_VAN.DATA.APPR_ID);
                // 수표조회 승인 전문 헤더 생성
                sSendData = m_cDataCommon.MakeCreditCardHeader(PosConst.POS_VAN_MASTER.TRADE_ID.VAN_BILL_CHECK, sSendData.Length, sCmpApprID, sApprID) + sSendData;

                string sPAY_WAY_CD = ItemConst.TR_ITEM_ID.CHECK_ITEM;              //수표 결제 그룹 코드
                string sPAY_DTL_CD_01 = ItemConst.TR_ITEM_ID.CHECK.CHECK_PAY;      //수표 결제 코드

                    // 요청 - 승인로그 저장   (판매구분, [0]결제수단, [1]결제상세코드, [2]전문구분, [3]요청구분, [4]카드번호, [5]결제금액, [6]승인번호, [7]승인일자, [8]승인시간, [9]응답상태값, [10]응답메시지, [11]전문)
                m_cDataCommon.SetSaleApprLog(PosConst.CANCEL_DIV.NORMAL, new string[] { sPAY_WAY_CD, sPAY_DTL_CD_01, PosConst.POS_VAN_MASTER.TRADE_ID.VAN_BILL_CHECK, "S", aParam[0], aParam[2], "", "", "", "", "", sSendData });

                //전문전송
                string sIrtRet = m_cDataCommon.ExecuteCardIrt(PosConst.POS_VAN_MASTER.TRADE_ID.VAN_BILL_CHECK, sSendData, ref sRecvData, true, "");
                
                if(sIrtRet == UserCom.RST_ERR)
                {
                    aRet[0] = "X";
                    aRet[1] = "";
                    aRet[2] = sRecvData.ToString();
                    return sRet;
                }
                else
                {
                    byte[] bytes = Encoding.Default.GetBytes(sRecvData);
                    int nNowPos = 0;

                    string[] aIrtDTLRsp = new string[Column.POS_RES_CHECK.LEN.Length];
                    ItemColumn.ParseMessage(Column.POS_RES_CHECK.LEN, Column.POS_RES_CHECK.TYPE, bytes, ref nNowPos, ref aIrtDTLRsp);

                    string sCheckAppNo = aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Status] == "0" ? aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message1].Trim() : "";
                    
                    // 응답 - 승인로그 저장   (판매구분, [0]결제수단, [1]결제상세코드, [2]전문구분, [3]요청구분, [4]카드번호, [5]결제금액, [6]승인번호, [7]승인일자, [8]승인시간, [9]응답상태값, [10]응답메시지, [11]전문)
                    m_cDataCommon.SetSaleApprLog(PosConst.CANCEL_DIV.NORMAL, new string[] { sPAY_WAY_CD, sPAY_DTL_CD_01, PosConst.POS_VAN_MASTER.TRADE_ID.VAN_BILL_CHECK, "R"
                                                            , aParam[0], aParam[2]
                                                            , sCheckAppNo, CmUtil.MidH(aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.AppDatatime], 0, 6), CmUtil.MidH(aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.AppDatatime], 6, 4)
                                                            , aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.ResponeCode].Trim()
                                                            , aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message1].Trim() + aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message2].Trim()
                                                            , sRecvData });
                    
                    aRet = aIrtDTLRsp;
                    
                    aRet[0] = aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Status];
                    aRet[1] = aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.AppDatatime];
                    aRet[2] = string.Format("{0} {1} {2}",aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message1],aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message2],aIrtDTLRsp[Column.POS_RES_CHECK.SEQ.Message3]);

                    return UserCom.RST_OK;
                }
                
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return UserCom.RST_ERR;
        }
        #endregion

        #region 결제 정보 획득
        /// <summary>
        /// 결제 정보 획득
        /// </summary>
        /// <param name="aParam"></param>
        /// <returns></returns>
        public object GetPayment(string[] aParam)
        {
            try
            {
                //return m_cPayItem;
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return null;
        }
        #endregion

        #region 결제 등록
        /// <summary>
        /// 결제 등록
        /// </summary>
        /// <param name="aParam">현금 결제금액(0), 현금,수표구분(1)</param>
        /// <returns></returns>
        public string SetPayment(string[] aParam)
        {
            string sRet = UserCom.RST_ERR;
            try
            {
                string sCashRecvAmt = aParam[0];    // 현금(0)
                string sCashKind = aParam[1];       // 수표구분(0:현금, 1:수표)

                //if (m_cTrnStatus.Sale.RemainPayAmt == 0)
                //{
                //    WinManager.ErrorMessage(POS_MESSAGE.ERROR.MSG_0034);    // 받을금액이 존재 하지 않습니다.
                //    return sRet;
                //}

                if (m_cTrnStatus.Sale.RemainPayAmt == 0 && CmUtil.DoubleParse(sCashRecvAmt) > 0)
                {
                    if (WinManager.QuestionMessage(POS_MESSAGE.ERROR.MSG_0516) == false)    //받을 금액이 없습니다. 0원으로 결제 하시겠습니까?
                    {
                        return sRet;
                    }
                    else
                    {
                        sCashRecvAmt = "0";
                    }                        
                }

                if (sCashRecvAmt.Length > 10)
                {
                    WinManager.ErrorMessage(POS_MESSAGE.ERROR.MSG_0035);    // 입력한 금액이 너무 큰 금액 입니다.
                    return sRet;
                }

                //#Rhee, 20171222 결제금액이 0원이고 미국 예약등록이면 0원으로도 결제가능하게 추가 start
                // 기존
                //if (CmUtil.DoubleParse(sCashRecvAmt) == 0 && m_cTrnStatus.Sale.RemainPayAmt > 0)
                // 변경
                if ((CmUtil.DoubleParse(sCashRecvAmt) == 0 && m_cTrnStatus.Sale.RemainPayAmt > 0) && (!m_cPosStatus.Base.CmpCd.Equals("PCUS") && m_cTrnStatus.Head.TradeKind != ItemConst.TRAN_KIND.UNDECIDED.RESERVATION_REG))
                //#Rhee, 20171222 결제금액이 0원이고 미국 예약등록이면0원으로도 결제가능하게 추가 end
                {   
                    WinManager.ErrorMessage(POS_MESSAGE.ERROR.MSG_0036);    // 입력한 금액은 입력 불가 단위 입니다.
                    return sRet;
                }

                if (CmUtil.AmountCut(CmUtil.DoubleParse(sCashRecvAmt), CmUtil.IntParse(m_cPosStatus.Mst.PayRudDwLoc)) != CmUtil.DoubleParse(sCashRecvAmt))
                {
                    WinManager.ErrorMessage(POS_MESSAGE.ERROR.MSG_0036);    // 입력한 금액은 입력 불가 단위 입니다.
                    return sRet;
                }

                // 결제 내역 받아 오기
                ArrayList aPayItem = (ArrayList)StateObject.GetItemObject(Column.TR_PAYMENT.ITEM);

                Column.TR_PAYMENT.DATA m_cPayItem = new Column.TR_PAYMENT.DATA();
                
                double nCashRecvAmt = CmUtil.DoubleParse(sCashRecvAmt);     // 현금받은금액
                double nCashPayAmt = nCashRecvAmt;                          // 현금결제금액
                double nChangeAmt = 0;                                      // 현금거스름금액

                // 받은금액이 받을금액 보다 큰경우 거스름돈 설정 처리
                if (nCashRecvAmt > m_cTrnStatus.Sale.RemainPayAmt)
                {
                    nCashPayAmt = m_cTrnStatus.Sale.RemainPayAmt;
                    nChangeAmt = CmUtil.DoubleSubtraction(nCashRecvAmt, m_cTrnStatus.Sale.RemainPayAmt);
                }
                
                //if (sCashKind == "1")
                if (sCashKind == PosKey.MENU_KEY.CHECK_CASH)
                {
                    // 수표결제
                    m_cPayItem.PAY_WAY_CD = ItemConst.TR_ITEM_ID.CHECK_ITEM;              //수표 결제 그룹 코드
                    m_cPayItem.PAY_DTL_CD_01 = ItemConst.TR_ITEM_ID.CHECK.CHECK_PAY;      //수표 결제 코드
                    m_cPayItem.OCCUR_ENTRY_20 = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0060);                                   //결제 수단명

                    m_cPayItem.OCCUR_ENTRY_01 = aParam[2];  //수표번호
                    m_cPayItem.OCCUR_ENTRY_03 = aParam[3];  //승인일자
                    m_cPayItem.OCCUR_ENTRY_04 = aParam[4];  //승인시간
                    m_cPayItem.OCCUR_ENTRY_08 = aParam[5];  //승인구분 x
                    m_cPayItem.OCCUR_ENTRY_09 = aParam[6];  //수표발행일자
                    m_cPayItem.OCCUR_ENTRY_10 = aParam[7];  //수표권종코드
                    
                    // 승인정보 내역 추가 필요!
                }
                else if (sCashKind == PosKey.MENU_KEY.MEAL_TICKET)
                {
                    // 식권
                    m_cPayItem.PAY_WAY_CD = ItemConst.TR_ITEM_ID.PAYETC_ITEM ;              
                    m_cPayItem.PAY_DTL_CD_01 = ItemConst.TR_ITEM_ID.PAYETC.MEAL_TIKET;
                    m_cPayItem.OCCUR_ENTRY_20 = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0258);   // 결제수단명
                }
                else if (sCashKind == PosKey.MENU_KEY.BALANCE_VOUCHER)
                {
                    // 잔액교환권
                    m_cPayItem.PAY_WAY_CD = ItemConst.TR_ITEM_ID.PAYETC_ITEM ;              
                    m_cPayItem.PAY_DTL_CD_01 = ItemConst.TR_ITEM_ID.PAYETC.BALANCE_VOUCHER;
                    m_cPayItem.OCCUR_ENTRY_20 = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0265);   // 결제수단명
                }
                else
                {
                    // 현금결제
                    m_cPayItem.PAY_WAY_CD = ItemConst.TR_ITEM_ID.CASH_ITEM;           //현금 결제 그룹 코드
                    m_cPayItem.PAY_DTL_CD_01 = ItemConst.TR_ITEM_ID.CASH.CASH_PAY;    //현금 결제 코드
                    m_cPayItem.OCCUR_ENTRY_20 = MessageManager.GetLabelMessage(POS_MESSAGE.LABEL.MSG_0059);                               //결제 수단명
                }

                m_cPayItem.BILLSPR_NO = m_cTrnStatus.Sale.BillSplitNo;                // 빌분리 번호

                m_cPayItem.OCCUR_ENTRY_21 = ItemConst.PAY_CASHBILL_DIV.YES;

                m_cPayItem.PAY_AMT = nCashPayAmt;                            //결제 금액
                m_cPayItem.AMT_ENTRY_01 = nCashRecvAmt;                      //받은돈
                m_cPayItem.AMT_ENTRY_02 = nChangeAmt;                        //거스름
                m_cPayItem.PAY_DTL_CD_05 = PosConst.PAY_DC_TYPE.PAY;

                m_cPayItem.SEQ = aPayItem.Count + 1;

                m_cPayItem.CANCEL_DIV = PosConst.CANCEL_DIV.NORMAL;

                aPayItem.Add(m_cPayItem);

                m_cPosStatus.Sale.ChangeCashAmt = nChangeAmt;               //현금거스름
                // 결제 금액 재 계산 처리
                m_cDataSrv.UpdatePayAmount();

                sRet = UserCom.RST_OK;
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sRet;
        }
        #endregion

        #region 결제 취소
        /// <summary>
        /// 결제 취소
        /// </summary>
        /// <param name="aParam"></param>
        /// <returns></returns>
        public string CancelPayment(string[] aParam)
        {
            string sRet = UserCom.RST_ERR;
            try
            {
                int nPayRow = CmUtil.IntParse(aParam[0]); // 취소할 행번호

                // 결제 내역 받아 오기
                ArrayList alPayItem = (ArrayList)StateObject.GetItemObject(Column.TR_PAYMENT.ITEM);

                Column.TR_PAYMENT.DATA cPayItem = (Column.TR_PAYMENT.DATA) alPayItem[nPayRow];

                cPayItem.CANCEL_DIV = PosConst.CANCEL_DIV.CANCEL;

                //#20170830 거스름돈 발생시 결제취소 해도 거스름돈(AMT_ENTRY_02)이 취소가 안되어 계산함 start
                //현금, 잔액교환권, 외화, 상품권, 식권
                m_cPosStatus.Sale.ChangeCashAmt = CmUtil.DoubleSubtraction(m_cPosStatus.Sale.ChangeCashAmt, cPayItem.AMT_ENTRY_02);
                //cPayItem.AMT_ENTRY_01 = 0;
                //cPayItem.AMT_ENTRY_02 = 0;
                //#20170830 거스름돈 발생시 결제취소 해도 거스름돈(AMT_ENTRY_02)이 취소가 안되어 계산함 end

                // 결제 금액 재 계산 처리
                m_cDataSrv.UpdateTranAmount();

                sRet = UserCom.RST_OK;
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sRet;
        }
        #endregion

        #region 결제 반품
        /// <summary>
        /// 결제 반품
        /// </summary>
        /// <param name="aParam"></param>
        /// <returns></returns>
        public string RefundPayment(string[] aParam)
        {
            string sRet = UserCom.RST_ERR;
            try
            {
                //int nPayRow = CmUtil.IntParse(aParam[0]); // 취소할 행번호

                ////결제 내역 받아 오기
                //ArrayList alPayItem = (ArrayList)StateObject.GetItemObject(Column.TR_PAYMENT.ITEM);

                //Column.TR_PAYMENT.DATA cPayItem = (Column.TR_PAYMENT.DATA)alPayItem[nPayRow];

                // 현금결제는 반품시 처리 내역 없음
                sRet = UserCom.RST_OK;
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return sRet;
        }
        #endregion

        #region 결제 수기 등록(임의등록)
        /// <summary>
        /// 결제 수기 등록(임의등록)
        /// </summary>
        /// <param name="aParam"></param>
        /// <returns></returns>
        public string SetMenualPayment(string[] aParam) 
        {
            try
            {
                return UserCom.RST_OK;
            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);
            }
            return UserCom.RST_ERR;
        }
        #endregion 결제 수기 등록(임의등록)

        #region 수표조회 전문 바디 생성
        /// <summary>
        /// 수표등록 전문 바디
        /// </summary>
        /// <param name="sDivMonth"></param>
        /// <param name="sCardRecvAmt"></param>
        /// <param name="sUnionPayDiv"></param>
        /// <param name="sInputType"></param>
        /// <returns></returns>
        private string MakeCheckBody(string[] aParam)
        {
            string sSendData = string.Empty;

            try
            {
                string[] aIrtBody = new string[Column.POS_REQ_CHECK.LEN.Length];

                aIrtBody[Column.POS_REQ_CHECK.SEQ.CheckNo] = aParam[0];        // 수표번호
                aIrtBody[Column.POS_REQ_CHECK.SEQ.KownCode] = aParam[1];       // 권종코드
                aIrtBody[Column.POS_REQ_CHECK.SEQ.CheckAmt] = aParam[2];       // 수표금액
                aIrtBody[Column.POS_REQ_CHECK.SEQ.IssueDate] = aParam[3];      // 발행일자
                aIrtBody[Column.POS_REQ_CHECK.SEQ.AccountNo] = aParam[4];      // 계좌번호
                aIrtBody[Column.POS_REQ_CHECK.SEQ.Filler] = "";
                aIrtBody[Column.POS_REQ_CHECK.SEQ.ETX] = string.Format("{0}", (char)0x03);
                aIrtBody[Column.POS_REQ_CHECK.SEQ.CR] = string.Format("{0}", (char)0x0D);
                

                // 수표 조회 요청 전문 생성
                sSendData = ItemColumn.MakeMessage(aIrtBody, Column.POS_REQ_CHECK.LEN, Column.POS_REQ_CHECK.TYPE);

            }
            catch (Exception ex)
            {
                WinManager.ExceptionMessage(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name,
                   System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "()", ex.Message);

            }
            return sSendData;

        }
        #endregion

    }
}
