/// <summary>
        /// Actualiza el pedido
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task <bool> UpdateOrder(String reference, OrderDataAPI value)
        {
            // Si no tenemos asociada la referencia no es correcto
            if (String.IsNullOrEmpty(reference) || String.IsNullOrEmpty(value?.Reference) || (!IsAdmin() && !IsVehicle()))
            {
                return(false);
            }

            Guid?vehicleId = null;
            Guid?userId    = null;

            if (!String.IsNullOrEmpty(value.UserName))
            {
                var usr = await _userRepository.GetUser(value.UserName);

                userId = usr?.Id;
            }
            // Si es un vehículo forzamos a asignar el Id como el del vehículo
            if (!IsAdmin())
            {
                // Asignamso el primer vehiculo del usuario asociado
                var vehicles = await _vehicleRepository.GetVehicles(GetUserId());

                vehicleId = vehicles?.FirstOrDefault()?.Id;
            }
            else if (!String.IsNullOrEmpty(value.ReferenceVehicle))
            {
                var vehicle = await _vehicleRepository.Find(value.ReferenceVehicle);

                vehicleId = vehicle?.Id;
            }

            // Creamos el pedido
            return(await _orderRepository.UpdateOrder(GetUserId(), reference, value, userId, vehicleId));
        }
        /// <summary>
        /// Añade un pedido al sistema
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task <bool> AddOrder(OrderDataAPI value, Guid?userId = null, Guid?vehicleId = null)
        {
            if (value == null)
            {
                return(false);
            }

            try
            {
                // Añadimos el pedido
                var order = await _context.Orders.AddAsync(new Order
                {
                    Reference             = value.Reference,
                    ReferenceUniqueAccess = value.ReferenceUniqueAccess,
                    Created   = DateTime.Now,
                    Address   = value.Address,
                    Status    = value.Status,
                    UserId    = userId,
                    VehicleId = vehicleId
                });

                return(await _context.SaveChangesAsync() > 0);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error añadiendo pedido. {@value}", value);
            }
            return(false);
        }
        /// <summary>
        /// Añade un pedido
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task <bool> AddOrder(OrderDataAPI value)
        {
            // Si no tenemos asociada la referencia no es correcto
            if (String.IsNullOrEmpty(value?.Reference) || (!IsAdmin() && !IsVehicle()))
            {
                return(false);
            }
            // Si existe un pedido con esa referencia devolvemos un fallo
            if (await _orderRepository.Find(value.Reference, value.ReferenceUniqueAccess) != null)
            {
                return(false);
            }
            Guid?vehicleId = null;
            Guid?userId    = null;

            if (!String.IsNullOrEmpty(value.UserName))
            {
                var usr = await _userRepository.GetUser(value.UserName);

                userId = usr?.Id;
            }

            // Chequeamos que el vehiculo exista en caso de estar indicado
            if (!String.IsNullOrEmpty(value.ReferenceVehicle))
            {
                var vehicle = await _vehicleRepository.Find(value.ReferenceVehicle);

                if (vehicle == null)
                {
                    return(false);
                }
                // Solo asociamos el vehiculo si es administrador o el usuario es el que lo tiene asignado
                if (IsAdmin() || vehicle.UserId == GetUserId())
                {
                    vehicleId = vehicle?.Id;
                }
                else
                {
                    throw new ExtendedResultException(new StatusCodeResult(StatusCodes.Status401Unauthorized));
                }
            }
            // Si no es administrador asociamos el vehiculo
            if (!IsAdmin())
            {
                // Asignamos el primer vehiculo del usuario asociado
                var vehicles = await _vehicleRepository.GetVehicles(GetUserId());

                vehicleId = vehicles?.FirstOrDefault()?.Id;
            }

            if (!Enum.IsDefined(typeof(OrderStatus), value.Status))
            {
                value.Status = vehicleId.HasValue ? OrderStatus.Assigned : OrderStatus.Added;
            }

            // Creamos el pedido
            return(await _orderRepository.AddOrder(value, userId, vehicleId));
        }
        public async Task <IActionResult> Post([FromBody] OrderDataAPI value)
        {
            try
            {
                if (await _orderService.AddOrder(value))
                {
                    return(Ok());
                }
            }catch (Exception ex)
            {
                // Capturamos la excepcion de resultado extendido
                if (ex is ExtendedResultException)
                {
                    var result = ex as ExtendedResultException;
                    return(result.ExtendedResult);
                }
            }

            return(BadRequest());
        }
        /// <summary>
        /// Actualiza un pedido en el sistema
        /// </summary>
        /// <param name="reference"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task <bool> UpdateOrder(Guid idUserChange, string reference, OrderDataAPI value, Guid?userId = null, Guid?vehicleId = null)
        {
            if (value == null)
            {
                return(false);
            }

            var orderPrevious = _context.Orders.FirstOrDefault(x => x.Reference == reference);

            if (orderPrevious == null)
            {
                return(false);
            }

            Dictionary <String, String> changes = new Dictionary <string, string>();

            //Cargamos los cambios
            if (orderPrevious.Reference != value.Reference)
            {
                changes["Reference"]    = orderPrevious.Reference;
                orderPrevious.Reference = value.Reference;
            }
            if (orderPrevious.ReferenceUniqueAccess != value.ReferenceUniqueAccess)
            {
                changes["ReferenceUniqueAccess"]    = orderPrevious.ReferenceUniqueAccess;
                orderPrevious.ReferenceUniqueAccess = value.ReferenceUniqueAccess;
            }
            if (orderPrevious.Address != value.Address)
            {
                changes["Address"]    = orderPrevious.Address;
                orderPrevious.Address = value.Address;
            }
            if (orderPrevious.Status != value.Status)
            {
                changes["Status"]    = orderPrevious.Status.ToString();
                orderPrevious.Status = value.Status;
            }
            if (orderPrevious.UserId != userId)
            {
                changes["UserId"]    = userId?.ToString() ?? String.Empty;
                orderPrevious.UserId = userId;
            }

            if (orderPrevious.VehicleId != vehicleId)
            {
                changes["VehicleId"]    = vehicleId?.ToString() ?? String.Empty;
                orderPrevious.VehicleId = vehicleId;
            }
            // Si no hay cambios no actualizamos nada
            if (!changes.Any())
            {
                return(true);
            }

            try
            {
                // Añadimos el pedido
                var order = _context.Orders.Update(orderPrevious);
                if (order != null)
                {
                    // Generamos un id para todo el grupo de cambios
                    Guid     groupChangesId = Guid.NewGuid();
                    DateTime dtNow          = DateTime.Now;
                    // Ahora añadimos los cambios
                    foreach (var kvp in changes)
                    {
                        await _context.OrderChanges.AddAsync(new OrderChanges
                        {
                            OrderId     = orderPrevious.Id,
                            ChangeId    = groupChangesId,
                            ChangeDate  = dtNow,
                            FieldChange = kvp.Key,
                            OldValue    = kvp.Value,
                            UserChange  = idUserChange
                        });
                    }
                }

                return(await _context.SaveChangesAsync() > 0);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error actualizando pedido({reference}). {@value}", reference, value);
            }
            return(false);
        }