diff --git a/src/Api/ApiSettings.cs b/src/Api/ApiSettings.cs new file mode 100644 index 0000000000..984895d81a --- /dev/null +++ b/src/Api/ApiSettings.cs @@ -0,0 +1,9 @@ +namespace Bit.Api +{ + public class ApiSettings + { + public string OurAddress1 { get; set; } + public string OurAddress2 { get; set; } + public string OurAddress3 { get; set; } + } +} diff --git a/src/Api/Controllers/OrganizationsController.cs b/src/Api/Controllers/OrganizationsController.cs index d780af84cc..9995bbb7b1 100644 --- a/src/Api/Controllers/OrganizationsController.cs +++ b/src/Api/Controllers/OrganizationsController.cs @@ -16,6 +16,7 @@ using jsreport.AspNetCore; using jsreport.Types; using Bit.Api.Models; using Stripe; +using Microsoft.Extensions.Options; namespace Bit.Api.Controllers { @@ -29,6 +30,7 @@ namespace Bit.Api.Controllers private readonly IUserService _userService; private readonly CurrentContext _currentContext; private readonly GlobalSettings _globalSettings; + private readonly ApiSettings _apiSettings; private readonly UserManager _userManager; public OrganizationsController( @@ -38,6 +40,7 @@ namespace Bit.Api.Controllers IUserService userService, CurrentContext currentContext, GlobalSettings globalSettings, + IOptions apiSettings, UserManager userManager) { _organizationRepository = organizationRepository; @@ -47,6 +50,7 @@ namespace Bit.Api.Controllers _currentContext = currentContext; _userManager = userManager; _globalSettings = globalSettings; + _apiSettings = apiSettings.Value; } [HttpGet("{id}")] @@ -123,8 +127,10 @@ namespace Bit.Api.Controllers throw new NotFoundException(); } - var model = new InvoiceModel(organization, invoice); - HttpContext.JsReportFeature().Recipe(Recipe.PhantomPdf); + var model = new InvoiceModel(organization, invoice, _apiSettings); + HttpContext.JsReportFeature().Recipe(Recipe.PhantomPdf) + .OnAfterRender((r) => HttpContext.Response.Headers["Content-Disposition"] = + $"attachment; filename=\"bitwarden_{model.InvoiceNumber}.pdf\""); return View("Invoice", model); } catch(StripeException) diff --git a/src/Api/Models/InvoiceModel.cs b/src/Api/Models/InvoiceModel.cs index b40ba2cb79..74df0fe56b 100644 --- a/src/Api/Models/InvoiceModel.cs +++ b/src/Api/Models/InvoiceModel.cs @@ -7,19 +7,19 @@ namespace Bit.Api.Models { public class InvoiceModel { - public InvoiceModel(Organization organization, StripeInvoice invoice) + public InvoiceModel(Organization organization, StripeInvoice invoice, ApiSettings apiSettings) { - // TODO: address - OurAddress1 = "567 Green St"; - OurAddress2 = "Jacksonville, FL 32256"; - OurAddress3 = "United States"; + OurAddress1 = apiSettings.OurAddress1; + OurAddress2 = apiSettings.OurAddress2; + OurAddress3 = apiSettings.OurAddress3; CustomerName = organization.BusinessName ?? "--"; // TODO: address and vat CustomerAddress1 = "123 Any St"; CustomerAddress2 = "New York, NY 10001"; CustomerAddress3 = "United States"; - CustomerVatNumber = "PT 123456789"; + CustomerAddress4 = null; + CustomerVatNumber = "PT123456789"; InvoiceDate = invoice.Date?.ToLongDateString(); InvoiceDueDate = invoice.DueDate?.ToLongDateString(); @@ -43,6 +43,7 @@ namespace Bit.Api.Models public string CustomerAddress1 { get; set; } public string CustomerAddress2 { get; set; } public string CustomerAddress3 { get; set; } + public string CustomerAddress4 { get; set; } public IEnumerable Items { get; set; } public string SubtotalAmount { get; set; } public string VatTotalAmount { get; set; } @@ -54,13 +55,11 @@ namespace Bit.Api.Models { public Item(StripeInvoiceLineItem item) { - Quantity = item.Quantity?.ToString() ?? "-"; Amount = (item.Amount / 100).ToString("F"); Description = item.Description ?? "--"; } public string Description { get; set; } - public string Quantity { get; set; } public string Amount { get; set; } } } diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 35e7adc825..0c976f89f1 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -44,6 +44,7 @@ namespace Bit.Api // Settings var globalSettings = services.AddGlobalSettingsServices(Configuration); + services.Configure(Configuration.GetSection("apiSettings")); if(!globalSettings.SelfHosted) { services.Configure(Configuration.GetSection("IpRateLimitOptions")); @@ -145,8 +146,7 @@ namespace Bit.Api // PDF generation if(!globalSettings.SelfHosted) { - services - .AddJsReport(new jsreport.Local.LocalReporting() + services.AddJsReport(new jsreport.Local.LocalReporting() .UseBinary(jsreport.Binary.JsReportBinary.GetBinary()) .AsUtility() .Create()); diff --git a/src/Api/Views/Organizations/Invoice.cshtml b/src/Api/Views/Organizations/Invoice.cshtml index 000546ce17..13c659216b 100644 --- a/src/Api/Views/Organizations/Invoice.cshtml +++ b/src/Api/Views/Organizations/Invoice.cshtml @@ -78,10 +78,6 @@

To

@Model.CustomerName
- @if(Model.UsesVat) - { - @:VAT @Model.CustomerVatNumber
- } @if(!string.IsNullOrWhiteSpace(Model.CustomerAddress1)) { @Model.CustomerAddress1
@@ -92,9 +88,17 @@ } @if(!string.IsNullOrWhiteSpace(Model.CustomerAddress3)) { - @Model.CustomerAddress3 + @Model.CustomerAddress3
+ } + @if(!string.IsNullOrWhiteSpace(Model.CustomerAddress4)) + { + @Model.CustomerAddress4 }

+ @if(Model.UsesVat) + { +

VAT @Model.CustomerVatNumber

+ } @@ -104,7 +108,6 @@ Description - Qty @if(Model.UsesVat) { VAT % @@ -118,7 +121,6 @@ { @item.Description - @item.Quantity @if(Model.UsesVat) { 0 diff --git a/src/Api/appsettings.json b/src/Api/appsettings.json index a6a561e461..4773f6f047 100644 --- a/src/Api/appsettings.json +++ b/src/Api/appsettings.json @@ -52,6 +52,11 @@ "privateKey": "SECRET" } }, + "apiSettings": { + "ourAddress1": "123 Green St.", + "ourAddress2": "New York, NY 10001", + "ourAddress3": "United States" + }, "IpRateLimitOptions": { "EnableEndpointRateLimiting": true, "StackBlockedRequests": false,