public async Task <Comment> AddComment(string photoId, string albumId, string message, User requestor) { if (!await _permissionsService.CanComment(requestor, albumId)) { return(null); } var photo = await _photoService.GetPhoto(photoId); var comment = new Comment { ReactionId = _guid.NewGuid().ToString(), Text = message, Reactor = requestor, ReactionDate = _clock.UtcNow }; var photoComment = new PhotoComment { Photo = photo, Comment = comment }; photo.PhotoComments.Add(photoComment); await _unitOfWork.Photos.Update(photo); return(comment); }
public async Task <DepartmentModel> Handle(CreateDepartment request, CancellationToken cancellationToken) { Store store = await dbContext.Stores .SingleOrDefaultAsync(x => x.Uuid == request.Model.StoreId, cancellationToken) ?? throw new NotFoundException(nameof(CreateDepartmentModel.StoreId)); if (store.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } DateTimeOffset now = dateTimeOffset.Now; var department = new Department { CreatedAt = now, Description = request.Model.Description?.CleanTrim(), Name = request.Model.Name?.CleanTrim() ?? throw new InvalidOperationException("The Name is required."), Number = request.Model.Number?.CleanTrim(), Store = store, StoreId = store.Id, UpdatedAt = now, Uuid = guid.NewGuid() }; dbContext.Departments.Add(department); await dbContext.SaveChangesAsync(cancellationToken); return(mapper.Map <DepartmentModel>(department)); } }
public Task <ProcessRejectedPaymentResponse> Handle(ProcessRejectedPaymentRequest request, CancellationToken cancellationToken = default) { var merchantKey = _merchantEncryptionKeyGetter.Key(request.Merchant.Id); var paymentRecord = new PaymentRecord { Id = _guid.NewGuid().ToString(), Source = new PaymentRecord.PaymentSource { CardExpiryEncrypted = _encrypter.EncryptUtf8(request.Source.CardExpiry, merchantKey), CardNumberEncrypted = _encrypter.EncryptUtf8(request.Source.CardNumber, merchantKey), CvvEncrypted = _encrypter.EncryptUtf8(request.Source.Cvv, merchantKey) }, Recipient = new PaymentRecord.PaymentRecipient { AccountNumberEncrypted = _encrypter.EncryptUtf8(request.Recipient.AccountNumber, merchantKey), SortCodeEncrypted = _encrypter.EncryptUtf8(request.Recipient.SortCode, merchantKey), }, Currency = request.Currency, Status = PaymentStatus.Rejected, Amount = request.Amount, CreatedAt = _dateTime.UtcNow(), MerchantId = request.Merchant.Id, FailureReason = request.BankResponse.FailureReason, }; _paymentRecordCreator.Add(paymentRecord); return(Task.FromResult(new ProcessRejectedPaymentResponse { Id = paymentRecord.Id })); }
public async Task <TokenModel> Handle(LogIn request, CancellationToken cancellationToken) { Account account = await dbContext.Accounts.SingleOrDefaultAsync( x => x.Username == request.Model.Username.ToLowerInvariant(), cancellationToken ); if (account?.Password.Match(request.Model.Password) != true) { throw new InvalidCredentialException(); } else if (account.ConfirmedAt == null) { throw new NotConfirmedException(); } var session = new Session { Account = account, AccountId = account.Id, CreatedAt = dateTimeOffset.Now, Uuid = guid.NewGuid() }; TokenModel model = authenticationService.GetToken(session); dbContext.Sessions.Add(session); await dbContext.SaveChangesAsync(cancellationToken); return(model); }
public async Task <Photo> StorePhoto(byte[] image, User author, string albumId) { if (!await _permissionsService.CanAddPicture(author, albumId)) { return(null); } var id = _guid.NewGuid().ToString(); var photo = new Photo { Author = author, PhotoComments = new List <PhotoComment>(), PhotoLikes = new List <PhotoLike>(), Link = $"{author.LastName}/{author.FirstName}/{id}", PhotoId = id, TakeDate = _clock.UtcNow }; var album = await _albumService.GetAlbum(albumId); album.Photos.Add(photo); await _unitOfWork.Albums.Update(album); await _ftpService.StorePhotoOnFtp(image, photo); return(photo); }
private string GenerateNewTempPath() { string tempFileName = _guid.NewGuid().ToString(); string fullTempPath = Path.Combine(_configSettings.PhysicalSitePath, _configSettings.RelativeTemporaryDirectory); return(string.Format(@"{0}\{1}", fullTempPath, tempFileName)); }
public async Task <CreateNmedianPayload> CreateNmedianAsync( CreateNmedianInput input, [Service] IDateTimeOffset dateTimeOffset, [Service] IGuid guid, [ScopedService] NmediaContext dbContext, CancellationToken cancellationToken ) { var entity = new Nmedian { Age = input.Age, Created = dateTimeOffset.Now, IsActive = input.IsActive, Hired = input.Hired, HourlyRate = input.HourlyRate, JobTitle = input.JobTitle, Name = input.Name, Picture = input.Picture, Slug = input.Slug, Uuid = guid.NewGuid() }; dbContext.Nmedians.Add(entity); await dbContext.SaveChangesAsync(cancellationToken); return(new CreateNmedianPayload(entity)); }
private async Task SaveUser(User user) { if (await _unitOfWork.Users.Any(x => x.Email == user.Email)) { return; } user.UserId = _guid.NewGuid().ToString(); user.CreationDate = _clock.UtcNow; await _unitOfWork.Users.Add(user); }
public async Task <ArticleModel> Handle(SaveArticle request, CancellationToken cancellationToken) { if (_appContext.User.Role != Role.Master) { throw new ForbiddenException(); } Nmedian?nmedian = null; if (request.Model.NmedianId.HasValue) { nmedian = await _dbContext.Nmedians .SingleOrDefaultAsync(x => x.Uuid == request.Model.NmedianId.Value, cancellationToken) ?? throw new NotFoundException(nameof(request.Model.NmedianId)); } Article entity; if (request.Id.HasValue) { entity = await _dbContext.Articles .SingleOrDefaultAsync(x => x.Uuid == request.Id.Value, cancellationToken) ?? throw new NotFoundException(); entity.Updated = _dateTimeOffset.Now; } else { entity = new Article { Created = _dateTimeOffset.Now, Uuid = _guid.NewGuid() }; _dbContext.Articles.Add(entity); } entity.Categories = request.Model.Categories ?.Select(category => Enum.Parse <Category>(category)) .Distinct() .ToArray(); entity.Content = request.Model.Content.CleanTrim(); entity.Nmedian = nmedian; entity.NmedianId = nmedian?.Id; entity.Picture = request.Model.Picture?.CleanTrim(); entity.Published = request.Model.Published; entity.Title = request.Model.Title?.CleanTrim() ?? throw new InvalidOperationException("The Title is required."); await _dbContext.SaveChangesAsync(cancellationToken); return(_mapper.Map <ArticleModel>(entity)); }
public async override Task <UserSessionBO> RunAsync(CreateSessionCmd process, CancellationToken cancellationToken = default) { var user = await p_DbContext.UserLogins .Include(a => a.User) .SingleOrDefaultAsync(a => a.Username == process.Username); if (user == null) { throw new LynxException("User not found"); } // we need to revoke active sessions to prevent multiple logins //TODO: this may cause performance problem in the future p_DbContext.UserSessions .Where(a => a.Status == SessionStatus.Active && a.ExpiredOn >= p_DateTime.Now && a.UserID == user.ID) .ToList() .ForEach(session => { session.Status = SessionStatus.Revoked; session.Remarks = "Forced expired to prevent multiple login"; }); var newSession = new UserSessionBO { UserID = user.ID, CreatedOn = p_DateTime.Now, SessionID = p_Guid.NewGuid(), Status = SessionStatus.Active, Token = p_Guid.NewGuid().ToString("D"), }; p_DbContext.UserSessions.Add(p_Mapper.Map <UserSession>(newSession)); return(newSession); }
public async Task <Album> CreateAlbum(User creator, string name) { if (await _unitOfWork.Albums.Any(x => x.Name == name)) { return(null); } var album = new Album { Name = name, AlbumId = _guid.NewGuid().ToString(), Creator = creator, CreationDate = _clock.UtcNow }; await _unitOfWork.Albums.Add(album); return(album); }
public async Task <NmedianModel> Handle(SaveNmedian request, CancellationToken cancellationToken) { if (_appContext.User.Role != Role.Master) { throw new ForbiddenException(); } Nmedian entity; if (request.Id.HasValue) { entity = await _dbContext.Nmedians .SingleOrDefaultAsync(x => x.Uuid == request.Id.Value, cancellationToken) ?? throw new NotFoundException(); entity.Updated = _dateTimeOffset.Now; } else { entity = new Nmedian { Created = _dateTimeOffset.Now, Uuid = _guid.NewGuid() }; _dbContext.Nmedians.Add(entity); } entity.Age = request.Model.Age; entity.Hired = request.Model.Hired; entity.HourlyRate = request.Model.HourlyRate; entity.IsActive = request.Model.IsActive; entity.JobTitle = request.Model.JobTitle == null ? (JobTitle?)null : Enum.Parse <JobTitle>(request.Model.JobTitle); entity.Name = request.Model.Name?.CleanTrim() ?? throw new InvalidOperationException("The Name is required."); entity.Picture = request.Model.Picture?.CleanTrim(); entity.Slug = request.Model.Slug?.CleanTrim(); await _dbContext.SaveChangesAsync(cancellationToken); return(_mapper.Map <NmedianModel>(entity)); }
public async Task <ArticleModel> Handle(SaveArticle request, CancellationToken cancellationToken) { Article article; if (request.Id.HasValue) { article = await dbContext.Articles .SingleOrDefaultAsync(x => x.Uuid == request.Id.Value, cancellationToken) ?? throw new NotFoundException(); if (article.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } article.UpdatedAt = dateTimeOffset.Now; } else { DateTimeOffset now = dateTimeOffset.Now; article = new Article { AccountId = appContext.Account !.Id, CreatedAt = now, UpdatedAt = now, Uuid = guid.NewGuid() }; dbContext.Articles.Add(article); } article.Description = request.Model.Description?.CleanTrim(); article.Gtin = request.Model.Gtin; article.Name = request.Model.Name?.CleanTrim() ?? throw new InvalidOperationException("The Name is required."); await dbContext.SaveChangesAsync(cancellationToken); return(mapper.Map <ArticleModel>(article)); } }
public async Task <CreateArticlePayload> CreateArticleAsync( CreateArticleInput input, [Service] IDateTimeOffset dateTimeOffset, [Service] IGuid guid, [Service] ITopicEventSender sender, [ScopedService] NmediaContext dbContext, CancellationToken cancellationToken ) { Nmedian?nmedian = null; if (input.NmedianId.HasValue) { nmedian = await dbContext.Nmedians.SingleOrDefaultAsync( x => x.Uuid == input.NmedianId.Value, cancellationToken ) ?? throw new ArgumentException($"The Nmédian (ID={input.NmedianId}) could not be found.", nameof(input)); } var entity = new Article { Categories = input.Categories, Content = input.Content, Created = dateTimeOffset.Now, Nmedian = nmedian, NmedianId = nmedian?.Id, Picture = input.Picture, Published = input.Published, Title = input.Title, Uuid = guid.NewGuid() }; dbContext.Articles.Add(entity); await dbContext.SaveChangesAsync(cancellationToken); await sender.SendAsync(nameof(Subscription.OnArticleSaved), entity, cancellationToken); return(new CreateArticlePayload(entity)); }
public async Task <BannerModel> Handle(SaveBanner request, CancellationToken cancellationToken) { Banner banner; if (request.Id.HasValue) { banner = await dbContext.Banners .SingleOrDefaultAsync(x => x.Uuid == request.Id.Value, cancellationToken) ?? throw new NotFoundException(); if (banner.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } banner.UpdatedAt = dateTimeOffset.Now; } else { DateTimeOffset now = dateTimeOffset.Now; banner = new Banner { AccountId = appContext.Account !.Id, CreatedAt = now, UpdatedAt = now, Uuid = guid.NewGuid() }; dbContext.Banners.Add(banner); } banner.Description = request.Model.Description?.CleanTrim(); banner.Name = request.Model.Name?.CleanTrim() ?? throw new InvalidOperationException("The Name is required."); await dbContext.SaveChangesAsync(cancellationToken); return(mapper.Map <BannerModel>(banner)); } }
public async Task <Unit> Handle(ProcessReceipt request, CancellationToken cancellationToken) { Receipt receipt = await dbContext.Receipts .Include(x => x.Store).ThenInclude(x => x !.Banner) .Include(x => x.Taxes) .SingleOrDefaultAsync(x => x.Uuid == request.Id, cancellationToken) ?? throw new NotFoundException(); if (receipt.Store !.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } Dictionary <Guid, Item> items = await dbContext.Items .Include(x => x.Product).ThenInclude(x => x !.Article) .Include(x => x.Product).ThenInclude(x => x !.Department) .Where(x => x.ReceiptId == receipt.Id) .ToDictionaryAsync(x => x.Uuid, x => x, cancellationToken); Dictionary <int, Line> lines = await dbContext.Lines .Where(x => x.ReceiptId == receipt.Id) .ToDictionaryAsync(x => x.ItemId, x => x); DateTimeOffset now = dateTimeOffset.Now; foreach (var(columnHeader, itemIds) in request.Model.Items) { foreach (Guid itemId in itemIds) { if (items.TryGetValue(itemId, out Item item)) { if (!lines.TryGetValue(item.Id, out Line line)) { line = new Line { Article = item.Product !.Article, ArticleId = item.Product.Article !.Id, CreatedAt = now, IssuedAt = receipt.IssuedAt, Item = item, ItemId = item.Id, Product = item.Product, ProductId = item.Product.Id, Receipt = receipt, ReceiptId = receipt.Id, Store = receipt.Store, StoreId = receipt.Store.Id, Uuid = guid.NewGuid() }; lines.Add(item.Id, line); dbContext.Lines.Add(line); } line.ArticleName = item.Product !.Article !.Name; line.Banner = receipt.Store.Banner; line.BannerId = receipt.Store.Banner?.Id; line.BannerName = receipt.Store.Banner?.Name; line.ColumnHeader = columnHeader; line.Department = item.Product.Department; line.DepartmentId = item.Product.Department?.Id; line.DepartmentName = item.Product.Department?.Name; line.DepartmentNumber = item.Product.Department?.Number; line.Flags = item.Product.Flags; line.Gtin = item.Product.Article.Gtin; line.Price = item.Price; line.ProductLabel = item.Product.Label; line.Quantity = item.Quantity ?? 1; line.ReceiptNumber = receipt.Number; line.Sku = item.Product.Sku; line.StoreName = receipt.Store.Name; line.StoreNumber = receipt.Store.Number; line.UnitPrice = item.UnitPrice; line.UnitType = item.Product.UnitType; line.UpdatedAt = now; } } } await dbContext.SaveChangesAsync(cancellationToken); return(Unit.Value); } }
/// <summary> /// Attended player has accepted game offer. Therefore this action should be processed both on the caller and receiver sides. /// Also all other players that are waiting for this player should be informed. /// </summary> /// <param name="playerId">Id of the player who has ofered game. In the terms of current method - receiver.</param> /// /// <param name="playerId">Id of the game to continue. If it is new game - 0.</param> /// <returns></returns> public async Task OnNewGameAccept(string playerId, int gameId) { if (PlayersCollection.AvailablePlayers.TryGetValue(currentUserService.UserId, out Player caller) && PlayersCollection.AvailablePlayers.TryGetValue(playerId, out Player receiver)) { var tasks = new List <Task>(); // try to add action for the users that are waiting for new game response (this is required for correct work of multiple UI sessions. // For example - user sent game request to another player. Then he opens new browser tab. UI should display correct state - waiting for another player to respond.) lock (LockObject) { // process caller // get all playerIds of the other players that are waiting for the response of the new game with caller. // There should not be many players waiting for one specific player. Therefore, regular foreach should be more efficient than Parallel foreach (SynchronizationAction action in caller.Actions.Where(x => x.Name == "NewGameStartReceiverHandle" && x.Parameters.First() != receiver.Id)) { if (PlayersCollection.AvailablePlayers.TryGetValue(action.Parameters.First(), out Player waitingPlayer)) { // add single NewGameFailureHandle method at the end of the actions list. It will enable UI for new user's connections waitingPlayer.Actions.RemoveAll(x => x.Name == "NewGameFailureHandle"); waitingPlayer.Actions.Add(new SynchronizationAction("NewGameFailureHandle")); // add specific NewGameFailureHandle method to show alert for existing user's connections tasks.Add(Clients.User(waitingPlayer.Id).SendAsync("NewGameFailureHandle", caller.Id, $"Sorry, {caller.Name} has already started another game.")); } } // move to the game collection if (PlayersCollection.AvailablePlayers.TryRemove(caller.Id, out Player _)) { PlayersCollection.InTheGamePlayers.TryAdd(caller.Id, caller); caller.Actions = new List <SynchronizationAction>(); } if (PlayersCollection.AvailablePlayers.TryRemove(receiver.Id, out Player _)) { PlayersCollection.InTheGamePlayers.TryAdd(receiver.Id, receiver); receiver.Actions = new List <SynchronizationAction>(); } // create game group string guidString = guid.NewGuid().ToString("d"); caller.GroupName = guidString; receiver.GroupName = guidString; // check if we need to open exisitng game or create new if (gameId > 0) { caller.GameId = gameId; receiver.GameId = gameId; } else { // coin Toss if (random.Next(0, 2) == 0) { // caller will make the first move and will play with cross caller.IsCrossPlayer = true; receiver.IsCrossPlayer = false; } else { // receiver make the first move and will play with cross caller.IsCrossPlayer = false; receiver.IsCrossPlayer = true; } } // add all connections of both players to the game group foreach (string callerConnectionId in caller.ConnectionIds) { tasks.Add(Groups.AddToGroupAsync(callerConnectionId, guidString)); } foreach (string receiverConnectionId in receiver.ConnectionIds) { tasks.Add(Groups.AddToGroupAsync(receiverConnectionId, guidString)); } // inform others that they need to hide those players foreach (KeyValuePair <string, Player> availablePlayer in PlayersCollection.AvailablePlayers) { tasks.Add(Clients.User(availablePlayer.Key).SendAsync("NewGameAcceptOthersHandle", receiver.Id)); tasks.Add(Clients.User(availablePlayer.Key).SendAsync("NewGameAcceptOthersHandle", caller.Id)); } // add methods that will handler start of the new game tasks.Add(Clients.User(caller.Id).SendAsync("NewGameAcceptCallerHandle", receiver)); tasks.Add(Clients.User(receiver.Id).SendAsync("NewGameAcceptReceiverHandle", caller)); } await Task.WhenAll(tasks); } }
private void AddToAuditChangeDbSet(DbContext context) { var auditChangesDbSet = context.Set <AuditChange>(); var auditChanges = new List <AuditChange>(); foreach (var entity in context.ChangeTracker.Entries() .Where(p => p.State == EntityState.Added || p.State == EntityState.Modified || p.State == EntityState.Deleted) .Select(p => p.Entity)) { var propertyNames = new List <string>(); PropertyValues originalValues = null; PropertyValues currentValues = null; if (context.Entry(entity).State == EntityState.Modified) { originalValues = context.Entry(entity).OriginalValues; propertyNames = originalValues.Properties.Select(p => p.Name).ToList(); } if (context.Entry(entity).State != EntityState.Deleted) { currentValues = context.Entry(entity).CurrentValues; propertyNames = currentValues.Properties.Select(p => p.Name).ToList(); } //var keyProperties = context.GetKeysFor(typeof(T)).ToList(); //var values = keyProperties.Select(keyProp => keyProp.GetValue(entity, null)).ToList(); var id = propertyNames.Any(pn => pn == "Id") ? "Id" : propertyNames.Any(pn => pn == "EntityId") ? "EntityId" : null; var registryId = Guid.Empty.ToString(); if (id == null) { var exception = new Exception($"Property not found {string.Join(",", propertyNames)}"); _customLogger.Error(exception, exception.Message); } else { if (originalValues != null) { registryId = originalValues[id]?.ToString() ?? Guid.Empty.ToString(); } if (currentValues != null) { registryId = currentValues[id]?.ToString() ?? Guid.Empty.ToString(); } } var state = (State)context.Entry(entity).State; if (state == State.Deleted) { var auditChange = AuditChange.Create(_guid.NewGuid(), registryId, entity.GetType().Name, "Deleted", null, null, _dateTime.UtcNow, state); auditChanges.Add(auditChange); continue; } foreach (var propertyName in propertyNames) { object original = null; if (originalValues != null) { original = originalValues[propertyName]; } object current = null; if (currentValues != null) { current = currentValues[propertyName]; } if (original == default && current == default || Equals(original, current)) { continue; } var auditChange = AuditChange.Create(_guid.NewGuid(), registryId, entity.GetType().Name, propertyName, original?.ToString(), current?.ToString(), _dateTime.UtcNow, state); auditChanges.Add(auditChange); } } auditChangesDbSet.AddRange(auditChanges); }
public async Task <StoreModel> Handle(SaveStore request, CancellationToken cancellationToken) { Banner?banner = null; if (request.Model.BannerId.HasValue) { banner = await dbContext.Banners .SingleOrDefaultAsync(x => x.Uuid == request.Model.BannerId.Value, cancellationToken) ?? throw new NotFoundException(nameof(SaveStoreModel.BannerId)); if (banner.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } } Store store; if (request.Id.HasValue) { store = await dbContext.Stores .SingleOrDefaultAsync(x => x.Uuid == request.Id.Value, cancellationToken) ?? throw new NotFoundException(); if (store.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } store.UpdatedAt = dateTimeOffset.Now; } else { DateTimeOffset now = dateTimeOffset.Now; store = new Store { AccountId = appContext.Account !.Id, CreatedAt = now, UpdatedAt = now, Uuid = guid.NewGuid() }; dbContext.Stores.Add(store); } store.Address = request.Model.Address?.CleanTrim(); store.Banner = banner; store.BannerId = banner?.Id; store.City = request.Model.City?.CleanTrim(); store.Country = request.Model.Country?.CleanTrim(); store.Description = request.Model.Description?.CleanTrim(); store.Name = request.Model.Name?.CleanTrim() ?? throw new InvalidOperationException("The Name is required."); store.Number = request.Model.Number?.CleanTrim(); store.Phone = request.Model.Phone?.CleanTrim(); store.PostalCode = request.Model.PostalCode?.CleanTrim(); store.State = request.Model.State?.CleanTrim(); await dbContext.SaveChangesAsync(cancellationToken); return(mapper.Map <StoreModel>(store)); } }
public async Task <ReceiptModel> Handle(ImportReceipt request, CancellationToken cancellationToken) { Store store = await dbContext.Stores .Include(x => x.Products).ThenInclude(x => x.Article) .SingleOrDefaultAsync(x => x.Uuid == request.Model.StoreId, cancellationToken) ?? throw new NotFoundException(nameof(request.Model.StoreId)); if (store.AccountId != appContext.Account !.Id) { throw new ForbiddenException(); } Dictionary <long, Article> articles = await dbContext.Articles .Where(x => x.AccountId == appContext.Account.Id && x.Gtin.HasValue) .ToDictionaryAsync(x => x.Gtin !.Value, x => x, cancellationToken); Dictionary <string, Department> departments = await dbContext.Departments .Where(x => x.StoreId == store.Id && x.Number != null) .ToDictionaryAsync(x => x.Number !, x => x, cancellationToken); Dictionary <int, Product> productsByArticle = store.Products .ToDictionary(x => x.ArticleId, x => x); Dictionary <string, Product> productsBySku = store.Products .Where(x => x.Sku != null) .ToDictionary(x => x.Sku !, x => x); DateTimeOffset now = dateTimeOffset.Now; var receipt = new Receipt { CreatedAt = now, IssuedAt = request.Model.IssuedAt ?? now, Number = request.Model.Number?.CleanTrim(), Store = store, StoreId = store.Id, UpdatedAt = now, Uuid = guid.NewGuid() }; var gst = new Tax { Code = "GST", Rate = taxOptions.Gst }; receipt.Taxes.Add(gst); var qst = new Tax { Code = "QST", Rate = taxOptions.Qst }; receipt.Taxes.Add(qst); IEnumerable <LineInfo> lines = parser.Execute(request.Model.Lines); foreach (LineInfo line in lines) { Article? article = null; Department?department = null; Product? product = null; if (line.Department != null) { if (!departments.TryGetValue(line.Department.Number, out department)) { department = new Department { CreatedAt = now, Name = line.Department.Name, Number = line.Department.Number, Store = store, StoreId = store.Id, UpdatedAt = now, Uuid = guid.NewGuid() }; departments.Add(department.Number, department); dbContext.Departments.Add(department); await dbContext.SaveChangesAsync(cancellationToken); } } string?sku = null; long? gtin = ParseGtin(line.Id); if (gtin.HasValue) { if (articles.TryGetValue(gtin.Value, out article)) { productsByArticle.TryGetValue(article.Id, out product); } } else { sku = line.Id; productsBySku.TryGetValue(sku, out product); } if (product == null) { if (article == null) { article = new Article { AccountId = appContext.Account.Id, CreatedAt = now, Gtin = gtin, Name = line.ToString(), UpdatedAt = now, Uuid = guid.NewGuid() }; dbContext.Articles.Add(article); if (gtin.HasValue) { articles.Add(gtin.Value, article); } } product = new Product { CreatedAt = now, Department = department, DepartmentId = department?.Id, Flags = line.Flags, Label = line.Label, Sku = sku, Store = store, StoreId = store.Id, UnitPrice = line.UnitPrice, UpdatedAt = now, Uuid = guid.NewGuid() }; article.Products.Add(product); if (sku != null) { productsBySku.Add(sku, product); } await dbContext.SaveChangesAsync(cancellationToken); productsByArticle.Add(article.Id, product); } receipt.Items.Add(new Item { Price = line.Price, Product = product, ProductId = product.Id, Quantity = line.Quantity ?? 1, UnitPrice = line.UnitPrice ?? line.Price, Uuid = guid.NewGuid() }); receipt.SubTotal += line.Price; if (product.Flags?.Any(x => x.Contains("F")) == true) { gst.TaxableAmount += line.Price; } if (product.Flags?.Any(x => x.Contains("P")) == true) { qst.TaxableAmount += line.Price; } } receipt.Total = receipt.SubTotal; foreach (Tax tax in receipt.Taxes) { tax.Amount = tax.TaxableAmount * (decimal)tax.Rate; receipt.Total += tax.Amount; } dbContext.Receipts.Add(receipt); await dbContext.SaveChangesAsync(cancellationToken); return(mapper.Map <ReceiptModel>(receipt)); }
public int Next(int minValue, int maxValue) { return(new Random(guid.NewGuid().GetHashCode()).Next(minValue, maxValue)); }