public async Task <Result <BookingVoucherData> > GenerateVoucher(Booking booking, string languageCode)
        {
            var(_, isAccommodationFailure, accommodationDetails, accommodationError) = await _accommodationMapperClient.GetAccommodation(booking.HtId, languageCode);

            if (isAccommodationFailure)
            {
                return(Result.Failure <BookingVoucherData>(accommodationError.Detail));
            }

            var bannerMaybe = await _imageFileService.GetBanner(booking.AgencyId);

            var logoMaybe = await _imageFileService.GetLogo(booking.AgencyId);

            var agent = await _context.Agents.SingleOrDefaultAsync(a => a.Id == booking.AgentId);

            if (agent == default)
            {
                return(Result.Failure <BookingVoucherData>("Could not find agent"));
            }

            if (!AvailableForVoucherBookingStatuses.Contains(booking.Status))
            {
                return(Result.Failure <BookingVoucherData>($"Voucher is not allowed for booking status '{EnumFormatters.FromDescription(booking.Status)}'"));
            }

            if (!AvailableForVoucherPaymentStatuses.Contains(booking.PaymentStatus))
            {
                return(Result.Failure <BookingVoucherData>($"Voucher is not allowed for payment status '{EnumFormatters.FromDescription(booking.PaymentStatus)}'"));
            }

            return(new BookingVoucherData
                   (
                       agentName: $"{agent.FirstName} {agent.LastName}",
                       bookingId: booking.Id,
                       accommodation: GetAccommodationInfo(accommodationDetails.ToEdoContract()),
                       nightCount: (booking.CheckOutDate - booking.CheckInDate).Days,
                       checkInDate: booking.CheckInDate.DateTime,
                       checkOutDate: booking.CheckOutDate.DateTime,
                       deadlineDate: booking.DeadlineDate?.DateTime,
                       mainPassengerName: booking.MainPassengerName,
                       referenceCode: booking.ReferenceCode,
                       supplierReferenceCode: booking.SupplierReferenceCode,
                       propertyOwnerConfirmationCode: booking.PropertyOwnerConfirmationCode,
                       bannerUrl: bannerMaybe.HasValue ? bannerMaybe.Value.Url : null,
                       logoUrl: logoMaybe.HasValue ? logoMaybe.Value.Url : null,
                       roomDetails: booking.Rooms.Select(r => new BookingVoucherData.RoomInfo(r.ContractDescription,
                                                                                              r.BoardBasis,
                                                                                              r.MealPlan,
                                                                                              r.DeadlineDate?.DateTime,
                                                                                              r.ContractDescription,
                                                                                              r.Passengers,
                                                                                              r.Remarks,
                                                                                              r.SupplierRoomReferenceCode))
                       .ToList()
                   ));
        }
        public async Task <Result <BookingVoucherData> > GenerateVoucher(int bookingId, AgentContext agent, string languageCode)
        {
            var(_, isBookingFailure, booking, bookingError) = await _bookingRecordsManager.Get(bookingId);

            if (isBookingFailure)
            {
                return(Result.Failure <BookingVoucherData>(bookingError));
            }

            var(_, isAccommodationFailure, accommodationDetails, accommodationError) = await _accommodationService.Get(booking.Supplier,
                                                                                                                       booking.AccommodationId, languageCode);

            if (isAccommodationFailure)
            {
                return(Result.Failure <BookingVoucherData>(accommodationError.Detail));
            }

            var(isBannerSuccess, _, bannerImage, _) = await _imageFileService.GetBanner(agent);

            var(isLogoSuccess, _, logoImage, _) = await _imageFileService.GetLogo(agent);

            if (!AvailableForVoucherBookingStatuses.Contains(booking.Status))
            {
                return(Result.Failure <BookingVoucherData>($"Voucher is not allowed for booking status '{EnumFormatters.FromDescription(booking.Status)}'"));
            }

            if (!AvailableForVoucherPaymentStatuses.Contains(booking.PaymentStatus))
            {
                return(Result.Failure <BookingVoucherData>($"Voucher is not allowed for payment status '{EnumFormatters.FromDescription(booking.PaymentStatus)}'"));
            }

            return(Result.Success(new BookingVoucherData
                                  (
                                      $"{agent.FirstName} {agent.LastName}",
                                      booking.Id,
                                      GetAccommodationInfo(in accommodationDetails),
                                      (booking.CheckOutDate - booking.CheckInDate).Days,
                                      booking.CheckInDate,
                                      booking.CheckOutDate,
                                      booking.DeadlineDate,
                                      booking.MainPassengerName,
                                      booking.ReferenceCode,
                                      isBannerSuccess ? bannerImage.Url : null,
                                      isLogoSuccess ? logoImage.Url : null,
                                      booking.Rooms.Select(r => new BookingVoucherData.RoomInfo(r.Type,
                                                                                                r.BoardBasis,
                                                                                                r.MealPlan,
                                                                                                r.DeadlineDate,
                                                                                                r.ContractDescription,
                                                                                                r.Passengers,
                                                                                                r.Remarks,
                                                                                                r.SupplierRoomReferenceCode))
                                      .ToList()
                                  )));
        }