public async Task <IActionResult> OnGetAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            WarehouseTransaction = await _context.WarehouseTransactions
                                   .Include(w => w.Company)
                                   .Include(w => w.FiscalPeriod)
                                   .Include(w => w.WarehouseItem)
                                   .Include(w => w.Section)
                                   .Include(w => w.TransWarehouseDocSeries)
                                   .Include(w => w.TransWarehouseDocType).FirstOrDefaultAsync(m => m.Id == id);

            if (WarehouseTransaction == null)
            {
                return(NotFound());
            }
            var section = _context.Sections.SingleOrDefault(s => s.SystemName == SectionSystemCode);

            if (section is null)
            {
                _toastNotification.AddAlertToastMessage("Supplier Transactions section not found in DB");
                return(BadRequest());
            }
            //If section is not our section the canot update disable input controls
            NotUpdatable = WarehouseTransaction.SectionId != section.Id;
            return(Page());
        }
Example #2
0
        /// <summary>
        /// Manipulates warehouse item transaction object based on the inventory action
        /// </summary>
        /// <param name="inventoryAction"></param>
        /// <param name="q1"></param>
        /// <param name="q2"></param>
        /// <param name="itemTrans"></param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static void ItemInventoryActionHandler(InventoryActionEnum inventoryAction, double q1, double q2,
                                                      WarehouseTransaction itemTrans)
        {
            switch (inventoryAction)
            {
            case InventoryActionEnum.InventoryActionEnumNoChange:
                itemTrans.TransactionType =
                    WarehouseTransactionTypeEnum.WarehouseTransactionTypeIgnore;
                itemTrans.TransQ1 = 0;
                itemTrans.TransQ2 = 0;
                break;

            case InventoryActionEnum.InventoryActionEnumImport:

                itemTrans.TransactionType =
                    WarehouseTransactionTypeEnum.WarehouseTransactionTypeImport;
                itemTrans.Quontity1 = q1;
                itemTrans.Quontity2 = q2;
                itemTrans.TransQ1   = (decimal)itemTrans.Quontity1;
                itemTrans.TransQ2   = (decimal)itemTrans.Quontity2;
                break;

            case InventoryActionEnum.InventoryActionEnumExport:

                itemTrans.TransactionType =
                    WarehouseTransactionTypeEnum.WarehouseTransactionTypeExport;
                itemTrans.Quontity1 = q1;
                itemTrans.Quontity2 = q2;
                itemTrans.TransQ1   = (decimal)itemTrans.Quontity1;
                itemTrans.TransQ2   = (decimal)itemTrans.Quontity2;
                break;

            case InventoryActionEnum.InventoryActionEnumNegativeImport:

                itemTrans.TransactionType =
                    WarehouseTransactionTypeEnum.WarehouseTransactionTypeImport;
                itemTrans.Quontity1 = q1;
                itemTrans.Quontity2 = q2;
                itemTrans.TransQ1   = (decimal)itemTrans.Quontity1 * -1;
                itemTrans.TransQ2   = (decimal)itemTrans.Quontity2 * -1;
                break;

            case InventoryActionEnum.InventoryActionEnumNegativeExport:

                itemTrans.TransactionType =
                    WarehouseTransactionTypeEnum.WarehouseTransactionTypeExport;
                itemTrans.Quontity1 = q1;
                itemTrans.Quontity2 = q2;
                itemTrans.TransQ1   = (decimal)itemTrans.Quontity1 * -1;
                itemTrans.TransQ2   = (decimal)itemTrans.Quontity2 * -1;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Example #3
0
        /// <summary>
        /// Manipulates item Trans based on material nature
        /// </summary>
        /// <param name="itemNature"></param>
        /// <param name="itemTrans"></param>
        /// <param name="itemTransDef"></param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static void ItemNatureHandler(WarehouseItemNatureEnum itemNature, WarehouseTransaction itemTrans,
                                             TransWarehouseDef itemTransDef)
        {
            switch (itemNature)
            {
            case WarehouseItemNatureEnum.WarehouseItemNatureUndefined:
                throw new ArgumentOutOfRangeException();

            case WarehouseItemNatureEnum.WarehouseItemNatureMaterial:
                itemTrans.InventoryAction      = itemTransDef.MaterialInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.MaterialInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            case WarehouseItemNatureEnum.WarehouseItemNatureService:
                itemTrans.InventoryAction      = itemTransDef.ServiceInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.ServiceInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            case WarehouseItemNatureEnum.WarehouseItemNatureExpense:
                itemTrans.InventoryAction      = itemTransDef.ExpenseInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.ExpenseInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            case WarehouseItemNatureEnum.WarehouseItemNatureIncome:
                itemTrans.InventoryAction      = itemTransDef.IncomeInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.IncomeInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            case WarehouseItemNatureEnum.WarehouseItemNatureFixedAsset:
                itemTrans.InventoryAction      = itemTransDef.FixedAssetInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.FixedAssetInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            case WarehouseItemNatureEnum.WarehouseItemNatureRawMaterial:
                itemTrans.InventoryAction      = itemTransDef.RawMaterialInventoryAction;
                itemTrans.InventoryValueAction = itemTransDef.RawMaterialInventoryValueAction;
                itemTrans.InvoicedVolumeAction = itemTransDef.MaterialInvoicedVolumeAction;
                itemTrans.InvoicedValueAction  = itemTransDef.MaterialInvoicedValueAction;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        public async Task <IActionResult> OnPostAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            WarehouseTransaction = await _context.WarehouseTransactions.FindAsync(id);

            if (WarehouseTransaction != null)
            {
                _context.WarehouseTransactions.Remove(WarehouseTransaction);
                await _context.SaveChangesAsync();
            }

            return(RedirectToPage("./Index"));
        }
        public async Task <IActionResult> OnGetAsync(int?id)
        {
            if (id == null)
            {
                return(NotFound());
            }

            WarehouseTransaction = await _context.WarehouseTransactions
                                   .Include(w => w.Company)
                                   .Include(w => w.FiscalPeriod)
                                   .Include(w => w.WarehouseItem)
                                   .Include(w => w.Section)
                                   .Include(w => w.TransWarehouseDocSeries)
                                   .Include(w => w.TransWarehouseDocType).FirstOrDefaultAsync(m => m.Id == id);

            if (WarehouseTransaction == null)
            {
                return(NotFound());
            }
            return(Page());
        }
Example #6
0
        /// <summary>
        /// Manipulates warehouse item transaction object based on the inventory value action
        /// </summary>
        /// <param name="inventoryValueAction"></param>
        /// <param name="itemTrans"></param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static void ItemInventoryValueActionHandler(InventoryValueActionEnum inventoryValueAction,
                                                           WarehouseTransaction itemTrans)
        {
            switch (inventoryValueAction)
            {
            case InventoryValueActionEnum.InventoryValueActionEnumNoChange:
                itemTrans.TransNetAmount      = 0;
                itemTrans.TransFpaAmount      = 0;
                itemTrans.TransDiscountAmount = 0;
                break;

            case InventoryValueActionEnum.InventoryValueActionEnumIncrease:
                itemTrans.TransNetAmount      = itemTrans.AmountNet;
                itemTrans.TransFpaAmount      = itemTrans.AmountFpa;
                itemTrans.TransDiscountAmount = itemTrans.AmountDiscount;
                break;

            case InventoryValueActionEnum.InventoryValueActionEnumDecrease:
                itemTrans.TransNetAmount      = itemTrans.AmountNet;
                itemTrans.TransFpaAmount      = itemTrans.AmountFpa;
                itemTrans.TransDiscountAmount = itemTrans.AmountDiscount;
                break;

            case InventoryValueActionEnum.InventoryValueActionEnumNegativeIncrease:
                itemTrans.TransNetAmount      = itemTrans.AmountNet * -1;
                itemTrans.TransFpaAmount      = itemTrans.AmountFpa * -1;
                itemTrans.TransDiscountAmount = itemTrans.AmountDiscount * -1;

                break;

            case InventoryValueActionEnum.InventoryValueActionEnumNegativeDecrease:
                itemTrans.TransNetAmount      = itemTrans.AmountNet * -1;
                itemTrans.TransFpaAmount      = itemTrans.AmountFpa * -1;
                itemTrans.TransDiscountAmount = itemTrans.AmountDiscount * -1;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private async Task <IActionResult> CreateSellDocFromRecTrans(SellDocCreateAjaxDto data, RecurringTransDoc recurringTransDoc)
        {
            const string sectionCode = "SYS-SELL-COMBINED-SCN";

            bool noWarehouseTrans = false;

            SellDocCreateAjaxNoLinesDto transToAttachNoLines;
            SellDocument transToAttach;
            DateTime     dateOfTrans;

            if (data == null)
            {
                return(BadRequest(new
                {
                    error = "Empty request data"
                }));
            }

            try
            {
                transToAttachNoLines         = _mapper.Map <SellDocCreateAjaxNoLinesDto>(data);
                transToAttach                = _mapper.Map <SellDocument>(transToAttachNoLines);
                transToAttach.SalesChannelId = 1;
                dateOfTrans = data.TransDate;
            }
            catch (Exception e)
            {
                return(BadRequest(new
                {
                    error = e.Message
                }));
            }

            using (var transaction = _context.Database.BeginTransaction())
            {
                #region Fiscal Period

                var fiscalPeriod = await _context.FiscalPeriods.FirstOrDefaultAsync(p =>
                                                                                    dateOfTrans >= p.StartDate && dateOfTrans <= p.EndDate);

                if (fiscalPeriod == null)
                {
                    transaction.Rollback();
                    ModelState.AddModelError(string.Empty, "No Fiscal Period covers Transaction Date");
                    return(NotFound(new
                    {
                        error = "No Fiscal Period covers Transaction Date"
                    }));
                }

                #endregion

                var docSeries = await
                                _context.SellDocSeriesDefs.SingleOrDefaultAsync(m => m.Id == data.SellDocSeriesId);

                if (docSeries is null)
                {
                    transaction.Rollback();
                    ModelState.AddModelError(string.Empty, "Δεν βρέθηκε η σειρά παραστατικού");
                    return(NotFound(new
                    {
                        error = "Buy Doc Series not found"
                    }));
                }

                await _context.Entry(docSeries).Reference(t => t.SellDocTypeDef).LoadAsync();

                var docTypeDef = docSeries.SellDocTypeDef;

                await _context.Entry(docTypeDef)
                .Reference(t => t.TransTransactorDef)
                .LoadAsync();

                await _context.Entry(docTypeDef).Reference(t => t.TransWarehouseDef)
                .LoadAsync();

                #region Section Management

                int sectionId = 0;
                if (docTypeDef.SectionId == 0)
                {
                    var sectn = await _context.Sections.SingleOrDefaultAsync(s => s.SystemName == sectionCode);

                    if (sectn == null)
                    {
                        transaction.Rollback();
                        ModelState.AddModelError(string.Empty, "Δεν υπάρχει το Section");
                        return(NotFound(new
                        {
                            error = "Could not locate section "
                        }));
                    }

                    sectionId = sectn.Id;
                }
                else
                {
                    sectionId = docTypeDef.SectionId;
                }

                #endregion

                var transTransactorDef = docTypeDef.TransTransactorDef;
                var transWarehouseDef  = docTypeDef.TransWarehouseDef;

                transToAttach.SectionId      = sectionId;
                transToAttach.FiscalPeriodId = fiscalPeriod.Id;
                transToAttach.SellDocTypeId  = docSeries.SellDocTypeDefId;
                _context.SellDocuments.Add(transToAttach);

                try
                {
                    await _context.SaveChangesAsync();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    transaction.Rollback();
                    string msg = e.InnerException.Message;
                    return(BadRequest(new
                    {
                        error = e.Message + " " + msg
                    }));
                }

                var docId = _context.Entry(transToAttach).Entity.Id;


                if (transTransactorDef.DefaultDocSeriesId > 0)
                {
                    var transTransactorDefaultSeries = await
                                                       _context.TransTransactorDocSeriesDefs.FirstOrDefaultAsync(p =>
                                                                                                                 p.Id == transTransactorDef.DefaultDocSeriesId);

                    if (transTransactorDefaultSeries == null)
                    {
                        transaction.Rollback();
                        ModelState.AddModelError(string.Empty, "Default series for transactor transaction not found");
                        return(NotFound(new
                        {
                            error = "Default series for transactor transaction not found"
                        }));
                    }

                    var sTransactorTransaction = _mapper.Map <TransactorTransaction>(data);
                    sTransactorTransaction.TransactorId             = data.TransactorId;
                    sTransactorTransaction.SectionId                = sectionId;
                    sTransactorTransaction.TransTransactorDocTypeId =
                        transTransactorDefaultSeries.TransTransactorDocTypeDefId;
                    sTransactorTransaction.TransTransactorDocSeriesId = transTransactorDefaultSeries.Id;
                    sTransactorTransaction.FiscalPeriodId             = fiscalPeriod.Id;
                    sTransactorTransaction.CreatorId = docId;
                    ActionHandlers.TransactorFinAction(transTransactorDef.FinancialTransAction,
                                                       sTransactorTransaction);

                    _context.TransactorTransactions.Add(sTransactorTransaction);
                    try
                    {
                        await _context.SaveChangesAsync();
                    }
                    catch (Exception e)
                    {
                        transaction.Rollback();
                        string msg = e.InnerException.Message;
                        return(BadRequest(new
                        {
                            error = e.Message + " " + msg
                        }));
                    }
                }

                #region Αυτόματη Εξόφληση

                //Αυτόματη εξόφληση
                var paymentMethod =
                    await _context.PaymentMethods.FirstOrDefaultAsync(p => p.Id == transToAttach.PaymentMethodId);

                if (paymentMethod is null)
                {
                    transaction.Rollback();
                    ModelState.AddModelError(string.Empty, "Δεν βρέθηκε ο τρόπος πληρωμής");
                    return(NotFound(new
                    {
                        error = "Δεν βρέθηκε ο τρόπος πληρωμής"
                    }));
                }

                if (paymentMethod.AutoPayoffWay == SeriesAutoPayoffEnum.SeriesAutoPayoffEnumAuto)
                {
                    var autoPaySeriesId = transToAttach.SellDocSeries.PayoffSeriesId;
                    if (autoPaySeriesId > 0)
                    {
                        var transTransactorPayOffSeries = await
                                                          _context.TransTransactorDocSeriesDefs.FirstOrDefaultAsync(p =>
                                                                                                                    p.Id == autoPaySeriesId);

                        if (transTransactorPayOffSeries == null)
                        {
                            transaction.Rollback();
                            ModelState.AddModelError(string.Empty, "AutoPayOff series not found");
                            return(NotFound(new
                            {
                                error = "AutoPayOff series not found"
                            }));
                        }

                        var sTransactorTransaction = _mapper.Map <TransactorTransaction>(data);
                        sTransactorTransaction.TransactorId             = data.TransactorId;
                        sTransactorTransaction.SectionId                = sectionId;
                        sTransactorTransaction.TransTransactorDocTypeId =
                            transTransactorPayOffSeries.TransTransactorDocTypeDefId;
                        sTransactorTransaction.TransTransactorDocSeriesId = transTransactorPayOffSeries.Id;
                        sTransactorTransaction.FiscalPeriodId             = fiscalPeriod.Id;
                        sTransactorTransaction.Etiology  = "AutoPayOff";
                        sTransactorTransaction.CreatorId = docId;
                        await _context.Entry(transTransactorPayOffSeries)
                        .Reference(t => t.TransTransactorDocTypeDef)
                        .LoadAsync();

                        var transTransactorDocTypeDef = transTransactorPayOffSeries.TransTransactorDocTypeDef;

                        await _context.Entry(transTransactorDocTypeDef)
                        .Reference(t => t.TransTransactorDef)
                        .LoadAsync();

                        var transPaymentTransactorDef = transTransactorDocTypeDef.TransTransactorDef;
                        ActionHandlers.TransactorFinAction(transPaymentTransactorDef.FinancialTransAction,
                                                           sTransactorTransaction);

                        _context.TransactorTransactions.Add(sTransactorTransaction);
                        try
                        {
                            await _context.SaveChangesAsync();
                        }
                        catch (Exception e)
                        {
                            transaction.Rollback();
                            string msg = e.InnerException.Message;
                            return(BadRequest(new
                            {
                                error = e.Message + " " + msg
                            }));
                        }
                    }
                }

                #endregion

                int warehouseSeriesId = 0;
                int warehouseTypeId   = 0;

                if (transWarehouseDef.DefaultDocSeriesId > 0)
                {
                    var transWarehouseDefaultSeries =
                        await _context.TransWarehouseDocSeriesDefs.FirstOrDefaultAsync(p =>
                                                                                       p.Id == transWarehouseDef.DefaultDocSeriesId);

                    if (transWarehouseDefaultSeries == null)
                    {
                        transaction.Rollback();
                        ModelState.AddModelError(string.Empty, "Default series for warehouse transaction not found");
                        return(NotFound(new
                        {
                            error = "Default series for warehouse transaction not found"
                        }));
                    }

                    noWarehouseTrans  = false;
                    warehouseSeriesId = transWarehouseDef.DefaultDocSeriesId;
                    warehouseTypeId   = transWarehouseDefaultSeries.TransWarehouseDocTypeDefId;
                }
                else
                {
                    noWarehouseTrans = true;
                }

                foreach (var docLine in data.SellDocLines)
                {
                    var warehouseItemId = docLine.WarehouseItemId;
                    var material        = await _context.WarehouseItems.SingleOrDefaultAsync(p => p.Id == warehouseItemId);

                    if (material is null)
                    {
                        //Handle error
                        transaction.Rollback();
                        ModelState.AddModelError(string.Empty, "Doc Line error null WarehouseItem");
                        return(NotFound(new
                        {
                            error = "Could not locate material in Doc Line "
                        }));
                    }

                    #region MaterialLine

                    var     sellDocLine        = new SellDocLine();
                    decimal unitPrice          = docLine.Price;
                    decimal units              = (decimal)docLine.Q1;
                    decimal fpaRate            = (decimal)docLine.FpaRate;
                    decimal discountRate       = (decimal)docLine.DiscountRate;
                    decimal lineNetAmount      = unitPrice * units;
                    decimal lineDiscountAmount = lineNetAmount * discountRate;
                    decimal lineFpaAmount      = (lineNetAmount - lineDiscountAmount) * fpaRate;
                    sellDocLine.UnitPrice       = unitPrice;
                    sellDocLine.AmountFpa       = lineFpaAmount;
                    sellDocLine.AmountNet       = lineNetAmount;
                    sellDocLine.AmountDiscount  = lineDiscountAmount;
                    sellDocLine.DiscountRate    = discountRate;
                    sellDocLine.FpaRate         = fpaRate;
                    sellDocLine.WarehouseItemId = docLine.WarehouseItemId;
                    sellDocLine.Quontity1       = docLine.Q1;
                    sellDocLine.Quontity2       = docLine.Q2;
                    sellDocLine.PrimaryUnitId   = docLine.MainUnitId;
                    sellDocLine.SecondaryUnitId = docLine.SecUnitId;
                    sellDocLine.Factor          = docLine.Factor;
                    sellDocLine.SellDocumentId  = docId;
                    sellDocLine.Etiology        = transToAttach.Etiology;
                    //_context.Entry(transToAttach).Entity
                    transToAttach.SellDocLines.Add(sellDocLine);

                    #endregion

                    if (!noWarehouseTrans)
                    {
                        #region Warehouse transaction

                        var warehouseTrans = new WarehouseTransaction();
                        warehouseTrans.FpaRate        = fpaRate;
                        warehouseTrans.DiscountRate   = discountRate;
                        warehouseTrans.UnitPrice      = unitPrice;
                        warehouseTrans.AmountDiscount = lineDiscountAmount;
                        warehouseTrans.AmountNet      = lineNetAmount;
                        warehouseTrans.AmountFpa      = lineFpaAmount;
                        warehouseTrans.CompanyId      = transToAttach.CompanyId;
                        warehouseTrans.Etiology       = transToAttach.Etiology;
                        warehouseTrans.FiscalPeriodId = transToAttach.FiscalPeriodId;

                        warehouseTrans.WarehouseItemId = warehouseItemId;
                        warehouseTrans.PrimaryUnitId   = docLine.MainUnitId;
                        warehouseTrans.SecondaryUnitId = docLine.SecUnitId;
                        warehouseTrans.SectionId       = sectionId;
                        warehouseTrans.CreatorId       = transToAttach.Id;
                        warehouseTrans.TransDate       = transToAttach.TransDate;
                        warehouseTrans.TransRefCode    = transToAttach.TransRefCode;
                        warehouseTrans.UnitFactor      = (decimal)docLine.Factor;

                        warehouseTrans.TransWarehouseDocSeriesId = warehouseSeriesId;
                        warehouseTrans.TransWarehouseDocTypeId   = warehouseTypeId;
                        ActionHandlers.ItemNatureHandler(material.WarehouseItemNature, warehouseTrans,
                                                         transWarehouseDef);
                        ActionHandlers.ItemInventoryActionHandler(warehouseTrans.InventoryAction, docLine.Q1,
                                                                  docLine.Q2,
                                                                  warehouseTrans);
                        ActionHandlers.ItemInventoryValueActionHandler(warehouseTrans.InventoryValueAction,
                                                                       warehouseTrans);

                        _context.WarehouseTransactions.Add(warehouseTrans);

                        #endregion
                    }
                }

                try
                {
                    await _context.SaveChangesAsync();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    string msg = e.InnerException.Message;
                    return(BadRequest(new
                    {
                        error = e.Message + " " + msg
                    }));
                }

                var curDate  = recurringTransDoc.NextTransDate;
                var nextDate = GetNextTransactionDate(curDate, recurringTransDoc.RecurringFrequency);
                recurringTransDoc.NextTransDate         = nextDate;
                _context.Entry(recurringTransDoc).State = EntityState.Modified;
                try
                {
                    await _context.SaveChangesAsync();

                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    string msg = e.InnerException.Message;
                    return(BadRequest(new
                    {
                        error = e.Message + " " + msg
                    }));
                }
            }

            return(Ok());
        }
Example #8
0
        public async Task <ServiceResponse <GetWarehouseTransactionDto> > CreateWarehouseTransactionAsync(CreateWarehouseTransactionDto dto)
        {
            var response = new ServiceResponse <GetWarehouseTransactionDto>();

            try
            {
                var userIdentifier = _httpCtxAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
                var user           = await _context.Users.SingleOrDefaultAsync(x => x.Email == userIdentifier);

                if (user == null)
                {
                    throw new UserNotFoundException();
                }

                Manufacturer dbManufacturer = null;

                if (dto.TransactionType == WarehouseTransactionType.Import)
                {
                    dbManufacturer = await _context.Manufacturers.FirstOrDefaultAsync(x => x.Id == dto.ManufacturerId);

                    if (dbManufacturer == null)
                    {
                        throw new ManufacturerNotFoundException();
                    }
                }

                var newTransaction = new WarehouseTransaction()
                {
                    TransactionType = dto.TransactionType,
                    CreatedAt       = dto.CreatedAt,
                    Status          = WarehouseTransactionStatus.Processing, // new warehouse transaction has processing status as default
                    Manufacturer    = dbManufacturer,
                    CreatedBy       = user,
                    Description     = dto.Description,
                };

                await _context.WarehouseTransactions.AddAsync(newTransaction);

                var dbWarehouseTransactionItems = dto.WarehouseTransactionItems.Select(item => new WarehouseTransactionItem
                {
                    WarehouseTransaction = newTransaction,
                    ProductId            = item.ProductId,
                    Cost     = item.Cost,
                    Quantity = item.Quantity
                });


                await _context.WarehouseTransactionItems.AddRangeAsync(dbWarehouseTransactionItems);

                await _context.SaveChangeWithValidationAsync();

                response.Data = _mapper.Map <GetWarehouseTransactionDto>(newTransaction);

                return(response);
            }
            catch (BaseServiceException ex)
            {
                response.Success = false;
                response.Message = ex.ErrorMessage;
                response.Code    = ex.Code;

                _logger.LogError(ex.Message, ex.StackTrace);
                return(response);
            }
            catch (Exception ex)
            {
                response.Success = false;
                response.Message = ex.Message;
                response.Code    = ErrorCode.WAREHOUSE_TRANSACTION_UNEXPECTED_ERROR;

                _logger.LogError(ex.Message, ex.StackTrace);
                return(response);
            }
        }