diff --git a/backend/app/plugins/wiaas/assets/css/package.css b/backend/app/plugins/wiaas/assets/css/package.css index cbfc97c..41596e8 100644 --- a/backend/app/plugins/wiaas/assets/css/package.css +++ b/backend/app/plugins/wiaas/assets/css/package.css @@ -1,5 +1,5 @@ -#wiaas_package_price { - padding: 20px; +#wiaas_package_price .wc-metaboxes-wrapper { + padding: 10px; } #wiaas_package_price label { @@ -12,7 +12,7 @@ } #wiaas_package_price_controls { - float: right; + border: none; } #wiaas_package_price_controls > select { @@ -90,3 +90,34 @@ font-size: 12px; height: 36px; } + + +#wiaas_linked_packages div.wc-metaboxes-wrapper { + float: none; + width: 100%; + padding: 10px 0; +} + +#wiaas_linked_packages .toolbar { + border: none; +} + +#wiaas_linked_packages .expand-close { + float: right; +} + +#wiaas_package_option_groups_list { + margin: 9px 12px; + border: 1px solid #eee; + border-radius: 3px; +} + +#wiaas_package_option_groups_list label { + float: none; + margin: 0; + width: auto; +} + +#wiaas_package_option_groups_list .wiaas_option_group h3 { + background-color:#F9F9F9; +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-package.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-package.php new file mode 100644 index 0000000..bc8c90e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-package.php @@ -0,0 +1,22 @@ +ID ); + $addons = Wiaas_Package_Addon::get_package_addons($package); + $option_groups = Wiaas_Package_Option_Groups::get_package_option_groups($package); + + include 'views/html-linked-packages.php'; + } + + /** + * Implements ajax search for package addons + */ + public static function json_search_addons() { + self::_json_search_packages('add_on'); + } + + /** + * Implements ajax searc for package options + */ + public static function json_search_options() { + + self::_json_search_packages('option'); + } + + /** + * Creates and renders new optional packages group + */ + public static function create_empty_option_group() { + $group = array( + 'name' => 'Untitled', + 'id' => uniqid('option_'), + 'default' => false, + 'options' => array() + ); + + ?> + + + $posted_option_group) { + $option_group = array( + 'id' => $posted_option_group['id'], + 'name' => $posted_option_group['name'], + 'default' => $posted_option_group['default'], + 'options' => array() + ); + $option_group['options'] = isset( $posted_option_group['options'] ) ? + array_filter( array_map( 'intval', (array) $posted_option_group['options'] ) ) : + array(); + + $option_groups[] = $option_group; + } + + Wiaas_Package_Option_Groups::set_package_option_groups( + $package, + $posted_option_groups); + } + + /** + * Implements search for packages of provided type + * @param $package_type + */ + private static function _json_search_packages($package_type) { + check_ajax_referer( 'search-products', 'security' ); + + $term = wc_clean( empty( $term ) ? wp_unslash( $_GET['term'] ) : $term ); + + if ( empty( $term ) ) { + wp_die(); + } + + $data_store = WC_Data_Store::load( 'product' ); + $ids = $data_store->search_products( $term ); + + $packages= array_filter( array_map( 'wc_get_product', $ids ), 'wc_products_array_filter_readable' ); + $result = array(); + + foreach ( $packages as $package ) { + + if (Wiaas_Package_Type::get_package_type($package->get_id()) === $package_type) { + $result[ $package->get_id() ] = rawurldecode( $package->get_formatted_name() ); + } + } + + wp_send_json( $result ); + } +} + +Wiaas_Admin_Linked_Packages::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/package/class-wiaas-admin-package-pricing.php b/backend/app/plugins/wiaas/includes/admin/package/class-wiaas-admin-package-pricing.php deleted file mode 100644 index d01e17b..0000000 --- a/backend/app/plugins/wiaas/includes/admin/package/class-wiaas-admin-package-pricing.php +++ /dev/null @@ -1,356 +0,0 @@ - __( 'Pricing', 'wiaas' ), - 'target' => 'wiaas_package_price', - 'class' => array( 'show_if_bundle', 'bundled_package_tab' ), - 'priority' => 50 - ); - - return $tabs; - } - - public static function package_data_panel() { - - global $post; - $package = wc_get_product( $post->ID ); - $pricing_rules = Wiaas_Package_Pricing::get_package_prices($package); - - ?> -
-
- - -
- -
-
- $pricing_rule_set ) { - $pay_type = $available_pay_types[$name]; - ?> -
-
-

- - REMOVE - -

-
-
- - - - - - - - - - - - - - - - -
- - - -
- - - - - -
-
- 0) { - $label .= '(' . $pay_type['services_contract_period'] . ' ' . $pay_type['period_unit'] . ')'; - } else { - $label .= '(Unbound)'; - } - - ?> - - - - - - - - - - - - - - 0) { - ?> - - - Final total: - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 && $pay_type['package_pay_period'] > 0) { - $value += $pricing_rule['principal_amount'] / $pay_type['package_pay_period']; - } - - ?> - - - - - - - - - $pay_type) { - if (!isset($pricing_rule_sets[$name])) { - $has_available_pay_types = true; - break; - } - } - - $class = $has_available_pay_types ? '' : 'wiaas_hidden'; - - ?> -
- - -
- - - ID ); + + include 'views/html-package-types.php'; + } + + /** + * Saves posted wiaas package type data + * @param $package_id + */ + public static function process_meta_box($package_id) { + + $package = wc_get_product($package_id); + + if ($package->get_type() === 'bundle') { + // Save wiaas package type + Wiaas_Package_Type::set_package_type($package_id, $_POST['wiaas_package_type']); + } else { + Wiaas_Package_Type::set_package_type($package_id, null); + } + } +} + +Wiaas_Admin_Package_Types::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/package/views/html-linked-packages.php b/backend/app/plugins/wiaas/includes/admin/package/views/html-linked-packages.php new file mode 100644 index 0000000..ab0a347 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/package/views/html-linked-packages.php @@ -0,0 +1,136 @@ + + +
+ +
+

+ + + +

+
+ +
+ + +
+
+ + + + / + + +
+
+ +
+
+ + + + + / + + +
+
+ +
+ +
diff --git a/backend/app/plugins/wiaas/includes/admin/package/views/html-package-options-group.php b/backend/app/plugins/wiaas/includes/admin/package/views/html-package-options-group.php new file mode 100644 index 0000000..c1f6082 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/package/views/html-package-options-group.php @@ -0,0 +1,86 @@ + + +
+

+ + + +
+ + + +

+
+ + + + + + + + + + +
+ + + + + + +
+ + +
+
+
\ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/package/views/html-package-types.php b/backend/app/plugins/wiaas/includes/admin/package/views/html-package-types.php new file mode 100644 index 0000000..57d44da --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/package/views/html-package-types.php @@ -0,0 +1,84 @@ + + + diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php new file mode 100644 index 0000000..b493291 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-package-pricing.php @@ -0,0 +1,78 @@ + __( 'Pricing', 'wiaas' ), + 'target' => 'wiaas_package_price', + 'class' => array( 'show_if_bundle', 'bundled_package_tab' ), + 'priority' => 50 + ); + + return $tabs; + } + + /** + * Renderes wiaas pricing tab content for package + */ + public static function package_data_panel() { + + global $post; + $package = wc_get_product( $post->ID ); + $pricing_rules = Wiaas_Package_Pricing::get_package_prices($package); + $commission = Wiaas_Package_Pricing::get_package_pricing_commission($package); + + include 'views/html-package-pricing.php'; + } + + /** + * Saves posted package pricing rules + * @param $post_id + * @param $post + */ + public function process_meta_box( $post_id, $post ) { + Wiaas_Package_Pricing::set_package_prices( + wc_get_product( $post_id ), + $_POST['wiaas_pricing_rules'], + $_POST['wiaas_pricing_rules_commision']); + } +} + +Wiaas_Admin_Package_Pricing::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-product-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-product-pricing.php new file mode 100644 index 0000000..282a0aa --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/class-wiaas-admin-product-pricing.php @@ -0,0 +1,50 @@ +ID ); + + $product_pricing = Wiaas_Product_Pricing::get_product_price($product); + + include 'views/html-product-pricing.php'; + } + + /** + * Saves posted product pricing settings + * @param $post_id + * @param $post + */ + public function process_meta_box( $post_id, $post ) { + + $product = wc_get_product( $post_id ); + if ($product->get_type() === 'simple') { + $is_recurring = $_POST['_wiaas_recurring_price'] === 'yes'; + $pay_period = isset($_POST['_wiaas_recurring_pay_period']) ? $_POST['_wiaas_recurring_pay_period'] : 0; + + Wiaas_Product_Pricing::set_product_price($product, $product->get_price(), $is_recurring, $pay_period); + } + } +} + +Wiaas_Admin_Product_Pricing::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-principal-amount.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-principal-amount.php new file mode 100644 index 0000000..77e54ac --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-principal-amount.php @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-recurrent-price.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-recurrent-price.php new file mode 100644 index 0000000..0b3b7d3 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-recurrent-price.php @@ -0,0 +1,28 @@ + + + 0 && $pay_type['package_pay_period'] > 0) { + $value += wiaas_PMT( + Wiaas_Pricing::INTEREST_RATE, + $pay_type['package_pay_period'], + $pricing_rule['principal_amount']); +} + +?> + + + + + + + + + diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-services-price.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-services-price.php new file mode 100644 index 0000000..c752e1b --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rule-services-price.php @@ -0,0 +1,57 @@ + + + 0) { + $label .= '(' . $pay_type['services_contract_period'] . ' ' . $pay_type['period_unit'] . ')'; +} else { + $label .= '(Unbound)'; +} + +?> + + + + + + + + + + + + + + 0) { + ?> + + + Final total: + + + + + + + + + diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rules-list.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rules-list.php new file mode 100644 index 0000000..976972c --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing-rules-list.php @@ -0,0 +1,59 @@ + $pricing_rule ) { + $pay_type = $available_pay_types[$name]; + ?> +
+
+

+ + REMOVE + +

+
+
+ + + + + + + + + + + + + + + + +
+ + + +
+ + + + + +
+
+ + + diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing.php new file mode 100644 index 0000000..2c4d51a --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-package-pricing.php @@ -0,0 +1,209 @@ + + +
+ + +
+ '_wiaas_price_commision', + 'name' => 'wiaas_pricing_rules_commision', + 'value' => $commission, + 'label' => __( 'Commision (Percent):', 'wiaas' ), + 'type' => 'number', + ) + ); + ?> +
+ +
+
+ $pay_type) { + if (!isset($pricing_rule_sets[$name])) { + $has_available_pay_types = true; + break; + } + } + + $class = $has_available_pay_types ? '' : 'wiaas_hidden'; + + ?> +
+ + +
+ +
+ +
+ +
+
+
diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php new file mode 100644 index 0000000..68ad9be --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php @@ -0,0 +1,36 @@ + + + + + '_wiaas_recurring_price', + 'value' => $product_pricing['is_recurring'] ? 'yes' : 'no', + 'data_type' => 'price', + 'label' => __( $product->get_category_ids()[0], 'wiaas' ), + ) +); + +woocommerce_wp_text_input( + array( + 'id' => '_wiaas_recurring_pay_period', + 'value' => $product_pricing['pay_period'], + 'label' => __( 'Pay period (Months)', 'wiaas' ), + 'type' => 'number', + ) +); +?> \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php index 73f8f3d..941b7a5 100644 --- a/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php @@ -72,10 +72,9 @@ class Wiaas_Cart_API { $count = 0; foreach ($items as $key => $item) { - if (isset($item['bundled_by'])) { - continue; + if (isset($item['_wiaas_standard_package'])) { + $count++; } - $count++; } return new WP_REST_Response(array( @@ -94,39 +93,78 @@ class Wiaas_Cart_API { $result = array(); foreach ($items as $key => $item) { - if (isset($item['bundled_by'])) { + if (!isset($item['_wiaas_standard_package'])) { continue; } $package = wc_get_product($item['product_id']); + // Retrieve package addons + $addon_cart_items = wiaas_get_cart_item_addons($item); + $additional_packages = array(); + + foreach ($addon_cart_items as $addon_cart_item) { + $additional_package = wc_get_product($addon_cart_item['product_id']); + $additional_packages[] = array( + 'idAdditionalPackage' => $additional_package->get_id(), + 'packageName' => $additional_package->get_title(), + 'prices' => array( + 'fixedExtra' => $addon_cart_item['_wiaas_payment']['fixed_extra'], + 'recurrentExtra' => $addon_cart_item['_wiaas_payment']['recurrent_extra'], + 'servicesExtra' => $addon_cart_item['_wiaas_payment']['services_extra'], + ) + ); + } + + // Retrieve package options + $option_cart_items = wiaas_get_cart_item_options($item); + $package_options = array(); + foreach ($option_cart_items as $option_cart_item) { + $option_package = wc_get_product($option_cart_item['product_id']); + $package_options[] = array( + 'idOptionPackage' => $option_package->get_id(), + 'groupName' => $option_cart_item['_wiaas_option_group_name'], + 'packageName' => $option_package->get_title(), + 'prices' => array( + 'fixedExtra' => $option_cart_item['_wiaas_payment']['fixed_extra'], + 'recurrentExtra' => $option_cart_item['_wiaas_payment']['recurrent_extra'], + 'servicesExtra' => $option_cart_item['_wiaas_payment']['services_extra'], + ) + ); + } + + $totalPrices = Wiaas_Cart::get_cart_item_total($item); + + $country = Wiaas_Countries::get_package_country($package); + + $result[] = array( 'idPackage' => $item['product_id'], 'key' => $item['key'], 'packageName' => $package->get_title(), - 'additionalPackages' => array(), + 'additionalPackages' => $additional_packages, 'areAdditionalAvailable' => true, 'areOptionsAvailable' => true, 'bids' => array(), 'commercialLead' => 'Coor Service Management', 'country' => array( - 'currency' => 'SEK' + 'currency' => $country['currency'] ), - 'options' => array(), + 'options' => $package_options, 'quantity' => $item['quantity'], - 'idPayType' => $item['_wiaas_price']['id'], - 'payType' => $item['_wiaas_price']['payment_type'], - 'periodUnit' => $item['_wiaas_price']['period_unit'], - 'idPrice' => $item['_wiaas_price']['id'], - 'fixedPrice' => $item['_wiaas_price']['minimal_fixed_price'], - 'recurentPrice' => $item['_wiaas_price']['recurrent_price'], - 'servicesPrice' => $item['_wiaas_price']['minimal_services_price'], + 'idPayType' => $item['_wiaas_payment']['id'], + 'payType' => $item['_wiaas_payment']['payment_type'], + 'periodUnit' => $item['_wiaas_payment']['period_unit'], + 'idPrice' => $item['_wiaas_payment']['id'], + 'fixedPrice' => $item['_wiaas_payment']['fixed_extra'], + 'recurrentPrice' => $item['_wiaas_payment']['recurrent_extra'], + 'servicesPrice' => $item['_wiaas_payment']['services_extra'], 'totalPrices' => array( - 'fixedPrice' => $item['_wiaas_price']['minimal_fixed_price'], - 'recurentPrice' => $item['_wiaas_price']['recurrent_price'], - 'servicesPrice' => $item['_wiaas_price']['minimal_services_price'], + 'fixedPrice' => $totalPrices['fixed_extra'], + 'recurrentPrice' => $totalPrices['recurrent_extra'], + 'servicesPrice' => $totalPrices['services_extra'], ), 'status' => 'available', @@ -136,6 +174,7 @@ class Wiaas_Cart_API { return new WP_REST_Response( array( 'cartItems' => $result, + 'items' => $items, 'totalPrice' => '' ) ); @@ -162,22 +201,10 @@ class Wiaas_Cart_API { */ public static function add_package_to_cart() { $package_id = $_POST['package_id']; - $price_id = $_POST['price_id']; - $package = wc_get_product($package_id); - $prices = Wiaas_Package_Pricing::get_package_prices($package); - $selected_price = $prices[$price_id]; - - WC()->session->set('wiaas_price_' . $package_id, $price_id); - - $success = WC()->cart->add_to_cart( - $package_id, - 1, - 0, - array(), - array( - '_wiaas_price' => $selected_price, - )); + $success = WC()->cart->add_to_cart($package_id, 1, 0, array(), array( + '_wiaas_standard_package' => true + )); if ($success) { return new WP_REST_Response(array( @@ -279,6 +306,15 @@ class Wiaas_Cart_API { $order_id = WC()->checkout()->create_order(array()); $order = wc_get_order( $order_id ); + // set order currency + $line_items = $order->get_items(); + foreach ($line_items as $line_item) { + if (isset($line_item['wiaas_currency'])) { + $order->set_currency($line_item['wiaas_currency']); + break; + } + } + $order->set_shipping_city($delivery_address['city']); $order->set_shipping_country($delivery_address['countryName']); $order->set_shipping_address_1($delivery_address['detailedAddress']); diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php new file mode 100644 index 0000000..d8e18ad --- /dev/null +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php @@ -0,0 +1,42 @@ + 'GET', + 'permission_callback' => 'is_user_logged_in', + 'callback' => array(__CLASS__, 'download_package_file'), + ) ); + } + + /** + * Download package document + */ + public static function download_package_file() { + $document_id = $_GET['document_id']; + $package_id = $_GET['package_id']; + + $package = wc_get_product($package_id); + + $file = $package->get_file($document_id); + + if ($file) { + WC_Download_Handler::download_file_force($package->get_file_download_path($document_id), $file->get_name()); + } + } +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php index d63ecae..bfbe7fe 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php @@ -7,7 +7,8 @@ if ( ! defined( 'ABSPATH' ) ) { class Wiaas_Admin { public static function init() { - require_once dirname( __FILE__ ) . '/admin/package/class-wiaas-admin-package-pricing.php'; + require_once dirname( __FILE__ ) . '/admin/class-wiaas-admin-package.php'; + require_once dirname( __FILE__ ) . '/admin/class-wiaas-admin-pricing.php'; } } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-api.php b/backend/app/plugins/wiaas/includes/class-wiaas-api.php index c34bf53..9d93713 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-api.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-api.php @@ -33,12 +33,14 @@ class Wiaas_API { #Delivery process controller include_once dirname( __FILE__ ) . '/api/class-wiaas-rest-delivery-process-api.php'; include_once dirname( __FILE__ ) . '/api/class-wiaas-cart-api.php'; + include_once dirname( __FILE__ ) . '/api/class-wiaas-document-api.php'; } public static function register_rest_routes() { $controllers = array( 'Wiass_REST_Delivery_Process_API', - 'Wiaas_Cart_API' + 'Wiaas_Cart_API', + 'Wiaas_Document_API' ); foreach ( $controllers as $controller ) { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php new file mode 100644 index 0000000..38147ce --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php @@ -0,0 +1,336 @@ +cart->get_cart_item($parent_key); + + $package_prices = Wiaas_Pricing::get_addon_package_customer_price($package, $parent_item['data']); + break; + case 'option': + $parent_key = $cart_item_data['_wiaas_option_for']; + $parent_item = WC()->cart->get_cart_item($parent_key); + + $option_group_name = Wiaas_Package_Option_Groups::get_group_name_for_package_option($parent_item['data'], $package); + $cart_item_data['_wiaas_option_group_name' ] = $option_group_name; + + $package_prices = Wiaas_Pricing::get_option_package_customer_price($package, $parent_item['data']); + break; + } + + $selected_price_index = array_search($_POST['price_id'], array_column($package_prices, 'id')); + + if (is_numeric($selected_price_index) && isset($package_prices[$selected_price_index])) { + $cart_item_data['_wiaas_payment'] = $package_prices[$selected_price_index]; + } + + return $cart_item_data; + } + + /** + * Add selected package options and addons after parent standard package is added to cart + * + * @param $cart_item_key + * @param $package_id + * @param $quantity + * @param $variation_id + * @param $variation + * @param $cart_item_data + */ + public static function add_additional_packages_to_cart($cart_item_key, $package_id, $quantity, $variation_id, $variation, $cart_item_data) { + + remove_action( 'woocommerce_add_to_cart', array( __CLASS__, 'add_additional_packages_to_cart' )); + + self::_add_options_to_cart($cart_item_key, $package_id, $cart_item_data); + + self::_add_addons_to_cart($cart_item_key, $package_id, $cart_item_data); + + add_action( 'woocommerce_add_to_cart', array( __CLASS__, 'add_additional_packages_to_cart' ), 10, 6 ); + } + + /** + * Update package cart item with `minimal_fixed_price` as its price + * so resulting totals would be sum of these prices + * @param $cart + */ + public static function on_calculate_totals($cart) { + + foreach ($cart->cart_contents as $key => $cart_item) { + if (isset($cart_item['_wiaas_standard_package'])) { + + $total = self::get_cart_item_total($cart_item); + + WC()->cart->cart_contents[ $key ]['data']->set_price( $total['fixed_extra'] ); + + } else { + WC()->cart->cart_contents[ $key ]['data']->set_price( 0 ); + } + } + } + + /** + * Persist used payment type information for package in corresponding order line item. + * Also for standard package type list of addons and options will be saved. + * + * @param $order_item + * @param $cart_item_key + * @param $cart_item + * @param $order + * + * @return array + */ + public static function add_order_item_meta( $order_item, $cart_item_key, $cart_item ) { + if (wc_pb_is_bundle_container_cart_item($cart_item) && isset($cart_item['_wiaas_payment'])) { + + $payment = $cart_item['_wiaas_payment']; + + $total = self::get_cart_item_total($cart_item); + + $order_item->add_meta_data( '_wiaas_payment_type', $payment['payment_type'], true ); + $order_item->add_meta_data( '_wiaas_services_extra', $total['services_extra'], true ); + $order_item->add_meta_data( '_wiaas_service_contract_period', $payment['services_contract_period'], true ); + $order_item->add_meta_data( '_wiaas_max_contract_period', $payment['max_contract_period'], true ); + $order_item->add_meta_data( '_wiaas_period_unit', $payment['period_unit'], true ); + $order_item->add_meta_data( '_wiaas_recurrent_extra', $total['recurrent_extra'], true ); + $order_item->add_meta_data( '_wiaas_pay_period', $payment['package_pay_period'], true ); + } + + if (isset($cart_item['_wiaas_standard_package'])) { + $order_item->add_meta_data( '_wiaas_standard_package', $cart_item['_wiaas_standard_package'], true ); + } + if (isset($cart_item['_wiaas_currency'])) { + $order_item->add_meta_data( '_wiaas_currency', $cart_item['_wiaas_currency'], true ); + } + + // add options metadata + if (isset($cart_item['_wiaas_option_items'])) { + $order_item->add_meta_data( '_wiaas_option_items', $cart_item['_wiaas_option_items'] ); + } + if (isset($cart_item['_wiaas_option_for'])) { + $order_item->add_meta_data( '_wiaas_option_for', $cart_item['_wiaas_option_for'], true ); + } + if (isset($cart_item['_wiaas_option_group_name'])) { + $order_item->add_meta_data( '_wiaas_option_group_name', $cart_item['_wiaas_option_group_name'], true ); + } + + // add addons metadata + if (isset($cart_item['_wiaas_addon_items'])) { + $order_item->add_meta_data( '_wiaas_addon_items', $cart_item['_wiaas_addon_items'] ); + } + if (isset($cart_item['_wiaas_addon_for'])) { + $order_item->add_meta_data( '_wiaas_addon_for', $cart_item['_wiaas_addon_for'], true ); + } + } + + /** + * Mark extended properties for order as hidden + * @param $hidden + * + * @return array + */ + public static function hidden_order_item_meta( $hidden ) { + + return array_merge( $hidden, array( + '_wiaas_payment_type', + '_wiaas_services_extra', + '_wiaas_service_contract_period', + '_wiaas_max_contract_period', + '_wiaas_period_unit', + '_wiaas_recurrent_extra', + '_wiaas_pay_period', + '_wiaas_addon_items', + '_wiaas_addon_for', + '_wiaas_option_items', + '_wiaas_option_for', + '_wiaas_option_group_name', + '_wiaas_standard_package', + '_wiaas_currency', + ) ); + } + + /** + * Calculate total cost for cart item + * + * @param $cart_item + * + * @return array + */ + + public static function get_cart_item_total($cart_item) { + + $package_price = isset($cart_item['_wiaas_payment']) ? $cart_item['_wiaas_payment'] : array( + 'fixed_extra' => 0, + 'services_extra' => 0, + 'recurrent_extra' => 0 + ); + + $total_fixed_extra = $package_price['fixed_extra']; + $total_services_extra = $package_price['services_extra']; + $total_recurrent_extra = $package_price['recurrent_extra']; + + $cart_item_addons = wiaas_get_cart_item_addons($cart_item); + foreach ($cart_item_addons as $cart_item_addon) { + $addon_price = $cart_item_addon['_wiaas_payment']; + $total_fixed_extra += $addon_price['fixed_extra']; + $total_services_extra += $addon_price['services_extra']; + $total_recurrent_extra += $addon_price['recurrent_extra']; + } + + $cart_item_options = wiaas_get_cart_item_options($cart_item); + foreach ($cart_item_options as $cart_item_option) { + $option_price = $cart_item_option['_wiaas_payment']; + $total_fixed_extra += $option_price['fixed_extra']; + $total_services_extra += $option_price['services_extra']; + $total_recurrent_extra += $option_price['recurrent_extra']; + } + + return array( + 'fixed_extra' => $total_fixed_extra, + 'services_extra' => $total_services_extra, + 'recurrent_extra' => $total_recurrent_extra + ); + } + + + //PRIVATE + + /** + * Add selected package options to cart + * @param $cart_item_key + * @param $package_id + * @param $cart_item_data + * + * @throws Exception + */ + private static function _add_options_to_cart($cart_item_key, $package_id, $cart_item_data) { + $is_option_parent = $_POST['package_id'] = $package_id && isset($cart_item_data['_wiaas_option_items']); + $has_selected_options = isset($_POST['options']) && is_array($_POST['options']); + + if ($is_option_parent && $has_selected_options) { + + $options_ids = $_POST['options']; + + foreach ($options_ids as $option_id) { + $option_package = wc_get_product($option_id); + if (is_object($option_package)) { + + $option_cart_item_key = WC()->cart->add_to_cart($option_id, 1, 0, array(), array( + '_wiaas_option_for' => $cart_item_key + )); + + if ($option_cart_item_key) { + WC()->cart->cart_contents[ $cart_item_key ]['_wiaas_option_items'][] = $option_cart_item_key; + } + } + } + } + } + + /** + * Add selected package addons to cart + * + * @param $cart_item_key + * @param $package_id + * @param $cart_item_data + * + * @throws Exception + */ + private static function _add_addons_to_cart($cart_item_key, $package_id, $cart_item_data) { + + $is_addon_parent = $_POST['package_id'] = $package_id && isset($cart_item_data['_wiaas_addon_items']); + $has_selected_addons = isset($_POST['addons']) && is_array($_POST['addons']); + + if ($is_addon_parent && $has_selected_addons) { + $addons_ids = $_POST['addons']; + + foreach ($addons_ids as $addon_id) { + $addon_package = wc_get_product($addon_id); + if (is_object($addon_package)) { + + $addon_cart_item_key = WC()->cart->add_to_cart($addon_id, 1, 0, array(), array( + '_wiaas_addon_for' => $cart_item_key + )); + + if ($addon_cart_item_key) { + WC()->cart->cart_contents[ $cart_item_key ]['_wiaas_addon_items'][] = $addon_cart_item_key; + } + } + } + } + } +} + +Wiaas_Cart::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-countries.php b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php new file mode 100644 index 0000000..375a013 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php @@ -0,0 +1,104 @@ + array( + 'name' => 'Sweden', + 'code' => 'se', + 'vat' => 9 , + 'currency' => 'SEK' + ), + 'Denmark' => array( + 'name' => 'Denmark', + 'code' => 'dk', + 'vat' => 9 , + 'currency' => 'DKK' + ), + 'Finland' => array( + 'name' => 'Finland', + 'code' => 'fi', + 'vat' => 9 , + 'currency' => 'EUR' + ), + ); + + public static function init() { + + add_action('woocommerce_after_register_taxonomy', array(__CLASS__, 'register_product_countries_taxonomy')); + } + + /** + * Registers product taxonomy for avaiable countries + */ + public static function register_product_countries_taxonomy() { + + $labels = array( + 'name' => _x( 'Country', 'taxonomy general name', 'wiaas' ), + 'singular_name' => _x( 'Country', 'taxonomy singular name', 'wiaas' ), + 'menu_name' => _x( 'Country', 'Admin menu name', 'wiaas' ), + 'search_items' => __( 'Search Countries', 'wiaas' ), + 'all_items' => __( 'All Countries', 'wiaas' ), + 'parent_item' => __( 'Parent Country', 'wiaas' ), + 'parent_item_colon' => __( 'Parent Country:', 'wiaas' ), + 'edit_item' => __( 'Edit Country', 'wiaas' ), + 'update_item' => __( 'Update Country', 'wiaas' ), + 'add_new_item' => __( 'Add New Country', 'wiaas' ), + 'new_item_name' => __( 'New Country Name', 'wiaas' ), + ); + + $args = array( + 'hierarchical' => false, + 'label' => __( 'Countries', 'wiaas' ), + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'rewrite' => array( 'slug' => 'product_country' ), + ); + + register_taxonomy( 'product_country', array( 'product' ), $args ); + + foreach (self::$available_countries as $available_country) { + wp_insert_term($available_country['name'], 'product_country'); + } + } + + /** + * Retrieves country for provided package + * @param $package + * + * @return array|null + */ + public static function get_package_country($package) { + return self::get_product_country($package); + } + + /** + * Retrieves country for provided product + * @param $product + * + * @return array|null + */ + public static function get_product_country($product) { + $product_country = get_the_terms($product->get_id(), 'product_country'); + return is_array($product_country) && isset($product_country[0]) ? + self::$available_countries[$product_country[0]->name] : + null; + } +} + +Wiaas_Countries::init(); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php index 97e8023..1b95a3b 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php @@ -11,7 +11,9 @@ class Wiaas_DB_Update { '20180807222206' => 'wiaas_db_update_setup_customer_capabilities', '20180811134511' => 'wiaas_db_update_enable_orders_access_management', '20180813134511' => 'wiaas_db_update_enable_order_numbers', - '20180826153509' => 'wiaas_create_broker_access_group' + '20180826153509' => 'wiaas_create_broker_access_group', + '20180911101010' => 'wiaas_db_setup_exclusive_taxonomies', + '20180912101010' => 'wiaas_db_setup_default_cl' ); public static function execute() { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-documents.php b/backend/app/plugins/wiaas/includes/class-wiaas-documents.php new file mode 100644 index 0000000..fcc5992 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-documents.php @@ -0,0 +1,103 @@ + array( + 'name' => 'Template Questionaire', + 'is_special_type' => false, + ), + 'order_questionaire' => array( + 'name' => 'Order Questionaire', + 'is_special_type' => true, + ), + 'configuration' => array( + 'name' => 'Configuration', + 'is_special_type' => true, + ), + 'install_guide' => array( + 'name' => 'Install guide', + 'is_special_type' => false, + ), + 'customer_acceptance' => array( + 'name' => 'Customer acceptance', + 'is_special_type' => true, + ), + 'template_agreement' => array( + 'name' => 'Template Agreement', + 'is_special_type' => false, + ), + 'order_agreement' => array( + 'name' => 'Order Agreement', + 'is_special_type' => true, + ), + 'installation_protocol' => array( + 'name' => 'Installation protocol', + 'is_special_type' => true, + ), + 'statements' => array( + 'name' => 'Statements', + 'is_special_type' => false, + ), + 'customer_acceptance_template' => array( + 'name' => 'Customer acceptance template', + 'is_special_type' => false, + ), + ); + + public static function init() { + add_action( 'init', array( __CLASS__, 'register_wiaas_document_types' )); + } + + /** + * Registers taxonomy and default values for wiaas document types + */ + public static function register_wiaas_document_types() { + $labels = array( + 'name' => _x( 'Document type', 'taxonomy general name', 'wiaas' ), + 'singular_name' => _x( 'Document type', 'taxonomy singular name', 'wiaas' ), + 'menu_name' => _x( 'Document types', 'Admin menu name', 'wiaas' ), + 'search_items' => __( 'Search Document types', 'wiaas' ), + 'all_items' => __( 'All Document types', 'wiaas' ), + 'parent_item' => __( 'Parent Document type', 'wiaas' ), + 'parent_item_colon' => __( 'Parent Document type:', 'wiaas' ), + 'edit_item' => __( 'Edit Document type', 'wiaas' ), + 'update_item' => __( 'Update Document type', 'wiaas' ), + 'add_new_item' => __( 'Add New Document type', 'wiaas' ), + 'new_item_name' => __( 'New Document type Name', 'wiaas' ), + ); + + $args = array( + 'hierarchical' => false, + 'label' => __( 'Document types', 'wiaas' ), + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'rewrite' => array( 'slug' => 'wiaas_document_types' ), + ); + + register_taxonomy( 'wiaas_document_types', array( 'attachment' ), $args ); + + foreach (self::$available_doc_types as $key => $available_doc_type) { + wp_insert_term($available_doc_type['name'], 'wiaas_document_types', array( + 'slug' => $key + )); + } + } +} + +Wiaas_Documents::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-order.php b/backend/app/plugins/wiaas/includes/class-wiaas-order.php index 06387ed..736cd70 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-order.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-order.php @@ -1,5 +1,10 @@ get_data(); # apply overrides - $data = self::_append_products_info($data, $order, $request); - - $data = self::_append_order_process($data, $order, $request); $data = self::_append_customer_info($data, $order, $request); $data = self::_append_commercial_lead_info($data, $order, $request); $data = self::_append_wiaas_order_details($data, $order, $request); - - $data = self::_append_order_comments($data, $order, $request); + + $data = self::_append_packages($data, $order, $request); + + if (isset($request['id'])) { + + $data = self::_append_order_process($data, $order, $request); + + $data = self::_append_order_comments($data, $order, $request); + } $response->set_data($data); @@ -182,27 +191,26 @@ class Wiaas_Order { * * @return mixed */ - private static function _append_products_info($data, $order, $request) { + private static function _append_packages($data, $order, $request) { $line_items = array(); + + $order_items = $order->get_items( 'line_item' ); + foreach ($data['line_items'] as $index => $product_line) { + + $item = $order->get_item($product_line['id']); + // add only product lines that represent product bundles - if (empty($product_line['bundled_by'])) { + if (isset($item['wiaas_standard_package'])) { - $item = $order->get_item($product_line['id']); - $payment = $item->get_meta('_wiaas_payment', true); - - # lock all products to `Purchase` payment type - $product_line['payment_type'] = $payment['payment_type']; - - # lock all products to have no service - $product_line['service_price'] = $payment['minimal_services_price']; - $product_line['service_contract_period'] = $payment['services_contract_period']; - $product_line['max_contract_period'] = $payment['max_contract_period']; - $product_line['period_unit'] = $payment['period_unit']; - - # simplify payment for all products - $product_line['recurring_price'] = $payment['recurrent_price']; - $product_line['pay_period'] = $payment['package_pay_period']; + # get payment type info + $product_line['payment_type'] = $item['wiaas_payment_type']; + $product_line['service_price'] = floatval($item['wiaas_services_extra']); + $product_line['service_contract_period'] = floatval($item['wiaas_service_contract_period']); + $product_line['max_contract_period'] = floatval($item['wiaas_max_contract_period']); + $product_line['period_unit'] = $item['wiaas_period_unit']; + $product_line['recurring_price'] = floatval($item['wiaas_recurrent_extra']); + $product_line['pay_period'] = floatval($item['wiaas_pay_period']); # collect status from order if ($data['status'] === 'completed') { @@ -212,16 +220,51 @@ class Wiaas_Order { } else { $product_line['status'] = 'processing'; } + $product_line['short_desc'] = $product_line['status']; # collect completion data from order $product_line['date_completed'] = $data['date_completed']; + if (isset($request['id'])) { + // collect package addons + $product_line['additional_packages'] = array(); + $addon_items = wiaas_get_order_item_addons($order_items, $item); + foreach ($addon_items as $addon_item) { + $product_line['additional_packages'][] = array( + 'id' => $addon_item->get_id(), + 'name' => $addon_item->get_name(), + ); + } + + // collect package options + $product_line['options'] = array(); + $option_items = wiaas_get_order_item_options($order_items, $item); + foreach ($option_items as $option_item) { + $product_line['options'][] = array( + 'id' => $option_item->get_id(), + 'name' => $option_item->get_name(), + 'group_name' => $option_item['wiaas_option_group_name'] + ); + } + } + $line_items[] = $product_line; } } $data['line_items'] = $line_items; + $total_recurring_price = 0; + + foreach ($order_items as $order_item) { + if (isset($order_item['wiaas_standard_package'])) { + $total_recurring_price += floatval($order_item['quantity']) * floatval($order_item['wiaas_services_extra']) + + floatval($order_item['quantity']) * floatval($order_item['wiaas_recurrent_extra']); + } + } + + $data['recurring_price'] = $total_recurring_price; + return $data; } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-package.php b/backend/app/plugins/wiaas/includes/class-wiaas-package.php index dc1c162..27900dd 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-package.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-package.php @@ -1,9 +1,19 @@ get_data(); - $data = self::_append_package_prices($data, $package, $request); + $data = self::_append_country_info($data, $package, $request); + + if (isset($request['id'])) { + $data = self::_append_package_prices($data, $package, $request); + + $data = self::_append_documents_info($data, $package, $request); + + $data = self::_append_additional_packages($data, $package, $request); + } $response->set_data($data); return $response; } + /** + * Append package documents + * @param $data + * @param $package + * @param $request + * + * @return array + */ + private static function _append_documents_info($data, $package, $request) { + + unset($data['downloads']); + + $data['documents'] = array_map(function($download) { + return array( + 'id' => $download->get_id(), + 'name' => $download->get_name(), + 'extension' => $download->get_file_extension(), + ); + }, array_values($package->get_downloads())); + + return $data; + } + + /** + * Append package country and currency info + * @param $data + * @param $package + * @param $request + * + * @return array + */ + private static function _append_country_info($data, $package, $request) { + $package_country = Wiaas_Countries::get_package_country($package); + + if (isset($package_country)) { + $data['country'] = $package_country['name']; + $data['country_code'] = $package_country['code']; + $data['currency'] = $package_country['currency']; + } + + return $data; + } + + /** + * Append package addons and options + * @param $data + * @param $package + * @param $request + * + * @return array + */ + private static function _append_additional_packages($data, $package, $request) { + + $data['additional_packages'] = array(); + $addons = Wiaas_Package_Addon::get_package_addons($package); + foreach ($addons as $addon) { + $data['additional_packages'][] = array( + 'id' => $addon->get_id(), + 'name' => $addon->get_name(), + 'description' => $addon->get_description(), + 'prices' => Wiaas_Pricing::get_addon_package_customer_price($addon, $package), + ); + } + + $data['groups'] = array(); + $option_groups = Wiaas_Package_Option_Groups::get_package_option_groups($package); + foreach ($option_groups as $option_group) { + $data['groups'][$option_group['id']] = array( + 'id' => $option_group['id'], + 'name' => $option_group['name'], + 'default' => $option_group['default'], + 'options' => array() + ); + $default_option_id = (int) $option_group['default']; + + foreach ($option_group['options'] as $option_package) { + $data['groups'][$option_group['id']]['options'][] = array( + 'id' => $option_package->get_id(), + 'name' => $option_package->get_name(), + 'description' => $option_package->get_description(), + 'default' => $default_option_id === $option_package->get_id(), + 'prices' => Wiaas_Pricing::get_option_package_customer_price($option_package, $package), + ); + } + } + + return $data; + } + /** * Append configured package prices on package json response * @param $data * @param $package * @param $request * - * @return mixed + * @return array */ private static function _append_package_prices($data, $package, $request) { - $package_prices = array_values(Wiaas_Package_Pricing::get_package_prices($package)); - - $data['prices'] = $package_prices; + $data['prices'] = Wiaas_Pricing::get_standard_package_customer_prices($package); return $data; } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php new file mode 100644 index 0000000..87f124b --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php @@ -0,0 +1,241 @@ +get_bundled_items(); + foreach ($bundled_items as $bundled_item) { + + $product = $bundled_item->product; + $product_cat = Wiaas_Product_Category::get_category($product); + + if (!isset($total_cost_per_category[$product_cat])) { + $total_cost_per_category[$product_cat] = 0; + } + + $total_item_cost = self::get_product_total_cost($product) * $bundled_item->get_quantity(); + + if (Wiaas_Product_Category::is_installation($product)) { + $total_cost_per_category[$product_cat] += $total_cost_per_category[$product_cat] < $total_item_cost ? + $total_item_cost : + $total_cost_per_category[$product_cat]; + } else { + $total_cost_per_category[$product_cat] += $total_item_cost; + } + } + + return array_sum(array_values($total_cost_per_category)); + } + + /** + * Calculates customer price for wiaas standard package + * @param $package + * + * @return array + */ + public static function get_standard_package_customer_prices($package) { + + $is_same_company_as_cl = self::_is_customer_same_company_as_cl(); + $package_prices = Wiaas_Package_Pricing::get_package_prices($package); + $cl_commision = (100 - Wiaas_Package_Pricing::get_package_pricing_commission($package)) / 100; + $total_cost = self::get_package_total_cost($package); + + $customer_package_prices = array(); + + foreach ($package_prices as $type => $package_price) { + $customer_package_prices[] = self::_get_package_customer_price( + $package_price, + $cl_commision, + $total_cost, + $is_same_company_as_cl); + } + + return $customer_package_prices; + + } + + /** + * Calculates customer price for wiaas addon package + * @param $addon_package + * @param $parent_package + * + * @return array + */ + public static function get_addon_package_customer_price($addon_package, $parent_package) { + + $is_same_company_as_cl = self::_is_customer_same_company_as_cl(); + $parent_total_cost = self::get_package_total_cost($parent_package); + $parent_cl_commision = (100 - Wiaas_Package_Pricing::get_package_pricing_commission($parent_package)) / 100; + $addon_package_prices = Wiaas_Package_Pricing::get_package_prices($addon_package); + + $customer_package_prices = array(); + + foreach ($addon_package_prices as $type => $addon_package_price) { + $customer_package_prices[] = self::_get_package_customer_price( + $addon_package_price, + $parent_cl_commision, + $parent_total_cost, + $is_same_company_as_cl); + } + + return $customer_package_prices; + } + + /** + * Calculates customer price for wiaas option package + * @param $option_package + * @param $parent_package + * + * @return array + */ + public static function get_option_package_customer_price($option_package, $parent_package) { + + $is_same_company_as_cl = self::_is_customer_same_company_as_cl(); + $parent_total_cost = self::get_package_total_cost($parent_package); + $parent_cl_commision = (100 - Wiaas_Package_Pricing::get_package_pricing_commission($parent_package)) / 100; + $option_package_prices = Wiaas_Package_Pricing::get_package_prices($option_package); + + $customer_package_prices = array(); + + foreach ($option_package_prices as $type => $option_package_price) { + $customer_package_prices[] = self::_get_package_customer_price( + $option_package_price, + $parent_cl_commision, + $parent_total_cost, + $is_same_company_as_cl); + } + + return $customer_package_prices; + } + + // PRIVATE + + /** + * Determines if customer and commercial lead are in the same company + * For now this is hardcoded and we have only one CL + * + * TODO: This should be changed after customer leads are handled + * @return bool + */ + private static function _is_customer_same_company_as_cl() { + $current_user = wp_get_current_user(); + $user_organization = Wiaas_User_Organization::get_user_organization($current_user->ID); + $is_same_company_as_cl = $user_organization->name === self::COMMERCIAL_LEAD_NAME; + + return $is_same_company_as_cl; + } + + /** + * Calculates customer price for wiaas package + * @param $package_price + * @param $cl_commision + * @param $total_cost + * @param $is_same_company_as_cl + * + * @return array + */ + private static function _get_package_customer_price($package_price, $cl_commision, $total_cost, $is_same_company_as_cl) { + + $package_total_margin = wiaas_get_price_margin( + $package_price['minimal_fixed_price'], + $package_price['principal_amount'], + $total_cost); + $cl_margin = $package_total_margin > 0 ? $package_total_margin * $cl_commision : 0; + + $cl_package_prices = array( + 'fixed_extra' => 0, + 'recurrent_extra' => 0, + 'services_extra' => 0 + ); + + $interest_rate = self::INTEREST_RATE; + + $customer_price = array( + 'id' => $package_price['id'], + 'payment_type' => $package_price['payment_type'], + 'max_contract_period' => $package_price['max_contract_period'], + 'package_pay_period' => $package_price['package_pay_period'], + 'period_unit' => $package_price['period_unit'], + 'services_contract_period' => $package_price['services_contract_period'], + + 'fixed_extra' => 0, + 'recurrent_extra' => 0, + 'services_extra' => 0 + ); + + if ($is_same_company_as_cl) { + + if ($package_price['package_pay_period'] > 0) { + $customer_price['fixed_extra'] = $package_price['minimal_fixed_price']; + $customer_price['recurrent_extra'] = wiaas_get_recurrent_price_mortage( + $package_price['principal_amount'], + $package_price['package_pay_period'], + $cl_margin, + $interest_rate); + } else { + $customer_price['fixed_extra'] = $package_price['minimal_fixed_price'] - $cl_margin; + $customer_price['recurrent_extra'] = 0; + } + $customer_price['services_extra'] = $package_price['minimal_services_price']; + + } else { + + $customer_price['fixed_extra'] = $cl_package_prices['fixed_extra'] + $package_price['minimal_fixed_price']; + $customer_price['recurrent_extra'] = $package_price['package_pay_period'] > 0 ? + $cl_package_prices['recurrent_extra'] + wiaas_get_recurrent_price_mortage( + $package_price['principal_amount'], + $package_price['package_pay_period'], + 0, + $interest_rate) + : 0; + $customer_price['services_extra'] = $cl_package_prices['services_extra'] + $package_price['minimal_services_price']; + } + + return $customer_price; + } +} + +Wiaas_Pricing::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-product.php b/backend/app/plugins/wiaas/includes/class-wiaas-product.php new file mode 100644 index 0000000..bdb764c --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiaas-product.php @@ -0,0 +1,10 @@ + 'Broker', )); +} + +function wiaas_db_setup_exclusive_taxonomies() { + update_option('radio_button_for_taxonomies_options', array( + 'taxonomies' => array( + 'product_cat', + 'product_country', + 'wiaas_document_types', + ), + 'delete' => 0, + )); +} + +function wiaas_db_setup_default_cl() { + wp_insert_term(Wiaas_Pricing::COMMERCIAL_LEAD_NAME, Wiaas_User_Organization::TAXONOMY_NAME); } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php new file mode 100644 index 0000000..43b9b22 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php @@ -0,0 +1,63 @@ +get_meta( '__wiaas_package_addons' ); + + $addons = array(); + + foreach ($addon_ids as $addon_id) { + $addon_package = wc_get_product( $addon_id ); + if (is_object($addon_package)) { + $addons[] = $addon_package; + } + } + + return $addons; + } + + /** + * Sets addons for provided wiaas standard package type + * @param $package + * @param $children_ids + */ + public static function set_package_addons($package, $children_ids) { + $package->update_meta_data( '__wiaas_package_addons', $children_ids ); + $package->save_meta_data(); + } +} + +Wiaas_Package_Addon::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php new file mode 100644 index 0000000..ba34f23 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php @@ -0,0 +1,95 @@ +get_meta( '_wiaas_package_option_groups' ); + + foreach ($option_groups as $option_group) { + foreach ($option_group['options'] as $group_option_id) { + if ((int) $group_option_id === $option_package->get_id()) { + return $option_group['name']; + } + } + } + + return null; + } + + /** + * Retrieve groups of optional packages configured for provided package + * @param $package + * + * @return array + */ + public static function get_package_option_groups($package) { + + $groups_data = $package->get_meta( '_wiaas_package_option_groups' ); + + $option_groups = array(); + + foreach ($groups_data as $group_data) { + $group = array( + 'id' => $group_data['id'], + 'name' => $group_data['name'], + 'default' => $group_data['default'], + 'options' => array() + ); + + foreach ($group_data['options'] as $option_id) { + $option_package = wc_get_product( $option_id ); + if (is_object($option_package)) { + $group['options'][] = $option_package; + } + } + $option_groups[] = $group; + } + + return $option_groups; + } + + /** + * Set groups of optional packages for provided package + * @param $package + * @param $groups_data + */ + public static function set_package_option_groups($package, $groups_data) { + $package->update_meta_data( '_wiaas_package_option_groups', $groups_data ); + $package->save_meta_data(); + } +} + +Wiaas_Package_Option_Groups::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-type.php b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-type.php new file mode 100644 index 0000000..3c30855 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-type.php @@ -0,0 +1,103 @@ + _x( 'Package type', 'taxonomy general name', 'wiaas' ), + 'singular_name' => _x( 'Package type', 'taxonomy singular name', 'wiaas' ), + 'search_items' => __( 'Search Package types', 'wiaas' ), + 'all_items' => __( 'All Package types', 'wiaas' ), + 'parent_item' => __( 'Parent Package type', 'wiaas' ), + 'parent_item_colon' => __( 'Parent Package type:', 'wiaas' ), + 'edit_item' => __( 'Edit Package type', 'wiaas' ), + 'update_item' => __( 'Update Package type', 'wiaas' ), + 'add_new_item' => __( 'Add New Package type', 'wiaas' ), + 'new_item_name' => __( 'New Package type Name', 'wiaas' ), + 'menu_name' => __( 'Package type', 'wiaas' ), + ); + + $args = array( + 'hierarchical' => false, + 'labels' => $labels, + 'show_ui' => false, + 'show_admin_column' => true, + 'query_var' => true, + 'rewrite' => array( 'slug' => 'package_type' ), + ); + + register_taxonomy( 'package_type', array( 'product' ), $args ); + + + // Register available package types + // standard package type is default package type for wiaas packages + + $types = apply_filters('wiaas_package_types', array('standard')); + + foreach ($types as $type) { + wp_insert_term($type, 'package_type'); + } + } + + /** + * Retrieve available wiaas package types + * @return array + */ + public static function get_available_package_types() { + $types = get_terms( array( + 'taxonomy' => 'package_type', + 'hide_empty' => false, + ) ); + + return array_map(function($type) { + return $type->name; + }, $types); + } + + /** + * Retrieve package type for provided package id + * @param $package_id + * + * @return null + */ + public static function get_package_type($package_id) { + $terms = wp_get_object_terms($package_id, 'package_type'); + $package_type = isset($terms[0]) ? $terms[0]->name : null; + return $package_type; + } + + /** + * Set package type for provided package id + * @param $package_id + * @param $type + */ + public static function set_package_type($package_id, $type) { + + wp_delete_object_term_relationships( $package_id, 'package_type' ); + + if (isset($type)) { + wp_set_object_terms($package_id, $type, 'package_type', false); + } + } +} + +Wiaas_Package_Type::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/package/wiaas-package-functions.php b/backend/app/plugins/wiaas/includes/package/wiaas-package-functions.php new file mode 100644 index 0000000..26cd623 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/package/wiaas-package-functions.php @@ -0,0 +1,91 @@ +cart->get_cart_item($option_cart_item_id); + + if (isset($option_cart_item)) { + $option_cart_items[] = $option_cart_item; + } + } + } + + return $option_cart_items; +} + +/** + * Collect addon packages for provided order item package + * @param $order_items + * @param $parent_order_item + * + * @return array + */ +function wiaas_get_order_item_addons($order_items, $parent_order_item) { + $addon_order_items = array(); + + if (isset($parent_order_item['wiaas_addon_items']) && isset($parent_order_item['bundle_cart_key'])) { + foreach ($order_items as $order_item) { + if (isset($order_item['bundle_cart_key']) && $order_item['wiaas_addon_for'] === $parent_order_item['bundle_cart_key']) { + $addon_order_items[] = $order_item; + } + } + } + + return $addon_order_items; +} + +/** + * Collect addon packages cart items for provided cart item + * @param $cart_item + * + * @return array + */ +function wiaas_get_cart_item_addons($cart_item) { + $addon_cart_items = array(); + + if (isset($cart_item['_wiaas_addon_items'])) { + $addon_cart_items_ids = $cart_item['_wiaas_addon_items']; + + foreach ($addon_cart_items_ids as $addon_cart_item_id) { + $addon_cart_item = WC()->cart->get_cart_item($addon_cart_item_id); + + if (isset($addon_cart_item)) { + $addon_cart_items[] = $addon_cart_item; + } + } + } + + return $addon_cart_items; +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-pricing.php b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php similarity index 58% rename from backend/app/plugins/wiaas/includes/package/class-wiaas-package-pricing.php rename to backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php index b2362f1..9ebbd32 100644 --- a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-pricing.php +++ b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php @@ -1,5 +1,9 @@ 0 ); - /** - * Meta key for pricing rules - * @var string - */ - private static $package_prices_meta_key = '_wiaas_pricing_rules'; - public static function init() { - add_filter( 'woocommerce_product_get_price', array( __CLASS__, 'on_get_price' ), 10, 2 ); + add_filter('woocommerce_bundle_price_html', array( __CLASS__, 'get_package_price_html' ), 10, 2); + } - add_filter('woocommerce_checkout_create_order_line_item_object', array( __CLASS__, 'record_price_for_order_line_item' ), 10, 4); + public static function get_package_price_html($price_html, $package) { + $bundled_items = $package->get_bundled_items(); + + $recurring_price = 0; + + foreach ($bundled_items as $bundled_item) { + $product = $bundled_item->product; + $product_price = Wiaas_Product_Pricing::get_product_price($product); + if ($product_price['is_recurring']) { + $recurring_price += $product_price['price'] * $bundled_item->get_quantity(); + } + } + + $price_html = 'Fixed: ' . $price_html . ' and ' . $recurring_price . ' / month'; + + return $price_html; } /** @@ -73,50 +87,6 @@ class Wiaas_Package_Pricing { return self::$payment_fields; } - /** - * Retrieve customer selected package price from session when adding package to cart - * @param $base_price - * @param $product - * - * @return mixed - */ - public static function on_get_price($base_price, $package) { - if ( empty( $package ) || - empty( $base_price ) || - $package->get_type() !== 'bundle' || - !isset(WC()->session)) { - return $base_price; - } - $result_price = $base_price; - - $preferred_price_id = WC()->session->get('wiaas_price_' . $package->get_id(), null); - - if (isset($preferred_price_id)) { - $prices = self::get_package_prices($package); - $preferred_price = $prices[$preferred_price_id]; - $result_price = $preferred_price['minimal_fixed_price']; - } - - return $result_price; - } - - /** - * Persist used payment type informations for package in corresponding order line item - * @param $order_item - * @param $cart_item_key - * @param $cart_item - * @param $order - * - * @return mixed - */ - public static function record_price_for_order_line_item($order_item, $cart_item_key, $cart_item, $order) { - if (wc_pb_is_bundle_container_cart_item($cart_item)) { - $order_item->add_meta_data('_wiaas_payment', $cart_item['_wiaas_price']); - } - - return $order_item; - } - /** * Retrieve configured payment prices for package * @param $package @@ -124,7 +94,33 @@ class Wiaas_Package_Pricing { * @return array */ public static function get_package_prices($package) { - $pricing_rules = $package->get_meta( self::$package_prices_meta_key ); + return self::_get_package_prices($package); + } + + public static function get_package_pricing_commission($package) { + return self::_get_package_pricing_commision($package); + } + + /** + * Persist payment prices configuration for package + * @param $package + * @param $pricing_rules + */ + public static function set_package_prices($package, $pricing_rules, $commision) { + if ( isset( $pricing_rules ) ) { + $package->update_meta_data( '_wiaas_pricing_rules', $pricing_rules ); + $package->update_meta_data('_package_pricing_commision', $commision, true); + } else { + $package->delete_meta_data( '_wiaas_pricing_rules' ); + } + $package->save_meta_data(); + } + + // PRIVATE + + private static function _get_package_prices($package) { + $pricing_rules = $package->get_meta( '_wiaas_pricing_rules' ); + $commision = self::_get_package_pricing_commision($package); $prices = array(); foreach ($pricing_rules as $type => $pricing_rule) { @@ -138,10 +134,10 @@ class Wiaas_Package_Pricing { 'package_pay_period' => floatval($pay_type['package_pay_period']), 'period_unit' => $pay_type['period_unit'], 'services_contract_period' => $pay_type['services_contract_period'], + 'commision_split' => $commision / 100.00, 'minimal_fixed_price' => floatval($pricing_rule['minimal_fixed_price']), 'principal_amount' => floatval($pricing_rule['principal_amount']), - 'recurrent_price' => 0, 'minimal_services_price' => floatval($pricing_rule['minimal_services_price']), ); } @@ -149,18 +145,14 @@ class Wiaas_Package_Pricing { return $prices; } - /** - * Persist payment prices configuration for package - * @param $package - * @param $pricing_rules - */ - public static function set_package_prices($package, $pricing_rules) { - if ( isset( $pricing_rules ) ) { - $package->update_meta_data( self::$package_prices_meta_key, $pricing_rules ); - } else { - $package->delete_meta_data( self::$package_prices_meta_key ); + private static function _get_package_pricing_commision($package) { + $commision = $package->get_meta( '_package_pricing_commision', true); + + if (!isset($commision) || $commision === '') { + return 50.00; } - $package->save_meta_data(); + + return (float) $commision; } } diff --git a/backend/app/plugins/wiaas/includes/pricing/class-wiaas-product-pricing.php b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-product-pricing.php new file mode 100644 index 0000000..baf9784 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-product-pricing.php @@ -0,0 +1,139 @@ +product; + + return isset($bundled_product) ? + !self::_get_is_product_price_recurring($bundled_product) : + false; + } + + /** + * Retrives fixed price for bundled product + * @param $price + * @param $product + * @param $discount + * @param $bundled_item + * + * @return int + */ + public static function get_bundled_product_fixed_price($price, $product, $discount, $bundled_item) { + if (self::_get_is_product_price_recurring($product)) { + return 0; + } + return $price; + } + + /** + * Builds html for product + * @param $price + * @param $object + * + * @return string + */ + public static function get_product_price_html($price, $object) { + + if ($object instanceof WC_Product_Simple) { + $is_recurring = self::_get_is_product_price_recurring($object); + if ($is_recurring) { + $price .= ' / month'; + } + } + + return $price; + } + + /** + * Retrieves product configured price + * @param $product + * + * @return array + */ + public static function get_product_price($product) { + $is_recurring = self::_get_is_product_price_recurring($product); + $pay_period = self::_get_product_price_pay_period($product); + + return array( + 'price' => $product->get_price(), + 'is_recurring' => $is_recurring, + 'pay_period' => $pay_period + ); + } + + /** + * Sets configured product price + * @param $product + * @param $price + * @param bool $is_recurring + * @param int $pay_period + */ + public static function set_product_price($product, $price, $is_recurring = false, $pay_period = 0) { + $product->set_price($price); + self::_set_is_product_price_recurring($product, $is_recurring); + self::_set_product_price_pay_period($product, $pay_period); + + $product->save_meta_data(); + + } + + // PRIVATE + + private static function _get_is_product_price_recurring($product) { + return $product->get_meta( '_wiaas_is_product_price_recurring', true) === 'yes'; + } + + private static function _get_product_price_pay_period($product) { + return (int) $product->get_meta( '_wiaas_product_pay_period', true); + } + + private static function _set_is_product_price_recurring($product, $is_recurring) { + $product->update_meta_data('_wiaas_is_product_price_recurring', $is_recurring ? 'yes' : 'no'); + } + + + private static function _set_product_price_pay_period($product, $pay_period) { + $product->update_meta_data('_wiaas_product_pay_period', (int) $pay_period); + } + +} + +Wiaas_Product_Pricing::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/pricing/wiaas-pricing-functions.php b/backend/app/plugins/wiaas/includes/pricing/wiaas-pricing-functions.php new file mode 100644 index 0000000..1a2baef --- /dev/null +++ b/backend/app/plugins/wiaas/includes/pricing/wiaas-pricing-functions.php @@ -0,0 +1,51 @@ + 4.282, + 30 => 3.451, + 36 => 2.896, + 42 => 2.500, + 48 => 2.223, + 54 => 2.025, + 60 => 1.834 + ]; + + $interest = isset($rates[$num_of_payments]) ? $rates[$num_of_payments] : 10; + + return round($PV * ($interest / 100)); +} + +function wiaas_get_recurrent_price_mortage($principal_amount, $pay_period, $margin, $interest_rate) { + $new_principal_amount = $principal_amount - $margin; + $interest_rate = $interest_rate / 100; + $fixed_mortage = wiaas_PMT($interest_rate, $pay_period, $new_principal_amount); + + return round($fixed_mortage, 2); +} + +function wiaas_get_price_margin($fixed_price, $principal_amount, $total_cost) { + $total_gain = $fixed_price + $principal_amount; + return $total_gain - $total_cost; +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/product/class-wiaas-product-category.php b/backend/app/plugins/wiaas/includes/product/class-wiaas-product-category.php new file mode 100644 index 0000000..fe7e70e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/product/class-wiaas-product-category.php @@ -0,0 +1,107 @@ + array( + 'name' => 'Hardware', + 'type' => 'product', + ), + 'software' => array( + 'name' => 'Software', + 'type' => 'product', + ), + 'service' => array( + 'name' => 'Service', + 'type' => 'service', + ), + 'installation' => array( + 'name' => 'Installation', + 'type' => 'installation', + ), + ); + + public static function init() { + + add_action('woocommerce_after_register_taxonomy', array(__CLASS__, 'register_product_categories')); + } + + /** + * Registers available wiaas product categories + */ + public static function register_product_categories() { + + foreach (self::$available_product_categories as $key => $available_product_category) { + wp_insert_term($key, 'product_cat'); + } + } + + /** + * Retrieves category for provided product + * @param $product + * + * @return string|null + */ + public static function get_category($product) { + $product_categories = get_the_terms($product->get_id(), 'product_cat'); + return is_array($product_categories) && isset($product_categories[0]) ? + $product_categories[0]->name : + null; + } + + /** + * Determines if provided product is installation + * @param $product + * + * @return bool + */ + public static function is_installation($product) { + return self::_get_product_category_type($product) === 'installation'; + } + + /** + * Determines if provided product is service + * @param $product + * + * @return bool + */ + public static function is_service($product) { + return self::_get_product_category_type($product) === 'service'; + } + + + + // PRIVATE + + + /** + * Retrives product type based on its category for provided product + * @param $product + * + * @return null + */ + private static function _get_product_category_type($product) { + $product_categories = get_the_terms($product->get_id(), 'product_cat'); + + return is_array($product_categories) && + isset($product_categories[0]) && + isset(self::$available_product_categories[$product_categories[0]->name]) ? + self::$available_product_categories[$product_categories[0]->name]['type'] : null; + } +} + +Wiaas_Product_Category::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/wiaas.php b/backend/app/plugins/wiaas/wiaas.php index fa6fb49..a9220a1 100644 --- a/backend/app/plugins/wiaas/wiaas.php +++ b/backend/app/plugins/wiaas/wiaas.php @@ -26,10 +26,20 @@ include_once WIAAS_DIR . '/includes/class-wiaas-delivery-process.php'; include_once WIAAS_DIR . '/includes/class-wiaas-order.php'; +include_once WIAAS_DIR . '/includes/class-wiaas-product.php'; + include_once WIAAS_DIR . '/includes/class-wiaas-package.php'; include_once WIAAS_DIR . '/includes/class-wiaas-user.php'; +include_once WIAAS_DIR . '/includes/class-wiaas-pricing.php'; + +include_once WIAAS_DIR . '/includes/class-wiaas-countries.php'; + +include_once WIAAS_DIR . '/includes/class-wiaas-documents.php'; + +include_once WIAAS_DIR . '/includes/class-wiaas-cart.php'; + include_once WIAAS_DIR . '/includes/class-wiaas-api.php'; include_once WIAAS_DIR . '/includes/class-wiaas-admin.php'; diff --git a/backend/composer.json b/backend/composer.json index 1fe0274..ba1ff64 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -61,6 +61,7 @@ "wpackagist-plugin/jwt-authentication-for-wp-rest-api": "1.2.4", "wpackagist-plugin/capability-manager-enhanced": "1.5.9", "wpackagist-plugin/wp-user-groups": "2.2.0", + "wpackagist-plugin/radio-buttons-for-taxonomies": "1.8.3", "3rdparty/gravityforms": "*", "3rdparty/gravityflow": "*", @@ -94,6 +95,7 @@ "wp plugin activate capability-manager-enhanced", "wp plugin activate groups", "wp plugin activate wp-user-groups", + "wp plugin activate radio-buttons-for-taxonomies", "wp plugin activate wiaas" ], "update-db": [ diff --git a/backend/composer.lock b/backend/composer.lock index 527c55b..69b5834 100644 --- a/backend/composer.lock +++ b/backend/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "302f569929ecdaf4d349b0bf764de74c", + "content-hash": "d979d3435513dd818189e2f68cc023fe", "packages": [ { "name": "3rdparty/gravityflow", @@ -568,6 +568,26 @@ "type": "wordpress-plugin", "homepage": "https://wordpress.org/plugins/mailchimp-for-woocommerce/" }, + { + "name": "wpackagist-plugin/radio-buttons-for-taxonomies", + "version": "1.8.3", + "source": { + "type": "svn", + "url": "https://plugins.svn.wordpress.org/radio-buttons-for-taxonomies/", + "reference": "tags/1.8.3" + }, + "dist": { + "type": "zip", + "url": "https://downloads.wordpress.org/plugin/radio-buttons-for-taxonomies.1.8.3.zip", + "reference": null, + "shasum": null + }, + "require": { + "composer/installers": "~1.0" + }, + "type": "wordpress-plugin", + "homepage": "https://wordpress.org/plugins/radio-buttons-for-taxonomies/" + }, { "name": "wpackagist-plugin/woocommerce-gateway-paypal-express-checkout", "version": "1.5.6", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 57bacec..56663e7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -4336,11 +4336,6 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index c2fddb8..7c2859d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "@tinymce/tinymce-react": "^2.0.3", "axios": "^0.17.0", "bootstrap": "^4.0.0-beta.2", + "classnames": "^2.2.5", "flag-icon-css": "^2.8.0", "font-awesome": "^4.7.0", "glamor": "^2.20.40", diff --git a/frontend/src/actions/coMarket/coMarketPackageDetailsActions.js b/frontend/src/actions/coMarket/coMarketPackageDetailsActions.js index a3a651b..f67c7a9 100644 --- a/frontend/src/actions/coMarket/coMarketPackageDetailsActions.js +++ b/frontend/src/actions/coMarket/coMarketPackageDetailsActions.js @@ -55,7 +55,7 @@ export const fetchPackageDetails = (params) => { if(packageData.groups){ Object.keys(packageData.groups).forEach((idGroup) => { - const defaultOption = packageData.groups[idGroup].options.find((option) => {return parseInt(option.isDefault, 10) === 1}); + const defaultOption = packageData.groups[idGroup].options.find((option) => option.isDefault); if(defaultOption){ dispatch(selectOption(idGroup, defaultOption)); } @@ -71,16 +71,18 @@ export const fetchPackageDetails = (params) => { } } -const generateOptions = (selectedOptions, selectedAdditionals, selectedAgreement) => { - const extraPackages = []; +const collectPackageOptionsAndAdditionals = (selectedOptions, selectedAdditionals, selectedAgreement) => { + const optionPackages = []; + const additionalPackages = []; const unavailablePackages = []; + if(selectedAdditionals && selectedAdditionals.length){ selectedAdditionals.forEach(additional => { const selectedPrice = priceHelper.getSelectedPrice(additional, selectedAgreement); if(!selectedPrice){ unavailablePackages.push(additional); }else{ - extraPackages.push(additional.idAdditionalPackage); + additionalPackages.push(additional.idAdditionalPackage); } }); } @@ -91,12 +93,12 @@ const generateOptions = (selectedOptions, selectedAdditionals, selectedAgreement if(!selectedPrice){ unavailablePackages.push(selectedOptions[idGroup]); }else{ - extraPackages.push(selectedOptions[idGroup].idOptionPackage); + optionPackages.push(selectedOptions[idGroup].idOptionPackage); } }); } - return {extraPackages, unavailablePackages}; + return {optionPackages, additionalPackages, unavailablePackages}; }; const requestAddToCart = () => ({ @@ -104,20 +106,24 @@ const requestAddToCart = () => ({ }); export const addToCart = (addParams) => { - // const options = generateOptions(addParams.selectedOptions, addParams.selectedAdditionals, addParams.selectedAgreement); + const result = collectPackageOptionsAndAdditionals( + addParams.selectedOptions, + addParams.selectedAdditionals, + addParams.selectedAgreement); const params = { 'package_id': addParams.selectedPackage.id, 'price_id': addParams.selectedAgreement.idPrice, - //options: options.extraPackages + 'addons': result.additionalPackages, + 'options': result.optionPackages }; - // if(options.unavailablePackages.length){ - // const unavailable = options.unavailablePackages.map((unavailable) =>{return unavailable.optionName || unavailable.packageName;}); - // const message = coMarketMessages.UNAVAILABLE_PACKAGES + ' ' + unavailable.join(); - // - // return dispatch => {dispatch(updateMessages([{code: 'warning', message}], coMarketMessages))}; - // } + if(result.unavailablePackages.length){ + const unavailable = result.unavailablePackages.map((unavailable) =>{return unavailable.optionName || unavailable.packageName;}); + const message = coMarketMessages.UNAVAILABLE_PACKAGES + ' ' + unavailable.join(); + + return dispatch => {dispatch(updateMessages([{code: 'warning', message}], coMarketMessages))}; + } return dispatch => { dispatch(requestAddToCart()); diff --git a/frontend/src/constants/cartConstants.js b/frontend/src/constants/cartConstants.js index 63117f2..1bee54c 100644 --- a/frontend/src/constants/cartConstants.js +++ b/frontend/src/constants/cartConstants.js @@ -143,7 +143,7 @@ export const cartTexts = { REMOVE_ITEM_HEADER: 'Remove item confirmation', REMOVE_ITEM_TEXT: 'Are you sure you want to remove ', REMOVE_FROM_CART: 'Remove from cart', - ADDITIOONAL_PACKAGE: 'Additional package', + ADDITIOONAL_PACKAGE: 'Addons', DOC_NOT_REQUIRED: 'Document not required', FILE_UPLOADED_TEXT: 'File uploaded! Select or drop to replace ', FILE: 'file', diff --git a/frontend/src/constants/coMarketConstants.js b/frontend/src/constants/coMarketConstants.js index d78376d..9959a5b 100644 --- a/frontend/src/constants/coMarketConstants.js +++ b/frontend/src/constants/coMarketConstants.js @@ -84,7 +84,7 @@ export const coMarketTexts = { ON_DELIVERY: 'On delivery', MONTHLY: 'Monthly', NOT_AVAILABLE: 'Not available', - SELECTION_NOT_AVAILABLE: 'This selection is not available for the selected price type!', + SELECTION_NOT_AVAILABLE: 'Not available for price type', RECURRENT_PRICE: 'Package recurent price', SERVICE_PRICE: 'Services and support', EXTEND: 'with possibility to extend each', diff --git a/frontend/src/containers/cart/CartItemsContainer.jsx b/frontend/src/containers/cart/CartItemsContainer.jsx index a28e840..a145bcf 100644 --- a/frontend/src/containers/cart/CartItemsContainer.jsx +++ b/frontend/src/containers/cart/CartItemsContainer.jsx @@ -32,36 +32,39 @@ class CartItemsContainer extends Component { isFormDisabled={isCartItemsDisabled}/>)}
- - - {cartTexts.labels.TOTAL_PRICE}: + + + + {cartTexts.labels.TOTAL_PRICE}: + { orderTotalPrice && - - - - - - - - - - - +
+
+
+ {cartTexts.labels.ON_DELIVERY}: + + + {cartTexts.labels.MONTHLY}: + + +
+
+
{orderTotalPrice.fixedPrice.toLocaleString()} {orderTotalPrice.currency} {' '} - -
+
{ orderTotalPrice.recurrentPrice && orderTotalPrice.recurrentPrice.toLocaleString() + ' ' + orderTotalPrice.currency } - - - -
{cartTexts.labels.ON_DELIVERY}{cartTexts.labels.MONTHLY}
+
+ + +
- + + +
+ } diff --git a/frontend/src/containers/cart/CartReviewOrderContainer.jsx b/frontend/src/containers/cart/CartReviewOrderContainer.jsx index 7138ea8..2eade59 100644 --- a/frontend/src/containers/cart/CartReviewOrderContainer.jsx +++ b/frontend/src/containers/cart/CartReviewOrderContainer.jsx @@ -93,7 +93,7 @@ class CartReviewOrderContainer extends Component { {customerDetails.details.idProject ? this.getProjectName(customerDetails.details.idProject) : '-'}
-

{cartTexts.labels.DELIVERY_ADDRESS}

+
{cartTexts.labels.DELIVERY_ADDRESS}
{cartTexts.labels.ADDRESS} {customerDetails.delivery.detailedAddress} @@ -113,7 +113,7 @@ class CartReviewOrderContainer extends Component {
-

{cartTexts.labels.BILLING_ADDRESS}

+
{cartTexts.labels.BILLING_ADDRESS}
{cartTexts.labels.COMPANY} {customerDetails.companyName} diff --git a/frontend/src/containers/cart/components/CartItem.jsx b/frontend/src/containers/cart/components/CartItem.jsx index 4e6648c..9618061 100644 --- a/frontend/src/containers/cart/components/CartItem.jsx +++ b/frontend/src/containers/cart/components/CartItem.jsx @@ -7,6 +7,7 @@ import {updateQuantity, removeCartItem} from '../../../actions/cart/cartActions' import {setDialogContent, setDialogOpenFlag} from '../../../actions/dialog/dialogActions'; import {cartMessages, cartTexts} from '../../../constants/cartConstants'; import PackageBids from './PackageBids.jsx'; +import {coMarketTexts} from "../../../constants/coMarketConstants"; class CartItem extends Component { constructor(props) { @@ -88,17 +89,17 @@ class CartItem extends Component { totalRecurrent += selectedBid.servicesPrice + selectedBid.recurrentPrice; oldTotal = cartItem.fixedPrice; - oldTotalRecurrent = cartItem.servicesPrice + cartItem.recurentPrice; + oldTotalRecurrent = cartItem.servicesPrice + cartItem.recurrentPrice; }else{ total += cartItem.fixedPrice; - totalRecurrent += cartItem.servicesPrice + cartItem.recurentPrice; + totalRecurrent += cartItem.servicesPrice + cartItem.recurrentPrice; } if(cartItem.options.length) { cartItem.options.forEach((packageOption) => { if(Object.keys(packageOption.prices).length) { total += parseFloat(packageOption.prices.fixedExtra); - totalRecurrent += parseFloat(packageOption.prices.recurentExtra) + parseFloat(packageOption.prices.servicesExtra); + totalRecurrent += parseFloat(packageOption.prices.recurrentExtra) + parseFloat(packageOption.prices.servicesExtra); } }); } @@ -106,7 +107,7 @@ class CartItem extends Component { cartItem.additionalPackages.forEach((additionalPackage) => { if(Object.keys(additionalPackage).length) { total += parseFloat(additionalPackage.prices.fixedExtra); - totalRecurrent += parseFloat(additionalPackage.prices.recurentExtra) + parseFloat(additionalPackage.prices.servicesExtra); + totalRecurrent += parseFloat(additionalPackage.prices.recurrentExtra) + parseFloat(additionalPackage.prices.servicesExtra); } }); } @@ -201,43 +202,52 @@ class CartItem extends Component { } {cartItem.options.length > 0 && cartItem.options.map((packageOption) => - - + + {packageOption.groupName}: - - + + {packageOption.packageName} - + ) } - {cartItem.additionalPackages.length > 0 && - cartItem.additionalPackages.map((additionalPackage) => - - + { + cartItem.additionalPackages.length > 0 && + {cartTexts.labels.ADDITIOONAL_PACKAGE}: - - - {additionalPackage.packageName} - + + { + cartItem.additionalPackages.map((additionalPackage) => + + {additionalPackage.packageName} + + ) + } - ) } - - - {cartItem.payType}: + + + {cartItem.payType}: - - - - - - - - - - - +
+
+
+ {cartTexts.labels.ON_DELIVERY}: + + + {cartTexts.labels.MONTHLY}: + + +
+
{ this.state.fixedPrice &&
@@ -251,8 +261,8 @@ class CartItem extends Component {
} - - { this.state.recurrentPrice &&
@@ -265,10 +275,9 @@ class CartItem extends Component {
} - - - -
{cartTexts.labels.ON_DELIVERY}{cartTexts.labels.MONTHLY}
+
+ +
+ +
+ diff --git a/frontend/src/containers/cart/style/Cart.scss b/frontend/src/containers/cart/style/Cart.scss index 02b1bd3..0b18637 100644 --- a/frontend/src/containers/cart/style/Cart.scss +++ b/frontend/src/containers/cart/style/Cart.scss @@ -2,7 +2,7 @@ #cart-count { vertical-align: middle; - color: $cart-count-color; + color: $accentColor; font-size: 1.5rem; border-radius: 1rem; font-family: arial,sans-serif; @@ -46,6 +46,11 @@ font-weight: $font-weight; } + .cart-item-additional-title { + font-weight: 600; + color: $font-light-color; + } + .cart-item-details { .item-name { } @@ -65,14 +70,34 @@ } .item-price { - background-color: $hoverColor; + background-color: #fbfbfb; margin-top: 1rem; - border-radius: $box-radius; + + .item-price-type { + padding: 0.4rem; + color: $font-light-color; + font-weight: 600; + } + + .item-price-header { + font-weight: 600; + color: $font-light-color; + padding: 0.4rem; + } + + .item-price-value { + padding: 0.4rem; + } } .cart-total-price { padding: 1rem 0; font-size: $font-size-big; + + .cart-total-price-header { + color: $font-light-color; + font-weight: 600; + } } .price-table th{ @@ -105,17 +130,27 @@ #cart-review-order-container { border-radius: $box-radius; + + .cart-customer-main-info-row { padding: 0.5rem; text-align: left; + > div:first-child { + color: $font-light-color; + font-weight: 600; + } } .place-order-btn { cursor: pointer; - background-color: $done-status-color; + background-color: $accentColor; + border: none; width: 100%; float: right; font-weight: $font-weight; + &:focus, &:hover { + box-shadow: 0 0 0 0.1rem lighten($accentColor, 0.9) !important; + } } .button-cart { diff --git a/frontend/src/containers/coMarket/CoMarketPackageDetailsContainer.jsx b/frontend/src/containers/coMarket/CoMarketPackageDetailsContainer.jsx index c5eeeb7..016a506 100644 --- a/frontend/src/containers/coMarket/CoMarketPackageDetailsContainer.jsx +++ b/frontend/src/containers/coMarket/CoMarketPackageDetailsContainer.jsx @@ -5,7 +5,7 @@ import WiaasBox from '../../mainComponents/box/WiaasBox.jsx'; import {fetchPackageDetails, addToCart} from '../../actions/coMarket/coMarketPackageDetailsActions'; import PackageInfo from './components/PackageInfo.jsx'; import PackagePrice from './components/PackagePrice.jsx'; -import PackageOptions from './components/PackageOptions.jsx'; +import PackageOptionGroup from './components/PackageOptionGroup'; import AdditionalPackages from './components/AdditionalPackages.jsx'; import AgreementOptions from './components/AgreementOptions.jsx'; import {coMarketTexts} from '../../constants/coMarketConstants'; @@ -64,21 +64,30 @@ class CoMarketPackageDetailsContainer extends Component {
- { - selectedPackage.groups && Object.keys(selectedPackage.groups).length > 0 && selectedAgreement && - - } + + { selectedPackage.additionalPackages && selectedPackage.additionalPackages.length > 0 && selectedAgreement && + currency={selectedPackage.currency}/> + } + { + selectedPackage.groups && Object.keys(selectedPackage.groups).length > 0 && selectedAgreement && + (
+ { + Object.keys(selectedPackage.groups).map(groupKey => { + const group = selectedPackage.groups[groupKey]; + return (); + }) + } +
) } -