diff --git a/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-documents.php b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-documents.php new file mode 100644 index 0000000..45c56eb --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/class-wiaas-admin-documents.php @@ -0,0 +1,14 @@ +post_type != 'wiaas_doc' ) { + return; + } + + // unset nonce because it's only valid of 1 post + unset( $_POST['wiaas_doc_nonce'] ); + + if (isset($_POST['wiaas_doc_version']) && $_POST['wiaas_doc_version'] !== '') { + $version = sanitize_text_field($_POST['wiaas_doc_version']); + + if(wiaas_document_version_exists($version)) { + Wiaas_Document::add_document_version($post_id, $version); + } + } + + if (isset($_POST['wiaas_doc_type'])) { + Wiaas_Document::set_doc_type($post_id, sanitize_key($_POST['wiaas_doc_type'])); + } + + Wiaas_Document::set_is_doc_visible($post_id, $_POST['wiaas_doc_visible'] === 'on'); + } + + /** + * Render wiaas document info metabox + */ + public static function document_info() { + global $post; + + $parent_post_type = $post->post_type; + $document_id = $post->ID; + + $ajax_action = 'wiaas_upload_file'; + + require 'views/html-document-info.php'; + } + +} + +Wiaas_Admin_Document_Editor::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/documents/class-wiaas-admin-product-documents.php b/backend/app/plugins/wiaas/includes/admin/documents/class-wiaas-admin-product-documents.php new file mode 100644 index 0000000..2e63445 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/class-wiaas-admin-product-documents.php @@ -0,0 +1,78 @@ + __( 'Linked Documents', 'wiaas' ), + 'target' => 'wiaas_documents', + 'class' => array('show_if_bundle', 'show_if_simple'), + 'priority' => 20, + ); + + return $tabs; + } + + /** + * Render linked documents tab content for product screen + */ + public static function linked_documents_tab() { + + global $post; + + $documents_ids = wiaas_get_object_attached_documents($post->ID); + + include 'views/html-product-documents.php'; + } + + + /** + * Save linked document for product + * + * @param int $package_id + */ + public static function process_meta_box($package_id) { + $documents = isset($_POST['wiaas_attached_documents']) && is_array($_POST['wiaas_attached_documents']) ? + $_POST['wiaas_attached_documents'] : array(); + + wiaas_attach_documents_to_object($package_id, $documents); + } +} + +Wiaas_Admin_Product_Documents::init(); diff --git a/backend/app/plugins/wiaas/includes/admin/documents/views/html-attached-document.php b/backend/app/plugins/wiaas/includes/admin/documents/views/html-attached-document.php new file mode 100644 index 0000000..786f182 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/views/html-attached-document.php @@ -0,0 +1,51 @@ + + + + + '; + } else { + echo ''; + } + ?> + + +
+ + + + +
+ + + + + + + + + + + + + + diff --git a/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-form.php b/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-form.php new file mode 100644 index 0000000..0cd880a --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-form.php @@ -0,0 +1,258 @@ +post_type !== 'wiaas_doc'; + +?> + + + + + +
+ + +

+ +

+ + +

+ +

+ +

+ ID), true, true) ?> + type="checkbox" + /> + +

+ + + +
+
+
+
+

+ +

+ +

+
+
+

+
+
+ +
+
+ +
diff --git a/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-info.php b/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-info.php new file mode 100644 index 0000000..118869f --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/views/html-document-info.php @@ -0,0 +1,87 @@ + + + + + + +
+ + + +
+ +
+ + +
+ + + + + + + + + + $version) { + ?> + + + + + + + +
Versions
+ + + +
+
+
diff --git a/backend/app/plugins/wiaas/includes/admin/documents/views/html-product-documents.php b/backend/app/plugins/wiaas/includes/admin/documents/views/html-product-documents.php new file mode 100644 index 0000000..4bdbe45 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/views/html-product-documents.php @@ -0,0 +1,84 @@ + + + + +
+
+

+ + +

+
+
+
+
+ + + + +
+
+
+
+
diff --git a/backend/app/plugins/wiaas/includes/admin/documents/wiaas-admin-document-ajax.php b/backend/app/plugins/wiaas/includes/admin/documents/wiaas-admin-document-ajax.php new file mode 100644 index 0000000..f02907e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/admin/documents/wiaas-admin-document-ajax.php @@ -0,0 +1,105 @@ +get_error_message(); + die(); + } + + echo $version; + die(); +} + +/** + * Quick add new document and return attachment view for it + */ +function wiaas_ajax_quick_add_document() { + check_ajax_referer('wiaas_quick_add_document'); + + //validate file + if (!isset($_FILES['wiaas_file']) || empty($_FILES['wiaas_file'])) { + echo "ERROR: No file present!"; + die(); + } + + // Upload document version file + $version = Wiaas_Document_Upload::upload_document_version('wiaas_file'); + + // Upload failed so return the error + if (is_wp_error($version)) { + echo 'ERROR:' . $version->get_error_message(); + die(); + } + + // Get document title + $title = isset($_POST['doc_title']) && $_POST['doc_title'] !== '' ? + sanitize_text_field($_POST['doc_title']) : + pathinfo( $version, PATHINFO_FILENAME ); + + // Try to create new document + $id = Wiaas_Document::add_document( + $title, + $version, + $_POST['doc_visible'] === 'true'); + + // Document creation failed so return the error + if (!$id) { + echo "ERROR: Document could not be created!"; + die(); + } + + // If document type is sent then assign new document to it + if (isset($_POST['doc_type'])) { + Wiaas_Document::set_doc_type( $id, sanitize_key($_POST['doc_type']) ); + } + + require 'views/html-attached-document.php'; + + die(); +} + +/** + * Render attacment view for linked document + */ +function wiaas_ajax_link_document() { + check_ajax_referer('wiaas_link_document'); + + $id = absint($_GET['id']); + + require 'views/html-attached-document.php'; + + die(); +} + +/** + * + *Search wiaas documents by name + */ +function wiaas_ajax_json_search_documents() { + check_ajax_referer('wiaas_json_search_documents'); + + $q = ( ! empty( $_GET['query'] ) ? sanitize_text_field($_GET['query']) : '' ); + + $result = Wiaas_Document::search($q); + + wp_send_json( $result ); +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/admin/package/views/html-package-types.php b/backend/app/plugins/wiaas/includes/admin/package/views/html-package-types.php index e225ebd..aa20080 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 @@ -28,20 +28,6 @@ if ( ! defined( 'ABSPATH' ) ) { } } - function showDownloadableFiles() { - $('#general_product_data').find('.show_if_downloadable').each(function() { - $(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(); - }); - } - - showDownloadableFiles(); - handlePackageTypeToolsVisiblity(); }); diff --git a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php index 68ad9be..f852b5f 100644 --- a/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php +++ b/backend/app/plugins/wiaas/includes/admin/pricing/views/html-product-pricing.php @@ -6,12 +6,24 @@ if ( ! defined( 'ABSPATH' ) ) { @@ -21,7 +33,7 @@ woocommerce_wp_checkbox( 'id' => '_wiaas_recurring_price', 'value' => $product_pricing['is_recurring'] ? 'yes' : 'no', 'data_type' => 'price', - 'label' => __( $product->get_category_ids()[0], 'wiaas' ), + 'label' => __( 'Is recurring?', 'wiaas' ), ) ); diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php index 376c086..a8cd272 100644 --- a/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-cart-api.php @@ -32,14 +32,12 @@ class Wiaas_Cart_API { 'description' => __( 'Wiaas package ID.', 'wiaas' ), 'type' => 'integer', 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', ), 'price_id' => array( 'description' => __( 'Selected price ID for Wiaas package.', 'wiaas' ), 'type' => 'string', 'enum' => array_keys(Wiaas_Package_Pricing::get_available_pay_types()), 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', ), 'options_ids' => array( 'description' => __( 'Wiaas package options IDs.', 'wiaas' ), @@ -47,7 +45,6 @@ class Wiaas_Cart_API { 'items' => array( 'type' => 'integer', 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', ) ), 'addons_ids' => array( @@ -56,7 +53,6 @@ class Wiaas_Cart_API { 'items' => array( 'type' => 'integer', 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', ) ) ) @@ -69,7 +65,6 @@ class Wiaas_Cart_API { 'description' => __( 'Unique key identifier for cart package item.', 'wiaas' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_key', - 'validate_callback' => 'rest_validate_request_arg', ), ), array( @@ -86,12 +81,69 @@ class Wiaas_Cart_API { 'description' => __( 'New quantity cart package item.', 'wiaas' ), 'type' => 'integer', 'sanitize_callback' => 'absint', - 'validate_callback' => 'rest_validate_request_arg', ) ) ) ) ); + register_rest_route(self::$namespace, '/' . self::$rest_base . '/documents', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array(__CLASS__, 'get_cart_documents'), + 'permission_callback' => 'is_user_logged_in', + ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array(__CLASS__, 'upload_cart_document'), + 'permission_callback' => 'is_user_logged_in', + 'args' => array( + 'doc_type' => array( + 'description' => __( 'Category of uploaded document.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'required' => true + ), + 'package_key' => array( + 'description' => __( 'Unique key identifier for cart package item.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'required' => true + ), + 'type' => array( + 'default' => 'wiaas_doc' + ) + ) + ) + )); + + register_rest_route(self::$namespace, '/' . self::$rest_base . '/items/(?P[\w-]+)/documents/(?P[\w-]+)', array( + 'args' => array( + 'key' => array( + 'description' => __( 'Unique key identifier for cart package item.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + ), + 'type' => array( + 'description' => __( 'Cart document Type.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + ), + ), + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array(__CLASS__, 'download_cart_document'), + 'permission_callback' => 'is_user_logged_in', + 'args' => array( + 'document_key' => array( + 'description' => __( 'Unique key identifier for cart document.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'required' => true + ), + ) + ), + )); + register_rest_route( self::$namespace, '/' . self::$rest_base . '/checkout', array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array(__CLASS__, 'checkout'), @@ -158,6 +210,7 @@ class Wiaas_Cart_API { public static function get_cart_items() { return rest_ensure_response(array( 'items' => Wiaas_Cart::get_cart_packages(), + 'raw' => WC()->cart->get_cart_contents(), )); } @@ -214,6 +267,54 @@ class Wiaas_Cart_API { return wiaas_api_notice('QUANTITY_NOT_UPDATED', 'error'); } + /** + * Retrive cart documents info + * + * @return mixed|WP_REST_Response + */ + public static function get_cart_documents() { + return rest_ensure_response( Wiaas_Cart::get_cart_documents()); + } + + /** + * Upload document to cart + * @param WP_REST_Request $request + * + * @return mixed|WP_REST_Response + */ + public static function upload_cart_document($request) { + $result = Wiaas_Cart::upload_cart_document($request['doc_type'], $request['package_key']); + + if (is_wp_error($result)) { + $error_code = $result->get_error_code(); + + if ($error_code === 'wiaas_upload_missing_file') { + return wiaas_api_generate_error('NO_FILE'); + } + + if ($error_code === 'wiaas_upload_error') { + return wiaas_api_generate_error('UPLOAD_ERROR'); + } + + return wiaas_api_generate_error('NOT_LINKED_TO_CART'); + } + + return wiaas_api_notice('FILE_UPLOADED', 'success', array( + 'id_document' => $result, + )); + } + + /** + * Download cart document + * @param WP_REST_Request $request + */ + public static function download_cart_document($request) { + Wiaas_Document_Download::download_cart_document( + $request['key'], + $request['type'], + $request['document_key']); + } + /** * @param WP_REST_Request $request Request data. diff --git a/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php b/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php index d8e18ad..7480c52 100644 --- a/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php +++ b/backend/app/plugins/wiaas/includes/api/class-wiaas-document-api.php @@ -17,26 +17,73 @@ class Wiaas_Document_API { private static $namespace = 'wiaas'; public static function register_routes() { - register_rest_route( self::$namespace, 'download-package-file', array( + register_rest_route( self::$namespace, 'documents', array( 'methods' => 'GET', 'permission_callback' => 'is_user_logged_in', 'callback' => array(__CLASS__, 'download_package_file'), + 'args' => array( + 'document_id' => array( + 'description' => __( 'Document ID.', 'wiaas' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ) + ) + ) ); + + register_rest_route( self::$namespace, 'documents/order/(?P\d+)/(?P[\w-]+)', array( + 'args' => array( + 'id' => array( + 'description' => __( 'Order ID.', 'wiaas' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + 'type' => array( + 'description' => __( 'Order document type.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + ), + ), + array( + 'methods' => 'GET', + 'permission_callback' => 'is_user_logged_in', + 'callback' => array(__CLASS__, 'download_order_document'), + 'args' => array( + 'item_id' => array( + 'description' => __( 'Package Order Item ID.', 'wiaas' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + 'document_key' => array( + 'description' => __( 'Unique key identifier for order document.', 'wiaas' ), + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + 'required' => true + ), + ) + ) ) ); } /** * Download package document + * + * @param WP_REST_Request $request */ - public static function download_package_file() { - $document_id = $_GET['document_id']; - $package_id = $_GET['package_id']; + public static function download_package_file($request) { + $document_id = $request['document_id']; - $package = wc_get_product($package_id); + Wiaas_Document_Download::download_document($document_id); + } - $file = $package->get_file($document_id); - - if ($file) { - WC_Download_Handler::download_file_force($package->get_file_download_path($document_id), $file->get_name()); - } + /** + * Download order document + * @param WP_REST_Request $request + */ + public static function download_order_document($request) { + Wiaas_Document_Download::download_order_item_document( + $request['id'], + $request['item_id'], + $request['type'], + $request['document_key']); } } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/cart/class-wiaas-cart-documents.php b/backend/app/plugins/wiaas/includes/cart/class-wiaas-cart-documents.php new file mode 100644 index 0000000..068868e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/cart/class-wiaas-cart-documents.php @@ -0,0 +1,36 @@ + 'template_agreement', + 'order_questionaire' => 'order_agreement' + ); + + public static function get_cart_documents() { + $packages_data = Wiaas_Cart::get_cart_packages(); + + $templates = array(); + + foreach ($packages_data as $package_data) { + $package = wc_get_product($packages_data['package_id']); + + $documents = $package->get_downloads(); + } + + get_terms(array( + 'taxonomy' => 'wiaas_document_types', + 'include' => 'template_questionaire, order_questionaire' + )); + } + + private static function _get_packages_templates($packages) { + $documents_ids = array_map(function($package) { + return array_keys($package->get_downloads()); + }, $packages); + + wp_get_object_terms($documents_ids, 'wiaas_document_types', array( + + )); + } +} \ 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 5b688a4..395459b 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-admin.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-admin.php @@ -15,6 +15,8 @@ class Wiaas_Admin { // Admin order projects interface require_once dirname(__FILE__) . '/admin/class-wiaas-admin-order-projects.php'; + // Admin documents + require_once dirname(__FILE__) . '/admin/class-wiaas-admin-documents.php'; } } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php index 23f28ee..9ac3df7 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-cart.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-cart.php @@ -12,6 +12,11 @@ if ( ! defined( 'ABSPATH' ) ) { */ class Wiaas_Cart { + private static $cart_doc_types = array( + 'template_questionaire' => 'order_questionaire', + 'template_agreement' => 'order_agreement' + ); + public static function init() { add_action( 'woocommerce_checkout_create_order_line_item', array( __CLASS__, 'add_order_item_meta' ), 10, 3 ); @@ -24,6 +29,76 @@ class Wiaas_Cart { } + /** + * Retrieve cart documents (templates and uploded documents) + * @return array + */ + public static function get_cart_documents() { + $templates = self::_get_cart_templates(); + $uploaded_documents = self::_get_cart_uploaded_documents(); + + $has_pending_uploads = false; + + foreach ($templates as $type => $package_documents) { + $uploaded_type = self::$cart_doc_types[$type]; + + if (!isset($uploaded_documents[$uploaded_type])) { + $has_pending_uploads = true; + break; + } + + $uploaded_package_documents = $uploaded_documents[$uploaded_type]; + + foreach ($package_documents as $package_id => $package_document) { + if (!isset($uploaded_package_documents[$package_id])) { + $has_pending_uploads = true; + break; + } + } + } + + return array( + 'templates' => $templates, + 'uploaded' => $uploaded_documents, + 'pending' => $has_pending_uploads + ); + } + + /** Uploaded document for cart + * + * @param $doc_type + * @param $package_item_key + * + * @return string | WP_Error + */ + public static function upload_cart_document($doc_type, $package_item_key) { + try { + $version = Wiaas_Document_Upload::upload_document_version(); + + if (is_wp_error($version)) { + return $version; + } + + $cart_document = array( + 'version' => $version, + 'key' => wp_generate_uuid4(), + ); + + // persist uploaded cart document in cart + WC()->cart->cart_contents[ $package_item_key ]['_wiaas_documents'][$doc_type] = $cart_document; + + // persist changes to cart session + // Note: TODO Refactor this logic of persisting updates made to cart + $s = new WC_Cart_Session(WC()->cart); + $s->set_session(); + + return $cart_document['key']; + + } catch( Exception $e) { + return new WP_Error('wiass_cart_upload_error', 'Error while uploading cart file!'); + } + } + /** * Handles adding standard wiaas package to cart along with selected addons and options * @@ -61,7 +136,8 @@ class Wiaas_Cart { '_wiaas_addon_items' => array(), '_wiaas_option_items' => array(), '_wiaas_currency' => isset($country) ? $country['currency'] : get_woocommerce_currency(), - '_wiaas_payment' => $package_prices[$selected_price_index] ? $package_prices[$selected_price_index] : null + '_wiaas_payment' => $package_prices[$selected_price_index] ? $package_prices[$selected_price_index] : null, + '_wiaas_documents' => array() ); $cart_item_key = WC()->cart->add_to_cart($package_id, 1, 0, array(), $wiaas_cart_item_data); @@ -79,8 +155,6 @@ class Wiaas_Cart { return true; } catch( Exception $e) { - - error_log($e->getMessage()); return false; } } @@ -181,7 +255,7 @@ class Wiaas_Cart { * @param $cart_item * @param $order * - * @return array + * @return WC_Order_Item */ public static function add_order_item_meta( $order_item, $cart_item_key, $cart_item ) { if (wc_pb_is_bundle_container_cart_item($cart_item) && isset($cart_item['_wiaas_payment'])) { @@ -224,6 +298,40 @@ class Wiaas_Cart { if (isset($cart_item['_wiaas_addon_for'])) { $order_item->add_meta_data( '_wiaas_addon_for', $cart_item['_wiaas_addon_for'], true ); } + + // add documents associated with the item + $cart_documents = isset($cart_item['_wiaas_documents']) ? $cart_item['_wiaas_documents'] : array(); + $attachment_document_ids = wiaas_get_object_attached_documents($cart_item['product_id']); + $item_documents = array(); + + foreach ($cart_documents as $type => $cart_document) { + $item_documents[] = array( + 'key' => $cart_document['key'], + 'version' => $cart_document['version'], + 'type' => $type + ); + } + + foreach ($attachment_document_ids as $attachment_document_id) { + $doc_info = Wiaas_Document::get_doc_info($attachment_document_id); + + // add customer visible attachment documents to order + if ($doc_info['visible'] || !$doc_info['type']) { + $item_documents[] = array( + 'key' => wp_generate_uuid4(), + 'name' => $doc_info['name'], + 'version' => $doc_info['version'], + 'type' => $doc_info['type']['id'], + ); + } + } + + if (count($item_documents) > 0) { + $order_item->add_meta_data( '_wiaas_documents', $item_documents, true ); + } + + + return $order_item; } /** @@ -249,6 +357,7 @@ class Wiaas_Cart { '_wiaas_option_group_name', '_wiaas_standard_package', '_wiaas_currency', + '_wiaas_documents' ) ); } @@ -401,6 +510,103 @@ class Wiaas_Cart { //PRIVATE + /** + * Retrieve cart templates + * @return array + */ + private static function _get_cart_templates() { + $items = WC()->cart->get_cart_contents(); + + $documents_ids = array(); + + foreach ($items as $key => $item) { + if (!isset($item['_wiaas_standard_package'])) { + continue; + } + + $package_documents_ids = get_post_meta( + $item['product_id'], + '_wiaas_attached_documents', + true); + + foreach ($package_documents_ids as $package_document_id) { + $package_document_id = absint($package_document_id); + $documents_ids[$package_document_id] ?: array(); + $documents_ids[$package_document_id][] = $item['product_id']; + } + } + + $q = new WP_Query(); + $retrieved_items = $q->query(array( + 'post_status' => 'publish', + 'post_type' => 'wiaas_doc', + 'post__in' => array_keys($documents_ids), + 'tax_query' => array( + array( + 'taxonomy' => 'wiaas_doc_type', + 'field' => 'slug', + 'terms' => array_keys(self::$cart_doc_types), + ) + ) + )); + + $cart_documents = array(); + + foreach ($retrieved_items as $retrieved_item) { + + $doc_info = Wiaas_Document::get_doc_info($retrieved_item->ID); + $type = $doc_info['type']['id']; + + $cart_documents[$type] ?: array(); + + $package_ids = $documents_ids[$doc_info['id']] ?: array(); + foreach ($package_ids as $package_id) { + $cart_documents[$type][$package_id] = array( + 'id' => $doc_info['id'], + 'name' => $doc_info['name'], + 'type' => $type, + 'extension' => $doc_info['extension'] + ); + } + } + + return $cart_documents; + } + + /** + * Retrieve cart uploaded documents + * @return array + */ + private static function _get_cart_uploaded_documents() { + $items = WC()->cart->get_cart_contents(); + + $cart_documents = array(); + + foreach ($items as $key => $item) { + if (!isset($item['_wiaas_standard_package'])) { + continue; + } + + $package_id = $item['product_id']; + + $documents = isset($item['_wiaas_documents']) ? $item['_wiaas_documents'] : array(); + + foreach ($documents as $type => $document) { + $cart_documents[$type] ?: array(); + $cart_documents[$type][$package_id] = array( + 'key' => $document['key'], + 'name' => wiaas_get_doc_version_filename($document['version']), + 'type' => $type, + 'extension' => wiaas_get_doc_version_extension($document['version']) + ); + + } + + } + + return $cart_documents; + } + /** * Add selected package options and addons after parent standard package is added to cart diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php index 1b95a3b..82fe426 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-db-update.php @@ -8,12 +8,12 @@ class Wiaas_DB_Update { '20180728222206' => 'wiaas_db_update_enable_product_by_user_role', '20180801222206' => 'wiaas_db_update_setup_gravity', '20180802222206' => 'wiaas_db_update_add_delivery_process_forms', - '20180807222206' => 'wiaas_db_update_setup_customer_capabilities', '20180811134511' => 'wiaas_db_update_enable_orders_access_management', '20180813134511' => 'wiaas_db_update_enable_order_numbers', '20180826153509' => 'wiaas_create_broker_access_group', '20180911101010' => 'wiaas_db_setup_exclusive_taxonomies', - '20180912101010' => 'wiaas_db_setup_default_cl' + '20180912101010' => 'wiaas_db_setup_default_cl', + '20181003164100' => 'wiaas_db_setup_customer_capabilities' ); public static function execute() { diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-documents.php b/backend/app/plugins/wiaas/includes/class-wiaas-documents.php index fcc5992..2a14864 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-documents.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-documents.php @@ -5,98 +5,21 @@ if ( ! defined( 'ABSPATH' ) ) { } /** - * Implements Wiaas Document types + * Implements Wiaas Documents * * Class Wiaas_Documents */ class Wiaas_Documents { - /** - * Default available document types for wiaas - * @var array - */ - private static $available_doc_types = array( - 'template_questionaire' => array( - 'name' => 'Template Questionaire', - 'is_special_type' => false, - ), - 'order_questionaire' => array( - 'name' => 'Order Questionaire', - 'is_special_type' => true, - ), - 'configuration' => array( - 'name' => 'Configuration', - 'is_special_type' => true, - ), - 'install_guide' => array( - 'name' => 'Install guide', - 'is_special_type' => false, - ), - 'customer_acceptance' => array( - 'name' => 'Customer acceptance', - 'is_special_type' => true, - ), - 'template_agreement' => array( - 'name' => 'Template Agreement', - 'is_special_type' => false, - ), - 'order_agreement' => array( - 'name' => 'Order Agreement', - 'is_special_type' => true, - ), - 'installation_protocol' => array( - 'name' => 'Installation protocol', - 'is_special_type' => true, - ), - 'statements' => array( - 'name' => 'Statements', - 'is_special_type' => false, - ), - 'customer_acceptance_template' => array( - 'name' => 'Customer acceptance template', - 'is_special_type' => false, - ), - ); - public static function init() { - add_action( 'init', array( __CLASS__, 'register_wiaas_document_types' )); - } - /** - * Registers taxonomy and default values for wiaas document types - */ - public static function register_wiaas_document_types() { - $labels = array( - 'name' => _x( 'Document type', 'taxonomy general name', 'wiaas' ), - 'singular_name' => _x( 'Document type', 'taxonomy singular name', 'wiaas' ), - 'menu_name' => _x( 'Document types', 'Admin menu name', 'wiaas' ), - 'search_items' => __( 'Search Document types', 'wiaas' ), - 'all_items' => __( 'All Document types', 'wiaas' ), - 'parent_item' => __( 'Parent Document type', 'wiaas' ), - 'parent_item_colon' => __( 'Parent Document type:', 'wiaas' ), - 'edit_item' => __( 'Edit Document type', 'wiaas' ), - 'update_item' => __( 'Update Document type', 'wiaas' ), - 'add_new_item' => __( 'Add New Document type', 'wiaas' ), - 'new_item_name' => __( 'New Document type Name', 'wiaas' ), - ); + require_once dirname( __FILE__ ) . '/document/class-wiaas-document.php'; - $args = array( - 'hierarchical' => false, - 'label' => __( 'Document types', 'wiaas' ), - 'labels' => $labels, - 'show_ui' => true, - 'show_admin_column' => true, - 'query_var' => true, - 'rewrite' => array( 'slug' => 'wiaas_document_types' ), - ); + require_once dirname( __FILE__ ) . '/document/class-wiaas-document-upload.php'; - register_taxonomy( 'wiaas_document_types', array( 'attachment' ), $args ); + require_once dirname( __FILE__ ) . '/document/class-wiaas-document-download.php'; - foreach (self::$available_doc_types as $key => $available_doc_type) { - wp_insert_term($available_doc_type['name'], 'wiaas_document_types', array( - 'slug' => $key - )); - } + require_once dirname( __FILE__ ) . '/document/wiaas-document-functions.php'; } } diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-order.php b/backend/app/plugins/wiaas/includes/class-wiaas-order.php index 006fa24..eca0dd8 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-order.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-order.php @@ -243,6 +243,9 @@ class Wiaas_Order { // add only product lines that represent product bundles if (isset($item['wiaas_standard_package'])) { + // get documents + $product_line['documents'] = wiaas_get_package_order_item_documents($order, $product_line['id']); + # get payment type info $product_line['payment_type'] = $item['wiaas_payment_type']; $product_line['service_price'] = floatval($item['wiaas_services_extra']); diff --git a/backend/app/plugins/wiaas/includes/class-wiaas-package.php b/backend/app/plugins/wiaas/includes/class-wiaas-package.php index 27900dd..4ae92ed 100644 --- a/backend/app/plugins/wiaas/includes/class-wiaas-package.php +++ b/backend/app/plugins/wiaas/includes/class-wiaas-package.php @@ -54,15 +54,11 @@ class Wiaas_Package { */ private static function _append_documents_info($data, $package, $request) { - unset($data['downloads']); - - $data['documents'] = array_map(function($download) { - return array( - 'id' => $download->get_id(), - 'name' => $download->get_name(), - 'extension' => $download->get_file_extension(), - ); - }, array_values($package->get_downloads())); + $data['documents'] = array_map(function($doc) { + unset($doc['url']); + unset($doc['version']); + return $doc; + }, wiaas_get_all_package_documents($package, true)); return $data; } diff --git a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-functions.php b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-functions.php index aeeaf09..ed4311c 100644 --- a/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-functions.php +++ b/backend/app/plugins/wiaas/includes/db-updates/wiaas-db-update-functions.php @@ -78,16 +78,6 @@ function wiaas_db_update_add_delivery_process_forms() { do_action('gform_forms_post_import', $created_forms); } -function wiaas_db_update_setup_customer_capabilities() { - $customer_role = get_role('customer'); - - $customer_role->add_cap('read_private_shop_orders'); - $customer_role->add_cap('read_private_products'); - $customer_role->add_cap('read_shop_order'); - $customer_role->add_cap('publish_shop_orders'); - -} - function wiaas_db_update_enable_orders_access_management() { $post_types_option = Groups_Options::get_option( Groups_Post_Access::POST_TYPES, array() ); @@ -125,4 +115,18 @@ function wiaas_db_setup_exclusive_taxonomies() { function wiaas_db_setup_default_cl() { wp_insert_term(Wiaas_Pricing::COMMERCIAL_LEAD_NAME, Wiaas_User_Organization::TAXONOMY_NAME); +} + +function wiaas_db_setup_customer_capabilities() { + $customer_role = get_role('customer'); + + $customer_role->add_cap('read_private_shop_orders'); + $customer_role->add_cap('read_private_products'); + $customer_role->add_cap('read_shop_order'); + $customer_role->add_cap('publish_shop_orders'); + + // user + $customer_role->add_cap('list_users'); + $customer_role->add_cap('edit_users'); + } \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/document/class-wiaas-document-download.php b/backend/app/plugins/wiaas/includes/document/class-wiaas-document-download.php new file mode 100644 index 0000000..71a3c97 --- /dev/null +++ b/backend/app/plugins/wiaas/includes/document/class-wiaas-document-download.php @@ -0,0 +1,142 @@ +get_item($item_id); + if (!$item) { + wp_die( __( 'Invalid Document Request.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + $item_documents = $item['wiaas_documents']; + + $order_document = null; + foreach ($item_documents as $item_document) { + if ($item_document['key'] === $document_key && $item_document['type'] === $type) { + $order_document = $item_document; + break; + } + } + + if (!isset($order_document)) { + wp_die( __( 'Invalid Document Request.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + $file_path = wiaas_get_document_version_path($order_document['version']); + + if (!file_exists($file_path)) { + wp_die( __( 'Document not found.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + WC_Download_Handler::download_file_force( + $file_path, + pathinfo( $file_path, PATHINFO_FILENAME ) . '.' . pathinfo( $file_path, PATHINFO_EXTENSION ) + ); + + } + + /** + * Download cart document + * + * @param $item_key + * @param $type + * @param $document_key + */ + public static function download_cart_document($item_key, $type, $document_key) { + $item = WC()->cart->get_cart_item($item_key); + if (!isset($item)) { + wp_die( __( 'Invalid Document Request.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + $item_documents = $item['_wiaas_documents']; + if (!isset($item_documents) || + empty($item_documents) || + !array_key_exists($type, $item_documents)) { + wp_die( __( 'Invalid Document Request.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + $cart_document = $item_documents[$type]; + if ($cart_document['key'] !== $document_key) { + wp_die( __( 'Invalid Document Request.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + $file_path = wiaas_get_document_version_path($cart_document['version']); + + if (!file_exists($file_path)) { + wp_die( __( 'Document not found.', 'wiaas' ), __( 'Download Error', 'wiaas' ) ); + } + + WC_Download_Handler::download_file_force( + $file_path, + pathinfo( $file_path, PATHINFO_FILENAME ) . '.' . pathinfo( $file_path, PATHINFO_EXTENSION ) + ); + + } + +} + +Wiaas_Document_Download::init(); diff --git a/backend/app/plugins/wiaas/includes/document/class-wiaas-document-upload.php b/backend/app/plugins/wiaas/includes/document/class-wiaas-document-upload.php new file mode 100644 index 0000000..9e7cdee --- /dev/null +++ b/backend/app/plugins/wiaas/includes/document/class-wiaas-document-upload.php @@ -0,0 +1,88 @@ + false ), + current_time('mysql')); + + if ( isset($file['error']) ) + return new WP_Error( 'wiaas_upload_error', $file['error'] ); + + return wiaas_get_doc_version_from_path($file['file']); + } + + /** + * Updates wordpress upload dir so that wiaas documents are uploaded to wiaas specific upload dir + * @param $pathdata + * + * @return mixed + */ + public static function upload_dir( $pathdata ) { + + if (defined('WIAAS_DOCUMENT_UPLOAD') ) { + if ( empty( $pathdata['subdir'] ) ) { + $pathdata['path'] = $pathdata['path'] . wiaas_documents_base_dir(); + $pathdata['url'] = $pathdata['url'] . wiaas_documents_base_dir(); + $pathdata['subdir'] = wiaas_documents_base_dir(); + } else { + $new_subdir = wiaas_documents_base_dir() . $pathdata['subdir']; + + $pathdata['path'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['path'] ); + $pathdata['url'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['url'] ); + $pathdata['subdir'] = str_replace( $pathdata['subdir'], $new_subdir, $pathdata['subdir'] ); + } + } + + return $pathdata; + } +} + +Wiaas_Document_Upload::init(); diff --git a/backend/app/plugins/wiaas/includes/document/class-wiaas-document.php b/backend/app/plugins/wiaas/includes/document/class-wiaas-document.php new file mode 100644 index 0000000..8eea08e --- /dev/null +++ b/backend/app/plugins/wiaas/includes/document/class-wiaas-document.php @@ -0,0 +1,406 @@ + array( + 'name' => 'Template Questionaire', + 'is_special_type' => false, + ), + 'order_questionaire' => array( + 'name' => 'Order Questionaire', + 'is_special_type' => true, + ), + 'configuration' => array( + 'name' => 'Configuration', + 'is_special_type' => true, + ), + 'install_guide' => array( + 'name' => 'Install guide', + 'is_special_type' => false, + ), + 'customer_acceptance' => array( + 'name' => 'Customer acceptance', + 'is_special_type' => true, + ), + 'template_agreement' => array( + 'name' => 'Template Agreement', + 'is_special_type' => false, + ), + 'order_agreement' => array( + 'name' => 'Order Agreement', + 'is_special_type' => true, + ), + 'installation_protocol' => array( + 'name' => 'Installation protocol', + 'is_special_type' => true, + ), + 'statements' => array( + 'name' => 'Statements', + 'is_special_type' => false, + ), + 'customer_acceptance_template' => array( + 'name' => 'Customer acceptance template', + 'is_special_type' => false, + ), + ); + + private static $special_doc_types= array( + 'order_questionaire', 'configuration', 'customer_acceptance', 'order_agreement', 'installation_protocol' + ); + + public static function init() { + + add_action('registered_taxonomy', array( __CLASS__, 'register_wiaas_doc_categories' )); + + add_action('init', array(__CLASS__, 'register_wiaas_document')); + } + + + + /** + * Retrieve available categories for wiaas documents + * + * @return array Array of available document categories + */ + public static function get_available_doc_types() { + + $terms = get_terms(array( + 'taxonomy' => 'wiaas_doc_type', + 'hide_empty' => false, + )); + + return array_map(function($term) { + $is_special = array_key_exists($term->slug, self::$available_doc_types) ? + self::$available_doc_types[$term->slug]['is_special_type'] : + false; + + return array( + 'id' => $term->slug, + 'name' => $term->name, + 'is_special_type' => $is_special, + + ); + + }, $terms); + } + + /** + * Create new document + * @param $name + * @param $path + * @param bool $visible + * + * @return bool|int|WP_Error + */ + public static function add_document($name, $path, $visible = false) { + // create + $id = wp_insert_post( array( + 'post_title' => $name, + 'post_author' => wp_get_current_user()->ID, + 'post_type' => 'wiaas_doc', + 'post_status' => 'publish', + ) ); + + if ( is_wp_error( $id ) ) { + return false; + } + + error_log(gettype($visible)); + + update_post_meta($id, '_wiaas_doc_versions', array( $path )); + + self::set_is_doc_visible($id, $visible); + + return $id; + } + + /** + * Add new version for document + * @param $doc_id + * @param $url + */ + public static function add_document_version($doc_id, $url) { + $versions = get_post_meta($doc_id, '_wiaas_doc_versions', true); + + $versions[] = $url; + + update_post_meta($doc_id, '_wiaas_doc_versions', $versions); + } + + /** + * Assign type to document + * @param $id + * @param $type + */ + public static function set_doc_type($id, $type) { + wp_set_object_terms($id, $type, 'wiaas_doc_type'); + } + + /** + * Set if document visible to customer + * @param $id + * @param $is_visible + */ + public static function set_is_doc_visible($id, $is_visible) { + + update_post_meta($id, '_wiaas_doc_visible', $is_visible ? 'yes' : 'no'); + } + + /** + * Retrieve document type + * @param $id + * + * @return array|null + */ + public static function get_doc_type($id) { + $terms = wp_get_object_terms($id, 'wiaas_doc_type'); + + if (is_wp_error($terms) || count($terms) === 0) { + return null; + } + + $term = $terms[0]; + return array( + 'id' => $term->slug, + 'name' => $term->name, + 'is_special_type' => in_array($term->slug, self::$special_doc_types), + ); + } + + /** + * Retrieve if document visible to customer + * @param $id + * + * @return bool + */ + public static function is_doc_visible($id) { + return get_post_meta($id, '_wiaas_doc_visible', true) === 'yes'; + } + + /** + * Retrieve all versions for document + * @param $doc_id + * + * @return mixed + */ + public static function get_document_versions($doc_id) { + return get_post_meta($doc_id, '_wiaas_doc_versions', true); + } + + /** + * Get latest or specific document version + * @param $id + * @param null $version_id + * + * @return null + */ + public static function get_doc_version($id, $version_id = null) { + $versions = self::get_document_versions($id); + + if (count($versions) === 0) { + return null; + } + + return isset($versions[$version_id]) ? + $versions[$version_id] : $versions[count($versions) - 1]; + } + + /** + * Get document download link for latest or specified version + * @param $id + * @param null $version + * + * @return string + */ + public static function get_doc_download_link($id, $version = null) { + $permalink = get_permalink($id); + $sap = strpos($permalink, '?')?'&':'?'; + + $ver = isset($version) ? "&v={$version}" : ''; + return $permalink.$sap."wiaasdoc={$id}{$ver}"; + } + + /** + * Retrieve document informations + * @param $id + * + * @return array|null + */ + public static function get_doc_info($id) { + $post = get_post($id, ARRAY_A); + + if (!$post) { + return null; + } + + $version = self::get_doc_version($id); + + return array( + 'id' => $id, + 'name' => $post['post_title'], + 'url' => self::get_doc_download_link($id), + 'type' => self::get_doc_type($id), + 'version' => $version, + 'visible' => self::is_doc_visible($id), + 'extension' => wiaas_get_doc_version_extension($version), + ); + + } + + + /** + * Search document by name + * @param $name + * @param int $limit + * @param bool $include_special + * + * @return array + */ + public static function search($name, $limit = 10, $include_special = false) { + $query = new WP_Query(); + + $args = array( + 'post_status' => 'publish', + 'post_type' => 'wiaas_doc', + 'posts_per_page' => $limit, + 's' => $name + ); + + if (!$include_special) { + $args['tax_query'] = array( + array( + 'taxonomy' => 'wiaas_doc_type', + 'field' => 'slug', + 'operator' => 'NOT IN', + 'terms' => self::$special_doc_types, + ) + ); + } + + $items = $query->query($args); + + return array_map(function($item) { + $id = $item->ID; + return array( + 'id' => $id, + 'name' => $item->post_title, + ); + }, $items); + } + + /** + * Registers taxonomy and default values for wiaas document types + */ + public static function register_wiaas_doc_categories($taxonomy) { + + if ($taxonomy !== 'wpdmcategory') { + return; + } + + foreach (self::$available_doc_types as $key => $available_doc_type) { + wp_insert_term($available_doc_type['name'], 'wpdmcategory', array( + 'slug' => $key + )); + } + } + + public static function register_wiaas_document() { + // Register document object + self::_register_document(); + // Register document types taxonomy + self::_register_doc_types(); + } + + // PRIVATE + + /** + * Register wiaas_doc post type + */ + private static function _register_document() { + $labels = array( + 'name' => __('Documents','wiaas'), + 'singular_name' => __('Document','wiaas'), + 'add_new' => __('Add New','wiaas'), + 'add_new_item' => __('Add New Document','wiaas'), + 'edit_item' => __('Edit Document','wiaas'), + 'new_item' => __('New Document','wiaas'), + 'all_items' => __('All Documents','wiaas'), + 'view_item' => __('View Document','wiaas'), + 'search_items' => __('Search Documents','wiaas'), + 'not_found' => __('No Document Found','wiaas'), + 'not_found_in_trash' => __('No Documents found in Trash','wiaas'), + 'parent_item_colon' => '', + 'menu_name' => __('Documents','wiaas') + + ); + + $args = array( + 'labels' => $labels, + 'public' => true, + 'publicly_queryable' => false, + 'show_ui' => true, + 'show_in_menu' => true, + 'show_in_nav_menus' => true, + 'query_var' => true, + 'rewrite' => array('slug' => 'wiaas_doc', 'with_front' => false), + 'capability_type' => 'post', + 'has_archive' => false, + 'hierarchical' => false, + 'taxonomies' => array(), + 'menu_icon' => 'dashicons-media-document', + 'exclude_from_search' => false, + 'supports' => array('title') + + ); + + register_post_type('wiaas_doc', $args); + } + + /** + * Register wiaas_doc_type taxonomy for wiaas_doc post type + */ + private static function _register_doc_types() { + $labels = array( + 'name' => _x( 'Document type', 'taxonomy general name', 'wiaas' ), + 'singular_name' => _x( 'Document type', 'taxonomy singular name', 'wiaas' ), + 'menu_name' => _x( 'Document types', 'Admin menu name', 'wiaas' ), + 'search_items' => __( 'Search Document types', 'wiaas' ), + 'all_items' => __( 'All Document types', 'wiaas' ), + 'parent_item' => __( 'Parent Document type', 'wiaas' ), + 'parent_item_colon' => __( 'Parent Document type:', 'wiaas' ), + 'edit_item' => __( 'Edit Document type', 'wiaas' ), + 'update_item' => __( 'Update Document type', 'wiaas' ), + 'add_new_item' => __( 'Add New Document type', 'wiaas' ), + 'new_item_name' => __( 'New Document type Name', 'wiaas' ), + ); + + $args = array( + 'hierarchical' => false, + 'label' => __( 'Document type', 'wiaas' ), + 'labels' => $labels, + 'show_ui' => true, + 'show_admin_column' => true, + 'query_var' => true, + 'rewrite' => array( 'slug' => 'wiaas_doc_type' ), + ); + + register_taxonomy( 'wiaas_doc_type', array( 'wiaas_doc' ), $args ); + + foreach (self::$available_doc_types as $key => $available_doc_type) { + wp_insert_term($available_doc_type['name'], 'wiaas_doc_type', array( + 'slug' => $key + )); + } + } + +} + +Wiaas_Document::init(); diff --git a/backend/app/plugins/wiaas/includes/document/wiaas-document-functions.php b/backend/app/plugins/wiaas/includes/document/wiaas-document-functions.php new file mode 100644 index 0000000..eae9beb --- /dev/null +++ b/backend/app/plugins/wiaas/includes/document/wiaas-document-functions.php @@ -0,0 +1,190 @@ +get_id()) + ); + + // retrieve all bundled products from all relevant packages + $all_product_ids = array_values( + WC_PB_DB::query_bundled_items(array( + 'return' => 'id=>product_id', + 'bundle_id' => $all_package_ids + )) + ); + + $all_object_ids = array_unique(array_merge($all_package_ids, $all_product_ids)); + + // retrieve document ids from all packages and products + $document_ids = array(); + foreach ($all_object_ids as $object_id) { + $document_ids = array_merge( + $document_ids, + wiaas_get_object_attached_documents($object_id)); + } + $document_ids = array_unique($document_ids); + + // filter only visible if needed and retrieve documents info + $documents = array(); + foreach ($document_ids as $document_id) { + if ($only_visible && Wiaas_Document::is_doc_visible($document_id) || !$only_visible) { + $documents[] = Wiaas_Document::get_doc_info($document_id); + } + } + + return $documents; +} + +/** + * Retrieve all documents for single order package item + * + * @param WC_Order $order + * @param int $package_item_id + * + * @return array + */ +function wiaas_get_package_order_item_documents($order, $package_item_id) { + + $order_items = $order->get_items( 'line_item' ); + $package_order_item = $order->get_item($package_item_id); + + // retrieve package order item addons and options + $all_package_order_items = array_merge( + wiaas_get_order_item_addons($order_items, $package_order_item), + wiaas_get_order_item_options($order_items, $package_order_item), + array( $package_order_item ) + ); + $all_order_items = $all_package_order_items; + + // retrieve bundled product items for each package + foreach ($all_package_order_items as $item) { + $all_order_items = array_merge( + $all_order_items, + wc_pb_get_bundled_order_items($item, $order) + ); + } + + + $order_documents = array(); + foreach ($all_order_items as $order_item) { + $order_documents = array_merge( + $order_documents, + isset($order_item['wiaas_documents']) ? $order_item['wiaas_documents'] : array() + ); + } + + return array_map(function($doc) { + // append document extension and name information + $doc['extension'] = wiaas_get_doc_version_extension($doc['version']); + $doc['name'] = isset($doc['name']) ? $doc['name'] : wiaas_get_doc_version_filename($doc['version']); + + return $doc; + }, $order_documents); +} \ No newline at end of file diff --git a/backend/app/plugins/wiaas/includes/order/class-wiaas-order-project.php b/backend/app/plugins/wiaas/includes/order/class-wiaas-order-project.php index 25012af..285155d 100644 --- a/backend/app/plugins/wiaas/includes/order/class-wiaas-order-project.php +++ b/backend/app/plugins/wiaas/includes/order/class-wiaas-order-project.php @@ -62,6 +62,8 @@ class Wiaas_Order_Project { return array(); } + $available_terms = array(); + foreach ($all_terms as $term) { if (self::is_order_project_available($term->term_id)) { $available_terms[] = array( diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php index 43b9b22..127fa47 100644 --- a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php +++ b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-addon.php @@ -49,6 +49,16 @@ class Wiaas_Package_Addon { return $addons; } + /** + * Retrieve ids of package addons + * @param int $package + * + * @return array + */ + public static function get_package_addons_ids($package) { + return $package->get_meta( '__wiaas_package_addons' ); + } + /** * Sets addons for provided wiaas standard package type * @param $package diff --git a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php index ba34f23..c032a6e 100644 --- a/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php +++ b/backend/app/plugins/wiaas/includes/package/class-wiaas-package-option-groups.php @@ -81,6 +81,24 @@ class Wiaas_Package_Option_Groups { return $option_groups; } + /** + * Retrieve ids of all package options + * @param int $package + * + * @return array + */ + public static function get_package_option_ids($package) { + $groups_data = $package->get_meta( '_wiaas_package_option_groups' ); + + $options_ids = array(); + + foreach ($groups_data as $group_data) { + $options_ids = array_merge($options_ids, $group_data['options']); + } + + return array_unique($options_ids); + } + /** * Set groups of optional packages for provided package * @param $package diff --git a/frontend/src/actions/cart/cartActions.js b/frontend/src/actions/cart/cartActions.js index 928235f..4384c4d 100644 --- a/frontend/src/actions/cart/cartActions.js +++ b/frontend/src/actions/cart/cartActions.js @@ -225,15 +225,15 @@ export const previousStep = (params) => ({type: GO_TO_PREVIOUS_STEP, params}); export const uploadDocumnet = () => ({type: UPLOAD_DOCUMENT}); -export const uploadOrderDocument = (idPackage, idDocumentType, file, packages) => { +export const uploadOrderDocument = (packageCartKey, idDocumentType, file, packages) => { return dispatch => { dispatch(uploadDocumnet()); return client.uploadFile(file, { - url: `${API_SERVER}/cart/api/uploadOrderDocument`, + url: `${API_SERVER}/wp-json/wiaas/cart/documents`, data: { - idDocumentType, - idPackage + 'doc_type': idDocumentType, + 'package_key': packageCartKey } }).then(response => { if (typeof response.data !== 'undefined' && 'messages' in response.data) { @@ -266,30 +266,21 @@ export const fetchCartDocuments = (packages, isForSteps = false) => { return dispatch => { dispatch(requestCartDocuments()); - dispatch(receiveCartDocuments({ - areFilesUploaded: true, - templates: [], - uploaded: [] - })); - if(isForSteps) { - dispatch(loadSteps(true)); - } - - // return client.fetch({ - // url: `${API_SERVER}/wp-json/wiaas/cart/documents`, - // method: 'get', - // data: {packages} - // }).then(response => { - // if (response.data) { - // dispatch(receiveCartDocuments(response.data)); - // if(isForSteps) { - // const whitoutUploadDoc = response.data.templates.length === 0; - // dispatch(loadSteps(whitoutUploadDoc)); - // } - // } - // }).catch(error => { - // client.onError(error, dispatch); - // }); + return client.fetch({ + url: `${API_SERVER}/wp-json/wiaas/cart/documents`, + method: 'get', + data: {packages} + }).then(response => { + if (response.data) { + dispatch(receiveCartDocuments(response.data)); + if(isForSteps) { + const whitoutUploadDoc = response.data.templates.length === 0; + dispatch(loadSteps(whitoutUploadDoc)); + } + } + }).catch(error => { + client.onError(error, dispatch); + }); } } diff --git a/frontend/src/constants/cartConstants.js b/frontend/src/constants/cartConstants.js index 1bee54c..2a3acb8 100644 --- a/frontend/src/constants/cartConstants.js +++ b/frontend/src/constants/cartConstants.js @@ -147,9 +147,9 @@ export const cartTexts = { DOC_NOT_REQUIRED: 'Document not required', FILE_UPLOADED_TEXT: 'File uploaded! Select or drop to replace ', FILE: 'file', - NO_FILE_UPLOAD_TEXT_1: 'Click here to select', - NO_FILE_UPLOAD_TEXT_2: 'or drag and drop file here', - TEMPLATES: 'Templates', + NO_FILE_UPLOAD_TEXT_1: 'Drag and drop', + NO_FILE_UPLOAD_TEXT_2: 'click to upload', + TEMPLATE: 'Template', UPLOADED: 'Uploaded dcuments', PACKAGE_UNAVAILABLE: 'This package is no longer available. Remove it from the cart to place the order successfully', BID_AVAILABLE: 'Bids available!', @@ -167,7 +167,7 @@ export const cartTexts = { buttons: { YES: 'Yes', CANCEL: 'Cancel', - PREVIOUS: 'Previous', + BACK: 'Back', NEXT: 'Next', ADD_ADDRESS: 'Add address', USE: 'Use', diff --git a/frontend/src/containers/cart/CartStepsContainer.jsx b/frontend/src/containers/cart/CartStepsContainer.jsx index 41eb7b3..ebd536e 100644 --- a/frontend/src/containers/cart/CartStepsContainer.jsx +++ b/frontend/src/containers/cart/CartStepsContainer.jsx @@ -38,7 +38,7 @@ class CartStepsContainer extends Component { {(cartSteps && cartSteps[currentStep] && cartSteps[currentStep].previous && !isLoading) && {this.handleStepChange('previous')}} className="prev-btn"> - {cartTexts.buttons.PREVIOUS} + {cartTexts.buttons.BACK} } diff --git a/frontend/src/containers/cart/CartUploadDocumentsContainer.jsx b/frontend/src/containers/cart/CartUploadDocumentsContainer.jsx index d10f73b..a7d9913 100644 --- a/frontend/src/containers/cart/CartUploadDocumentsContainer.jsx +++ b/frontend/src/containers/cart/CartUploadDocumentsContainer.jsx @@ -9,10 +9,10 @@ import {updateMessages} from '../../actions/notification/notificationActions'; import {nextStep, setNextActionFct} from '../../actions/cart/cartActions'; const DOCUMENT_TYPES = { - TEMPLATE_QUESTINNAIRE: 1, - QUESTIONNAIRE: 2, - TEMPLATE_AGREEMENT: 6, - AGREEMENT: 7 + TEMPLATE_QUESTINNAIRE: 'template_questionaire', + QUESTIONNAIRE: 'order_questionaire', + TEMPLATE_AGREEMENT: 'template_agreement', + AGREEMENT: 'order_agreement' }; class CartCustomerQuestionnaireContainer extends Component { @@ -34,7 +34,7 @@ class CartCustomerQuestionnaireContainer extends Component { } handleStepChange() { - if(this.props.cartDocuments && this.props.cartDocuments.areFilesUploaded) { + if(this.props.cartDocuments && !this.props.cartDocuments.pending) { this.props.dispatch(nextStep()); } else { this.props.dispatch(updateMessages([{code:'warning', message: 'DOCS_MISSING'}], cartMessages)); diff --git a/frontend/src/containers/cart/components/CartUploadDocument.jsx b/frontend/src/containers/cart/components/CartUploadDocument.jsx index 32186b9..af84eba 100644 --- a/frontend/src/containers/cart/components/CartUploadDocument.jsx +++ b/frontend/src/containers/cart/components/CartUploadDocument.jsx @@ -6,11 +6,13 @@ import Dropzone from 'react-dropzone'; import {API_SERVER} from '../../../config'; import FileDownloader from '../../../helpers/FileDownloader'; import {cartTexts} from '../../../constants/cartConstants'; +import {getDocumentIcon} from '../../../helpers/DocumentHelper'; +import classnames from 'classnames'; const fileHandler = new FileDownloader(); const documentTypes = { - 2 : 'Customer Questionnaire', - 7 : 'Customer Agreement' + 'order_questionaire' : 'Customer Questionnaire', + 'order_agreement' : 'Customer Agreement' }; class CartUploadDocument extends Component { @@ -20,11 +22,11 @@ class CartUploadDocument extends Component { this.uploadFile = this.uploadFile.bind(this); } - uploadFile(idPackage, idDocumentType,acceptedFiles, rejectedFiles, packages){ + uploadFile(packageCartKey, idDocumentType,acceptedFiles, rejectedFiles, packages){ const self = this; acceptedFiles.forEach(file => { - self.props.dispatch(uploadOrderDocument(idPackage, idDocumentType, file, packages)); + self.props.dispatch(uploadOrderDocument(packageCartKey, idDocumentType, file, packages)); }); if(rejectedFiles && rejectedFiles.length) { @@ -33,9 +35,15 @@ class CartUploadDocument extends Component { } downloadDocument(document){ - const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}` - const fileName = document.documentName + '.' + document.extension; - fileHandler.download(fileUrl, fileName); + fileHandler.download( + `${API_SERVER}/wp-json/wiaas/cart/items/${this.props.cartItem.key}/documents/${this.props.idDocumentType}?document_key=${document.key}`, + document.name); + } + + downloadTemplate(document) { + fileHandler.download( + `${API_SERVER}/wp-json/wiaas/documents?document_id=${document.id}`, + document.name); } render() { @@ -45,30 +53,51 @@ class CartUploadDocument extends Component { { templateDocument &&
- +

{documentTypes[idDocumentType]} {cartTexts.labels.TEMPLATE}:

+

{this.downloadTemplate(templateDocument)}}> + {templateDocument.name} +

+
+ + {this.uploadFile(cartItem.idPackage, idDocumentType, acceptedFiles, rejectedFiles, packages)}}> + onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(cartItem.key, idDocumentType, acceptedFiles, rejectedFiles, packages)}}> { uploadedDocument - ?
{cartTexts.labels.FILE_UPLOADED_TEXT} {documentTypes[idDocumentType]} {cartTexts.labels.FILE}
- :
{cartTexts.labels.NO_FILE_UPLOAD_TEXT_1} {documentTypes[idDocumentType]} {cartTexts.labels.NO_FILE_UPLOAD_TEXT_2}
+ ? ( +
+

+ +

+
{uploadedDocument.name}
+ + Drag and drop or click to replace file + +
+ ) + : ( +
+

+ +

+ + Drag and drop or click to upload file + +
+ ) }
{ uploadedDocument &&
-
{cartTexts.labels.UPLOADED}:
-
{this.downloadDocument(uploadedDocument)}}> - - {' ' + uploadedDocument.documentName + ' (' + uploadedDocument.extension + ')'} -
+ {this.downloadDocument(uploadedDocument)}}> + + {uploadedDocument.name} + +
} -
{cartTexts.labels.TEMPLATES}:
-
{this.downloadDocument(templateDocument)}}> - - {' ' + templateDocument.documentName + ' (' + templateDocument.extension + ')'} -
} diff --git a/frontend/src/containers/cart/style/CartUploadDocumentsContainer.scss b/frontend/src/containers/cart/style/CartUploadDocumentsContainer.scss index 6ecea36..3119fbc 100644 --- a/frontend/src/containers/cart/style/CartUploadDocumentsContainer.scss +++ b/frontend/src/containers/cart/style/CartUploadDocumentsContainer.scss @@ -6,19 +6,37 @@ .upload-file-drop-zone { width: 100%; - border: 3px dashed $borderColor; - margin-top: 1rem; - height: 5rem; + border: 1px dashed $borderColor; + margin: 1rem 0; + padding: 1rem; cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + &:hover { + background-color: $lightHoverColor; + } + color: $font-light-color; + &.pending-upload { + border: 1px dashed $accentColor; + + .drop-zone-icon, .drop-zone-text { + color: $accentColor; + } + } + } .drop-zone-text { text-align: center; - padding: 1.3rem 0.5rem; + color: $font-light-color; + padding: 0; + font-size: $font-size-small; } - .uploaded { - color: #155724; + .drop-zone-icon { + color: #b3b3b3; } .next-btn { @@ -28,18 +46,33 @@ color: $darkGreyColor; } + .cart-template { + margin: 1rem 0; + .cart-subtitle { + margin-right: 1rem; + } + } + .cart-subtitle { font-weight: $font-weight; + color: $font-light-color; + font-size: $font-size-small; padding-top: 0.3rem; } } .upload-layer{ background: $whiteColor; - padding-bottom: 1rem; + padding: 1rem; + color: $title-color; + + .upload-layer { + color: $title-color; + } .document-link{ cursor: pointer; + color: #2b6279; } } diff --git a/frontend/src/containers/coMarket/components/PackageInfo.jsx b/frontend/src/containers/coMarket/components/PackageInfo.jsx index bdc26c5..b678e24 100644 --- a/frontend/src/containers/coMarket/components/PackageInfo.jsx +++ b/frontend/src/containers/coMarket/components/PackageInfo.jsx @@ -8,9 +8,9 @@ const fileHandler = new FileDownloader(); class PackageInfo extends Component { downloadDocument(document){ - const fileUrl = `${API_SERVER}/wp-json/wiaas/download-package-file?document_id=${document.idDocument}&package_id=${document.idPackage}` - const fileName = document.documentName + '.' + document.extension; - fileHandler.download(fileUrl, fileName); + fileHandler.download( + `${API_SERVER}/wp-json/wiaas/documents?document_id=${document.id}`, + document.name); } render() { @@ -41,9 +41,9 @@ class PackageInfo extends Component {
{coMarketTexts.labels.DOCUMENTS}:
{ documents.map((document) => - {this.downloadDocument(document)}}> - {document.documentName} ({document.extension}) + {document.name} ) } diff --git a/frontend/src/containers/orders/components/OrderDocuments.jsx b/frontend/src/containers/orders/components/OrderDocuments.jsx index 1b42f47..eb7e8a1 100644 --- a/frontend/src/containers/orders/components/OrderDocuments.jsx +++ b/frontend/src/containers/orders/components/OrderDocuments.jsx @@ -10,7 +10,12 @@ class OrderDocuments extends Component { return (
{ - orderInfo.packages.map(orderPackage => ) + orderInfo.packages.map(orderPackage => ( + )) } { orderInfo.orderDocuments && diff --git a/frontend/src/containers/orders/components/OrderDocumentsGroup.jsx b/frontend/src/containers/orders/components/OrderDocumentsGroup.jsx index cd11fb0..29f8af1 100644 --- a/frontend/src/containers/orders/components/OrderDocumentsGroup.jsx +++ b/frontend/src/containers/orders/components/OrderDocumentsGroup.jsx @@ -1,5 +1,4 @@ import React, {Component} from 'react'; -import {Tooltip} from 'reactstrap'; import WiaasBox from '../../../mainComponents/box/WiaasBox.jsx'; import {API_SERVER} from '../../../config'; import FileDownloader from '../../../helpers/FileDownloader'; @@ -18,62 +17,39 @@ const iconTypes = { xlsx: 'file-excel-o', ppt: 'file-powerpoint-o', pptx: 'file-powerpoint-o' -} +}; class OrderDocumentsGroup extends Component { constructor(props) { super(props); - this.toggle = this.toggle.bind(this); this.state = {}; } - toggle(idDocument) { - const obj = {} - obj[idDocument] = !this.state[idDocument]; - - this.setState(obj); - } - getDocumentIcon(documentType) { return iconTypes[documentType] || 'file'; } - getDocumentText(document) { - const name = document.documentName + '.' + document.extension; - - return name.length > 9 ? name.substring(0, 10) + '...' : name; - } - - downloadDocument(document){ - const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}&fileType=${document.documentTypeName}` - const fileName = document.documentName + '.' + document.extension; - fileHandler.download(fileUrl, fileName); + downloadDocument(orderId, itemId, document){ + const fileUrl = `${API_SERVER}/wp-json/wiaas/documents/order/${orderId}/${document.type}?item_id=${itemId}&document_key=${document.key}`; + fileHandler.download(fileUrl, document.name); } render() { - const {documentsGroup} = this.props; + const {documentsGroup, orderId} = this.props; return (
{ documentsGroup.documents && documentsGroup.documents.length > 0 && - + { - documentsGroup.documents.map(document => -
{this.downloadDocument(document)}} className="document-link-big"> + documentsGroup.documents.map(document => +
{this.downloadDocument(orderId, documentsGroup.orderItemId, document)}} className="document-link-big">
- {this.getDocumentText(document)} - this.toggle(document.idDocument)}> - {document.documentName} ({document.extension}) - + {document.name}
) } diff --git a/frontend/src/helpers/DocumentHelper.js b/frontend/src/helpers/DocumentHelper.js new file mode 100644 index 0000000..3ab1f2c --- /dev/null +++ b/frontend/src/helpers/DocumentHelper.js @@ -0,0 +1,17 @@ +const iconTypes = { + doc: 'file-word-o', + docx: 'file-word-o', + odt: 'file-word-o', + ods: 'file-excel-o', + pdf: 'file-pdf-o', + png: 'file-image-o', + jpg: 'file-image-o', + xls: 'file-excel-o', + xlsx: 'file-excel-o', + ppt: 'file-powerpoint-o', + pptx: 'file-powerpoint-o' +}; + +export const getDocumentIcon = extension => { + return iconTypes[extension] || 'file'; +}; \ No newline at end of file diff --git a/frontend/src/helpers/FileDownloader.js b/frontend/src/helpers/FileDownloader.js index 58bd1a7..a65416c 100644 --- a/frontend/src/helpers/FileDownloader.js +++ b/frontend/src/helpers/FileDownloader.js @@ -7,6 +7,7 @@ class FileDownloader { download(fileUrl, fileName){ htmlClient.fetch({ url: fileUrl, + method: 'get', responseType: 'arraybuffer' }) .then((response) => { diff --git a/frontend/src/helpers/HtmlClient.js b/frontend/src/helpers/HtmlClient.js index 99ab53c..482440e 100644 --- a/frontend/src/helpers/HtmlClient.js +++ b/frontend/src/helpers/HtmlClient.js @@ -45,14 +45,14 @@ class HtmlClient { uploadFile(file, configParams = null) { let formData = new FormData(); formData.append('file', file, file.name); - /* + if(configParams) { - + Object.keys(configParams.data).forEach((paramKey) => { formData.append(paramKey, configParams.data[paramKey]); }); - - }*/ + + } configParams.data = formData; const params = Object.assign({}, uploadParams(), configParams); diff --git a/frontend/src/helpers/OrderHelper.js b/frontend/src/helpers/OrderHelper.js index 10b604a..df8394e 100644 --- a/frontend/src/helpers/OrderHelper.js +++ b/frontend/src/helpers/OrderHelper.js @@ -1,5 +1,6 @@ import moment from 'moment'; import {fromWiaasProcessStep} from './ProcessHelper'; +import { getDocumentIcon } from './DocumentHelper'; function formatDate(date) { return date ? moment(date).format("Do MMM, YYYY") : undefined; @@ -40,6 +41,7 @@ export const fromWCOrder = (WCOrder) => { packages: WCOrder['line_items'].map(packageLine => { return { id: packageLine['product_id'], + orderItemId: packageLine['id'], name: packageLine.name, quantity: packageLine.quantity, price: packageLine.price, @@ -62,6 +64,10 @@ export const fromWCOrder = (WCOrder) => { packageName: packageOption.name, groupName: packageOption['group_name'] || '', })) : [], + documents: packageLine.documents.map(document => { + document['icon'] = getDocumentIcon(document.extension); + return document; + }) || [] }; }), process: processInfo, diff --git a/frontend/src/helpers/PackageHelper.js b/frontend/src/helpers/PackageHelper.js index d6b0087..c59d6c6 100644 --- a/frontend/src/helpers/PackageHelper.js +++ b/frontend/src/helpers/PackageHelper.js @@ -1,3 +1,4 @@ +import { getDocumentIcon } from './DocumentHelper'; const DEFAULT_PACKAGE_IMG = 'static/img/no-photo-package.jpg'; @@ -49,12 +50,10 @@ export const fromWCPackage = wcPackage => { country: wcPackage.country, countryCode: wcPackage['country_code'], currency: wcPackage.currency, - documents: wcPackage.documents ? wcPackage.documents.map(document => ({ - idDocument: document.id, - documentName: document.name, - extension: document.extension, - idPackage: wcPackage.id, - })) : [], + documents: wcPackage.documents ? wcPackage.documents.map(document => { + document.icon = getDocumentIcon(document.extension); + return document; + }) : [], shortDescription: wcPackage.description, prices: extractPrices(wcPackage.id, wcPackage.prices || []), groups: extractGroups(wcPackage.groups || {}),