<?php
/**
 * Cost & Reports
 *
 * @package CostReports
 *
 * Plugin Name: Cost & Reports for WooCommerce
 * Plugin URI: https://woocommerce.com/products/cost-reports-woocommerce/
 * Description: Add cost, cost of goods, Markup, create prices and view profit, order and sales reports.
 * Version: 3.6.2
 * Author: Consortia
 * Author URI: http://www.consortia.no/us/
 * Text Domain: woo-calculate-your-price
 * Domain Path: /languages
 *
 * Tested up to: 6.8.2
 * Requires at least: 5.0
 * Requires PHP: 5.6
 * WC requires at least: 3.3
 * WC tested up to: 10.5.1
 *
 * Copyright: © 2018-2026 Consortia AS.
 * License: GNU General Public License v3.0
 * License URI: http://www.gnu.org/licenses/gpl-3.0.html
 * Woo: 5672510:32940bdd46501b19a59c2ac13602345f

 */

define( 'CAS_COST_REPORTS_VS', '3.6.2' );
define( 'CAS_COST_REPORTS_PROD', true );

add_action( 'before_woocommerce_init', function() {
	if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
	}
} );

register_activation_hook( __FILE__, 'cyp_install' );
register_deactivation_hook( __FILE__, 'cyp_deactivate' );


add_action( 'init', function() {
	require_once dirname( __FILE__ ) . '/includes/class-cyp-woo.php';
} );


/**
 * Install
 */
function cyp_install() {

	global $wp_version;

	if ( version_compare( $wp_version, '4.1', '<' ) ) {
		wp_die( 'This plugin require WordPress 4.1 or higher.' );
	}

	$cyp_options_arr = array(
		'cyp_posts_per_page'         => '150',
		'cyp_product_cat'            => '',
		'cyp_autosort'               => '',
		'cyp_default_markup'         => '',
		'cyp_hide_purchase_price'    => '',
		'cyp_hide_cost_of_goods'     => '',
		'cyp_no_stock_management'    => '',
		'cyp_no_autofocus'           => '',
		'cyp_cost_of_goods_field'    => '',
		'cyp_purchase_price_field'   => '',
		'cyp_other_cost_name'        => '',
		'cyp_shipping_cost_field'    => '',
		'cyp_shipping_cost_name'     => '',
		'cyp_hide_shipping_cost'     => '',
		'cyp_show_shipping_cost_tbl' => '',
		'cyp_report_per_page'        => '300',
		'cyp_report_csv_max_count'   => '5000',
		'cyp_good_profit_percent'    => '50',
		'cyp_bad_profit_percent'     => '20',
		'cyp_report_order_refresh'   => '',
		'cyp_table_hide_id_sku'      => '',
		'cyp_custom_field_1'         => '',
		'cyp_custom_field_1_lbl'     => '',
		'cyp_custom_field_2'         => '',
		'cyp_custom_field_2_lbl'     => '',
		'cyp_orders_show_role'       => '',
		'cyp_orders_show_company'    => '',
		'cyp_orders_show_weight'     => '',
		'cyp_products_show_weight'   => '',
		'cyp_custom_1_orders'        => '',
		'cyp_custom_1_products'      => '',
		'cyp_custom_1_customers'     => '',
		'cyp_custom_2_orders'        => '',
		'cyp_custom_2_products'      => '',
		'cyp_custom_2_customers'     => '',
		'cyp_order_date_modified'    => '',
		'cyp_purchase_price_label'   => '',
		'cyp_use_dark_mode'          => '',
	);

	update_option( 'cyp_options', $cyp_options_arr );

	set_transient( 'cyp-admin-notice-activated', true );

	flush_rewrite_rules();
}

/**
 * Deactivate
 *
 * @return void
 */
function cyp_deactivate() {

	flush_rewrite_rules();
}

/**
 * Create submenu in products
 */
function cyp_woocommerce_submenu_page() {

	add_submenu_page(
		'woocommerce',
		__( 'Cost & Reports', 'woo-calculate-your-price' ),
		__( 'Cost & Reports', 'woo-calculate-your-price' ),
		'manage_woocommerce',
		'crw',
		'cyp_products_page',
		30
	);

}
add_action( 'admin_menu', 'cyp_woocommerce_submenu_page' );

/**
 * Get Bulk Table Editor main page
 */
function cyp_products_page() {

	if ( class_exists( 'WooCommerce' ) ) {
		/**
		 * Get Cost & Reports main page
		 * 
		 * @since 2.0.1
		 */
		do_action( 'cyp_action_get_main_page' );
	}

}

/**
 * Get the main page
 */
function cyp_get_main_page() {

	if ( class_exists( 'WooCommerce' ) ) {

		include_once dirname( __FILE__ ) . '/includes/class-cyp-templates.php';
		global $cyp_templates;
		$cyp_templates = new Cyp_Templates();
		$cyp_templates->cyp_get_selected_view();

	}

}
add_action( 'cyp_action_get_main_page', 'cyp_get_main_page' );


/**
 * Update product (ajax)
 */
function cyp_update_table_rows_ajax_handler() {
	
	check_ajax_referer( 'footer_id', 'nonce' );
	$data = wp_unslash( $_POST );

	cyp_update_table_rows_data( $data );

	delete_transient( 'cyp_json_products' );

	die();
}
add_action( 'wp_ajax_cyp_update_table_rows_data', 'cyp_update_table_rows_ajax_handler' );
add_action( 'wp_ajax_nopriv_cyp_update_table_rows_data', 'cyp_update_table_rows_ajax_handler' );

/**
 * Update products
 * 
 * @param var $data data.
 */
function cyp_update_table_rows_data( $data ) {

	include_once dirname( __FILE__ ) . '/includes/class-cyp-functions.php';
	$functions = new Cyp_Functions();
	
	foreach ( (array) $data['rows'] as $row ) {
		$functions->cyp_update_product( $row );
	}
	
}
add_action( 'cyp_update_table_rows_data_async', 'cyp_update_table_rows_data', 5 );

/**
 * Check for new orders
 */
function cyp_check_for_new_orders() {

	check_ajax_referer( 'footer_id', 'nonce' );
	$data = wp_unslash( $_POST );
	
	$current_new_orders = wc_processing_order_count();

	echo wp_kses( strval( $current_new_orders ), 'post' );
	
	die();

}
add_action( 'wp_ajax_cyp_check_for_new_orders', 'cyp_check_for_new_orders' );
add_action( 'wp_ajax_nopriv_cyp_check_for_new_orders', 'cyp_check_for_new_orders' );

/**
 * Create csv file
 */
function cyp_create_csv_file() {

	include_once dirname( __FILE__ ) . '/includes/class-cyp-functions.php';
	$functions = new Cyp_Functions();

	$functions->cyp_create_csv_export_file();

}
add_action( 'admin_post_return_csv_file', 'cyp_create_csv_file' );

/**
 * Create csv file
 */
function cyp_create_report_csv_file() {

	include_once dirname( __FILE__ ) . '/includes/class-cyp-functions.php';
	$functions = new Cyp_Functions();

	$functions->cyp_create_report_csv_export_file();

}
add_action( 'admin_post_return_report_csv_file', 'cyp_create_report_csv_file' );

/**
 * Delete product (ajax)
 */
function cyp_delete_table_rows_ajax_handler() {
	
	check_ajax_referer( 'footer_id', 'nonce' );
	$data = wp_unslash( $_POST );

	cyp_delete_table_rows_data( $data );

	delete_transient( 'cyp_json_products' );

	die();

}
add_action( 'wp_ajax_cyp_delete_table_rows_data', 'cyp_delete_table_rows_ajax_handler' );
add_action( 'wp_ajax_nopriv_cyp_delete_table_rows_data', 'cyp_delete_table_rows_ajax_handler' );

/**
 * Delete products
 * 
 * @param var $data data.
 */
function cyp_delete_table_rows_data( $data ) {

	include_once dirname( __FILE__ ) . '/includes/class-cyp-functions.php';
	$functions = new Cyp_Functions();

	foreach ( (array) $data['rows'] as $row ) {
		$functions->cyp_move_to_trash( $row );
	}

}
add_action( 'cyp_delete_table_rows_data_async', 'cyp_delete_table_rows_data' );

/**
 * Notice - success
 */
function cyp_admin_notice_message_success( $message ) {
	?>
		<div class="notice notice-success is-dismissible">
			<p><?php echo esc_attr( $message ); ?></p>
		</div>
	<?php
}
add_action( 'admin_notices_message_success', 'cyp_admin_notice_message_success' );


/**
 * Add COGS and purchase price snapshot to order line items on checkout.
 */
function cyp_create_order_line_item( $item, $cart_item_key, $values, $order ) {

	$cyp_options = get_option( 'cyp_options' );

	$cost_of_goods_field  = ! empty( $cyp_options['cyp_cost_of_goods_field'] )
		? $cyp_options['cyp_cost_of_goods_field']
		: '_cost_of_goods';

	$purchase_price_field = ! empty( $cyp_options['cyp_purchase_price_field'] )
		? $cyp_options['cyp_purchase_price_field']
		: '_purchase_price';

	$product_id     = ( $item->get_variation_id() > 0 ) ? $item->get_variation_id() : $item->get_product_id();
	$purchase_price = get_post_meta( $product_id, $purchase_price_field, true );

	// Always read COGS from the product at checkout time (snapshot).
	$cost_of_goods = get_post_meta( $product_id, $cost_of_goods_field, true );

	if ( '' !== $cost_of_goods && null !== $cost_of_goods ) {
		$item->update_meta_data( '_cost_of_goods', wc_format_decimal( $cost_of_goods ) );

		// Optional: also set WooCommerce native COGS if the selected field is '_cogs_value'
		// (only if method exists in the installed Woo version).
		if ( '_cogs_value' === $cost_of_goods_field && is_callable( [ $item, 'set_cogs_value' ] ) ) {
			$item->set_cogs_value( (float) $cost_of_goods );
		}
	}

	if ( '' !== $purchase_price && null !== $purchase_price ) {
		$item->update_meta_data( '_purchase_price', wc_format_decimal( $purchase_price ) );
	}
}
add_action( 'woocommerce_checkout_create_order_line_item', 'cyp_create_order_line_item', 90, 4 );


/**
 * Order items (admin) - set meta on variations
 * 
 * Not in USE - TODO: review if needed or remove.
 */
function cyp_woocommerce_admin_order_item_values( $product, $item, $item_id ) {

	if ( is_null( $product ) || ! $item->is_type( 'line_item' ) || ! is_a( $product, 'WC_Product' ) ) {
		return;
	}

	$cyp_options    = get_option( 'cyp_options' );	
	$cost_of_goods  = ( $cyp_options['cyp_cost_of_goods_field'] ) ? $cyp_options['cyp_cost_of_goods_field'] : '_cost_of_goods';
	$purchase_price = ( $cyp_options['cyp_purchase_price_field'] ) ? $cyp_options['cyp_purchase_price_field'] : '_purchase_price';

	if ( ( $product && $product->is_type( 'variable' ) ) || ( $product && $product->is_type( 'variation' ) ) ) {
		
		$cog_value = get_post_meta( $product->get_id(), $cost_of_goods, true );
		$pp_value  = get_post_meta( $product->get_id(), $purchase_price, true );

		if ( ! empty( $cog_value ) && empty( $item->get_meta( $cost_of_goods ) ) ) {
			wc_add_order_item_meta( $item_id, $cost_of_goods, $cog_value );
		}

		if ( ! empty( $pp_value ) && empty( $item->get_meta( $purchase_price ) ) ) {
			wc_add_order_item_meta( $item_id, $purchase_price, $pp_value );
		}
	
	}

}
//add_filter('woocommerce_admin_order_item_values', 'cyp_woocommerce_admin_order_item_values', 10, 3 );


/**
 * Add COGS snapshot only if not already set on order item.
 * Prevents overwriting historical COGS.
 */
function cyp_add_order_meta_for_line_item( $item_id, $item, $order_id ) {

	if ( ! is_admin() ) {
		return;
	}

	if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) {
		return;
	}

	// Do not override if COGS already exists
	if ( $item->get_meta( '_cost_of_goods', true ) !== '' ) {
		return;
	}

	$cyp_options          = get_option( 'cyp_options' );	
	$purchase_price_field = ! empty( $cyp_options['cyp_purchase_price_field'] ) ? $cyp_options['cyp_purchase_price_field'] : '_purchase_price';
	$cost_of_goods_field  = ! empty( $cyp_options['cyp_cost_of_goods_field'] ) ? $cyp_options['cyp_cost_of_goods_field']	: '_cost_of_goods';

	$product_id = $item->get_product_id();
	if ( ! $product_id ) {
		return;
	}

	$purchase_price = get_post_meta( $product_id, $purchase_price_field, true );
	$current_cost   = '';

	if ( '_cogs_value' === $cost_of_goods_field ) {
		$current_cost = get_post_meta( $product_id, '_cogs_value', true );
	} else {
		$current_cost = get_post_meta( $product_id, $cost_of_goods_field, true );
	}

	$dirty = false;

	// Update COGS value if not empty
	if ( '' !== $current_cost && null !== $current_cost ) {
		$item->update_meta_data( '_cost_of_goods', wc_format_decimal( $current_cost ) );
		$dirty = true;
	}

	// Update purchase price value if not empty
	if ( '' !== $purchase_price && null !== $purchase_price ) {
		$item->update_meta_data( '_purchase_price', wc_format_decimal( $purchase_price ) );
		$dirty = true;
	}

	if ( $dirty ) {
		$item->save();
	}

}
add_action( 'woocommerce_new_order_item', 'cyp_add_order_meta_for_line_item', 10, 3 );


/**
 * Add custom product variation fields.
 *
 * @param var $loop loop var.
 * @param var $variation_data data.
 * @param var $variation variation.
 */
function cyp_add_product_variation_options_pricing( $loop, $variation_data, $variation  ) {

	$cyp_options         = get_option( 'cyp_options' );
	$hide_purchase_price = $cyp_options['cyp_hide_purchase_price'] ? $cyp_options['cyp_hide_purchase_price'] : 'no';
	$hide_cost_of_goods  = $cyp_options['cyp_hide_cost_of_goods'] ? $cyp_options['cyp_hide_cost_of_goods'] : 'no';

	if ( 'no' === $hide_purchase_price ) {
		woocommerce_wp_text_input(
			array(
				'id'       => '_purchase_price[' . $variation->ID . ']',
				'class'    => 'wc_input_price',
				'label'    => __( 'Purchase price', 'woo-calculate-your-price' ),
				'type'     => 'text',
				'value'    => get_post_meta( $variation->ID, '_purchase_price', true ),
			)
		);
	} else {
		woocommerce_wp_hidden_input(
			array(
				'id'      => '_purchase_price[' . $variation->ID . ']',
				'label'   => __( 'Purchase price', 'woo-calculate-your-price' ),
				'type'    => 'number',
				'value'   => get_post_meta( $variation->ID, '_purchase_price', true ),
			)
		);
	}

	woocommerce_wp_hidden_input(
		array(
			'id'        => '_cyp_shipping_cost[' . $variation->ID . ']',
			'label'     => __( 'Shipping cost', 'woo-calculate-your-price' ),
			'type'      => 'number',
			'value'     => get_post_meta( $variation->ID, '_cyp_shipping_cost', true ),
		)
	);

	woocommerce_wp_hidden_input(
		array(
			'id'        => '_other_cost[' . $variation->ID . ']',
			'label'     => __( 'Other cost', 'woo-calculate-your-price' ),
			'type'      => 'number',
			'value'     => get_post_meta( $variation->ID, '_other_cost', true ),
		)
	);

	if ( 'no' === $hide_cost_of_goods ) {
		woocommerce_wp_text_input(
			array(
				'id'        => '_cost_of_goods[' . $variation->ID . ']',
				'class'     => 'wc_input_price',
				'label'     => __( 'Cost of goods', 'woo-calculate-your-price' ),
				'type'      => 'text',
				'value'     => get_post_meta( $variation->ID, '_cost_of_goods', true ),
			)
		);
	} else {
		woocommerce_wp_hidden_input(
			array(
				'id'        => '_cost_of_goods[' . $variation->ID . ']',
				'label'     => __( 'Cost of goods', 'woo-calculate-your-price' ),
				'type'      => 'number',
				'value'     => get_post_meta( $variation->ID, '_cost_of_goods', true ),
			)
		);
	}

	woocommerce_wp_hidden_input(
		array(
			'id'      => '_markup_percent[' . $variation->ID . ']',
			'label'   => __( 'Markup', 'woo-calculate-your-price' ),
			'type'    => 'number',
			'value'   => get_post_meta( $variation->ID, '_markup_percent', true ),
		)
	);
}
add_action( 'woocommerce_product_after_variable_attributes', 'cyp_add_product_variation_options_pricing', 10, 3 );

/**
 * Save custom fields to product variations.
 *
 * @param var $variation_id variation id.
 * @param var $i iteration.
 */
function cyp_save_product_variation_meta( $variation_id, $i ) {

	check_ajax_referer( 'save-variations', 'security' );
	
	$data = wp_unslash( $_POST );

	if ( ! empty( $data['_purchase_price'][ $variation_id ] ) ) {
		update_post_meta( $variation_id, '_purchase_price', esc_attr( $data['_purchase_price'][ $variation_id ] ) );
	}
	
	if ( ! empty( $data['_cost_of_goods'][ $variation_id ] ) ) {
		update_post_meta( $variation_id, '_cost_of_goods', esc_attr( $data['_cost_of_goods'][ $variation_id ] ) );
	}

	if ( ! empty( $data['_cyp_shipping_cost'][ $variation_id ] ) ) {
		update_post_meta( $variation_id, '_cyp_shipping_cost', esc_attr( $data['_cyp_shipping_cost'][ $variation_id ] ) );
	}

	delete_transient( 'cyp_json_products' );

}
add_action( 'woocommerce_save_product_variation', 'cyp_save_product_variation_meta', 20, 2 );

