public BookingApi GetBookingInfo(BookingInfo model)
        {
            List<InvoiceDto> invoices = Services.Invoices.GetInvoiceByBookingId(model.BookingId);
            InvoiceDto customerInvoice = new InvoiceDto();
            InvoiceDto specialistInvoice = new InvoiceDto();
            BookingDto booking = new BookingDto();

            if (invoices == null || !invoices.Any())
            {
                booking = Services.Booking.GetById(model.BookingId);
            }
            else
            {
                booking = invoices.First(i => i.Booking.Id == model.BookingId).Booking;
                customerInvoice = invoices.First(i => i.User.Id == booking.Customer.Id && i.Type == InvoiceType.Consultation);
                specialistInvoice = invoices.First(i => i.User.Id == booking.Specialist.Id);
            }

            var bookingInfo = Mapper.Map<BookingApi>(booking);

            bookingInfo.IsMinCharge = false;

            if (bookingInfo != null)
            {
                var call = Services.Call.GetByBookingIdAndConference(bookingInfo.Id);

                var specialist = booking.Specialist;
                var customer = booking.Customer;

                var s3Root = BlueChilli.Web.Helpers.S3PathWithoutQuery("").Substring(1);
                if (!string.IsNullOrWhiteSpace(bookingInfo.DocumentPath))
                {
                    bookingInfo.DocumentPath = Path.Combine(s3Root, bookingInfo.DocumentPath);
                }

                bookingInfo.IsFavourite = Services.Users.IsFavourite(specialist.Id, customer.Id);
                bookingInfo.SpecialistStatus = specialist.CurrentAvailabilityStatus;

                //check specilist is calling with customer to change curremt status to "not avaiable"
                if (!AvailabilityStatus.NotAvailable.Equals(bookingInfo.SpecialistStatus)
                    && Services.Call.CheckCallInProgressBySpecialistId(specialist.Id))
                {
                    bookingInfo.SpecialistStatus = AvailabilityStatus.NotAvailable;
                }

                // Convert to client time
                //TRI:TODO
                //bookingInfo.StartTime = Utilities.ConvertToClientTimeById(bookingInfo.CreatedDate, timeZoneId);
                //bookingInfo.EndTime = Utilities.ConvertToClientTimeById(bookingInfo.EndTime, timeZoneId);
                //bookingInfo.CreatedDate = Utilities.ConvertToClientTimeById(bookingInfo.CreatedDate, timeZoneId);

                if (call != null)
                {
                    if (specialist != null && customer != null)
                    {
                        bookingInfo.IsFeedback = Services.Call.CheckExistFeedbackAndRatingByCallId(call.Id);
                        string recordUrl = "";
                        if (!string.IsNullOrWhiteSpace(call.RecordSid))
                        {
                            var twilioServer = System.Configuration.ConfigurationManager.AppSettings["Twilio_ApiServer"];

                            recordUrl = !string.IsNullOrWhiteSpace(call.RecordUrl) && call.RecordUrl.Contains(twilioServer)
                                    ? Utilities.ConvertLinkRecord(call.RecordSid)
                                    : S3ReaderHelper.CombineFileS3Root(call.RecordUrl);
                        }

                        bookingInfo.Rating = (int)Math.Round(Services.Booking.GetRatingByBooking(bookingInfo.Id), 0, MidpointRounding.AwayFromZero);
                        bookingInfo.PastBooking = new PastBooking();
                        bookingInfo.PastBooking.CallId = call.Id;
                        bookingInfo.PastBooking.DurationMinute = call.Duration;
                        bookingInfo.PastBooking.CallStartTime = call.StartTime.HasValue ? (DateTime?)call.StartTime.Value.ConvertToCurrentTimeZone() : null;
                        bookingInfo.PastBooking.CallEndTime = call.EndTime.HasValue ? (DateTime?)call.EndTime.Value.ConvertToCurrentTimeZone() : null;
                        bookingInfo.PastBooking.RecordUrl = recordUrl;
                        bookingInfo.Feedback = call.Feedback;
                    }
                }

                if (customerInvoice != null && specialistInvoice != null)
                {
                    if (bookingInfo.PastBooking == null)
                    {
                        bookingInfo.PastBooking = new PastBooking();
                    }

                    if (ConsultationType.MinimumCharge.Equals(customerInvoice.ConsultationType))
                    {
                        bookingInfo.IsMinCharge = true;
                    }
                    bookingInfo.IsWaiveFee = customerInvoice.IsWaiveFee;
                    bookingInfo.InvoiceCreatedDate = customerInvoice.CreatedDate.ConvertToCurrentTimeZone();
                    bookingInfo.PastBooking.CustomerTotalRate = customerInvoice.Amount;
                    bookingInfo.PastBooking.SpecialistTotalRate = specialistInvoice.Amount;
                }
            }

            return bookingInfo;
        }
        /// <summary>
        /// tranform invoice object into Invoice email template
        /// </summary>
        /// <param name="user"></param>
        /// <param name="invoice"></param>
        /// <param name="unit">months, minutes, hours,...</param>
        /// <returns></returns>
        public string TranformToInvoiceTemplate(UserDto user, InvoiceDto invoice, string unit, string mailTemplateKey, List<InvoiceDto> listConsultationInvoiceForWalvedFee)
        {
            try
            {
                LocationDto location = user.Locations.First();
                bool hasDisplayMinimum = true;
                decimal originAmount = invoice.Amount - invoice.GST;
                decimal invoiceTotal = invoice.Amount;
                decimal walvedFee = 0;
                decimal subTotal = 0;
                int duration = invoice.Duration;
                decimal GST = invoice.GST;
                decimal ratePerMinute = GST > 0 ? invoice.RatePerMinute - SubtractGSTCalculator(invoice.RatePerMinute) : invoice.RatePerMinute;
                if (InvoiceType.OrderTranscript.Equals(invoice.Type) || InvoiceType.Prepayment.Equals(invoice.Type))
                {
                    hasDisplayMinimum = false;
                }
                else if (InvoiceType.WaiveFee.Equals(invoice.Type) && listConsultationInvoiceForWalvedFee != null)
                {
                    var customerInvoice = listConsultationInvoiceForWalvedFee.First(x => x.Booking.Customer.Id == x.User.Id && x.Type == InvoiceType.Consultation);
                    var specialistInvoice = listConsultationInvoiceForWalvedFee.First(x => x.Booking.Specialist.Id == x.User.Id && x.Type == InvoiceType.Consultation);
                    duration = customerInvoice.Duration;
                    originAmount = customerInvoice.Amount - customerInvoice.GST;
                    walvedFee = specialistInvoice.Amount - specialistInvoice.GST;
                    subTotal = originAmount - walvedFee;
                    GST = customerInvoice.GST > 0 ? SubtractGSTCalculator(customerInvoice.Amount - specialistInvoice.Amount) : 0;
                    ratePerMinute = GST > 0 ? customerInvoice.RatePerMinute - SubtractGSTCalculator(customerInvoice.RatePerMinute) : customerInvoice.RatePerMinute;
                    invoiceTotal = subTotal + GST;
                }

                object transformWith = new
                {
                    BaseUrl = baseUrl,
                    //- XXXXXXXX-X
                    InvoiceNumber = invoice.InvoiceNumber,
                    //- 27/02/2015
                    CreatedDate = invoice.CreatedDate.ToString(Infrastructure.Core.Const.SystemConfig.GlobalDateFormat),

                    Name = user.Name,
                    Street = string.Format("{0} {1}", location.StreetNumber, location.Street),
                    Country = string.Format("{0} {1} {2}", location.Country, location.Suburb, location.Postcode),
                    MobileNumber = user.MobileCountryCode + user.MobilePhone,
                    //- AUD USD VND ...
                    Currency = invoice.Currency,
                    Description = invoice.Description,
                    //- 1 (minutes) or 12 (months)
                    Duration = invoice.Type != InvoiceType.Subscription ? TimeSpan.FromSeconds(duration).ToString() : duration.ToString(),
                    Unit = unit,
                    //- $XX
                    Cost = invoice.Type == InvoiceType.Subscription ?
                            (originAmount - GST).ToString("C", new CultureInfo("en-Us"))
                            : ratePerMinute.ToString("C", new CultureInfo("en-Us")),
                    Amount = originAmount.ToString("C", new CultureInfo("en-Us")),
                    Total = invoiceTotal.ToString("C", new CultureInfo("en-Us")),
                    //WaivedFeeDescription = string.IsNullOrWhiteSpace(waiveFeeDescription) ? null : "*" + waiveFeeDescription,
                    IsWavedFee = InvoiceType.WaiveFee.Equals(invoice.Type) ? string.Empty : "display:none;",
                    WaivedFee = walvedFee.ToString("C", new CultureInfo("en-Us")),
                    Subtotal = subTotal.ToString("C", new CultureInfo("en-Us")),
                    IsGST = GST > 0 ? string.Empty : "display:none;",
                    GST = GST.ToString("C", new CultureInfo("en-Us")),
                    Minimum = (hasDisplayMinimum && invoice.Booking != null) ? string.Format(InvoiceConst.InvoiceMinimumDescription, invoice.Booking.CustomerMinCharge.ToString("C", new CultureInfo("en-Us"))) : string.Empty
                };

                var mailTemplate = ConfigurationManager.AppSettings[mailTemplateKey];

                var transformWithDynamic = transformWith.ToDynamic();
                //- Generate mail content from mail template and object transformWith (invoice information)
                string mailContent = StringExtend.TransformWithDynamic(File.ReadAllText(HostingEnvironment.MapPath(mailTemplate)), transformWithDynamic);

                return mailContent;
            }
            catch (Exception e)
            {
                Log.Error("Tranform to invoice template", e);
                return null;
            }
        }
        public string GetEmailContentOfInvoice(InvoiceDto invoice)
        {
            string result = string.Empty;
            string FirstFullName = invoice.User.Name;
            string SecondFullName = string.Empty;
            if (invoice.Booking != null)
            {
                SecondFullName = Role.Customer.Equals(invoice.User.Role) ? invoice.Booking.Specialist.Name : invoice.Booking.Customer.Name;
            }

            string ammount = invoice.Amount.ToString("C", new CultureInfo("en-Us"));
            switch (invoice.Type)
            {
                case InvoiceType.WaiveFee:
                case InvoiceType.Consultation:
                    result = string.Format(InvoiceEmailContent.ConsultationInvoices, FirstFullName, ammount, SecondFullName);
                    if (ConsultationType.MinimumCharge.Equals(invoice.ConsultationType))
                    {
                        result = string.Format(InvoiceEmailContent.CancelInvoices, FirstFullName, ammount, SecondFullName);
                    }
                    break;

                case InvoiceType.Subscription:
                    string subscriptionEndDate = Role.Specialist.Equals(invoice.User.Role) && invoice.User.Profile != null ? invoice.User.Profile.SubscriptionEndDate.ToString("dd/MM/yyyy") : string.Empty;
                    result = string.Format(InvoiceEmailContent.SubscriptionInvoices, FirstFullName, ammount, subscriptionEndDate);
                    break;

                case InvoiceType.Prepayment:
                    result = string.Format(InvoiceEmailContent.TopupInvoices, FirstFullName, ammount);
                    break;

                case InvoiceType.OrderTranscript:
                    result = string.Format(InvoiceEmailContent.OrderTranscriptInvoices, FirstFullName, ammount, SecondFullName);
                    break;

                default:
                    break;
            }

            if (!string.IsNullOrWhiteSpace(result))
            {
                object transformWith = new
                {
                    BaseUrl = AppSettings.BaseUrl,
                    content = result.Replace("\n", "<br/>")
                };
                var transformWithDynamic = transformWith.ToDynamic();
                result = StringExtend.TransformWithDynamic(File.ReadAllText(HostingEnvironment.MapPath(ConfigurationData.GeneralEmailTemplate())), transformWithDynamic);
            }

            return result;
        }
 /// <summary>
 /// Create new invoice
 /// </summary>
 /// <param name="invoice">Invoice DTO</param>
 /// <returns>Invoice DTO</returns>
 public InvoiceDto Create(InvoiceDto invoice)
 {
     Repository.Insert<Invoice>(invoice.ExposedAs<Invoice>(Repository));
     UnitOfWork.Save();
     return invoice;
 }
        private static void CreateUnsuccessInvoice(UserDto user, BookingDto booking, IServices Services, decimal amount)
        {
            ConsultationType consultType;

            switch (booking.Type)
            {
                case BookingType.ASAP:
                    consultType = ConsultationType.StandardHour;
                    break;

                default:
                    Enum.TryParse(booking.Type.ToString(), out consultType);
                    break;
            }
            var call = Services.Call.GetByBookingId(booking.Id);

            InvoiceDto unsuccessInvoice = new InvoiceDto()
            {
                Amount = amount,
                CreatedDate = DateTime.UtcNow,
                ModifiedDate = DateTime.UtcNow,
                Type = InvoiceType.Consultation,
                PaymentStatus = false,
                InvoiceNumber = Services.Invoices.GetInvoiceNumber(),
                Booking = Services.Booking.GetById(booking.Id),
                User = user,
                Description = InvoiceType.Consultation.ToString(),
                RatePerMinute = booking.CostPerMinute,
                ConsultationType = consultType,
            };
            if (call != null)
            {
                unsuccessInvoice.Duration = 0;
            }

            Services.Invoices.Create(unsuccessInvoice);
        }
        public ActionResult PastBookingOLD(Guid bookingId)
        {
            try
            {
                ViewBag.IsSpecialist = false;
                List<InvoiceDto> invoices = Services.Invoices.GetInvoiceByBookingId(bookingId);
                InvoiceDto invoice = new InvoiceDto();
                BookingDto booking = new BookingDto();

                if (invoices == null || !invoices.Any())
                {
                    booking = Services.Booking.GetById(bookingId);
                }
                else
                {
                    booking = invoices.First(i => i.Booking.Id == bookingId).Booking;
                    invoice = invoices.First(i => i.User.Id == booking.Customer.Id && i.Type == InvoiceType.Consultation);
                }

                ViewBag.IsSpecialist = IsSpecialist();

                PopupPastBookingViewModel popupPastBooking = new PopupPastBookingViewModel();
                //TRI:TODO
                popupPastBooking.PopupBooking = BookingHelper.LoadBookingByBookingId(booking, ViewBag.IsSpecialist);
                popupPastBooking.IsFavourite = Services.Users.IsFavourite(popupPastBooking.PopupBooking.SpecialistId, CurrentUser.Id);
                popupPastBooking.PopupBooking.RatingRatio = (int)Math.Round(Services.Booking.GetRatingByBooking(booking.Id), 0, MidpointRounding.AwayFromZero);
                var specialist = booking.Specialist;

                popupPastBooking.SpecialistStatus = specialist.CurrentAvailabilityStatus;
                //check specilist is calling with customer to change curremt status to "not avaiable"
                if (!AvailabilityStatus.NotAvailable.Equals(popupPastBooking.SpecialistStatus)
                    && Services.Call.CheckCallInProgressBySpecialistId(specialist.Id))
                {
                    popupPastBooking.SpecialistStatus = AvailabilityStatus.NotAvailable;
                }

                popupPastBooking.Invoice = new InvoiceDto { Amount = 0 };
                if (invoice != null)
                {
                    popupPastBooking.Invoice = invoice;

                    if (!ConsultationType.MinimumCharge.Equals(invoice.ConsultationType))
                    {
                        popupPastBooking.ConsultationFee = invoice.Duration * booking.RatePerMinute;
                        popupPastBooking.ApplicableCost = invoice.Amount;
                    }
                    else
                    {
                        popupPastBooking.ApplicableCost = invoice.DeclineBookingRate;
                        var specialistInvoice = Services.Invoices.GetByBookingIdAndUserId(booking.Id, booking.Specialist.Id);
                        popupPastBooking.ConsultationFee = specialistInvoice.DeclineBookingRate;
                    }
                }

                var callLog = Services.Call.GetByBookingId(bookingId);

                if (callLog != null)
                {
                    var twilioServer = System.Configuration.ConfigurationManager.AppSettings["Twilio_ApiServer"];

                    // Check record url
                    var recordUrl = callLog.RecordUrl.Contains(twilioServer)
                        ? Utilities.ConvertLinkRecord(callLog.RecordSid)
                        : S3ReaderHelper.CombineS3Root(callLog.RecordUrl);

                    popupPastBooking.CallId = callLog.Id;
                    popupPastBooking.CallStartTime = TeleConsult.Web.Code.Helpers.DateTimeHelper.ConvertToCurrentTimeZone(callLog.StartTime.GetValueOrDefault(DateTime.UtcNow));
                    popupPastBooking.CallEndTime = TeleConsult.Web.Code.Helpers.DateTimeHelper.ConvertToCurrentTimeZone(callLog.EndTime.GetValueOrDefault(DateTime.UtcNow));
                    popupPastBooking.DurationMinute = callLog.Duration;
                    if (!string.IsNullOrWhiteSpace(callLog.RecordSid))
                    {
                        string urlTwilio = string.Format(Settings.UrlCallRecord, Settings.Twilio.Key);
                        popupPastBooking.RecordUrl = string.Format("{0}{1}", urlTwilio, callLog.RecordUrl);
                    }
                    popupPastBooking.IsFeedback = Services.Call.CheckExistFeedbackAndRatingByCallId(callLog.Id);
                    popupPastBooking.RecordUrl = recordUrl;
                }
                return PartialView("BookingPopUpTemplate/_PastBooking", popupPastBooking);
            }
            catch (Exception e)
            {
                Log.Error("Past booking", e);
                throw;
            }
        }