private void AddOrder(object sender, RoutedEventArgs e) { String name = Name.Text; if (Name.Text == "") { MessageBox.Show("Fill all required fields!"); return; } String phone = Phone.Text; if (Phone.Text == "") { MessageBox.Show("Fill all required fields!"); return; } EntOrder order = new EntOrder(); order.surname = name; order.pnone = phone; order.animalId = id; PetsContext context = new PetsContext(); context.Orders.Add(order); context.SaveChanges(); this.Close(); }
/// <summary> /// Función: Consulta los datos de una orden generada en Conekta /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="orderId">Id de ordan Conekta</param> /// <returns>Datos de la orden</returns> public IMDResponse <EntOrder> BGetOrder(string orderId) { IMDResponse <EntOrder> response = new IMDResponse <EntOrder>(); string metodo = nameof(this.BGetOrder); logger.Info(IMDSerialize.Serialize(67823458109701, $"Inicia {metodo}(string orderId)", orderId)); try { if (string.IsNullOrWhiteSpace(orderId)) { response.Code = 67823458120579; response.Message = "No se ingresó el id de la orden."; return(response); } IMDResponse <EntCreateUserAgent> respuestaObtenerAgenteUsuario = busAgent.BGetUserAgent(); if (respuestaObtenerAgenteUsuario.Code != 0) { return(respuestaObtenerAgenteUsuario.GetResponse <EntOrder>()); } IMDResponse <string> respuestaServicioConsultarOrden = servOrder.SGetOrder(orderId, respuestaObtenerAgenteUsuario.Result); if (respuestaServicioConsultarOrden.Code != 0) { return(respuestaServicioConsultarOrden.GetResponse <EntOrder>()); } logger.Info(IMDSerialize.Serialize(67823458218481, $"Respuesta del servicio consulta por Conekta", orderId, respuestaObtenerAgenteUsuario.Result, respuestaServicioConsultarOrden)); EntOrder entOrder = null; try { entOrder = JsonConvert.DeserializeObject <EntOrder>(respuestaServicioConsultarOrden.Result); } catch (Exception) { entOrder = null; } response.Code = 0; response.Result = entOrder; response.Message = entOrder == null ? respuestaServicioConsultarOrden.Result : "Orden obtenida."; } catch (Exception ex) { response.Code = 67823458110478; response.Message = "Ocurrió un error inesperado al recopilar la información de la orden."; logger.Error(IMDSerialize.Serialize(67823458110478, $"Error en {metodo}(string orderId): {ex.Message}", orderId, ex, response)); } return(response); }
/// <summary> /// Función: Guarda los datos de la orden en la base de datos /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="puId">ID generado de la orden</param> /// <param name="entOrder">Datos de la orden</param> /// <param name="psOrigin">Origen de status</param> /// <param name="piIdCupon">ID del cupón si aplica</param> /// <returns></returns> public IMDResponse <bool> DSaveConektaOrder(Guid puId, EntOrder entOrder, string psOrigin, int?piIdOrigen = null, int?coupon = null) { IMDResponse <bool> response = new IMDResponse <bool>(); string metodo = nameof(this.DSaveConektaOrder); logger.Info(IMDSerialize.Serialize(67823458097269, $"Inicia {metodo}(Guid puId, EntOrder entOrder, string psOrigin, int? piIdCupon = null)", puId, entOrder, psOrigin)); try { using (DbCommand dbCommand = database.GetStoredProcCommand(spSaveConektaOrder)) { database.AddInParameter(dbCommand, "puId", DbType.Guid, puId); database.AddInParameter(dbCommand, "psOrderId", DbType.String, entOrder.id?.Trim()); database.AddInParameter(dbCommand, "piOrigin", DbType.Int32, piIdOrigen); database.AddInParameter(dbCommand, "pnAmount", DbType.Decimal, entOrder.amount); database.AddInParameter(dbCommand, "pnAmountDiscount", DbType.Decimal, entOrder.amount_discount); database.AddInParameter(dbCommand, "pnAmountTax", DbType.Decimal, entOrder.amount_tax); database.AddInParameter(dbCommand, "pnAmountPaid", DbType.Decimal, entOrder.amount_paid); database.AddInParameter(dbCommand, "pnAmountRefunded", DbType.Decimal, entOrder.amount_refunded); database.AddInParameter(dbCommand, "psCurrency", DbType.String, entOrder.currency?.Trim()); database.AddInParameter(dbCommand, "psPaymentStatus", DbType.String, entOrder.payment_status?.Trim()); database.AddInParameter(dbCommand, "psOrigin", DbType.String, psOrigin?.Trim()); database.AddInParameter(dbCommand, "piIdCupon", DbType.Int32, coupon); database.AddInParameter(dbCommand, "piCreated", DbType.Int64, entOrder.created_at); database.AddInParameter(dbCommand, "piUpdated", DbType.Int64, entOrder.updated_at); response = imdCommonData.DExecute(database, dbCommand); } } catch (Exception ex) { response.Code = 67823458098046; response.Message = "Ocurrió un error inesperado al guardar el detalle de la orden en la base de datos."; logger.Error(IMDSerialize.Serialize(67823458098046, $"Error en {metodo}(Guid puId, EntOrder entOrder, string psOrigin, int? piIdCupon = null): {ex.Message}", puId, entOrder, psOrigin, ex, response)); } return(response); }
/// <summary> /// Función: Crea un orden con los datos de la compra /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="entCreateOrder">Datos de la compra</param> /// <returns>Datos de la orden generada</returns> public IMDResponse <EntOrder> BCreateOrder(EntCreateOrder entCreateOrder) { IMDResponse <EntOrder> response = new IMDResponse <EntOrder>(); string metodo = nameof(this.BCreateOrder); logger.Info(IMDSerialize.Serialize(67823458108147, $"Inicia {metodo}(EntCreateOrder entCreateOrder)", entCreateOrder)); try { string defaultPhoneNumber = "+525555555555"; if (entCreateOrder == null) { response.Code = 67823458112809; response.Message = "No se ingresaron datos de la compra."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.currency)) { response.Code = 67823458217704; response.Message = "No se ingresó el tipo de moneda."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info?.email)) { response.Code = 67823458113586; response.Message = "El correo electrónico es requerido."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info.name)) { response.Code = 45654345434543; response.Message = "El nombre del cliente es requerido."; return(response); } if (string.IsNullOrWhiteSpace(entCreateOrder.customer_info.phone)) { entCreateOrder.customer_info.phone = defaultPhoneNumber; } else { entCreateOrder.customer_info.phone = entCreateOrder.customer_info.phone.Replace(" ", ""); if (entCreateOrder.customer_info.phone.Length != 10) { response.Code = 67823458114363; response.Message = "El número de teléfono proporcionado debe tener 10 dígitos."; return(response); } else { entCreateOrder.customer_info.phone = $"{ConfigurationManager.AppSettings["CONEKTA_PHONE_ACCESS"]}{entCreateOrder.customer_info.phone}"; } } if (entCreateOrder.line_items?.Count == 0 || entCreateOrder.line_items == null) { response.Code = 67823458114363; response.Message = "No se ingresaron artículos para generar la orden."; return(response); } foreach (EntCreateLineItem articulo in entCreateOrder.line_items) { if (string.IsNullOrWhiteSpace(articulo?.name) || articulo?.quantity <= 0 || articulo?.unit_price <= 0) { response.Code = 67823458115140; response.Message = "La información de los artículos es incompleta."; return(response); } } string mensajeErrorMetodoPago = "No se ingresó información de pago."; if (entCreateOrder.charges?.Count == 0) { response.Code = 67823458115917; response.Message = mensajeErrorMetodoPago; return(response); } if (entCreateOrder.charges?[0]?.payment_method == null) { response.Code = 67823458116694; response.Message = mensajeErrorMetodoPago; return(response); } entCreateOrder.charges[0].amount = entCreateOrder.line_items.Sum(articulo => articulo.unit_price * articulo.quantity); if (entCreateOrder.charges[0].payment_method.type == "oxxo_cash") { int horasLimitePagoOxxo = 24; try { int configurationHorasLimitePagoOxxo = Convert.ToInt32(ConfigurationManager.AppSettings["CONEKTA_CASH_EXPIRE_HOURS"]); horasLimitePagoOxxo = configurationHorasLimitePagoOxxo <= 0 ? 24 : configurationHorasLimitePagoOxxo; } catch (Exception) { } DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); long unixTimeStampInTicks = (DateTime.Now.AddHours(horasLimitePagoOxxo).ToUniversalTime() - unixStart).Ticks; entCreateOrder.charges[0].payment_method.expires_at = unixTimeStampInTicks / TimeSpan.TicksPerSecond; } else if (entCreateOrder.charges[0].payment_method.type == "card") { if (string.IsNullOrWhiteSpace(entCreateOrder.charges[0].payment_method.token_id)) { response.Code = 67823458117471; response.Message = mensajeErrorMetodoPago; return(response); } } else { response.Code = 67823458118248; response.Message = mensajeErrorMetodoPago; return(response); } long amount = entCreateOrder.charges[0].amount; bool aplicaPromocion = false; string couponCode = null; long discount = 0; if (entCreateOrder.coupon != null) { IMDResponse <EntCupon> respuestaValidarPromocion = busPromociones.BValidarCupon(piIdCupon: entCreateOrder.coupon); if (respuestaValidarPromocion.Code != 0) { entCreateOrder.coupon = null; } else { double porcentajeDescuentoMaximo = Convert.ToDouble(ConfigurationManager.AppSettings["CONEKTA_DESCUENTO_MAXIMO"]); switch (respuestaValidarPromocion.Result.fiIdCuponCategoria) { case (int)EnumCategoriaCupon.DescuentoMonto: double descuentoMaximo = entCreateOrder.charges[0].amount * porcentajeDescuentoMaximo; if (respuestaValidarPromocion.Result.fnMontoDescuento > descuentoMaximo) { respuestaValidarPromocion.Result.fnMontoDescuento = descuentoMaximo; } discount = (long)respuestaValidarPromocion.Result.fnMontoDescuento; entCreateOrder.discount_lines = new List <EntCreateDiscountLine> { new EntCreateDiscountLine { type = "coupon", amount = discount, code = respuestaValidarPromocion.Result.fsCodigo } }; aplicaPromocion = true; couponCode = respuestaValidarPromocion.Result.fsCodigo; break; case (int)EnumCategoriaCupon.DescuentoPorcentaje: if (respuestaValidarPromocion.Result.fnPorcentajeDescuento > porcentajeDescuentoMaximo) { respuestaValidarPromocion.Result.fnPorcentajeDescuento = porcentajeDescuentoMaximo; } discount = (long)(entCreateOrder.charges[0].amount * respuestaValidarPromocion.Result.fnPorcentajeDescuento); entCreateOrder.discount_lines = new List <EntCreateDiscountLine> { new EntCreateDiscountLine { type = "coupon", amount = discount, code = respuestaValidarPromocion.Result.fsCodigo } }; aplicaPromocion = true; couponCode = respuestaValidarPromocion.Result.fsCodigo; break; } } } entCreateOrder.charges[0].amount -= discount; long tax = 0; double taxIVA = Convert.ToDouble(ConfigurationManager.AppSettings["CONEKTA_IMPUESTO"]); if (taxIVA > 0d) { tax = (long)(entCreateOrder.charges[0].amount * taxIVA); entCreateOrder.tax_lines = new List <EntCreateTaxLine> { new EntCreateTaxLine { amount = tax, description = "IVA" } }; } entCreateOrder.charges[0].amount += tax; IMDResponse <EntCreateUserAgent> respuestaObtenerAgenteUsuario = busAgent.BGetUserAgent(); if (respuestaObtenerAgenteUsuario.Code != 0) { return(respuestaObtenerAgenteUsuario.GetResponse <EntOrder>()); } int[] mesesSinInteresesValidos = { 3, 6, 9, 12, 18 }; List <string> ocultarPropiedades = new List <string> { "coupon", "tax", "product_id", "monthsExpiration", "iIdOrigen" }; if (!mesesSinInteresesValidos.Contains(entCreateOrder.charges[0].payment_method.monthly_installments)) { ocultarPropiedades.Add("monthly_installments"); } IMDResponse <string> respuestaServicioCrearOrden = servOrder.SCreateOrder(entCreateOrder, respuestaObtenerAgenteUsuario.Result, ocultarPropiedades.ToArray()); if (respuestaServicioCrearOrden.Code != 0 && respuestaServicioCrearOrden.Code != -1500000) { return(respuestaServicioCrearOrden.GetResponse <EntOrder>()); } ///Guardar respuesta textual del servicio en log ///Intentar convetir la respuesta en la entidad EntOrder ///Si no se puede convertir solo lo dejamos en null pero no se marca error porque la compra ya se abrá realizado logger.Info(IMDSerialize.Serialize(67823458119025, $"Respuesta del servicio pago por Conekta", entCreateOrder, respuestaObtenerAgenteUsuario.Result, respuestaServicioCrearOrden)); EntOrder entOrder = null; try { if (respuestaServicioCrearOrden.Code == 0) { entOrder = JsonConvert.DeserializeObject <EntOrder>(respuestaServicioCrearOrden.Result); } else { EntOrderDeclined entOrderDeclined = JsonConvert.DeserializeObject <EntOrderDeclined>(respuestaServicioCrearOrden.Result); if (entOrderDeclined != null) { entOrder = entOrderDeclined.data; if (entOrder != null) { entOrder.payment_status = entOrder.charges?.data[0]?.status; } } } if (entOrder != null) { entOrder.amount = amount; entOrder.amount_paid = entCreateOrder.charges[0].amount; entOrder.coupon_code = couponCode; entOrder.amount_discount = discount; entOrder.amount_tax = tax; if (entOrder.customer_info?.phone == defaultPhoneNumber) { entOrder.customer_info.phone = null; } } } catch (Exception) { entOrder = null; } string guardarOrdenEnBD = ConfigurationManager.AppSettings["CONEKTA_SAVE_DB"]; if (Convert.ToBoolean(guardarOrdenEnBD) && entOrder != null) { IMDResponse <bool> respuestaGuardarBD = this.BSaveOrder(entOrder, entCreateOrder); if (respuestaGuardarBD.Code != 0) { logger.Error(IMDSerialize.Serialize(67823458119802, $"Error en guardado en base de datos de orden Conekta.", entOrder, respuestaGuardarBD)); } } if (respuestaServicioCrearOrden.Code == -1500000) { response.Code = respuestaServicioCrearOrden.Code; response.Result = entOrder; response.Message = respuestaServicioCrearOrden.Message; } else { if (aplicaPromocion) { IMDResponse <bool> respuestaAplicarCupon = busPromociones.BAplicarCupon((int)entCreateOrder.coupon); if (respuestaAplicarCupon.Code != 0) { logger.Error(IMDSerialize.Serialize(67823458119803, $"Error en aplicar promoción.", entCreateOrder)); } } response.Code = 0; response.Result = entOrder; response.Message = "Orden creada."; } } catch (Exception ex) { response.Code = 67823458108924; response.Message = "No pudimos procesar el pago de tu pedido, revisa nuevamente los datos ingresados o intenta con otra tarjeta."; logger.Error(IMDSerialize.Serialize(67823458108924, $"Error en {metodo}(EntCreateOrder entCreateOrder): {ex.Message}", entCreateOrder, ex, response)); } return(response); }
/// <summary> /// Función: Guarda los datos de la orden generada en la base de datos proporcionada /// Creado: Cristopher Noh 03/07/2020 /// Modificado: /// </summary> /// <param name="entOrder">Datos de la orden</param> /// <param name="piIdCupon">Cupón si aplicó</param> /// <returns>Guardado correcto</returns> private IMDResponse <bool> BSaveOrder(EntOrder entOrder, EntCreateOrder entCreateOrder) { IMDResponse <bool> response = new IMDResponse <bool>(); string metodo = nameof(this.BSaveOrder); logger.Info(IMDSerialize.Serialize(67823458111255, $"Inicia {metodo}(EntOrder entOrder, int? piIdCupon = null)", entOrder, entCreateOrder)); try { Guid uid = Guid.NewGuid(); string origin = "conekta_service"; //using (TransactionScope scope = new TransactionScope()) //{ IMDResponse <bool> respuestaGuardarOrden = datOrder.DSaveConektaOrder(uid, entOrder, origin, entCreateOrder.iIdOrigen, entCreateOrder.coupon); if (respuestaGuardarOrden.Code != 0) { return(respuestaGuardarOrden); } IMDResponse <bool> respuestaGuardarCliente = datOrder.DSaveCustomerInfo(uid, entOrder.customer_info); if (respuestaGuardarCliente.Code != 0) { return(respuestaGuardarCliente); } int consecutivoArticulo = 0; for (int i = 0; i < entOrder.line_items.data.Count; i++) { EntCreateLineItem itemRef = entCreateOrder.line_items.Find(x => x.name == entOrder.line_items.data[i].name); entOrder.line_items.data[i].consecutive = ++consecutivoArticulo; entOrder.line_items.data[i].product_id = itemRef.product_id; entOrder.line_items.data[i].months_expiration = itemRef.monthsExpiration; IMDResponse <bool> respuestaGuardarArticulo = datOrder.DSaveLineItem(uid, entOrder.line_items.data[i]); if (respuestaGuardarArticulo.Code != 0) { return(respuestaGuardarArticulo); } } IMDResponse <bool> respuestaGuardarDatosPago = datOrder.DSaveCharge(uid, entOrder.charges.data.First(), origin); if (respuestaGuardarDatosPago.Code != 0) { return(respuestaGuardarOrden); } // scope.Complete(); //} response.Code = 0; response.Message = "Guardado completo"; response.Result = true; } catch (Exception ex) { response.Code = 67823458112032; response.Message = "Ocurrió un error inesperado al guardar la información en la base de datos."; logger.Error(IMDSerialize.Serialize(67823458112032, $"Error en {metodo}(EntOrder entOrder, int? piIdCupon = null): {ex.Message}", entOrder, entCreateOrder, ex, response)); } return(response); }
/// <summary> /// Función: Actualiza los status de la orden escuchando las llamadas de conekta /// Creado: Cristopher Noh 28/07/2020 /// Modificado: /// </summary> /// <param name="entWebHook"></param> /// <returns></returns> public IMDResponse <bool> BUpdateState(EntWebHook entWebHook) { IMDResponse <bool> response = new IMDResponse <bool>(); string metodo = nameof(this.BUpdateState); logger.Info(IMDSerialize.Serialize(67823458158652, $"Inicia {metodo}(EntWebHook entWebHook)", entWebHook)); try { if (entWebHook == null) { response.Code = 65723765236345; response.Message = "No se ingresó información de la orden."; return(response); } IMDResponse <Guid> respuestaObtenerUID = new IMDResponse <Guid>(); if (entWebHook.data?.@object?.@object == "order") { respuestaObtenerUID = busOrder.BGetOrderGuid(entWebHook.data?.@object?.id); } else if (entWebHook.data?.@object?.@object == "charge") { respuestaObtenerUID = busOrder.BGetOrderGuid(entWebHook.data?.@object?.order_id); } else { if (entWebHook.@object?.@object == "order") { respuestaObtenerUID = busOrder.BGetOrderGuid(entWebHook.@object?.id); } else if (entWebHook.@object?.@object == "charge") { respuestaObtenerUID = busOrder.BGetOrderGuid(entWebHook.@object?.order_id); } else { response.Code = 68763459686234; response.Message = "El tipo de objeto no es ORDER ni CHARGE."; return(response); } } if (respuestaObtenerUID.Code != 0) { return(respuestaObtenerUID.GetResponse <bool>()); } Guid uId = respuestaObtenerUID.Result; string origin = "conekta_webhook"; if (entWebHook.type == "order.created") { string status = "order created"; EntOrder entOrder = new EntOrder { payment_status = status, charges = new EntCharge { data = new List <EntChargeDetail> { new EntChargeDetail { status = status, payment_method = new EntPaymentMehod() } } } }; string mensajeErrorGuardado = ""; IMDResponse <bool> respuestaGuardarOrden = datOrder.DSaveConektaOrder(uId, entOrder, origin); IMDResponse <bool> respuestaGuardarCargo = datOrder.DSaveCharge(uId, entOrder.charges.data.First(), origin); if (respuestaGuardarOrden.Code != 0 || respuestaGuardarCargo.Code != 0) { mensajeErrorGuardado = " No a sido posible guardar en la base de datos."; } response.Code = 0; response.Message = $"Se actualizó la orden con uID {uId} a: {status}.{mensajeErrorGuardado}"; response.Result = true; } else { string statusOrder = null; if (entWebHook.data?.@object?.@object == "order") { statusOrder = entWebHook.data?.@object?.payment_status; } else if (entWebHook.data?.@object?.@object == "charge") { statusOrder = entWebHook.data?.@object?.status; } else { if (entWebHook.@object?.@object == "order") { statusOrder = entWebHook.@object?.payment_status; } else if (entWebHook.@object?.@object == "charge") { statusOrder = entWebHook.@object?.status; } } if (string.IsNullOrWhiteSpace(statusOrder)) { response.Code = 687634596456434; response.Message = "No se pudo determinar el status de la orden."; return(response); } string statusCharge = entWebHook.data?.@object?.charges?.data?[0]?.status; if (string.IsNullOrWhiteSpace(statusCharge)) { statusCharge = entWebHook.@object?.charges?.data?[0]?.status; if (string.IsNullOrWhiteSpace(statusCharge)) { statusCharge = statusOrder; } } EntOrder entOrder = new EntOrder { payment_status = statusOrder, charges = new EntCharge { data = new List <EntChargeDetail> { new EntChargeDetail { status = statusCharge, payment_method = new EntPaymentMehod() } } } }; string mensajeErrorGuardado = ""; IMDResponse <bool> respuestaGuardarOrden = datOrder.DSaveConektaOrder(uId, entOrder, origin); IMDResponse <bool> respuestaGuardarCargo = datOrder.DSaveCharge(uId, entOrder.charges.data.First(), origin); if (respuestaGuardarOrden.Code != 0 || respuestaGuardarCargo.Code != 0) { mensajeErrorGuardado = " No a sido posible guardar en la base de datos."; } response.Code = 0; response.Message = $"Se actualizó la orden con uID {uId} a: {statusOrder}.{mensajeErrorGuardado}"; response.Result = true; } } catch (Exception ex) { response.Code = 67823458159429; response.Message = "Ocurrió un error al procesar la información de la orden."; logger.Error(IMDSerialize.Serialize(67823458159429, $"Error en {metodo}(EntWebHook entWebHook): {ex.Message}", entWebHook, ex, response)); } return(response); }