#region Using Statements
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
#endregion

namespace LLNet.Tienda.MainForms.Controls
{
    /// <summary>
    /// User Control para Pago con Tarjeta de Credito
    /// </summary>
    public partial class ctlCreditCard : UserControl
    {
        #region Events

        public event System.ComponentModel.CancelEventHandler BeforePayWithCreditCard;
        public event System.EventHandler PayWithCreditCard;

        #endregion

        public decimal? OriginalValue;
        public decimal Rate = 1;
        public decimal? Currency;
        public string RequiredData;

        private string Emisor;
        private string Enganche;
        private string Autorizacion;
        private string Monto;
        private string Modalidad;

        #region Constructor

        public ctlCreditCard(bool ingManual)
        {
            InitializeComponent();
            if (!DesignMode)
            {
                if (ingManual)
                {
                    Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsGeneral1.GetType(), dsGeneral1.CG_REF_CODES2.TableName), dsGeneral1);
                    lueEMISOR.DataSource = dsGeneral1.CG_REF_CODES2;
                    this.lueEMISOR.DisplayMember = "RV_MEANING";
                    this.lueEMISOR.ValueMember = "RV_LOW_VALUE";
                }
                else
                    Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsGeneral1.GetType(), dsGeneral1.CG_REF_CODES1.TableName), dsGeneral1);
                Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsTienda1.GetType(), dsTienda1.TDA_V_MONEDAS.TableName), dsTienda1);
                Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsTienda1.GetType(), dsTienda1.MEDIO_AUTORIZACION.TableName), dsTienda1);
                rowMONEDA.Properties.Value = GUI.CApp.bll.GetSingleValue("MonedaBase", "General");
            }

            GUI.CApp.TraducirForm(this);
        }

        #endregion

        #region Events

        public void BeginInit()
        {
            Modalidad = string.Empty;
            rowMODALIDAD.Properties.Value = null;
        }

        public void Init()
        {
            Enganche = string.Empty;
            Autorizacion = string.Empty;
            Monto = string.Empty;
            Modalidad = string.Empty;
            RequiredData = string.Empty;
            
            if (Program.FrmMainPos != null)
            {
                if (Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS.Count > 0)
                {
                    Utils.QueryParams qp = new LLNet.Utils.QueryParams();
                    if (Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["CUOTAS"]) == "")
                    {
                        Enganche = Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["ENGANCHE"]);
                        if (Enganche == string.Empty)
                            Enganche = "0";
                        Modalidad = Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["SUBTIPO_PAGO"]);
                        if (Modalidad != string.Empty)
                        {
                            qp.AddReplaceParam("MODALIDAD", Modalidad);
                            Emisor = Utils.Helpers.ObjToStr(GUI.CApp.bll.GetSingleValue("ObtieneEmisor", qp, "PDV"));

                            if (Utils.Helpers.ObjToStr(Emisor).Trim() != string.Empty)
                            {
                                Utils.QueryParams qp2 = new LLNet.Utils.QueryParams();
                                qp2.AddReplaceParam("RV_DOMAIN", "MODALIDADES EMISOR' AND RV_MPCC01 = '" + Emisor);
                                dsModalidad.CG_REF_CODES.Clear();

                                Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsModalidad.GetType(), dsModalidad.CG_REF_CODES.TableName, qp2), dsModalidad);

                                DataRow[] drReqData = dsGeneral1.CG_REF_CODES.Select("RV_LOW_VALUE = " + Emisor);
                                foreach (DataRow drrd in drReqData)
                                {
                                    RequiredData = Utils.Helpers.ObjToStr(drrd["RV_MPCC02"]);
                                }
                            }
                            rowMONTO.Properties.Value = Convert.ToDecimal(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["TOTAL"]) - Convert.ToDecimal(Enganche);
                        }

                        else
                        {
                            Modalidad = null;
                            if (Enganche == "0")
                                rowMONTO.Properties.Value = Convert.ToDecimal(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["TOTAL"]);
                            else
                                rowMONTO.Properties.Value = Convert.ToDecimal(Enganche);
                        }
                    }
                    else
                    {
                        Enganche = Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["ENGANCHE"]);
                        if (Enganche == string.Empty)
                            Enganche = "0";

                        if (Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["ESCENARIO_FINANCIERA"]).Trim() != string.Empty)
                        {
                            qp.AddReplaceParam("MODALIDAD", Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["ESCENARIO_FINANCIERA"]));
                            Emisor = Utils.Helpers.ObjToStr(GUI.CApp.bll.GetSingleValue("ObtieneEmisorF", qp, "PDV"));
                            Autorizacion = Utils.Helpers.ObjToStr(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["APROBACION2"]);

                            rowMONTO.Properties.Value = Convert.ToDecimal(Program.FrmMainPos.DsPedido.WMS_DOCUMENTOS[0]["TOTAL"]) - Convert.ToDecimal(Enganche);
                        }
                        else
                            rowMONTO.Properties.Value = Convert.ToDecimal(Enganche);

                        Modalidad = null;

                    }
                }
            }

            if (Enganche != "" && Emisor != "")
            {
                rowENGANCHE.Properties.Value = Enganche;
                rowEMISOR.Properties.Value = Emisor;
                rowAUTORIZACION.Properties.Value = Autorizacion;
                rowMODALIDAD.Properties.Value = Modalidad;
            }
        }

        private void ctlCreditCard_Load(object sender, EventArgs e)
        {
            catMain.Properties.Caption = ((Forms.frmPayments)FindForm()).btnCreditCard.Text.Substring(12).Trim();
            Vgc.FocusedRow = rowMONTO;
            Vgc.ShowEditor();
        }

        private void txtAutorizacion_KeyDown(object sender, KeyEventArgs e)
        {
            // Si presiona enter en Autorizacion
            if (e.KeyCode == Keys.Enter)
                AgregarPago(((TextEdit)sender).EditValue.ToString());
        }

        public void AgregarPago(string pAutorizacion)
        {
            // Ejecuta el evento antes de pagar con tarjeta de credito
            CancelEventArgs cea = new CancelEventArgs();
            if (BeforePayWithCreditCard != null)
                BeforePayWithCreditCard(null, cea);

            // Si en el evento se cancelo la operacion detiene el proceso
            if (cea.Cancel == true)
                return;

            if (RequiredData != string.Empty)
            {
                if (!ValidateRequiredData("MOD",rowMODALIDAD,"Ingrese la modalidad")) return;
                if (!ValidateRequiredData("TAR", rowTARJETA, "Ingrese la tarjeta")) return;
                if (!ValidateRequiredData("VEN", rowVENCIMIENTO, "Ingrese el vencimiento")) return;
                if (!ValidateRequiredData("ENG", rowENGANCHE, "Ingrese el enganche")) return;
                if (!ValidateRequiredData("MET", rowMEDIO, "Ingrese el método de autorización")) return;
                if (!ValidateRequiredData("AUT", rowAUTORIZACION, "Ingrese la autorización")) return;
            }

            decimal pCurrencyValue = Convert.ToDecimal(rowMONTO.Properties.Value);

            if (pCurrencyValue == 0)
            {
                GUI.CApp.ShowMessage(GUI.CApp.TraducirPalabra("El monto a abonar debe ser mayor a cero"), catMain.Properties.Caption,false);
                Vgc.FocusedRow = rowMONTO;
                return;
            }

            // Obtiene los datos para el pago con tarjeta de credito
            decimal pPay = pCurrencyValue * Rate;
            decimal pValue = (OriginalValue < pCurrencyValue * Rate) ? (decimal)OriginalValue : pCurrencyValue * Rate;

            string pTarjeta = Utils.Helpers.ObjToStr(rowTARJETA.Properties.Value);

            decimal? pEnganche = null;
            if (rowENGANCHE.Properties.Value != null && rowENGANCHE.Properties.Value != DBNull.Value && Utils.Helpers.ObjToStr(rowENGANCHE.Properties.Value) != "")
                pEnganche = Convert.ToDecimal(rowENGANCHE.Properties.Value);

            decimal? pModalidad = null;
            if (rowMODALIDAD.Properties.Value != null && rowMODALIDAD.Properties.Value != DBNull.Value)
                pModalidad = Convert.ToDecimal(rowMODALIDAD.Properties.Value);

            DateTime? pVencimiento = null;
            if (rowVENCIMIENTO.Properties.Value != null && rowVENCIMIENTO.Properties.Value != DBNull.Value)
                pVencimiento = Convert.ToDateTime(rowVENCIMIENTO.Properties.Value);

            if (rowEMISOR.Properties.Value == null || rowEMISOR.Properties.Value == DBNull.Value || Utils.Helpers.ObjToStr(rowEMISOR.Properties.Value) =="")
            {
                GUI.CApp.ShowMessage(GUI.CApp.TraducirPalabra("Seleccione emisor de la tarjeta"), catMain.Properties.Caption,false);
                Vgc.FocusedRow = rowEMISOR;
                return;
            }

            decimal pEmisor = Decimal.Parse(rowEMISOR.Properties.Value.ToString());
            
            // Efectua el pago
            CreditCard(pValue, pPay, pTarjeta, pEmisor, pAutorizacion, Rate, Currency, Decimal.Parse(rowMONTO.Properties.Value.ToString()), pVencimiento, pModalidad, pEnganche, Utils.Helpers.ObjToStr(rowMEDIO.Properties.Value));

            // Ejecuta el evento despues de pagar con tarjeta de credito
            if (PayWithCreditCard != null)
                PayWithCreditCard(null, null);

        }

        private bool ValidateRequiredData(string code, DevExpress.XtraVerticalGrid.Rows.EditorRow row, string sendedMessage)
        {
            if (RequiredData != null)
            {
                if (RequiredData.IndexOf(code) >= 0)
                {
                    if (Utils.Helpers.ObjToStr(row.Properties.Value) == string.Empty)
                    {
                        GUI.CApp.ShowMessage(GUI.CApp.TraducirPalabra(sendedMessage), catMain.Properties.Caption,false);
                        Vgc.FocusedRow = row;
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// Pago con Tarjeta de Credito
        /// </summary>
        public void CreditCard(decimal pValue, decimal pPay, string pTarjeta,
            decimal pEmisor, string pAutorizacion,
            decimal pRate, decimal? pCurrency, decimal pCurrencyValue,
            DateTime? pVencimiento, decimal? pModalidad, decimal? pEnganche,string pMedioAutorizacion)
        {
            Forms.frmPayments payment = ((Forms.frmPayments)FindForm());

            if (Convert.ToDecimal(payment.rowTotal.Properties.Value) < Convert.ToDecimal(payment.rowAbonado.Properties.Value) + pPay)
            {
                if (GUI.CApp.ShowMessage("El monto ingresado genera vuelto, ¿está seguro de ingresar este pago?", "Cobros y Facturación", true, true) == DialogResult.Cancel)
                    return;
            }

            if (payment.beforePay(pValue) == -1) return; 

            Model.PDV.DsPDV.WMS_PAGO_DOCUMENTOSRow pdr = payment.DsRecibo.WMS_PAGO_DOCUMENTOS.NewWMS_PAGO_DOCUMENTOSRow();

            pdr.DOCUMENTO = payment.DsRecibo.WMS_DOCUMENTOS[0].DOCUMENTO;
            pdr.TIPO_PAGO = 1;
            Utils.QueryParams qp = new LLNet.Utils.QueryParams();
            qp.AddReplaceParam("DOCUMENTO", (payment.DsRecibo.WMS_DOCUMENTOS[0].DOCUMENTO).ToString());
            pdr.LINEA = Convert.ToDecimal(GUI.CApp.bll.GetSingleValue("SiguienteLineaPago", qp, "PDV")) + payment.DsRecibo.WMS_PAGO_DOCUMENTOS.Rows.Count;
            pdr.VALOR = pValue;
            pdr.PAGADO = pPay;
            pdr.FECHA = DateTime.Now;
            pdr.TARJETA = pTarjeta;
            pdr.EMISOR = pEmisor;
            pdr.AUTORIZACION = pAutorizacion;
            pdr.TASA_CAMBIO = pRate;
            pdr.MEDIO_AUTORIZACION = pMedioAutorizacion;

            if (pEnganche !=null)
                pdr.ENGANCHE = (decimal)pEnganche;
            if (pVencimiento != null)
                pdr.FECHA_VENCIMIENTO = (DateTime)pVencimiento;
            if (pModalidad != null)
                pdr.SUBTIPO_PAGO = (decimal)pModalidad;
            if (pCurrency != null)
                pdr.MONEDA = (decimal)pCurrency;

            pdr.VALOR_MONEDA = pCurrencyValue;
            payment.DsRecibo.WMS_PAGO_DOCUMENTOS.AddWMS_PAGO_DOCUMENTOSRow(pdr);
        }

        private void lueMoneda_EditValueChanged(object sender, EventArgs e)
        {
            Rate = decimal.Parse(((LookUpEdit)sender).GetColumnValue("FACTOR").ToString());
            Currency = decimal.Parse(((LookUpEdit)sender).GetColumnValue("MONEDA").ToString());

            RecalcularMonto();
        }

        public void RecalcularMonto()
        {
            rowMONTO.Properties.Value = OriginalValue / Rate;
            Vgc.FocusedRow = rowMONTO;
            Vgc.ShowEditor();
            rowMONEDA.Properties.Value = Currency;
        }

        #endregion

        private void lueEMISOR_EditValueChanged(object sender, EventArgs e)
        {
            RequiredData = Utils.Helpers.ObjToStr(((LookUpEdit)sender).GetColumnValue("RV_MPCC02"));
        }

        private void Vgc_CellValueChanged(object sender, DevExpress.XtraVerticalGrid.Events.CellValueChangedEventArgs e)
        {
            switch (e.Row.Name)
            { 
                case "rowEMISOR":
                    Utils.QueryParams qp = new LLNet.Utils.QueryParams();
                    qp.AddReplaceParam("RV_DOMAIN", "MODALIDADES EMISOR' AND RV_MPCC01 = '" + e.Value);
                    dsModalidad.CG_REF_CODES.Clear();
                    Utils.Helpers.Merge(GUI.CApp.bll.getTypedDataSet(dsModalidad.GetType(), dsModalidad.CG_REF_CODES.TableName, qp), dsModalidad);
                    rowMODALIDAD.Properties.Value = null;                    
                    break;
            }
        }

        private void Vgc_FocusedRowChanged(object sender, DevExpress.XtraVerticalGrid.Events.FocusedRowChangedEventArgs e)
        {
            Vgc.ShowEditor();
        }

        private void repVencimiento_Validating(object sender, CancelEventArgs e)
        {
        }

        private void Vgc_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {
            if (Vgc.FocusedRow.Name == "rowVENCIMIENTO")
            {
                object dt = e.Value;
                if (dt != null && dt != DBNull.Value)
                {
                    if (Convert.ToDateTime(dt) < DateTime.Today)
                    {
                        if (Convert.ToDateTime(dt).Month != DateTime.Today.Month || Convert.ToDateTime(dt).Year != DateTime.Today.Year)
                        {
                            e.ErrorText = "La tarjeta ya está vencida";
                            e.Valid = false;
                        }
                    }
                }
            }

        }

        private void ctlCreditCard_Enter(object sender, EventArgs e)
        {
        }

        private void lueMoneda_Enter(object sender, EventArgs e)
        {
            DevExpress.XtraEditors.LookUpEdit lue = ((DevExpress.XtraEditors.LookUpEdit)sender);
            rowMONEDA.Properties.Value = lue.EditValue;
        }

        private void lueMoneda_Leave(object sender, EventArgs e)
        {
            if (((LookUpEdit)sender).EditValue != DBNull.Value && ((LookUpEdit)sender).EditValue != null)
            {
                Rate = decimal.Parse(((LookUpEdit)sender).GetColumnValue("FACTOR").ToString());
                Currency = decimal.Parse(((LookUpEdit)sender).GetColumnValue("MONEDA").ToString());
                RecalcularMonto();
            }
            else
                rowMONEDA.Properties.Value = GUI.CApp.bll.GetSingleValue("MonedaBase", "General");               
        }
    }
}