WooCommerce


Source

File: classes/WooCommerce.php

class WooCommerce {

	public function __construct() {

		if ( ! dozent_wc_exists() ) {
			return;
		}

		add_filter( 'product_type_options', [ $this, 'dozent_type_in_wc_product' ] );
		add_action( 'save_post_product', array( $this, 'save_wc_product_meta' ) );

		add_filter( 'woocommerce_product_data_tabs', [ $this, 'add_dozent_courses_product_data_tab' ] );
		add_action( 'woocommerce_product_data_panels', [ $this, 'dozent_courses_data_panel' ] );

		add_action( 'save_post_product', [ $this, 'attach_courses_to_product' ] );
		add_filter( 'dozent_course_price', [ $this, 'filter_course_price' ], 10, 2 );
		add_action( 'dozent_course_type_closed_gate', [ $this, 'dozent_course_gate' ] );

		/**
		 * Placing order and sync with course enrolment process
		 */

		add_action( 'woocommerce_new_order', [ $this, 'placing_order_from_admin' ] );
		add_action( 'woocommerce_new_order_item', [ $this, 'placing_order_from_frontend' ], 10, 3 );

		add_action( 'woocommerce_order_status_changed', [ $this, 'order_status_changed' ], 10, 3 );
		add_filter( 'dozent_course_new_enrol_status', [ $this, 'new_enrol_status' ], 10, 4 );

		/**
		 * Add earning data to the database table
		 */

		add_action( 'woocommerce_new_order_item', array( $this, 'add_earning_data' ), 10, 3 );
		add_action( 'woocommerce_order_status_changed', array( $this, 'earning_data_status_change' ), 10, 3 );

	}

	public function dozent_type_in_wc_product( $types ) {
		$types['dozent_product'] = array(
			'id'          => '_dozent_product',
			//'wrapper_class' => 'show_if_simple',
			'label'       => __( 'For Dozent LMS', 'dozent' ),
			'description' => __( 'This checkmark ensure that this product has course(s) to sell via this product.',
				'dozent' ),
			'default'     => 'no',
		);

		return $types;
	}

	public function save_wc_product_meta( $post_ID ) {
		$is_dozent_product = dozent_input_text( '_dozent_product' );

		if ( $is_dozent_product === 'on' ) {
			update_post_meta( $post_ID, '_dozent_product', 'yes' );
		} else {
			delete_post_meta( $post_ID, '_dozent_product' );
		}
	}

	function add_dozent_courses_product_data_tab( $product_data_tabs ) {
		$product_data_tabs['dozent_courses'] = array(
			'label'    => __( 'Dozent Courses', 'dozent' ),
			'target'   => 'dozent_courses_data_panel',
			'priority' => 10,
		);

		return $product_data_tabs;
	}

	public function dozent_courses_data_panel() {
		include DOZENT_ABSPATH . 'integration/woocommerce/views/courses-data-panel.php';
	}

	public function attach_courses_to_product( $product_ID ) {

		//Attach or detach course to product only from data panel
		$data_source = dozent_input_text( 'dozent_courses_data_panel' );
		if ( $data_source !== 'wc' ) {
			return;
		}

		$course_ids = (array) dozent_input_array_field( 'dozent_attach_course_ids_to_product' );
		$course_ids = array_filter( $course_ids );

		$attached_course_ids = dozent_get_attached_course_ids_to_product( $product_ID );

		if ( dozent_count( $attached_course_ids ) ) {
			$removed_course_ids = array_diff( $attached_course_ids, $course_ids );

			foreach ( $removed_course_ids as $removed_course_id ) {
				delete_post_meta( $removed_course_id, '_attached_product_id' );
				delete_post_meta( $removed_course_id, '_product_by' );
			}
		}

		if ( dozent_count( $course_ids ) ) {
			foreach ( $course_ids as $course_id ) {
				update_post_meta( $course_id, '_attached_product_id', $product_ID );
				update_post_meta( $course_id, '_product_by', 'WooCommerce' );
			}
		}

	}

	/**
	 * Filter course price and return price from the attached WC Product Price
	 *
	 * @since DozentLMS 1.0.0
	 *
	 * @see filter_course_price();
	 *
	 *
	 * @param  float  $price  course price
	 * @param  Course  $course  Course Object
	 *
	 * @return mixed
	 */

	public function filter_course_price( $price, $course ) {
		$course = dozent_get_course( $course );

		if ( $course->is_closed() ) {
			$course_id = $course->get_id();

			$product_id = dozent_get_attached_product_id_by_course( $course_id );

			$product = wc_get_product( $product_id );

			if ( $product ) {
				$price = $product->get_price_html();
			}
		}

		return $price;
	}

	/**
	 * When user click Take this course button from course single page.
	 * make sure user will be redirect to WooCommerce product landing page.
	 *
	 * @since DozentLMS 1.0.0
	 *
	 *
	 * @param $course
	 */

	public function dozent_course_gate( $course ) {
		$course                = dozent_get_course( $course );
		$attached_product_type = dozent_attached_product_type_to_course( $course );

		if ( $attached_product_type === 'WooCommerce' ) {
			$product_id = dozent_get_attached_product_id_by_course( $course->get_id() );

			dozent_redirect( get_the_permalink( $product_id ) );
		}
	}


	/**
	 * Place woocommerce order from the admin panel and sync it with course enrol
	 *
	 * @since DozentLMS 1.0.0
	 *
	 *
	 * @param $order_id
	 */

	public function placing_order_from_admin( $order_id ) {
		if ( ! is_admin() ) {
			return;
		}

		$order = wc_get_order( $order_id );

		foreach ( $order->get_items() as $item ) {
			$product_id  = $item->get_product_id();
			$customer_id = $order->get_customer_id();

			$course_ids = dozent_get_attached_course_ids_to_product( $product_id );

			if ( dozent_count( $course_ids ) ) {
				foreach ( $course_ids as $course_id ) {
					dozent_enrol_course( $course_id, $customer_id, $order_id );
				}
			}

		}
	}


	/**
	 * Course placing order from customer
	 *
	 *
	 * Example usage:
	 *
	 *     placing_order_from_frontend();
	 *
	 * more description
	 * Note: if any
	 *
	 * @since DozentLMS 1.0.0
	 *
	 * @see dozent_get_attached_course_ids_to_product();
	 * @see dozent_enrol_course();
	 *
	 * @param  int  $item_id  Product ID
	 * @param  object  $item  Product
	 * @param  int  $order_id  Order ID
	 *
	 */

	public function placing_order_from_frontend( $item_id, $item, $order_id ) {
		if ( is_admin() ) {
			return;
		}

		$order       = wc_get_order( $order_id );
		$item        = new \WC_Order_Item_Product( $item );
		$product_id  = $item->get_product_id();
		$customer_id = $order->get_customer_id();

		$course_ids = dozent_get_attached_course_ids_to_product( $product_id );

		if ( dozent_count( $course_ids ) ) {
			foreach ( $course_ids as $course_id ) {
				dozent_enrol_course( $course_id, $customer_id, $order_id );
			}
		}
	}

	public function order_status_changed( $order_id, $status_from, $status_to ) {
		$order = wc_get_order( $order_id );

		if ( $order ) {
			if ( $status_to === 'completed' ) {
				$status_to = 'active';
			}

			$enrolments = dozent_get_enrolments_by_order( $order_id );

			if ( dozent_count( $enrolments ) ) {
				foreach ( $enrolments as $enrolment ) {
					$enrolmentModel = new Enrol( $enrolment->ID );
					$enrolmentModel->update_status( $status_to );
				}
			}
		}
	}


	/**
	 * Set new enrolment status from WooCommerce
	 *
	 *
	 * @since DozentLMS 1.0.0
	 *
	 *
	 * @param $status
	 * @param $course
	 * @param $order_id
	 * @param $expired_at
	 *
	 * @return string
	 */

	public function new_enrol_status( $status, $course, $order_id, $expired_at ) {
		$order = wc_get_order( $order_id );

		if ( $order ) {
			$status = $order->get_status();
		}

		return $status;
	}

	/**
	 * Add earning data and split the earning between instructors
	 *
	 *
	 * @since DozentLMS 1.0.0
	 *
	 *
	 * @param $item_id
	 * @param $item
	 * @param $order_id
	 */
	public function add_earning_data( $item_id, $item, $order_id ) {
		$enable_earning = (bool) dozent_get_option( 'enable_dozent_earning' );
		if ( ! $enable_earning ) {
			return;
		}

		global $wpdb;
		$item = new \WC_Order_Item_Product( $item );

		$product_id = $item->get_product_id();
		$course_ids = dozent_get_attached_course_ids_to_product( $product_id );

		if ( dozent_count( $course_ids ) ) {

			$total_courses    = count( $course_ids );
			$total_price      = $item->get_total();
			$per_course_price = $total_price;

			/**
			 * Divide Split course price into all courses
			 * so each attached course will get the earning based on equal amount
			 */

			if ( $per_course_price > 0 && $total_courses > 1 ) {
				$per_course_price = $total_price / $total_courses;
			}

			$enable_fees_deducting = (bool) dozent_get_option( 'dozent_earning_fees.enable_fees_deducting' );
			$fees_name             = dozent_get_option( 'dozent_earning_fees.fees_name' );
			$deduct_fees_rate      = dozent_get_option( 'dozent_earning_fees.fees_amount' );
			$fees_type             = dozent_get_option( 'dozent_earning_fees.fees_type' );

			$fees_deduct_data = array();

			if ( $enable_fees_deducting ) {
				$fees_amount = $deduct_fees_rate;

				if ( $deduct_fees_rate > 0 ) {
					if ( $fees_type === 'percent' ) {
						$fees_amount = ( $total_price * $deduct_fees_rate ) / 100;
					}

					if ( $fees_amount > 0 && $total_courses > 1 ) {
						$fees_amount = $fees_amount / $total_courses;
					}

					//If fis amount fixed, it will deduct direct $fees_amount

					$per_course_price = $per_course_price - $fees_amount;
				}

				$fees_deduct_data = array(
					'deduct_fees_rate'   => $deduct_fees_rate,
					'deduct_fees_amount' => $fees_amount,
					'deduct_fees_name'   => $fees_name,
					'deduct_fees_type'   => $fees_type,
				);
			}

			$instructor_rate = dozent_get_option( 'earning_instructor_commission' );
			$admin_rate      = dozent_get_option( 'earning_admin_commission' );

			$instructor_amount = 0;
			if ( $instructor_rate > 0 ) {
				$instructor_amount = ( $per_course_price * $instructor_rate ) / 100;
			}

			$admin_amount = 0;
			if ( $admin_rate > 0 ) {
				$admin_amount = ( $per_course_price * $admin_rate ) / 100;
			}

			foreach ( $course_ids as $course_id ) {

				$user_id      = $wpdb->get_var( "SELECT post_author FROM {$wpdb->posts} WHERE ID = {$course_id} " );
				$order_status = $wpdb->get_var( "SELECT post_status FROM {$wpdb->posts} WHERE ID = {$order_id} " );

				$order_status = str_replace( 'wc-', '', strtolower( $order_status ) );

				$earning_data = array(
					'user_id'                   => $user_id,
					'course_id'                 => $course_id,
					'order_id'                  => $order_id,
					'order_status'              => $order_status,
					'total_courses_under_order' => $total_courses,
					'course_price_total'        => $total_price,
					'per_course_price'          => $per_course_price,
					'instructor_amount'         => $instructor_amount,
					'instructor_rate'           => $instructor_rate,
					'admin_amount'              => $admin_amount,
					'admin_rate'                => $admin_rate,
					'commission_type'           => 'percent',
					'process_by'                => 'WooCommerce',
					'created_at'                => date( 'Y-m-d H:i:s', dozent_time() ),
				);

				$earning_data['raw_data'] = json_encode( $earning_data );

				$earning_data = apply_filters( 'dozent_new_earning_data',
					array_merge( $earning_data, $fees_deduct_data ) );

				$wpdb->insert( $wpdb->prefix . 'dozent_earnings', $earning_data );
			}
		}

	}

	/**
	 * Change earning status of related to WooCommerce order
	 *
	 * @since DozentLMS 1.0.0
	 *
	 *
	 * @param $order_id
	 * @param $status_from
	 * @param $status_to
	 */

	public function earning_data_status_change( $order_id, $status_from, $status_to ) {
		global $wpdb;

		$earning_data = (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->dozent_earnings} WHERE order_id = {$order_id};" );

		if ( $earning_data ) {
			$wpdb->update( $wpdb->dozent_earnings , [ 'order_status' => $status_to ], [ 'order_id' => $order_id ] );
		}
	}

}

Methods