/// <summary> /// Validate Product form data /// </summary> private async Task ValidateProductFormData(Product product, Product dbProduct = null) { OperationErrorsList errorsList = new OperationErrorsList(); if (string.IsNullOrEmpty(product.Name)) { errorsList.AddError("Name", Phrases.GlobalRequiredField); } if (string.IsNullOrEmpty(product.Reference)) { errorsList.AddError("Reference", Phrases.GlobalRequiredField); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // Check if the reference already exist This validation only occurs when all form fields // have no errors And only if is a create or an update and the reference has changed Product nameCheck = ((dbProduct == null) || (dbProduct.Reference != product.Reference)) ? await _repository.Products.FindOneAsync(p => p.Reference.ToLower() == product.Reference.ToLower()) : null; if (nameCheck != null) { errorsList.AddError("Reference", Phrases.ProductErrorReference); throw new OperationErrorException(errorsList); } }
/// <summary> /// Validate Location form data /// </summary> private async Task ValidateLocationFormData(Location location, Location dbLocation = null) { OperationErrorsList errorsList = new OperationErrorsList(); if (string.IsNullOrEmpty(location.Name)) { errorsList.AddError("Name", Phrases.GlobalRequiredField); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // Check if the name already exist This validation only occurs when all form fields have // no errors And only if is a create or an update and the name has changed Location nameCheck = ((dbLocation == null) || (dbLocation.Name != location.Name)) ? await _repository.Locations.FindOneAsync(x => x.Name.ToLower() == location.Name.ToLower()) : null; if (nameCheck != null) { errorsList.AddError("Name", Phrases.LocationErrorName); throw new OperationErrorException(errorsList); } }
private async Task ValidateProductLocationDataAsync(ProductLocation productLocation) { OperationErrorsList errorsList = new OperationErrorsList(); if (productLocation.LocationId <= 0) { errorsList.AddError("LocationId", Phrases.GlobalRequiredField); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // check if the product is already associated with the location ProductLocation pLocationCheck = await _repository.ProductLocations .FindOneAsync(pl => pl.ProductId == productLocation.ProductId && pl.LocationId == productLocation.LocationId); if (pLocationCheck != null) { errorsList.AddError("LocationId", Phrases.ProductLocationErrorAlreadyAssociated); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } }
/// <summary> /// Validate User form data /// </summary> private async Task ValidateUserFormDataAsync(User user, User dbUser = null) { OperationErrorsList errorsList = new OperationErrorsList(); if (string.IsNullOrEmpty(user.Username)) { errorsList.AddError("Username", Phrases.GlobalRequiredField); } if ((dbUser == null) && string.IsNullOrEmpty(user.Password)) { errorsList.AddError("Password", Phrases.GlobalRequiredField); } // Validate the form values if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // Check if the username already exist This validation only occurs when all form fields // have no errors And only if is a create or an update and the username has changed User usernameCheck = ((dbUser == null) || (dbUser.Username != user.Username)) ? await _repository.Users.FindOneWithRoleAsync(u => u.Username.ToLower() == user.Username.ToLower()) : null; if (usernameCheck != null) { errorsList.AddError("Username", Phrases.UserErrorUsername); throw new OperationErrorException(errorsList); } }
public async Task DeleteAsync(int[] locationIds, int userId) { OperationErrorsList errorsList = new OperationErrorsList(); try { for (int i = 0; i < locationIds.Length; i += 1) { int locationId = locationIds[i]; Location location = await _repository.Locations.GetByIdAsync(locationId); if (location != null) { // If it is the main location cannot be deleted if (location.IsMain) { errorsList.AddError( "MainLocation", Phrases.LocationErrorMainLocation ); throw new OperationErrorException(errorsList); } // Iterate through the productLocations and move the stock to the main // location before remove the location if ((location.ProductLocations != null) && location.ProductLocations.Any()) { while (location.ProductLocations.Any()) { ProductLocation producLocation = location.ProductLocations.ElementAt(0); // Remove the ProductLocation association and move the stock await AppServices.ProductLocationService .DeleteAsyn(producLocation.ProductLocationId, userId); } } _repository.Locations.Remove(location); } } await _repository.SaveChangesAsync(); } catch (OperationErrorException operationErrorException) { // Catch operation errors throw operationErrorException; } catch { // catch other errors and send a Service Error Exception errorsList.AddError("delete-location-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task DeleteAsync(int[] productIds) { OperationErrorsList errorsList = new OperationErrorsList(); try { for (int i = 0; i < productIds.Length; i += 1) { int productId = productIds[i]; Product product = await _repository.Products.GetByIdAsync(productId); if (product != null) { _repository.Products.Remove(product); } } await _repository.SaveChangesAsync(); } catch { errorsList.AddError("delete-product-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task DeleteAsync(int[] userIds, int loggedInUserId) { OperationErrorsList errorsList = new OperationErrorsList(); try { // You can't delete yourself if (userIds.Contains(loggedInUserId)) { errorsList.AddError("LoggedInUserId", Phrases.UserErrorDeleteYourself); throw new OperationErrorException(errorsList); } for (int i = 0; i < userIds.Length; i += 1) { int userId = userIds[i]; User user = await _repository.Users.GetByIdWithRoleAsync(userId); if (user != null) { _repository.Users.Remove(user); } } await _repository.SaveChangesAsync(); // Catch operation errors } catch (OperationErrorException operationErrorException) { throw operationErrorException; // catch other errors and send a Service Error Exception } catch { errorsList.AddError("delete-user-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
private void VerifyIfHasStockAvailableToMove(ProductLocation plocation, float qty, string field = "qty") { OperationErrorsList errorsList = new OperationErrorsList(); if (plocation.Stock < qty) { errorsList.AddError(field, Phrases.StockMovementErrorQty); throw new OperationErrorException(errorsList); } }
public async Task ExportNotificationsToPDFAsync(IEnumerable <Notification> notifications) { try { PDFGenerator pdf = new PDFGenerator(Phrases.GlobalStockAlerts, Phrases.StockAlertsListOf); Section section = pdf.CreateDocumentSection(); // Set title pdf.AddParagraph(Phrases.GlobalStockAlerts, true, false, 16); pdf.AddParagraph($"{Phrases.GlobalDate}: {DateTime.Now.ShortDate()}", false, true, null, 1); // Create table and table columns Table table = pdf.CreateTable(); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Right); pdf.AddTableColumn(table, ParagraphAlignment.Right); // Create table header Row row = pdf.CreateTableHeaderRow(table); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, Phrases.GlobalDate, true); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, Phrases.GlobalReference, true); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Left, Phrases.GlobalProduct, true); pdf.AddTableRowCell(row, 3, ParagraphAlignment.Left, Phrases.GlobalLocation, true); pdf.AddTableRowCell(row, 4, ParagraphAlignment.Right, Phrases.StockMovementMinStock, true); pdf.AddTableRowCell(row, 5, ParagraphAlignment.Right, Phrases.StockMovementsStock, true); // Populate the table rows notifications.ToList().ForEach((notification) => { row = table.AddRow(); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, notification.CreatedAt.ShortDateWithTime()); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, notification.ProductLocation.Product.Reference); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Left, notification.ProductLocation.Product.Name); pdf.AddTableRowCell(row, 3, ParagraphAlignment.Left, notification.ProductLocation.Location.Name); pdf.AddTableRowCell(row, 4, ParagraphAlignment.Right, notification.ProductLocation.Stock.ToString()); pdf.AddTableRowCell(row, 5, ParagraphAlignment.Right, notification.ProductLocation.MinStock.ToString()); }); // Add the table to the section pdf.AddTableToLastSection(table); // Rendering the document await pdf.GenerateAsync(); } catch { OperationErrorsList errorsList = new OperationErrorsList(); errorsList.AddError("export-notifications-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task <User> AuthenticateAsync(string username, string password) { OperationErrorsList errorsList = new OperationErrorsList(); // Validate data if (string.IsNullOrEmpty(username)) { errorsList.AddError("Username", Phrases.GlobalRequiredField); } if (string.IsNullOrEmpty(password)) { errorsList.AddError("Password", Phrases.GlobalRequiredField); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // get the user from the DB User user = await _repository.Users.FindOneWithRoleAsync(u => u.Username.ToLower() == username.ToLower()); // If the user exist and the password are match, it's all good. if (user != null && BCrypt.Net.BCrypt.Verify(password, user.Password)) { // Set the last login data user.LastLogin = DateTime.UtcNow; await _repository.SaveChangesAsync(); } else { errorsList.AddError("Generic", Phrases.UserErrorLogin); throw new OperationErrorException(errorsList); } return(user); }
public async Task DeleteAsyn(int productLocationId, int userId) { OperationErrorsList errorsList = new OperationErrorsList(); try { ProductLocation productLocation = await _repository.ProductLocations.GetByIdAsync(productLocationId); if (productLocation != null) { // Cannot remove the association with the main location if (productLocation.Location.IsMain) { errorsList.AddError("LocationId", Phrases.ProductLocationDeleteErrorMainLocation); throw new OperationErrorException(errorsList); } // Move the stock back to the main location, if any. await AppServices.StockMovementService.MoveStockToMainLocationAsync(productLocation, userId); // Remove the location _repository.ProductLocations.Remove(productLocation); await _repository.SaveChangesAsync(); } } catch (OperationErrorException operationErrorException) { // catch operations errors throw operationErrorException; } catch { // catch service errors errorsList.AddError("remove-product-location-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task ChangePasswordAsync(int userId, string currentPassword, string newPassword) { OperationErrorsList errorsList = new OperationErrorsList(); // Validate data if (string.IsNullOrEmpty(currentPassword)) { errorsList.AddError("CurrentPassword", Phrases.GlobalRequiredField); } if (string.IsNullOrEmpty(newPassword)) { errorsList.AddError("NewPassword", Phrases.GlobalRequiredField); } if (errorsList.HasErrors()) { throw new OperationErrorException(errorsList); } // Get the user to verify the current password User dbUser = await _repository.Users.GetByIdWithRoleAsync(userId); if ((dbUser != null) && BCrypt.Net.BCrypt.Verify(currentPassword, dbUser.Password)) { // Encrypt password dbUser.Password = BCrypt.Net.BCrypt.HashPassword(newPassword); await _repository.SaveChangesAsync(); } else { errorsList.AddError("CurrentPassword", Phrases.UserErrorInvalidPassword); throw new OperationErrorException(errorsList); } }
public async Task ExportProductLocationsFromLocationToPDFAsync(IEnumerable <ProductLocation> productLocations) { try { string locationName = productLocations.ElementAt(0).Location.Name; PDFGenerator pdf = new PDFGenerator($"{Phrases.GlobalProducts} {locationName}", Phrases.ProductsListOf); Section section = pdf.CreateDocumentSection(); // Set title pdf.AddParagraph(Phrases.GlobalProducts, true, false, 16); pdf.AddParagraph($"{Phrases.GlobalDate}: {DateTime.Now.ShortDate()}", false, true); pdf.AddParagraph($"{Phrases.GlobalLocation}: {locationName}", false, true, null, 1); // Create table and table columns Table table = pdf.CreateTable(); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Right); // Create table header Row row = pdf.CreateTableHeaderRow(table); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, Phrases.GlobalReference, true); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, Phrases.GlobalName, true); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Right, Phrases.StockMovementsStock, true); // Populate the table rows productLocations.ToList().ForEach((productLocation) => { row = table.AddRow(); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, productLocation.Product.Reference); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, productLocation.Product.Name); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Right, productLocation.Stock.ToString()); }); // Add the table to the section pdf.AddTableToLastSection(table); // Rendering the document await pdf.GenerateAsync(); } catch { OperationErrorsList errorsList = new OperationErrorsList(); errorsList.AddError("export-location-products-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task CreateAsync(StockMovement data, bool applyDbChanges = false) { try { int locationId = ( int )((data.ToLocationId != null) ? data.ToLocationId : data.FromLocationId); ProductLocation productLocation = await AppServices.ProductLocationService .GetOneAsync(data.ProductId, locationId); // Calculate the new accumulated stock if (productLocation != null) { data.Stock = (productLocation.Stock + data.Qty); await AppServices.NotificationService.ToggleStockAlertsAsync(productLocation, data.Stock); } else { // Set the accumulated if it is the first movement data.Stock = data.Qty; } await _repository.StockMovements.AddAsync(data); // Normally this service is called inside other services and the call of the // SaveChangesAsync method it will be the responsibility of the other service. In // some circumstances we want the apply the db changes after create the stock // movement, for that we need to sent the applyDbChanges setted to true. if (applyDbChanges) { await _repository.SaveChangesAsync(); } } catch { OperationErrorsList errorsList = new OperationErrorsList(); errorsList.AddError("add-stock-movement-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task UpdateMinStock(int productLocation, float minStock) { try { ProductLocation dbProductLocation = await _repository.ProductLocations.GetByIdAsync(productLocation); dbProductLocation.MinStock = minStock; await AppServices.NotificationService.ToggleStockAlertsAsync(dbProductLocation, dbProductLocation.Stock); await _repository.SaveChangesAsync(); } catch { // catch service errors OperationErrorsList errorsList = new OperationErrorsList(); errorsList.AddError("remove-product-location-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task UpdateAppSettingsAsync(AppSettings data) { OperationErrorsList errorsList = new OperationErrorsList(); try { AppSettings appSettings = await _repository.AppSettings.GetByIdAsync(data.AppSettingsId); appSettings.DocumentsFolder = data.DocumentsFolder; appSettings.Language = data.Language; appSettings.DefaultGlobalMinStock = data.DefaultGlobalMinStock; await _repository.SaveChangesAsync(); } catch { errorsList.AddError("update-settings-db-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }
public async Task ExportStockMovementsToPDFAsync(ExportData <IEnumerable <StockMovement>, StockMovementOptions> data) { try { IEnumerable <StockMovement> movements = data.Data; StockMovementOptions options = data?.Options; PDFGenerator pdf = new PDFGenerator(Phrases.StockMovementsLabel, Phrases.StockMovementsListOf); Section section = pdf.CreateDocumentSection(); // Set title pdf.AddParagraph(Phrases.StockMovementsLabel, true, false, 16); if (options != null) { string startDate = (options?.StartDate != default) ? $"{options.StartDate.ShortDate()} - " : ""; string endDate = (options?.EndDate != default) ? options.EndDate.ShortDate() : ""; pdf.AddParagraph($"{Phrases.GlobalDate}: {startDate}{endDate}", false, true); if (!string.IsNullOrEmpty(options.SearchValue)) { Product product = movements.ElementAt(0).Product; pdf.AddParagraph($"{Phrases.GlobalProduct}: {product.Reference} {product.Name}", false, true); } if (options.LocationId != null) { Location location = await AppServices.LocationService.GetByIdAsync(( int )options.LocationId); pdf.AddParagraph($"{Phrases.GlobalLocation}: {location.Name}", false, true); } if (options.UserId != null) { User user = await AppServices.UserService.GetByIdAsync(( int )options.UserId); pdf.AddParagraph($"{Phrases.GlobalUser}: {user.Username}", false, true); } pdf.AddParagraph("", false, false, null, 1); } // Create table and table columns Table table = pdf.CreateTable(); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Left); pdf.AddTableColumn(table, ParagraphAlignment.Right); pdf.AddTableColumn(table, ParagraphAlignment.Right); // Create table header Row row = pdf.CreateTableHeaderRow(table); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, Phrases.GlobalDate, true); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, Phrases.GlobalUser, true); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Left, Phrases.GlobalReference, true); pdf.AddTableRowCell(row, 3, ParagraphAlignment.Left, Phrases.GlobalName, true); pdf.AddTableRowCell(row, 4, ParagraphAlignment.Left, Phrases.GlobalMovement, true); pdf.AddTableRowCell(row, 5, ParagraphAlignment.Right, Phrases.StockMovementQty, true); pdf.AddTableRowCell(row, 6, ParagraphAlignment.Right, Phrases.StockMovementStockAcc, true); // Populate the table rows movements.ToList().ForEach((movement) => { row = table.AddRow(); pdf.AddTableRowCell(row, 0, ParagraphAlignment.Left, movement.CreatedAt.ShortDateWithTime()); pdf.AddTableRowCell(row, 1, ParagraphAlignment.Left, movement.User.Username); pdf.AddTableRowCell(row, 2, ParagraphAlignment.Left, movement.Product.Reference); pdf.AddTableRowCell(row, 3, ParagraphAlignment.Left, movement.Product.Name); pdf.AddTableRowCell(row, 4, ParagraphAlignment.Left, movement.ConcatMovementString()); pdf.AddTableRowCell(row, 5, ParagraphAlignment.Right, movement.Qty.ToString()); pdf.AddTableRowCell(row, 6, ParagraphAlignment.Right, movement.Stock.ToString()); }); // Add the table to the section pdf.AddTableToLastSection(table); // Rendering the document await pdf.GenerateAsync(); } catch { OperationErrorsList errorsList = new OperationErrorsList(); errorsList.AddError("export-stock-movements-error", Phrases.GlobalErrorOperationDB); throw new ServiceErrorException(errorsList); } }