private ExcursionPrice ConvertPrice(ExcursionPrice inp, string targetCurrency)
        {
            //ключ для кэша курсов
            string key = inp.price.currency + "to" + targetCurrency;

            //если курса нет в кэше, ищем в базе
            if (!_courses.ContainsKey(key))
                _courses[key] = GetCourse(inp.price.currency, targetCurrency);

            //если ключ найден и он реальный, конвертируем
            if (_courses[key] > 0)
            {
                inp.price.adult *= _courses[key];
                inp.price.adult = Math.Round(inp.price.adult, 2);

                inp.price.child *= _courses[key];
                inp.price.child = Math.Round(inp.price.child, 2);

                inp.price.service *= _courses[key];
                inp.price.service = Math.Round(inp.price.service, 2);

                inp.price.infant *= _courses[key];
                inp.price.infant = Math.Round(inp.price.infant, 2);

                inp.price.currency = targetCurrency;
            }
            return inp;
        }
            internal ExcursionPrice ExcursionPrice(DataRow row, System.DateTime date)
            {
                ExcursionPrice result = new ExcursionPrice
                {
                    id       = row.ReadInt("excurs$inc"),
                    date     = date,
                    language = row.IsNull("lang$inc") ? null : new Language
                    {
                        id    = row.ReadInt("lang$inc"),
                        alias = row.ReadNullableTrimmedString("lang$alias"),
                        name  = row.ReadNullableTrimmedString("lang$name")
                    },
                    group = row.IsNull("group$inc") ? null : new ExcursionGroup
                    {
                        id   = row.ReadInt("group$inc"),
                        name = row.ReadNullableTrimmedString("group$name")
                    },
                    time = row.IsNull("time$inc") ? null : new ExcursionTime
                    {
                        id   = row.ReadInt("time$inc"),
                        name = row.ReadNullableTrimmedString("time$name")
                    },
                    issaleclosed  = !row.IsNull("excurs$closedsale") && row.ReadInt("excurs$closedsale") > 0,
                    closesaletime = row.ReadNullableDateTime("excurs$closesale"),
                    isstopsale    = !row.IsNull("excurs$stopsale") && row.ReadInt("excurs$stopsale") > 0,
                    freeseats     = (row.ReadNullableInt("seats$free") > 0) ? row.ReadNullableInt("seats$free") : null
                };
                XElement departureXml = row.ReadXml("excurs$departurepoints");

                if (departureXml != null)
                {
                    result.departures = (
                        from d in departureXml.Descendants()
                        select new GeoArea
                    {
                        id = (int)d.Attribute("inc"),
                        alias = (string)d.Attribute("alias"),
                        name = (string)d.Attribute("name"),
                        location = (d.Attribute("latitude") == null || d.Attribute("longitude") == null) ? null : new GeoLocation
                        {
                            latitude = (decimal)d.Attribute("latitude"),
                            longitude = (decimal)d.Attribute("longitude")
                        }
                    }).ToList <GeoArea>();
                }
                if (!result.isstopsale && !result.issaleclosed)
                {
                    result.price = (row.IsNull("price$isserviceprice") ? null : new PriceDetails
                    {
                        priceType = (row.ReadInt("price$isserviceprice") > 0) ? PriceDetails.PriceType.perService : PriceDetails.PriceType.perPerson,
                        service = row.ReadDecimal("price$service"),
                        adult = row.ReadDecimal("price$adult"),
                        child = row.ReadDecimal("price$child"),
                        infant = row.ReadDecimal("price$infant"),
                        currency = row.ReadNullableTrimmedString("price$alias"),
                        minGroup = row.ReadInt("price$groupfrom", 1),
                        maxGroup = row.ReadInt("price$grouptill", 999)
                    });
                }
                XElement pickuppointsXml = row.ReadXml("excurs$pickuppoints");

                if (pickuppointsXml != null)
                {
                    result.pickuppoints = (
                        from d in pickuppointsXml.Descendants()
                        select new ExcursionPickup
                    {
                        id = (int)d.Attribute("inc"),
                        name = (string)d.Attribute("name"),
                        location = (d.Attribute("latitude") == null || d.Attribute("longitude") == null) ? null : new GeoLocation
                        {
                            latitude = (decimal)d.Attribute("latitude"),
                            longitude = (decimal)d.Attribute("longitude")
                        },
                        note = (string)d.Attribute("note"),
                        pickuptime = (d.Attribute("time") == null) ? null : ((System.DateTime?)d.Attribute("time"))
                    }).ToList <ExcursionPickup>();
                }
                return(result);
            }