public DomainObjects.InventoryOperation Create(FuelReportDetail fuelReportDetail, long inventoryOperationId, string actionNumber, Enums.InventoryActionType actionType, DateTime actionDate)
        {
            InventoryOperation result = new InventoryOperation(
                inventoryOperationId,
                actionNumber,
                actionDate,
                actionType,
                fuelReportDetail.Id,
                null);

            return result;
        }
        //================================================================================
        private decimal calculateConsumption(FuelReportDetail fuelReportDetail)
        {
            if (!(fuelReportDetail.FuelReport.FuelReportType == FuelReportTypes.EndOfMonth ||
                fuelReportDetail.FuelReport.FuelReportType == FuelReportTypes.EndOfVoyage ||
                fuelReportDetail.FuelReport.FuelReportType == FuelReportTypes.EndOfYear))
            {
                return 0;
            }

            var fuelReportDomainService = ServiceLocator.Current.GetInstance<IFuelReportDomainService>();

            var reportingConsumption = fuelReportDomainService.CalculateReportingConsumption(fuelReportDetail);

            return reportingConsumption;
        }
        public List<InventoryOperation> NotifySubmittingFuelReportDetail(FuelReportDetail source)
        {
            var fuelReportDetailDto = fuelReportDetailToFuelReportDetailDtoMapper.MapToModel(source);

            fuelReportDetailDto.FuelReport = fuelReportToFuelReportDtoMapper.MapToModel(source.FuelReport);

            //var inventoryOperationDtosResult = svc.NotifySubmittingFuelReportDetail(fuelReportDetailDto).ToList();

            //var result = inventoryOperationDtosResult.Select(mapInventoryOperationDtoToInventoryOperation);

            //return result.ToList();

            var syncEvent = new AutoResetEvent(false);

            List<InventoryOperation> callResult = null;
            Exception callException = null;

            ClientHelper.Post<List<FuelReportInventoryOperationDto>, FuelReportDetailDto>
                //(new Uri("http://localhost:65234/api/fuelevents", UriKind.Absolute),
                //(new Uri("http://evaluation-srv:9090/api/fuelevents", UriKind.Absolute),
                (MessageBrokerApiUri, (result, exp) =>
                {
                    callException = exp;
                    if (result != null)
                        callResult = result.Select(mapInventoryOperationDtoToInventoryOperation).ToList();

                    syncEvent.Set();
                },
                fuelReportDetailDto, ClientHelper.MessageFormat.Json, new Dictionary<string, string>(), "FuelReportDetailDto");

            syncEvent.WaitOne();

            if (callException != null)
                throw callException;

            return callResult;
        }
        public List<InventoryOperation> NotifySubmittingFuelReportDetail(FuelReportDetail source)
        {
            //var fuelReportDetailDto = fuelReportDetailToFuelReportDetailDtoMapper.MapToModel(source);

            //fuelReportDetailDto.FuelReport = fuelReportToFuelReportDtoMapper.MapToModel(source.FuelReport);

            //var inventoryOperationDtosResult = svc.NotifySubmittingFuelReportDetail(fuelReportDetailDto).ToList();

            //var result = inventoryOperationDtosResult.Select(mapInventoryOperationDtoToInventoryOperation);

            //return result.ToList();

            return null;
        }
        internal void Update(
            double rob,
            double consumption,
            double? receive,
            ReceiveTypes? receiveType,
            double? transfer,
            TransferTypes? transferType,
            double? correction,
            CorrectionTypes? correctionType,
            decimal? correctionPrice,
            long? correctionPriceCurrencyId,
            Reference transferReference,
            Reference receiveReference,
            Reference correctionReference,
            FuelReportDetail relevantFuelReportDetailOfTheDayBefore,
            bool isDetailOfFirstFuelReport,
            ICurrencyDomainService currencyDomainService)
        {
            validateValues(rob, consumption, receive, receiveType, transfer, transferType, correction, correctionType,
                correctionPrice, correctionPriceCurrencyId,
                transferReference,
                receiveReference,
                correctionReference,
                relevantFuelReportDetailOfTheDayBefore, isDetailOfFirstFuelReport, currencyDomainService);

            refineValues(ref rob, ref consumption, ref receive, ref receiveType, ref transfer, ref transferType, ref correction, ref correctionType, ref correctionPrice, ref correctionPriceCurrencyId, ref transferReference, ref receiveReference, ref correctionReference);

            ROB = rob;
            Consumption = consumption;
            Receive = receive;
            ReceiveType = receiveType;
            Transfer = transfer;
            TransferType = transferType;
            Correction = correction;
            CorrectionPrice = correctionPrice;
            CorrectionType = correctionType;
            CorrectionPriceCurrencyId = correctionPriceCurrencyId;

            TransferReference = transferReference;
            ReceiveReference = receiveReference;
            CorrectionReference = correctionReference;
        }
        public List<InventoryOperation> NotifySubmittingFuelReportDetail(FuelReportDetail source, IFuelReportDomainService fuelReportDomainService)
        {
            var result = new List<InventoryOperation>();

            try
            {
                if (source.Correction.HasValue && source.CorrectionType.HasValue)
                {
                    if (source.CorrectionType.Value == CorrectionTypes.Plus)
                    {
                        if (source.CorrectionReference.IsEmpty())
                        {
                            if (source.IsCorrectionPriceEmpty())
                            {
                                var lastReceiveFuelReportDetailBefore = fuelReportDomainService.GetLastReceiveFuelReportDetailBefore(source);

                                var lastReceiveInventoryOperationId = inventoryOperationManager.GetFueReportDetailReceiveOperationReference(lastReceiveFuelReportDetailBefore).OperationId;

                                result.AddRange(this.inventoryOperationManager.ManageFuelReportDetailIncrementalCorrectionUsingReferencePricing(source, lastReceiveInventoryOperationId, "PricingByLastReceipt",
                                    //TODO: Fake ActorId
                                    1101));
                            }
                            else
                            {
                                result.AddRange(this.inventoryOperationManager.ManageFuelReportDetailIncrementalCorrectionDirectPricing(source,
                                    //TODO: Fake ActorId
                                    1101));
                            }
                        }
                        else
                        {
                            if (source.CorrectionReference.ReferenceType.Value == ReferenceType.Voyage)
                            {
                                //var eovFuelReport = fuelReportDomainService.GetVoyageValidEndOfVoyageFuelReport(source.CorrectionReference.ReferenceId.Value);

                                //var consumptionInventoryOperationId = eovFuelReport.ConsumptionInventoryOperations.Last().InventoryOperationId;

                                var consumptionInventoryOperationId = fuelReportDomainService.GetVoyageConsumptionIssueOperation(source.CorrectionReference.ReferenceId.Value).InventoryOperationId;

                                result.AddRange(this.inventoryOperationManager.ManageFuelReportDetailIncrementalCorrectionUsingReferencePricing(source, consumptionInventoryOperationId, "PricingByIssuedVoyage",
                                    //TODO: Fake ActorId
                                    1101));
                            }
                        }
                    }
                    else
                    {
                        result.AddRange(this.inventoryOperationManager.ManageFuelReportDetailDecrementalCorrection(source,
                            //TODO: Fake ActorId
                                             1101));
                    }
                }

                result.AddRange(this.inventoryOperationManager.ManageFuelReportDetail(source,
                    //TODO: Fake ActorId
                    1101));
            }
            catch (Exception)
            {

                throw;
            }

            return result;
        }
        //================================================================================
        public List<InventoryOperation> ManageFuelReportDetailIncrementalCorrectionUsingReferencePricing(FuelReportDetail fuelReportDetail, long pricingReferenceId, string pricingReferenceType, int userId)
        {
            using (var dbContext = new InventoryDbContext())
            {
                using (var transaction = dbContext.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                {
                    var result = new List<Domain.Model.DomainObjects.InventoryOperation>();

                    #region Incremental Correction

                    var transactionReferenceNumber = fuelReportDetail.Id.ToString();

                    var reference = findInventoryOperationReference(dbContext, InventoryOperationType.Receipt, FUEL_REPORT_DETAIL_INCREMENTAL_CORRECTION, transactionReferenceNumber);

                    //if (reference.OperationId == INVALID_ID)
                    if (reference == null)
                    {
                        string transactionCode, transactionMessage;

                        var operationReference =
                            receipt(
                                  dbContext,
                                  (int)fuelReportDetail.FuelReport.VesselInCompany.CompanyId,
                                  (int)fuelReportDetail.FuelReport.VesselInCompany.VesselInInventory.Id,
                                  1,
                                  convertFuelReportCorrectionTypeToStoreType(fuelReportDetail),
                                    (int)pricingReferenceId,
                                  FUEL_REPORT_DETAIL_INCREMENTAL_CORRECTION,
                                  transactionReferenceNumber,
                                  userId,
                                  out transactionCode,
                                  out transactionMessage);

                        string transactionItemMessage;

                        var transactionItems = new List<TransactionItem>();
                        transactionItems.Add(new TransactionItem()
                        {
                            GoodId = (int)fuelReportDetail.Good.SharedGoodId,
                            CreateDate = DateTime.Now,
                            Description = fuelReportDetail.FuelReport.FuelReportType.ToString(),
                            QuantityAmount = (decimal?)fuelReportDetail.Correction,
                            QuantityUnitId = getMeasurementUnitId(dbContext, fuelReportDetail.MeasuringUnit.Abbreviation),
                            TransactionId = (int)operationReference.OperationId,
                            UserCreatorId = userId
                        });

                        var transactionItemIds = addTransactionItems(dbContext, (int)operationReference.OperationId, transactionItems, userId, out transactionItemMessage);

                        string pricingMessage;

                        priceSuspendedTransactionUsingReference(dbContext, (int)operationReference.OperationId, pricingReferenceType, userId, out pricingMessage, FUEL_REPORT_DETAIL_INCREMENTAL_CORRECTION_PRICING, transactionReferenceNumber);

                        result.Add(new InventoryOperation(
                                       inventoryOperationId: operationReference.OperationId,
                                       actionNumber: string.Format("{0}/{1}", (InventoryOperationType)operationReference.OperationType, transactionCode),
                                       actionDate: DateTime.Now,
                                       actionType: InventoryActionType.Receipt,
                                       fuelReportDetailId: fuelReportDetail.Id,
                                       charterId: null));

                    }
                    else
                    {
                        throw new InvalidOperation("FR Incremental Correction Edit", "FueReport  Incremental Correction edit is invalid");
                        var transactionItems = dbContext.TransactionItems.Where(ti => ti.TransactionId == reference.OperationId);
                    }

                    #endregion

                    transaction.Commit();

                    return result;
                }
            }
        }
 private int convertFuelReportTransferTypeToStoreType(FuelReportDetail detail)
 {
     switch (detail.TransferType)
     {
         case TransferTypes.InternalTransfer:
             return 10;
         case TransferTypes.TransferSale:
             return 11;
         case TransferTypes.Rejected:
             return 12;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
        //================================================================================
        public List<Reference> GetFuelReportDetailCorrectionReferences(FuelReportDetail fuelReportDetail)
        {
            List<Reference> result = null;

            var lastIssuedEOVFuelReportsOfPreviousVoyages = GetLastIssuedEOVFuelReportOfPreviousVoyages(fuelReportDetail.FuelReport);

            if (lastIssuedEOVFuelReportsOfPreviousVoyages != null)
            {
                result = new List<Reference>(){
                    new Reference(){
                        ReferenceType= ReferenceType.Voyage,
                        ReferenceId = lastIssuedEOVFuelReportsOfPreviousVoyages.Voyage.Id,
                        Code = lastIssuedEOVFuelReportsOfPreviousVoyages.Voyage.VoyageNumber
                    }};
            }

            return result;
        }
        //================================================================================
        private void populateFuelReportDetailDtoReferencesLookup(FuelReportDetail fuelReportDetail, FuelReportDetailDto fuelReportDetailDto)
        {
            var correctionReferences = fuelReportDomainService.GetFuelReportDetailCorrectionReferences(fuelReportDetail);
            var transferReferences = fuelReportDomainService.GetFuelReportDetailTransferReferences(fuelReportDetail);
            var receiveReferences = fuelReportDomainService.GetFuelReportDetailReceiveReferences(fuelReportDetail);
            var rejectedReferences = fuelReportDomainService.GetFuelReportDetailRejectedTransferReferences(fuelReportDetail);

            fuelReportDetailDto.FuelReportCorrectionReferenceNoDtos = new List<FuelReportCorrectionReferenceNoDto>();

            if (correctionReferences != null)
            {
                fuelReportDetailDto.FuelReportCorrectionReferenceNoDtos.AddRange(
                    correctionReferences.Select(r => new FuelReportCorrectionReferenceNoDto()
                        {
                            Id = r.ReferenceId.Value,
                            Code = r.Code,
                            ReferenceType = (ReferenceTypeEnum)(int)r.ReferenceType.Value
                        }));
            }

            fuelReportDetailDto.FuelReportTransferReferenceNoDtos = new List<FuelReportTransferReferenceNoDto>();

            if (transferReferences != null)
            {
                fuelReportDetailDto.FuelReportTransferReferenceNoDtos.AddRange(transferReferences.Select(r => new FuelReportTransferReferenceNoDto()
                {
                    Id = r.ReferenceId.Value,
                    Code = r.Code,
                    ReferenceType = (ReferenceTypeEnum)(int)r.ReferenceType.Value
                }));
            }

            fuelReportDetailDto.FuelReportReciveReferenceNoDtos = new List<FuelReportReciveReferenceNoDto>();

            if (receiveReferences != null)
            {
                fuelReportDetailDto.FuelReportReciveReferenceNoDtos.AddRange(receiveReferences.Select(r => new FuelReportReciveReferenceNoDto()
                {
                    Id = r.ReferenceId.Value,
                    Code = r.Code,
                    ReferenceType = (ReferenceTypeEnum)(int)r.ReferenceType.Value
                }));
            }

            fuelReportDetailDto.RejectedTransferReferenceNoDtos = new List<FuelReportTransferReferenceNoDto>();

            if (rejectedReferences != null)
            {
                fuelReportDetailDto.RejectedTransferReferenceNoDtos.AddRange(rejectedReferences.Select(r => new FuelReportTransferReferenceNoDto()
                {
                    Id = r.ReferenceId.Value,
                    Code = r.Code,
                    ReferenceType = (ReferenceTypeEnum)(int)r.ReferenceType.Value
                }));
            }
        }
        public List<InventoryOperation> NotifySubmittingFuelReportDetail(FuelReportDetail source)
        {
            var dto = fuelReportDetailDtoMapper.MapToModel(source);
            dto.FuelReport = fuelReportDtoMapper.MapToModel(source.FuelReport);

            setConsumption(dto, source);

            return new List<InventoryOperation>(new InventoryOperation[]
                    {
                     new InventoryOperation(
                        "INV# - " +DateTime.Now.Ticks,
                        DateTime.Now,
                        InventoryActionType.Issue,
                        (long? )null,
                        (long? )null)
                    });
        }
        private void validateValues(
            double rob,
            double consumption,
            double? receive,
            ReceiveTypes? receiveType,
            double? transfer,
            TransferTypes? transferType,
            double? correction,
            CorrectionTypes? correctionType,
            decimal? correctionPrice,
            long? correctionPriceCurrencyId,
            //ReferenceType? transferReferenceType,
            //long? transferReferenceEntityId,
            //ReferenceType? receiveReferenceType,
            //long? receiveReferenceEntityId,
            //ReferenceType? correctionReferenceType,
            //long? correctionReferenceEntityId,
            Reference transferReference,
            Reference receiveReference,
            Reference correctionReference,
            FuelReportDetail relevantFuelReportDetailOfTheDayBefore,
            bool isDetailOfFirstFuelReport,
            ICurrencyDomainService currencyDomainService)
        {
            refineValues(ref rob, ref consumption, ref receive, ref receiveType, ref transfer, ref transferType, ref correction, ref correctionType, ref correctionPrice, ref correctionPriceCurrencyId, ref transferReference, ref receiveReference, ref correctionReference);

            //BR_FR3
            validateConsumptionAndROBAvailability(consumption, rob);

            //BR_FR4
            validateNotNegativeConsumptionAndROB(consumption, rob);

            //BR_FR5
            validateReceiveType(receive, receiveType);

            //BR_FR6
            validateTransferType(transfer, transferType);

            //BR_FR7
            validateCorrectionType(correction, correctionType, correctionPriceCurrencyId,
                                                         correctionPrice, currencyDomainService);

            //validatePositiveCorrectionTypeCurrencyAndPriceValues(correction, correctionType, correctionPriceCurrencyId,
            //                                             correctionPrice, currencyDomainService);

            //BR_FR8
            validateNotNegativeReceiveTransferCorrection(receive, transfer, correction);

            //BR_FR9
            //This is already implemented via BR_FR5, BR_FR6, BR_FR7.

            //BR_FR34
            validateValuesForEndOfVoyageEndOfMonthEndOfYearFuelReport(
                rob,
                consumption,
                receive,
                receiveType,
                transfer,
                transferType,
                correction,
                correctionType,
                correctionPrice,
                correctionPriceCurrencyId);

            if (relevantFuelReportDetailOfTheDayBefore == null)
            {
                if (isDetailOfFirstFuelReport)
                {
                    //NOTE: No need to validate ROB for Details of the First Fuel Report in the system.
                }
                else
                {
                    //NOTE: The Detail of Yesterday Fuel Report is not found.
                    throw new ObjectNotFound(string.Format("RelevantFuelReportDetailOfTheDayBefore for '{0}'", this.Good.Code));
                }
            }
            else
            {
                //The Detail for Yesterday Report has been found.
                double? robOfTheDayBefore = relevantFuelReportDetailOfTheDayBefore.ROB;
                //double? receiveOfTheDayBefore = relevantFuelReportDetailOfTheDayBefore.Receive;
                //double? correctionOfTheDayBefore = relevantFuelReportDetailOfTheDayBefore.Correction;
                //CorrectionTypes? correctionTypeOfTheDayBefore = relevantFuelReportDetailOfTheDayBefore.CorrectionType;
                //double? transferOfTheDayBefore = relevantFuelReportDetailOfTheDayBefore.Transfer;

                //BR_FR10
                validateROB(
                    rob,
                    consumption,
                    receive,
                    correction,
                    correctionType,
                    transfer,
                    robOfTheDayBefore);
            }
        }
 //===================================================================================
 internal void ValidateCurrentValues(
     FuelReportDetail relevantFuelReportDetailOfTheDayBefore,
     bool isDetailOfFirstFuelReport,
     ICurrencyDomainService currencyDomainService)
 {
     validateValues(this.ROB, this.Consumption, this.Receive, this.ReceiveType, this.Transfer, this.TransferType, this.Correction, this.CorrectionType, this.CorrectionPrice, this.CorrectionPriceCurrencyId, this.TransferReference, this.ReceiveReference, this.CorrectionReference, relevantFuelReportDetailOfTheDayBefore, isDetailOfFirstFuelReport, currencyDomainService);
 }
        //===================================================================================
        internal void UpdateConsumption(FuelReportDetail relevantFeulReportDetailOfPreviousReport)
        {
            double? calculatedCorrection = (this.Correction * getCorrectionTypeFactor(this.CorrectionType));

            double calculatedNewConsumption =
                this.ROB - relevantFeulReportDetailOfPreviousReport.ROB +
                    (this.Receive ?? 0) +
                    (calculatedCorrection ?? 0) -
                    (this.Transfer ?? 0);

            this.Consumption = calculatedNewConsumption;
        }
        //===================================================================================
        internal void Update(double rob, double consumption,
            FuelReportDetail relevantFuelReportDetailOfTheDayBefore,
            bool isDetailOfFirstFuelReport,
            ICurrencyDomainService currencyDomainService)
        {
            validateValues(rob, consumption, this.Receive, this.ReceiveType, this.Transfer, this.TransferType, this.Correction, this.CorrectionType, this.CorrectionPrice, this.CorrectionPriceCurrencyId, this.TransferReference, this.ReceiveReference, this.CorrectionReference, relevantFuelReportDetailOfTheDayBefore, isDetailOfFirstFuelReport, currencyDomainService);

            //Values refinement.
            //rob = !rob.HasValue || rob == 0 ? null : rob;
            //consumption = !consumption.HasValue || consumption == 0 ? null : consumption;

            ROB = rob;
            Consumption = consumption;
        }
 private int convertFuelReportCorrectionTypeToStoreType(FuelReportDetail detail)
 {
     switch (detail.CorrectionType)
     {
         case CorrectionTypes.Plus:
             return 7;
         case CorrectionTypes.Minus:
             return 13;
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
        //private decimal? calculateCorrectionAmount(FuelReportDetail detail)
        //{
        //    if (detail.Correction.HasValue && detail.CorrectionType.HasValue)
        //    {
        //        return (decimal?)((detail.CorrectionType.Value == CorrectionTypes.Minus ? -1 : 1) * detail.Correction.Value);
        //    }
        //    return null;
        //}
        /*
            1,  1, N'Charter In Start'
            2,  1, N'FuelReport Receive Trust'
            3,  1, N'FuelReport Receive InternalTransfer'
            4,  1, N'FuelReport Receive TransferPurchase'
            5,  1, N'FuelReport Receive Purchase'
            6 , 1, N'FuelReport Receive From Tank'
            7 , 1, N'FuelReport Incremental Correction',
            8 , 1, N'Charter Out End'

            9 , 2, N'Charter Out Start'
            10, 2, N'FuelReport Transfer InternalTransfer'
            11, 2, N'FuelReport Transfer TransferSale'
            12, 2, N'FuelReport Transfer Rejected'
            13, 2, N'FuelReport Decremental Correction'
            14, 2, N'EOV Consumption'
            15, 2, N'EOM Consumption'
            16, 2, N'EOY Consumption'
            17, 2, N'Charter In End'

        */
        private int convertFuelReportReceiveTypeToStoreType(FuelReportDetail detail)
        {
            switch (detail.ReceiveType)
            {
                case ReceiveTypes.Trust:
                    return 2;
                case ReceiveTypes.InternalTransfer:
                    return 3;
                case ReceiveTypes.TransferPurchase:
                    return 4;
                case ReceiveTypes.Purchase:
                    return 5;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
 //================================================================================
 public List<Reference> GetFuelReportDetailRejectedTransferReferences(FuelReportDetail fuelReportDetail)
 {
     return inventoryManagementDomainService.GetVesselPurchaseReceiptNumbers(fuelReportDetail.FuelReport.VesselInCompany.CompanyId, fuelReportDetail.FuelReport.VesselInCompanyId);
 }
        public List<InventoryOperation> ManageFuelReportDetail(FuelReportDetail fuelReportDetail, int userId)
        {
            using (var dbContext = new InventoryDbContext())
            {
                using (var transaction = dbContext.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                {
                    var result = new List<Domain.Model.DomainObjects.InventoryOperation>();

                    if (fuelReportDetail.Receive.HasValue)
                    {
                        //TODO: Receive OK Except for Trust
                        #region Receive
                        var reference = findInventoryOperationReference(dbContext, InventoryOperationType.Receipt, FUEL_REPORT_DETAIL_RECEIVE, fuelReportDetail.Id.ToString());

                        //if (reference.OperationId == INVALID_ID)
                        if (reference == null)
                        {
                            string transactionCode, transactionMessage;

                            var operationReference =
                                receipt(
                                    dbContext,
                                    (int)fuelReportDetail.FuelReport.VesselInCompany.CompanyId,
                                    (int)fuelReportDetail.FuelReport.VesselInCompany.VesselInInventory.Id,
                                    1,
                                    convertFuelReportReceiveTypeToStoreType(fuelReportDetail),
                                    null,
                                    FUEL_REPORT_DETAIL_RECEIVE,
                                    fuelReportDetail.Id.ToString(),
                                    userId,
                                    out transactionCode,
                                    out transactionMessage);

                            string transactionItemMessage;

                            var transactionItems = new List<TransactionItem>();
                            transactionItems.Add(new TransactionItem()
                            {
                                GoodId = (int)fuelReportDetail.Good.SharedGoodId,
                                CreateDate = DateTime.Now,
                                Description = fuelReportDetail.FuelReport.FuelReportType.ToString(),
                                QuantityAmount = (decimal?)fuelReportDetail.Receive.Value,
                                QuantityUnitId = getMeasurementUnitId(dbContext, fuelReportDetail.MeasuringUnit.Abbreviation),
                                TransactionId = (int)operationReference.OperationId,
                                UserCreatorId = userId
                            });

                            addTransactionItems(dbContext, (int)operationReference.OperationId, transactionItems, userId, out transactionItemMessage);

                            result.Add(new InventoryOperation(
                                        inventoryOperationId: operationReference.OperationId,
                                        actionNumber: string.Format("{0}/{1}", (InventoryOperationType)operationReference.OperationType, transactionCode),
                                        actionDate: DateTime.Now,
                                        actionType: InventoryActionType.Receipt,
                                        fuelReportDetailId: fuelReportDetail.Id,
                                        charterId: null));
                        }
                        else
                        {
                            throw new InvalidOperation("FR Receive Receipt Edit", "FueReport Receive edit is invalid");

                            var transactionItems = dbContext.TransactionItems.Where(ti => ti.TransactionId == reference.OperationId);

                        }
                        #endregion
                    }

                    if (fuelReportDetail.Transfer.HasValue)
                    {
                        //TODO: Transfer
                        #region Transfer

                        var reference = findInventoryOperationReference(dbContext, InventoryOperationType.Issue, FUEL_REPORT_DETAIL_TRANSFER, fuelReportDetail.Id.ToString());

                        //if (reference.OperationId == INVALID_ID)
                        if (reference == null)
                        {
                            string transactionCode, transactionMessage;

                            var operationReference =
                                issue(
                                    dbContext,
                                    (int)fuelReportDetail.FuelReport.VesselInCompany.CompanyId,
                                    (int)fuelReportDetail.FuelReport.VesselInCompany.VesselInInventory.Id,
                                    1,
                                    convertFuelReportTransferTypeToStoreType(fuelReportDetail),
                                    null,
                                    FUEL_REPORT_DETAIL_TRANSFER,
                                    fuelReportDetail.Id.ToString(),
                                    userId,
                                    out transactionCode,
                                    out transactionMessage);

                            string transactionItemMessage;

                            var transactionItems = new List<TransactionItem>();
                            transactionItems.Add(new TransactionItem()
                            {
                                GoodId = (int)fuelReportDetail.Good.SharedGoodId,
                                CreateDate = DateTime.Now,
                                Description = fuelReportDetail.FuelReport.FuelReportType.ToString(),
                                QuantityAmount = (decimal?)fuelReportDetail.Transfer.Value,
                                QuantityUnitId = getMeasurementUnitId(dbContext, fuelReportDetail.MeasuringUnit.Abbreviation),
                                TransactionId = (int)operationReference.OperationId,
                                UserCreatorId = userId
                            });

                            addTransactionItems(dbContext, (int)operationReference.OperationId, transactionItems, userId, out transactionItemMessage);

                            result.Add(new InventoryOperation(
                                        inventoryOperationId: operationReference.OperationId,
                                        actionNumber: string.Format("{0}/{1}", (InventoryOperationType)operationReference.OperationType, transactionCode),
                                        actionDate: DateTime.Now,
                                        actionType: InventoryActionType.Issue,
                                        fuelReportDetailId: fuelReportDetail.Id,
                                        charterId: null));
                        }
                        else
                        {
                            throw new InvalidOperation("FR Transfer Issue Edit", "FueReport Transfer edit is invalid");

                            var transactionItems = dbContext.TransactionItems.Where(ti => ti.TransactionId == reference.OperationId);

                        }
                        #endregion
                    }

                    transaction.Commit();

                    return result;
                }
            }
            return null;
        }
        //================================================================================
        public List<Reference> GetFuelReportDetailTransferReferences(FuelReportDetail fuelReportDetail)
        {
            List<Reference> result = null;

            //if (fuelReportDetail.TransferType.HasValue)
            //{
            //    switch (fuelReportDetail.TransferType.Value)
            //    {
            //        case TransferTypes.TransferSale:

            //            var finalApprovedTransferOrder = orderDomainService.GetFinalApprovedTransferOrders(fuelReportDetail.FuelReport.Vessel.CompanyId);

            //            result = new List<Reference>(
            //                finalApprovedTransferOrder.Select(
            //                    o => new Reference
            //                        {
            //                            ReferenceType = ReferenceType.Order,
            //                            ReferenceId = o.Id,
            //                            Code = o.Code
            //                        }));
            //            break;

            //        case TransferTypes.InternalTransfer:

            //            var finalApprovedInternalTransferOrder = orderDomainService.GetFinalApprovedInternalTransferOrders(fuelReportDetail.FuelReport.Vessel.CompanyId);

            //            result = new List<Reference>(
            //                finalApprovedInternalTransferOrder.Select(
            //                o => new Reference
            //                    {
            //                        ReferenceType = ReferenceType.Order,
            //                        ReferenceId = o.Id,
            //                        Code = o.Code
            //                    }));

            //            break;
            //    }
            //}

            result = new List<Reference>();

            var finalApprovedTransferOrder = orderDomainService.GetFinalApprovedTransferOrders(fuelReportDetail.FuelReport.VesselInCompany.CompanyId);

            result.AddRange(
                finalApprovedTransferOrder.Select(
                    o => new Reference
                    {
                        ReferenceType = ReferenceType.Order,
                        ReferenceId = o.Id,
                        Code = o.Code
                    }));

            var finalApprovedInternalTransferOrder = orderDomainService.GetFinalApprovedInternalTransferOrders(fuelReportDetail.FuelReport.VesselInCompany.CompanyId);

            result.AddRange(
                finalApprovedInternalTransferOrder.Select(
                o => new Reference
                {
                    ReferenceType = ReferenceType.Order,
                    ReferenceId = o.Id,
                    Code = o.Code
                }));

            return result;
        }
        public OperationReference GetFueReportDetailReceiveOperationReference(FuelReportDetail fuelReportDetail)
        {
            var transactionReferenceNumber = fuelReportDetail.Id.ToString();

            using (var dbContext = new InventoryDbContext())
            {
                var operationReference = findInventoryOperationReference(dbContext, InventoryOperationType.Receipt, FUEL_REPORT_DETAIL_RECEIVE, transactionReferenceNumber);

                return operationReference;
            }
        }
        //================================================================================
        public FuelReportDetail GetLastReceiveFuelReportDetailBefore(FuelReportDetail fuelReportDetail)
        {
            var fetchStrategy = new SingleResultFetchStrategy<FuelReport>().OrderByDescending( fr => fr.EventDate);

            var lastFuelReportWithReceivedGood = fuelReportRepository.First(
                isFuelReportSubmitted.Predicate.And(
                    isFuelReportNotCancelled.Predicate.And(
                        fr =>
                            fr.EventDate < fuelReportDetail.FuelReport.EventDate &&
                            fr.FuelReportDetails.Any(
                                frd =>
                                    frd.GoodId == fuelReportDetail.GoodId &&
                                    frd.Receive.HasValue))),
                fetchStrategy);

            return lastFuelReportWithReceivedGood.FuelReportDetails.Single(frd=>frd.GoodId == fuelReportDetail.GoodId);
        }
        private void setConsumption(FuelReportDetailDto dto, FuelReportDetail source)
        {
            if (!(source.FuelReport.FuelReportType == FuelReportTypes.EndOfMonth ||
                source.FuelReport.FuelReportType == FuelReportTypes.EndOfVoyage ||
                source.FuelReport.FuelReportType == FuelReportTypes.EndOfYear))
            {
                dto.Consumption = 0;
            }
            else
            {
                var fuelReportDomainService = ServiceLocator.Current.GetInstance<IFuelReportDomainService>();

                var reportingConsumption = fuelReportDomainService.CalculateReportingConsumption(source);

                dto.Consumption = (double?)reportingConsumption;
            }
        }
        //================================================================================
        public decimal CalculateReportingConsumption(FuelReportDetail fuelReportDetail)
        {
            var processingFuelReport = fuelReportDetail.FuelReport;

            if (!(processingFuelReport.FuelReportType == FuelReportTypes.EndOfMonth ||
                processingFuelReport.FuelReportType == FuelReportTypes.EndOfVoyage ||
                processingFuelReport.FuelReportType == FuelReportTypes.EndOfYear))
            {
                throw new BusinessRuleException("", "FuelReport is not of type EOV, EOM or EOY.");
            }

            var startDateOfVesselActivation = DateTime.MinValue;

            switch (processingFuelReport.VesselInCompany.VesselStateCode)
            {
                case VesselStates.Inactive:
                case VesselStates.CharterOut:
                case VesselStates.Scrapped:
                    throw new BusinessRuleException("", "The vessel is in an incorrect state.");

                case VesselStates.CharterIn:

                    var charterInStart = charteringDomainService.GetCharterInStart(processingFuelReport.VesselInCompany.Company, processingFuelReport.VesselInCompany, processingFuelReport.EventDate);

                    if (charterInStart == null)
                        throw new BusinessRuleException("", "The proper Charter-In Start record not found.");

                    startDateOfVesselActivation = charterInStart.ActionDate;

                    break;

                case VesselStates.Owned:

                    var charterOutEnd = charteringDomainService.GetCharterOutEnd(processingFuelReport.VesselInCompany.Company, processingFuelReport.VesselInCompany, processingFuelReport.EventDate);

                    if (charterOutEnd != null)
                        startDateOfVesselActivation = charterOutEnd.ActionDate;

                    break;

                default:
                    throw new InvalidArgument("VesselStateCode is invalid.", "VesselStateCode");
            }

            var singleFetchStrategy = new SingleResultFetchStrategy<FuelReport>(nolock: true).OrderByDescending(fr => fr.EventDate);

            var lastConsumptionIssuingFuelReport = fuelReportRepository.First(
                    fr =>
                        fr.EventDate >= startDateOfVesselActivation &&
                        fr.EventDate < processingFuelReport.EventDate &&
                        fr.VesselInCompany.Id == processingFuelReport.VesselInCompanyId &&
                            (fr.FuelReportType == FuelReportTypes.EndOfMonth ||
                            fr.FuelReportType == FuelReportTypes.EndOfMonth ||
                            fr.FuelReportType == FuelReportTypes.EndOfYear),
                    singleFetchStrategy);

            if (lastConsumptionIssuingFuelReport != null && !isFuelReportIssued.IsSatisfiedBy(lastConsumptionIssuingFuelReport))
                throw new BusinessRuleException("", "Previous EOV, EOM or EOY FuelReport is not issued yet.");

            var startDateToCalculateConsumption = (lastConsumptionIssuingFuelReport != null)
                ? lastConsumptionIssuingFuelReport.EventDate
                : startDateOfVesselActivation;

            Expression<Func<FuelReport, bool>> queryToFindPreviousFuelReportsForCalculation =
                fr =>
                    fr.VesselInCompanyId == processingFuelReport.VesselInCompanyId &&
                    fr.EventDate > startDateToCalculateConsumption &&
                    fr.EventDate < processingFuelReport.EventDate;

            var notSubmittedFuelReportsCount = fuelReportRepository.Count(
                isFuelReportSubmitted.Not().Predicate.And(queryToFindPreviousFuelReportsForCalculation));

            if (notSubmittedFuelReportsCount != 0)
                throw new BusinessRuleException("", "There are some not approved FuelReports.");

            var calculatedPreviousConsumptions =
                fuelReportRepository.Find(queryToFindPreviousFuelReportsForCalculation)
                    .SelectMany(fr => fr.FuelReportDetails.Where(frd => frd.GoodId == fuelReportDetail.GoodId))
                    .Sum(frd => frd.Consumption);

            return new decimal(calculatedPreviousConsumptions + fuelReportDetail.Consumption);
        }