<?php

class Wiaas_Pricing_Test extends Wiaas_Unit_Test_Case {

	private function _create_package_to_sell() {
		$package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
				$this->factory->product->create_simple_product(array(
					'price' => 20,
					'is_recurring' => true,
					'pay_period'  => 2,
					'category' => 'installation' ))
			)
		));

		$pricing_rules = array(
			'purchase' => array(
				'minimal_fixed_price' => 100,
				'principal_amount' => 0,
				'minimal_services_price' => 0
			),
			'purchase_24' => array(
				'minimal_fixed_price' => 100,
				'principal_amount' => 0,
				'minimal_services_price' => 100
			),
			'managed_36' => array(
				'minimal_fixed_price' => 100,
				'principal_amount' => 100,
				'minimal_services_price' => 100
			)
		);
		$commision = 50;
		$cost_margin = 0;

		$this->factory->product->set_product_bundle_prices($package, $pricing_rules, $commision, $cost_margin);

		$customer_id = $this->factory->organization->create_new_organization(
			array( 'name' => 'Customer' )
		);

		$commercial_lead_id = $this->factory->organization->create_new_organization(
			array( 'name' => 'Commercial Lead' )
		);


		self::_set_package_default_extras($commercial_lead_id, $package->get_id());

		$expected_prices = array(
			'purchase' => array(
				'fixed_extra' => 100,
				'recurrent_extra' => 0,
				'services_extra' => 0
			),
			'purchase_24' => array(
				'fixed_extra' => 100,
				'recurrent_extra' => 0,
				'services_extra' => 100
			),
			'managed_36' => array(
				'fixed_extra' => 100,
				'recurrent_extra' => 3,
				'services_extra' => 100
			)
		);

		return array( $package,  $expected_prices, $customer_id, $commercial_lead_id );
	}

	private function _set_package_default_extras($commercial_lead_id, $package_id) {
		$cl_extras = array(
			'purchase_default' => array(
				'fixed' => 0,
				'recurrent' => 0,
				'services' => 0,
				'visible' => true
			),
			'purchase_24_default' => array(
				'fixed' => 0,
				'recurrent' => 0,
				'services' => 0,
				'visible' => true
			),
			'managed_36_default' => array(
				'fixed' => 0,
				'recurrent' => 0,
				'services' => 0,
				'visible' => true
			)
		);

		Wiaas_Package_CL_Pricing::set_extras($commercial_lead_id, $package_id, $cl_extras);
	}

	/**
	 * @covers Wiaas_Pricing::get_product_total_cost()
	 */
	function test_get_fixed_product_total_cost() {
		$product  = $this->factory->product->create_simple_product();

		$total_cost = Wiaas_Pricing::get_product_total_cost($product);

		$this->assertEquals($total_cost, $product->get_price());
	}

	/**
	 * @covers Wiaas_Pricing::get_product_total_cost()
	 */
	function test_get_recurring_product_total_cost() {
		$product  = $this->factory->product->create_simple_product(array(
			'price' => 10,
			'is_recurring' => true,
			'pay_period'  => 2
		));

		$total_cost = Wiaas_Pricing::get_product_total_cost($product);

		$this->assertEquals($total_cost, 20);
	}

	/**
	 * @covers Wiaas_Pricing::get_package_total_cost()
	 */
	function test_get_package_with_fixed_products_total_cost() {
		$package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'software' ))
			)
		));

		$expected_total_price = 40;

		$total_price = Wiaas_Pricing::get_package_total_cost($package);

		$this->assertEquals($expected_total_price, $total_price);
	}

	/**
	 * @covers Wiaas_Pricing::get_package_total_cost()
	 */
	function test_get_package_with_recurring_products_total_cost() {
		$package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
				$this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period'  => 2, 'category' => 'software' ))
			)
		));

		$expected_total_price = 60;

		$total_price = Wiaas_Pricing::get_package_total_cost($package);

		$this->assertEquals($expected_total_price, $total_price);
	}

	/**
	 * @covers Wiaas_Pricing::get_package_total_cost()
	 */
	function test_package_with_single_installation_product_total_cost() {
		$package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
				$this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period'  => 2, 'category' => 'installation' ))
			)
		));

		$expected_total_price = 60;

		$total_price = Wiaas_Pricing::get_package_total_cost($package);

		$this->assertEquals($expected_total_price, $total_price);
	}

	/**
	 * @covers Wiaas_Pricing::get_package_total_cost()
	 */
	function test_package_with_multiple_installation_products_total_cost() {
		$package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
				$this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period'  => 2, 'category' => 'installation' )),
				$this->factory->product->create_simple_product(array( 'price' => 20, 'is_recurring' => true, 'pay_period'  => 2, 'category' => 'installation' ))
			)
		));

		// price will be 20 + 20*2 , more expensive installation will be applied
		$expected_total_price = 60;

		$total_price = Wiaas_Pricing::get_package_total_cost($package);

		$this->assertEquals($expected_total_price, $total_price);
	}

	/**
	 * @covers Wiaas_Pricing::get_standard_package_customer_prices()
	 */
	function test_get_standard_package_customer_price() {

		list( $package,  $expected_prices, $customer_id, $commercial_lead_id ) = $this->_create_package_to_sell();

		$customer_prices = Wiaas_Pricing::get_standard_package_customer_prices(
			$package,
			$customer_id,
			$commercial_lead_id);

		$this->assertCount(3, $customer_prices);

		foreach ($customer_prices as $customer_price) {

			$this->assertArrayHasKey('id', $customer_price);
			$this->assertArrayHasKey('payment_type', $customer_price);
			$this->assertArrayHasKey('max_contract_period', $customer_price);
			$this->assertArrayHasKey('package_pay_period', $customer_price);
			$this->assertArrayHasKey('period_unit', $customer_price);
			$this->assertArrayHasKey('services_contract_period', $customer_price);
			$this->assertArrayHasKey('fixed_extra', $customer_price);
			$this->assertArrayHasKey('recurrent_extra', $customer_price);
			$this->assertArrayHasKey('services_extra', $customer_price);

			$id = $customer_price['id'];

			$this->assertEquals($customer_price['fixed_extra'], $expected_prices[$id]['fixed_extra']);
			$this->assertEquals($customer_price['recurrent_extra'], $expected_prices[$id]['recurrent_extra']);
			$this->assertEquals($customer_price['services_extra'], $expected_prices[$id]['services_extra']);
		}

	}

	/**
	 * @covers Wiaas_Pricing::get_addon_package_customer_price()
	 */
	function test_get_addon_package_customer_price() {
		list( $package, $expected_prices, $customer_id, $commercial_lead_id ) = $this->_create_package_to_sell();

		$addon_package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
			)
		));

		$pricing_rules = array(
			'purchase' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 0,
				'minimal_services_price' => 0
			),
			'purchase_24' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 0,
				'minimal_services_price' => 500
			),
			'managed_36' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 500,
				'minimal_services_price' => 500
			)
		);
		$commision = 50;
		$cost_margin = 0;
		Wiaas_Package_Pricing::set_package_prices($addon_package, $pricing_rules, $commision, $cost_margin);

		self::_set_package_default_extras($commercial_lead_id, $addon_package->get_id());

		Wiaas_Package_Addon::set_package_addons($package, array($addon_package->get_id()));

		$expected_prices = array(
			'purchase' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 0,
				'services_extra' => 0
			),
			'purchase_24' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 0,
				'services_extra' => 500
			),
			'managed_36' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 14,
				'services_extra' => 500
			)
		);

		$customer_prices = Wiaas_Pricing::get_addon_package_customer_price(
			$addon_package,
			$package,
			$customer_id,
			$commercial_lead_id);

		$this->assertCount(3, $customer_prices);

		foreach ($customer_prices as $customer_price) {

			$this->assertArrayHasKey('id', $customer_price);
			$this->assertArrayHasKey('payment_type', $customer_price);
			$this->assertArrayHasKey('max_contract_period', $customer_price);
			$this->assertArrayHasKey('package_pay_period', $customer_price);
			$this->assertArrayHasKey('period_unit', $customer_price);
			$this->assertArrayHasKey('services_contract_period', $customer_price);
			$this->assertArrayHasKey('fixed_extra', $customer_price);
			$this->assertArrayHasKey('recurrent_extra', $customer_price);
			$this->assertArrayHasKey('services_extra', $customer_price);

			$id = $customer_price['id'];

			$this->assertEquals($customer_price['fixed_extra'], $expected_prices[$id]['fixed_extra']);
			$this->assertEquals($customer_price['recurrent_extra'], $expected_prices[$id]['recurrent_extra']);
			$this->assertEquals($customer_price['services_extra'], $expected_prices[$id]['services_extra']);
		}
	}

	/**
	 * @covers Wiaas_Pricing::get_option_package_customer_price()
	 */
	function test_get_option_package_customer_price() {
		list( $package,  $customer_id, $commercial_lead_id ) = $this->_create_package_to_sell();

		$option_package = $this->factory->product->create_product_bundle(array(
			'products' => array(
				$this->factory->product->create_simple_product(array( 'price' => 20, 'category' => 'hardware' )),
			)
		));

		$pricing_rules = array(
			'purchase' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 0,
				'minimal_services_price' => 0
			),
			'purchase_24' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 0,
				'minimal_services_price' => 500
			),
			'managed_36' => array(
				'minimal_fixed_price' => 500,
				'principal_amount' => 500,
				'minimal_services_price' => 500
			)
		);
		$commision = 50;
		$cost_margin = 0;
		Wiaas_Package_Pricing::set_package_prices($option_package, $pricing_rules, $commision, $cost_margin);

		self::_set_package_default_extras($commercial_lead_id, $option_package->get_id());

		Wiaas_Package_Option_Groups::set_package_option_groups($package, array(
			'id' => 'option',
			'name' => 'Option',
			'default' => $option_package->get_id(),
			'options' => array( $option_package->get_id() )
		));

		$expected_prices = array(
			'purchase' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 0,
				'services_extra' => 0
			),
			'purchase_24' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 0,
				'services_extra' => 500
			),
			'managed_36' => array(
				'fixed_extra' => 500,
				'recurrent_extra' => 14,
				'services_extra' => 500
			)
		);

		$customer_prices = Wiaas_Pricing::get_option_package_customer_price(
			$option_package,
			$package,
			$customer_id,
			$commercial_lead_id);

		$this->assertCount(3, $customer_prices);

		foreach ($customer_prices as $customer_price) {

			$this->assertArrayHasKey('id', $customer_price);
			$this->assertArrayHasKey('payment_type', $customer_price);
			$this->assertArrayHasKey('max_contract_period', $customer_price);
			$this->assertArrayHasKey('package_pay_period', $customer_price);
			$this->assertArrayHasKey('period_unit', $customer_price);
			$this->assertArrayHasKey('services_contract_period', $customer_price);
			$this->assertArrayHasKey('fixed_extra', $customer_price);
			$this->assertArrayHasKey('recurrent_extra', $customer_price);
			$this->assertArrayHasKey('services_extra', $customer_price);

			$id = $customer_price['id'];

			$this->assertEquals($customer_price['fixed_extra'], $expected_prices[$id]['fixed_extra']);
			$this->assertEquals($customer_price['recurrent_extra'], $expected_prices[$id]['recurrent_extra']);
			$this->assertEquals($customer_price['services_extra'], $expected_prices[$id]['services_extra']);
		}
	}
}