package Cyber::ProcessedAPI;
use strict;
use warnings;

use Data::Dumper;
use String::Random;
use POSIX 'strftime';
use Encode;
use JSON;
use LWP::UserAgent;
use IO::Compress::Gzip qw(gzip);
use IO::Uncompress::Gunzip qw( gunzip );
use Cyber::Database;
use Date::Simple qw(date);
no warnings "uninitialized";
use HTTP::BrowserDetect;
use HTML::Entities;

#Constructor
sub new {
	my $class = shift;
	
	my $obj = {};
	
	my $obj_database = new Cyber::Database;
	$obj->{'obj_database'} = $obj_database;
	
	bless $obj, $class;
	
	return $obj;
}

#Authenticate User
sub get_property_detail {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	#Check user name
	my $hotel_detail = $class->{'obj_database'}->get({
		'table'  => 'hotels',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $hotel_id,
			'hotel_status' => 'Y'
		}
	});
	
	if ( scalar @$hotel_detail ) {
		my $hotel_detail_data = $hotel_detail->[0];
		$class->{'hotel_detail'} = $hotel_detail_data;

		return 1;
	}
	
	return 0;
}

sub get_hotel_settings {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	#Check user name
	my $hotel_settings = $class->{'obj_database'}->get({
		'table'  => 'hotel_settings',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id,
		}
	});
	
	if ( scalar @$hotel_settings ) {
		my $hotel_setting_data = $hotel_settings->[0];
		$class->{'hotel_settings'} = $hotel_setting_data;

		return 1;
	}
	else {
		$class->{'hotel_settings'} = {};
	}
	
	return 0;
}

sub get_room_type_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $room_type_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'room_types',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'id'
	});
	
	if ( defined $room_type_list ) {
		$class->{'room_type_list'} = $room_type_list;
	}
	return 1;
}

sub get_rate_type_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $rate_type_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'rate_types',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'id'
	});

	if ( defined $rate_type_list ) {
		$class->{'rate_type_list'} = $rate_type_list;
	}
	return 1;
}

sub get_rate_plan_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $rate_plan_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'rate_plans',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'room_type_id'
	});

	if ( defined $rate_plan_list ) {
		$class->{'rate_plan_list'} = $rate_plan_list;
	}
	return 1;
}

sub get_rate_plan_list_with_key_id {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $rate_plan_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'rate_plans',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'hotel_id' => $hotel_id
		},
		'key' => 'id'
	});

	if ( defined $rate_plan_list ) {
		$class->{'rate_plan_list_with_key_id'} = $rate_plan_list;
	}
	return 1;
}

sub get_master_room_facilities {
	my $class = shift;

	my $master_facility_list = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'room_facilities',
		'hash'   => 1,
		'select' => '*',
		'key' => 'id'
	});

	if ( defined $master_facility_list ) {
		$class->{'master_facility_list'} = $master_facility_list;
	}
	return 1;
}

sub get_inventory {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};

	my $whr->{'hotel_id'} = $hotel_id;
	if ( exists $cgi_params->{'room_type_id'} && $cgi_params->{'room_type_id'} !~ /^\s*$/ ) {
		$whr->{'room_type_id'} = $cgi_params->{'room_type_id'};
	}

	$whr = [
		$whr,
		'AND',
		"date BETWEEN '$check_in' AND '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		my $inventory_data_hash = {};
		foreach my $data ( @$inventory_data ) {
			$inventory_data_hash->{$data->{'room_type_id'}}->{$data->{'date'}} = $data->{'availability'};
		}
		$class->{'inventory_data_hash'} = $inventory_data_hash;
	}
	
	return 1;
}

sub check_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		my $is_available = 1;
		foreach my $data ( @$inventory_data ) {
			if ( $data->{'availability'} < $no_of_room ) {
				$is_available = 0;
				last;
			}
		}
		
		$class->{'is_available'} = $is_available;
	}
	else {
		$class->{'is_available'} = 0;
	}
	
	return 1;
}

sub reduce_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'id, date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		foreach my $data ( @$inventory_data ) {
			my $current_inventory = $data->{'availability'};
			my $available_inventory = $current_inventory - $no_of_room;
			if ( $available_inventory < 0 ) {
				$available_inventory = 0;
			}

			$class->{'obj_database'}->set(
				'table' => 'inventory_masters',
				'update' => {
					'availability'  => $available_inventory,
					'updated_at'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				},
				'where' => {
					'id' => $data->{'id'}
				}
			);
		}
	}

	return 1;
}

sub replenish_inventory {
	my $class = shift;

	my $hotel_id   = shift;
	my $check_in   = shift;
	my $check_out  = shift;
	my $room_type_id = shift;
	my $no_of_room = shift;

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'room_type_id'} = $room_type_id;
	
	$whr = [
		$whr,
		'AND',
		"date >= '$check_in' AND date < '$check_out'"
	];

	my $inventory_data = undef;
	eval {
		$inventory_data = $class->{'obj_database'}->get({
			'table'  => 'inventory_masters',
			'hash'   => 1,
			'select' => 'id, date, room_type_id, availability',
			'where'  => $whr
		});
	};

	if ( defined $inventory_data && scalar @$inventory_data ) {
		foreach my $data ( @$inventory_data ) {
			my $current_inventory = $data->{'availability'};
			my $available_inventory = $current_inventory + $no_of_room;
			if ( $available_inventory < 0 ) {
				$available_inventory = 0;
			}

			$class->{'obj_database'}->set(
				'table' => 'inventory_masters',
				'update' => {
					'availability'  => $available_inventory,
					'updated_at'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				},
				'where' => {
					'id' => $data->{'id'}
				}
			);
		}
	}

	return 1;
}

sub get_rate_restriction {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};

	my $whr->{'hotel_id'} = $hotel_id;
	if ( exists $cgi_params->{'rate_plan_id'} && $cgi_params->{'rate_plan_id'} !~ /^\s*$/ && $cgi_params->{'rate_plan_id'} =~ /^\d+$/ ) {
		$whr->{'rate_plan_id'} = $cgi_params->{'rate_plan_id'};
	}

	$whr = [
		$whr,
		'AND',
		"date BETWEEN '$check_in' AND '$check_out'"
	];

	my $rate_restriction_data = undef;
	eval {
		$rate_restriction_data = $class->{'obj_database'}->get({
			'table'  => 'rate_restriction_masters',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $rate_restriction_data && scalar @$rate_restriction_data ) {
		my $rate_data_hash = {};
		foreach my $data ( @$rate_restriction_data ) {
			delete( $data->{'created_at'} );
			delete( $data->{'updated_at'} );
			$rate_data_hash->{$data->{'rate_plan_id'}}->{$data->{'date'}} = $data;
		}
		$class->{'rate_data_hash'} = $rate_data_hash;
	}
	
	return 1;
}

sub get_all_offers {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $offer_id   = $cgi_params->{'offer_id'};
	
	my $is_mobile = 0;
	my $bw = HTTP::BrowserDetect->new(); 
	if ( $bw->mobile ) {
		$is_mobile = 1;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	if ( $is_mobile ) {
		$whr->{'mobile_offer'} = 'on';
	}

	if ( defined $offer_id && $offer_id !~ /^\s*$/ ) {
		$whr->{'id'} = $offer_id;
	}
	# else {
	# 	$whr = [
	# 		$whr,
	# 		"AND",
	# 		"mobile_offer != 'on'"
	# 	];
	# }

	my $today_date = ::get_today_day();
	if ( $whr ) {
		$whr = [
			$whr,
			"AND",
			"'$today_date' between valid_from AND valid_to"
		];
	}
	# print Dumper $whr;
	my $offers_list = undef;

	$offers_list = $class->{'obj_database'}->get({
		'table'  => 'offers',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr
	});
	
	# print Dumper $decided_room_offers;
	my $new_list = [];
	if ( defined $offers_list ) {
		foreach my $x ( @$offers_list ) {
			my $offer_image = $x->{'image'};
			my $image_path = $::config{'base_url'}->{'image_base_offer'}.$offer_image;

			$x->{'image'} = $image_path;

			if ( $is_mobile ) {
				push @$new_list, $x;
			}
			else {
				if ( $x->{'mobile_offer'} !~ /on/i ) {
					push @$new_list, $x;
				}
			}
		}
	}
	
	$class->{'all_offers_list'} = $offers_list;

	return 1;
}

sub get_offers {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	
	my $is_mobile = 0;
	my $bw = HTTP::BrowserDetect->new(); 
	if ( $bw->mobile ) {
		$is_mobile = 1;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	if ( $is_mobile ) {
		$whr->{'mobile_offer'} = 'on';
	}
	else {
		$whr = [
			$whr,
			"AND",
			"mobile_offer is null"
		];
	}

	my $offers_list = undef;

	$offers_list = $class->{'obj_database'}->get({
		'table'  => 'offers',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr
	});
	# print Dumper $offers_list;
	
	my $no_of_adult = $cgi_params->{'no_of_adult'};
	my $no_of_child = $cgi_params->{'no_of_child'};
	my $today_date = ::get_today_day();
	my $check_in  = $cgi_params->{'check_in'};
	my $check_out = $cgi_params->{'check_out'};
	my $no_of_night = $cgi_params->{'no_of_night'};

	my $dow_num = ::get_day_of_week( $check_in );
	$dow_num =~ s/^0//;

	my $dow_string = $::single_digit_dow->{$dow_num};

	my $adv_days = ::get_delta_days( $today_date, $check_in );

	my $no_of_room = $cgi_params->{'no_of_room'};

	# $class->get_rate_plan_list_with_key_id;
	# my $rate_plan_list_with_key_id = $class->{'rate_plan_list_with_key_id'};

	my $min_night_offers = undef
	my $decided_room_offers = undef;
	if ( defined $offers_list && scalar @$offers_list ) {
		foreach my $offer ( @$offers_list ) {
			my $offer_id = $offer->{'id'};
			my $min_no_of_night = $offer->{'min_no_of_night'};
			my $max_no_of_night = $offer->{'max_no_of_night'};
			if ( defined $min_no_of_night && $min_no_of_night !~ /^\s*$/ && $min_no_of_night > 0 && 
					defined $max_no_of_night && $max_no_of_night !~ /^\s*$/ && $max_no_of_night > 0 ) {
				if ( $no_of_night >= $min_no_of_night && $no_of_night <= $max_no_of_night ) {
					
				}
				else {

					my $night_diff = $min_no_of_night - $no_of_night;

					if ( defined $min_night_offers && scalar keys %$min_night_offers ) {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );

						foreach my $x (@$current_room_list) {
							my $plan_id = $x->{'room_list'};

							# my $room_id = undef;
							# if ( exists $rate_plan_list_with_key_id->{$plan_id} ) {
							# 	my $t = $rate_plan_list_with_key_id->{$plan_id};
							# 	if ( ref $t eq 'HASH' ) {
							# 		$room_id = $t->{'room_type_id'};
							# 	}
							# 	elsif ( ref $t eq 'ARRAY' ) {
							# 		$room_id = $t->[0]->{'room_type_id'};
							# 	}
							# }

							if ( exists $min_night_offers->{$plan_id} && $min_night_offers->{$plan_id} > $night_diff ) {
								$min_night_offers->{$plan_id} = {
									'min_night' => $night_diff,
									'name' => $offer->{'name'},
									'name_it' => $offer->{'name_it'},
									'name_fr' => $offer->{'name_fr'},
									'name_es' => $offer->{'name_es'},
									'name_de' => $offer->{'name_de'},

									'description' => $offer->{'description'},
									'description_it' => $offer->{'description_it'},
									'description_fr' => $offer->{'description_fr'},
									'description_es' => $offer->{'description_es'},
									'description_de' => $offer->{'description_de'},
									'offer_id' => $offer_id
								}
							}
							else {
								$min_night_offers->{$plan_id} = {
									'min_night' => $night_diff,
									'name' => $offer->{'name'},
									'name_it' => $offer->{'name_it'},
									'name_fr' => $offer->{'name_fr'},
									'name_es' => $offer->{'name_es'},
									'name_de' => $offer->{'name_de'},

									'description' => $offer->{'description'},
									'description_it' => $offer->{'description_it'},
									'description_fr' => $offer->{'description_fr'},
									'description_es' => $offer->{'description_es'},
									'description_de' => $offer->{'description_de'},
									'offer_id' => $offer_id
								}
							}
						}
					}
					else {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );
						foreach my $x (@$current_room_list) {
							my $plan_id = $x->{'room_list'};

							# my $room_id = undef;
							# if ( exists $rate_plan_list_with_key_id->{$plan_id} ) {
							# 	my $t = $rate_plan_list_with_key_id->{$plan_id};
							# 	if ( ref $t eq 'HASH' ) {
							# 		$room_id = $t->{'room_type_id'};
							# 	}
							# 	elsif ( ref $t eq 'ARRAY' ) {
							# 		$room_id = $t->[0]->{'room_type_id'};
							# 	}
							# }

							$min_night_offers->{$plan_id} = {
								'min_night' => $night_diff,
								'name' => $offer->{'name'},
								'name_it' => $offer->{'name_it'},
								'name_fr' => $offer->{'name_fr'},
								'name_es' => $offer->{'name_es'},
								'name_de' => $offer->{'name_de'},

								'description' => $offer->{'description'},
								'description_it' => $offer->{'description_it'},
								'description_fr' => $offer->{'description_fr'},
								'description_es' => $offer->{'description_es'},
								'description_de' => $offer->{'description_de'},
								'offer_id' => $offer_id
							}
						}
					}
				}
			}

			for (my $r = 1; $r <= $no_of_room; $r++) {
				my $no_of_adult = $cgi_params->{'no_of_adult'.$r};
				my $no_of_child = $cgi_params->{'no_of_child'.$r};
				my $pas_key = $no_of_adult.'A'.$no_of_child.'C';

				my $valid_from     = $offer->{'valid_from'};
				my $valid_to       = $offer->{'valid_to'};
				my $exclusive_days = $offer->{'exclusive_days'};
				my $days_of_week   = $offer->{'days_of_week'};
				my $disc           = $offer->{'discount_percentage'};

				my $min_adult = $offer->{'min_no_of_adults'};
				my $max_adult = $offer->{'max_no_of_adults'};
				my $min_child = $offer->{'min_no_of_child'};
				if ( !defined $min_child || $min_child =~ /^\s*$/ || $min_child =~ /null/i ) {
					$min_child = 0;
				}
				my $max_child = $offer->{'max_no_of_child'};
				if ( !defined $max_child || $max_child =~ /^\s*$/ || $max_child =~ /null/i ) {
					$max_child = 0;
				}
				my $min_adv_days = $offer->{'min_days_in_advance'};
				if ( !defined $min_adv_days || $min_adv_days =~ /^\s*$/ || $min_adv_days =~ /null/i ) {
					$min_adv_days = 0;
				}
				my $max_adv_days = $offer->{'max_days_in_advance'};
				if ( !defined $max_adv_days || $max_adv_days =~ /^\s*$/ || $max_adv_days =~ /null/i ) {
					$max_adv_days = 0;
				}

				if ( $check_in ge $valid_from && $check_in le $valid_to ) {
					
					my $exclude_dates = from_json( $exclusive_days );

					##check exclude dates
					# print "1\n";
					my $is_exclude = 0;
					if ( defined $exclude_dates && ref $exclude_dates eq 'HASH' && scalar keys %$exclude_dates ) {
						foreach my $ex ( keys %$exclude_dates ) {
							if ( $exclude_dates->{$ex}->{'exclusive_days'} eq $check_in ) {
								$is_exclude = 1;
								last;
							}
						}
					}

					if ( $is_exclude ) {
						next;
					}
					# print "2\n";
					##check applicable day
					my $is_day_matched = 0;
					my $days_of_week_list = from_json( $days_of_week );
					if ( defined $days_of_week_list && scalar @$days_of_week_list ) {
						foreach my $d ( @$days_of_week_list ) {
							if ( $d->{'days_of_week'} =~ /$dow_string/i ) {
								$is_day_matched = 1;
							}
						}
					}

					unless ( $is_day_matched ) {
						next;
					}
					# print "3\n";
					# print $no_of_adult.'--'.$min_adult;
					if ( defined $min_adult && $min_adult !~ /^\s*$/ && $min_adult > 0 ) {
						if ( $no_of_adult < $min_adult ) {
							next;
						}
					}
					# print $no_of_adult.'--'.$max_adult;
					# print "4\n";
					if ( defined $max_adult && $max_adult !~ /^\s*$/ && $max_adult > 0 ) {
						if ( $no_of_adult > $max_adult ) {
							next;
						}
					}

					if ( defined $min_child && $min_child !~ /^\s*$/ && $min_child > 0 ) {
						if ( $no_of_child < $min_child ) {
							next;
						}
					}
					# print "5\n";
					if ( defined $max_child && $max_child !~ /^\s*$/ && $max_child > 0 ) {
						if ( $no_of_child > $max_child ) {
							next;
						}
					}
					# print "6\n";
					if ( defined $min_adv_days && $min_adv_days !~ /^\s*$/ && $min_adv_days > 0 ) {
						if ( $adv_days < $min_adv_days ) {
							next;
						}
					}
					# print "7\n";
					if ( defined $max_adv_days && $max_adv_days !~ /^\s*$/ && $max_adv_days > 0 ) {
						if ( $adv_days > $max_adv_days ) {
							next;
						}
					}
					# print "8\n";
					if ( defined $decided_room_offers && scalar keys %$decided_room_offers ) {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );

						foreach my $x (@$current_room_list) {
							my $room_id = $x->{'room_list'};

							if ( exists $decided_room_offers->{$room_id}->{$pas_key} ) {
								if ( $offer->{'discount_percentage'} > $decided_room_offers->{$room_id}->{$pas_key}->{'discount_percentage'} ) {
									$decided_room_offers->{$room_id}->{$pas_key} = {
										'name' => $offer->{'name'},
										'name_it' => $offer->{'name_it'},
										'name_fr' => $offer->{'name_fr'},
										'name_es' => $offer->{'name_es'},
										'name_de' => $offer->{'name_de'},

										'description' => $offer->{'description'},
										'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
										'discount_percentage' => $offer->{'discount_percentage'}
									};
								}
							}
							else {
								$decided_room_offers->{$room_id}->{$pas_key} = {
									'name' => $offer->{'name'},
									'name_it' => $offer->{'name_it'},
									'name_fr' => $offer->{'name_fr'},
									'name_es' => $offer->{'name_es'},
									'name_de' => $offer->{'name_de'},
									'description' => $offer->{'description'},
									'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
									'discount_percentage' => $offer->{'discount_percentage'}
								};
							}
						}
					}
					else {
						my $offer_rooms = $offer->{'room_list'};

						my $current_room_list = from_json( $offer_rooms );
						foreach my $x (@$current_room_list) {
							my $room_id = $x->{'room_list'};

							$decided_room_offers->{$room_id}->{$pas_key} = {
								'name' => $offer->{'name'},
								'name_it' => $offer->{'name_it'},
								'name_fr' => $offer->{'name_fr'},
								'name_es' => $offer->{'name_es'},
								'name_de' => $offer->{'name_de'},
								'description' => $offer->{'description'},
								'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
								'discount_percentage' => $offer->{'discount_percentage'}
							};
						}
					}
				}
			}
		}
	}
	
	# print Dumper $decided_room_offers;
	$class->{'decided_room_offers'} = $decided_room_offers;
	$class->{'min_night_offers'} = $min_night_offers;

	return 1;
}

sub get_apts_offers {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	
	my $is_mobile = 0;
	my $bw = HTTP::BrowserDetect->new(); 
	if ( $bw->mobile ) {
		$is_mobile = 1;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	if ( $is_mobile ) {
		$whr->{'mobile_offer'} = 'on';
	}
	else {
		$whr = [
			$whr,
			"AND",
			"mobile_offer is null"
		];
	}

	my $offers_list = undef;

	$offers_list = $class->{'obj_database'}->get({
		'table'  => 'offers',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr
	});
	# print Dumper $offers_list;
	
	my $no_of_adult = $cgi_params->{'no_of_adult'};
	my $no_of_child = $cgi_params->{'no_of_child'};
	my $today_date = ::get_today_day();
	my $check_in  = $cgi_params->{'check_in'};
	my $check_out = $cgi_params->{'check_out'};
	my $no_of_night = $cgi_params->{'no_of_night'};

	my $dow_num = ::get_day_of_week( $check_in );
	$dow_num =~ s/^0//;

	my $dow_string = $::single_digit_dow->{$dow_num};

	my $adv_days = ::get_delta_days( $today_date, $check_in );

	my $no_of_room = $cgi_params->{'no_of_room'};

	my $decided_room_offers = undef;
	if ( defined $offers_list && scalar @$offers_list ) {
		foreach my $offer ( @$offers_list ) {
			my $min_no_of_night = $offer->{'min_no_of_night'};
			my $max_no_of_night = $offer->{'max_no_of_night'};
			my $valid_from     = $offer->{'valid_from'};
			my $valid_to       = $offer->{'valid_to'};
			my $exclusive_days = $offer->{'exclusive_days'};
			my $days_of_week   = $offer->{'days_of_week'};
			my $disc           = $offer->{'discount_percentage'};
			my $min_adult = $offer->{'min_no_of_adults'};
			my $max_adult = $offer->{'max_no_of_adults'};
			my $min_child = $offer->{'min_no_of_child'};
			if ( !defined $min_child || $min_child =~ /^\s*$/ || $min_child =~ /null/i ) {
				$min_child = 0;
			}
			my $max_child = $offer->{'max_no_of_child'};
			if ( !defined $max_child || $max_child =~ /^\s*$/ || $max_child =~ /null/i ) {
				$max_child = 0;
			}
			my $min_adv_days = $offer->{'min_days_in_advance'};
			if ( !defined $min_adv_days || $min_adv_days =~ /^\s*$/ || $min_adv_days =~ /null/i ) {
				$min_adv_days = 0;
			}
			my $max_adv_days = $offer->{'max_days_in_advance'};
			if ( !defined $max_adv_days || $max_adv_days =~ /^\s*$/ || $max_adv_days =~ /null/i ) {
				$max_adv_days = 0;
			}

			if ( defined $min_no_of_night && $min_no_of_night !~ /^\s*$/ && $min_no_of_night > 0 && 
					defined $max_no_of_night && $max_no_of_night !~ /^\s*$/ && $max_no_of_night > 0 ) {
				if ( $no_of_night >= $min_no_of_night && $no_of_night <= $max_no_of_night ) {
					
				}
				else {
					next;
				}
			}

			if ( $check_in ge $valid_from && $check_in le $valid_to ) {
				my $exclude_dates = from_json( $exclusive_days );

				##check exclude dates
				# print "1\n";
				my $is_exclude = 0;
				foreach my $ex ( @$exclude_dates ) {
					if ( $ex->{'exclusive_days'} eq $check_in ) {
						$is_exclude = 1;
						last;
					}
				}

				if ( $is_exclude ) {
					next;
				}
				# print "2\n";
				##check applicable day
				my $is_day_matched = 0;
				my $days_of_week_list = from_json( $days_of_week );
				if ( defined $days_of_week_list && scalar @$days_of_week_list ) {
					foreach my $d ( @$days_of_week_list ) {
						if ( $d->{'days_of_week'} =~ /$dow_string/i ) {
							$is_day_matched = 1;
						}
					}
				}

				unless ( $is_day_matched ) {
					next;
				}
				# print "3\n";
				# print $no_of_adult.'--'.$min_adult;
				if ( defined $min_adult && $min_adult !~ /^\s*$/ && $min_adult > 0 ) {
					if ( $no_of_adult < $min_adult ) {
						next;
					}
				}
				# print $no_of_adult.'--'.$max_adult;
				# print "4\n";
				if ( defined $max_adult && $max_adult !~ /^\s*$/ && $max_adult > 0 ) {
					if ( $no_of_adult > $max_adult ) {
						next;
					}
				}

				if ( defined $min_child && $min_child !~ /^\s*$/ && $min_child > 0 ) {
					if ( $no_of_child < $min_child ) {
						next;
					}
				}
				# print "5\n";
				if ( defined $max_child && $max_child !~ /^\s*$/ && $max_child > 0 ) {
					if ( $no_of_child > $max_child ) {
						next;
					}
				}
				# print "6\n";
				if ( defined $min_adv_days && $min_adv_days !~ /^\s*$/ && $min_adv_days > 0 ) {
					if ( $adv_days < $min_adv_days ) {
						next;
					}
				}
				# print "7\n";
				if ( defined $max_adv_days && $max_adv_days !~ /^\s*$/ && $max_adv_days > 0 ) {
					if ( $adv_days > $max_adv_days ) {
						next;
					}
				}
				# print "8\n";
				if ( defined $decided_room_offers && scalar keys %$decided_room_offers ) {
					my $offer_rooms = $offer->{'room_list'};

					my $current_room_list = from_json( $offer_rooms );

					foreach my $x (@$current_room_list) {
						my $room_id = $x->{'room_list'};

						if ( exists $decided_room_offers->{$room_id} ) {
							if ( $offer->{'discount_percentage'} > $decided_room_offers->{$room_id}->{'discount_percentage'} ) {
								$decided_room_offers->{$room_id} = {
									'name' => $offer->{'name'},
									'name_it' => $offer->{'name_it'},
									'name_fr' => $offer->{'name_fr'},
									'name_es' => $offer->{'name_es'},
									'name_de' => $offer->{'name_de'},

									'description' => $offer->{'description'},
									'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
									'discount_percentage' => $offer->{'discount_percentage'}
								};
							}
						}
						else {
							$decided_room_offers->{$room_id} = {
								'name' => $offer->{'name'},
								'name_it' => $offer->{'name_it'},
								'name_fr' => $offer->{'name_fr'},
								'name_es' => $offer->{'name_es'},
								'name_de' => $offer->{'name_de'},
								'description' => $offer->{'description'},
								'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
								'discount_percentage' => $offer->{'discount_percentage'}
							};
						}
					}
				}
				else {
					my $offer_rooms = $offer->{'room_list'};

					my $current_room_list = from_json( $offer_rooms );
					foreach my $x (@$current_room_list) {
						my $room_id = $x->{'room_list'};

						$decided_room_offers->{$room_id} = {
							'name' => $offer->{'name'},
							'name_it' => $offer->{'name_it'},
							'name_fr' => $offer->{'name_fr'},
							'name_es' => $offer->{'name_es'},
							'name_de' => $offer->{'name_de'},
							'description' => $offer->{'description'},
							'image' => $::config{'base_url'}->{'image_base_offer'}.$offer->{'image'},
							'discount_percentage' => $offer->{'discount_percentage'}
						};
					}
				}
			}
		}
	}
	
	# print Dumper $decided_room_offers;
	$class->{'decided_room_offers'} = $decided_room_offers;

	return 1;
}


sub get_coupon_detail {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $promo_code = $cgi_params->{'promo_code'};
	my $today_date = ::get_today_day();

	my $check_in = $cgi_params->{'check_in'};
	if ( defined $check_in && $check_in !~ /^\s*$/ && $check_in =~ /\d{4}\-\d{2}\-\d{2}/i ) {
		$today_date = $check_in;
	}

	my $whr->{'hotel_id'} = $hotel_id;
	$whr->{'code'} = $promo_code;
	
	$whr = [
		$whr,
		'AND',
		"'$today_date' BETWEEN valid_from AND valid_to"
	];

	my $coupon_data = undef;
	eval {
		$coupon_data = $class->{'obj_database'}->get({
			'table'  => 'coupons',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $coupon_data && scalar @$coupon_data ) {
		$class->{'coupon_detail'} = $coupon_data->[0];
	}
	
	return 1;
}

sub check_param_validation {
	my $class = shift;
	
	my $cgi_params  = $class->{'cgi_params'};
	my $check_in    = $cgi_params->{'check_in'};
	if ( !defined $check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-start'} && $cgi_params->{'t-start'} !~ /^\s*$/ ) {
			$check_in = $cgi_params->{'t-start'};
			$cgi_params->{'check_in'} = $cgi_params->{'t-start'};
		}
	}

	my $check_out   = $cgi_params->{'check_out'};
	if ( !defined $check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-end'} && $cgi_params->{'t-end'} !~ /^\s*$/ ) {
			$check_out = $cgi_params->{'t-end'};
			$cgi_params->{'check_out'} = $cgi_params->{'t-end'};
		}
	}

	my $no_of_adult = $cgi_params->{'no_of_adult'};
	my $no_of_child = $cgi_params->{'no_of_child'};
	my $no_of_room  = $cgi_params->{'no_of_room'};

	my $search_params = $class->{'search_params'};

	##if checkin date not found
	if ( !$check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_in'} && $search_params->{'check_in'} !~ /^\s*$/ ) {
			$check_in = $search_params->{'check_in'};
		}
		else {
			$check_in = ::get_today_day();
		}
		$cgi_params->{'check_in'} = $check_in;
	}
	if ( !$check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_out'} && $search_params->{'check_out'} !~ /^\s*$/ ) {
			$check_out = $search_params->{'check_out'};
		}
		else {
			my $today_date = ::get_today_day();
			$check_out = ::add_one_day( $today_date );
		}
		
		$cgi_params->{'check_out'} = $check_out;
	}

	my $today_date = ::get_today_day();
	my $past_days = ::get_delta_days( $today_date, $check_in );

	my $is_valid = 1;
	my $error_message = '';
	if ( $past_days < 0 ) {
		$error_message .= "Check In date should greater then today date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}

	my $day_diff = ::get_delta_days( $check_in, $check_out );

	if ( $day_diff < 0 ) {
		$error_message .= "Please select proper Check In & Check Out date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}
	if ( $error_message !~ /^\s*$/ ) {
		$error_message =~ s/<br\/>$//;
	}
	$cgi_params->{'no_of_night'} = $day_diff;

	if ( !defined $no_of_adult || $no_of_adult =~ /^\s*$/ || $no_of_adult == 0 ) {
		if ( exists $search_params->{'no_of_adult'} && $search_params->{'no_of_adult'} !~ /^\s*$/ ) {
			$no_of_adult = $search_params->{'no_of_adult'};
		}
		else {
			$no_of_adult = 2;
		}
		
		$cgi_params->{'no_of_adult'} = $no_of_adult;
	}

	if ( !defined $no_of_child || $no_of_child =~ /^\s*$/ || $no_of_child == 0 ) {
		if ( exists $search_params->{'no_of_child'} && $search_params->{'no_of_child'} !~ /^\s*$/ ) {
			$no_of_child = $search_params->{'no_of_child'};
		}
		else {
			$no_of_child = 0;
		}
		$cgi_params->{'no_of_child'} = $no_of_child;
	}
	
	if ( !defined $no_of_room || $no_of_room =~ /^\s*$/ || $no_of_room == 0 ) {
		if ( exists $search_params->{'no_of_room'} && $search_params->{'no_of_room'} !~ /^\s*$/ ) {
			$no_of_room = $search_params->{'no_of_room'};
		}
		else {
			$no_of_room = 1;
		}
		$cgi_params->{'no_of_room'} = $no_of_room;
	}

	$class->{'is_valid'} = $is_valid;
	$class->{'error_message'} = $error_message;

	$cgi_params->{'check_in_string'} = ::convert_date_to_string( $check_in, $cgi_params->{'lang'} );
	$cgi_params->{'check_out_string'} = ::convert_date_to_string( $check_out, $cgi_params->{'lang'} );

	$cgi_params->{'check_in_string_2'} = ::convert_date_to_string_dd_mmm_yy( $check_in, $cgi_params->{'lang'} );
	$cgi_params->{'check_out_string_2'} = ::convert_date_to_string_dd_mmm_yy( $check_out, $cgi_params->{'lang'} );
	
	return;
}

sub check_apt_param_validation {
	my $class = shift;
	
	my $cgi_params  = $class->{'cgi_params'};
	my $check_in    = $cgi_params->{'check_in'};
	if ( !defined $check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-start'} && $cgi_params->{'t-start'} !~ /^\s*$/ ) {
			$check_in = $cgi_params->{'t-start'};
			$cgi_params->{'check_in'} = $cgi_params->{'t-start'};
		}
	}

	my $check_out   = $cgi_params->{'check_out'};
	if ( !defined $check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $cgi_params->{'t-end'} && $cgi_params->{'t-end'} !~ /^\s*$/ ) {
			$check_out = $cgi_params->{'t-end'};
			$cgi_params->{'check_out'} = $cgi_params->{'t-end'};
		}
	}

	my $no_of_adult = $cgi_params->{'no_of_adult'};
	my $no_of_child = $cgi_params->{'no_of_child'};
	my $no_of_room  = $cgi_params->{'no_of_room'};

	my $search_params = $class->{'search_params'};

	##if checkin date not found
	if ( !$check_in || $check_in =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_in'} && $search_params->{'check_in'} !~ /^\s*$/ ) {
			$check_in = $search_params->{'check_in'};
		}
		else {
			$check_in = ::get_today_day();
		}
		$cgi_params->{'check_in'} = $check_in;
	}
	if ( !$check_out || $check_out =~ /^\s*$/ ) {
		if ( exists $search_params->{'check_out'} && $search_params->{'check_out'} !~ /^\s*$/ ) {
			$check_out = $search_params->{'check_out'};
		}
		else {
			my $today_date = ::get_today_day();
			$check_out = ::add_one_day( $today_date );
		}
		
		$cgi_params->{'check_out'} = $check_out;
	}

	my $today_date = ::get_today_day();
	my $past_days = ::get_delta_days( $today_date, $check_in );

	my $is_valid = 1;
	my $error_message = '';
	if ( $past_days < 0 ) {
		$error_message .= "Check In date should greater then today date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}

	my $day_diff = ::get_delta_days( $check_in, $check_out );

	if ( $day_diff < 0 ) {
		$error_message .= "Please select proper Check In & Check Out date";
		$error_message .= "<br/>";
		$is_valid = 0;
	}
	if ( $error_message !~ /^\s*$/ ) {
		$error_message =~ s/<br\/>$//;
	}
	$cgi_params->{'no_of_night'} = $day_diff;

	$class->{'is_valid'} = $is_valid;
	$class->{'error_message'} = $error_message;

	$cgi_params->{'check_in_string'} = ::convert_date_to_string( $check_in, $cgi_params->{'lang'} );
	$cgi_params->{'check_out_string'} = ::convert_date_to_string( $check_out, $cgi_params->{'lang'} );

	$cgi_params->{'check_in_string_2'} = ::convert_date_to_string_dd_mmm_yy( $check_in, $cgi_params->{'lang'} );
	$cgi_params->{'check_out_string_2'} = ::convert_date_to_string_dd_mmm_yy( $check_out, $cgi_params->{'lang'} );
	
	return;
}

sub get_hotel_detail {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'} ;

	my $hotel_detail = undef;
	my $whr->{'hotel_code'} = $hotel_id;

	eval {
		$hotel_detail = $class->{'obj_database'}->get({
			'table'  => 'hotels',
			'hash'   => 1,
			'select' => '*',
			'where'  => $whr
		});
	};

	if ( defined $hotel_detail && scalar @$hotel_detail ) {
		$class->{'hotel_detail'} = $hotel_detail->[0];
	}

	return 1;
}

sub get_extra_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};

	my $extra_list = undef;
	eval {
		$extra_list = $class->{'obj_database'}->get({
			'table'  => 'extras',
			'hash'   => 1,
			'select' => '*',
			'where'  => {
				'hotel_id' => $hotel_id
			},
			'order' => 'priority asc'
		});
	};

	if ( defined $extra_list && scalar @$extra_list ) {

		foreach my $extra ( @$extra_list ) {
			$extra->{'image'} = $::config{'base_url'}->{'image_base_extra'}.$extra->{'image'};
		}

		$class->{'extra_list'} = $extra_list;
	}
	return;
}

sub store_booking_master {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $search_params      = $class->{'search_params'};
	my $final_room_details = $class->{'final_room_details'};
	my $selected_extras    = $class->{'selected_extras'};
	my $hotel_detail       = $class->{'hotel_detail'};
	my $coupon_detail      = $class->{'coupon_detail'};

	my $no_of_room  = $search_params->{'no_of_room'};
	my $no_of_adult = $search_params->{'no_of_adult'};
	my $no_of_child = $search_params->{'no_of_child'};
	my $child_ages = '';
	if ( $no_of_child > 0 ) {
		for (my $i = 1; $i <= $no_of_child; $i++) {
			$child_ages .= $search_params->{'child_age_'.$i};
			$child_ages .= ", ";
		}
	}
	$child_ages =~ s/\,\s$//g;

	my $no_of_night = $search_params->{'no_of_night'};
	my $check_in    = $search_params->{'check_in'};
	my $check_out   = $search_params->{'check_out'};
	my $hotel_id    = $search_params->{'hotel_id'};

	my $first_name   = $cgi_params->{'first_name'};
	my $last_name   = $cgi_params->{'last_name'};
	my $email       = $cgi_params->{'email'};
	my $phone       = $cgi_params->{'phone'};
	my $arrival_time       = $cgi_params->{'arrival_time'};

	my $country     = $cgi_params->{'country'};
	my $category        = $cgi_params->{'card_type'};
	my $category_number      = $cgi_params->{'card_number'};
	my $category_name   = $cgi_params->{'card_holder'};
	my $category_code         = $cgi_params->{'card_cvv'};
	my $last_date = $cgi_params->{'card_expiry_date'};
	my $guest_comment    = $cgi_params->{'guest_note'};
	my $payment_type = $cgi_params->{'payment_type'};
	
    my $string_gen  = String::Random->new;
    my $dk = $string_gen->randregex('\d{32}');
    $dk =~ s/^\s*//g;
	$dk =~ s/\s*$//g;

	my ( $str1, $str2, $str3 ) = ::encrypt_second_level($dk, $category_number, $category_code );

	my $lang = $cgi_params->{'lang'};

	my $twin_double = $cgi_params->{'twin_double'};
	if ( defined $twin_double && $twin_double !~ /^\s*$/ ) {
		if ( $lang =~ /it/i ) {
			$guest_comment .= " preferenza letto:: ".$twin_double;
		}
		else {
	        $guest_comment .= " You have requested a ".$twin_double." Bed";
	    }
	}

	$first_name =~ s/^\s*//g;
	$first_name =~ s/\s*$//g;
	$last_name =~ s/^\s*//g;
	$last_name =~ s/\s*$//g;
	$email =~ s/^\s*//g;
	$email =~ s/\s*$//g;
	$guest_comment =~ s/^\s*//g;
	$guest_comment =~ s/\s*$//g;

	$category_number =~ s/^\s*//g;
	$category_number =~ s/\s*$//g;
	$category_name =~ s/^\s*//g;
	$category_name =~ s/\s*$//g;
	$category_code =~ s/^\s*//g;
	$category_code =~ s/\s*$//g;
	$last_date =~ s/^\s*//g;
	$last_date =~ s/\s*$//g;

	my $ipaddr = $ENV{'REMOTE_ADDR'};

	my $total_extra_cost = 0;
	if ( defined $selected_extras && ref $selected_extras eq 'ARRAY' ) {
		foreach my $extra ( @$selected_extras ) {
			$total_extra_cost += $extra->{'total_price'};
		}
	}

	my $extras_json = undef;
	eval {
		$extras_json = to_json( $selected_extras );
	};

	my $gross_amount = 0;
	my $total_base_amount = 0;
	my $total_extra_person_amount = 0;
	my $total_discount = 0;
	
	foreach my $x (@$final_room_details) {
		$total_base_amount += $x->{'rate_segment'}->{'base_room_rate'};
		$total_extra_person_amount += $x->{'rate_segment'}->{'extra_adult_rate'};
		$total_extra_person_amount += $x->{'rate_segment'}->{'extra_child_rate'};
		$total_discount += $x->{'rate_segment'}->{'total_discount'};

		$x->{'rate_type'}->{'cancellation_condition_it'} = decode_string($x->{'rate_type'}->{'cancellation_condition_it'});
		$x->{'rate_type'}->{'cancellation_condition_fr'} = decode_string($x->{'rate_type'}->{'cancellation_condition_fr'});
		$x->{'rate_type'}->{'cancellation_condition_es'} = decode_string($x->{'rate_type'}->{'cancellation_condition_es'});
		$x->{'rate_type'}->{'cancellation_condition_de'} = decode_string($x->{'rate_type'}->{'cancellation_condition_de'});

		$x->{'rate_type'}->{'short_description_it'} = decode_string($x->{'rate_type'}->{'short_description_it'});
		$x->{'rate_type'}->{'short_description_fr'} = decode_string($x->{'rate_type'}->{'short_description_fr'});
		$x->{'rate_type'}->{'short_description_es'} = decode_string($x->{'rate_type'}->{'short_description_es'});
		$x->{'rate_type'}->{'short_description_de'} = decode_string($x->{'rate_type'}->{'short_description_de'});

		$x->{'room_type'}->{'short_description_it'} = decode_string($x->{'room_type'}->{'short_description_it'});
		$x->{'room_type'}->{'short_description_fr'} = decode_string($x->{'room_type'}->{'short_description_fr'});
		$x->{'room_type'}->{'short_description_es'} = decode_string($x->{'room_type'}->{'short_description_es'});
		$x->{'room_type'}->{'short_description_de'} = decode_string($x->{'room_type'}->{'short_description_de'});

		$x->{'room_type'}->{'long_description_it'} = decode_string($x->{'room_type'}->{'long_description_it'});
		$x->{'room_type'}->{'long_description_fr'} = decode_string($x->{'room_type'}->{'long_description_fr'});
		$x->{'room_type'}->{'long_description_es'} = decode_string($x->{'room_type'}->{'long_description_es'});
		$x->{'room_type'}->{'long_description_de'} = decode_string($x->{'room_type'}->{'long_description_de'});
	}

	my $coupon_code = $coupon_detail->{'code'};
	my $disc_perc   = $coupon_detail->{'discount_percentage'};
    my $disc_fixed  = $coupon_detail->{'fixed_discount'};
	
	my $coupon_hash = undef;

	if ( defined $coupon_code && $coupon_code !~ /^\s*$/ ) {
		$coupon_hash = {
			'code' => $coupon_code,
			'perc' => $disc_perc,
			'fixed' => $disc_fixed
		};

		my $temp_base = $total_base_amount;
	    $temp_base -= $disc_fixed;
	    $temp_base = $temp_base - ( ( $temp_base * $disc_perc ) / 100 );

	    if ( $total_base_amount - $temp_base > 0 ) {
		    $total_discount = $total_base_amount - $temp_base;
		}
	}

	$gross_amount = $total_base_amount + $total_extra_person_amount + $total_extra_cost;
	$gross_amount -= $total_discount;

	my $coupon_json = to_json( $coupon_hash );
	
	my $required_deposit_percentage = $class->{'required_deposit_percentage'};
	my $deposit_amount = 0;
	if ( $required_deposit_percentage > 0 ) {
		$deposit_amount = ( $gross_amount * $required_deposit_percentage ) / 100;
	}
	$class->{'deposit_amount'} = $deposit_amount;

	my $booking_status = 1;
	if ( $deposit_amount > 0 ) {
		$booking_status = 3;
	}

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel, 3: pending payment
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'insert' => {
				'hotel_id'         => $search_params->{'hotel_id'},
				'first_name'       => $first_name,
				'last_name'        => $last_name,
				'email'            => $email,
				'phone'            => $phone,
				'arrival_time'     => $arrival_time,
				'country'          => $country,
				'no_of_adult'      => $no_of_adult,
				'no_of_child'      => $no_of_child,
				'child_ages'       => to_json($search_params->{'child_ages'}),
				'guest_comment'    => $guest_comment,
				'check_in_date'    => $check_in,
				'check_out_date'   => $check_out,
				'ip_address'        => $ipaddr,
				'booking_status'    => $booking_status,
				'total_base_amount' => $total_base_amount,
				'total_extra_person_amount' => $total_extra_person_amount,
				'currency'          => 'EUR',
				'total_discount'    => $total_discount,
				'extra_amount'      => $total_extra_cost,
				'gross_amount'      => $gross_amount,
				'deposit_amount'    => $deposit_amount,
				'category'          => $category,
				'category_name'     => $category_name,
				'numbers'           => $str1,
				'last_date'         => $last_date,
				'category_code'     => $str2,
				'selected_room_type' => to_json( $final_room_details ),
				'selected_extras'  => to_json( $selected_extras ),
				't_type'         => $payment_type,
				'tt1'            => $dk,
				'tt2'            => $str3,
				'coupon_code'    => $coupon_json,
				'create_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				'modify_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
			},
		);

		$class->{'system_booking_id'} = $class->{'obj_database'}->last_insert_id();
	};
	if ( $@ ) {
		::log($@);
	}

	return 1;
}

sub decode_string {
	my $str = shift;

	$str = decode('utf-8', $str);

	return $str;	
}

sub cancel_booking {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $booking_ref_id = $cgi_params->{'booking_ref_id'};
	my $email = $cgi_params->{'email'};

	my $ipaddr = $ENV{'REMOTE_ADDR'};

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'update' => {
				'ip_address'        => $ipaddr,
				'booking_status'    => 2,
				'is_posted'         => 0,
				'attempt'           => 0,
				'modify_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
			},
			'where' => {
				'id' => $booking_ref_id
			}
		);
	};
	if ( $@ ) {
		return 0;
	}

	return 1;
}

sub fetch_booking_master_data {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $booking_ref_id = $cgi_params->{'booking_ref_id'};
	my $email          = $cgi_params->{'email'};

	##special condition for search booking external via guest or via user
	my $whr = {};
	$whr->{'id'} = $booking_ref_id;
	$whr->{'email'} = $email;

	my $get_booking_master_data = $class->{'obj_database'}->get({
		'table'  => 'booking_master',
		'hash'   => 1,
		'select' => '*',
		'where'  => $whr,
	});

	if ( defined $get_booking_master_data ) {
		$class->{'booking_master_data'} = $get_booking_master_data->[0];
	}

	return 1;
}

sub get_booking_master_data {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $get_booking_master_data = $class->{'obj_database'}->get({
		'table'  => 'booking_master',
		'hash'   => 1,
		'select' => '*'
		# 'where' => {
		# 	'hotel_id' => 2
		# }
	});

	if ( defined $get_booking_master_data ) {
		$class->{'booking_master_data'} = $get_booking_master_data;
	}

	return 1;
}

sub update_booking_master_data {
	my $class = shift;
	my $booking_ref_id = shift;
	my $tt1 = shift;
	my $tt2 = shift;
	my $str1 = shift;
	my $str2 = shift;

	my $cgi_params = $class->{'cgi_params'};

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'update' => {
				'tt1' => $tt1,
				'tt2' => $tt2,
				'numbers' => $str1,
				'category_code' => $str2
			},
			'where' => {
				'id' => $booking_ref_id
			}
		);
	};
	if ( $@ ) {
		return 0;
	}

	return 1;
}

sub update_booking_master_status {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $booking_ref_id = $cgi_params->{'booking_ref_id'};

	##booking status 0: before booking attempt status, 1: confirm, 2: cancel
	eval {
		$class->{'obj_database'}->set(
			'table' => 'booking_master',
			'update' => {
				'booking_status' => 1,
			},
			'where' => {
				'id' => $booking_ref_id
			}
		);
	};
	if ( $@ ) {
		return 0;
	}

	return 1;
}

sub get_agent_detail {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $user_id = $class->{'booking_master_data'}->{'agent_id'};
	if ( !defined $user_id || $user_id =~ /^\s*$/ ) {
		$user_id = $class->{'user_id'};
	}

	my $agent_detail = $class->{'obj_database'}->get({
		'table'  => 'user_master',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $user_id,
		}
	})->[0];

	if ( defined $agent_detail ) {
		$class->{'agent_detail'} = $agent_detail;
	}
	
	return 1;
}

sub send_email {
	my $class = shift;

	my $hotel_detail = $class->{'hotel_detail'};
	my $hotel_name = $hotel_detail->{'name'};
	my $hotel_email = $hotel_detail->{'reservation_email'};

	my $credential = $::config{'credential'};

    my $smtpserver   = $credential->{'EMAIL_HOST'};
	my $smtpport     = $credential->{'EMAIL_PORT'};
	my $smtpuser     = $credential->{'EMAIL_USER'};
	my $smtppassword = $credential->{'EMAIL_PASS'};

	use Email::Sender::Simple qw(sendmail);
	use Email::Sender::Transport::SMTPS ();
	use Email::Simple ();
	use Email::Simple::Creator ();
	use Email::MIME;

	my $transport = Email::Sender::Transport::SMTPS->new({
	 	host => $smtpserver,
	 	port => $smtpport,
	  	# ssl  => "starttls",
	  	sasl_username => $smtpuser,
	  	sasl_password => $smtppassword,
	});

	my $booking_status = 'Confirmed';
	if ( $class->{'booking_master_data'}->{'booking_status'} == 2 ) {
		$booking_status = 'Cancelled';
	}

	my $from = $hotel_name." booking engine <".$credential->{'EMAIL_FROM'}.">";
	my $to = [ $class->{'booking_master_data'}->{'email'} ];

	if ( defined $hotel_email && $hotel_email !~ /^\s*$/ ) {
		push @$to, $hotel_email;
	}
	my $cc = $::config{'reservationemail'}->{'cc'};
	my $subject = "$booking_status Booking Voucher: #".$class->{'booking_master_data'}->{'id'};
	use Encode;
	my $body = Encode::decode( "utf8", $class->{'email_content'} );

	my @parts = (
	    Email::MIME->create(
	        attributes => {
	            content_type => "text/html",
	            disposition  => "attachment",
	            charset      => "UTF-8",
	            encoding     => "base64",
	        },
	        body_str => $body,
	    ),
	);

	my $email = Email::MIME->create(
	    header_str => [
	        From => $from,
	        To => $to,
	        Cc => $cc,
	        Subject => $subject,
	    ],
	    parts      => [ @parts ],
	);
	# my $email = Email::Simple->create(
	# 	header => [
	# 		To      => $to,
	# 		From    => $from,
	# 		Subject => $subject,
	# 	],
	# 	body => 'Testing',
	# );
	# $email->header_set( 'content-type' => 'text/html' );
	$email->charset_set( 'UTF-8' );
	$email->content_type_set( 'text/html' );
	eval {
		sendmail($email, { transport => $transport });
	};
	if ( $@ ) {
		print $@;
	}
}

sub send_request_email {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $guest_email = $cgi_params->{'email'};

	my $hotel_detail = $class->{'hotel_detail'};
	my $hotel_name = $hotel_detail->{'name'};
	my $hotel_email = $hotel_detail->{'reservation_email'};

	my $credential = $::config{'credential'};

    my $smtpserver   = $credential->{'EMAIL_HOST'};
	my $smtpport     = $credential->{'EMAIL_PORT'};
	my $smtpuser     = $credential->{'EMAIL_USER'};
	my $smtppassword = $credential->{'EMAIL_PASS'};

	use Email::Sender::Simple qw(sendmail);
	use Email::Sender::Transport::SMTPS ();
	use Email::Simple ();
	use Email::Simple::Creator ();
	use Email::MIME;

	my $transport = Email::Sender::Transport::SMTPS->new({
	 	host => $smtpserver,
	 	port => $smtpport,
	  	ssl  => "starttls",
	  	sasl_username => $smtpuser,
	  	sasl_password => $smtppassword,
	});

	my $from = $hotel_name." booking engine <".$hotel_email.">";
	my $to = [ $class->{'booking_master_data'}->{'email'} ];

	if ( defined $hotel_email && $hotel_email !~ /^\s*$/ ) {
		push @$to, $hotel_email;
	}
	my $cc = $::config{'reservationemail'}->{'cc'};
	my $subject = "Availability Inquiry Form";
	my $body = $class->{'email_content'};

	my @parts = (
	    Email::MIME->create(
	        attributes => {
	            content_type => "text/html",
	            disposition  => "attachment",
	            charset      => "UTF-8",
	            encoding     => "base64",
	        },
	        body_str => $body,
	    ),
	);

	my $email = Email::MIME->create(
	    header_str => [
	        From => $from,
	        To => $to,
	        Cc => $cc,
	        'Reply-To' => $guest_email,
	        Subject => $subject,
	    ],
	    parts      => [ @parts ],
	);
	# my $email = Email::Simple->create(
	# 	header => [
	# 		To      => $to,
	# 		From    => $from,
	# 		Subject => $subject,
	# 	],
	# 	body => 'Testing',
	# );
	# $email->header_set( 'content-type' => 'text/html' );
	$email->content_type_set( 'text/html' );
	eval {
		sendmail($email, { transport => $transport });
	};
	if ( $@ ) {
		print $@;
	}
}

sub get_currency_conversion_ratio {
	my $class = shift;

	my $currency_ratio = undef;
	eval {
		$currency_ratio = $class->{'obj_database'}->get_record_with_limit({
			'table'  => 'currency_converter_master',
			'hash'   => 1,
			'select' => '*',
			'key' => 'source'
		});
	};
	
	if ( defined $currency_ratio ) {
		$class->{'currency_ratio_list'} = $currency_ratio;
	}

	return 1;
}

sub get_commission_list {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};
	my $params_data = $class->{'params_data'};

	my $start_date = $cgi_params->{'check_in_date'} || $params_data->{'check_in_date'};
	my $end_date   = $cgi_params->{'check_out_date'} || $params_data->{'check_out_date'};
	
	my $whr->{'is_active'} = 'Y';

	my $get_commission_data = undef;
	eval {
		$get_commission_data = $class->{'obj_database'}->get({
			'table'  => 'commission',
			'hash'   => 1,
			'select' => 'start_date, end_date, addition, percentage',
			'where'  => $whr
		});
	};
	if ($@) {
		# handle failure...
	}

	my $day_diff = date($end_date) - date($start_date);
	
	my $commission_date_hash = {};
	my $is_all_commission_set = 0;
	my $higher_percentage_commission = 0;
	if ( scalar @$get_commission_data ) {
		foreach my $data ( @$get_commission_data ) {
			my $db_start_date = $data->{'start_date'};
			my $db_end_date   = $data->{'end_date'};

			$db_start_date =~ s/-//g;
			$db_end_date   =~ s/-//g;

			for( my $i = 0; $i < $day_diff; $i++ ) {
				my $stay_date = date($start_date) + $i;

				my $temp_date = $stay_date;
				$temp_date =~ s/-//g;
				
				if ( $temp_date >= $db_start_date && $temp_date <= $db_end_date ) {
					$commission_date_hash->{$stay_date}->{'addition'} += $data->{'addition'};
					$commission_date_hash->{$stay_date}->{'percentage'} += $data->{'percentage'};
				}

				if ( $higher_percentage_commission < $data->{'percentage'} ) {
					$higher_percentage_commission = $data->{'percentage'};
				}
			}

			if ( $data->{'destination_code'} =~ /^ALL$/ ) {
				$is_all_commission_set = 1;
			}
		}
	}

	##if global commission is not set then default 10
	# unless ( $is_all_commission_set ) {
	# 	for( my $i = 0; $i < $day_diff; $i++ ) {
	# 		my $stay_date = date($start_date) + $i;

	# 		$commission_date_hash->{$stay_date}->{'addition'} += 0;
	# 		$commission_date_hash->{$stay_date}->{'percentage'} += 10;
	# 	}
	# }	

	# print Dumper $commission_date_hash;
	$class->{'commission_data'} = $commission_date_hash;
	$class->{'higher_percentage_commission'} = $higher_percentage_commission;
}

sub get_provider_community_id {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	#Fetch Hotel list
	if ( defined $cgi_params->{'community'} && $cgi_params->{'community'} !~ /^\s*$/ ) {
		my $community_detail = $class->{'obj_database'}->get({
			'table'  => 'community_master',
			'hash'   => 1,
			'select' => 'community_id, global_community_id',
			'where'  => {
				'id' => $cgi_params->{'community'},
			}
		})->[0];

		if ( defined $community_detail ) {
			if ( defined $community_detail->{'community_id'} && $community_detail->{'community_id'} !~ /^\s*$/ && $community_detail->{'community_id'} !~ /null/i ) {
				$cgi_params->{'ciirus_community_id'} = $community_detail->{'community_id'};	
			}
			else {
				$cgi_params->{'ciirus_community_id'} = '';
			}

			if ( defined $community_detail->{'global_community_id'} && $community_detail->{'global_community_id'} !~ /^\s*$/ && $community_detail->{'global_community_id'} !~ /null/i ) {
				$cgi_params->{'global_community_id'} = $community_detail->{'global_community_id'};	
			}
			else {
				$cgi_params->{'global_community_id'} = '';
			}
		}
	}
	else {
		$cgi_params->{'ciirus_community_id'} = '';
		$cgi_params->{'global_community_id'} = '';
	}
	
	return 1;
}

sub get_next_prev_available_rooms {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id   = $cgi_params->{'hotel_id'};
	my $check_in   = $cgi_params->{'check_in'};
	my $check_out  = $cgi_params->{'check_out'};
	my $no_of_night = $cgi_params->{'no_of_night'};

	my $today_date = ::get_today_day();
	my $before_check_in_days = ::get_delta_days( $today_date, $check_in );
	
	my $calendar_start_date = '';
	my $calendar_end_date = '';
	if ( $before_check_in_days > 9 ) {
		$calendar_start_date = ::add_number_of_day( $check_in, -9 );
		$calendar_end_date   = ::add_number_of_day( $check_out, 9 );
	}
	else {
		$calendar_start_date = $today_date;
		my $total = 20 - $no_of_night - $before_check_in_days;
		$calendar_end_date   = ::add_number_of_day( $check_out, $total );
	}

	my $covered_month_hash = {};
	my $calendar_days = [];

	my $temp_date_hash = {};
	my $inventory_data_hash = {};
	if ( $calendar_start_date && $calendar_end_date ) {
		my $whr->{'hotel_id'} = $hotel_id;

		$whr = [
			$whr,
			'AND',
			"date >= '$calendar_start_date' AND date <= '$calendar_end_date'"
		];

		my $inventory_data = undef;
		eval {
			$inventory_data = $class->{'obj_database'}->get({
				'table'  => 'inventory_masters',
				'hash'   => 1,
				'select' => 'date, room_type_id, availability',
				'where'  => $whr
			});
		};

		if ( defined $inventory_data && scalar @$inventory_data ) {
			my $is_set = 0;
			foreach my $data ( @$inventory_data ) {
				my ( $y, $m, $d ) = split('-', $data->{'date'});
				$covered_month_hash->{$m} = {
					'm' => $m,
					'y' => $y
				};

				my $dow = ::get_day_of_week( $data->{'date'} );

				$temp_date_hash->{$data->{'room_type_id'}}->{$data->{'date'}} = {
					'date' => $data->{'date'},
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => $data->{'availability'}
				};
			}
		}
	}

	my $calendar_day_diff = ::get_delta_days( $calendar_start_date, $calendar_end_date );
	for (my $i = 0; $i < $calendar_day_diff; $i++) {
		my $stay_date = ::add_number_of_day( $calendar_start_date, $i );

		my ( $y, $m, $d ) = split('-', $stay_date);
		my $dow = ::get_day_of_week( $stay_date );

		push @$calendar_days, {
			'day'  => $::single_digit_dow_single_char->{$dow},
			'date' => $d
		};
	}
	
	my $avail_room_date_group = {};
	my $distinct_room_ids = '';
	foreach my $room_type_id ( keys %$temp_date_hash ) {
		my $dates = $temp_date_hash->{$room_type_id};

		my $avail_segment = [];
		my $temp_group = [];
		my $prev_date = undef;
		for (my $i = 0; $i < $calendar_day_diff; $i++) {
			my $stay_date = ::add_number_of_day( $calendar_start_date, $i );
			my $dow = ::get_day_of_week( $stay_date );

			if ( exists $temp_date_hash->{$room_type_id}->{$stay_date} ) {
				push @{$inventory_data_hash->{$room_type_id}}, {
					'date' => $stay_date,
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => $temp_date_hash->{$room_type_id}->{$stay_date}->{'inventory'}
				};
			}
			else {
				push @{$inventory_data_hash->{$room_type_id}}, {
					'date' => $stay_date,
					'day'  => $::single_digit_dow_single_char->{$dow},
					'inventory' => 0
				};
			}

			if ( $temp_date_hash->{$room_type_id}->{$stay_date}->{'inventory'} > 0 ) {
				if ( scalar @$temp_group ) {
					my $f_date = $temp_group->[0];
					my $l_date = $temp_group->[scalar @$temp_group - 1];

					my $day_diff = ::get_delta_days( $l_date, $stay_date );
					if ( $day_diff == 1 ) {
						push @$temp_group, $stay_date;

						if ( scalar @$temp_group == $no_of_night ) {
							push @$avail_segment, $temp_group;
							$temp_group = [];
						}
					}
				}
				else {
					push @$temp_group, $stay_date;
					if ( scalar @$temp_group == $no_of_night ) {
						push @$avail_segment, $temp_group;
						$temp_group = [];
					}
				}
			}
		}

		$distinct_room_ids .= $room_type_id.",";
		$avail_room_date_group->{$room_type_id} = $avail_segment;
	}
	$class->{'calendar_inventory_data_hash'} = $inventory_data_hash;
	$distinct_room_ids =~ s/,$//g;

	my $final_avail_segment = [];
	my $min_price = undef;
	if ( defined $distinct_room_ids && $distinct_room_ids !~ /^\s*$/ ) {
		my $whr->{'hotel_id'} = $hotel_id;
		$whr = [
			$whr,
			"AND",
			"room_type_id IN ($distinct_room_ids)"
		];

		eval {
			$min_price = $class->{'obj_database'}->get({
				'table'  => 'rate_plans',
				'select' => 'min(room_price)',
				'where'  => $whr
			})->[0]->[0];
		};
	}

	foreach my $room_type_id ( keys %$avail_room_date_group ) {
		my $seg = $avail_room_date_group->{$room_type_id};
		if ( scalar @$seg >= 2 ) {
			##seg 1
			my $sd = $seg->[0]->[0];
			my $dow = ::get_day_of_week( $sd );
			my $sdw = $::single_digit_dow_short->{$dow};

			my $ed = $seg->[0]->[-1];
			$ed = ::add_one_day( $ed );
			$dow = ::get_day_of_week( $ed );
			my $edw = $::single_digit_dow_short->{$dow};

			my ( $y, $m, $d ) = split('-', $sd);
			$sd = $d." ".$::single_digit_month->{$m};

			( $y, $m, $d ) = split('-', $ed);
			$ed = $d." ".$::single_digit_month->{$m};

			my $n = scalar @{$seg->[0]};
			push @$final_avail_segment, {
				'price' => $min_price,
				'date_string' => $sd." - ".$ed,
				'night' => $n,
				'day' => $sdw.'-'.$edw
			};

			#seg last
			$sd = $seg->[-1]->[0];
			$dow = ::get_day_of_week( $sd );
			$sdw = $::single_digit_dow_short->{$dow};

			$ed = $seg->[-1]->[-1];
			$ed = ::add_one_day( $ed );
			$dow = ::get_day_of_week( $ed );
			$edw = $::single_digit_dow_short->{$dow};

			( $y, $m, $d ) = split('-', $sd);
			$sd = $d." ".$::single_digit_month->{$m};

			( $y, $m, $d ) = split('-', $ed);
			$ed = $d." ".$::single_digit_month->{$m};

			$n = scalar @{$seg->[-1]};
			push @$final_avail_segment, {
				'price' => $min_price,
				'date_string' => $sd." - ".$ed,
				'night' => $n,
				'day' => $sdw.'-'.$edw
			};
		}

		last if scalar @$final_avail_segment >= 2;
	}

	my $covered_month = [];
	foreach my $m ( sort keys %$covered_month_hash ) {
		my $month = $::single_digit_month->{$m};
		my $year  = $covered_month_hash->{$m}->{'y'};
		$year =~ s/(\d{2})(\d{2})/$2/;

		push @$covered_month, "$month $year";
	}
	$class->{'covered_month'} = $covered_month;
	$class->{'calendar_days'} = $calendar_days;
	$class->{'final_avail_segment'} = $final_avail_segment;

	return 1;
}

sub booking_param_validation {
	my $class = shift;

	my $cgi_params = $class->{'cgi_params'};

	my $params = [{
			'caption' => 'first_name',
			'label'   => 'First Name'
		},
		{
			'caption' => 'email',
			'label'   => 'Email'
		},
		{
			'caption' => 'phone',
			'label'   => 'Phone'
		}
	];

	if ( $cgi_params->{'payment_type'} =~ /^cc$/i ) {
		push @$params, {
			'caption' => 'card_number',
			'label'   => 'Card Number'
		};
		push @$params, {
			'caption' => 'card_expiry_date',
			'label'   => 'Card Expiry Date'
		};
		push @$params, {
			'caption' => 'card_holder',
			'label'   => 'Card Holder'
		};
	}

	# print Dumper $cgi_params;

	my $string = '';
	foreach my $rec ( @$params ) {
		my $param = $rec->{'caption'};
		my $label = $rec->{'label'};

		if ( !defined $cgi_params->{$param} || $cgi_params->{$param} =~ /^\s*$/ ) {
			$string .= "$label is missing <br/>";
		}
		if ( $param =~ /email/i ) {
			if ( $cgi_params->{$param} !~ /.*?\@.*/ ) {
				$string .= "$label is Wrong <br/>";
			}
		}
		if ( $param =~ /phone/i ) {
			if ( length($cgi_params->{$param}) < 10 ) {
				$string .= "$label is Wrong <br/>";
			}
		}
		if ( $param =~ /card_number/i ) {
			if ( length($cgi_params->{$param}) < 16 ) {
				$string .= "$label is Wrong <br/>";
			}
		}
	}

	if ( $string !~ /^\s*$/ ) {
		$class->{'error_string'} = $string;
		return 0;
	}

	return 1;
}

sub insert_no_avail_rooms_data {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $ip_address = '';
	if ( exists $ENV{'REMOTE_ADDR'} ) {
		$ip_address = $ENV{'REMOTE_ADDR'};
	}
	else {
		$ip_address = $cgi_params->{'cgi_object'}->remote_host();
	}

	my $params = {};
	foreach my $key ( keys %$cgi_params ) {
	    if ( $key !~ /cgi_object/ ) {
	        $params->{$key} = $cgi_params->{$key};
	    }
	}
	$params->{'ip_address'} = $ip_address;
	my $params_json = to_json( $params );


	#Check user name
	eval {
		$class->{'obj_database'}->set(
			'table' => 'no_avail_rooms',
			'insert' => {
				'hotel_id'       => $cgi_params->{'hotel_id'},
				'check_in'       => $cgi_params->{'check_in'},
				'check_out'      => $cgi_params->{'check_out'},
				'params'         => $params_json,
				'create_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
				'modify_date'    => strftime("%Y-%m-%d %H:%M:%S", localtime(time())),
			},
		);
	};
	if ( $@ ) {
		::log($@);
	}
	
	return 1;
}

sub get_lowest_rate {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $hotel_id = $cgi_params->{'hotel_id'};

	my $today_date = ::get_today_day();

	my $whr->{'hotel_id'} = $hotel_id;
	$whr = [
		$whr,
		'AND',
		"date >= '$today_date'"
	];

	#Check user name
	my $lowest_data = $class->{'obj_database'}->get_record_with_limit({
		'table'  => 'lowest_rate_data',
		'hash'   => 1,
		'select' => 'date, lowest_rate',
		'where'  => $whr,
		'key' => 'date'
	});

	my $final_lowest_rate_data = {};
	if ( scalar keys %$lowest_data ) {
		foreach my $date (sort { $a <=> $b} keys %$lowest_data) {
			my $rate = $lowest_data->{$date}->{'lowest_rate'};
			if ( $rate =~ /-/ ) {
				$final_lowest_rate_data->{$date} = $rate;
			}
			else {
				$final_lowest_rate_data->{$date} = "€".$rate;
			}
		}
	}
	# print Dumper $final_lowest_rate_data;
	# return to_json( $final_lowest_rate_data );
	$class->{'data'} = $final_lowest_rate_data;

	return 1;
}

sub get_request_params {
	my $class = shift;
	
	my $cgi_params = $class->{'cgi_params'};
	my $request_id = $cgi_params->{'request_id'};

	#Check user name
	my $request_data = $class->{'obj_database'}->get({
		'table'  => 'requests',
		'hash'   => 1,
		'select' => '*',
		'where'  => {
			'id' => $request_id
		}
	});

	if ( defined $request_data && scalar @$request_data ) {
		$class->{'request_data'} = $request_data->[0];
	}

	return 1;
}

1;
