419 lines
20 KiB
C#
419 lines
20 KiB
C#
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
|
|
|
|
}
|
|
}
|