public async Task <IActionResult> SaveInvoice([FromBody] SaveInvoiceRequest req)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            repository.SetTimeout(120);

            PortalUser user = await repository.AuthenticateUserToken(req.CurrentUser.UserId, req.CurrentUser.UserToken);

            if (user == null)
            {
                return(NotFound());
            }

            try
            {
                return(Ok(await paymentWorkflow.SaveInvoice(user, req.CurrentInvoice)));
            }
            catch (NullReferenceException e)
            {
                return(NotFound(e.Message));
            }
            catch (UnauthorizedAccessException e)
            {
                return(NotFound(e.Message));
            }
            catch (Exception e)
            {
                return(StatusCode((int)HttpStatusCode.InternalServerError, e.Message));
            }
        }
        public async Task <ActionResult> Update(long id, [FromBody] SaveInvoiceRequest entity)
        {
            try
            {
                var invoice = await context.Invoices
                              .Include(c => c.LineItems)
                              .AsNoTracking()
                              .SingleOrDefaultAsync(c => c.Id == id);

                if (invoice == null)
                {
                    return(NotFound());
                }

                // Revert the quantities
                var oldOrderIds       = invoice.LineItems.Where(a => a.OrderId != null).Select(a => a.OrderId.Value);
                var oldOrderLineItems = context.OrderLineItems.Where(a => oldOrderIds.Contains(a.OrderId));
                await inventoryService.ProcessAdjustments(oldOrderLineItems, AdjustmentType.Add, Constants.AdjustmentRemarks.InvoiceUpdated, QuantityType.StockQuantity);

                var newOrderIds       = entity.LineItems.Where(a => a.OrderId != null).Select(a => a.OrderId.Value);
                var newOrderLineItems = context.OrderLineItems.Where(a => newOrderIds.Contains(a.OrderId));
                await inventoryService.ProcessAdjustments(newOrderLineItems, AdjustmentType.Deduct, Constants.AdjustmentRemarks.InvoiceUpdated, QuantityType.StockQuantity);

                await orderService.ProcessInvoice(invoice.LineItems, false);

                await orderService.ProcessInvoice(entity.LineItems, true);

                // Process deleted line items
                entityListHelpers.CheckItemsForDeletion(invoice.LineItems, entity.LineItems);

                // Update the invoice data
                invoice = mapper.Map <Invoice>(entity);

                context.Update(invoice);
                await context.SaveChangesAsync();

                return(StatusCode(StatusCodes.Status204NoContent));
            }
            catch (DbUpdateConcurrencyException concurrencyEx)
            {
                logger.LogError(concurrencyEx.Message);
                return(StatusCode(StatusCodes.Status409Conflict, Constants.ErrorMessages.ConcurrencyErrorMessage));
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(StatusCode(StatusCodes.Status500InternalServerError));
            }
        }
        public async Task <ActionResult> Create([FromBody] SaveInvoiceRequest entity)
        {
            try
            {
                var invoice = mapper.Map <Invoice>(entity);
                await orderService.ProcessInvoice(invoice.LineItems, true);

                var orderIds       = invoice.LineItems.Where(a => a.OrderId != null).Select(a => a.OrderId.Value);
                var orderLineItems = context.OrderLineItems
                                     .Where(a => orderIds.Contains(a.OrderId));
                await inventoryService.ProcessAdjustments(orderLineItems, AdjustmentType.Deduct, Constants.AdjustmentRemarks.InvoiceCreated, QuantityType.StockQuantity);

                await context.Invoices.AddAsync(invoice);

                await context.SaveChangesAsync();

                return(StatusCode(StatusCodes.Status201Created));
            }
            catch (Exception e)
            {
                logger.LogError(e.Message);
                return(StatusCode(StatusCodes.Status500InternalServerError));
            }
        }