Пример #1
0
        public async Task <IActionResult> Put(long typeId, long id, [FromBody] EditBillViewModel model)
        {
            if (model == null)
            {
                return(BadRequest());
            }

            if (model.Id != id)
            {
                return(BadRequest());
            }

            var billType = await _billTypeRepo.GetAsync(typeId);

            if (billType == null)
            {
                return(NotFound(Resources.Bills.BillResource.BillTypeNotFound));
            }

            var bill = await _billRepo.GetAsync(billType.Id, id);

            if (bill == null)
            {
                return(NotFound(Resources.Bills.BillResource.BillNotFound));
            }

            #region checks

            Guid currencyId;
            var  currency = await _currencyRepo.GetAsync(model.CurrencyId);

            if (currency != null)
            {
                currencyId = currency.Id;
                if (!model.CurrencyValue.HasValue)
                {
                    model.CurrencyValue = currency.Value;
                }
            }
            else
            {
                currencyId          = _defaultKeysOptions.Value.CurrencyId;
                model.CurrencyValue = 1;
            }

            Guid cashAccountId;
            var  cashAccount = await _accountRepo.GetAsync(model.AccountId);

            if (cashAccount == null)
            {
                return(NotFound("Cash account not found"));
            }
            cashAccountId = cashAccount.Id;


            Guid?customerAccountId = null;
            if (model.CustomerAccountId.HasValue)
            {
                var customerAccount = await _accountRepo.GetAsync(model.CustomerAccountId.Value);

                if (customerAccount == null)
                {
                    return(NotFound("Customer account not found"));
                }
                if (customerAccount.CustomerId == null)
                {
                    ModelState.AddModelError("CustomerAccountId", "account not related to customer or supplier");
                    return(BadRequest(ModelState.GetWithErrorsKey()));
                }
                customerAccountId = customerAccount.Id;
            }

            Guid?storeId = null;
            if (model.StoreId.HasValue)
            {
                var store = await _storeRepo.GetAsync(model.StoreId.Value);

                if (store == null)
                {
                    return(NotFound(Resources.Stores.StoreResource.StoreNotFound));
                }
                storeId = store.Id;
            }

            Guid?costCenterId = null;
            if (model.CostCenterId.HasValue)
            {
                var costCenter = await _costCenterRepo.GetAsync(model.CostCenterId.Value);

                if (costCenter == null)
                {
                    return(NotFound(Resources.CostCenters.CostCenterResource.CostCenterNotFound));
                }
                costCenterId = costCenter.Id;
            }

            Guid?branchId = null;
            if (model.BranchId.HasValue)
            {
                var branch = await _branchRepo.GetAsync(model.BranchId.Value);

                if (branch == null)
                {
                    return(NotFound(Resources.Branchs.BranchResource.BranchNotFound));
                }
                branchId = branch.Id;
            }

            #endregion

            #region undo bill posting to stores

            if (bill.IsPosted)
            {
                foreach (var billItem in bill.BillItems)
                {
                    await PostToStore(bill, bill.BillType, billItem, billItem.ItemUnit, true);
                }
            }
            #endregion

            bill.AccountId         = cashAccountId;
            bill.CurrencyId        = currencyId;
            bill.CurrencyValue     = model.CurrencyValue.Value;
            bill.CustomerAccountId = customerAccountId;
            bill.CustomerName      = model.CustomerAccountCodeName;
            bill.Date         = model.Date;
            bill.PayType      = model.PayType;
            bill.StoreId      = storeId;
            bill.CostCenterId = costCenterId;
            bill.BranchId     = branchId;
            bill.Extra        = model.Extra;
            bill.Disc         = model.Disc;
            bill.TotalPaid    = model.TotalPaid;
            bill.Note         = model.Note;
            bill.BillItems    = new HashSet <BillItem>();

            var itemsIndex = 0;
            // check form items if not found
            foreach (var item in model.Items)
            {
                itemsIndex++;
                Guid itemStoreId;
                if (model.StoreId.HasValue && model.StoreId.Value == item.StoreId)
                {
                    itemStoreId = storeId.Value;
                }
                else
                {
                    var itemStore = await _storeRepo.GetAsync(item.StoreId.Value);

                    if (itemStore == null)
                    {
                        return(NotFound($"store in item {itemsIndex} not found"));
                    }
                    itemStoreId = itemStore.Id;
                }

                Guid?itemCostCenterId = null;
                if (model.CostCenterId.HasValue && item.CostCenterId.HasValue && model.CostCenterId == item.CostCenterId)
                {
                    itemCostCenterId = costCenterId;
                }
                else
                {
                    if (item.CostCenterId.HasValue)
                    {
                        var itemCostCenter = await _storeRepo.GetAsync(item.CostCenterId.Value);

                        if (itemCostCenter == null)
                        {
                            return(NotFound($"costCenter in item {0} not found"));
                        }
                    }
                }

                var itemUnit = _itemUnitRepo.Get(item.ItemId, item.UnitId);

                if (itemUnit == null)
                {
                    ModelState.AddModelError($"Items[{itemsIndex}].ItemId", "المادة غير موجودة");
                    return(BadRequest(ModelState.GetWithErrorsKey()));
                }

                var billItem = new BillItem(itemUnit.Id, itemStoreId, itemCostCenterId, item.Quantity, item.Price, item.Extra, item.Disc, model.Note);
                bill.BillItems.Add(billItem);

                if (bill.BillType.AutoPostToStores)
                {
                    if (!await PostToStore(bill, bill.BillType, billItem, itemUnit))
                    {
                        ModelState.AddModelError($"Items[{itemsIndex}].Quantity", "لا يوجد كل هذه الكمية في المستودع");
                        return(BadRequest(ModelState.GetWithErrorsKey()));
                    }
                }
            }

            bill.CalcTotal();

            #region billEntryItem
            if (bill.Extra + bill.TotalItemsExtra > 0 && bill.BillType.DefaultExtraAccountId.HasValue)
            {
                var extraEntryItem = new BillEntryItem(bill.Date, bill.BillType.DefaultExtraAccountId.Value, bill.CurrencyId, bill.CurrencyValue, bill.CostCenterId, BillEntryItemType.ExtraDisc, 0, bill.Extra + bill.TotalItemsExtra, bill.Note);
                bill.BillEntryItems.Add(extraEntryItem);
            }

            if (bill.Disc + bill.TotalItemsDisc > 0 && bill.BillType.DefaultDiscAccountId.HasValue)
            {
                var discEntryItem = new BillEntryItem(bill.Date, bill.BillType.DefaultDiscAccountId.Value, bill.CurrencyId, bill.CurrencyValue, bill.CostCenterId, BillEntryItemType.ExtraDisc, bill.Disc + bill.TotalItemsDisc, 0, bill.Note);
                bill.BillEntryItems.Add(discEntryItem);
            }

            foreach (var pay in model.Pays)
            {
                var payEntryItem = new BillEntryItem(pay.Date, pay.AccountId, pay.CurrencyId, pay.CurrencyValue, pay.CostCenterId, BillEntryItemType.Pay, pay.Debit, pay.Credit, pay.Note);
            }
            #endregion

            if (bill.IsEntryGenerated)
            {
                var entry = bill.BillEntry.Entry;
                if (entry.IsPosted)
                {
                    // rolback
                    await _accountBalanceService.PostEntryToAccounts(entry, true);

                    //await PostEntryToAccounts(entry,true);
                }

                if (bill.PayType == PaysType.Cash)
                {
                    bill.AccountId = cashAccountId;
                }
                else
                {
                    bill.AccountId = customerAccountId;
                }
                entry = GenerateEntry(bill, bill.BillType);
                _entryRepo.Edit(entry, false);

                if (entry.IsPosted)
                {
                    // Post to Account
                    await _accountBalanceService.PostEntryToAccounts(entry);

                    //await PostEntryToAccounts(entry);
                }
            }

            var affectedRows = await _billRepo.EditAsync(bill);

            if (affectedRows > 0)
            {
                var viewModel = AutoMapper.Mapper.Map <BillViewModel>(bill);

                return(CreatedAtRoute("GetBill", new { id = bill.Number }, viewModel));
            }
            return(BadRequest());
        }