diff --git a/backend/app/plugins/wiaas/assets/css/package.css b/backend/app/plugins/wiaas/assets/css/package.css index 08fe4cc..3cb3f82 100644 --- a/backend/app/plugins/wiaas/assets/css/package.css +++ b/backend/app/plugins/wiaas/assets/css/package.css @@ -128,4 +128,9 @@ #your-profile label[for="role"], #your-profile label[for="url"],#your-profile #role, #your-profile #url{ display: none; +} + +#adminmenu #toplevel_page_wiaas-cl-packages div.wp-menu-image::before { + font-family: WooCommerce!important; + content: '\e006'; } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages-list.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages-list.php new file mode 100644 index 0000000..2cd40aa --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages-list.php @@ -0,0 +1,129 @@ + 'Package', + 'plural' => 'Packages', + 'ajax' => false, + ) ); + + return true; + } + public function column_default( $item, $column_name ) { + switch ( $column_name ) { + case 'thumb': + return '' . + $item->get_image( 'thumbnail' ) . + ''; + case 'name': + return '' . + esc_attr( $item->get_name() ) . + '' . + '
ID: '. $item->get_id() . '
'; + case 'country': + $country = Wiaas_Countries::get_package_country($item); + if (! empty($country)) { + return ''. $country['name'] . ''; + } + return ''; + case 'type': + $type = Wiaas_Package_Type::get_package_type($item->get_id()); + return ''. $type . ''; + + } + } + + + public function prepare_items() { + $columns = $this->get_columns(); + $sortable = $this->get_sortable_columns(); + $this->_column_headers = array( $columns, $sortable ); + + $items_per_page = 10; + + $current_page = $this->get_pagenum(); + + $query_args = array( + 'status' => 'publish', + 'type' => 'bundle', + 'tag' => array(), + 'limit' => $items_per_page, + 'page' => $current_page, + 'paginate' => true + ); + + if (!empty($_REQUEST['s'])) { + $query_args['s'] = sanitize_text_field($_REQUEST['s']); + } + + $results = wc_get_products($query_args); + + $this->items = $results->products; + + $this->set_pagination_args( array( + 'total_items' => $results->total, + 'per_page' => $items_per_page, + ) ); + + return true; + + } + + public function get_views() { + + return array(); + } + + public function get_columns() { + $columns = array( + 'thumb' => __( '', 'wiaas' ), + 'name' => __( 'Name', 'wiaas' ), + 'country' => __( 'Sell in', 'wiaas' ), + 'type' => __( 'Type', 'wiaas' ), + ); + + return $columns; + } + + public function get_primary_column_name() { + return 'product_name'; + } + + public function get_sortable_columns() { + $sort = array( + 'product_name' => array( 'product_name', true ), + ); + + return $sort; + } + + public function no_items() { + _e( 'No packages found.', 'wiaas' ); + return true; + } +} + +function wiaas_handle_custom_query_var($query, $query_vars) { + if ( ! empty( $query_vars['catalogue'] ) ) { + + $query['meta_query'][] = array( + 'key' => '_wiaas_catalogue_'.$query_vars['catalogue'], + 'value' => 'yes', + ); + } + + return $query; +} + +add_filter('woocommerce_product_data_store_cpt_get_products_query', 'wiaas_handle_custom_query_var', 10, 2); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php new file mode 100644 index 0000000..fe8b56b --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/class-wiaas-admin-cl-packages.php @@ -0,0 +1,170 @@ +prepare_items(); + + require 'views/html-admin-cl-packages-page.php'; + } + + public static function output_package() { + wp_enqueue_script( 'jquery-ui-tabs' ); + + $package_id = absint( $_GET['id'] ); + + $package = wc_get_product($package_id); + + if (!$package) { + return; + } + + if (! empty($_POST['wiaas_save_cl_extras_nonce']) && ! empty($_POST['cl_extras'])) { + if (wp_verify_nonce($_POST['wiaas_save_cl_extras_nonce'], 'wiaas_save_cl_extras')) { + self::_handle_cl_extras_update($package_id); + } + } + + $bundled_items = $package->get_bundled_items(); + + $bundled_items_per_category = array(); + foreach ($bundled_items as $bundled_item) { + $category = Wiaas_Product_Category::get_category($bundled_item->product); + if (isset($category)) { + if ($category ==='hardware' || $category === 'software') { + $category = 'products'; + } + $bundled_items_per_category[$category] ?: array(); + $bundled_items_per_category[$category][] = $bundled_item; + } + } + + $configured_prices = Wiaas_Package_Pricing::get_package_prices($package); + + $cl_id = wiaas_get_current_user_organization_id(); + + $cl_extras = Wiaas_Package_CL_Pricing::get_extras($cl_id, $package_id); + + $has_default_cl_extras = ! empty($cl_extras); + + // default values for catalogue package + if (! $has_default_cl_extras) { + $cl_extras = array(); + + foreach ($configured_prices as $type => $configured_price) { + $cl_extras[$type.'_default'] = array( + 'visible' => true, + 'fixed' => 0, + 'services' => 0, + 'recurrent' => 0 + ); + } + } + + $package_cl_extra_types = array_keys($cl_extras); + + $customer_ids_with_extras = array(); + foreach ($package_cl_extra_types as $package_cl_extra_type) { + $customer_id_with_extras = explode('_customer_', $package_cl_extra_type)[1]; + + if (isset($customer_id_with_extras) && ($customer_id_with_extras = absint($customer_id_with_extras)) > 0) { + $customer_ids_with_extras[] = $customer_id_with_extras; + } + } + $customer_ids_with_extras = array_unique($customer_ids_with_extras); + + require 'views/html-cl-package-details.php'; + } + + + + + // PRIVATE HANDLERS + + private static function _handle_cl_extras_update($package_id) { + $cl_extras = wp_unslash($_POST['cl_extras']); + + $pay_types = array_keys(Wiaas_Package_Pricing::get_available_pay_types()); + + $posted_cl_extras = array(); + + foreach ($cl_extras as $cl_extra) { + + $customer_id = isset($cl_extra['customer']) ? absint($cl_extra['customer']) : 0; + $type = sanitize_key($cl_extra['type']); + + $fixed_extra = isset($cl_extra['fixed']) ? floatval($cl_extra['fixed']) : 0; + $services_extra = isset($cl_extra['services']) ? floatval($cl_extra['services']) : 0; + $recurrent_extra = isset($cl_extra['recurrent']) ? floatval($cl_extra['recurrent']) : 0; + + $extra_type = $customer_id > 0 ? $type.'_customer_'.$customer_id : $type.'_default'; + + if (in_array($type, $pay_types)) { + $posted_cl_extras[$extra_type] = array( + 'type' => $type, + 'visible' => $cl_extra['visible'] === 'on', + 'fixed' => $fixed_extra, + 'services' => $services_extra, + 'recurrent' => $recurrent_extra, + ); + } + } + + Wiaas_Package_CL_Pricing::set_extras( + wiaas_get_current_user_organization_id(), + $package_id, + $posted_cl_extras + ); + } +} + +Wiaas_Admin_CL_Packages::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-admin-cl-packages-page.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-admin-cl-packages-page.php new file mode 100644 index 0000000..a927c22 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-admin-cl-packages-page.php @@ -0,0 +1,43 @@ + + + + +
+

+ ' . esc_html__( 'Search results for', 'wiaas' ) . ' "' . sanitize_text_field( $_REQUEST['s'] ) . '"'; + } + ?> +

+ + + +
+ + search_box( __( 'Search Products', 'wiaas' ), 'wiaas_packages_search_id' ); ?> + display(); ?> +
+ +
\ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php new file mode 100644 index 0000000..c94fa49 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-details.php @@ -0,0 +1,296 @@ + + + + + + +
+
+
+
+
+
+
+
+
+ $category_bundled_items) { + echo sprintf( + '%s (%s)', + esc_attr( $category ), + esc_attr(count($category_bundled_items)) ); + foreach ($category_bundled_items as $bundled_item) { + $title = $bundled_item->product->get_title(); + echo sprintf( '

%s x %s

', esc_attr($bundled_item->get_quantity('max')), esc_attr( $title ) ); + } + } + ?> +
+
+
+
+
+
+ +
+ +
+
+
+
+

get_name(); ?>

+
+
+
+
+ + get_short_description())) { + ?> +
+ get_short_description(), 'content', array( + '_content_editor_dfw' => $_content_editor_dfw, + 'drag_drop_upload' => false, + 'media_buttons' => false, + 'quicktags' => false, + 'tabfocus_elements' => 'content-html', + 'tinymce' => array( + 'resize' => false, + 'wp_autoresize_on' => true, + 'add_unload_trigger' => false, + 'wp_keep_scroll_position' => ! $is_IE, + 'readonly'=> true, + 'toolbar' => false, + ), + ) ); ?> +
+ + +
+
+
+
+ +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ + +
+ + + +
+ + + +
+
+ +
+ + +
+ + +
+ + + + +
+
+ +
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php new file mode 100644 index 0000000..e4cc6c1 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/views/html-cl-package-prices.php @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + $configured_price) { + + $extra_type = isset($customer_id) ? $type.'_customer_'.$customer_id : $type.'_default'; + + ?> + + + + + + + + + + + + + + + +
+ '. esc_html(wiaas_get_organization_name($customer_id)). ''; + } + ?> + Minimal sell priceExtra commisionDefault priceVisible? + + + +
+ + +
+ + +
+
+ + + 0) { + echo sprintf( '(%s for services)', esc_attr( $configured_price['minimal_services_price'] ) ); + } + ?> + +
+
+
+ + +
+ 0) { + ?> +
+ + + +
+ +
+ + + +
+
+
= + + + +
+
= + + +
+
+ + type="checkbox" + > +
diff --git a/backend/app/plugins/wiaas/includes/admin/admin-cl/wiaas-admin-cl-packages-ajax.php b/backend/app/plugins/wiaas/includes/admin/admin-cl/wiaas-admin-cl-packages-ajax.php new file mode 100644 index 0000000..815f7c8 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/admin-cl/wiaas-admin-cl-packages-ajax.php @@ -0,0 +1,31 @@ + $configured_price) { + $cl_extras[$type.'_customer_'.$customer_id] = array( + 'type' => $type, + 'visible' => true, + 'fixed' => 0, + 'services' => 0, + 'recurrent' => 0 + ); + } + + require_once 'views/html-cl-package-prices.php'; + + die(); + +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php new file mode 100644 index 0000000..c25a964 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-cl.php @@ -0,0 +1,18 @@ + 0 && $pay_type['package_pay_period'] > 0) { - $value += wiaas_PMT( - Wiaas_Pricing::INTEREST_RATE, - $pay_type['package_pay_period'], - $pricing_rule['principal_amount']); -} +$value = $pricing_rule['minimal_recurrent_price']; ?> diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-package-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-package-api.php new file mode 100644 index 0000000..b26a786 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-package-api.php @@ -0,0 +1,49 @@ + WP_REST_Server::READABLE, + 'callback' => array(__CLASS__, 'get_customer_commercial_leads'), + 'permission_callback' => 'is_user_logged_in' + ) ); + } + + public static function get_customer_commercial_leads() { + $commercial_leads = array(); + + foreach (wiaas_get_commercial_leads() as $id => $name) { + $commercial_leads[] = array( + 'id' => $id, + 'name' => $name + ); + } + + return rest_ensure_response($commercial_leads); + } + + public static function filter_by_commercial_lead($args, $request) { + + $catalogue_id = absint($request['cl_id']); + + $args['meta_query'] ?: array(); + + $args['meta_query'][] = array( + 'key' => '_wiaas_catalogue_'.$catalogue_id, + 'value' => 'yes', + ); + + return $args; + } +} + +Wiaas_Package_API::init(); \ 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 05c12ca..096f2e4 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php @@ -20,13 +20,17 @@ class Wiaas_Admin { // Admin organization interface require_once dirname(__FILE__) . '/admin/class-wiaas-admin-organization.php'; + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-cl.php'; + add_action( 'admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts'), 100 ); } public static function enqueue_scripts() { $plugin_url = untrailingslashit( plugins_url( '/', WIAAS_FILE ) ); + wp_enqueue_style( 'wiaas_admin_menu', $plugin_url . '/assets/css/menu.css' ); + wp_enqueue_style( 'wiaas_admin_packages', $plugin_url . '/assets/css/package.css' ); } } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-api.php b/backend/app/plugins/wiaas/includes/class-wiaas-api.php index 7f5eadf..a394380 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-api.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-api.php @@ -43,6 +43,8 @@ class Wiaas_API { include_once dirname( __FILE__ ) . '/api/class-wiaas-order-projects-api.php'; + include_once dirname( __FILE__ ) . '/api/class-wiaas-package-api.php'; + // API functions include_once dirname( __FILE__ ) . '/api/wiaas-api-functions.php'; @@ -55,7 +57,8 @@ class Wiaas_API { 'Wiaas_Document_API', 'Wiass_REST_User_API', 'Wiaas_REST_Customer_API', - 'Wiaas_Order_Projects_API' + 'Wiaas_Order_Projects_API', + 'Wiaas_Package_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 index 03e9f65..db614b7 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php @@ -138,8 +138,12 @@ class Wiaas_Cart { // Retrieve package country $country = Wiaas_Countries::get_package_country($package); - // Retrieve package price - $package_prices = Wiaas_Pricing::get_standard_package_customer_prices($package); + // TODO: Change this so commercial lead is sent via request + $customer_id = wiaas_get_current_user_organization_id(); + $commercial_lead_id = array_keys(wiaas_get_commercial_leads())[0]; + + // Retrieve package price + $package_prices = Wiaas_Pricing::get_standard_package_customer_prices($package, $customer_id, $commercial_lead_id); $selected_price_index = array_search($price_id, array_column($package_prices, 'id')); // Initialize additional cart item data for wiaas packages @@ -638,6 +642,10 @@ class Wiaas_Cart { $addon_items_keys = array(); $option_items_keys = array(); + // TODO: Change this so commercial lead is sent via request + $customer_id = wiaas_get_current_user_organization_id(); + $commercial_lead_id = array_keys(wiaas_get_commercial_leads())[0]; + // Try adding package addons to cart foreach ($addons_ids as $addon_id) { //Check if addon package exists @@ -646,8 +654,13 @@ class Wiaas_Cart { throw new Exception( __( 'Sorry, additional package does not exist.', 'wiaas' ) ); } - // Retrieve addon package price - $package_prices = Wiaas_Pricing::get_addon_package_customer_price($addon_package, $parent_item['data']); + // Retrieve addon package price + $package_prices = Wiaas_Pricing::get_addon_package_customer_price( + $addon_package, + $parent_item['data'], + $customer_id, + $commercial_lead_id + ); $selected_price_index = array_search($price_id, array_column($package_prices, 'id')); // Initialize additional cart item data for wiaas addon packages @@ -678,8 +691,12 @@ class Wiaas_Cart { throw new Exception( __( 'Sorry, option package does not exist.', 'wiaas' ) ); } - // Retrieve option package price - $package_prices = Wiaas_Pricing::get_option_package_customer_price($option_package, $parent_item['data']); + // Retrieve option package price + $package_prices = Wiaas_Pricing::get_option_package_customer_price( + $option_package, + $parent_item['data'], + $customer_id, + $commercial_lead_id); $selected_price_index = array_search($price_id, array_column($package_prices, 'id')); // Retrieve option package group name diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-package.php b/backend/app/plugins/wiaas/includes/class-wiaas-package.php index 5c4dea8..a7d4d32 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-package.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-package.php @@ -92,6 +92,9 @@ class Wiaas_Package { * @return array */ private static function _append_additional_packages($data, $package, $request) { + // TODO: Change this so commercial lead is sent via request + $customer_id = wiaas_get_current_user_organization_id(); + $commercial_lead_id = array_keys(wiaas_get_commercial_leads())[0]; $data['additional_packages'] = array(); $addons = Wiaas_Package_Addon::get_package_addons($package); @@ -100,7 +103,7 @@ class Wiaas_Package { 'id' => $addon->get_id(), 'name' => $addon->get_name(), 'description' => $addon->get_description(), - 'prices' => Wiaas_Pricing::get_addon_package_customer_price($addon, $package), + 'prices' => Wiaas_Pricing::get_addon_package_customer_price($addon, $package, $customer_id, $commercial_lead_id), ); } @@ -121,7 +124,7 @@ class Wiaas_Package { '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), + 'prices' => Wiaas_Pricing::get_option_package_customer_price($option_package, $package, $customer_id, $commercial_lead_id), ); } } @@ -138,7 +141,11 @@ class Wiaas_Package { * @return array */ private static function _append_package_prices($data, $package, $request) { - $data['prices'] = Wiaas_Pricing::get_standard_package_customer_prices($package); + // TODO: Change this so commercial lead is sent via request + $customer_id = wiaas_get_current_user_organization_id(); + $commercial_lead_id = array_keys(wiaas_get_commercial_leads())[0]; + + $data['prices'] = Wiaas_Pricing::get_standard_package_customer_prices($package, $customer_id, $commercial_lead_id); return $data; } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php index 2134676..2555030 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-pricing.php @@ -1,7 +1,7 @@ get_bundled_items(); + foreach ($bundled_items as $bundled_item) { - $bundled_items = $package->get_bundled_items(); - foreach ($bundled_items as $bundled_item) { + $product = $bundled_item->product; + $product_cat = Wiaas_Product_Category::get_category($product); - $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; + } - 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(); - $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; + } + } - 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)); + } - return array_sum(array_values($total_cost_per_category)); - } + /** + * Calculates customer prices for wiaas standard package + * @param WC_Product_Bundle $package + * @param int $customer_id + * @param int $commercial_lead_id + * + * @return array + */ + public static function get_standard_package_customer_prices($package, $customer_id, $commercial_lead_id) { - /** - * Calculates customer price for wiaas standard package - * @param $package - * - * @return array - */ - public static function get_standard_package_customer_prices($package) { + return self::_get_package_customer_prices( + $package, + (100 - Wiaas_Package_Pricing::get_package_pricing_commission($package)) / 100, // commercial lead commission + self::get_package_total_cost($package), // total cost of package items + $customer_id, + $commercial_lead_id); - $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(); + /** + * Calculates customer prices for wiaas addon package + * + * @param WC_Product_Bundle $addon_package + * @param WC_Product_Bundle $parent_package + * @param int $customer_id + * @param int $commercial_lead_id + * + * @return array + */ + public static function get_addon_package_customer_price($addon_package, $parent_package, $customer_id, $commercial_lead_id) { - 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); - } + $parent_total_cost = self::get_package_total_cost($parent_package); + $parent_cl_commision = (100 - Wiaas_Package_Pricing::get_package_pricing_commission($parent_package)) / 100; - return $customer_package_prices; + return self::_get_package_customer_prices( + $addon_package, + $parent_cl_commision, // commercial lead commission of parent package + $parent_total_cost, // total cost of parent package items + $customer_id, + $commercial_lead_id); + } - } + /** + * Calculates customer prices for wiaas option package + * + * @param WC_Product_Bundle $option_package + * @param WC_Product_Bundle $parent_package + * @param int $customer_id + * @param int $commercial_lead_id + * + * @return array + */ + public static function get_option_package_customer_price($option_package, $parent_package, $customer_id, $commercial_lead_id) { - /** - * 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) { + $parent_total_cost = self::get_package_total_cost($parent_package); + $parent_cl_commision = (100 - Wiaas_Package_Pricing::get_package_pricing_commission($parent_package)) / 100; - $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); + return self::_get_package_customer_prices( + $option_package, + $parent_cl_commision, // commercial lead commission of parent package + $parent_total_cost, // total cost of parent package items + $customer_id, + $commercial_lead_id); + } - $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) { + // PRIVATE SECTION - $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(); + /** + * Calculates customer prices for all package payment types + * + * @param WC_Product_Bundle $package + * @param int $cl_commision + * @param int $total_cost + * @param int $customer_id + * @param int $commercial_lead_id + * + * @return array + */ + private static function _get_package_customer_prices($package, $cl_commision, $total_cost, $customer_id, $commercial_lead_id) { + $is_same_company_as_cl = $customer_id === $commercial_lead_id; - 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); - } + $package_prices = Wiaas_Package_Pricing::get_package_prices($package); - return $customer_package_prices; - } + $customer_package_prices = array(); - // PRIVATE + foreach ($package_prices as $type => $package_price) { + $cl_package_extras = Wiaas_Package_CL_Pricing::get_extras_for_customer( + $commercial_lead_id, + $package_price['id'], + $package->get_id(), + $customer_id + ); - /** - * Determines if customer and commercial lead are in the same company - * For now this is hardcoded and we have only one CL - * - * TODO: This will be handled in next PR for setting commercial lead prices - * @return bool - */ - private static function _is_customer_same_company_as_cl() { - return false; - } + // commercial lead did not set prices for this payment type so it must not be visible for customer + if (empty($cl_package_extras)) { + continue; + } - /** - * 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) { + $customer_package_prices[] = self::_get_package_customer_price( + $package_price, + $total_cost, + $cl_package_extras, + $cl_commision, + $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; + return $customer_package_prices; + } - $cl_package_prices = array( - 'fixed_extra' => 0, - 'recurrent_extra' => 0, - 'services_extra' => 0 - ); + /** + * Calculates customer price for single package payment type + * + * @param array $package_price + * @param int $total_cost + * @param array $cl_package_extras + * @param int $cl_commision + * @param bool $is_same_company_as_cl + * + * @return array + */ + private static function _get_package_customer_price($package_price, $total_cost, $cl_package_extras, $cl_commision, $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; - $interest_rate = self::INTEREST_RATE; + $customer_package_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'], - $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 + ); - 'fixed_extra' => 0, - 'recurrent_extra' => 0, - 'services_extra' => 0 - ); + if ($is_same_company_as_cl) { - if ($is_same_company_as_cl) { + if ($package_price['package_pay_period'] > 0) { + $customer_package_price['fixed_extra'] = $package_price['minimal_fixed_price']; + $customer_package_price['recurrent_extra'] = wiaas_get_recurrent_price_mortage( + $package_price['principal_amount'], + $package_price['package_pay_period'], + $cl_margin, + self::INTEREST_RATE); + } else { + $customer_package_price['fixed_extra'] = $package_price['minimal_fixed_price'] - $cl_margin; + $customer_package_price['recurrent_extra'] = 0; + } + $customer_package_price['services_extra'] = $package_price['minimal_services_price']; - 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 { - } else { + $customer_package_price['fixed_extra'] = $cl_package_extras['fixed'] + $package_price['minimal_fixed_price']; + $customer_package_price['recurrent_extra'] = $package_price['package_pay_period'] > 0 ? + $cl_package_extras['recurrent'] + wiaas_get_recurrent_price_mortage( + $package_price['principal_amount'], + $package_price['package_pay_period'], + 0, + self::INTEREST_RATE) + : 0; + $customer_package_price['services_extra'] = $cl_package_extras['services'] + $package_price['minimal_services_price']; + } - $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; - } + return $customer_package_price; + } } Wiaas_Pricing::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php index e336a43..7dbc5f8 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-roles.php @@ -37,7 +37,8 @@ function wiaas_db_update_create_default_roles() { 'Commercial Lead', array( 'read', - 'view_admin_dashboard' + 'view_admin_dashboard', + 'wiaas_manage_cl_products' ) ); diff --git a/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-cl-pricing.php b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-cl-pricing.php new file mode 100644 index 0000000..e6bb374 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-cl-pricing.php @@ -0,0 +1,102 @@ + $cl_extra) { + unset($cl_extra['type']); + unset($cl_extra['customer']); + + $has_extras = $has_extras || $cl_extra['visible']; + + $cl_extras[$extra_type] = $cl_extra; + } + + $package = wc_get_product($package_id); + + $package->add_meta_data('_wiaas_catalogue_'.$organization_id, $has_extras ? 'yes' : 'no', true); + $package->save_meta_data(); + + // Persist package catalogue extras + update_term_meta( + $organization_id, + '_wiaas_cm_extras_'.$package_id, + $cl_extras); + } + + /** + * Retrieves package catalogue extra prices + * + * @param int $organization_id + * @param int $package_id + * + * @return array|null + */ + public static function get_extras($organization_id, $package_id) { + $cl_extras = get_term_meta( + $organization_id, + '_wiaas_cm_extras_'.$package_id, + true); + + return is_array($cl_extras) ? $cl_extras : null; + } + + /** + * Retrieve catalogue package extra prices for provided customer + * + * @param int $organization_id + * @param string $pay_type + * @param int $package_id + * @param int $customer_id + * + * @return array|null + */ + public static function get_extras_for_customer($organization_id, $pay_type, $package_id, $customer_id) { + $cl_extras = self::get_extras($organization_id, $package_id); + + if (! empty($cl_extras)) { + // retrieve default and customer specific extras + $cl_pay_type_customer_extras = $cl_extras[$pay_type.'_customer_'.$customer_id]; + $cl_pay_type_extras = $cl_extras[$pay_type.'_default']; + + // if commercial lead has special prices for this customer then use them + if (! empty($cl_pay_type_customer_extras) && $cl_pay_type_customer_extras['visible']) { + + return array( + 'fixed' => floatval($cl_pay_type_customer_extras['fixed']), + 'services' => floatval($cl_pay_type_customer_extras['services']), + 'recurrent' => floatval($cl_pay_type_customer_extras['recurrent']) + ); + } + + // if commercial lead has default price for this package then use it + if (! empty($cl_pay_type_extras) && $cl_pay_type_extras['visible']) { + + return array( + 'fixed' => floatval($cl_pay_type_extras['fixed']), + 'services' => floatval($cl_pay_type_extras['services']), + 'recurrent' => floatval($cl_pay_type_extras['recurrent']) + ); + } + } + + // there are no prices set for this payment type + return null; + } +} diff --git a/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php index 9ebbd32..7aea921 100644 --- a/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php +++ b/backend/app/plugins/wiaas/includes/pricing/class-wiaas-package-pricing.php @@ -140,6 +140,16 @@ class Wiaas_Package_Pricing { 'principal_amount' => floatval($pricing_rule['principal_amount']), 'minimal_services_price' => floatval($pricing_rule['minimal_services_price']), ); + + $minimal_recurrent_price = $prices[$type]['minimal_services_price']; + if ($prices[$type]['principal_amount'] > 0 && $prices[$type]['package_pay_period'] > 0) { + $minimal_recurrent_price += wiaas_PMT( + Wiaas_Pricing::INTEREST_RATE, + $prices[$type]['package_pay_period'], + $prices[$type]['principal_amount']); + } + + $prices[$type]['minimal_recurrent_price'] = round($minimal_recurrent_price); } return $prices; diff --git a/backend/app/plugins/wiaas/includes/user/wiaas-organization-functions.php b/backend/app/plugins/wiaas/includes/user/wiaas-organization-functions.php index 61ed58c..def7138 100644 --- a/backend/app/plugins/wiaas/includes/user/wiaas-organization-functions.php +++ b/backend/app/plugins/wiaas/includes/user/wiaas-organization-functions.php @@ -61,7 +61,7 @@ function wiaas_get_organizations_with_role($role) { * @return array */ function wiaas_get_commercial_leads() { - return wiaas_get_organizations_with_role('shop_manager'); + return wiaas_get_organizations_with_role('commercial_lead'); } /** diff --git a/frontend/src/actions/coMarket/coMarketPackagesActions.js b/frontend/src/actions/coMarket/coMarketPackagesActions.js index d85a169..6d9e7d3 100644 --- a/frontend/src/actions/coMarket/coMarketPackagesActions.js +++ b/frontend/src/actions/coMarket/coMarketPackagesActions.js @@ -27,15 +27,9 @@ export const fetchShopPackages = (cl, search) => { return dispatch => { dispatch(requestShopPackages()); let searchParam = search ? '?search=' +search : '' - return client.fetch({ - url: `${API_SERVER}/wp-json/wc/v2/products` + searchParam, - // TODO: Add comercialLead parameter after the support for it is added on backend - // method: 'post', - // data: { - // idCommercialLead: (cl && cl.value) || 0, - // search - // } + return client.fetch({ + url: `${API_SERVER}/wp-json/wc/v2/products?cl_id=${cl.idCommercialLead}` + searchParam, }) .then(response => { if (response.data) { @@ -68,23 +62,29 @@ const generateClOptions = (commercialLeads) => { export const fetchShopCommercialLeads = () => { return dispatch => { dispatch(requestShopCommercialLeads()); - // TODO: FetchcomercialLead after the support for it is added on backend - // return client.fetch({url: `${API_SERVER}/coMarket/api/getAllCommercialLeads`}) - // .then(response => { - // if(response.data && response.data.commercialLeads){ - const clOptions = generateClOptions([{ "idCommercialLead": 14, "commercialLeadName": "Coor Service Management", "mail": "rikard@co-ideation.com" }]); - dispatch(recieveShopCommercialLeads(clOptions)); - if (clOptions.length) { - dispatch(selectCommercialLead(clOptions[0])); - dispatch(fetchShopPackages(clOptions[0])); - } + return client.fetch({url: `${API_SERVER}/wp-json/wiaas/commercial-leads` }) + .then(response => { + + if(response.data){ + + const clOptions = generateClOptions(response.data.map(cl => ({ + idCommercialLead: cl.id, + commercialLeadName: cl.name + }))); + + dispatch(recieveShopCommercialLeads(clOptions)); + + if (clOptions.length) { + dispatch(selectCommercialLead(clOptions[0])); + dispatch(fetchShopPackages(clOptions[0])); + } + } + }) + .catch(error => { + client.onError(error, dispatch); + }); } - // }) - // .catch(error => { - // client.onError(error, dispatch); - // }); } -// } export const selectCommercialLead = (cl) => ({ type: SELECT_SHOP_COMMERCIAL_LEAD,