public static OTA_HotelResReturnEntity BookHotelRoom(HotelRoomBookInfo bookInfo)
        {
            OTA_HotelResCallEntity callEntity = new OTA_HotelResCallEntity();
            var guests = bookInfo.Customers.Where(u =>
            {
                return !string.IsNullOrEmpty(u);
            }).ToList();
            callEntity.AmountBeforeTax = bookInfo.AmountBeforeTax;
            callEntity.BeforeCheckInTime = bookInfo.BeforeCheckInTime;
            callEntity.CheckInTime = bookInfo.InRoomDate;
            callEntity.CheckOutTime = bookInfo.OffRoomDate;

            callEntity.ContactPersonFirstName = bookInfo.ContactName;

            callEntity.ContactType = ContactType.sms;
            callEntity.Email = bookInfo.ContactEmail;
            callEntity.GuestCount = guests.Count;
            callEntity.HotelCode = bookInfo.HotelCode;
            callEntity.HotelRoomCode = bookInfo.RoomTypeCode;
            callEntity.IsPerRoom = bookInfo.IsPerRoom;
            callEntity.LastCheckInTime = bookInfo.LastCheckInTime;
            callEntity.PersonList = guests;
            callEntity.PhoneNumber = bookInfo.MobilePhone;
            callEntity.Email = bookInfo.ContactEmail;
            callEntity.RoomCount = bookInfo.RoomCount;
            callEntity.ArriveTime = bookInfo.InRoomDate.ToCtripTimeFormat();

            var rep = hotelOTAService.OTA_HotelRes(callEntity);

            return rep;
        }
        /// <summary>
        /// 生成新订单
        /// 需要预订房型列表和价格计划列表、预订客人相关信息、入住全局信息
        /// 返回酒店新订单信息,包括酒店不可订原因或酒店订单信息,其中酒店订单信息包含
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public OTA_HotelResReturnEntity OTA_HotelRes(OTA_HotelResCallEntity req)
        {
            OTA_HotelResReturnEntity rep = new OTA_HotelResReturnEntity();
            StringBuilder reqXml = new StringBuilder();
            reqXml.Append("<ns:OTA_HotelResRQ TimeStamp=\"2012-07-28T13:06:30.000+08:00\" Version=\"1.0\" PrimaryLangID=\"en\" >");
            reqXml.Append("<ns:UniqueID Type=\"504\" ID=\"100000\"/>");
            reqXml.AppendFormat("<ns:UniqueID Type=\"28\" ID=\"{0}\"/>", AllianceID);
            reqXml.AppendFormat("<ns:UniqueID Type=\"503\" ID=\"{0}\"/>", SID);
            reqXml.AppendFormat("<ns:UniqueID Type=\"1\" ID=\"c563a9ed-a090-4ded-b5dc-ddf1d3709e29\"/>");
            reqXml.Append("<ns:HotelReservations>");
            reqXml.Append("<ns:HotelReservation>");
            reqXml.Append("<ns:RoomStays>");
            reqXml.Append("<ns:RoomStay>");
            reqXml.Append("<ns:RoomTypes>");
            reqXml.AppendFormat("<ns:RoomType NumberOfUnits=\"{0}\"/>", req.RoomCount);//订几间房;int类型;必填
            reqXml.Append("</ns:RoomTypes>");
            reqXml.Append("<ns:RatePlans>");
            reqXml.AppendFormat("<ns:RatePlan RatePlanCode=\"{0}\"/>", req.HotelRoomCode);
            reqXml.Append("</ns:RatePlans>");
            reqXml.AppendFormat("<ns:BasicPropertyInfo HotelCode=\"{0}\"/>", req.HotelCode);
            reqXml.Append("</ns:RoomStay>");
            reqXml.Append("</ns:RoomStays>");
            reqXml.Append("<ns:ResGuests>");
            reqXml.AppendFormat("<ns:ResGuest ArrivalTime=\"{0}\">", req.ArriveTime);
            reqXml.Append("<ns:Profiles>");
            reqXml.Append("<ns:ProfileInfo>");
            reqXml.Append("<ns:Profile>");
            reqXml.Append("<ns:Customer>");
            req.PersonList.ForEach(u =>
            {
                reqXml.Append("<ns:PersonName>");
                reqXml.AppendFormat("<ns:Surname>{0}</ns:Surname>", u);
                reqXml.Append("</ns:PersonName>");
            });
            reqXml.AppendFormat("<ns:ContactPerson ContactType=\"{0}\">", req.ContactType.ToString().ToLower());
            reqXml.Append("<ns:PersonName>");
            reqXml.AppendFormat("<ns:Surname>{0}</ns:Surname>", req.ContactPersonFirstName);
            reqXml.Append("</ns:PersonName>");
            reqXml.AppendFormat("<ns:Telephone PhoneNumber=\"{0}\" PhoneTechType=\"{1}\"/>", req.PhoneNumber,(int)req.PhoneTechType);
            if (!string.IsNullOrEmpty(req.Email))
            {
                reqXml.AppendFormat("<ns:Email>{0}</ns:Email>", req.Email);
            }
            
            reqXml.Append("</ns:ContactPerson>");
            reqXml.Append("</ns:Customer>");
            reqXml.Append("</ns:Profile>");
            reqXml.Append("</ns:ProfileInfo>");
            reqXml.Append("</ns:Profiles>");
            reqXml.Append("<ns:TPA_Extensions>");

           
            reqXml.AppendFormat("<ns:LateArrivalTime>{0}</ns:LateArrivalTime>", req.LastCheckInTime);
            reqXml.Append("</ns:TPA_Extensions>");
            reqXml.Append("</ns:ResGuest>");
            reqXml.Append("</ns:ResGuests>");
            reqXml.AppendFormat("<ns:ResGlobalInfo>");
            reqXml.AppendFormat("<ns:GuestCounts IsPerRoom=\"{0}\">", req.IsPerRoom.ToString().ToLower());
            reqXml.AppendFormat("<ns:GuestCount Count=\"{0}\"/>", req.GuestCount);
            reqXml.Append("</ns:GuestCounts>");
            reqXml.AppendFormat(" <ns:TimeSpan Start=\"{0}\" End=\"{1}\"/>", req.CheckInTime.ToCtripDateFormat(), req.CheckOutTime.ToCtripDateFormat());
            
            if(req.SpecialDescription!=null&&req.SpecialDescription.Count>0)
            {
                reqXml.Append("<ns:SpecialRequests>");
                req.SpecialDescription.ForEach(u =>
                {
                    reqXml.Append("<ns:SpecialRequest>");
                    reqXml.AppendFormat("<ns:Text>{0}</ns:Text>", u);
                    reqXml.Append("</ns:SpecialRequest>");
                });
                reqXml.Append("</ns:SpecialRequests>");
            }
            
            
            reqXml.AppendFormat("<ns:Total AmountBeforeTax=\"{0}\" CurrencyCode=\"CNY\"/>", req.AmountBeforeTax);
            reqXml.AppendFormat("</ns:ResGlobalInfo>");
            reqXml.Append("</ns:HotelReservation>");
            reqXml.Append("</ns:HotelReservations>");
            reqXml.Append("</ns:OTA_HotelResRQ>");

            req.RequestContent = reqXml.ToString();
            string repXml = HotelApiCall(req);
            //LogHelper.Info(repXml);
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(repXml);

            var errorNode = xmlDoc.SelectSingleNode("Response/HotelResponse/OTA_HotelResRS/Errors/Error");
            if (errorNode != null)
            {
                var error = new ErrorInfo();
                error.Type = errorNode.ToXmlElement().GetAttribute("Type").Trim().ToInt32();
                error.Code = errorNode.ToXmlElement().GetAttribute("Code").Trim().ToInt32();
                error.ShortText = errorNode.ToXmlElement().GetAttribute("ShortText").Trim();
                error.Text = errorNode.InnerText.Trim();
                rep.Error = error;
                return rep;
            }

            rep.Error = null;
            XmlNode HotelReservationNode = xmlDoc.SelectSingleNode("Response/HotelResponse/OTA_HotelResRS/HotelReservations/HotelReservation");
            rep.CreateDateTime = ((XmlElement)HotelReservationNode).GetAttribute("CreateDateTime").Trim().ToDateTime();
            rep.ResStatus = ((XmlElement)HotelReservationNode).GetAttribute("ResStatus").Trim();
            var RatePlanNode = HotelReservationNode.SelectSingleNode("RoomStays/RoomStay/RatePlans/RatePlan");
            rep.RatePlanCode = ((XmlElement)RatePlanNode).GetAttribute("RatePlanCode").Trim();
            XmlElement BasicPropertyInfoEle = (XmlElement)HotelReservationNode.SelectSingleNode("RoomStays/RoomStay/BasicPropertyInfo");
            if (BasicPropertyInfoEle != null)
            {
                rep.HotelCode = BasicPropertyInfoEle.GetAttribute("HotelCode");
            }
            else
            {
                rep.HotelCode = req.HotelCode.ToString();
            }


            XmlElement HotelReservationIDEle = (XmlElement)HotelReservationNode.SelectSingleNode("ResGlobalInfo/HotelReservationIDs/HotelReservationID");
            if (HotelReservationIDEle != null)
            {
                rep.ResIDType = HotelReservationIDEle.GetAttribute("ResIDType").Trim();
                rep.ResIDValue = HotelReservationIDEle.GetAttribute("ResID_Value").Trim();
            }

            XmlElement TotalNode = (XmlElement)HotelReservationNode.SelectSingleNode("ResGlobalInfo/Total");
            rep.AmountAfterTax = TotalNode.GetAttribute("AmountAfterTax").Trim().ToDecimal();
            rep.CurrencyCode = TotalNode.GetAttribute("CurrencyCode").Trim();

            XmlNode GuaranteePaymentNode = HotelReservationNode.SelectSingleNode("ResGlobalInfo/DepositPayments/GuaranteePayment");
            if (GuaranteePaymentNode != null)
            {
                rep.GuaranteeCode = (GuaranteePaymentNode as XmlElement).GetAttribute("GuaranteeCode");
                rep.GuaranteeAmount = ((XmlElement)GuaranteePaymentNode.SelectSingleNode("AmountPercent")).GetAttribute("Amount").Trim().ToDecimal();
                rep.GuaranteeCurrencyCode = ((XmlElement)GuaranteePaymentNode.SelectSingleNode("AmountPercent")).GetAttribute("CurrencyCode").Trim();
            }


            XmlNode CancelPenaltyNode = HotelReservationNode.SelectSingleNode("ResGlobalInfo/CancelPenalties/CancelPenalty");
            if (CancelPenaltyNode != null)
            {
                rep.CancelPenaltyStartTime = (CancelPenaltyNode as XmlElement).GetAttribute("Start").Trim().ToDateTime();
                rep.CancelPenaltyEndTime = (CancelPenaltyNode as XmlElement).GetAttribute("End").Trim().ToDateTime();
                rep.CancelAmount = ((XmlElement)CancelPenaltyNode.SelectSingleNode("AmountPercent")).GetAttribute("Amount").Trim().ToDecimal();
                rep.CancelCurrencyCode = ((XmlElement)CancelPenaltyNode.SelectSingleNode("AmountPercent")).GetAttribute("CurrencyCode").Trim();
            }
            return rep;
        }