Backend for the Teso project written in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1014 lines
54 KiB

using System;
using System.Collections.Generic;
using System.Data;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Cloud.Firestore;
using Google.Cloud.Firestore.V1;
using Grpc.Auth;
using Grpc.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Teso_API.Methods.Controllers;
using Teso_API.Models;
namespace Teso_API.Controllers
{
[AllowAnonymous, Route("coupons")]
[ApiController]
public class CouponsController : ControllerBase
{
private readonly TESOContext _context;
private FirestoreDb db;
public CouponsController(TESOContext context)
{
_context = context;
db = new FirestoreDbBuilder
{
ProjectId = ServerLocation.credentials.project_id,
ChannelCredentials = GoogleCredential.FromJson(JsonConvert.SerializeObject(ServerLocation.credentials)).ToChannelCredentials(),
}.Build();
}
[Authorize]
[Route("acquiredcoupons"), HttpGet]
public async Task<ActionResult<IEnumerable<CouponDetails>>> GetCouponsHeads()
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
string connString = ServerLocation.connection;
string sprocname = "[dbo].[usp_acquiredCoupons_Get]";
using (SqlConnection conn = new SqlConnection(connString))
{
try
{
string result = "";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sprocname, conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@userGUID", userID);
cmd.ExecuteNonQuery();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
result += sdr[0];
}
}
}
conn.Close();
List<CouponDetails> coupons = JsonConvert.DeserializeObject<List<CouponDetails>>(result);
return coupons;
}
catch (Exception ex)
{
conn.Close();
return null;
}
}
}
//set Expiration after algorithm design
[Authorize]
[Route("proximity"), HttpPost]
public async Task<ActionResult<IEnumerable<ProximityCoupon>>> ProximityCoupons(ProximityPosition position)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
List<string> businesses = await _context.CouponsHeads.AsQueryable().Where(p => p.Type == "TESCP004" || p.Type == "TESCP003" &&
p.State == "active" && p.Expiration > DateTime.Now).Select(b => b.BusinessId).Distinct().ToListAsync();
List<ProximityCoupon> coupons = new List<ProximityCoupon>();
List<string> declined = await _context.CouponsDeclineds.AsQueryable().Where(u => u.UserGuid == userID).Select(p => p.CouponId).ToListAsync();
List<string> acquired = await _context.UserCouponBanks.AsQueryable().Where(u => u.UserGuid == userID).Select(p => p.CouponId).ToListAsync();
foreach (string p in businesses)
{
var param = new SqlParameter[] {
new SqlParameter() {
ParameterName = "@Status",
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Value = "active"
},
new SqlParameter()
{
ParameterName = "@businessID",
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Value = p
}
};
TesoBusinessDetail tesoBusiness = await _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == p).FirstOrDefaultAsync();
if (tesoBusiness != null && !String.IsNullOrEmpty(tesoBusiness.BusinessLat) && !String.IsNullOrEmpty(tesoBusiness.BusinessLng))
{
Position businessPosition = new Position
{
Latitude = double.Parse(tesoBusiness.BusinessLat),
Longitude = double.Parse(tesoBusiness.BusinessLng)
};
Position position1 = new Position
{
Latitude = position.latitude,
Longitude = position.longitude
};
HaversineClass haversine = new HaversineClass();
double distance = haversine.Distance(pos1: position1, pos2: businessPosition, type: DistanceType.Miles);
if (distance <= 1.0)
{
List<ProximityCoupon> cc = await _context.ProximityCoupons.FromSqlRaw("Select ch.couponID,ch.businessID as BusinessBusinessID,ch.productID as targetID,p.pname as targetName," +
"p.productImage as targetImage,p.unitPrice as targetCost,p.pdescription as targetDescription,cd.condition as condition," +
"ch.lowerlimit as LowerLimit,ch.upperlimit as UpperLimit, ch.expiration as Expiration,ch.businessID as BusinessID,ch.quantity as Quantity," +
"ch.state as State, cT.typeName as Type from CouponsHead ch Inner Join TesoBusinessDetail b on b.businessID = ch.businessID Inner Join Products p on p.productId = ch.productID Inner Join " +
"CouponTypes cT on cT.typeCode = ch.type Inner Join CouponCondition cd on cd.couponID = ch.couponID where ch.businessID = @businessID and ch.state = @Status", param).AsQueryable()
.Where(d => !declined.Contains(d.CouponId) && d.Expiration > DateTime.Now && !acquired.Contains(d.CouponId) && d.Type.ToLower().Contains("proximity"))
.ToListAsync();
coupons.AddRange(cc);
}
}
}
return coupons;
}
[Authorize]
[Route("declineCoupon"), HttpPost]
public async Task<ActionResult> DeclineCoupons(CouponsHead coupon)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
CouponsDeclined declined = new CouponsDeclined();
declined.DateDeclined = DateTime.Now;
declined.CouponId = coupon.CouponId;
declined.UserGuid = userID;
declined.CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID;
_context.CouponsDeclineds.Add(declined);
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
return Conflict();
}
return Ok();
}
[Authorize]
[Route("acceptCoupon"), HttpPost]
public async Task<ActionResult> AcceptCoupons(CouponsHead coupon)
{
CouponsHead head = await _context.CouponsHeads.AsQueryable().Where(d => d.CouponId == coupon.CouponId).FirstOrDefaultAsync();
if (head.Quantity > 0 && (head.Quantity - coupon.Quantity) >= 0)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
string username = jwtToken.Claims.First(claim => claim.Type == "username").Value;
List<UserCouponBank> banked = new List<UserCouponBank>();
List<CouponAcquisition> couponAcquisitions = new List<CouponAcquisition>();
string shopName = await _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == coupon.BusinessId).Select(b => b.BusinessName).FirstOrDefaultAsync();
string couponType = coupon.Type;
Product product = await _context.Products.AsQueryable().Where(b => b.ProductId == coupon.TargetProduct).FirstOrDefaultAsync();
double priceDiscounted = double.Parse(product.UnitPrice.ToString()) * (coupon.LowerLimit / 100);
int cost = CouponRateCalculator.GetRate(priceDiscounted);
for (int i = 0; i < coupon.Quantity; i++)
{
CouponAcquisition acquisition = new CouponAcquisition();
acquisition.Dateacquired = DateTime.Now;
acquisition.CouponId = coupon.CouponId;
acquisition.UserGuid = userID;
acquisition.CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 100000000) + userID + i;
if (couponType == "TESCP001" || couponType == "TESCP004")
{
acquisition.Worth = 100;
}
else
{
acquisition.Worth = coupon.LowerLimit;
}
acquisition.SilverCost = cost;
acquisition.Mode = "purchased";
acquisition.Expiration = coupon.Expiration;
couponAcquisitions.Add(acquisition);
UserCouponBank bank = new UserCouponBank();
bank.CountId = coupon.CouponId + String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID;
bank.CouponId = coupon.CouponId;
bank.UserGuid = userID;
if (couponType == "TESCP001" || couponType == "TESCP004")
{
bank.Worth = 100;
bank.Expiration = DateTime.Now.AddMinutes(60);
}
else
{
bank.Worth = coupon.LowerLimit;
bank.Expiration = await _context.CouponsHeads.AsQueryable().Where(i => i.CouponId == coupon.CouponId).Select(e => e.Expiration).FirstOrDefaultAsync();
}
acquisition.Expiration = bank.Expiration;
banked.Add(bank);
}
UserFinance finance = await _context.UserFinances.AsQueryable().Where(u => u.UserGUID == userID).FirstOrDefaultAsync();
finance.Silver = finance.Silver - (cost * coupon.Quantity.Value);
UserTransaction transaction = new UserTransaction();
transaction.RealCash = 0;
transaction.CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync(); ;
transaction.Comments = "coupon acquisition ... coupon id " + coupon.CouponId;
transaction.CoinAmount = cost * coupon.Quantity.Value;
transaction.Timestamp = DateTime.Now;
transaction.TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID;
transaction.UserGUID = userID;
transaction.TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver debit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync();
head.Quantity -= coupon.Quantity;
await SilverBankOperations.DepositToBank(transaction.CoinAmount.Value, _context);
_context.CouponAcquisitions.AddRange(couponAcquisitions);
_context.UserCouponBanks.AddRange(banked);
_context.UserTransactions.Add(transaction);
string message;
string message2;
if (coupon.Quantity > 1)
{
message = "You acquired " + coupon.Quantity + " " + couponType + " vouchers for " + product.Name + " from " + shopName + " with " + cost.ToString() +
" silver coins ";
message2 = username + " acquired " + coupon.Quantity + " " + couponType + " vouchers for " + product.Name + " from " + shopName;
}
else
{
message = "You acquired a " + couponType + " voucher for " + product.Name + " from " + shopName + " with " + cost.ToString() +
" silver coins ";
message2 = username + " acquired " + coupon.Quantity + " " + couponType + " vouchers for " + product.Name + " from " + shopName;
}
if (couponType == "TESCP001" || couponType == "TESCP004")
message = message + "which expires in 60 minutes";
try
{
await _context.SaveChangesAsync();
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(userID).Collection(userID).Document();
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "notificationType", "redeemable" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", message },
{ "couponID", coupon.CouponId },
{ "productImage", product.ProductImage },
};
DocumentReference BusdocRef = db.Collection(ServerLocation.business_notifications).Document(product.BusinessId).Collection(product.BusinessId).Document();
Dictionary<string, object> Bususer = new Dictionary<string, object>
{
{ "notificationType", "couponAcquisition" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", message2 },
{ "couponID", coupon.CouponId },
{ "userID", userID},
};
await docRef.SetAsync(user);
await BusdocRef.SetAsync(Bususer);
}
catch (DbUpdateException)
{
return Conflict();
}
return Ok(message);
}
else
{
return StatusCode(999);
}
}
[Authorize]
[Route("qrCoupon"), HttpPost]
public async Task<ActionResult<IEnumerable<CouponDetails>>> GetShopCoupons([FromBody] string businessID)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
try
{
DailyVisit visit = await _context.DailyVisits.AsQueryable().Where(u => u.UserGuid == userID && u.Timestamp.Value.Month == DateTime.Now.Month &&
u.Timestamp.Value.Day == DateTime.Now.Day && u.Timestamp.Value.Year == DateTime.Now.Year).FirstOrDefaultAsync();
if (visit == null)
{
visit = new DailyVisit
{
BusinessId = businessID,
CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID,
Timestamp = DateTime.Now,
UserGuid = userID
};
_context.DailyVisits.Add(visit);
await _context.SaveChangesAsync();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
var param = new SqlParameter[] {
new SqlParameter() {
ParameterName = "@user",
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Value = userID
},
new SqlParameter()
{
ParameterName = "@businessID",
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Value = businessID
}
};
string connString = ServerLocation.connection;
string sprocname = "[dbo].[usp_scanqrcode_Get]";
using (SqlConnection conn = new SqlConnection(connString))
{
try
{
string result = "";
conn.Open();
using (SqlCommand cmd = new SqlCommand(sprocname, conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@userGUID", userID);
cmd.Parameters.AddWithValue("@businessID", businessID);
cmd.ExecuteNonQuery();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
result += sdr[0];
}
}
}
conn.Close();
List<CouponDetails> coupons = JsonConvert.DeserializeObject<List<CouponDetails>>(result);
return coupons;
}
catch (Exception ex)
{
conn.Close();
return null;
}
}
//List<CouponDetails> coupons = new List<CouponDetails>();
//List<CouponDetails> acquired = await _context.Details.FromSqlRaw("Select ch.couponID as CouponID,ch.businessID as BusinessId,ct.TypeName as Type,ch.quantity as Quantity," +
// "ch.expiration as Expiration,ca.worth as Worth,ch.state as State,ch.businessID as IssuerBusinessID,ch.productID as TargetProductID,ch.lowerLimit as LowerLimit,ch.upperLimit as UpperLimit " +
// ",ch.productID as ProductCost,ca.countID as CountID, cd.condition as condition From CouponsHead ch Inner Join CouponTypes ct on ch.type = ct.typeCode Inner Join UserCouponBank ca on ca.couponID = ch.couponID " +
// "Inner Join Products p on p.productID = ch.productID Inner Join CouponCondition cd on ch.couponID = cd.CouponID where ca.userGUID = @user and ch.businessID = @businessID", param)
// .AsQueryable().Where(e => e.Expiration > DateTime.Now && e.State == "active").ToListAsync();
//coupons.AddRange(acquired);
//List<CouponDetails> shop = await _context.Details.FromSqlRaw("Select ch.couponID as CouponID,ch.businessID as BusinessId,ct.TypeName as Type,ch.quantity as Quantity," +
// "ch.expiration as Expiration,(Cast(0.0 as float)) as Worth,ch.state as State,ch.businessID as IssuerBusinessID,ch.productID as TargetProductID,ch.lowerLimit as LowerLimit,ch.upperLimit as UpperLimit" +
// ",ch.productID as ProductCost,'null' as CountID, cd.condition as condition From CouponsHead ch Inner Join CouponTypes ct on ch.type = ct.typeCode Inner Join Products p on p.productID = ch.productID " +
// "Inner Join CouponCondition cd on ch.couponID = cd.CouponID where ch.businessID = @businessID", param).AsQueryable()
// .Where(e => !acquired.Contains(e) && e.Expiration > DateTime.Now && e.State == "active").ToListAsync();
//coupons.AddRange(shop);
//foreach (CouponDetails details in coupons)
//{
// details.Issuer = await _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == details.BusinessId).FirstOrDefaultAsync();
// details.Target = await _context.Products.AsQueryable().Where(b => b.ProductId == details.ProductCost).FirstOrDefaultAsync();
// if (String.IsNullOrEmpty(details.condition)) details.condition = "none";
//}
}
[Authorize]
[Route("viewCoupon"), HttpPost]
public async Task<ActionResult> ViewCoupons(CouponsHead head)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
CouponDetails coupon = new CouponDetails();
coupon.BusinessId = head.BusinessId;
coupon.CouponId = head.CouponId;
coupon.Expiration = head.Expiration;
coupon.lowerLimit = await _context.CouponsHeads.AsQueryable().Where(d => d.CouponId == head.CouponId).Select(e => e.LowerLimit).FirstOrDefaultAsync();
coupon.upperLimit = await _context.CouponsHeads.AsQueryable().Where(d => d.CouponId == head.CouponId).Select(e => e.UpperLimit).FirstOrDefaultAsync();
coupon.Quantity = head.Quantity;
coupon.State = head.State;
coupon.Target = await _context.Products.AsQueryable().Where(p => p.ProductId == head.TargetProduct).FirstOrDefaultAsync();
coupon.Issuer = await _context.TesoBusinessDetails.AsQueryable().Where(p => p.BusinessId == head.BusinessId).FirstOrDefaultAsync();
coupon.Type = head.Type;
DocumentReference docRef = db.Collection("recentlyViewed").Document("users").Collection(userID).Document(coupon.CouponId);
Dictionary<string, object> user = new Dictionary<string, object>
{
{"couponId", coupon.CouponId },
{"businessId",coupon.Issuer.BusinessId },
{ "type", coupon.Type},
{ "quantity", coupon.Quantity },
{ "expiration",coupon.Expiration.Value.ToString("yyyy-MM-dd HH:mm:ss")},
{ "worth",coupon.Worth},
{ "state", coupon.State},
{ "productCost", coupon.Target.UnitPrice.ToString()},
{"businessName",coupon.Issuer.BusinessName},
{"businessDescription",coupon.Issuer.BusinessDescription},
{"businessCategory",coupon.Issuer.BusinessCategory},
{"businessAddress",coupon.Issuer.BusinessAddress},
{"businessContact",coupon.Issuer.BusinessContact},
{"businessLogo",coupon.Issuer.BusinessLogo},
{"businessLat",coupon.Issuer.BusinessLat},
{"businessLng",coupon.Issuer.BusinessLng},
{"productId",coupon.Target.ProductId},
{"name",coupon.Target.Name},
{"description",coupon.Target.Description},
{"category",coupon.Target.Category},
{"unitPrice",coupon.Target.UnitPrice.ToString()},
{"productImage",coupon.Target.ProductImage},
{"lowerLimit",coupon.lowerLimit.ToString()},
{"upperLimit",coupon.upperLimit.ToString()},
{"dateViewed",new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
};
if (TrendingExists(head.TargetProduct))
{
TrendingProduct trend = await _context.TrendingProducts.AsQueryable().Where(p => p.ProductId == head.TargetProduct).FirstOrDefaultAsync();
trend.Views += 1;
}
else
{
TrendingProduct trend = new TrendingProduct();
trend.ProductId = coupon.Target.ProductId;
trend.Views = 1;
_context.TrendingProducts.Add(trend);
}
try
{
await _context.SaveChangesAsync();
await docRef.SetAsync(user);
}
catch (DbUpdateException)
{
return StatusCode(500);
}
return Ok();
}
[Authorize]
[Route("giftCoupon"), HttpPost]
public async Task<ActionResult> GiftCoupons(CouponsHead details)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
TesoUserDetail userT = await _context.TesoUserDetails.AsQueryable().Where(u => u.UserGUID == userID).FirstOrDefaultAsync();
UserCouponBank userCoupon = await _context.UserCouponBanks.AsQueryable().Where(c => c.CountId == details.State).FirstOrDefaultAsync();
Product product = await _context.Products.AsQueryable().Where(p => p.ProductId == details.TargetProduct).FirstOrDefaultAsync();
string type = await _context.CouponsHeads.AsQueryable().Where(c => c.CouponId == details.CouponId).Select(t => t.Type).AsNoTracking().FirstOrDefaultAsync();
UserCouponBank recipient = new UserCouponBank();
recipient.CountId = details.CouponId + String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + details.Type;
recipient.CouponId = details.CouponId;
recipient.UserGuid = details.Type;
recipient.Worth = (details.LowerLimit / 100) * userCoupon.Worth;
recipient.Expiration = userCoupon.Expiration;
userCoupon.Worth -= recipient.Worth;
CouponAcquisition acquisition = new CouponAcquisition();
acquisition.CountId = details.CouponId + String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + details.Type;
acquisition.CouponId = details.CouponId;
acquisition.Dateacquired = DateTime.Now;
acquisition.Expiration = userCoupon.Expiration;
acquisition.Mode = "gifted";
acquisition.SilverCost = 0;
acquisition.UserGuid = recipient.UserGuid;
acquisition.Worth = recipient.Worth;
if (userCoupon.Worth == 0 || type == "TESCP001" || type == "TESCP004")
{
_context.Remove(userCoupon);
}
_context.UserCouponBanks.Add(recipient);
_context.CouponAcquisitions.Add(acquisition);
try
{
await _context.SaveChangesAsync();
string message = "";
if (type == "TESCP001" || type == "TESCP004")
{
message = userT.Firstname + " " + userT.Surname + " has gifted you a " + details.BusinessId + "'s Freebie voucher for " + product.Name;
}
else
{
message = userT.Firstname + " " + userT.Surname + " has gifted you a " + details.BusinessId + "'s voucher worth "
+ recipient.Worth.ToString() + " % OFF for " + product.Name;
}
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(recipient.UserGuid).Collection(recipient.UserGuid).Document();
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "notificationType", "gifted" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", message },
{ "couponID", details.CouponId },
{ "productImage", product.ProductImage },
{ "recipient", recipient.UserGuid },
};
await docRef.SetAsync(user);
}
catch (Exception ex)
{
return BadRequest();
}
return Ok();
}
[Authorize]
[Route("productCoupon"), HttpPost]
public async Task<ActionResult<IEnumerable<CouponDetails>>> GetProductCoupons([FromBody] string productID)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
List<CouponDetails> coupons = await (from c in _context.CouponsHeads.AsQueryable()
join ct in _context.CouponTypes on c.Type equals ct.TypeCode
join p in _context.Products on c.TargetProduct equals p.ProductId
join con in _context.CouponConditions on c.CouponId equals con.CouponId into Conditions
from cond in Conditions.DefaultIfEmpty()
where p.ProductId == productID && c.Quantity > 0 && c.State == "active"
&& (c.Type == "TESCP001" || c.Type == "TESCP002")
select new CouponDetails()
{
BusinessId = p.BusinessId,
condition = cond.Condition,
countID = c.CouponId,
CouponId = c.CouponId,
Expiration = c.Expiration,
Issuer = _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == p.BusinessId).FirstOrDefault(),
lowerLimit = c.LowerLimit,
ProductCost = p.ProductId,
Quantity = c.Quantity,
State = c.State,
Target = p,
Type = ct.TypeName,
upperLimit = c.UpperLimit,
Worth = 0
}
).ToListAsync();
//List<CouponDetails> coupons = await _context.Details.FromSqlRaw("Select ch.couponID as CouponID,ch.businessID as BusinessId,ct.TypeName as Type,ch.quantity as Quantity," +
// "ch.expiration as Expiration,(Cast(0.0 as float)) as Worth,ch.state as State,ch.businessID as IssuerBusinessID,ch.productID as TargetProductID,ch.lowerLimit as LowerLimit,ch.upperLimit as UpperLimit" +
// ",ch.productID as ProductCost,'null' as CountID, cd.condition as condition From CouponsHead ch Inner Join CouponTypes ct on ch.type = ct.typeCode Inner Join Products p on p.productID = ch.productID " +
// "Inner Join CouponCondition cd on ch.couponID = cd.CouponID where ch.productID = @productID", param).AsQueryable()
// .Where(e => e.Expiration > DateTime.Now && e.State == "active").ToListAsync();
//foreach (CouponDetails details in coupons)
//{
// details.Issuer = await _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == details.BusinessId).FirstOrDefaultAsync();
// details.Target = await _context.Products.AsQueryable().Where(b => b.ProductId == details.ProductCost).FirstOrDefaultAsync();
// if (String.IsNullOrEmpty(details.condition)) details.condition = "none";
//}
return coupons;
}
[Route("redeemCoupon"), HttpPost]
public async Task<ActionResult<UserFinance>> RedeemCoupons(CouponDetails coupon)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
string username = jwtToken.Claims.First(claim => claim.Type == "username").Value;
try
{
UserCouponBank bank = await _context.UserCouponBanks.AsQueryable().Where(u => u.UserGuid == userID && u.CouponId == coupon.CouponId).FirstOrDefaultAsync();
string type = await _context.CouponsHeads.AsQueryable().Where(c => c.CouponId == coupon.CouponId).Select(t => t.Type).AsNoTracking().FirstOrDefaultAsync();
CouponAcquisition acquiredMain = new CouponAcquisition();
CouponAcquisition acquired = await _context.CouponAcquisitions.AsQueryable().Where(u => u.UserGuid == userID && u.CouponId == coupon.CouponId).FirstOrDefaultAsync();
int calculated = 0;
if (acquired.Mode == "gifted")
{
acquiredMain = await _context.CouponAcquisitions.AsQueryable().Where(u => u.Mode.ToLower() == "purchased" && u.CouponId == coupon.CouponId).FirstOrDefaultAsync();
int refund;
if (type == "TESCP001" || type == "TESCP004")
{
refund = acquiredMain.SilverCost.Value;
}
else
{
double percentageWorth = (acquired.Worth.Value / acquiredMain.Worth.Value);
calculated = RedemptionReturn.CalculateReturns(acquired.SilverCost.Value);
refund = (int)Math.Round((calculated - (calculated / percentageWorth) * 100), MidpointRounding.ToPositiveInfinity);
}
if (refund > 0)
{
UserFinance finance = await _context.UserFinances.AsQueryable().Where(u => u.UserGUID == acquiredMain.UserGuid).FirstOrDefaultAsync();
finance.Silver += refund;
}
UserTransaction transaction = new UserTransaction();
transaction.RealCash = 0;
transaction.CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync(); ;
transaction.Comments = "coupon redemption ... coupon id " + coupon.CouponId;
transaction.CoinAmount = refund;
transaction.Timestamp = DateTime.Now;
transaction.TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID;
transaction.UserGUID = userID;
transaction.TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver credit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync();
_context.UserTransactions.Add(transaction);
bool possible = await SilverBankOperations.WithdrawFromBank(refund, _context);
if (!possible)
return StatusCode(500);
}
else
{
if (type == "TESCP001" || type == "TESCP004" || type == "TESCP005" || type == "TESCP006")
{
calculated = acquired.SilverCost.Value;
}
else
{
calculated = RedemptionReturn.CalculateReturns(acquired.SilverCost.Value);
}
UserFinance finance = await _context.UserFinances.AsQueryable().Where(u => u.UserGUID == acquired.UserGuid).FirstOrDefaultAsync();
finance.Silver += calculated;
UserTransaction transaction = new UserTransaction();
transaction.RealCash = 0;
transaction.CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync(); ;
transaction.Comments = "coupon redemption ... coupon id " + coupon.CouponId;
transaction.CoinAmount = calculated;
transaction.Timestamp = DateTime.Now;
transaction.TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID;
transaction.UserGUID = userID;
transaction.TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver credit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync();
_context.UserTransactions.Add(transaction);
bool possible = await SilverBankOperations.WithdrawFromBank(calculated, _context);
if (!possible)
return StatusCode(500);
}
double price = double.Parse(coupon.Target.UnitPrice.Value.ToString());
double worth = price - (price * bank.Worth.Value / 100);
CouponRedemption redeemed = new CouponRedemption
{
CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID,
CouponId = coupon.CouponId,
Discount = bank.Worth,
UserGuid = userID,
Timestamp = DateTime.Now,
Worth = decimal.Parse(worth.ToString())
};
DailyVisit visit = await _context.DailyVisits.AsQueryable().Where(u => u.UserGuid == userID && u.Timestamp.Value.Month == DateTime.Now.Month &&
u.Timestamp.Value.Day == DateTime.Now.Day && u.Timestamp.Value.Year == DateTime.Now.Year).FirstOrDefaultAsync();
if (visit == null)
{
visit = new DailyVisit
{
BusinessId = coupon.BusinessId,
CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userID,
Timestamp = DateTime.Now,
UserGuid = userID
};
_context.DailyVisits.Add(visit);
}
_context.UserCouponBanks.Remove(bank);
_context.CouponRedemptions.Add(redeemed);
await _context.SaveChangesAsync();
if (acquired.Mode == "gifted")
{
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(acquiredMain.UserGuid).Collection(acquiredMain.UserGuid).Document();
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "notificationType", "gifted" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", username + " redeemed a coupon you gifted them therefore you get silver coins back" },
{ "couponID", coupon.CouponId },
{ "productImage", coupon.Target.ProductImage },
{ "recipient", acquiredMain.UserGuid },
};
DocumentReference docRef1 = db.Collection(ServerLocation.user_notifications).Document(userID).Collection(userID).Document();
Dictionary<string, object> user1 = new Dictionary<string, object>
{
{ "notificationType", "redeemable" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", "You successfully redeemed a coupon" },
{ "couponID", coupon.CouponId },
{ "productImage", coupon.Target.ProductImage },
};
await docRef.SetAsync(user);
await docRef1.SetAsync(user1);
}
else
{
DocumentReference docRef1 = db.Collection(ServerLocation.user_notifications).Document(userID).Collection(userID).Document();
Dictionary<string, object> user1 = new Dictionary<string, object>
{
{ "notificationType", "redeemable" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", "You successfully redeemed a coupon" },
{ "couponID", coupon.CouponId },
{ "productImage", coupon.Target.ProductImage },
};
await docRef1.SetAsync(user1);
}
if (coupon.BusinessId == ServerLocation.tesoghanaID)
{
string businessMessage = username + " just redeemed a coupon from the shop";
DocumentReference BusdocRef = db.Collection(ServerLocation.business_notifications).Document(coupon.Issuer.BusinessId).Collection(coupon.Issuer.BusinessId).Document();
Dictionary<string, object> Bususer = new Dictionary<string, object>
{
{ "notificationType", "couponRedemption" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", businessMessage },
{ "couponID", coupon.CouponId },
{ "userID", userID},
};
string businessMessageTeso = username + " just redeemed a coupon at " + coupon.Issuer.BusinessName;
DocumentReference BusdocRef2 = db.Collection(ServerLocation.business_notifications).Document(coupon.BusinessId).Collection(coupon.BusinessId).Document();
Dictionary<string, object> Bususer2 = new Dictionary<string, object>
{
{ "notificationType", "couponRedemption" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", businessMessageTeso },
{ "couponID", coupon.CouponId },
{ "userID", userID},
};
await BusdocRef2.SetAsync(Bususer2);
await BusdocRef.SetAsync(Bususer);
}
else
{
string businessMessage = username + " just redeemed a coupon from the shop";
DocumentReference BusdocRef = db.Collection(ServerLocation.business_notifications).Document(coupon.Issuer.BusinessId).Collection(coupon.Issuer.BusinessId).Document();
Dictionary<string, object> Bususer = new Dictionary<string, object>
{
{ "notificationType", "couponRedemption" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", businessMessage },
{ "couponID", coupon.CouponId },
{ "userID", userID},
};
await BusdocRef.SetAsync(Bususer);
}
return Ok(calculated);
}
catch (DbUpdateException)
{
return Conflict();
}
}
[Authorize]
[Route("acceptPersonalized"), HttpPost]
public async Task<ActionResult> AcceptPerosnalizedCoupons(CouponsHead coupon)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
string username = jwtToken.Claims.First(claim => claim.Type == "username").Value;
string shopname = await _context.TesoBusinessDetails.AsQueryable().Where(i => i.BusinessId == coupon.BusinessId).Select(n => n.BusinessName).FirstOrDefaultAsync();
Product product = await _context.Products.AsQueryable().Where(p => p.ProductId == coupon.TargetProduct).FirstOrDefaultAsync();
DocumentReference deleteRef = db.Collection(ServerLocation.user_notifications).Document(userID).Collection(userID).Document(coupon.CouponId);
if (coupon.Expiration > DateTime.Now)
{
CouponsHead couponsHead = new CouponsHead();
couponsHead.BusinessId = coupon.BusinessId;
couponsHead.CouponId = "TESCP" + String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + coupon.BusinessId;
couponsHead.Expiration = coupon.Expiration;
couponsHead.Quantity = 1;
couponsHead.State = "active";
couponsHead.TargetProduct = coupon.TargetProduct;
couponsHead.Type = coupon.Type;
couponsHead.LowerLimit = coupon.LowerLimit;
couponsHead.UpperLimit = coupon.UpperLimit;
couponsHead.Generated = coupon.Generated;
CouponCondition condition = new CouponCondition();
condition.CouponId = couponsHead.CouponId;
if (!String.IsNullOrEmpty(coupon.State))
{
condition.Condition = coupon.State;
}
else
{
condition.Condition = "none";
}
_context.CouponAcquisitions.Add(new CouponAcquisition
{
CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 100000000) + userID,
CouponId = couponsHead.CouponId,
Dateacquired = DateTime.Now,
Expiration = coupon.Expiration,
Mode = "personalized",
SilverCost = 0,
UserGuid = userID,
Worth = couponsHead.UpperLimit,
});
_context.UserCouponBanks.Add(new UserCouponBank
{
CountId = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 100000000) + userID,
CouponId = couponsHead.CouponId,
Expiration = coupon.Expiration,
Worth = couponsHead.UpperLimit,
UserGuid = userID
});
_context.CouponsHeads.Add(couponsHead);
_context.CouponConditions.Add(condition);
try
{
await _context.SaveChangesAsync();
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(userID).Collection(userID).Document();
Dictionary<string, object> user = new Dictionary<string, object>
{
{ "notificationType", "redeemable" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", $"Congrats you just accepted a personalized coupon from {shopname}" },
{ "couponID", coupon.CouponId },
{ "productImage", product.ProductImage },
};
DocumentReference BusdocRef = db.Collection(ServerLocation.business_notifications).Document(product.BusinessId).Collection(product.BusinessId).Document();
Dictionary<string, object> Bususer = new Dictionary<string, object>
{
{ "notificationType", "couponAcquisition" },
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
{ "message", $"{username} just accepted a personalized coupon you sent them!!" },
{ "couponID", couponsHead.CouponId },
{ "userID", userID},
};
await docRef.SetAsync(user);
await deleteRef.DeleteAsync();
await BusdocRef.SetAsync(Bususer);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return StatusCode(500);
}
return Ok();
}
else
{
await deleteRef.DeleteAsync();
return StatusCode(400);
}
}
[Authorize]
[Route("campaign_coupons"), HttpPost]
public async Task<ActionResult<IEnumerable<CouponDetails>>> GetCampaignCoupons([FromBody] string campaignID)
{
var accessToken = Request.Headers[HeaderNames.Authorization];
string token = accessToken;
token = token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadToken(token) as JwtSecurityToken;
string userID = jwtToken.Claims.First(claim => claim.Type == "userGUID").Value;
List<CouponDetails> coupons = await (from c in _context.CouponsHeads.AsQueryable()
join ct in _context.CouponTypes on c.Type equals ct.TypeCode
join cam in _context.Campaigns on c.TargetProduct equals cam.TargetProduct into campaignList
from campaignItem in campaignList.DefaultIfEmpty()
join p in _context.Products on campaignItem.TargetProduct equals p.ProductId
join con in _context.CouponConditions on c.CouponId equals con.CouponId
where campaignItem.CampaignId == campaignID && c.Quantity > 0 && c.State == "active"
&& (c.Type == "TESCP001" || c.Type == "TESCP002")
select new CouponDetails()
{
BusinessId = campaignItem.BusinessId,
condition = con.Condition,
countID = c.CouponId,
CouponId = c.CouponId,
Expiration = c.Expiration,
Issuer = _context.TesoBusinessDetails.AsQueryable().Where(b => b.BusinessId == campaignItem.BusinessId).FirstOrDefault(),
lowerLimit = c.LowerLimit,
ProductCost = p.ProductId,
Quantity = c.Quantity,
State = c.State,
Target = p,
Type = ct.TypeName,
upperLimit = c.UpperLimit,
Worth = 0
}
).ToListAsync();
return coupons;
}
private bool TrendingExists(string id)
{
return _context.TrendingProducts.Any(e => e.ProductId == id);
}
}
}