示例#1
0
        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);
        }
示例#2
0
        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
            }));
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
        private string GenerateNewTempPath()
        {
            string tempFileName = _guid.NewGuid().ToString();
            string fullTempPath = Path.Combine(_configSettings.PhysicalSitePath, _configSettings.RelativeTemporaryDirectory);

            return(string.Format(@"{0}\{1}", fullTempPath, tempFileName));
        }
示例#7
0
        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));
        }
示例#8
0
        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));
        }
示例#10
0
        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);
        }
示例#11
0
        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));
        }
示例#13
0
        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));
        }
    }
示例#14
0
        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));
        }
示例#15
0
        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));
        }
    }
示例#16
0
        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);
        }
    }
示例#17
0
        /// <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);
        }
示例#19
0
        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));
        }
    }
示例#20
0
        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));
        }
示例#21
0
 public int Next(int minValue, int maxValue)
 {
     return(new Random(guid.NewGuid().GetHashCode()).Next(minValue, maxValue));
 }