<?php
if ( ! function_exists( 'wpj_refresh_user_notifications_cron' ) ) {
	function wpj_refresh_user_notifications_cron() {
		$uid = get_current_user_id();

		if ( $uid ) {
			$current_time = current_time( 'timestamp', 1 );
			$timeout      = get_user_meta( $uid, 'notifications_cron_timeout', true );

			if ( $current_time > $timeout ) {
				wpj_refresh_user_notifications( $uid );

				$new_timeout = $current_time + 3600; // + 1h * 60m * 60s

				update_user_meta( $uid, 'notifications_cron_timeout', $new_timeout );
			}
		}
	}
}

if ( ! function_exists( 'wpj_update_user_level_cron' ) ) {
	function wpj_update_user_level_cron() {
		if ( wpj_get_option( 'wpj_user_level_cron_enabled' ) != 'no' ) {
			if ( wpj_get_option( 'wpjobster_auto_upgrade_user_level' ) == 'yes' || wpj_get_option( 'wpjobster_auto_downgrade_user_level' ) == 'yes' ) {
				$users = get_users();

				if ( $users ) {
					foreach ( $users as $user ) {
						$uid          = $user->ID;
						$current_time = current_time( 'timestamp', 1 );

						if ( $current_time > get_user_meta( $uid, 'date_toclear', true ) ) {
							$query_where = ['p.post_author' => $uid, 'o.done_seller' => 1, 'o.done_buyer' => 1, 'o.closed' => 0];

							// Get Level 1 data
							$date_min = wpj_get_start_date_for_active_period( $uid, 1 );
							$date_max = strtotime( '+1 day', time() );

							$query_between = ['column' => 'o.date_completed', 'date_min' => $date_min, 'date_max' => $date_max];

							$orders_level1     = wpj_get_job_order_post( 'SUM(mc_gross) as total', $query_where, 'row', $query_between );
							$orders_sum_level1 = ! empty( $orders_level1->total ) ? $orders_level1->total : 0;

							$ratings_level1     = wpj_get_awarded_job_ratings_between_by_user( 'SUM(grade) as total_amount, COUNT(*) as total_count', $uid, $date_min, $date_max, 'row' );
							$ratings_sum1       = ! empty( $ratings_level1->total_amount ) ? $ratings_level1->total_amount : 0;
							$ratings_count1     = ! empty( $ratings_level1->total_count ) ? $ratings_level1->total_count : 0;
							$ratings_avg_level1 = $ratings_count1 > 0 ? ( $ratings_sum1 / $ratings_count1 ) * 20 : 0;

							// Get Level 2 data
							$date_min = wpj_get_start_date_for_active_period( $uid, 2 );
							$date_max = strtotime( '+ 1 day', time() );

							$query_between = ['column' => 'o.date_completed', 'date_min' => $date_min, 'date_max' => $date_max];

							$orders_level2     = wpj_get_job_order_post( 'SUM(mc_gross) as total', $query_where, 'row', $query_between );
							$orders_sum_level2 = ! empty( $orders_level2->total ) ? $orders_level2->total : 0;

							$ratings_level2     = wpj_get_awarded_job_ratings_between_by_user( 'SUM(grade) as total_amount, COUNT(*) as total_count', $uid, $date_min, $date_max, 'row' );
							$ratings_sum2       = ! empty( $ratings_level2->total_amount ) ? $ratings_level2->total_amount : 0;
							$ratings_count2     = ! empty( $ratings_level2->total_count ) ? $ratings_level2->total_count : 0;
							$ratings_avg_level2 = $ratings_count2 > 0 ? ( $ratings_sum2 / $ratings_count2 ) * 20 : 0;

							// Set Level 2
							$amount_upgrade2  = wpj_get_option( 'wpjobster_level2_min' );
							$ratings_upgrade2 = wpj_get_option( 'wpjobster_level2_upgrade_rating' );

							if ( $ratings_upgrade2 < 1 )
								$ratings_upgrade2 = 95;

							if ( $orders_sum_level2 >= $amount_upgrade2 && $ratings_avg_level2 >= $ratings_upgrade2 )
								$level2 = 1;
							else
								$level2 = 0;

							// Set Level 1
							$amount_upgrade1  = wpj_get_option( 'wpjobster_level1_min' );
							$ratings_upgrade1 = wpj_get_option( 'wpjobster_level1_upgrade_rating' );

							if ( $ratings_upgrade1 < 1 )
								$ratings_upgrade1 = 90;

							if ( $orders_sum_level1 >= $amount_upgrade1 && $ratings_avg_level1 >= $ratings_upgrade1 )
								$level1 = 1;
							else
								$level1 = 0;

							// Set new recheck period
							$user_level = $new_user_level = get_user_meta( $uid, 'user_level', true );

							if ( $new_user_level != 3 ) {
								if ( $level2 == 1 ) {
									$recheck_interval2 = wpj_get_option( 'wpjobster_level2_recheck_interval' );

									if ( ! is_numeric( $recheck_interval2 ) || $recheck_interval2 <= 1 )
										$recheck_interval2 = 2;

									update_user_meta( $uid, 'date_toclear', strtotime( '+' . $recheck_interval2 . ' month', time() ) );

									$new_user_level = 2;

								} elseif ( $level1 == 1 ) {
									$recheck_interval1 = wpj_get_option( 'wpjobster_level1_recheck_interval' );

									if ( ! is_numeric( $recheck_interval1 ) || $recheck_interval1 <= 1 )
										$recheck_interval1 = 1;

									update_user_meta( $uid, 'date_toclear', strtotime( '+' . $recheck_interval1 . ' month', time() ) );

									$new_user_level = 1;

								} else {
									$recheck_interval0 = wpj_get_option( 'wpjobster_level0_recheck_interval' );

									if ( ! is_numeric( $recheck_interval0 ) || $recheck_interval0 <= 1 )
										$recheck_interval0 = 1;

									update_user_meta( $uid, 'date_toclear', strtotime( '+' . $recheck_interval0 . ' month', time() ) );

									$new_user_level = 0;

								}
							}

							// Set new levels
							if ( $new_user_level > $user_level && wpj_get_option( 'wpjobster_auto_upgrade_user_level' ) == 'yes' ) {
								// Update level
								update_user_meta( $uid, 'user_level', $new_user_level );

								// Send email
								wpj_notify_user_translated( 'level_up', $uid, ['##current_level##' => $new_user_level]);

							} elseif ( $new_user_level < $user_level && wpj_get_option( 'wpjobster_auto_downgrade_user_level' ) == 'yes' ) {
								// Update level
								update_user_meta( $uid, 'user_level', $new_user_level );

								// Send email
								wpj_notify_user_translated( 'level_down', $uid, ['##current_level##' => $new_user_level]);

							}

						}

						wpj_do_user_level_extras_check( $uid );
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_vacation_check_cron' ) ) {
	function wpj_vacation_check_cron() {
		if ( wpj_get_option( 'wpj_vacation_check_cron_enabled' ) != 'no' ) {
			$today = current_time( 'timestamp', 1 );

			$inactive_vacations = wpj_get_vacation( 'id', [
				'vacation_mode'     => 0,
				'duration_start_ts' => $today,
				'duration_end_ts'   => $today
			], 'results' );

			if ( $inactive_vacations ) {
				foreach ( $inactive_vacations as $index => $vacation ) {
					wpj_update_vacation(
						['vacation_mode' => 1],
						['id' => $vacation->id]
					);
				}
			}

			$active_vacations = wpj_get_vacation( 'id, duration_end_ts, duration_end', [
				'vacation_mode' => 1,
				'duration_end_ts' => $today
			], 'results' );

			if ( $active_vacations ) {
				foreach ( $active_vacations as $index => $vacation ) {
					wpj_update_vacation(
						[
							'vacation_mode'          => 0,
							'duration_end_actual_ts' => $vacation->duration_end_ts,
							'duration_end_actual'    => $vacation->duration_end
						],
						['id' => $vacation->id]
					);
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_inactive_expired_requests_cron' ) ) {
	function wpj_inactive_expired_requests_cron() {
		if ( wpj_get_option( 'wpj_inactive_expired_requests_cron_enabled' ) != 'no' ) {
			$requests = wpj_get_expired_active_requests();

			if ( $requests ) {
				foreach ( $requests as $request ) {
					update_post_meta( $request->ID, 'active', 0 );
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_update_exchange_rates_cron' ) ) {
	function wpj_update_exchange_rates_cron() {
		if ( wpj_get_option( 'wpj_update_exchange_rates_cron_enabled' ) != 'no' ) {
			if ( wpj_get_option( 'wpjobster_enable_open_exchange_api_rate' ) == 'yes' ) {
				wpj_fetch_exchange_rates();
			}
		}

		return true;
	}
}

if ( ! function_exists( 'wpj_check_featured_cron' ) ) {
	function wpj_check_featured_cron() {
		if ( wpj_get_option( 'wpj_check_featured_cron_enabled' ) != 'no' ) {
			if ( wpj_get_option( 'wpjobster_featured_enable' ) == 'yes' ) {
				// Home
				$home_query = new WP_Query([
					'posts_per_page' =>'-1',
					'post_type'      => 'job',
					'post_status'    => 'publish',
					'meta_query'     => [
						[
							'relation' => 'AND',
							['key' => 'home_featured_until', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '<'],
							['key' => 'home_featured_now', 'value' => 'y', 'type' => 'meta_value', 'compare' => '=']
						]
					]
				]);

				if ( $home_query->have_posts() ) {
					while ( $home_query->have_posts() ) { $home_query->the_post();
						update_post_meta( get_the_ID(), 'home_featured_until', 'z' );
						update_post_meta( get_the_ID(), 'home_featured_now', 'z' );
					}
				}

				// Category
				$category_query = new WP_Query([
					'posts_per_page' =>'-1',
					'post_type'      => 'job',
					'post_status'    => 'publish',
					'meta_query'     => [
						[
							'relation' => 'AND',
							['key' => 'category_featured_until', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '<'],
							['key' => 'category_featured_now', 'value' => 'y', 'type' => 'meta_value', 'compare' => '=']
						]
					]
				]);

				if ( $category_query->have_posts() ) {
					while ( $category_query->have_posts() ) { $category_query->the_post();
						update_post_meta( get_the_ID(), 'category_featured_until', 'z' );
						update_post_meta( get_the_ID(), 'category_featured_now', 'z' );
					}
				}

				// Subcategory
				$subcategory_query = new WP_Query([
					'posts_per_page' =>'-1',
					'post_type'      => 'job',
					'post_status'    => 'publish',
					'meta_query'     => [
						[
							'relation' => 'AND',
							['key' => 'subcategory_featured_until', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '<'],
							['key' => 'subcategory_featured_now', 'value' => 'y', 'type' => 'meta_value', 'compare' => '=']
						]
					]
				]);

				if ( $subcategory_query->have_posts() ) {
					while ( $subcategory_query->have_posts() ) { $subcategory_query->the_post();
						update_post_meta( get_the_ID(), 'subcategory_featured_until', 'z' );
						update_post_meta( get_the_ID(), 'subcategory_featured_now', 'z' );
					}
				}

				$featured_until_time = strtotime( '+' . ( wpj_get_option( 'wpjobster_featured_interval' ) - 1 ) . ' day', time() );

				// Home
				if ( wpj_get_option( 'wpjobster_homepage_featured_enable' ) == 'yes' ) {
					$home_query = new WP_Query([
						'posts_per_page' => '-1',
						'post_type'      => 'job',
						'post_status'    => 'publish',
						'meta_query'     => [
							[
								'relation' => 'AND',
								['key' => 'home_featured_until', 'value' => $featured_until_time , 'type' => 'meta_value_num', 'compare' => '<='],
								['key' => 'home_featured_now', 'value' => 'z', 'type' => 'meta_value', 'compare' => '='],
								['key' => 'home_featured_until', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '>'],
							]
						]
					]);

					if ( $home_query->have_posts() ) {
						while ( $home_query->have_posts() ) { $home_query->the_post();
							update_post_meta( get_the_ID(), 'home_featured_now', 'y' );
						}
					}
				}

				// Category
				if ( wpj_get_option( 'wpjobster_category_featured_enable' ) == 'yes' ) {
					$category_query = new WP_Query([
						'posts_per_page' => '-1',
						'post_type'      => 'job',
						'post_status'    => 'publish',
						'meta_query'     => [
							[
								'relation' => 'AND',
								['key' => 'category_featured_until', 'value' => $featured_until_time , 'type' => 'meta_value_num', 'compare' => '<='],
								['key' => 'category_featured_now', 'value' => 'z', 'type' => 'meta_value', 'compare' => '='],
								['key' => 'category_featured_now', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '>'],
							]
						]
					]);

					if ( $category_query->have_posts() ) {
						while ( $category_query->have_posts() ) { $category_query->the_post();
							update_post_meta( get_the_ID(), 'category_featured_now', 'y' );
						}
					}
				}

				// Subcategory
				if ( wpj_get_option( 'wpjobster_subcategory_featured_enable' ) == 'yes' ) {
					$subcategory_query = new WP_Query([
						'posts_per_page' => '-1',
						'post_type'      => 'job',
						'post_status'    => 'publish',
						'meta_query'     => [
							[
								'relation' => 'AND',
								['key' => 'subcategory_featured_until', 'value' => $featured_until_time , 'type' => 'meta_value_num', 'compare' => '<='],
								['key' => 'subcategory_featured_now', 'value' => 'z', 'type' => 'meta_value', 'compare' => '='],
								['key' => 'subcategory_featured_now', 'value' => time(), 'type' => 'meta_value_num', 'compare' => '>'],
							]
						]
					]);

					if ( $subcategory_query->have_posts() ) {
						while ( $subcategory_query->have_posts() ) { $subcategory_query->the_post();
							update_post_meta( get_the_ID(), 'subcategory_featured_now', 'y' );
						}
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_check_subscription_cron' ) ) {
	function wpj_check_subscription_cron() {
		if ( wpj_get_option( 'wpj_check_subscription_cron_enabled' ) != 'no' ) {
			if ( wpj_get_option( 'wpjobster_subscription_enabled' ) == 'yes' ) {
				// Get active subscriptions
				$subscriptions = wpj_get_active_subscriptions();

				if ( $subscriptions ) {
					foreach ( $subscriptions as $subscription ) {
						$uid = $subscription->user_id;

						$order = wpj_get_subscription_order( 'id, payment_gateway_name', ['user_id' => $uid, 'subscription_status' => 'active'] );

						if ( $order ) {
							$order_id = $order->id;

							if ( $order->payment_gateway_name == 'credits' ) {
								$sub_level         = $subscription->next_subscription_level;
								$sub_type          = $subscription->next_subscription_type;
								$sub_id            = 'wpjobster_subscription_' . $sub_type . '_amount_' . $sub_level;
								$payable_amount    = wpj_get_option( $sub_id );
								$user_credit       = wpj_get_user_credit( $uid );
								$next_billing_date = wpj_get_subscription_next_billing_date( $sub_type );

								if ( $payable_amount > 0 && $payable_amount > $user_credit ) {
									// Action
									do_action( 'wpj_before_subscription_activation', 'schedule', $order_id, $sub_type, $sub_level );

									// Update user credits
									wpj_update_user_credit( $uid, $user_credit - $payable_amount );

									// Update subscription table
									wpj_update_active_subscription(
										['subscription_level' => $sub_level, 'subscription_type' => $sub_type, 'subscription_amount' => $payable_amount, 'next_billing_date' => $next_billing_date],
										['user_id' => $uid]
									);

									// Update subscription order table
									wpj_update_subscription_order(
										['profile_id' => $uid, 'payment_gateway_transaction_id' => $order_id, 'payment_response' => json_encode( $order )],
										['id' => $order_id]
									);

									// Insert payment to database
									$currency = apply_filters( 'wpjobster_take_allowed_currency_' . $order->payment_gateway_name, '' );

									if ( empty( $currency ) ) $currency = wpj_get_site_currency();

									wpj_insert_payment(
										[
											'payment_status'         => 'completed',
											'payment_gateway'        => $order->payment_gateway_name,
											'payment_response'       => json_encode( $order ),
											'payment_details'        => 'Subscription renewal',
											'payment_type'           => 'subscription',
											'payment_type_id'        => $order_id,
											'currency'               => wpj_get_site_default_currency(),
											'amount'                 => $payable_amount,
											'tax'                    => 0,
											'fees'                   => 0,
											'final_amount'           => $payable_amount,
											'final_amount_exchanged' => wpj_number_format_special_exchange( $payable_amount, 2, $currency ),
											'final_amount_currency'  => $currency,
											'datemade'               => current_time( 'timestamp', 1 ),
											'payment_made_on'        => current_time( 'timestamp', 1 )
										],
										['%s', '%s', '%s', '%s', '%s', '%d', '%s', '%f', '%f', '%f', '%f', '%f', '%s', '%d', '%d']
									);

									// Save log
									wpj_add_history_log([
										'tp'      => '0',
										'reason'  => __( 'Payment for subscription renewal', 'wpjobster' ),
										'amount'  => $payable_amount,
										'uid'     => $uid,
										'oid'     => $order_id,
										'rid'     => 11,
										'details' => $sub_type . '_' . $sub_level . '_renew'
									]);

									// Delete email meta
									delete_user_meta( $uid, 'wpjobster_subscription_prior_email_notification_sent' );

									// Send email
									wpj_notify_user_translated( 'balance_down_subscription', $uid, [
										'##username##'                    => wpj_get_user_display_type( $uid ),
										'##amount_updated##'              => $payable_amount,
										'##current_subscription_level##'  => wpj_translate_string( $sub_level ),
										'##current_subscription_period##' => wpj_translate_string( $sub_type ),
										'##current_subscription_amount##' => $payable_amount,
										'##next_billing_date##'           => $next_billing_date,
										'##next_subscription_level##'     => wpj_translate_string( $sub_level ),
										'##next_subscription_type##'      => wpj_translate_string( $sub_type ),
										'##next_subscription_amount##'    => $payable_amount
									]);

								} else {
									// Send email
									wpj_notify_user_translated( 'subscription_cancel_lowbalance', $uid, [
										'##username##'                    => wpj_get_user_display_type( $uid ),
										'##amount_updated##'              => $payable_amount,
										'##current_subscription_level##'  => wpj_translate_string( $sub_level ),
										'##current_subscription_period##' => wpj_translate_string( $sub_type ),
										'##current_subscription_amount##' => $payable_amount,
										'##next_billing_date##'           => $next_billing_date,
										'##next_subscription_level##'     => wpj_translate_string( $sub_level ),
										'##next_subscription_type##'      => wpj_translate_string( $sub_type ),
										'##next_subscription_amount##'    => $payable_amount
									]);

									// Remove subscription
									wpj_remove_subscription( $order_id );

								}

								// Checks
								wpj_do_user_level_extras_check( $uid );
								wpj_do_user_level_extras_price_check( $uid );
								wpj_do_user_level_job_price_check( $uid );

								// Send reminder email
								$total_seconds_prior = wpj_get_option( 'wpjobster_subscription_prior_notification' ) * 60 * 60 * 24;

								if ( $total_seconds_prior + time() > $subscription->next_billing_date
									&& get_user_meta( $uid, 'wpjobster_subscription_prior_email_notification_sent', true ) != '1'
								) {
									// Update email meta
									update_user_meta( $uid, 'wpjobster_subscription_prior_email_notification_sent', '1' );

									// Send email
									wpj_notify_user_translated( 'wpjobster_subscription_prior_notification', $uid, [
										'##amount_updated##'               => $subscription->subscription_amount,
										'##current_subscription_level##'   => wpj_translate_string( $subscription->subscription_level ),
										'##current_subscription_period##'  => wpj_translate_string( $subscription->subscription_type ),
										'##current_subscription_amount##'  => $subscription->subscription_amount,
										'##next_billing_date##'            => $subscription->next_billing_date,
										'##next_subscription_level##'      => wpj_translate_string( $subscription->next_subscription_level ),
										'##next_subscription_type##'       => wpj_translate_string( $subscription->next_subscription_type ),
										'##next_subscription_amount##'     => $subscription->next_subscription_amount,
										'##no_of_days_subscription_left##' => wpj_get_option( 'wpjobster_subscription_prior_notification' )
									]);
								}
							}
						}
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_order_cleared_cron' ) ) {
	function wpj_order_cleared_cron() {
		if ( wpj_get_option( 'wpj_order_cleared_cron_enabled' ) != 'no' ) {
			$orders = wpj_get_job_order(
				'id, date_to_clear',
				['clearing_period' => 2],
				'results',
				['column' => 'date_to_clear', 'date_max' => current_time( 'timestamp', 1 )]
			);

			if ( $orders ) {
				foreach ( $orders as $order ) {
					wpj_update_job_order(
						['clearing_period' => 1],
						['id' => $order->id]
					);

					wpj_mark_order_as_cleared( $order->id );
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_order_completed_cron' ) ) {
	function wpj_order_completed_cron() {
		if ( wpj_get_option( 'wpj_order_completed_cron_enabled' ) != 'no' ) {
			$wait_time = wpj_get_option( 'wpjobster_max_time_to_wait' );

			if ( ! is_numeric( $wait_time ) ) $wait_time = 72;

			$wait_time_ts = current_time( 'timestamp', 1 ) - $wait_time * 3600;

			$orders = wpj_get_job_order(
				'id',
				['done_seller' => 1, 'completed' => 0, 'closed' => 0],
				'results',
				['column' => 'date_finished', 'date_max' => $wait_time_ts]
			);

			if ( $orders ) {
				foreach ( $orders as $order ) {
					wpj_mark_order_as_completed( $order->id, true );
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_order_expired_cron' ) ) {
	function wpj_order_expired_cron() {
		if ( wpj_get_option( 'wpj_order_expired_cron_enabled' ) != 'no' ) {
			$no_of_days = wpj_get_option( 'wpjobster_pending_jobs_days' );

			if ( $no_of_days == 0 || ! is_numeric( $no_of_days ) ) $no_of_days = 7;

			$orders = wpj_get_job_order(
				'id',
				['payment_status' => 'pending', 'done_seller' => 0, 'done_buyer' => 0, 'date_finished' => 0, 'closed' => 0],
				'results',
				['column' => 'date_made', 'date_max' => strtotime( "- $no_of_days days" )]
			);

			foreach ( $orders as $order ) {
				wpj_update_order_meta( $order->id, 'payment_status', 'expired' );
				wpj_update_order_meta( $order->id, 'payment_details', "Expired on " . time() );

				wpj_update_job_order(['closed' => 1, 'date_closed' => current_time( 'timestamp', 1 )], ['id' => $order->id]);

				wpj_update_payment(
					['payment_status' => 'expired', 'payment_response' => 'Transaction Cancelled by Cron job on ' . date( 'Y-d-m' ), 'payment_details' => 'Expired on ' . time()],
					['payment_type_id' => $order->id, 'payment_type' => 'job_purchase']
				);
			}
		}
	}
}

if ( ! function_exists( 'wpj_order_failed_cron' ) ) {
	function wpj_order_failed_cron() {
		if ( wpj_get_option( 'wpj_order_failed_cron_enabled' ) != 'no' ) {
			wpj_update_job_order(
				['closed' => 1, 'date_closed' => current_time( 'timestamp', 1 ), 'payment_details' => 'Failed payment, closed by cron.'],
				['payment_status' => 'failed', 'done_seller' => 0, 'done_buyer' => 0, 'date_finished' => 0, 'closed' => 0]
			);
		}
	}
}

if ( ! function_exists( 'wpj_autoreject_order_cron' ) ) {
	function wpj_autoreject_order_cron() {
		if ( wpj_get_option( 'wpj_autoreject_order_cron_enabled' ) != 'no' ) {
			if ( wpj_get_option( 'wpjobster_seller_order_rejection_enable' ) == 'yes' ) {
				$orders = wpj_get_job_order(
					'id, uid, pid, date_made',
					['payment_status' => 'completed', 'seller_confirmation' => 0],
					'results'
				);

				if ( $orders ) {
					foreach ( $orders as $order ) {
						$diff  = current_time( 'timestamp', 1 ) - $order->date_made;
						$hours = round( $diff / ( 60 * 60 ) );

						if ( $hours > 24 ) {
							// Update orders table
							wpj_update_job_order(['seller_confirmation' => 2], ['id' => $order->id]);

							// Cancel order and refund buyer
							wpj_cancel_order_by_id( $order->id, 'autoclose', true );

							// Insert notification
							$this_notification = wpj_insert_order_notification( ['uid' => -47, 'oid' => $order->id, 'content' => __( 'Autoclosed', 'wpjobster' )], ['%d', '%d', '%s'] );

							if ( $this_notification > 0 ) {
								// Update notification
								wpj_update_user_notifications([
									'user1'       => $order->uid,
									'user2'       => get_post_field( 'post_author', $order->pid ),
									'type'        => 'notifications',
									'number'      => +1,
									'notify_id'   => $this_notification,
									'notify_type' => 'order_rejected',
									'order_id'    => $order->id
								]);

								// Send emails
								wpj_notify_user_translated( 'order_rejected', $order->uid, [
									'##transaction_page_link##' => wpj_get_order_link( $order->id ),
									'##transaction_number##'    => wpj_camouflage_oid( $order->id, $order->date_made )
								]);
							}
						}
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_buyer_cart_notify_cron' ) ) {
	function wpj_buyer_cart_notify_cron() {
		if ( wpj_get_option( 'wpj_buyer_cart_notify_cron_enabled' ) != 'no' ) {
			$all_users = get_users();

			if ( $all_users ) {
				foreach ( $all_users as $_user ) {
					$last_viewed = get_user_meta( $_user->ID, 'last_checkout_viewed', true );

					if ( is_array( $last_viewed ) ) {
						if ( array_filter( $last_viewed ) ) {
							$args = [
								'post_type'           => 'job',
								'posts_per_page'      => 12,
								'post__in'            => array_filter( $last_viewed ),
								'ignore_sticky_posts' => true,
								'orderby'             => 'post__in'
							];

							$results = get_posts( $args );

							if ( $results ) {
								$incompleted_orders  = [];

								$cart_notify_number_option = wpj_get_option( 'wpj_buyer_cart_notify_number' );

								if ( ! is_numeric( $cart_notify_number_option ) ) $cart_notify_number_option = 3;

								foreach ( $results as $row ) {
									$pid = $row->ID;

									$cart_notify_number_meta = get_post_meta( $pid, 'buyer_cart_notify_number_' . $_user->ID, true );

									if ( ! is_numeric( $cart_notify_number_meta ) ) $cart_notify_number_meta = 0;

									if ( $cart_notify_number_meta < $cart_notify_number_option ) {
										$cart_notify_number_meta++;

										update_post_meta( $pid, 'buyer_cart_notify_number_' . $_user->ID, $cart_notify_number_meta );

										$incompleted_orders [] = [
											'##job_link##' => get_permalink( $pid ),
											'##job_name##' => get_the_title( $pid )
										];

									} else {
										$cart_notify_number_meta = 0;

										update_post_meta( $pid, 'buyer_cart_notify_number_' . $_user->ID, $cart_notify_number_meta );

										wpj_update_last_checkout_viewed( $pid, $_user->ID, 'remove' );

									}
								}

								if ( $incompleted_orders  ) wpj_notify_user_translated( 'incomplete_order', $_user->ID, '', $incompleted_orders  );
							}
						}
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_order_expire_soon_notify_cron' ) ) {
	function wpj_order_expire_soon_notify_cron() {
		if ( wpj_get_option( 'wpj_order_expire_soon_notify_cron_enabled' ) != 'no' ) {
			$orders = wpj_get_job_order(
				'id, date_made, expected_delivery, job_title, pid',
				['payment_status' => 'completed', 'completed' => 0, 'closed' => 0, 'date_closed' => 0, 'date_finished' => 0],
				'results'
			);

			if ( $orders ) {
				foreach ( $orders as $order ) {
					$diff  = $order->expected_delivery - current_time( 'timestamp', 1 );
					$hours = round( $diff / ( 60 * 60 ) );

					if ( $hours < 24 && current_time( 'timestamp', 1 ) < $order->expected_delivery ) {
						wpj_notify_user_translated( 'ord_expires_soon', get_post_field( 'post_author', $order->pid ), [
							'##job_name##'              => $order->job_title,
							'##job_link##'              => urldecode( get_permalink( $order->pid ) ),
							'##transaction_page_link##' => wpj_get_order_link( $order->id ),
							'##transaction_number##'    => wpj_camouflage_oid( $order->id, $order->date_made )
						]);
					}
				}
			}
		}
	}
}

if ( ! function_exists( 'wpj_pending_payment_expire_soon_notify_cron' ) ) {
	function wpj_pending_payment_expire_soon_notify_cron() {
		if ( wpj_get_option( 'wpj_pending_payment_expire_soon_notify_cron_enabled' ) != 'no' ) {
			$orders = wpj_get_job_order(
				'id, uid, job_title, pid, date_made',
				['payment_status' => 'pending', 'done_seller' => 0, 'done_buyer' => 0, 'date_finished' => 0, 'closed' => 0],
				'results',
				['column' => 'date_made', 'date_max' => current_time( 'timestamp', 1 )]
			);

			if ( $orders ) {
				$no_of_days = wpj_get_option( 'wpjobster_pending_jobs_days' );

				if ( $no_of_days == 0 || ! is_numeric( $no_of_days ) ) $no_of_days = 7;

				$no_of_days--;

				foreach ( $orders as $order ) {
					$expected_expire = $order->date_made + ( 24 * 3600 * $no_of_days );

					$diff  = $expected_expire - current_time( 'timestamp', 1 );
					$hours = round( $diff / ( 60 * 60 ) );

					if ( $hours < 24 && current_time( 'timestamp', 1 ) < $expected_expire ) {
						wpj_notify_user_translated( 'pending_payment_expires', $order->uid, [
							'##job_name##'              => $order->job_title,
							'##job_link##'              => urldecode( get_permalink( $order->pid ) ),
							'##transaction_page_link##' => wpj_get_order_link( $order->id ),
							'##transaction_number##'    => wpj_camouflage_oid( $order->id, $order->date_made )
						]);
					}
				}
			}
		}
	}
}