diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-selection.js b/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-selection.js new file mode 100644 index 0000000..4a264db --- /dev/null +++ b/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-selection.js @@ -0,0 +1,51 @@ +jQuery(document).ready(function ($) { + var $selectTemplate = $('#_select_template'); + var $container = $('#wiaas_selected_template_items_container'); + + $selectTemplate + + .on('change', function () { + var selectedTemplate = $selectTemplate.val(); + + var data = { + action: 'wiaas_select_template', + selected_template: selectedTemplate + }; + + + setTimeout(function () { + + $.post(woocommerce_admin_meta_boxes.ajax_url, data, function (response) { + + if ('' !== response.markup) { + $container.children("div").remove(); + $container.append(response.markup); + + } else { + $container.children("div").remove(); + } + + if (response.message !== '') { + window.alert(response.message); + } + + + }); + + }, 250); + }); + + var $product_type = $('#product-type'); + var $template_product_meta_box = $('#template_product_meta_box'); + $product_type.on('change', function () { + var selectedProductType = $product_type.val(); + + if (selectedProductType === 'bundle') { + $template_product_meta_box.show(); + } else { + $template_product_meta_box.hide(); + } + }); + + +}); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-write-panels.js b/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-write-panels.js new file mode 100644 index 0000000..c12c4c2 --- /dev/null +++ b/backend/app/plugins/wiaas/assets/js/wiaas-template-admin-write-panels.js @@ -0,0 +1,332 @@ +jQuery(function ($) { + + var $edit_in_cart = $('.bundle_edit_in_cart'), + $group_mode_select = $('select#_wc_pb_group_mode'), + $bundled_products_panel = $('#bundled_product_data'), + $bundled_products_toolbar = $bundled_products_panel.find('.toolbar'), + $template_products_container_hardware = $('.wiaas-template-items_hardware'), + $template_products_container_software = $('.wiaas-template-items_software'), + $template_products_container_services = $('.wiaas-template-items_services'), + $template_products_container_isntallation = $('.wiaas-template-items_installation'), + + $template_products = $('.wc-bundled-item', + $template_products_container_services, + $template_products_container_software, + $template_products_container_hardware, + $template_products_container_isntallation), + + $template_search_hardware = $('#wiaastemplate_products_hardware'), + $template_search_software = $('#wiaastemplate_products_software'), + $template_search_services = $('#wiaastemplate_products_services'), + $template_search_installation = $('#wiaastemplate_products_installation'), + bundled_product_objects = {}, + bundled_products_add_count = $template_products.length, + block_params = { + message: null, + overlayCSS: { + background: '#fff', + opacity: 0.6 + } + }; + + $.fn.wc_bundles_select2 = function () { + $(document.body).trigger('wc-enhanced-select-init'); + }; + + // Bundle type move stock msg up. + $('.bundle_stock_msg').appendTo('._manage_stock_field .description'); + + // Simple type options are valid for bundles. + $('.show_if_simple:not(.hide_if_bundle)').addClass('show_if_bundle'); + + $('body').on('woocommerce-product-type-change', function (event, select_val) { + + if ('bundle' === select_val) { + + $('.show_if_external').hide(); + $('.show_if_bundle').show(); + + $('input#_manage_stock').change(); + + $('#_nyp').change(); + } + + }); + + $group_mode_select.change(function () { + if ($.inArray($group_mode_select.val(), wc_bundles_admin_params.group_modes_with_parent) === -1) { + $edit_in_cart.hide(); + } else { + $edit_in_cart.show(); + } + }); + + // Downloadable support. + $('input#_downloadable').change(function () { + $('select#product-type').change(); + }); + + // Trigger product type change. + $('select#product-type').change(); + + // Trigger group mode change. + $group_mode_select.change(); + + + init_event_handlers(); + + function init_event_handlers() { + + + $template_search_hardware + + .on('change', function () { + addSearchedProduct('hardware', $template_search_hardware, $template_products_container_hardware) + }); + + $template_search_software + + .on('change', function () { + addSearchedProduct('software', $template_search_software, $template_products_container_software) + }); + + + $template_search_installation + + .on('change', function () { + addSearchedProduct('services', $template_search_installation, $template_products_container_isntallation) + }); + + + $template_search_services + + .on('change', function () { + addSearchedProduct('installation', $template_search_services, $template_products_container_services) + }); + + + function addSearchedProduct(options, search, container) { + var bundled_product_ids = search.val(), + bundled_product_id = bundled_product_ids && bundled_product_ids.length > 0 ? bundled_product_ids.shift() : false; + + var template_category_title =search.text(); + + if (!bundled_product_id) { + return false; + } + + search.val([]).change(); + + $bundled_products_panel.block(block_params); + + bundled_products_add_count++; + + var data = { + action: 'wiaas_add_template_product', + post_id: woocommerce_admin_meta_boxes.post_id, + id: bundled_products_add_count, + title: template_category_title, + product_id: bundled_product_id, + security: wc_bundles_admin_params.add_bundled_product_nonce, + options: options, + }; + + setTimeout(function () { + + $.post(woocommerce_admin_meta_boxes.ajax_url, data, function (response) { + + if ('' !== response.markup) { + + container.append(response.markup); + + var $added = $('.wiaas-template-item', container).last(), + added_id = 'bundled_item_' + bundled_products_add_count; + + $added.data('bundled_item_id', added_id); + $added.wc_bundles_select2(); + + $bundled_products_panel.trigger('wc-bundles-added-bundled-product'); + + } else if (response.message !== '') { + window.alert(response.message); + } + + // Open and close to resolve "sticky" modal issue. + if ('yes' === wc_bundles_admin_params.is_wc_version_gte_3_2) { + search.selectWoo('open'); + search.selectWoo('close'); + } else { + search.select2('open'); + search.select2('close'); + } + search.text(''); + + $bundled_products_panel.unblock(); + + }); + + }, 250); + + return false; + } + + $template_products_container_isntallation + + // Remove Item. + .on('click', 'a.remove_row', function (e) { + + var $el = $(this).closest('.wc-bundled-item'), + el_id = $el.data('bundled_item_id'); + + $el.find('*').off(); + $el.remove(); + + delete bundled_product_objects[el_id]; + + $bundled_products_panel.triggerHandler('wc-bundled-products-changed'); + + e.preventDefault(); + + }); + + $template_products_container_hardware + + // Remove Item. + .on('click', 'a.remove_row', function (e) { + + var $el = $(this).closest('.wc-bundled-item'), + el_id = $el.data('bundled_item_id'); + + $el.find('*').off(); + $el.remove(); + + delete bundled_product_objects[el_id]; + + $bundled_products_panel.triggerHandler('wc-bundled-products-changed'); + + e.preventDefault(); + + }); + + $template_products_container_software + + // Remove Item. + .on('click', 'a.remove_row', function (e) { + + var $el = $(this).closest('.wc-bundled-item'), + el_id = $el.data('bundled_item_id'); + + $el.find('*').off(); + $el.remove(); + + delete bundled_product_objects[el_id]; + + $bundled_products_panel.triggerHandler('wc-bundled-products-changed'); + + e.preventDefault(); + + }); + + $template_products_container_services + + // Remove Item. + .on('click', 'a.remove_row', function (e) { + + var $el = $(this).closest('.wc-bundled-item'), + el_id = $el.data('bundled_item_id'); + + $el.find('*').off(); + $el.remove(); + + delete bundled_product_objects[el_id]; + + $bundled_products_panel.triggerHandler('wc-bundled-products-changed'); + + e.preventDefault(); + + }) + + } + + // Ajax product search box + $( ':input.wiaas-term-search' ).filter( ':not(.enhanced)' ).each( function() { + var select2_args = { + allowClear: $( this ).data( 'allow_clear' ) ? true : false, + placeholder: $( this ).data( 'placeholder' ), + minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3', + escapeMarkup: function( m ) { + return m; + }, + ajax: { + url: wc_enhanced_select_params.ajax_url, + dataType: 'json', + delay: 250, + data: function( params ) { + return { + term: params.term, + action: 'wiaas_template_category_search', + security: wc_enhanced_select_params.search_products_nonce, + exclude: $( this ).data( 'exclude' ), + include: $( this ).data( 'include' ), + limit: $( this ).data( 'limit' ) + }; + }, + processResults: function( data ) { + var terms = []; + if ( data ) { + $.each( data, function( id, text ) { + terms.push( { id: id, text: text } ); + }); + } + return { + results: terms + }; + }, + cache: true + } + }; + + // select2_args = $.extend( select2_args, getEnhancedSelectFormatString() ); + + $( this ).selectWoo( select2_args ).addClass( 'enhanced' ); + + if ( $( this ).data( 'sortable' ) ) { + var $select = $(this); + var $list = $( this ).next( '.select2-container' ).find( 'ul.select2-selection__rendered' ); + + $list.sortable({ + placeholder : 'ui-state-highlight select2-selection__choice', + forcePlaceholderSize: true, + items : 'li:not(.select2-search__field)', + tolerance : 'pointer', + stop: function() { + $( $list.find( '.select2-selection__choice' ).get().reverse() ).each( function() { + var id = $( this ).data( 'data' ).id; + var option = $select.find( 'option[value="' + id + '"]' )[0]; + $select.prepend( option ); + } ); + } + }); + // Keep multiselects ordered alphabetically if they are not sortable. + } else if ( $( this ).prop( 'multiple' ) ) { + $( this ).on( 'change', function(){ + var $children = $( this ).children(); + $children.sort(function(a, b){ + var atext = a.text.toLowerCase(); + var btext = b.text.toLowerCase(); + + if ( atext > btext ) { + return 1; + } + if ( atext < btext ) { + return -1; + } + return 0; + }); + $( this ).html( $children ); + }); + } + }); + +}); + 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 index 57d44da..e225ebd 100644 --- 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 @@ -33,6 +33,8 @@ if ( ! defined( 'ABSPATH' ) ) { $(this).show(); $(this).removeClass('hidden'); $(this).removeClass('show_if_downloadable'); + $(this).addClass('show_if_simple'); + $(this).addClass('show_if_bundle'); $(this).find('._download_limit_field, ._download_expiry_field').hide(); }); diff --git a/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-admin-template-selection.php b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-admin-template-selection.php new file mode 100644 index 0000000..e1012a6 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-admin-template-selection.php @@ -0,0 +1,244 @@ +(optional)', 'cmb'), + 'Wiaas_Admin_Template_Selection::add_custom_content_meta_box', + 'product', + 'normal', + 'high' + ); + } + + + public static function add_custom_content_meta_box($post) { + + $value = get_post_meta($post->ID, '_select_template', true); + + if (empty($value)) { + $value = ''; + } + + $products = wc_get_products(array( + 'type' => 'wiaastemplate' + )); + $product_ids[''] = __('Select a template', 'wiaas'); + foreach ($products as $prod) { + $product_ids[$prod->id] = $prod->name; + } + woocommerce_wp_select(array( + 'id' => '_select_template', + 'options' => $product_ids, + 'value' => $value + )); + + ?> +
$template_products_hardware, + 'service' => $template_products_service, + 'installation' => $template_products_installation, + 'software' => $template_products_software + ); + + } + + public static function render_template_products($template_products) { + if (!empty($template_products)) { + + + foreach ($template_products as $item) { + + $product_id = $item['template_category_id']; + $title = $item['template_category_title']; + $quantity = $item['quantity']; + + include('views/html-wiaas-template-selection.php'); + + } + } + } + + public static function get_product_categories($category_meta) { + $category_objects = array(); + + + if (empty($category_meta)) { + return array(); + } + + foreach ($category_meta as $meta) { + + if (!empty($meta)) { + + + $category_template_id = $meta['template_category_id']; + + $template_category_object = new Wiaas_Template_Category_Object( + $category_template_id, + $meta['template_category_title'], + $meta['quantity']); + + $category_objects[$category_template_id] = $template_category_object; + } + + } + return empty($category_objects) ? null : $category_objects; + } + + public static function get_bundled_product_categories($bundled_items) { + + $template_category_objects = array(); + foreach ($bundled_items as $item_id => $item) { + $item_data = $item->get_data(); + $post_terms = wp_get_object_terms($item->get_product_id(), 'template_category', array('fields' => 'id=>name')); + + if (!empty($post_terms) && !is_wp_error($post_terms)) { + + $cat = ''; + $category_template_id = ''; + + foreach ($post_terms as $id => $term) { + $cat = $term; + $category_template_id = $id; + } + + $template_category_object = new Wiaas_Template_Category_Object( + $category_template_id, + $cat, + $item_data['quantity_max']); + $template_category_objects[$category_template_id] = $template_category_object; + + } + } + + return $template_category_objects; + } + + + function save_custom_content_meta_box($post_id) { + $selected_template = $_POST['_select_template']; + if (!empty($selected_template)) + update_post_meta($post_id, '_select_template', esc_attr($selected_template)); + else { + update_post_meta($post_id, '_select_template', ''); + } + + } + + public static function validate_bundle($product) { + + + if ($product->get_type() == 'bundle') { + $selected_template = $_POST['_select_template']; + $bundled_items = $product->get_bundled_items('view'); + $products_form_template = self::show_template_products($selected_template); + + $missing_categories = array(); + $insufficient_product_quantities = array(); + + + $categories_form_template = self::get_categories_from_templates($products_form_template); + $categories_form_bundle = self::get_bundled_product_categories($bundled_items); + $bundle_category_keys = array_keys($categories_form_bundle); + + + if (!empty($categories_form_template)) { + + foreach ($categories_form_template as $category) { + $template_cat_id = $category->template_category_id; + + + if (!in_array($template_cat_id, $bundle_category_keys)) { + + array_push($missing_categories, $category->name); + + } else { + + $product_from_bundle_quantity = $categories_form_bundle[$template_cat_id]->quantity; + $quantity_from_template = $category->quantity; + + if ((int)($quantity_from_template) !== $product_from_bundle_quantity) { + array_push($insufficient_product_quantities, $category->name); + } + } + } + } + + $categories_message = implode(',', $missing_categories); + $quantity_message = implode(',', $insufficient_product_quantities); + + if (!empty($missing_categories)) { + WC_PB_Meta_Box_Product_Data::add_admin_error(__(' WIAAS This product bundle does not correspond to selected template Categories missing: ' . $categories_message, 'woocommerce-product-bundles')); + } + + if (!empty($insufficient_product_quantities)) { + WC_PB_Meta_Box_Product_Data::add_admin_error(__(' WIAAS This product bundle does not correspond to selected template Categories with different quantities: ' . $quantity_message, 'woocommerce-product-bundles')); + } + } + + } + + public static function get_category_ids_form_bundle($product) { + $products_form_budnle = $product->get_bundled_data_items(); + $product_ids = array(); + + foreach ($products_form_budnle as $product) { + array_push($product_ids, $product->get_id()); + } + + return self::get_product_categories($product_ids); + + } +} + +Wiaas_Admin_Template_Selection::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-admin-ajax.php b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-admin-ajax.php new file mode 100644 index 0000000..656f0ef --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-admin-ajax.php @@ -0,0 +1,93 @@ + '', + 'message' => '' + ); + + $template_products = Wiaas_Admin_Template_Selection::show_template_products($selected_template_id); + + if (!empty($template_products)) { + ob_start(); + Wiaas_Admin_Template_Selection::render_template_products($template_products['hardware']); + Wiaas_Admin_Template_Selection::render_template_products($template_products['service']); + Wiaas_Admin_Template_Selection::render_template_products($template_products['installation']); + Wiaas_Admin_Template_Selection::render_template_products($template_products['software']); + + $response['markup'] = ob_get_clean(); + } + + wp_send_json($response); + } + + + /** + * Handles adding template categories to template via ajax. + */ + public static function ajax_add_wiaas_template_product() { + + check_ajax_referer('wc_bundles_add_bundled_product', 'security'); + + $loop = intval($_POST['id']); + $product_id = intval($_POST['product_id']); + $title = $_POST['title']; + $options = $_POST['options']; + + $response = array( + 'markup' => '', + 'message' => '' + ); + + ob_start(); + include('views/html-wiaas-template-product.php'); + $response['markup'] = ob_get_clean(); + + wp_send_json($response); + } + + /** + * + */ + public static function ajax_wiaas_template_category_search() { + + $term = ($_POST['term']); + $response = array(); + + $terms = get_terms(array( + 'taxonomy' => 'template_category', + 'name__like' => $term + )); + + foreach ($terms as $t) { + $response[$t->term_id] = $t->name; + } + + wp_send_json($response); + } +} + +Wiaas_Template_Admin_Ajax::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-products.php b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-products.php new file mode 100644 index 0000000..ddb5e54 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/template/class-wiaas-template-products.php @@ -0,0 +1,226 @@ + + __('Hardware', 'wiaastemplate_hardware'), + 'target' => 'wiaastemplate_options_hardware', + 'class' => array('show_if_wiaastemplate', 'show_if_wiaastemplate'), + ); + + $tabs['wiaastemplate_installation'] = array( + 'label' => __('Installation', 'wiaastemplate_isntallation'), + 'target' => 'wiaastemplate_options_installation', + 'class' => array('show_if_wiaastemplate', 'show_if_wiaastemplate'), + ); + + $tabs['wiaastemplate_services'] = array( + 'label' => __('Services', 'wiaastemplate_services'), + 'target' => 'wiaastemplate_options_services', + 'class' => array('show_if_wiaastemplate', 'show_if_wiaastemplate'), + ); + + $tabs['wiaastemplate_software'] = array( + 'label' => __('Software', 'wiaastemplate_software'), + 'target' => 'wiaastemplate_options_software', + 'class' => array('show_if_wiaastemplate', 'show_if_wiaastemplate'), + ); + + return $tabs; + + } + + public static function wiaastemplate_product_tab_content_all() { + + self::wiaastemplate_product_tab_content('hardware'); + self::wiaastemplate_product_tab_content('installation'); + self::wiaastemplate_product_tab_content('services'); + self::wiaastemplate_product_tab_content('software'); + } + + + /** + * Contents of the template options product tab. + */ + public static function wiaastemplate_product_tab_content($options) { + + global $post; + $template_items = get_post_meta($post->ID, '_template_items_' . $options, true); + + ?> +
' class='panel woocommerce_options_panel'> +
+ + + + +
$product_id, + 'template_category_title' => trim($product_title), + 'quantity' => $quantity + + ); + + $processed_template_data[$product_id] = $item_data; + + } + + update_post_meta($post_id, '_template_items_' . $option, $processed_template_data); + } + + public static function menu_sort_order($a, $b) { + if (isset($a['menu_order']) && isset($b['menu_order'])) { + return $a['menu_order'] - $b['menu_order']; + } else { + return isset($a['menu_order']) ? 1 : -1; + } + } + + + /** + * Hide Attributes data panel. + */ + function hide_attributes_data_panel($tabs) { + + $tabs['advanced']['class'][] = 'hide_if_simple_wiaastemplate hide_if_wiaastemplate'; + $tabs['shipping']['class'][] = 'hide_if_simple_wiaastemplate hide_if_wiaastemplate'; + $tabs['linked_product']['class'][] = 'hide_if_simple_wiaastemplate hide_if_wiaastemplate'; + $tabs['attribute']['class'][] = 'hide_if_simple_wiaastemplate hide_if_wiaastemplate'; + + return $tabs; + + } +} + +Wiaas_template::init(); + diff --git a/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-product.php b/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-product.php new file mode 100644 index 0000000..0c0e03d --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-product.php @@ -0,0 +1,36 @@ + +
+

+ + +

+
+ + +
'_product_quantity', + 'label' => __('Quantity', 'woocommerce'), + 'desc_tip' => 'true', + 'description' => __('Choose the quantity of product', 'woocommerce'), + 'type' => 'text', + 'name' => 'template_data_'.$options .'['. $loop.'][quantity]', + 'value' => $quantity + )); + + ?>
diff --git a/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-selection.php b/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-selection.php new file mode 100644 index 0000000..4c19b4e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/template/views/html-wiaas-template-selection.php @@ -0,0 +1,13 @@ + +
+

+ + [] +

+
\d+)/profile-addresses', array( + 'methods' => 'PUT', + 'callback' => array(__CLASS__, 'update_customer_profile_addresses'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'customer/(?P\d+)/profile-addresses/(?P\d+)', array( + 'methods' => 'DELETE', + 'callback' => array(__CLASS__, 'delete_customer_profile_address'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'customer/(?P\d+)/billing-addresses', array( + 'methods' => 'PUT', + 'callback' => array(__CLASS__, 'update_customer_billing_addresses'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'customer/(?P\d+)/billing-addresses/(?P\d+)', array( + 'methods' => 'DELETE', + 'callback' => array(__CLASS__, 'delete_customer_billing_addresses'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'customer/(?P\d+)/personal-info', array( + 'methods' => 'PUT', + 'callback' => array(__CLASS__, 'update_customer_personal_info'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'customer/(?P\d+)/company-info', array( + 'methods' => 'PUT', + 'callback' => array(__CLASS__, 'update_customer_company_info'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + } + + + + public static function update_customer_profile_addresses(WP_REST_Request $request){ + $customer_id = $request['id']; + $params = $request->get_body_params(); + $new_address = json_decode($params['profile_address']); + + if (!Wiaas_Customer::update_customer_profile_addresses($customer_id, $new_address)){ + return self::generate_wiaas_response('PROFILE_ADDRESS_NOT_CHANGED', 'warning', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('PROFILE_ADDRESS_UPDATED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + } + + public static function delete_customer_profile_address(WP_REST_Request $request){ + $customer_id = $request['id']; + $address_id = $request['address_id']; + + if (!Wiaas_Customer::delete_customer_profile_address($customer_id, $address_id)){ + return self::generate_wiaas_response('ADDRESS_ERROR', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('ADDRESS_REMOVED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + } + + public static function update_customer_billing_addresses(WP_REST_Request $request){ + $customer_id = $request['id']; + $params = $request->get_body_params(); + $new_address = json_decode($params['billing_address']); + + if (!Wiaas_Customer::update_customer_billing_addresses($customer_id, $new_address)){ + return self::generate_wiaas_response('BILLING_ADDRESS_NOT_CHANGED', 'warning', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('BILLING_ADDRESS_UPDATED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + + } + + public static function delete_customer_billing_addresses(WP_REST_Request $request){ + $customer_id = $request['id']; + $address_id = $request['address_id']; + + if (!Wiaas_Customer::delete_customer_billing_address($customer_id, $address_id)){ + return self::generate_wiaas_response('ADDRESS_ERROR', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('ADDRESS_REMOVED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + } + + public static function update_customer_personal_info(WP_REST_Request $request){ + $customer_id = $request['id']; + $params = $request->get_body_params(); + + $first_name = $params['first_name']; + $last_name = $params['last_name']; + $phone = $params['phone']; + $name = $first_name . ' ' . $last_name; + + if (!is_string($name) || strlen($name) === 1){ + return self::generate_wiaas_response('ADD_NAME', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + if (!is_string($phone) || strlen($phone) < 1){ + return self::generate_wiaas_response('ADD_PHONE_NUMBER', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + if (!Wiaas_Customer::update_customer_profile_info($customer_id, $first_name, $last_name, $phone)){ + return self::generate_wiaas_response('PROFILE_NOT_CHANGED', 'warning', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('PROFILE_UPDATED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + } + + public static function update_customer_company_info(WP_REST_Request $request){ + $customer_id = $request['id']; + $params = $request->get_body_params(); + + $company_name = $params['company_name']; + $vat_code = $params['vat_code']; + + + if (!is_string($company_name) || strlen($company_name) < 1){ + return self::generate_wiaas_response('ADD_COMPANY_NAME', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + if (!is_string($vat_code) || strlen($vat_code) < 1){ + return self::generate_wiaas_response('ADD_VAT', 'error', Wiaas_Customer::get_customer_info($customer_id)); + } + + if (!Wiaas_Customer::update_customer_company_info($customer_id, $company_name, $vat_code)){ + return self::generate_wiaas_response('COMPANY_NOT_CHANGED', 'warning', Wiaas_Customer::get_customer_info($customer_id)); + } + + return self::generate_wiaas_response('COMPANY_UPDATED', 'success', Wiaas_Customer::get_customer_info($customer_id)); + + + } + + + + + private static function generate_wiaas_response($message, $code, $data = NULL){ + $response = array( + 'messages' => [ + array( + 'code' => $code, + 'message' => $message + ) + ], + 'data' => $data + ); + + return new WP_REST_Response($response); + } + + +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-user-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-user-api.php new file mode 100644 index 0000000..1615ad5 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-rest-user-api.php @@ -0,0 +1,50 @@ + 'POST', + 'callback' => array(__CLASS__, 'validate_token'), + 'permission_callback' => 'is_user_logged_in' + ) ); + + register_rest_route( self::$namespace, 'user/get-countries', array( + 'methods' => 'GET', + 'callback' => array(__CLASS__, 'get_countries'), + 'permission_callback' => 'is_user_logged_in' + ) ); + } + + + public static function validate_token() { + $user = wp_get_current_user(); + + return new WP_REST_Response(array( + 'userInfo' => array( + 'wiaas_id_user' => $user->ID, + 'wiaas_is_company_admin' => 1, //TODO: don't hardcode this + 'wiaas_user_full_name' => $user->first_name . ' ' . $user->last_name, + 'wiaas_user_type' => $user->roles, + 'wiaas_username' => $user->data->user_login + ) + )); + } + + public static function get_countries(){ + $countries = Wiaas_Countries::get_list_of_countries(); + + return new WP_REST_Response($countries); + } +} \ 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 bfbe7fe..6af9d1d 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php @@ -9,7 +9,10 @@ class Wiaas_Admin { public static function init() { require_once dirname( __FILE__ ) . '/admin/class-wiaas-admin-package.php'; require_once dirname( __FILE__ ) . '/admin/class-wiaas-admin-pricing.php'; + require_once dirname(__FILE__) . '/admin/template/class-wiaas-admin-template-selection.php'; + require_once dirname(__FILE__) . '/admin/template/class-wiaas-template-products.php'; + require_once dirname(__FILE__) . '/admin/template/class-wiaas-template-admin-ajax.php'; } } -Wiaas_Admin::init(); \ No newline at end of file +Wiaas_Admin::init(); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-api.php b/backend/app/plugins/wiaas/includes/class-wiaas-api.php index 9d93713..574a7bc 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-api.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-api.php @@ -34,13 +34,22 @@ class Wiaas_API { 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'; + + #User controller + include_once dirname( __FILE__ ) . '/api/class-wiaas-rest-user-api.php'; + + #Customer controller + include_once dirname( __FILE__ ) . '/api/class-wiaas-rest-customer.php'; + } public static function register_rest_routes() { $controllers = array( 'Wiass_REST_Delivery_Process_API', 'Wiaas_Cart_API', - 'Wiaas_Document_API' + 'Wiaas_Document_API', + 'Wiass_REST_User_API', + 'Wiaas_REST_Customer_API' ); foreach ( $controllers as $controller ) { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-countries.php b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php index 375a013..368f4c7 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-countries.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-countries.php @@ -17,18 +17,21 @@ class Wiaas_Countries { */ private static $available_countries = array( 'Sweden' => array( + 'id' => 1, 'name' => 'Sweden', 'code' => 'se', 'vat' => 9 , 'currency' => 'SEK' ), 'Denmark' => array( + 'id' => 2, 'name' => 'Denmark', 'code' => 'dk', 'vat' => 9 , 'currency' => 'DKK' ), 'Finland' => array( + 'id' => 3, 'name' => 'Finland', 'code' => 'fi', 'vat' => 9 , @@ -41,6 +44,24 @@ class Wiaas_Countries { add_action('woocommerce_after_register_taxonomy', array(__CLASS__, 'register_product_countries_taxonomy')); } + public static function get_list_of_countries(){ + $result = []; + foreach(self::$available_countries as $country){ + array_push($result, array( + 'country_id' => $country['id'], + 'country_name' => $country['name'] + )); + } + return $result; + } + + public static function get_country_name_by_id($id){ + foreach(self::$available_countries as $country){ + if ($country['id'] == $id) return $country['name']; + } + return ''; + } + /** * Registers product taxonomy for avaiable countries */ diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-user.php b/backend/app/plugins/wiaas/includes/class-wiaas-user.php index 710ecd7..f61fcb1 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-user.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-user.php @@ -8,8 +8,14 @@ defined( 'ABSPATH' ) || exit; class Wiaas_User { public static function init() { + include_once dirname( __FILE__ ) . '/class-wiaas-countries.php'; + include_once dirname( __FILE__ ) . '/user/class-wiaas-customer.php'; + add_action('init', array(__CLASS__, 'load_user_organization')); add_action('plugins_loaded', array(__CLASS__, 'remove_default_user_groups'), 30); + + add_filter('woocommerce_rest_prepare_customer', array(__CLASS__, 'transform_rest_customer'), 10, 3); + add_filter('jwt_auth_token_before_dispatch', array(__CLASS__, 'transform_jwt_token_response'), 10, 2); } public static function load_user_organization() { @@ -24,6 +30,47 @@ class Wiaas_User { remove_action( 'init', 'wp_register_default_user_group_taxonomy' ); remove_action( 'init', 'wp_register_default_user_type_taxonomy' ); } + + /** + * Apply wiaas custom transformation on retrieved JSON customer object + * + * @param $response + * @param $order + * @param $request + * + * @return mixed + */ + public static function transform_rest_customer($response, $order, $request) { + $data = $response->get_data(); + $user_id = $data['id']; + $customer_info = Wiaas_Customer::get_customer_info($user_id); + + return new WP_REST_Response($customer_info); + } + + /** + * Apply wiaas custom transformation on JWT token response + * + * @param $data + * @param $user + * + * @return mixed + */ + public static function transform_jwt_token_response($data, $user) { + return new WP_REST_Response(array( + 'token' => $data['token'], + 'userInfo' => array( + 'wiaas_id_user' => $user->ID, + 'wiaas_is_company_admin' => 1, //TODO: don't hardcode this + 'wiaas_user_full_name' => $user->first_name . ' ' . $user->last_name, + 'wiaas_user_type' => $user->roles, + 'wiaas_username' => $user->data->user_login + ) + )); + + } + + } Wiaas_User::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/class-wiass-templates.php b/backend/app/plugins/wiaas/includes/class-wiass-templates.php new file mode 100644 index 0000000..ef41c39 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/class-wiass-templates.php @@ -0,0 +1,12 @@ +template_category_id = $id; + $this->name = $title; + $this->quantity = $quant; + } + + public function get_quantity(){ + return $this->quantity; + } + +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/templates/class-wiaas-template-category.php b/backend/app/plugins/wiaas/includes/templates/class-wiaas-template-category.php new file mode 100644 index 0000000..575f5e5 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/templates/class-wiaas-template-category.php @@ -0,0 +1,93 @@ + _x( 'Template category', 'taxonomy general name', 'wiaas' ), + 'singular_name' => _x( 'Template category', 'taxonomy singular name', 'wiaas' ), + 'search_items' => __( 'Search Template categories', 'wiaas' ), + 'all_items' => __( 'All Template categories', 'wiaas' ), + 'parent_item' => __( 'Parent Template category', 'wiaas' ), + 'parent_item_colon' => __( 'Parent Template category:', 'wiaas' ), + 'edit_item' => __( 'Edit Template category', 'wiaas' ), + 'update_item' => __( 'Update Template category', 'wiaas' ), + 'add_new_item' => __( 'Add New Template category', 'wiaas' ), + 'new_item_name' => __( 'New Template category Name', 'wiaas' ), + 'menu_name' => __( 'Template category', 'wiaas' ), + ); + + $args = array( + 'hierarchical' => false, + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'rewrite' => array( 'slug' => 'template_category' ), + ); + + register_taxonomy( 'template_category', array( 'product' ), $args ); + } + + /** + * Retrieve available wiaas Template categories + * @return array + */ + public static function get_available_template_categories() { + $types = get_terms( array( + 'taxonomy' => 'template_category', + 'hide_empty' => false, + ) ); + + return array_map(function($type) { + return $type->name; + }, $types); + } + + /** + * Retrieve Template category for provided package id + * @param $product_id + * + * @return null + */ + public static function get_template_category($product_id) { + $terms = wp_get_object_terms($product_id, 'template_category'); + $template_category = isset($terms[0]) ? $terms[0]->name : null; + return $template_category; + } + + /** + * Set Template category for provided package id + * @param $product_id + * @param $type + */ + public static function set_template_category($product_id, $type) { + + wp_delete_object_term_relationships( $product_id, 'template_category' ); + + if (isset($type)) { + wp_set_object_terms($product_id, $type, 'template_category', false); + } + } +} + +Wiaas_Template_Category::init(); \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/templates/class-wiaas-wc-product-template.php b/backend/app/plugins/wiaas/includes/templates/class-wiaas-wc-product-template.php new file mode 100644 index 0000000..5080c6d --- /dev/null +++ b/backend/app/plugins/wiaas/includes/templates/class-wiaas-wc-product-template.php @@ -0,0 +1,46 @@ + $customer_id, + 'company_id' => self::get_customer_company_id($customer_id), + 'is_company_admin' => self::get_customer_company_admin_status($customer_id), + 'mail' => $user->user_email, + 'name' => $user->first_name . ' ' . $user->last_name, + 'phone' => self::get_customer_phone_number($customer_id), + 'company_name' => self::get_customer_company_name($customer_id), + 'vat_code' => self::get_customer_vat_code($customer_id), + 'billing_addresses' => self::get_customer_billing_addresses($customer_id), + 'profile_addresses' => self::get_customer_profile_addresses($customer_id), + 'user_type' => $user->roles + ); + + return $result; + } + + public static function get_customer_profile_addresses($customer_id){ + return get_user_meta($customer_id, 'profile_addresses', true) ?: []; + } + + public static function get_customer_billing_addresses($customer_id){ + return get_user_meta($customer_id, 'billing_addresses', true) ?: []; + } + + public static function get_customer_vat_code($customer_id){ + return get_user_meta($customer_id, 'vat_code', true) ?: ''; + } + + public static function get_customer_company_name($customer_id){ + return get_user_meta($customer_id, 'company_name', true) ?: ''; + } + + public static function get_customer_company_id($customer_id){ + return 0; //TODO: don't hardocde this + } + + public static function get_customer_company_admin_status($customer_id){ + return 1; //TODO: don't hardcode this + } + + public static function get_customer_phone_number($customer_id){ + return get_user_meta($customer_id, 'phone', true) ?: ''; + } + + public static function update_customer_profile_info($customer_id, $first_name, $last_name, $phone){ + $user = array( + 'ID' => $customer_id, + 'first_name' => $first_name, + 'last_name' => $last_name + ); + + if (is_wp_error(wp_update_user($user))){ + return false; + } + update_user_meta( $customer_id, 'phone', $phone); + + return true; + } + + public static function update_customer_company_info($customer_id, $company_name, $vat_code){ + $result1 = update_user_meta( $customer_id, 'company_name', $company_name); + $result2 = update_user_meta( $customer_id, 'vat_code', $vat_code ); + return $result1 || $result2; + } + + public static function update_customer_billing_addresses($customer_id, $new_address){ + if (!self::validate_address($new_address)){ + return false; + } + $billing_addresses = self::get_customer_billing_addresses($customer_id); + + if ($new_address->id){ + $updated = array( + 'id' => $new_address->id, + 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'delivery_mail' => $new_address->delivery_mail, + 'id_country_selected' => $new_address->id_country_selected, + 'city' => $new_address->city, + 'detailed_address' => $new_address->detailed_address, + 'zip_code' => $new_address->zip_code, + 'first_name' => $new_address->first_name, + 'last_name' => $new_address->last_name, + 'invoice_mail' => $new_address->invoice_mail + ); + foreach($billing_addresses as $key => $address){ + if ($address['id'] === $new_address->id){ + $billing_addresses[$key] = $updated; + break; + } + } + }else{ + $new_billing_address = array( + 'id' => time(), + 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'delivery_mail' => $new_address->delivery_mail, + 'id_country_selected' => $new_address->id_country_selected, + 'city' => $new_address->city, + 'detailed_address' => $new_address->detailed_address, + 'zip_code' => $new_address->zip_code, + 'first_name' => $new_address->first_name, + 'last_name' => $new_address->last_name, + 'invoice_mail' => $new_address->invoice_mail + ); + + array_push($billing_addresses, $new_billing_address); + } + + return update_user_meta( $customer_id, 'billing_addresses', $billing_addresses); + } + + public static function update_customer_profile_addresses($customer_id, $new_address){ + if (!self::validate_address($new_address)){ + return false; + } + $profile_addresses = self::get_customer_profile_addresses($customer_id); + + if ($new_address->id){ + $updated = array( + 'id' => $new_address->id, + 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'delivery_mail' => $new_address->delivery_mail, + 'id_country_selected' => $new_address->id_country_selected, + 'city' => $new_address->city, + 'detailed_address' => $new_address->detailed_address, + 'zip_code' => $new_address->zip_code, + 'first_name' => $new_address->first_name, + 'last_name' => $new_address->last_name, + 'invoice_mail' => $new_address->invoice_mail + ); + foreach($profile_addresses as $key => $address){ + if ($address['id'] === $new_address->id){ + $profile_addresses[$key] = $updated; + break; + } + } + }else{ + $new_delivery_address = array( + 'id' => time(), + 'country_name' => Wiaas_Countries::get_country_name_by_id($new_address->id_country_selected), + 'delivery_mail' => $new_address->delivery_mail, + 'id_country_selected' => $new_address->id_country_selected, + 'city' => $new_address->city, + 'detailed_address' => $new_address->detailed_address, + 'zip_code' => $new_address->zip_code, + 'first_name' => $new_address->first_name, + 'last_name' => $new_address->last_name, + 'invoice_mail' => $new_address->invoice_mail + ); + + array_push($profile_addresses, $new_delivery_address); + } + + return update_user_meta( $customer_id, 'profile_addresses', $profile_addresses); + } + + public static function delete_customer_profile_address($customer_id, $address_id){ + $profile_addresses = self::get_customer_profile_addresses($customer_id); + $counter = 0; + foreach($profile_addresses as $key => $address){ + if ($address['id'] == $address_id){ + array_splice($profile_addresses, $counter, 1); + break; + } + $counter++; + } + return update_user_meta( $customer_id, 'profile_addresses', $profile_addresses); + } + + public static function delete_customer_billing_address($customer_id, $address_id){ + $billing_addresses = self::get_customer_billing_addresses($customer_id); + $counter = 0; + foreach($billing_addresses as $key => $address){ + if ($address['id'] == $address_id){ + array_splice($billing_addresses, $counter, 1); + break; + } + $counter++; + } + return update_user_meta( $customer_id, 'billing_addresses', $billing_addresses); + } + + /** + * Check if address is valid + * + * @param $address + * + * @return bool + */ + private static function validate_address($address){ + if (empty($address->city)){ + return false; + } + + if (empty($address->detailed_address)){ + return false; + } + + return is_numeric($address->zip_code); + } + + +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-customer-api.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-customer-api.php new file mode 100644 index 0000000..ba5f79f --- /dev/null +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-customer-api.php @@ -0,0 +1,597 @@ +server = $wp_rest_server = new \WP_REST_Server; + do_action( 'rest_api_init' ); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_profile_addresses + */ + function test_update_customer_profile_addresses_as_guest() { + wp_set_current_user(0); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/0/profile-addresses'); + $request->set_body_params(array( + 'profile_address' => $dummy_address + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_profile_addresses + */ + function test_add_customer_profile_addresses_with_valid_address() { + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/profile-addresses'); + $request->set_body_params(array( + 'profile_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('profile_addresses', $profile_info); + $this->assertEquals($profile_info['profile_addresses'][0]['city'], $dummy_address['city']); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'PROFILE_ADDRESS_UPDATED'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_profile_addresses + */ + function test_add_customer_profile_addresses_with_invalid_address() { + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + $dummy_address['zip_code'] = 'this is not a zip code'; + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/profile-addresses'); + $request->set_body_params(array( + 'profile_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('profile_addresses', $profile_info); + $this->assertEquals($profile_info['profile_addresses'][0], NULL); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'PROFILE_ADDRESS_NOT_CHANGED'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_billing_addresses + */ + function test_update_customer_billing_addresses_as_guest() { + wp_set_current_user(0); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/0/billing-addresses'); + $request->set_body_params(array( + 'billing_address' => $dummy_address + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_billing_addresses + */ + function test_add_customer_billing_addresses_with_valid_address() { + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/billing-addresses'); + $request->set_body_params(array( + 'billing_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('billing_addresses', $profile_info); + $this->assertEquals($profile_info['billing_addresses'][0]['city'], $dummy_address['city']); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'BILLING_ADDRESS_UPDATED'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_billing_addresses + */ + function test_add_customer_billing_addresses_with_invalid_address() { + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + $dummy_address['zip_code'] = 'this is not a zip code'; + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/billing-addresses'); + $request->set_body_params(array( + 'billing_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('billing_addresses', $profile_info); + $this->assertEquals($profile_info['billing_addresses'][0], NULL); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'BILLING_ADDRESS_NOT_CHANGED'); + } + + /** + * @covers Wiass_REST_Customer_API::delete_customer_billing_addresses + */ + function test_delete_customer_billing_addresses_as_guest() { + $address_id = self::insert_dummy_billing_address(); + wp_set_current_user(0); + + $request = new WP_REST_Request( 'DELETE', '/wiaas/customer/1/billing-addresses/' . $address_id); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::delete_customer_billing_addresses + */ + function test_delete_customer_billing_addresses() { + $address_id = self::insert_dummy_billing_address(); + wp_set_current_user(1); + + $request = new WP_REST_Request( 'DELETE', '/wiaas/customer/1/billing-addresses/' . $address_id); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('billing_addresses', $profile_info); + $this->assertEquals($profile_info['billing_addresses'][0], NULL); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADDRESS_REMOVED'); + } + + /** + * @covers Wiass_REST_Customer_API::delete_customer_profile_addresses + */ + function test_delete_customer_delivery_addresses_as_guest() { + $address_id = self::insert_dummy_profile_address(); + wp_set_current_user(0); + + $request = new WP_REST_Request( 'DELETE', '/wiaas/customer/1/profile-addresses/' . $address_id); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::delete_customer_profile_addresses + */ + function test_delete_customer_profile_addresses() { + $address_id = self::insert_dummy_profile_address(); + wp_set_current_user(1); + + $request = new WP_REST_Request( 'DELETE', '/wiaas/customer/1/profile-addresses/' . $address_id); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('profile_addresses', $profile_info); + $this->assertEquals($profile_info['profile_addresses'][0], NULL); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADDRESS_REMOVED'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_personal_info + */ + function test_update_customer_personal_info_as_guest() { + wp_set_current_user(0); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/personal-info'); + $request->set_body_params(array( + 'first_name' => 'Trunks', + 'last_name' => 'Goten', + 'phone' => 11111 + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_personal_info + */ + function test_update_customer_personal_info_with_empty_phone() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/personal-info'); + $request->set_body_params(array( + 'first_name' => 'Trunks', + 'last_name' => 'Goten', + 'phone' => '' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('phone', $profile_info); + $this->assertEquals($profile_info['phone'], ''); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADD_PHONE_NUMBER'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_personal_info + */ + function test_update_customer_personal_info_with_empty_name() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/personal-info'); + $request->set_body_params(array( + 'first_name' => '', + 'last_name' => '', + 'phone' => '23232' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('phone', $profile_info); + $this->assertEquals($profile_info['phone'], ''); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADD_NAME'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_personal_info + */ + function test_update_customer_personal_info() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/personal-info'); + $request->set_body_params(array( + 'first_name' => 'Trunks', + 'last_name' => 'Goten', + 'phone' => '3434' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('phone', $profile_info); + $this->assertArrayHasKey('name', $profile_info); + $this->assertEquals($profile_info['phone'], '3434'); + $this->assertEquals($profile_info['name'], 'Trunks Goten'); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'PROFILE_UPDATED'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_company_info + */ + function test_update_customer_company_info_as_guest() { + wp_set_current_user(0); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/company-info'); + $request->set_body_params(array( + 'company_name' => 'Saburly', + 'vat_code' => '12345' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_company_info + */ + function test_update_customer_company_info_with_empty_company_name() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/company-info'); + $request->set_body_params(array( + 'company_name' => '', + 'vat_code' => '12345' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('company_name', $profile_info); + $this->assertArrayHasKey('vat_code', $profile_info); + $this->assertEquals($profile_info['company_name'], ''); + $this->assertEquals($profile_info['vat_code'], ''); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADD_COMPANY_NAME'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_company_info + */ + function test_update_customer_company_info_with_empty_vat() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/company-info'); + $request->set_body_params(array( + 'company_name' => 'Saburly', + 'vat_code' => '' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('company_name', $profile_info); + $this->assertArrayHasKey('vat_code', $profile_info); + $this->assertEquals($profile_info['company_name'], ''); + $this->assertEquals($profile_info['vat_code'], ''); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'ADD_VAT'); + } + + /** + * @covers Wiass_REST_Customer_API::update_customer_company_info + */ + function test_update_customer_company_info() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/company-info'); + $request->set_body_params(array( + 'company_name' => 'Saburly', + 'vat_code' => '123' + )); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + + $this->assertArrayHasKey('data', $data); + $this->assertArrayHasKey('messages', $data); + + $profile_info = $data['data']; + $messages = $data['messages'][0]; + + $this->assertArrayHasKey('company_name', $profile_info); + $this->assertArrayHasKey('vat_code', $profile_info); + $this->assertEquals($profile_info['company_name'], 'Saburly'); + $this->assertEquals($profile_info['vat_code'], '123'); + + $this->assertArrayHasKey('message', $messages); + $this->assertEquals($messages['message'], 'COMPANY_UPDATED'); + } + + + + //Helper functions + private function create_dummy_address(){ + return array( + 'country_name' => 'Sweden', + 'delivery_mail' => 'delivery@email.com', + 'id_country_selected' => 1, + 'city' => 'Stockholm', + 'detailed_address' => 'Dummy Street 7', + 'zip_code' => 124443, + 'first_name' => 'Tester', + 'last_name' => 'Retset', + 'invoice_mail' => 'invoice@mail.com' + ); + } + + private function insert_dummy_billing_address(){ + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/billing-addresses'); + $request->set_body_params(array( + 'billing_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + return $response->get_data()['data']['billing_addresses'][0]['id']; + } + + private function insert_dummy_profile_address(){ + wp_set_current_user(1); + + $dummy_address = self::create_dummy_address(); + + $request = new WP_REST_Request( 'PUT', '/wiaas/customer/1/profile-addresses'); + $request->set_body_params(array( + 'profile_address' => json_encode($dummy_address) + )); + $response = $this->server->dispatch( $request ); + + return $response->get_data()['data']['profile_addresses'][0]['id']; + } +} diff --git a/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-user-api.php b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-user-api.php new file mode 100644 index 0000000..6f8176a --- /dev/null +++ b/backend/app/plugins/wiaas/tests/unit-tests/test-wiaas-rest-user-api.php @@ -0,0 +1,108 @@ +server = $wp_rest_server = new \WP_REST_Server; + do_action( 'rest_api_init' ); + } + + /** + * @covers Wiass_REST_User_API::validate_token + */ + function test_validate_token_as_guest() { + wp_set_current_user(0); + + $request = new WP_REST_Request( 'POST', '/wiaas/user/validate-token'); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_User_API::validate_token + */ + function test_validate_token_with_valid_user() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'POST', '/wiaas/user/validate-token'); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $user_info = $response->get_data()['userInfo']; + $this->assertNotNull($user_info); + $this->assertTrue(is_array($user_info)); + $this->assertArrayHasKey('wiaas_id_user', $user_info); + $this->assertArrayHasKey('wiaas_is_company_admin', $user_info); + $this->assertArrayHasKey('wiaas_user_full_name', $user_info); + $this->assertArrayHasKey('wiaas_user_type', $user_info); + $this->assertArrayHasKey('wiaas_username', $user_info); + $this->assertEquals($user_info['wiaas_id_user'], '1'); + $this->assertEquals($user_info['wiaas_is_company_admin'], '1'); + $this->assertEquals($user_info['wiaas_username'], 'admin'); + } + + /** + * @covers Wiass_REST_User_API::get_countries + */ + function test_get_countries_as_guest() { + wp_set_current_user(0); + + $request = new WP_REST_Request( 'GET', '/wiaas/user/get-countries'); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertTrue($response->is_error()); + $this->assertEquals($response->get_status(), 401); + + $error_data = $response->as_error(); + $this->assertEquals($error_data->get_error_message(), 'Sorry, you are not allowed to do that.'); + } + + /** + * @covers Wiass_REST_User_API::get_countries + */ + function test_get_countries() { + wp_set_current_user(1); + + $request = new WP_REST_Request( 'GET', '/wiaas/user/get-countries'); + $response = $this->server->dispatch( $request ); + + $this->assertNotNull($response); + $this->assertInstanceOf('WP_REST_Response',$response); + $this->assertFalse($response->is_error()); + $this->assertEquals($response->get_status(), 200); + + $data = $response->get_data(); + $this->assertNotNull($data); + $this->assertTrue(is_array($data)); + + $country = $data[0]; + $this->assertNotNull($country); + $this->assertTrue(is_array($country)); + $this->assertArrayHasKey('country_id', $country); + $this->assertArrayHasKey('country_name', $country); + } +} diff --git a/backend/app/plugins/wiaas/wiaas.php b/backend/app/plugins/wiaas/wiaas.php index a9220a1..96c0250 100644 --- a/backend/app/plugins/wiaas/wiaas.php +++ b/backend/app/plugins/wiaas/wiaas.php @@ -43,3 +43,5 @@ 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'; + +include_once WIAAS_DIR . '/includes/class-wiass-templates.php'; diff --git a/docker/frontend/000-default.conf b/docker/frontend/000-default.conf new file mode 100644 index 0000000..82a3f0c --- /dev/null +++ b/docker/frontend/000-default.conf @@ -0,0 +1,41 @@ + + # The ServerName directive sets the request scheme, hostname and port that + # the server uses to identify itself. This is used when creating + # redirection URLs. In the context of virtual hosts, the ServerName + # specifies what hostname must appear in the request's Host: header to + # match this virtual host. For the default virtual host (this file) this + # value is not decisive as it is used as a last resort host regardless. + # However, you must set it for any further virtual host explicitly. + #ServerName www.example.com + + ServerAdmin webmaster@localhost + DocumentRoot /var/www/html + + + RewriteEngine on + # Don't rewrite files or directories + RewriteCond %{REQUEST_FILENAME} -f [OR] + RewriteCond %{REQUEST_FILENAME} -d + RewriteRule ^ - [L] + # Rewrite everything else to index.html to allow html5 state links + RewriteRule ^ index.html [L] + + + # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, + # error, crit, alert, emerg. + # It is also possible to configure the loglevel for particular + # modules, e.g. + #LogLevel info ssl:warn + + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined + + # For most configuration files from conf-available/, which are + # enabled or disabled at a global level, it is possible to + # include a line for only one particular virtual host. For example the + # following line enables the CGI configuration for this host only + # after it has been globally disabled with "a2disconf". + #Include conf-available/serve-cgi-bin.conf + + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/frontend.dockerfile b/frontend.dockerfile index 77bb2f2..0904278 100644 --- a/frontend.dockerfile +++ b/frontend.dockerfile @@ -8,6 +8,8 @@ RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - RUN apt-get install -y nodejs COPY frontend /home/wiaas/frontend +RUN a2enmod rewrite +COPY docker/frontend/000-default.conf /etc/apache2/sites-available WORKDIR /home/wiaas/frontend RUN npm install && npm rebuild node-sass --force && npm run build diff --git a/frontend/src/actions/login/authActions.js b/frontend/src/actions/login/authActions.js index 55e2b4d..5c64b61 100644 --- a/frontend/src/actions/login/authActions.js +++ b/frontend/src/actions/login/authActions.js @@ -34,56 +34,23 @@ export const validateToken = () => ({ type: VALIDATE_TOKEN }); -export const validateAccessToken = (token) => { +export const validateAccessToken = () => { return dispatch => { dispatch(validateToken()); return htmlClient.fetch({ - url: `${API_SERVER}/wp-json/jwt-auth/v1/token/validate`, - method: 'post' - }) + url: `${API_SERVER}/wp-json/wiaas/user/validate-token`, + method: 'post' + }) .then(response => { - if (response.data && response.data.data.status === 200) { + if (response.data && response.status === 200) { // TODO: Implement refresh logic on backend as it was on old wias , or find a nother way // to handle token validation another way // const serverTime = response.data.serverTime || 1; - - dispatch(loggedIn({ - accessToken: token, - userInfo: { - "id": 2, - "name": "Customer User", - "mail": "customer@mail.com", - "phone": "", - "userType": "customer", - "vatCode": "556084-6783", - "companyName": "Coor Service Management AB", - "billingAddresses": [ - { - "id": 1, - "city": "fsdfcsdfcs", - "countryName": "SE", - "detailedAddress": "sdfcsvfsdf, fdfvds, fdfvds", - "firstName": "Customer", - "lastName": "User", - "zipCode": "323232" - } - ], - "profileAddresses": [ - { - "id": 1, - "city": "fsdfcsdfcs", - "countryName": "fsdfcsdfcs", - "detailedAddress": "sdfcsvfsdf, fdfvds, fdfvds", - "zipCode": "323232" - } - ] - } - })); + dispatch(loggedIn(response.data.userInfo)); // refreshToken = response.data.refreshToken; // startRefreshTimer(dispatch, serverTime); - // dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); - dispatch(setUserAsCompanyAdmin(false)); + dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); } else { dispatch(loginFail(response.data)); } @@ -96,7 +63,7 @@ export const validateAccessToken = (token) => { } } -export const setUserAsCompanyAdmin = (isCompanyAdmin) => ({type: SET_COMPANY_ADMIN_FLAG, isCompanyAdmin}); +export const setUserAsCompanyAdmin = (isCompanyAdmin) => ({ type: SET_COMPANY_ADMIN_FLAG, isCompanyAdmin }); export const validateCredentials = (username, password) => { return dispatch => { @@ -113,22 +80,12 @@ export const validateCredentials = (username, password) => { .then(response => { if (response.data && response.data.token) { const decodedAceessToken = jwtDecode(response.data.token); - - // TODO : Uncomment code, and fix user type logic after adding customer type to woocommerce backend - - // if(decodedAceessToken.data.wiaas_user_type === 'customer'){ localStorage.setItem('accessToken', response.data.token); - localStorage.setItem('username', username); + localStorage.setItem('userInfo', JSON.stringify(response.data.userInfo)); const serverTime = decodedAceessToken.nbf || 1; - // refreshToken = response.data.refreshToken; startRefreshTimer(dispatch, serverTime); - dispatch(loggedIn(response.data)); - // dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); - dispatch(setUserAsCompanyAdmin(false)); - - // }else{ - // dispatch(loginFail({status: 'fail', errorMessage: 'INVALID_USER_TYPE'})); - // } + dispatch(loggedIn(response.data.userInfo)); + dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); } else { dispatch(loginFail(response.data)); } @@ -145,10 +102,10 @@ const startRefreshTimer = (dispatch, serverTime) => { const tokenTimeLeft = decodedAceessToken.exp - serverTime; const refreshTime = tokenTimeLeft ? (tokenTimeLeft - TEN_MINUTES) * 1000 : REFRESH_TIME; - if(refreshTime <= 0){ + if (refreshTime <= 0) { dispatch(validateRefreshToken()); - }else{ - refreshTimer = setTimeout(()=>{ + } else { + refreshTimer = setTimeout(() => { dispatch(validateRefreshToken()); }, refreshTime); } @@ -162,28 +119,28 @@ const validateRefreshToken = () => { return dispatch => { dispatch(requestRefreshToken()); return htmlClient.fetch({ - url: `${API_SERVER}/login/api/refreshToken`, - method: 'post', - data: { - refreshToken, - lastActivity: authActivity.lastActivity - } - }) - .then(response => { - if (response.data.status === 'success') { - localStorage.setItem('accessToken', response.data.accessToken); - const serverTime = response.data.serverTime || 1; - refreshToken = response.data.refreshToken; - dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); - startRefreshTimer(dispatch, serverTime); - } else { - dispatch(logout(response.data)); - dispatch(loginFail(response.data)); + url: `${API_SERVER}/login/api/refreshToken`, + method: 'post', + data: { + refreshToken, + lastActivity: authActivity.lastActivity } }) - .catch(error => { - htmlClient.onError(error, dispatch); - }); + .then(response => { + if (response.data.status === 'success') { + localStorage.setItem('accessToken', response.data.accessToken); + const serverTime = response.data.serverTime || 1; + refreshToken = response.data.refreshToken; + dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin)); + startRefreshTimer(dispatch, serverTime); + } else { + dispatch(logout(response.data)); + dispatch(loginFail(response.data)); + } + }) + .catch(error => { + htmlClient.onError(error, dispatch); + }); } } @@ -193,62 +150,62 @@ export const getModules = () => { dispatch(requestModules()); let appModules = { modules: { - modules: [ - { - id: '15', - name: 'Terms', - menuName: 'Terms', - url: 'terms', - isInMenu: '0' - }, - { - id: '19', - name: 'Cart', - menuName: 'Cart', - url: 'cart', - isInMenu: '0' - }, - { - id: '14', - name: 'ProfileSettings', - menuName: 'ProfileSettings', - url: 'profileSettings', - isInMenu: '0' - }, - { - id: '23', - name: 'OrderProjects', - menuName: 'OrderProjects', - url: 'orderProjects', - isInMenu: '0' - }, - { - id: '1', - name: 'Dashboards', - menuName: 'Overview', - url: 'dashboards', - isInMenu: '1' - }, - { - id: '18', - name: 'CoMarket', - menuName: 'Co-Market', - url: 'co-market', - isInMenu: '1' + modules: [ + { + id: '15', + name: 'Terms', + menuName: 'Terms', + url: 'terms', + isInMenu: '0' + }, + { + id: '19', + name: 'Cart', + menuName: 'Cart', + url: 'cart', + isInMenu: '0' + }, + { + id: '14', + name: 'ProfileSettings', + menuName: 'ProfileSettings', + url: 'profileSettings', + isInMenu: '0' + }, + { + id: '23', + name: 'OrderProjects', + menuName: 'OrderProjects', + url: 'orderProjects', + isInMenu: '0' + }, + { + id: '1', + name: 'Dashboards', + menuName: 'Overview', + url: 'dashboards', + isInMenu: '1' + }, + { + id: '18', + name: 'CoMarket', + menuName: 'Co-Market', + url: 'co-market', + isInMenu: '1' + } + ], + subModules: { + 'co-market': [ + { + moduleUrl: 'co-market', + menuName: 'Orders', + name: 'Orders', + url: 'orders' + } + ] } - ], - subModules: { - 'co-market': [ - { - moduleUrl: 'co-market', - menuName: 'Orders', - name: 'Orders', - url: 'orders' - } - ] - } } - } + } return dispatch(recieveModules(appModules)); // return htmlClient.fetch({ // url: `${API_SERVER}/login/api/getModules`, @@ -275,6 +232,7 @@ const recieveModules = (json) => ({ export const logout = () => { localStorage.removeItem('accessToken'); + localStorage.removeItem('userInfo'); clearInterval(refreshTimer); return { type: LOGOUT, @@ -283,11 +241,11 @@ export const logout = () => { } } -export const loggedIn = (jsonData) => { +export const loggedIn = (userInfo) => { return { type: LOGIN_SUCCESS, - isLoggedIn: true - // userInfo: jsonData.userInfo + isLoggedIn: true, + userInfo: userInfo } } @@ -303,13 +261,13 @@ export const generatePassword = (mail) => { return dispatch => { dispatch(requestForgotPassword()); return htmlClient.fetch({ - url: `${API_SERVER}/login/api/forgotPassword`, - method: 'post', - data: {mail}, - header: {} - }) + url: `${API_SERVER}/login/api/forgotPassword`, + method: 'post', + data: { mail }, + header: {} + }) .then(response => { - if(typeof response.data !== 'undefined' && 'messages' in response.data) { + if (typeof response.data !== 'undefined' && 'messages' in response.data) { dispatch(forgotPasswordMessage(response.data.messages[0])); } }) @@ -319,7 +277,7 @@ export const generatePassword = (mail) => { } } -const requestForgotPassword = () => ({ +const requestForgotPassword = () => ({ type: REQUEST_FORGOT_PASSWORD, errorMessage: 'FORGOT_REQUEST_SENT' }); @@ -350,13 +308,13 @@ export const changePassword = (token, newPassword, confirmPassword) => { return dispatch => { dispatch(requestChange()); return htmlClient.fetch({ - url: `${API_SERVER}/login/api/changePassword`, - method: 'post', - data: {token, newPassword, confirmPassword}, - header: {} - }) + url: `${API_SERVER}/login/api/changePassword`, + method: 'post', + data: { token, newPassword, confirmPassword }, + header: {} + }) .then(response => { - if(response.data.messages && response.data.messages.length > 0){ + if (response.data.messages && response.data.messages.length > 0) { dispatch(passwordChanged(response.data.messages[0])); } }) diff --git a/frontend/src/actions/profileSettings/addressActions.js b/frontend/src/actions/profileSettings/addressActions.js index fc4f2df..3db8807 100644 --- a/frontend/src/actions/profileSettings/addressActions.js +++ b/frontend/src/actions/profileSettings/addressActions.js @@ -9,9 +9,11 @@ import { REQUEST_SAVE_BILLING_ADDRESS, profileTexts } from '../../constants/profileSettingsConstants'; -import {fetchProfileInfo} from './profileSettingsActions'; import {updateMessages} from '../notification/notificationActions'; import {setDialogOpenFlag} from '../dialog/dialogActions'; +import {recieveProfileInfo} from './profileSettingsActions'; +import { fromWiaasProfileInfo } from '../../helpers/ProfileHelper'; +import { toWiaasAddress } from '../../helpers/AddressHelper'; const client = new HtmlClient(); @@ -23,17 +25,17 @@ export const saveProfileAddress = (idUser, profileAddress) => { return dispatch => { dispatch(requestSaveAddress()); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/saveProfileAddress`, - method: 'post', - data: {profileAddress: JSON.stringify(profileAddress)} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/profile-addresses`, + method: 'put', + data: { + 'profile_address': JSON.stringify(toWiaasAddress(profileAddress)) + } }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - if(response.data.messages[0].code === 'success'){ - dispatch(fetchProfileInfo(idUser)); - dispatch(setDialogOpenFlag(false)); - } + dispatch(setDialogOpenFlag(false)); } }) .catch(error => { @@ -50,14 +52,13 @@ export const removeProfileAddress = (idUser, idProfileAddress) => { return dispatch => { dispatch(requestRemoveAddress()); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/removeProfileAddress`, - method: 'post', - data: {idProfileAddress} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/profile-addresses/${idProfileAddress}`, + method: 'delete' }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - dispatch(fetchProfileInfo(idUser)); } }) .catch(error => { @@ -70,21 +71,21 @@ const requestSaveBillingAddress = () => ({ type: REQUEST_SAVE_BILLING_ADDRESS }); -export const saveBillingAddress = (idUser, idCompany, billingAddress) => { +export const saveBillingAddress = (idUser, billingAddress) => { return dispatch => { dispatch(requestSaveBillingAddress()); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/saveBillingAddress`, - method: 'post', - data: {idCompany, billingAddress: JSON.stringify(billingAddress)} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/billing-addresses`, + method: 'put', + data: { + 'billing_address': JSON.stringify(toWiaasAddress(billingAddress)) + } }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - if(response.data.messages[0].code === 'success'){ - dispatch(fetchProfileInfo(idUser)); - dispatch(setDialogOpenFlag(false)); - } + dispatch(setDialogOpenFlag(false)); } }) .catch(error => { @@ -101,14 +102,14 @@ export const removeBillingAddress = (idUser, idBillingAddress) => { return dispatch => { dispatch(requestRemoveBillingAddress()); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/removeBillingAddress`, - method: 'post', - data: {idBillingAddress} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/billing-addresses/${idBillingAddress}`, + method: 'delete' }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - dispatch(fetchProfileInfo(idUser)); + dispatch(setDialogOpenFlag(false)); } }) .catch(error => { diff --git a/frontend/src/actions/profileSettings/profileSettingsActions.js b/frontend/src/actions/profileSettings/profileSettingsActions.js index 8f5ad69..5d8a216 100644 --- a/frontend/src/actions/profileSettings/profileSettingsActions.js +++ b/frontend/src/actions/profileSettings/profileSettingsActions.js @@ -12,6 +12,8 @@ import { profileTexts } from '../../constants/profileSettingsConstants'; import {updateMessages} from '../notification/notificationActions'; +import { fromWiaasProfileInfo} from '../../helpers/ProfileHelper'; +import {fromWiaasCountryList} from '../../helpers/CountryHelper'; const client = new HtmlClient(); @@ -29,49 +31,15 @@ export const recieveProfileInfo = (json) => ({ export const fetchProfileInfo = (idUser) => { return dispatch => { dispatch(requestProfileInfo()); - - dispatch(recieveProfileInfo({ - "id": 2, - "name": "Customer User", - "mail": "customer@mail.com", - "phone": "", - "userType": "customer", - "vatCode": "556084-6783", - "companyName": "Coor Service Management AB", - "billingAddresses": [ - { - "id": 1, - "city": "Göteborg", - "countryName": "SE", - "detailedAddress": "Lilla Bommen 2", - "firstName": "Customer", - "lastName": "User", - "zipCode": "12323" + return client.fetch({ + url: `${API_SERVER}/wp-json/wc/v2/customers/${idUser}`, + method: 'get' + }) + .then(response => { + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data))); } - ], - "profileAddresses": [ - { - "id": 1, - "city": "Göteborg", - "countryName": "Göteborg", - "detailedAddress": "Lilla Bommen 2", - "zipCode": "12323" - } - ] - })); - // return client.fetch({ - // url: `${API_SERVER}/wp-json/wiaas/cart/customer-info`, - // method: 'get', - // data: {idUser} - // }) - // .then(response => { - // if(response.data){ - // dispatch(recieveProfileInfo(response.data)); - // } - // }) - // .catch(error => { - // client.onError(error, dispatch); - // }); + }); } }; @@ -82,15 +50,20 @@ const requestSaveProfile = () => ({ export const saveProfileInfo = (idUser, profile) => { return dispatch => { dispatch(requestSaveProfile()); + const parsedFullName = profile.name.trim().split(' '); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/saveProfileInfo`, - method: 'post', - data: {idUser, profile: JSON.stringify(profile)} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/personal-info`, + method: 'PUT', + data: { + 'first_name': parsedFullName[0], + 'last_name': parsedFullName[1], + 'phone': profile.phone + } }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - dispatch(fetchProfileInfo(idUser)); } }) .catch(error => { @@ -107,14 +80,17 @@ export const saveCompanyInfo = (idUser, companyInfo) => { return dispatch => { dispatch(requestSaveCompany()); return client.fetch({ - url: `${API_SERVER}/profileSettings/api/saveCompanyInfo`, - method: 'post', - data: {companyInfo: JSON.stringify(companyInfo)} + url: `${API_SERVER}/wp-json/wiaas/customer/${idUser}/company-info`, + method: 'put', + data: { + 'vat_code': companyInfo.vatCode, + 'company_name': companyInfo.companyName + } }) .then(response => { - if(response.data && response.data.messages){ + if(response.data){ + dispatch(recieveProfileInfo(fromWiaasProfileInfo(response.data.data))); dispatch(updateMessages(response.data.messages, profileTexts.messages)); - dispatch(fetchProfileInfo(idUser)); } }) .catch(error => { @@ -137,32 +113,17 @@ const recieveCountries = (json) => ({ export const fetchCountries = () => { return dispatch => { dispatch(requestCountries()); - - dispatch(recieveCountries([ - { - "idCountry": 3, - "countryName": "Denmark" - }, - { - "idCountry": 4, - "countryName": "Finland" - }, - { - "idCountry": 2, - "countryName": "Sweden" - } - ])); - // return client.fetch({ - // url: `${API_SERVER}/profileSettings/api/getCoutnries`, - // method: 'get' - // }) - // .then(response => { - // if(response.data){ - // dispatch(recieveCountries(response.data)); - // } - // }) - // .catch(error => { - // client.onError(error, dispatch); - // }); + return client.fetch({ + url: `${API_SERVER}/wp-json/wiaas/user/get-countries`, + method: 'get' + }) + .then(response => { + if(response.data){ + dispatch(recieveCountries(response.data.map(country => fromWiaasCountryList(country)))); + } + }) + .catch(error => { + client.onError(error, dispatch); + }); } }; diff --git a/frontend/src/constants/profileSettingsConstants.js b/frontend/src/constants/profileSettingsConstants.js index cd4a7de..8477a1e 100644 --- a/frontend/src/constants/profileSettingsConstants.js +++ b/frontend/src/constants/profileSettingsConstants.js @@ -35,7 +35,8 @@ export const profileTexts = { FIRST_NAME: 'First Name', LAST_NAME: 'Last Name', DELEGATE: 'Attention', - INVOICE_MAIL: 'Invoice Mail' + INVOICE_MAIL: 'Invoice Mail', + DELIVERY_MAIL: 'Delivery Mail' }, buttons: { SAVE: 'Save', @@ -56,7 +57,7 @@ export const profileTexts = { PROFILE_NOT_CHANGED: 'No changes!', NOT_COMPANY_ADMIN: 'You are not allowed to change the company information! Contact your company admin user.', ADD_VAT: 'The vat code can not be empty!', - ADD_COPMANY_NAME: 'The company name can not be empty!', + ADD_COMPANY_NAME: 'The company name can not be empty!', COMPANY_UPDATED: 'Company info updated!', COMPANY_NOT_CHANGED: 'No changes!', ADD_COMPANY: 'Invalid company!', @@ -77,6 +78,7 @@ export const profileTexts = { ADD_FIRST_NAME: 'The first name field can not be empty', ADD_LAST_NAME: 'The last name field can not be empty', ADD_INVOICE_MAIL: 'The invoice mail field can not be empty', - INVALID_INVOICE_MAIL: 'Invalid invoice mail address' + INVALID_INVOICE_MAIL: 'Invalid invoice mail address', + INTERNAL_SERVER_ERROR: 'Error occured. Please try again' } }; diff --git a/frontend/src/containers/cart/CartCustomerDetailsContainer.jsx b/frontend/src/containers/cart/CartCustomerDetailsContainer.jsx index 564f69e..1cd43bb 100644 --- a/frontend/src/containers/cart/CartCustomerDetailsContainer.jsx +++ b/frontend/src/containers/cart/CartCustomerDetailsContainer.jsx @@ -45,8 +45,7 @@ class CartCustomerDetailsContainer extends Component { this.props.dispatch(fetchCartItems()); this.props.dispatch(setNextActionFct(this.handleNextAction)); this.props.dispatch(setPrevActionFct(this.handlePrevAction)); - //this.props.dispatch(fetchProfileInfo(this.props.userInfo.wiaas_id_user)); - this.props.dispatch(fetchProfileInfo()); + this.props.dispatch(fetchProfileInfo(this.props.userInfo.wiaas_id_user)); this.props.dispatch(fetchCountries()); } @@ -192,7 +191,7 @@ class CartCustomerDetailsContainer extends Component { (profileInfo && !isProfileLoading) && + idUser={this.props.userInfo.wiaas_id_user}/> } @@ -206,7 +205,7 @@ class CartCustomerDetailsContainer extends Component { + idUser={this.props.userInfo.wiaas_id_user}/> } diff --git a/frontend/src/containers/cart/components/SelectDeliveryAddress.jsx b/frontend/src/containers/cart/components/SelectDeliveryAddress.jsx index 9fddad5..2dea908 100644 --- a/frontend/src/containers/cart/components/SelectDeliveryAddress.jsx +++ b/frontend/src/containers/cart/components/SelectDeliveryAddress.jsx @@ -21,7 +21,16 @@ class SelectDeliveryAddress extends Component {
- {profileAddress.countryName}, {profileAddress.city}, {profileAddress.detailedAddress}, {profileAddress.zipCode} +
+ {profileAddress.firstName} {profileAddress.lastName} + { + profileAddress.deliveryMail && + ( {profileAddress.deliveryMail} ) + } +
+
+ {profileAddress.countryName}, {profileAddress.city}, {profileAddress.detailedAddress}, {profileAddress.zipCode} +
0){ + this.props.dispatch(updateMessages(messages, profileTexts.messages)); + }else{ + this.props.dispatch(saveBillingAddress(this.props.idUser, address)); + } } onAddressChange(address){ diff --git a/frontend/src/containers/profileSettings/ProfileAddressesContainer.jsx b/frontend/src/containers/profileSettings/ProfileAddressesContainer.jsx index b636cd9..079441d 100644 --- a/frontend/src/containers/profileSettings/ProfileAddressesContainer.jsx +++ b/frontend/src/containers/profileSettings/ProfileAddressesContainer.jsx @@ -9,6 +9,7 @@ import {profileTexts} from '../../constants/profileSettingsConstants'; import {setDialogContent, setDialogOpenFlag} from '../../actions/dialog/dialogActions'; import {saveProfileAddress, removeProfileAddress} from '../../actions/profileSettings/addressActions'; import './style/AddressesContainer.css'; +import { updateMessages } from '../../actions/notification/notificationActions'; class ProfileAddressesContainer extends Component { constructor(props) { @@ -21,7 +22,30 @@ class ProfileAddressesContainer extends Component { } saveProfileAddress(profileAddress){ - this.props.dispatch(saveProfileAddress(this.props.idUser, profileAddress)); + const messages = []; + if (!profileAddress.zipCode){ + messages.push({ + 'code':'error', + 'message':'ADD_ZIP' + }); + } + if (!profileAddress.detailedAddress){ + messages.push({ + 'code':'error', + 'message':'ADD_ADDRESS' + }); + } + if (!profileAddress.city){ + messages.push({ + 'code':'error', + 'message':'ADD_CITY' + }); + } + if (messages.length > 0){ + this.props.dispatch(updateMessages(messages, profileTexts.messages)); + }else{ + this.props.dispatch(saveProfileAddress(this.props.idUser, profileAddress)); + } } onAddressChange(address){ diff --git a/frontend/src/containers/profileSettings/components/AddEditBillingAddress.jsx b/frontend/src/containers/profileSettings/components/AddEditBillingAddress.jsx index c889af9..3748e78 100644 --- a/frontend/src/containers/profileSettings/components/AddEditBillingAddress.jsx +++ b/frontend/src/containers/profileSettings/components/AddEditBillingAddress.jsx @@ -42,6 +42,7 @@ class AddEditBillingAddress extends Component { {profileTexts.labels.LAST_NAME} {profileTexts.labels.INVOICE_MAIL} @@ -89,6 +93,7 @@ class AddEditBillingAddress extends Component { {profileTexts.labels.ADDRESS_DETAILS}* {profileTexts.labels.ADDRESS_ZIP}*
+
{profileTexts.labels.DELEGATE}
+ + + + + + + + + + + + + + + +
{profileTexts.labels.BILLING_ADDRESSES}
{profileTexts.labels.ADDRESS_CITY}*
- {profileAddress.countryName}, {profileAddress.city}, {profileAddress.detailedAddress}, {profileAddress.zipCode} +
+ {profileAddress.firstName} {profileAddress.lastName} + { + profileAddress.deliveryMail && + ( {profileAddress.deliveryMail} ) + } +
+
+ {profileAddress.countryName}, {profileAddress.city}, {profileAddress.detailedAddress}, {profileAddress.zipCode} +
{ + return { + id: address.id, + countryName: address.country_name, + deliveryMail: address.delivery_mail, + idCountrySelected: address.id_country_selected, + city: address.city, + detailedAddress: address.detailed_address, + zipCode: address.zip_code, + firstName: address.first_name, + lastName: address.lastName, + invoiceMail: address.invoice_mail + } +}; + +export const toWiaasAddress = (address) => { + return { + id: address.id, + country_name: address.countryName, + delivery_mail: address.deliveryMail, + id_country_selected: address.idCountrySelected, + city: address.city, + detailed_address: address.detailedAddress, + zip_code: address.zipCode, + first_name: address.firstName, + last_name: address.lastName, + invoice_mail: address.invoiceMail + } +}; \ No newline at end of file diff --git a/frontend/src/helpers/CountryHelper.js b/frontend/src/helpers/CountryHelper.js new file mode 100644 index 0000000..e1c2ca6 --- /dev/null +++ b/frontend/src/helpers/CountryHelper.js @@ -0,0 +1,6 @@ +export const fromWiaasCountryList = (countryList) => { + return { + idCountry: countryList.country_id, + countryName: countryList.country_name + } +} \ No newline at end of file diff --git a/frontend/src/helpers/ProfileHelper.js b/frontend/src/helpers/ProfileHelper.js new file mode 100644 index 0000000..17d3d93 --- /dev/null +++ b/frontend/src/helpers/ProfileHelper.js @@ -0,0 +1,17 @@ +import { fromWiaasAddress } from "./AddressHelper"; + +export const fromWiaasProfileInfo = (profileInfo) => { + return { + id: profileInfo.id, + idCompany: profileInfo.company_id, + companyName: profileInfo.company_name, + vatCode: profileInfo.vat_code, + isCompanyAdmin: profileInfo.is_company_admin, + mail: profileInfo.mail, + name: profileInfo.name, + phone: profileInfo.phone, + billingAddresses: profileInfo.billing_addresses.map(address => fromWiaasAddress(address)), + profileAddresses: profileInfo.profile_addresses.map(address => fromWiaasAddress(address)), + userType: profileInfo.user_type, + } +}; \ No newline at end of file