Untitled
unknown
plain_text
2 years ago
38 kB
8
Indexable
public function salesking_register_order_calculate_earnings($order_id, $posted_data = array(), $order = array()){
// check order post type / compatibility with plugins
$type = get_post_type($order_id);
if ($type !== 'shop_order'){
$order = wc_get_order($order_id);
if (!$order){
$order_id = intval($order_id)-1;
}
}
// sanity
// if order already has an earning, then clearly the earnings have been calculated
$order = wc_get_order($order_id);
if ($order){
$earning_id_check = $order->get_meta('salesking_earning_id');
if (!empty($earning_id_check)){
$order->update_meta_data('_salesking_calculated_earnings', 'yes');
$order->save();
}
}
// for marketking multivendor orders, skip, because we calculate for each order
if (defined('MARKETKINGCORE_DIR')){
if (marketking()->is_multivendor_order($order_id)){
$order->update_meta_data('_salesking_calculated_earnings', 'yes');
$order->save();
}
}
// check it has not already been calculated
if ($order->get_meta('_salesking_calculated_earnings') !== 'yes'){
// Determine if this order should be assigned to any agent, by checking all assignment possibilities
/*
5 possibilities:
- customer is assigned to agent and places order
- a user places an order and uses agent coupon
- agent uses shop as customer to place order on behalf of customer, customer only pays it
- cart sharing:
same as coupons, user gets assigned to agent + order appears as placed by customer
- customer shops with affiliate cookie
*/
if ($order){
$order->update_meta_data('_salesking_calculated_earnings', 'yes');
$order->save();
$assign_customer_to_agent = true; // assign the customer to the agent found, or not
// STEP 1: we find the assigned agent for this order
$order_assigned_agent = 0;
$customer_id = $order->get_customer_id();
// if all agents can shop for all customers, then customer's assigned agent no longer takes priority
if (intval(get_option( 'salesking_all_agents_shop_all_customers_setting', 0 )) === 0 || ! apply_filters('salesking_agent_shop_customer_use_commission', true)){
// CUSTOMER ALREADY ASSIGNED
$customer_agent = get_user_meta($customer_id,'salesking_assigned_agent', true);
if (!empty($customer_agent)){
if ($this->is_agent($customer_agent)){
$order_assigned_agent = $customer_agent;
}
}
if ($order_assigned_agent === 0){
$customer_agent = get_user_meta($customer_id,'salesking_agent', true);
if (!empty($customer_agent)){
if ($this->is_agent($customer_agent)){
$order_assigned_agent = $customer_agent;
}
}
}
if (defined('B2BKING_DIR') || defined('B2BKINGCORE_DIR')){
// Search customer group
if ($order_assigned_agent === 0){
$b2b_user = get_user_meta($customer_id,'b2bking_b2buser', true);
if ($b2b_user === 'yes'){
$b2b_group = get_user_meta($customer_id,'b2bking_customergroup', true);
if (!empty($b2b_group)){
$group_agent = get_post_meta($b2b_group,'salesking_assigned_agent', true);
if (!empty($group_agent)){
if ($this->is_agent($group_agent)){
$order_assigned_agent = $group_agent;
}
}
}
}
}
}
}
// if the customer is an agent themselves
if ($this->is_agent($customer_id)){
// if agents earn commission on their own orders
if (intval(get_option( 'salesking_agents_own_orders_commission_setting', 0 )) === 1){
// assigned agent is self
$order_assigned_agent = $customer_id;
}
}
// COUPONS // if no agent yet, keep searching.
if (apply_filters('salesking_commissions_use_coupons', true)){
if ($order_assigned_agent === 0){
foreach( $order->get_coupon_codes() as $coupon_code) {
$coupon = new WC_Coupon($coupon_code);
$coupon_id = $coupon->get_id();
// check agent
$coupon_agent = get_post_meta($coupon_id,'salesking_agent', true);
if (!empty($coupon_agent)){
if ($this->is_agent($coupon_agent)){
$order_assigned_agent = $coupon_agent;
$assign_customer_to_agent = apply_filters('salesking_assign_customer_to_agent_coupon', $assign_customer_to_agent, $coupon_agent, $order);
}
}
}
}
}
// AGENT USED SHOP AS CUSTOMER // if no agent yet, keep searching.
if (apply_filters('salesking_commissions_use_shop_as_customer', true)){
if ($order_assigned_agent === 0){
if ($this->check_user_is_agent_with_access()){
$agent_id = $this->get_current_agent_id();
$order_assigned_agent = $agent_id;
$assign_customer_to_agent = apply_filters('salesking_assign_customer_to_agent_shopping_as_customer', $assign_customer_to_agent, $order);
}
}
}
// SEARCH CART SHARING COOKIE OR AFFILIATE COOKIE
if (apply_filters('salesking_commissions_use_cookies', true)){
if ($order_assigned_agent === 0){
if (isset($_COOKIE['salesking_affiliate_cookie'])){
$affiliate_cookie = sanitize_text_field($_COOKIE['salesking_affiliate_cookie']);
// search agentid
$agent = get_users(array(
'meta_key' => 'salesking_agentid',
'meta_value' => $affiliate_cookie,
'meta_compare' => '=',
'fields' => 'ids',
));
if (count($agent) === 1){
$order_assigned_agent = $agent[0];
}
}
}
}
if ($order_assigned_agent === 0){
if (intval(get_option( 'salesking_all_agents_shop_all_customers_setting', 0 ))=== 1 && apply_filters('salesking_agent_shop_customer_use_commission', true)){
// CUSTOMER ALREADY ASSIGNED
$customer_id = $order->get_customer_id();
$customer_agent = get_user_meta($customer_id,'salesking_assigned_agent', true);
if (!empty($customer_agent)){
if ($this->is_agent($customer_agent)){
$order_assigned_agent = $customer_agent;
}
}
if ($order_assigned_agent === 0){
$customer_agent = get_user_meta($customer_id,'salesking_agent', true);
if (!empty($customer_agent)){
if ($this->is_agent($customer_agent)){
$order_assigned_agent = $customer_agent;
}
}
}
if (defined('B2BKING_DIR') || defined('B2BKINGCORE_DIR')){
// Search customer group
if ($order_assigned_agent === 0){
$b2b_user = get_user_meta($customer_id,'b2bking_b2buser', true);
if ($b2b_user === 'yes'){
$b2b_group = get_user_meta($customer_id,'b2bking_customergroup', true);
if (!empty($b2b_group)){
$group_agent = get_post_meta($b2b_group,'salesking_assigned_agent', true);
if (!empty($group_agent)){
if ($this->is_agent($group_agent)){
$order_assigned_agent = $group_agent;
}
}
}
}
}
}
}
}
if (isset($_POST['customer_user'])){
if (intval($order_assigned_agent) === 0){
$order_assigned_agent = $_POST['customer_user'];
// check if this user has an agent, and if so, set the user's agent
$customer_agent = get_user_meta($order_assigned_agent,'salesking_assigned_agent', true);
if (!empty($customer_agent)){
if (intval($customer_agent) !== 0){
$order_assigned_agent = $customer_agent;
}
}
}
}
$order_assigned_agent = apply_filters('salesking_agent_assigned_order', $order_assigned_agent, $order);
// check, must be agent
if (!$this->is_agent($order_assigned_agent)){
$order_assigned_agent = 0;
}
// cancel function if this order does not have an agent
if ($order_assigned_agent !== 0 or intval(get_option( 'salesking_individual_agents_auto_commissions_setting', 0 )) === 1){
// here let's have an option via FILTER to always set the assigned agent to 0 (so that individual agent rules are not affected by for example an agent giving a coupon or affilaite link)
if (apply_filters('salesking_assigned_agent_order_never', false)){
$order_assigned_agent = 0;
}
$agent_id = $order_assigned_agent;
// STEP 2: We check and set who placed the order
$placed_by = 0;
if ($this->check_user_is_agent_with_access()){
$agent_id = $this->get_current_agent_id();
if ($agent_id !== $order->get_customer_id()){
$placed_by = 'placed_by_agent';
$order->update_meta_data('salesking_order_placed_by', $agent_id);
} else {
$placed_by = 'placed_by_customer';
}
} else {
$placed_by = 'placed_by_customer';
}
$order->update_meta_data('salesking_order_placed_type', $placed_by);
$order->save();
// Step 3: Assign customer to agent if not already assigned + assign order to agent
// (only if we're not applying commission by product for individual agents)
if ($order_assigned_agent !== 0){
if ($assign_customer_to_agent){
if (apply_filters('salesking_assign_customer_to_agent', true)){
update_user_meta($customer_id, 'salesking_assigned_agent', $order_assigned_agent);
}
}
$order->update_meta_data('salesking_assigned_agent', $order_assigned_agent);
$agent_obj = new WP_User($order_assigned_agent);
$customer_obj = new WP_User($customer_id);
$agent_name = $agent_obj->first_name.' '.$agent_obj->last_name;
$customer_name = $customer_obj->first_name.' '.$customer_obj->last_name;
if ($agent_name !== $customer_name){
$order->update_meta_data('salesking_assigned_agent_name', $agent_name);
$agent_id_code = get_user_meta($order_assigned_agent, 'salesking_agentid', true);
$order->update_meta_data('salesking_assigned_agent_code', $agent_id_code);
do_action('salesking_assign_agent_code_order', $order_id, $order_assigned_agent);
} else {
$agent_name_id = get_user_meta($customer_id,'salesking_assigned_agent', true);
$agent_obj = new WP_User($agent_name_id);
$agent_name = $agent_obj->first_name.' '.$agent_obj->last_name;
$order->update_meta_data('salesking_assigned_agent_name', $agent_name);
$agent_id_code = get_user_meta($agent_name_id, 'salesking_agentid', true);
$order->update_meta_data('salesking_assigned_agent_code', $agent_id_code);
do_action('salesking_assign_agent_code_order', $order_id, $agent_name_id);
}
$order->save();
}
// sanity check, user cannot be his own agent
if (intval(get_option( 'salesking_agents_own_orders_commission_setting', 0 )) === 0){
if (intval($order_assigned_agent) === get_current_user_id()){
$order_assigned_agent = 0;
$agent_id = 0;
}
if (intval($order_assigned_agent) === $customer_id or intval($agent_id) === $customer_id){
$order_assigned_agent = 0;
$agent_id = 0;
}
}
if (empty($order_assigned_agent)){
$order_assigned_agent = 0;
$agent_id = 0;
}
if (intval($customer_id) === 0){
if (isset($_POST['customer_user'])){
$customer_id = sanitize_text_field($_POST['customer_user']);
}
}
// Step 4: Now that we have the agent of the order, we must calculate earnings
// We begin by getting all rules applicable to this agent
$agent_group_id = get_user_meta($agent_id,'salesking_group', true);
if ($order_assigned_agent !== 0){
$rules = $this->get_all_agent_rules($agent_id);
} else {
$rules = $this->get_all_agent_rules($agent_id, 'yes'); // all rules for all agents
}
$rules = $this->filter_which_rules_apply_to_customer($rules, $customer_id);
$rules = $this->filter_which_rules_apply_to_order($rules, $order_id, $customer_id, $agent_id);
// Step 5: Calculate earnings
// 5.1 check if there is a different commission for above price
// apply that commission indifferent of commission rules
$agent_id = $order_assigned_agent;
$above_original_price = 0;
$above_original_price_commission = 0;
$below_original_price = 0;
// check if discounts should be taken from agent's commission
if (intval(get_option( 'salesking_take_out_discount_agent_commission_setting', 1 )) === 1 && $order_assigned_agent !== 0){
// if order is placed by agent on behalf of customer, calculate commission on edited increased price
if ($this->check_user_is_agent_with_access() || $this->agent_can_edit_price_for_themselves()){
$agent_id = $this->get_current_agent_id();
if ($agent_id !== $order->get_customer_id() || $this->agent_can_edit_price_for_themselves()){
// Iterating through each "line" items in the order
foreach ($order->get_items() as $item_id => $item ) {
$original_price = $item->get_meta('_salesking_original_price');
$set_price = $item->get_meta('_salesking_set_price');
$quantity = $item->get_quantity();
if (!empty($original_price) && !empty($set_price)){
$original_price = floatval($original_price);
$set_price = floatval($set_price);
if ($set_price < $original_price){
// price difference
$below_original_price += ($original_price-$set_price)*$quantity;
}
}
}
}
}
}
if (intval(get_option( 'salesking_different_commission_price_increase_setting', 1 )) === 1 && $order_assigned_agent !== 0){
// if order is placed by agent on behalf of customer, calculate commission on edited increased price
if ($this->check_user_is_agent_with_access() || $this->agent_can_edit_price_for_themselves()){
$agent_id = $this->get_current_agent_id();
if ($agent_id !== $order->get_customer_id() || $this->agent_can_edit_price_for_themselves()){
// Iterating through each "line" items in the order
foreach ($order->get_items() as $item_id => $item ) {
$original_price = $item->get_meta('_salesking_original_price');
$set_price = $item->get_meta('_salesking_set_price');
$quantity = $item->get_quantity();
if (!empty($original_price) && !empty($set_price)){
$original_price = floatval($original_price);
$set_price = floatval($set_price);
if ($set_price > $original_price){
// price difference
$above_original_price += ($set_price-$original_price)*$quantity;
$above_original_price_commission += ($set_price-$original_price)*$quantity*get_option('salesking_different_commission_price_increase_number_setting', 100 )/100;
}
}
}
}
}
}
// 5.2 now apply rules for the rest (item price < increased price by agent)
$commission_rules_total = 0;
$commission_log = array();
$rules_apply_log = array();
$commission_by_agent = array(); // here we hold agent ID and commission in the case of individual agent rules
foreach ($order->get_items() as $item_id => $item ) {
// Get the WC_Order_Item_Product object properties in an array
$item_data = $item->get_data();
if ($item['quantity'] > 0) {
// get the WC_Product object
$product_id = $item['product_id'];
if (isset($item['variation_id'])){
if (intval($item['variation_id']) !== 0){
$product_id = $item['variation_id'];
}
}
$rules_that_apply_to_product = $this->filter_which_rules_apply_to_product($rules, $order_id, $customer_id, $product_id);
require_once ( SALESKING_DIR . 'includes/class-salesking-helper.php' );
$helper = new Salesking_Helper();
$rules_that_apply_to_product = $helper->get_rules_apply_priority($rules_that_apply_to_product);
$rules_apply_log[]=array('Product ID: '.$product_id, 'All rules: '.serialize($rules), 'Rules that apply: '.serialize($rules_that_apply_to_product));
if (!empty($rules_that_apply_to_product)){
// get the calculation basis for the product (amount < increased price if setting is enabled)
$original_price = $item->get_meta('_salesking_original_price');
$set_price = $item->get_meta('_salesking_set_price');
if (floatval($set_price) === floatval(0) && $set_price !== ''){
continue; // no commission on this item, if item price is 0
}
$quantity = $item->get_quantity();
if (!empty($original_price)){
if (intval(get_option( 'salesking_commissions_calculated_including_tax_setting', 1 )) === 1){
//$calculation_basis = floatval($original_price) * $quantity;
// calculate price without tax based on original price
$price_without_tax_edited_price = round($item->get_total(), 2) + round($item->get_total_tax(), 2);
$ratio = $price_without_tax_edited_price / $set_price;
$price_without_tax_original_price = $ratio * floatval($original_price) * $quantity;
$calculation_basis = $price_without_tax_original_price;
} else {
// calculate price without tax based on original price
$price_without_tax_edited_price = round($item->get_total(), 2);
// change in v 1.5.03 it used to be $set_price only
$ratio = $price_without_tax_edited_price / ($set_price*$quantity);
$price_without_tax_original_price = $ratio * floatval($original_price) * $quantity;
$calculation_basis = $price_without_tax_original_price;
}
} else {
$item_total = round($item->get_total(), 2); // Get the item line total discounted
$item_total_tax = round($item->get_total_tax(), 2); // Get the item line total tax discounted
if (intval(get_option( 'salesking_commissions_calculated_including_tax_setting', 1 )) === 1){
$calculation_basis = $item_total + $item_total_tax;
} else {
$calculation_basis = $item_total;
}
}
if (intval(get_option( 'salesking_commissions_calculated_based_profit_setting', 0 )) === 1){
// overwrite completely, exclusively based on profit, tax irrelevant
if ( class_exists( 'Alg_WC_Cost_of_Goods' ) ) {
if (empty($original_price) or floatval($set_price) < floatval($original_price)){
$price_without_tax = round($item->get_total(), 2);
} else {
$price_without_tax_edited_price = round($item->get_total(), 2);
$ratio = $price_without_tax_edited_price / ($set_price*$quantity);
$price_without_tax = $ratio * floatval($original_price) * $quantity;
}
$cost_id = $product_id;
if (isset($item['variation_id'])){
if (intval($item['variation_id']) !== 0){
$cost_id = $item['variation_id'];
}
}
$product_cost_temp = alg_wc_cog()->core->products->get_product_cost( $cost_id ) * $quantity;
$product_cost = apply_filters('salesking_product_cost', $product_cost_temp, $cost_id, alg_wc_cog()->core->products->get_product_cost( $cost_id ), $quantity, $order);
$profit = $price_without_tax - $product_cost;
$calculation_basis = $profit;
}
}
$fixed_commission_amount = $this->get_commission_amount($rules_that_apply_to_product, $calculation_basis, 'fixed', $quantity);
$percentage_commission_amount = $this->get_commission_amount($rules_that_apply_to_product, $calculation_basis, 'percentage', $quantity);
if (intval(get_option( 'salesking_individual_agents_auto_commissions_setting', 0 )) === 1){
// who is the agent of the applied rule (for individual agent commission rules)
$fixed_rules_agent = $this->get_commission_amount_rules_agent($rules_that_apply_to_product, $calculation_basis, 'fixed', $quantity);
$percentage_rules_agent = $this->get_commission_amount_rules_agent($rules_that_apply_to_product, $calculation_basis, 'percentage', $quantity);
if (!isset($commission_by_agent[$fixed_rules_agent])){
$commission_by_agent[$fixed_rules_agent] = $fixed_commission_amount;
} else {
$commission_by_agent[$fixed_rules_agent] += $fixed_commission_amount;
}
if (!isset($commission_by_agent[$percentage_rules_agent])){
$commission_by_agent[$percentage_rules_agent] = $percentage_commission_amount;
} else {
$commission_by_agent[$percentage_rules_agent] += $percentage_commission_amount;
}
}
$item_commission = $fixed_commission_amount + $percentage_commission_amount;
$commission_rules_total += $item_commission;
// log into database for reference / debugging purposes
$item_log = array('Product ID: '.$product_id, 'Fixed commission: '.$fixed_commission_amount, 'Percentage commission: '.$percentage_commission_amount, 'Total commission: '.$item_commission, 'Rules that apply: '.serialize($rules_that_apply_to_product), 'Calculation basis value: '.$calculation_basis);
$commission_log[] = $item_log;
}
}
}
if ($order_assigned_agent !== 0){
// 5.3 apply rules that apply once per order
$rules_that_apply_once = $this->filter_which_rules_apply_once($rules, $order_id, $customer_id, $product_id);
require_once ( SALESKING_DIR . 'includes/class-salesking-helper.php' );
$helper = new Salesking_Helper();
$rules_that_apply_once = $helper->get_rules_apply_priority($rules_that_apply_once);
if (!empty($rules_that_apply_once)){
// get order total calculation basis
if (intval(get_option( 'salesking_commissions_calculated_including_tax_setting', 1 )) === 1){
$calculation_basis = $order->get_total();
} else {
$calculation_basis = $order->get_total() - $order->get_total_tax();
}
// check if any items have increased price, and if they do, set the calculation basis to original price
$original_total = 0;
$items_increased_price = 'no';
foreach ($order->get_items() as $item_id => $item ) {
// Get the WC_Order_Item_Product object properties in an array
$item_data = $item->get_data();
if ($item['quantity'] > 0) {
// get the calculation basis for the product (amount < increased price if setting is enabled)
$original_price = $item->get_meta('_salesking_original_price');
$quantity = $item->get_quantity();
$set_price = $item->get_meta('_salesking_set_price');
if (!empty($original_price) && $original_price !== $set_price && floatval($set_price) > floatval($original_price)){
$items_increased_price = 'yes';
if (intval(get_option( 'salesking_commissions_calculated_including_tax_setting', 1 )) === 1){
$original_total += floatval($original_price) * $quantity;
} else {
// calculate price without tax based on original price
$price_without_tax_edited_price = round($item->get_total(), 2);
$ratio = $price_without_tax_edited_price / $set_price;
$price_without_tax_original_price = $ratio * floatval($original_price) * $quantity;
$original_total += $price_without_tax_original_price;
}
}
}
}
if ($items_increased_price === 'yes'){
// reset calculation basis depending on original total
$calculation_basis = $original_total;
}
if (intval(get_option( 'salesking_commissions_calculated_based_profit_setting', 0 )) === 1){
// overwrite completely, exclusively based on profit, tax irrelevant
if ( class_exists( 'Alg_WC_Cost_of_Goods' ) ) {
// ignore shipping and tax
$total_cost = 0;
$total_price = 0;
// first calculate all products cost
foreach ($order->get_items() as $item_id => $item ) {
if ($item['quantity'] > 0) {
$product_id = $item['product_id'];
$cost_id = $product_id;
if (isset($item['variation_id'])){
if (intval($item['variation_id']) !== 0){
$cost_id = $item['variation_id'];
}
}
$product_cost_temp = alg_wc_cog()->core->products->get_product_cost( $cost_id ) * $item['quantity'];
$cost = apply_filters('salesking_product_cost', $product_cost_temp, $cost_id, alg_wc_cog()->core->products->get_product_cost( $cost_id ), $item['quantity'], $order);
$total_cost += $cost;
$original_price = $item->get_meta('_salesking_original_price');
if (!empty($original_price) && $original_price !== $set_price && floatval($set_price) > floatval($original_price)){
$total_price += floatval($original_price) * $quantity;
} else {
$total_price += round($item->get_total(), 2) * $quantity;
}
}
}
$total_profit = $total_price - $total_cost;
$calculation_basis = $total_profit;
}
}
$calculation_basis = apply_filters('salesking_custom_calculation_basis', $calculation_basis, $order);
$fixed_commission_amount = $this->get_commission_amount_once($rules_that_apply_once, $calculation_basis, 'fixed');
$percentage_commission_amount = $this->get_commission_amount_once($rules_that_apply_once, $calculation_basis, 'percentage');
$item_commission = $fixed_commission_amount + $percentage_commission_amount;
$commission_rules_total += $item_commission;
}
}
$commission_rules_total = round($commission_rules_total, 2);
$above_original_price = round($above_original_price, 2);
$below_original_price = round($below_original_price, 2);
$above_original_price_commission = round($above_original_price_commission, 2);
// Step 6: Finally create and set earnings
$all_earnings_total = round( ($above_original_price_commission + $commission_rules_total - $below_original_price), 2); //calculate all here
// reference / log
$order->update_meta_data('commission_log_before', $commission_log);
$order->update_meta_data('rules_apply_log_before', $rules_apply_log);
if ($all_earnings_total > apply_filters('salesking_earnings_total_threshold', 0 )){
// Create transaction
$earning = array(
'post_title' => sanitize_text_field(esc_html__('Earning','salesking')),
'post_status' => 'publish',
'post_type' => 'salesking_earning',
'post_author' => 1,
);
$earning_post_id = wp_insert_post($earning);
// reference / log
update_post_meta($earning_post_id, 'commission_log', $commission_log);
update_post_meta($earning_post_id, 'rules_apply_log', $rules_apply_log);
// set meta
update_post_meta($earning_post_id, 'time', time());
update_post_meta($earning_post_id, 'order_id', $order_id);
update_post_meta($earning_post_id, 'customer_id', $order->get_customer_id());
update_post_meta($earning_post_id, 'order_status', $order->get_status());
if ($agent_id !== 0){
update_post_meta($earning_post_id, 'agent_id', $agent_id);
} else {
// get a first agent
if ($order_assigned_agent === 0){
unset($commission_by_agent[0]);
$first_agent = array_key_first($commission_by_agent);
update_option('earning_key_first', $first_agent);
update_post_meta($earning_post_id,'agent_id', array_key_first($commission_by_agent)); // first agent is the one with the commissions
update_post_meta($earning_post_id,'individual_agents_earnings', 'yes'); // first agent is the one with the commissions
}
}
// create transaction as pending if the agent did collect extra over original price
if ($above_original_price > 0){
update_post_meta($earning_post_id, 'above_original_price', $above_original_price);
update_post_meta($earning_post_id, 'above_original_price_commission', $above_original_price_commission);
}
if ($below_original_price > 0){
update_post_meta($earning_post_id, 'below_original_price', $below_original_price);
}
if ($commission_rules_total > 0){
update_post_meta($earning_post_id, 'commission_rules_total', $commission_rules_total);
}
$order->update_meta_data('salesking_earning_id', $earning_post_id);
update_post_meta($earning_post_id, 'salesking_commission_total', $all_earnings_total);
if ($order_assigned_agent === 0){
// first agent in commission by agent var
update_post_meta($earning_post_id, 'salesking_commission_total', $commission_by_agent[array_key_first($commission_by_agent)]);
unset($commission_by_agent[array_key_first($commission_by_agent)]);
$agents_of_earning = array();
foreach ($commission_by_agent as $agent_id => $commission_value){
update_post_meta($earning_post_id, 'parent_agent_id_'.$agent_id, $agent_id);
update_post_meta($earning_post_id, 'parent_agent_id_'.$agent_id.'_earnings', $commission_value);
array_push($agents_of_earning, $agent_id);
}
} else {
// Step 7: We must check if current agent is subagent, -> if any of this should go to parent account
// get all earnings rules that apply to subagent
if (apply_filters('salesking_calculation_apply_step_7', true)){
$rules = $this->filter_which_rules_are_earnings_rules($rules);
$subagent_id = $agent_id;
// if user is indeed a subagent (has a parent) // recursive, all parents up the chain
$parent_agent = get_user_meta($subagent_id,'salesking_parent_agent', true);
$agents_of_earning = array();
$all_earnings_total_original = $all_earnings_total;
$i = 1;
$max_agents = apply_filters('salesking_max_parent_agents_commission', 1000000);
$all_earnings_total = apply_filters('salesking_parent_agent_calculation_basis', $all_earnings_total, $order);
while (!empty($parent_agent) && $i <= $max_agents){
array_push($agents_of_earning, $parent_agent);
/*
CHANGE SALESKING 1.3.0
Calculation now based on PARENT RULES
START
*/
$parentrules = $this->get_all_agent_rules($parent_agent);
$parentrules = $this->filter_which_rules_are_earnings_rules($parentrules);
$parentrules = $this->filter_which_earnings_rules_apply($parentrules, $subagent_id);
// replaced $parent_earnings = $this->get_parent_total_earnings($rules, $all_earnings_total);
$parent_earnings = $this->get_parent_total_earnings($parentrules, $all_earnings_total);
/* CHANGE 1.3.0 END */
if (intval(get_option( 'salesking_substract_subagent_earnings_agent_setting', 0 )) === 1){
/* example order was 20000, with 10% parent ag com
Normally it would go to agent 1 = 2000, ag 2 = 200, ag 3 = 20
here we must adjust so that for 3 agents we end up with agent 1 = 1800, agent 2 = 180, agent 3 = 20
*/
// if first agent, remove from original commission
if ($i === 1){
$substracted = $all_earnings_total_original - $parent_earnings;
update_post_meta($earning_post_id, 'salesking_commission_total', $substracted);
} else {
// subsequent agents
$substracted = $all_earnings_total - $parent_earnings;
update_post_meta($earning_post_id, 'parent_agent_id_'.$subagent_id.'_earnings', $substracted);
}
}
update_post_meta($earning_post_id, 'parent_agent_id_'.$parent_agent, $parent_agent);
update_post_meta($earning_post_id, 'parent_agent_id_'.$parent_agent.'_earnings', $parent_earnings);
// if there is any rule based on "single value", then always use all_earnings_total_original, do not cascade values
if ($this->have_single_value_earnings_rules($parentrules)){
// do not cascade values
} else {
$all_earnings_total = $parent_earnings;
}
$subagent_id = $parent_agent;
$parent_agent = get_user_meta($subagent_id,'salesking_parent_agent', true);
$i++;
}
}
}
update_post_meta($earning_post_id, 'created_in', 'frontend_register_order');
update_post_meta($earning_post_id, 'agents_of_earning', $agents_of_earning);
// Step 8: Apply TOTAL GROUP Rules (e.g. change agent group on threshold reached)
// check if there are any group rules that apply to this agent's group
$group_rules_applicable = $this->get_group_rules($agent_group_id);
// foreach rule, check if the condition is met, and then apply it
foreach ($group_rules_applicable as $group_rule_id){
$howmuch = get_post_meta($group_rule_id,'salesking_rule_howmuch', true);
$newgroup = get_post_meta($group_rule_id, 'salesking_rule_who', true);
$newgroup_id = explode('_', $newgroup)[1];
$condition = get_post_meta($group_rule_id, 'salesking_rule_applies', true);
$total_orders_amount = $total_agent_commissions = 0;
$group_rules_args = apply_filters('salesking_group_rules_args', array(
'post_type' => 'salesking_earning',
'numberposts' => -1,
'post_status' => 'any',
'fields' => 'ids',
'meta_key' => 'agent_id',
'meta_value' => $agent_id,
), $agent_id);
// get total agent commissions
$earnings = get_posts( $group_rules_args );
foreach ($earnings as $earning_id){
$order_id = get_post_meta($earning_id,'order_id', true);
$orderobj = wc_get_order($order_id);
if ($orderobj !== false){
$earnings_total = get_post_meta($earning_id,'salesking_commission_total', true);
if (!empty($earnings_total) && floatval($earnings_total) !== 0){
$status = $orderobj->get_status();
$order_total = $orderobj->get_total();
if (in_array($status,apply_filters('salesking_earning_completed_statuses', array('completed')))){
$total_agent_commissions+=$earnings_total;
$total_orders_amount += $order_total;
}
if (in_array($status, apply_filters('salesking_group_rules_allowed_statuses', array()))){
$total_agent_commissions+=$earnings_total;
$total_orders_amount += $order_total;
}
}
}
}
$site_time = time()+(get_option('gmt_offset')*3600);
$current_day = date_i18n( 'd', $site_time );
// also get all earnings where this agent is parent
$group_rules_args_parent = apply_filters('salesking_group_rules_args_parent', array(
'post_type' => 'salesking_earning',
'numberposts' => -1,
'post_status' => 'any',
'date_query' => array(
'after' => date('Y-m-d', strtotime('-'.$current_day.' days'))
),
'fields' => 'ids',
'meta_key' => 'parent_agent_id_'.$agent_id,
'meta_value' => $agent_id,
), $agent_id);
$earnings = get_posts( $group_rules_args_parent );
foreach ($earnings as $earning_id){
$order_id = get_post_meta($earning_id,'order_id', true);
$orderobj = wc_get_order($order_id);
if ($orderobj !== false){
$status = $orderobj->get_status();
$earnings_total = get_post_meta($earning_id,'parent_agent_id_'.$agent_id.'_earnings', true);
// check if approved
if (in_array($status,apply_filters('salesking_earning_completed_statuses', array('completed')))){
$total_agent_commissions+=$earnings_total;
}
if (in_array($status, apply_filters('salesking_group_rules_allowed_statuses', array()))){
$total_agent_commissions+=$earnings_total;
}
}
}
$total_orders_amount = apply_filters('salesking_group_monthly_earnings', $total_orders_amount, $total_agent_commissions, $agent_id);
if ($condition === 'earnings_total'){
// calculate agent earnings total
if ($total_agent_commissions >= $howmuch){
// change group
update_user_meta($agent_id,'salesking_group', $newgroup_id);
}
}
if ($condition === 'order_value_total'){
// calculate agent order value total
if ($total_orders_amount >= $howmuch){
// change group
update_user_meta($agent_id,'salesking_group', $newgroup_id);
}
}
}
}
}
do_action('salesking_after_calculated_earnings', $order_id, get_current_user_id());
}
}
if ($order){
$order->save();
}
}Editor is loading...
Leave a Comment