public void Should_Success_AddMovement_when_Type_ADJ()
        {
            var dbContext = new PackingInventoryDbContext(CreateNewContextOptions(MethodBase.GetCurrentMethod().ReflectedType.FullName + MethodBase.GetCurrentMethod().Name));

            //Arrange
            var serviceProviderMock = new Mock <IServiceProvider>();

            serviceProviderMock
            .Setup(serviceProvider => serviceProvider.GetService(typeof(IIdentityProvider)))
            .Returns(new IdentityProvider()
            {
                TimezoneOffset = 1, Token = "token", Username = "******"
            });

            var unitOfWork = new UnitOfWork(dbContext, serviceProviderMock.Object);


            var azureServiceBusSenderMock = new Mock <IAzureServiceBusSender <ProductSKUInventoryMovementModel> >();

            var service = GetService(GetServiceProvider(unitOfWork, azureServiceBusSenderMock.Object).Object);

            //Act
            var inventoryMovement = new ProductSKUInventoryMovementModel(0, 0, 0, 0, "storageCode", "storageName", 0, "ADJ", "Remark");

            inventoryMovement.SetPreviousBalance(0);
            inventoryMovement.SetCurrentBalance(1);

            service.AddMovement(inventoryMovement);
        }
        public void Should_Success_AddMovement_when_Type_Out()
        {
            //Arrange
            var unitOfWorkMock            = new Mock <IUnitOfWork>();
            var azureServiceBusSenderMock = new Mock <IAzureServiceBusSender <ProductSKUInventoryMovementModel> >();

            unitOfWorkMock
            .Setup(s => s.ProductSKUInventorySummaries.Get(It.IsAny <Expression <Func <ProductSKUInventorySummaryModel, bool> > >(), It.IsAny <Func <IQueryable <ProductSKUInventorySummaryModel>, IOrderedQueryable <ProductSKUInventorySummaryModel> > >(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <int>()))
            .Returns(new List <ProductSKUInventorySummaryModel>()
            {
                new ProductSKUInventorySummaryModel(0, 0, "storageCode", "storageName", 1)
            });

            unitOfWorkMock
            .Setup(s => s.ProductSKUInventoryMovements
                   .Insert(It.IsAny <ProductSKUInventoryMovementModel>())).Verifiable();

            unitOfWorkMock
            .Setup(s => s.ProductSKUInventorySummaries
                   .Insert(It.IsAny <ProductSKUInventorySummaryModel>())).Verifiable();

            var service = GetService(GetServiceProvider(unitOfWorkMock.Object, azureServiceBusSenderMock.Object).Object);

            //Act
            var inventoryMovement = new ProductSKUInventoryMovementModel(0, 0, 0, 0, "storageCode", "storageName", 0, "OUT", "Remark");

            inventoryMovement.SetPreviousBalance(0);
            inventoryMovement.SetCurrentBalance(1);
            inventoryMovement.AdjustCurrentBalance(1);

            service.AddMovement(inventoryMovement);
        }
        public void AddMovement(ProductSKUInventoryMovementModel inventoryMovement)
        {
            var summary = _unitOfWork.ProductSKUInventorySummaries.Get().FirstOrDefault(entity => entity.ProductSKUId == inventoryMovement.ProductSKUId && entity.UOMId == inventoryMovement.UOMId && entity.StorageId == inventoryMovement.StorageId);

            if (summary == null)
            {
                switch (inventoryMovement.Type.ToUpper())
                {
                case "IN":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity);
                    break;

                case "OUT":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity * -1);
                    break;

                case "ADJ":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity);
                    break;

                default:
                    throw new Exception("Invalid Type");
                }
                _unitOfWork.ProductSKUInventoryMovements.Insert(inventoryMovement);

                summary = new ProductSKUInventorySummaryModel(inventoryMovement.ProductSKUId, inventoryMovement.StorageId, inventoryMovement.StorageCode, inventoryMovement.StorageName, inventoryMovement.UOMId);
                summary.SetBalance(inventoryMovement.CurrentBalance);
                _unitOfWork.ProductSKUInventorySummaries.Insert(summary);
            }
            else
            {
                inventoryMovement.SetPreviousBalance(summary.Balance);
                switch (inventoryMovement.Type.ToUpper())
                {
                case "IN":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity);
                    break;

                case "OUT":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity * -1);
                    break;

                case "ADJ":
                    inventoryMovement.SetCurrentBalance(inventoryMovement.Quantity);
                    break;

                default:
                    throw new Exception("Invalid Type");
                }
                _unitOfWork.ProductSKUInventoryMovements.Insert(inventoryMovement);

                summary.SetBalance(inventoryMovement.CurrentBalance);
                _unitOfWork.ProductSKUInventorySummaries.Update(summary);
            }

            _unitOfWork.Commit();
        }
        public int AddDocument(FormDto form)
        {
            var documentNo = CodeGenerator.GenerateCode();

            do
            {
                documentNo = CodeGenerator.GenerateCode();
            }while (_unitOfWork.ProductSKUInventoryDocuments.Get(entity => entity.DocumentNo == documentNo).Count() > 0);

            var model = new ProductSKUInventoryDocumentModel(
                documentNo,
                form.Date.GetValueOrDefault(),
                form.ReferenceNo,
                form.ReferenceType,
                form.Storage._id.GetValueOrDefault(),
                form.Storage.name,
                form.Storage.code,
                form.Type,
                form.Remark);

            _unitOfWork.ProductSKUInventoryDocuments.Insert(model);
            _unitOfWork.Commit();

            if (model.Id > 0)
            {
                foreach (var item in form.Items)
                {
                    var movementItem = new ProductSKUInventoryMovementModel(model.Id, item.ProductSKUId.GetValueOrDefault(), item.UOMId.GetValueOrDefault(), model.StorageId, model.StorageCode, model.StorageName, item.Quantity.GetValueOrDefault(), model.Type, item.Remark);

                    var summary = _unitOfWork.ProductSKUInventorySummaries.Get(element => element.ProductSKUId == item.ProductSKUId.GetValueOrDefault() && element.StorageId == model.StorageId && item.UOMId.GetValueOrDefault() == element.StorageId).FirstOrDefault();

                    if (summary == null)
                    {
                        switch (movementItem.Type.ToUpper())
                        {
                        case "IN":
                            movementItem.SetCurrentBalance(movementItem.Quantity);
                            break;

                        case "OUT":
                            movementItem.SetCurrentBalance(movementItem.Quantity * -1);
                            break;

                        case "ADJ":
                            movementItem.SetCurrentBalance(movementItem.Quantity);
                            break;

                        default:
                            throw new Exception("Invalid Type");
                        }

                        summary = new ProductSKUInventorySummaryModel(item.ProductSKUId.GetValueOrDefault(), model.StorageId, model.StorageCode, model.StorageName, item.UOMId.GetValueOrDefault());
                        summary.SetBalance(movementItem.CurrentBalance);
                        _unitOfWork.ProductSKUInventorySummaries.Insert(summary);
                    }
                    else
                    {
                        movementItem.SetPreviousBalance(summary.Balance);
                        switch (movementItem.Type.ToUpper())
                        {
                        case "IN":
                            movementItem.SetCurrentBalance(movementItem.Quantity);
                            break;

                        case "OUT":
                            movementItem.SetCurrentBalance(movementItem.Quantity * -1);
                            break;

                        case "ADJ":
                            movementItem.SetCurrentBalance(movementItem.Quantity);
                            break;

                        default:
                            throw new Exception("Invalid Type");
                        }

                        summary.SetBalance(movementItem.CurrentBalance);
                        _unitOfWork.ProductSKUInventorySummaries.Update(summary);
                    }

                    _unitOfWork.ProductSKUInventoryMovements.Insert(movementItem);
                    _unitOfWork.Commit();
                }
            }

            return(model.Id);
        }