Esempio n. 1
0
        public async Task <ExpenseBillModel> GetById(int id)
        {
            var query = _repository.GetQuery <ExpenseBill>();
            var bill  = await query.Include(x => x.Items).FirstOrDefaultAsync(x => x.Id == id);

            var model = new ExpenseBillModel
            {
                Id            = bill.Id,
                AccountId     = bill.AccountId,
                ExpenseFlowId = bill.ExpenseFlowId,
                DateTime      = bill.DateTime,
                Cost          = bill.SumPrice,
                OwnerId       = bill.OwnerId ?? 0,
                IsCorection   = bill.IsCorrection,
                Items         = bill.Items.Select(x => new ExpenseItemModel
                {
                    Id         = x.Id,
                    CategoryId = x.CategoryId,
                    Comment    = x.Comment,
                    Cost       = x.Price,
                    ProductId  = x.ProductId,
                    Quantity   = x.Quantity
                }).ToList()
            };

            await FullfillItemsFields(model).ConfigureAwait(false);

            return(model);
        }
Esempio n. 2
0
        public async Task <int> Create(ExpenseBillModel model, bool correction = false)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            model.Validate();

            var bill = new ExpenseBill
            {
                ExpenseFlowId = model.ExpenseFlowId,
                AccountId     = model.AccountId,
                DateTime      = model.DateTime,
                SumPrice      = model.Cost,
                OwnerId       = _currentSession.UserId,
                IsCorrection  = correction,
            };

            model.IsCorection = correction;

            _repository.Create(bill);

            foreach (var item in model.Items)
            {
                _repository.Create(new ExpenseItem
                {
                    Bill       = bill,
                    CategoryId = item.CategoryId,
                    ProductId  = item.ProductId,
                    Price      = item.Cost,
                    Quantity   = item.Quantity,
                    Comment    = item.Comment
                });
            }

            Account account = null;

            if (model.AccountId != null)
            {
                account = await _repository.LoadAsync <Account>(model.AccountId.Value);
            }

            if (account != null)
            {
                var balancesUpdater = _balancesUpdaterFactory.Create(account.AccountType);
                await balancesUpdater.Create(account, bill).ConfigureAwait(false);

                _transactionBuilder.CreateExpense(bill, account.Balance);
            }

            await _repository.SaveChangesAsync().ConfigureAwait(false);

            model.Id = bill.Id;
            return(model.Id);
        }
Esempio n. 3
0
 public Task Save(ExpenseBillModel model)
 {
     if (model == null)
     {
         throw new ArgumentNullException(nameof(model));
     }
     if (model.IsNew)
     {
         return(Create(model));
     }
     else
     {
         return(Update(model));
     }
 }
Esempio n. 4
0
        private static ExpenseBillModel CreateBill(UserQuerySession session, int?accountId = null)
        {
            var bill = new ExpenseBillModel
            {
                OwnerId       = session.UserSession.UserId,
                AccountId     = accountId ?? session.DebitCardAccount.Id,
                ExpenseFlowId = session.FoodExpenseFlow.Id,
                DateTime      = DateTime.Now,
            };

            bill.AddItem(new ExpenseItemModel
            {
                Category = session.FoodCategory.Name,
                Cost     = 120.45m,
                Product  = session.Meat.Name
            });
            return(bill);
        }
Esempio n. 5
0
        private async Task FullfillItemsFields(ExpenseBillModel bill)
        {
            foreach (var item in bill.Items)
            {
                if (item.ProductId != null)
                {
                    var product = await _repository.LoadAsync <Product>(item.ProductId.Value);

                    item.Product = product.Name;
                }
                if (item.CategoryId != null)
                {
                    var category = await _repository.LoadAsync <Category>(item.CategoryId.Value);

                    item.Category = category.Name;
                }
            }
        }
Esempio n. 6
0
        private async Task PrepareEditBill(int flowId, Func <Task <ExpenseBillModel> > prepareBill, string returnUrl)
        {
            await PrepareModelsAsync(flowId);

            Bill = await prepareBill();

            Good = new AddExpenseBill
            {
                FlowId       = flowId,
                Bill         = JsonConvert.SerializeObject(Bill),
                FlowName     = Flows.FirstOrDefault(x => x.Id == flowId)?.Name,
                ReturnUrl    = returnUrl,
                ReturnPage   = returnUrl.Replace("/Expenses/", "./"),
                IsCorrection = Bill.IsCorection,
            };
            if (Categories.Count == 1)
            {
                Good.Category = Categories.First().Name;
            }
        }
Esempio n. 7
0
        public async Task <ExpenseBillModel> CreateExpenseBill(int accountId, int flowId, DateTime dateTime,
                                                               Product product, decimal cost)
        {
            var bill = new ExpenseBillModel
            {
                AccountId     = accountId,
                OwnerId       = UserSession.UserId,
                ExpenseFlowId = flowId,
                DateTime      = dateTime
            };

            bill.AddItem(new ExpenseItemModel
            {
                CategoryId = product.CategoryId,
                ProductId  = product.Id,
                Cost       = cost
            });
            var commands = CreateExpensesBillCommands();
            await commands.Save(bill);

            return(bill);
        }
Esempio n. 8
0
        public async Task <IActionResult> OnPostRemoveLastAsync()
        {
            Bill = JsonConvert.DeserializeObject <ExpenseBillModel>(Good.Bill);
            if (Bill.Items.Count == 0)
            {
                ModelState.AddModelError(string.Empty,
                                         @"Невозможно отменить последнюю добавленную позицию, так как счет пуст. 
                      Добавьте хотя бы одну запись, чтобы ее можно было отменить.");
            }
            else
            {
                Bill.RemoveLastAddedItem();
                Good.Bill = JsonConvert.SerializeObject(Bill);
                ModelState.Clear();
            }
            var flowId = await _expenseFlowQueries.GetIdByName(Good.FlowName);

            await PrepareModelsAsync(flowId.Value);

            Good.FlowId = flowId.Value;
            return(Page());
        }
Esempio n. 9
0
        public async Task <int> ProcessReducingBalanceAsCreditFees(Account account, decimal reduceAmount)
        {
            if (account == null)
            {
                throw new ArgumentNullException(nameof(account));
            }
            if (account.AccountType != AccountType.CreditCard)
            {
                throw new InvalidOperationException("Счет должен быть кредитной картой");
            }

            var category = await _repository.FindByNameAsync <Category>(
                _currentSession.UserId, "Кредиты").ConfigureAwait(false);

            if (category == null)
            {
                category = new Category
                {
                    OwnerId = _currentSession.UserId,
                    Name    = "Кредиты",
                };
                _repository.Create(category);
                await _repository.SaveChangesAsync().ConfigureAwait(false);
            }

            var mustSave = false;
            var product  = await _repository.FindByNameAsync <Product>(_currentSession.UserId, account.Name).ConfigureAwait(false);

            if (product == null)
            {
                product = new Product
                {
                    OwnerId    = _currentSession.UserId,
                    Name       = account.Name,
                    CategoryId = category.Id
                };
                _repository.Create(product);
                mustSave = true;
            }

            var flow = await _repository.FindByNameAsync <ExpenseFlow>(_currentSession.UserId, "Кредиты").ConfigureAwait(false);

            if (flow == null)
            {
                flow = new ExpenseFlow
                {
                    OwnerId     = _currentSession.UserId,
                    Balance     = 0,
                    DateCreated = _timeService.ClientLocalNow,
                    Name        = "Кредиты",
                    Number      = 1,
                    Version     = 1
                };
                _repository.Create(flow);
                mustSave = true;
            }

            if (mustSave)
            {
                await _repository.SaveChangesAsync().ConfigureAwait(false);
            }

            var bill = new ExpenseBillModel
            {
                DateTime      = _timeService.ClientLocalNow,
                OwnerId       = _currentSession.UserId,
                AccountId     = account.Id,
                ExpenseFlowId = flow.Id,
                IsCorection   = true,
            };
            var item = new ExpenseItemModel
            {
                CategoryId = category.Id,
                ProductId  = product.Id,
                Cost       = reduceAmount
            };

            bill.AddItem(item);

            return(await _expensesBillCommands.Create(bill, true).ConfigureAwait(false));
        }
Esempio n. 10
0
        public async Task <ExpenseBillModel> Update(ExpenseBillModel model)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            model.Validate();

            var bill = await _repository.LoadAsync <ExpenseBill>(model.Id);

            if (bill == null)
            {
                throw new ArgumentException($"Нет счета с Id = {model.Id}");
            }

            var oldsum       = bill.SumPrice;
            var oldAccountId = bill.AccountId;

            bill.DateTime      = model.DateTime;
            bill.SumPrice      = model.Cost;
            bill.ExpenseFlowId = model.ExpenseFlowId;
            bill.AccountId     = model.AccountId;

            foreach (var item in model.Items)
            {
                if (item.Id > 0 && !item.IsModified && !item.IsDeleted)
                {
                    continue;
                }
                if (item.Id <= 0 || item.IsModified)
                {
                    var itemModel = new ExpenseItem
                    {
                        BillId     = model.Id,
                        CategoryId = item.CategoryId,
                        ProductId  = item.ProductId,
                        Price      = item.Cost,
                        Quantity   = item.Quantity,
                        Comment    = item.Comment
                    };
                    if (item.Id <= 0)
                    {
                        _repository.Create(itemModel);
                    }
                    else
                    {
                        itemModel.Id = item.Id;
                        _repository.Update(itemModel);
                    }
                }
                else if (item.IsDeleted)
                {
                    var itemModel = await _repository.LoadAsync <ExpenseItem>(item.Id);

                    if (itemModel == null)
                    {
                        continue;
                    }
                    _repository.Delete(itemModel);
                }
            }

            _repository.Update(bill);

            var balance = await _transitionBalanceUpdater.Update(bill, oldsum, oldAccountId);

            await _transactionBuilder.UpdateExpense(bill, oldAccountId, balance);

            await _repository.SaveChangesAsync().ConfigureAwait(false);

            return(model);
        }
Esempio n. 11
0
        public async Task AddExpense(ExpenseFlowExpense expense)
        {
            if (expense.Account.IsNullOrEmpty())
            {
                throw new ArgumentException("Необходимо указать счет");
            }

            var account = await _repository.FindByNameAsync <Account>(_currentSession.UserId, expense.Account);

            if (account == null)
            {
                throw new ArgumentException($"Нет счета с именем \"{expense.Account}\"");
            }

            var flow = await _repository.LoadAsync <ExpenseFlow>(expense.ExpenseFlowId);

            if (flow == null)
            {
                throw new ArgumentException($"Нет статьи расходов с идентификатором Id = {expense.ExpenseFlowId}");
            }

            if (string.IsNullOrEmpty(expense.Category) && string.IsNullOrEmpty(expense.Product))
            {
                throw new ArgumentException("Необходимо ввести хотя бы категорию или продукт");
            }

            Category category = null;

            if (!string.IsNullOrEmpty(expense.Category))
            {
                category = await _repository.FindByNameAsync <Category>(_currentSession.UserId, expense.Category);

                if (category == null)
                {
                    throw new ArgumentException($"Нет категории продуктов с именем \"{expense.Category}\"");
                }
            }

            Product product = null;

            if (!string.IsNullOrEmpty(expense.Product))
            {
                product = await _repository.FindByNameAsync <Product>(_currentSession.UserId, expense.Product);

                if (product == null)
                {
                    throw new ArgumentException($"Нет товара с именем \"{expense.Product}\"");
                }
            }

            if (product == null && category == null)
            {
                throw new ArgumentException("Были введены или категория или продукт, но ни один из них не найден");
            }

            var billModel = new ExpenseBillModel
            {
                AccountId     = account.Id,
                ExpenseFlowId = expense.ExpenseFlowId,
                DateTime      = expense.DateCreated,
                Cost          = expense.Cost,
                OwnerId       = _currentSession.UserId,
                Items         = new List <ExpenseItemModel>
                {
                    new ExpenseItemModel
                    {
                        CategoryId = category?.Id,
                        ProductId  = product?.Id,
                        Comment    = null,
                        Quantity   = null,
                        Cost       = expense.Cost,
                    }
                }
            };

            await _expensesBillCommands.Create(billModel, expense.Correcting).ConfigureAwait(false);
        }
Esempio n. 12
0
        public async Task <IActionResult> OnPostAddAsync()
        {
            return(await Good.ProcessAsync(ModelState, nameof(Good),
                                           async() =>
            {
                await PrepareModelsAsync(Good.FlowId);
                Bill = JsonConvert.DeserializeObject <ExpenseBillModel>(Good.Bill);
                Bill.AddItem(await GetExpenseItem());
                Good.ClearInput();
                Good.Bill = JsonConvert.SerializeObject(Bill);
                return Page();
            },
                                           async() =>
            {
                await PrepareModelsAsync(Good.FlowId);
                Bill = JsonConvert.DeserializeObject <ExpenseBillModel>(Good.Bill);
                return Page();
            },
                                           async vrList =>
            {
                if (Good.Account.IsNullOrEmpty())
                {
                    vrList.Add(new ModelValidationResult(nameof(Good.Account), "Укажите счет"));
                }
                else
                {
                    var account = await _accountQueries.GetByName(Good.Account);
                    if (account == null)
                    {
                        vrList.Add(new ModelValidationResult(nameof(Good.Account), "Нет такого счета"));
                    }
                }

                if (Good.FlowName.IsNullOrEmpty())
                {
                    vrList.Add(new ModelValidationResult(nameof(Good.FlowName), "Укажите статью расходов"));
                    return;
                }

                var flowId = await _expenseFlowQueries.GetIdByName(Good.FlowName);
                if (flowId == null)
                {
                    vrList.Add(new ModelValidationResult(nameof(Good.FlowName), "Нет такой статьи расходов"));
                    return;
                }

                Good.FlowId = flowId.Value;

                CategoryModel category = null;
                if (!Good.Category.IsNullOrEmpty())
                {
                    category = await _categoriesQueries.GetFlowCategoryByName(Good.FlowId, Good.Category);
                    if (category == null)
                    {
                        if (Good.Category == Good.CategoryToAdd)
                        {
                            category = await _categoriesCommands.CreateNewOrBind(Good.FlowId, Good.Category);
                            Good.CategoryToAdd = null;
                        }
                        else
                        {
                            vrList.Add(new ModelValidationResult(nameof(Good.Category),
                                                                 "Нет такой категории, добавить ее?"));
                            Good.CategoryToAdd = Good.Category;
                        }
                    }
                }
                if (!Good.Product.IsNullOrEmpty())
                {
                    var product = await _productQueries.GetFlowProductByName(Good.FlowId, Good.Product);
                    if (product == null)
                    {
                        if (Good.Product == Good.ProductToAdd && category != null)
                        {
                            await _productCommands.AddProductToCategory(category.Id, Good.Product);
                            Good.ProductToAdd = null;
                        }
                        else
                        {
                            vrList.Add(new ModelValidationResult(nameof(Good.Product),
                                                                 "Нет такого товара, добавить его?"));
                            Good.ProductToAdd = Good.Product;
                        }
                    }
                }
            }));
        }