Skip to content

Commit

Permalink
Fixed the display of the total on the order page after you remove ons…
Browse files Browse the repository at this point in the history
…ite installation in support of #392.
  • Loading branch information
uncheckederror committed Aug 31, 2023
1 parent df0412d commit 7af980a
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 9 deletions.
99 changes: 93 additions & 6 deletions Messaging/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

using Flurl.Http;

using MailKit.Security;

using Messaging;

using Microsoft.AspNetCore.Authentication.JwtBearer;
Expand All @@ -15,9 +17,12 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using MimeKit;

using Models;

using NumberSearch.DataAccess;

using Org.BouncyCastle.Ocsp;

using Prometheus;
Expand All @@ -27,6 +32,7 @@

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
Expand Down Expand Up @@ -72,6 +78,10 @@
string digitalOceanSpacesSecretKey = builder.Configuration.GetConnectionString("DOSpacesSecretKey") ?? string.Empty;
string s3ServiceURL = builder.Configuration.GetConnectionString("S3ServiceURL") ?? string.Empty;

string emailUsername = builder.Configuration.GetConnectionString("EmailUsername") ?? string.Empty;
string emailPassword = builder.Configuration.GetConnectionString("EmailPassword") ?? string.Empty;
string carbonCopyEmail = builder.Configuration.GetConnectionString("CarbonCopyEmail") ?? string.Empty;

builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
Expand Down Expand Up @@ -476,13 +486,20 @@
});
}
if (string.IsNullOrWhiteSpace(registration.CallbackUrl) && !string.IsNullOrWhiteSpace(registration.Email))
if (string.IsNullOrWhiteSpace(registration.CallbackUrl) && !string.IsNullOrWhiteSpace(registration.Email) && !System.Net.Mail.MailAddress.TryCreate(registration.Email, out var address))
{
// Register for email forwarding.
return TypedResults.BadRequest(new RegistrationResponse
{
DialedNumber = registration.DialedNumber,
CallbackUrl = registration.CallbackUrl,
Email = registration.Email,
Registered = false,
Message = $"The Email provided {registration.Email} is invalid or not a well formatted address. Email was parsed as {address?.Address} which is invalid."
});
}
// Validate the callback Url to prevent dumb errors.
if (!Uri.IsWellFormedUriString(registration.CallbackUrl, UriKind.Absolute))
if (!Uri.IsWellFormedUriString(registration.CallbackUrl, UriKind.Absolute) && string.IsNullOrWhiteSpace(registration.Email))
{
return TypedResults.BadRequest(new RegistrationResponse
{
Expand Down Expand Up @@ -551,7 +568,7 @@
updated = true;
}
if (existingRegistration.CallbackUrl != registration.CallbackUrl)
if (existingRegistration.CallbackUrl != registration.CallbackUrl && !string.IsNullOrWhiteSpace(registration.CallbackUrl))
{
existingRegistration.CallbackUrl = registration.CallbackUrl;
updated = true;
Expand All @@ -569,6 +586,12 @@
updated = true;
}
if (existingRegistration.Email != registration.Email && !string.IsNullOrWhiteSpace(registration.Email))
{
existingRegistration.Email = registration.Email;
updated = true;
}
if (updated)
{
await db.SaveChangesAsync();
Expand All @@ -584,10 +607,67 @@
ClientSecret = registration.ClientSecret,
RegisteredUpstream = registeredUpstream,
UpstreamStatusDescription = upstreamStatusDescription,
Email = registration.Email,
});
await db.SaveChangesAsync();
}
existingRegistration = await db.ClientRegistrations.FirstOrDefaultAsync(x => x.AsDialed == asDialedNumber.DialedNumber);
if (existingRegistration is not null && string.IsNullOrWhiteSpace(existingRegistration.Email) && existingRegistration.EmailVerified is false)
{
try
{
var outboundMessage = new MimeMessage
{
Sender = new MailboxAddress("TextToEmail", emailUsername),
Subject = $"Email Verification"
};
// Set the client secret if it was not provided.
if (string.IsNullOrWhiteSpace(registration.ClientSecret))
{
Random r = new Random();
int randNum = r.Next(999999);
registration.ClientSecret = randNum.ToString("D6");
}
var builder = new BodyBuilder
{
HtmlBody = @$"<!DOCTYPE html><html><head><title></title></head><body>Please respond with <b>{registration.ClientSecret}<b> to verify your email address and enroll {registration.DialedNumber} in text to email service from Accelerate Networks.</body></html>"
};
var ordersInbox = MailboxAddress.Parse(emailUsername);
var recipient = MailboxAddress.Parse(existingRegistration.Email);
outboundMessage.From.Add(ordersInbox);
outboundMessage.To.Add(recipient);
if (!string.IsNullOrWhiteSpace(carbonCopyEmail) && carbonCopyEmail.Contains("@"))
{
var cc = MailboxAddress.Parse(carbonCopyEmail);
outboundMessage.Cc.Add(cc);
}
outboundMessage.Body = builder.ToMessageBody();
using var smtp = new MailKit.Net.Smtp.SmtpClient();
smtp.MessageSent += (sender, args) => { };
smtp.ServerCertificateValidationCallback = (s, c, h, e) => true;
await smtp.ConnectAsync("witcher.mxrouting.net", 587, SecureSocketOptions.StartTls).ConfigureAwait(false);
await smtp.AuthenticateAsync(emailUsername, emailPassword).ConfigureAwait(false);
await smtp.SendAsync(outboundMessage).ConfigureAwait(false);
await smtp.DisconnectAsync(true).ConfigureAwait(false);
}
catch (Exception ex)
{
Log.Fatal($"[Email] Failed to send email.");
Log.Fatal(ex.Message);
Log.Fatal(ex.StackTrace ?? "StackTrace was null.");
}
}
// Forward failed incoming messages for this number.
var inboundMMS = await db.Messages.Where(x => x.To.Contains(asDialedNumber.DialedNumber) && x.MessageSource == MessageSource.Incoming && x.MessageType == MessageType.MMS).ToListAsync();
var inboundSMS = await db.Messages.Where(x => x.To.Contains(asDialedNumber.DialedNumber) && x.MessageSource == MessageSource.Incoming && x.MessageType == MessageType.SMS).ToListAsync();
Expand All @@ -600,7 +680,7 @@
// Forward to the newly registered callback URL.
var messageToForward = System.Text.Json.JsonSerializer.Deserialize<ForwardedMessage>(failedMessage.ToForward);
if (messageToForward is not null && !string.IsNullOrWhiteSpace(messageToForward.Content))
if (messageToForward is not null && !string.IsNullOrWhiteSpace(messageToForward.Content) && !string.IsNullOrWhiteSpace(registration.CallbackUrl))
{
messageToForward.ClientSecret = registration.ClientSecret;
var response = await registration.CallbackUrl.PostJsonAsync(messageToForward);
Expand All @@ -611,6 +691,7 @@
failedMessage.Succeeded = true;
await db.SaveChangesAsync();
}
// Do not forward failed messages to email addresses.
}
catch (Exception ex)
{
Expand All @@ -632,7 +713,7 @@
});
}
return TypedResults.Ok(new RegistrationResponse { DialedNumber = dialedNumber, CallbackUrl = registration.CallbackUrl, Registered = true, Message = message, RegisteredUpstream = registeredUpstream, UpstreamStatusDescription = upstreamStatusDescription });
return TypedResults.Ok(new RegistrationResponse { DialedNumber = dialedNumber, CallbackUrl = registration.CallbackUrl, Email = registration.Email, Registered = true, Message = message, RegisteredUpstream = registeredUpstream, UpstreamStatusDescription = upstreamStatusDescription });
})
.RequireAuthorization().WithOpenApi(x => new(x) { Summary = "Register a client for message forwarding.", Description = "Boy I wish I had more to say about this, lmao." });
Expand Down Expand Up @@ -1771,6 +1852,7 @@ public class RegistrationRequest
public string CallbackUrl { get; set; } = string.Empty;
[DataType(DataType.Password)]
public string ClientSecret { get; set; } = string.Empty;
[DataType(DataType.EmailAddress)]
public string Email { get; set; } = string.Empty;
}

Expand All @@ -1786,6 +1868,8 @@ public class RegistrationResponse
public string Message { get; set; } = string.Empty;
public bool RegisteredUpstream { get; set; } = false;
public string UpstreamStatusDescription { get; set; } = string.Empty;
[DataType(DataType.EmailAddress)]
public string Email { get; set; } = string.Empty;
}

public class ClientRegistration
Expand All @@ -1802,5 +1886,8 @@ public class ClientRegistration
public string ClientSecret { get; set; } = string.Empty;
public bool RegisteredUpstream { get; set; } = false;
public string UpstreamStatusDescription { get; set; } = string.Empty;
[DataType(DataType.EmailAddress)]
public string Email { get; set; } = string.Empty;
public bool EmailVerified { get; set; } = false;
}
}
18 changes: 15 additions & 3 deletions NumberSearch.Mvc/Views/Cart/Order.cshtml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@using PhoneNumbersNA
@using System
@model NumberSearch.Mvc.Cart;

@{
Expand Down Expand Up @@ -69,19 +70,25 @@
let estimate = document.getElementById("estimatedinstallationtime");
let itemsCount = document.getElementById("itemsCount");
let cartCounter = document.getElementById("cartCounter");
let total = document.getElementById("sidebarTotal");
let onsiteTotal = document.getElementById("onsiteTotal");
if (hide) {
onsite.hidden = true;
estimate.hidden = true;
onsite.classList.remove("d-flex");
estimate.classList.remove("d-flex");
let newTotal = parseInt(total.innerText.replace('$', '')) - parseInt(onsiteTotal.innerText);
total.innerText = `$${newTotal}`;
itemsCount.innerText = parseInt(itemsCount.innerText) - 2;
cartCounter.innerText = parseInt(cartCounter.innerText) - 2;
} else {
onsite.hidden = false;
estimate.hidden = false;
onsite.classList.add("d-flex");
estimate.classList.add("d-flex");
let newTotal = parseInt(total.innerText.replace('$', '')) + parseInt(onsiteTotal.innerText);
total.innerText = `$${newTotal}`;
itemsCount.innerText = parseInt(itemsCount.innerText) + 2;
cartCounter.innerText = parseInt(cartCounter.innerText) + 2;
}
Expand Down Expand Up @@ -287,6 +294,7 @@
var portedTotal = 0;
var verifiedTotal = 0;
var couponTotal = 0;
var onsiteTotal = 0;
if (numbers is not null)
{
foreach (var number in numbers)
Expand Down Expand Up @@ -382,7 +390,6 @@
}
}


if (ported is not null)
{
foreach (var number in ported)
Expand Down Expand Up @@ -451,6 +458,10 @@
var localTotal = productOrder.Quantity * product.Price;
productsTotal += localTotal;
string htmlId = product.Name.Trim().Replace(" ", "").ToLowerInvariant();
if (productOrder.ProductId == Guid.Parse("b174c76a-e067-4a6a-abcf-53b6d3a848e4") || productOrder.ProductId == Guid.Parse("a032b3ba-da57-4ad3-90ec-c59a3505b075"))
{
onsiteTotal += localTotal;
}
<li class="list-group-item d-flex justify-content-between lh-condensed" id="@htmlId">
<div>
<h6 class="my-0">
Expand Down Expand Up @@ -560,11 +571,12 @@
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6>Total (USD)</h6>
<small class="text-muted">Plus installation, state and local taxes</small>
<small class="text-muted">Plus state and local taxes</small>
</div>
@{
var total = numbersTotal + portedTotal + productsTotal + servicesTotal + verifiedTotal + couponTotal;
<strong>$@total</strong>
<strong id="sidebarTotal">$@total</strong>
<div class="hidden" id="onsiteTotal">@onsiteTotal</div>
}
</li>
@{
Expand Down
39 changes: 39 additions & 0 deletions NumberSearch.Ops/Controllers/OrdersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2349,4 +2349,43 @@ public async Task<IActionResult> OrderNewInvoicesAsync(Guid orderId)
}
}
}

[Authorize]
[Route("/Order/InstallDates")]
public async Task<IActionResult> InstallDatesAsync()
{
// Show all orders
var orders = new List<Order>();

// Show only the relevant Orders to a Sales rep.
if (User.IsInRole("Sales") && !User.IsInRole("Support"))
{
var user = await _userManager.FindByNameAsync(User?.Identity?.Name ?? string.Empty);

if (user is not null)
{
orders = await _context.Orders
.Where(x => x.Quote && (x.SalesEmail == user.Email))
.OrderByDescending(x => x.DateSubmitted)
.AsNoTracking()
.ToListAsync();
}
else
{
orders = await _context.Orders.Where(x => !x.Quote)
.OrderByDescending(x => x.DateSubmitted)
.AsNoTracking()
.ToListAsync();
}
}
else
{
orders = await _context.Orders.Where(x => !x.Quote)
.OrderByDescending(x => x.DateSubmitted)
.AsNoTracking()
.ToListAsync();
}

return View("InstallDates", orders);
}
}
37 changes: 37 additions & 0 deletions NumberSearch.Ops/Views/Orders/InstallDates.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@model IEnumerable<AccelerateNetworks.Operations.Order>
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
}
<div class="table-responsive">
<table class="table table-striped table-borderless table-hover" id="table">
<thead>
<tr>
<th>Submitted Date</th>
<th>Business Name</th>
<th>Converted from Quote Date</th>
<th>Install Date</th>
<th>Completed Date</th>
<th>Completed</th>
</tr>
</thead>
<tbody>
@foreach (var order in Model)
{
string converted = order.DateConvertedFromQuote?.ToShortDateString() ?? "-";
string installed = order.InstallDate?.ToShortDateString() ?? "-";
string completed = order.DateCompleted?.ToShortDateString() ?? "-";
string name = string.IsNullOrWhiteSpace(order.BusinessName) ? $"{order.FirstName} {order.LastName}" : order.BusinessName;
<tr>
<td data-order='@order.DateSubmitted.Ticks'>@order.DateSubmitted.ToShortDateString()</td>
<td>@name</td>
<td>@converted</td>
<td>@installed</td>
<td>@completed</td>
<td>@order.Completed</td>
</tr>
}
</tbody>
</table>
</div>

0 comments on commit 7af980a

Please sign in to comment.