示例#1
0
        private void SaveAllocation(int eventId, List <ISaleEventAllocation> existing, SaleEventAllocationDto dto)
        {
            var existingAllocations = existing
                                      .Where(a => a.Batch.MaterialId == dto.MaterialId && a.Batch.BatchNumber == dto.BatchNumber).ToList();

            if (existing.Any() && !existingAllocations.Any())
            {
                throw new InvalidOperationException("Pri zmene existujici prodejni akce nesmi byt zmeneny polozky, jen vracene mnozstvi");
            }

            if (dto.ReturnedQuantity != null &&
                m_amountProcessor.GreaterThan(dto.ReturnedQuantity, dto.AllocatedQuantity))
            {
                throw new InvalidOperationException("Nelze vracet vetsi nez blokovane mnozstvi");
            }

            if (!existingAllocations.Any())
            {
                var batches = m_batchFacade.ProposeAllocations(dto.MaterialId, dto.BatchNumber, dto.AllocatedQuantity)
                              .ToList();
                if (batches.Any(b => b.Item1 == null))
                {
                    throw new InvalidOperationException($"Pozadovane mnozstvi {dto.AllocatedQuantity} {m_materialRepository.GetMaterialById(dto.MaterialId)?.Name} neni v sarzi {dto.BatchNumber} k dispozici");
                }

                foreach (var batch in batches)
                {
                    m_database.Save(m_database.New <ISaleEventAllocation>(a =>
                    {
                        a.AllocationDt      = DateTime.Now;
                        a.AllocatedQuantity = batch.Item2.Value;
                        a.UnitId            = batch.Item2.Unit.Id;
                        a.BatchId           = batch.Item1.Value;
                        a.AllocationUserId  = m_session.User.Id;
                        a.SaleEventId       = eventId;

                        if (dto.ReturnedQuantity != null)
                        {
                            a.ReturnedQuantity = dto.ReturnedQuantity.Value;
                            a.ReturnDt         = DateTime.Now;
                            a.ReturnUserId     = m_session.User.Id;
                        }
                    }));
                }

                return;
            }

            var totalAllocatedInDb =
                m_amountProcessor.Sum(existingAllocations.Select(a => new Amount(a.AllocatedQuantity, a.Unit)));

            if (!m_amountProcessor.AreEqual(totalAllocatedInDb, dto.AllocatedQuantity))
            {
                throw new InvalidOperationException("Nelze zmenit alokovane mnozstvi pro existujici akci");
            }

            var totalReturnedInDb = m_amountProcessor.Sum(existingAllocations.Where(a => a.ReturnedQuantity != null)
                                                          .Select(a => new Amount(a.ReturnedQuantity.Value, a.Unit)));

            var returnedAmount = dto.ReturnedQuantity == null
                ? new Amount(0, dto.AllocatedQuantity.Unit)
                : dto.ReturnedQuantity;

            if (m_amountProcessor.AreEqual(totalReturnedInDb, returnedAmount))
            {
                return;
            }

            if (m_amountProcessor.GreaterThan(totalReturnedInDb, returnedAmount))
            {
                throw new InvalidOperationException("Nelze snizovat vracene mnozstvi");
            }

            var newReturn = m_amountProcessor.Subtract(returnedAmount, totalReturnedInDb);

            foreach (var existingAloc in existingAllocations)
            {
                if (!newReturn.IsPositive)
                {
                    break;
                }

                var alreadyReturnedHere = existingAloc.ReturnedQuantity == null
                    ? new Amount(0, existingAloc.Unit)
                    : new Amount(existingAloc.ReturnedQuantity.Value, existingAloc.Unit);

                var toReturnHere =
                    m_amountProcessor.Subtract(new Amount(existingAloc.AllocatedQuantity, existingAloc.Unit),
                                               alreadyReturnedHere);

                if (!toReturnHere.IsPositive)
                {
                    continue;
                }

                var actuallyReturningHere = m_amountProcessor.Min(toReturnHere, newReturn);

                existingAloc.ReturnedQuantity = actuallyReturningHere.Value;
                existingAloc.UnitId           = actuallyReturningHere.Unit.Id;
                m_database.Save(existingAloc);

                newReturn = m_amountProcessor.Subtract(newReturn, actuallyReturningHere);
            }

            if (newReturn.IsPositive)
            {
                throw new InvalidOperationException("Nebylo mozne vratit vsechno pozadovane mnozstvi");
            }
        }