private void Configure(ConverterConfigurator <SecondContractDocument <SecondContractDocumentBody>, SecondContractDocumentBody, InnerDocument, InnerDocument, InnerDocument> subConfigurator)
        {
            subConfigurator.Target(data => data.OrdersNumber).Set(message => message.BeginningOfMessage.DocumentMessageIdentification.DocumentIdentifier);
            subConfigurator.ConfigureDateOrUtcNow("137", data => data.OrdersDate);
            subConfigurator.ConfigureDate("50", data => data.ReceivingDate);

            subConfigurator.Target(data => data.CurrencyCode).Set(message => (from details in message.Currency.CurrencyDetails
                                                                              where details.UsageCodeQualifier == "2" && details.TypeCodeQualifier == "4"
                                                                              select details.IdentificationCode).FirstOrDefault(),
                                                                  s => defaultConverter.Convert(s));

            subConfigurator.Target(data => data.FlowType).Set(message => message.FreeText.Any(y => y.TextSubjectCodeQualifier == "DEL")
                                                                             ? defaultConverter.Convert(message.FreeText.FirstOrDefault(y => y.TextSubjectCodeQualifier == "DEL").TextReference.FreeTextValueCode)
                                                                             : message.FreeText.Any(y => y.TextSubjectCodeQualifier == "ZZZ" && y.TextLiteral.FreeTextValue[0] == "Fresh")
                                                                                 ? "fresh"
                                                                                 : defaultConverter.Convert(message.SG28.FirstOrDefault().FreeText.FirstOrDefault(y => y.TextSubjectCodeQualifier == "DEL" && y.TextReference.CodeListResponsibleAgencyCode == "ZZZ").TextReference.FreeTextValueCode));

            subConfigurator.Target(data => data.TransportDetails.VehicleNumber)
            .Set(message => message.SG10.FirstOrDefault(sg10 => sg10.DetailsOfTransport.TransportStageCodeQualifier == "1").DetailsOfTransport.TransportIdentification.TransportMeansIdentificationName);

            subConfigurator.Target(data => data.FreeText).Set(message => ArrayStringConverter.ToString(message.FreeText.FirstOrDefault(freeText => freeText.TextSubjectCodeQualifier == "ZZZ" || freeText.TextSubjectCodeQualifier == "PUR" || freeText.TextSubjectCodeQualifier == "AAI").TextLiteral.FreeTextValue));

            subConfigurator.GoTo(x => x, x => x.References).ConfigureReference("BO", data => data.BlanketOrdersNumber);

            subConfigurator.If(message => !string.IsNullOrEmpty(message.ControlTotal.FirstOrDefault(cnt => cnt.Control.ControlTotalTypeCodeQualifier == "11").Control.ControlTotalValue))
            .Target(data => data.OrdersTotalPackageQuantity)
            .Set(message => decimalConverter.ToDecimal(message.ControlTotal.FirstOrDefault(cnt => cnt.Control.ControlTotalTypeCodeQualifier == "11").Control.ControlTotalValue));

            subConfigurator.ConfigureMonetaryAmountsInfo(new MonetaryAmountConfig <InnerDocument>("79", x => x.RecadvTotal),
                                                         new MonetaryAmountConfig <InnerDocument>(new[] { "77", "9" }, x => x.TotalWithVAT));

            subConfigurator.GoTo(x => x.DespatchParties.Each().PartyInfo, message => message.PartiesArray.Where(sg2 => sg2.NameAndAddress.PartyFunctionCodeQualifier == "PW").Current())
            .ConfigureParty <SecondContractDocument <SecondContractDocumentBody>, InnerDocument, SG2, SG3, SG5>();

            subConfigurator.GoTo(data => data.Transports.Each(),
                                 message => message.SG10.Where(sg10 => sg10.DetailsOfTransport.TransportStageCodeQualifier == "20")
                                 .SelectMany(sg10 => DefaultIfNullOrEmpty(sg10.SG11),
                                             (sg10, sg11) => new
            {
                sg10.DetailsOfTransport.TransportMeans.TransportMeansDescription,
                TypeOfTransportCode = defaultConverter.Convert(sg10.DetailsOfTransport.TransportMeans.TransportMeansDescriptionCode),
                sg11.DateTimePeriod
            })
                                 .Where(x => !string.IsNullOrEmpty(x.TypeOfTransportCode) || !string.IsNullOrEmpty(x.TransportMeansDescription) || x.DateTimePeriod != null)
                                 .Current())
            .BatchSet((x, y) => new Batch
            {
                { x.TypeOfTransport, y.TransportMeansDescription },
                { x.TypeOfTransportCode, y.TypeOfTransportCode },
                { x.DeliveryDateForVehicle, dateTimePeriodConverter.ToDateTime(y.DateTimePeriod.FirstOrDefault(period => period.DateTimePeriodGroup.FunctionCodeQualifier == "232").DateTimePeriodGroup) },
            });

            ConfigureGoodItems(subConfigurator.GoTo(data => data.GoodItems.Each(), message => message.SG28.Current()));
        }
        public static void ConfigurePartyName <TSecondContract, TData, TSG2, TPartyInfo>(
            this ConverterConfigurator <TSecondContract, TSG2, TData, TPartyInfo, TPartyInfo> configurator)
            where TSG2 : INameAndAddressContainer
            where TPartyInfo : IContainsRussianPartyInfo
        {
            configurator.Target(party => party.RussianPartyInfo.IPInfo.LastName)
            .Set(sg2 => sg2.NameAndAddress.PartyNameType.PartyName[0])
            .NullifyIf(party => party.RussianPartyInfo.RussianPartyType != RussianPartyType.IP);
            configurator.Target(party => party.RussianPartyInfo.IPInfo.FirstName)
            .Set(sg2 => sg2.NameAndAddress.PartyNameType.PartyName[1])
            .NullifyIf(party => party.RussianPartyInfo.RussianPartyType != RussianPartyType.IP);

            configurator.If(sg2 => sg2.NameAndAddress.PartyNameType.PartyName != null)
            .Target(party => party.RussianPartyInfo.ULInfo.Name)
            .Set(sg2 => sg2.NameAndAddress.PartyNameType.PartyName, strings => ArrayStringConverter.ToString(strings))
            .NullifyIf(party => party.RussianPartyInfo.RussianPartyType != RussianPartyType.UL);

            configurator.If(sg2 => sg2.NameAndAddress.PartyNameType.PartyName == null)
            .Target(party => party.RussianPartyInfo.ULInfo.Name)
            .Set(sg2 => sg2.NameAndAddress.NameAndAddressGroup.NameAndAddressDescription, strings => ArrayStringConverter.ToString(strings))
            .NullifyIf(party => party.RussianPartyInfo.RussianPartyType != RussianPartyType.UL);
        }
        public static void ConfigureCommonGoodItemInfo <TSecondContract, TSecondContractGoodItem, TData, TGoodItem>(
            this ConverterConfigurator <TSecondContract, TSecondContractGoodItem, TData, TGoodItem, TGoodItem> configurator)
            where TSecondContractGoodItem : ISecondContractGoodItemWithAdditionalInfo
            where TGoodItem : GoodItemWithAdditionalInfo
        {
            ConfigureGoodItemBaseInfo(configurator);

            var typeOfUnitConfigurator = configurator.GoTo(goodItem => goodItem, lin => lin.ItemDescription.Where(id => id.DescriptionFormatCode == "C"));

            typeOfUnitConfigurator.Target(goodItem => goodItem.IsReturnableContainer)
            .Set(x => x.FirstOrDefault(code => code.ItemDescriptionGroup.ItemDescriptionCode == "RC").ItemDescriptionGroup.ItemDescriptionCode,
                 rc => rc == "RC");
            typeOfUnitConfigurator.Target(goodItem => goodItem.TypeOfUnit)
            .Set(x => x.FirstOrDefault().ItemDescriptionGroup.ItemDescriptionCode,
                 type => defaultConverter.Convert(type));

            configurator.Target(goodItem => goodItem.Name).Set(goodItem => (from description in goodItem.ItemDescription
                                                                            where description.ItemCharacteristic.ItemCharacteristicCode == null
                                                                            where description.ItemDescriptionGroup.ItemDescription.Length > 0
                                                                            select description.ItemDescriptionGroup.ItemDescription).FirstOrDefault(), strings => ArrayStringConverter.ToString(strings));
        }
        public static void ConfigurePartyAddress <TSecondContract, TData>(
            this ConverterConfigurator <TSecondContract, NameAndAddress, TData, PartyInfo, PartyInfo> configurator)
        {
            configurator.Target(party => party.PartyAddress.AddressType)
            .Set(nameAndAddress => defaultConverter.Convert(nameAndAddress.CountryNameCode), code => GetAddressType(code));
            configurator.Target(party => party.PartyAddress.ForeignAddressInfo.CountryCode)
            .Set(nameAndAddress => nameAndAddress.CountryNameCode,
                 s => defaultConverter.Convert(s),
                 s => s != null && defaultConverter.Convert(s) == null,
                 s => new TestText {
                Text = s
            })
            .NullifyIf(party => party.PartyAddress.AddressType != AddressType.Foreign);

            configurator.Target(party => party.PartyAddress.ForeignAddressInfo.Address)
            .Set(nameAndAddress => nameAndAddress.Street.StreetAndNumberOrPostBoxIdentifier, strings => ArrayStringConverter.ToString(strings))
            .NullifyIf(party => party.PartyAddress.AddressType != AddressType.Foreign);

            configurator.GoTo(x => x.PartyAddress).ConfigureRussianPartyAddress();
            configurator.Target(party => party.PartyAddress.RussianAddressInfo).NullifyIf(party => party.PartyAddress.AddressType != AddressType.Russian);
        }
 public static void ConfigureRussianPartyAddress <TSecondContract, TData, TPartyInfo>(this ConverterConfigurator <TSecondContract, NameAndAddress, TData, TPartyInfo, TPartyInfo> configurator)
     where TPartyInfo : IContainsRussianPartyAdress, IContainsAddressType
 {
     configurator.Target(party => party.RussianAddressInfo.City)
     .Set(nameAndAddress => nameAndAddress.CityName)
     .NullifyIf(party => party.AddressType != AddressType.Russian);
     configurator.Target(party => party.RussianAddressInfo.Street)
     .Set(nameAndAddress => nameAndAddress.Street.StreetAndNumberOrPostBoxIdentifier, strings => ArrayStringConverter.ToString(strings))
     .NullifyIf(party => party.AddressType != AddressType.Russian);
 }