Esempio n. 1
0
        public async Task <Invoice> UpdateInvoice(Invoice invoice, EditInvoiceModel model)
        {
            // get team out of invoice
            var team = invoice.Team;

            // find account
            var account = await _dbContext.FinancialAccounts
                          .FirstOrDefaultAsync(a => a.Team.Id == team.Id && a.Id == model.AccountId);

            if (account == null)
            {
                throw new ArgumentException("Account Id not found for this team.", nameof(model.AccountId));
            }

            if (!account.IsActive)
            {
                throw new ArgumentException("Account is inactive.", nameof(model.AccountId));
            }

            // find coupon
            Coupon coupon = null;

            if (model.CouponId > 0)
            {
                coupon = await _dbContext.Coupons
                         .FirstOrDefaultAsync(c => c.Team.Id == team.Id && c.Id == model.CouponId);
            }

            // TODO: Consider modifying items instead of replacing
            // remove old items
            _dbContext.LineItems.RemoveRange(invoice.Items);

            // update invoice
            invoice.Account         = account;
            invoice.Coupon          = coupon;
            invoice.CustomerAddress = model.Customer.Address;
            invoice.CustomerEmail   = model.Customer.Email;
            invoice.CustomerName    = model.Customer.Name;
            invoice.CustomerCompany = model.Customer.Company;
            invoice.Memo            = model.Memo;
            invoice.ManualDiscount  = model.ManualDiscount;
            invoice.TaxPercent      = model.TaxPercent;
            invoice.DueDate         = model.DueDate;

            // increase draft count
            invoice.DraftCount++;

            // add line items
            var items = model.Items.Select(i => new LineItem()
            {
                Amount      = i.Amount,
                Description = i.Description,
                Quantity    = i.Quantity,
                TaxExempt   = i.TaxExempt,
                Total       = i.Quantity * i.Amount,
            });

            invoice.Items = items.ToList();

            // add attachments
            var attachments = model.Attachments.Select(a => new InvoiceAttachment()
            {
                Identifier  = a.Identifier,
                FileName    = a.FileName,
                ContentType = a.ContentType,
                Size        = a.Size,
            });

            invoice.Attachments = attachments.ToList();

            // editing a sent invoice will modify the link id
            if (invoice.Sent)
            {
                SetInvoiceKey(invoice);
            }

            invoice.UpdateCalculatedValues();
            return(invoice);
        }
Esempio n. 2
0
        public async Task <IActionResult> Edit(int id)
        {
            // look for invoice
            var invoice = await _dbContext.Invoices
                          .Include(i => i.Account)
                          .Include(i => i.Coupon)
                          .Include(i => i.Items)
                          .Include(i => i.Attachments)
                          .Where(i => i.Team.Slug == TeamSlug)
                          .FirstOrDefaultAsync(i => i.Id == id);

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

            // fetch team data
            var team = await _dbContext.Teams
                       .Include(t => t.Accounts)
                       .Include(t => t.Coupons)
                       .FirstOrDefaultAsync(t => t.Slug == TeamSlug);

            ViewBag.Team = new { team.Id, team.Name, team.Slug, team.ContactEmail, team.ContactPhoneNumber };

            ViewBag.Accounts = team.Accounts
                               .Where(a => a.IsActive)
                               .Select(a => new
            {
                a.Id,
                a.Name,
                a.Description,
                a.IsDefault,
                a.Chart,
                a.Account,
                a.SubAccount,
                a.Project,
            });

            // include all active coupons, and the currently selected coupon
            ViewBag.Coupons = team.Coupons
                              .Where(c => c.ExpiresAt == null ||
                                     c.ExpiresAt >= DateTime.UtcNow.ToPacificTime().Date ||
                                     c.Id == invoice.Coupon?.Id)
                              .Select(c => new
            {
                c.Id,
                c.Name,
                c.Code,
                c.DiscountAmount,
                c.DiscountPercent,
                c.ExpiresAt,
            });

            // build model for view
            var model = new EditInvoiceModel()
            {
                AccountId      = invoice.Account?.Id ?? 0,
                CouponId       = invoice.Coupon?.Id ?? 0,
                ManualDiscount = invoice.ManualDiscount,
                DueDate        = invoice.DueDate,
                TaxPercent     = invoice.TaxPercent,
                Memo           = invoice.Memo,
                Customer       = new EditInvoiceCustomerModel()
                {
                    Name    = invoice.CustomerName,
                    Address = invoice.CustomerAddress,
                    Email   = invoice.CustomerEmail,
                    Company = invoice.CustomerCompany,
                },
                Items = invoice.Items.Select(i => new EditInvoiceItemModel()
                {
                    Amount      = i.Amount,
                    Description = i.Description,
                    Quantity    = i.Quantity,
                    TaxExempt   = i.TaxExempt,
                    Total       = i.Amount * i.Quantity,
                }).ToList(),
                Attachments = invoice.Attachments.Select(a => new EditInvoiceAttachmentModel()
                {
                    Identifier  = a.Identifier,
                    FileName    = a.FileName,
                    ContentType = a.ContentType,
                    Size        = a.Size,
                }).ToList()
            };

            // add other relevant data
            ViewBag.Id   = id;
            ViewBag.Sent = invoice.Sent;

            return(View(model));
        }
Esempio n. 3
0
        public async Task <IActionResult> Edit(int id, [FromBody] EditInvoiceModel model)
        {
            var user = await _userManager.GetUserAsync(User);

            // find item
            var invoice = await _dbContext.Invoices
                          .Include(i => i.Items)
                          .Include(i => i.Attachments)
                          .Include(i => i.Team)
                          .Where(i => i.Team.Slug == TeamSlug)
                          .FirstOrDefaultAsync(i => i.Id == id);

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

            // validate model
            if (!ModelState.IsValid)
            {
                return(new JsonResult(new
                {
                    success = false,
                    errorMessage = "Errors found in request",
                    modelState = ModelState
                }));
            }

            try
            {
                await _invoiceService.UpdateInvoice(invoice, model);
            }
            catch (ArgumentException ex)
            {
                ModelState.AddModelError(ex.ParamName, ex.Message);
                return(new JsonResult(new
                {
                    success = false,
                    errorMessage = "Errors found in request",
                    modelState = ModelState
                }));
            }

            // record action
            var action = new History()
            {
                Type           = HistoryActionTypes.InvoiceEdited.TypeCode,
                ActionDateTime = DateTime.UtcNow,
                Actor          = user.Name,
            };

            invoice.History.Add(action);

            // save to db
            _dbContext.SaveChanges();

            return(new JsonResult(new
            {
                success = true
            }));
        }
Esempio n. 4
0
        public async Task <IActionResult> Edit(int id, [FromBody] EditInvoiceModel model)
        {
            var team = await GetAuthorizedTeam();

            // find item
            var invoice = await _dbContext.Invoices
                          .Include(i => i.Items)
                          .Include(i => i.Attachments)
                          .Include(i => i.Team)
                          .Where(i => i.Team.Id == team.Id)
                          .FirstOrDefaultAsync(i => i.Id == id);

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

            // validate model
            if (!ModelState.IsValid)
            {
                return(new BadRequestObjectResult(new
                {
                    success = false,
                    errorMessage = "Errors found in request",
                    modelState = ModelState
                }));
            }

            try
            {
                await _invoiceService.UpdateInvoice(invoice, model);
            }
            catch (ArgumentException ex)
            {
                ModelState.AddModelError(ex.ParamName, ex.Message);
                return(new BadRequestObjectResult(new
                {
                    success = false,
                    errorMessage = "Errors found in request",
                    modelState = ModelState
                }));
            }

            // record action
            var action = new History()
            {
                Type           = HistoryActionTypes.InvoiceEdited.TypeCode,
                ActionDateTime = DateTime.UtcNow,
            };

            invoice.History.Add(action);

            await _dbContext.SaveChangesAsync();

            // build response, send possible new link
            var response = new EditInvoiceResult
            {
                Success = true,
                Id      = invoice.Id,
            };

            if (invoice.Sent)
            {
                response.PaymentLink = Url.Action("Pay", "Payments", new { id = invoice.LinkId });
            }

            return(new JsonResult(response));
        }