Merge branch 'frontend-orders/number' into 'master'

Frontend orders/number

See merge request saburly/wiaas/new-wiaas!13
This commit was merged in pull request #13.
This commit is contained in:
Almira
2018-08-29 11:06:01 +00:00
35 changed files with 1632 additions and 588 deletions

View File

@@ -1,6 +1,24 @@
<?php <?php
class Wiass_REST_Delivery_Process_API { class Wiass_REST_Delivery_Process_API {
const BASE_NAME = WP_HOME . '/';
const FILE_KEY_NAME = 'file';
const PATH_PARTS_TO_EXTRACT = 7;
const ACCEPTANCE_STATUS_FIELD_ID = 8;
const EXPIRATION_DATE_FIELD_ID = 9;
const DECLINE_REASON_FIELD_ID = 10;
const UPLOADED_FILES_FIELD_ID = 12;
const USER_INPUT_STEP_NAME = 'Upload acceptance file';
const ACCEPT_STATUS_LABEL = 'accept';
const DECLINE_STATUS_LABEL = 'decline';
const ACCEPTABLE_STATUS = [self::ACCEPT_STATUS_LABEL, self::DECLINE_STATUS_LABEL];
/** /**
* Endpoint namespace. * Endpoint namespace.
* *
@@ -14,8 +32,25 @@ class Wiass_REST_Delivery_Process_API {
'methods' => 'GET', 'methods' => 'GET',
'callback' => array(__CLASS__, 'get_next_actions_for_user'), 'callback' => array(__CLASS__, 'get_next_actions_for_user'),
) ); ) );
}
register_rest_route( self::$namespace, 'customer-acceptance/(?P<entry_id>\d+)', array(
'methods' => 'GET',
'callback' => array(__CLASS__, 'get_customer_acceptance'),
'permission_callback' => 'is_user_logged_in'
) );
register_rest_route( self::$namespace, 'customer-acceptance/(?P<entry_id>\d+)', array(
'methods' => 'POST',
'callback' => array(__CLASS__, 'submit_customer_acceptance'),
'permission_callback' => 'is_user_logged_in'
) );
register_rest_route( self::$namespace, 'customer-acceptance/(?P<entry_id>\d+)/upload-file' , array(
'methods' => 'POST',
'callback' => array(__CLASS__, 'upload_file'),
'permission_callback' => 'is_user_logged_in'
) );
}
public static function get_next_actions_for_user() { public static function get_next_actions_for_user() {
$current_user = wp_get_current_user(); $current_user = wp_get_current_user();
@@ -62,4 +97,207 @@ class Wiass_REST_Delivery_Process_API {
return $response; return $response;
} }
public static function get_customer_acceptance(WP_REST_Request $request){
$entry = GFAPI::get_entry($request['entry_id']);
if (is_wp_error($entry)){
return self::generate_error('Customer acceptance entry not found', 404);
}
$acceptance_documents = array();
$uploaded_files = json_decode($entry[self::UPLOADED_FILES_FIELD_ID]);
foreach($uploaded_files as $file_url){
//example of decoded url :
//http://localhost/wp/index.php?gf-download=2018/08/rokovi-1535378841.docx&form-id=1&field-id=12&hash=1be6c30f0eeff93563b352d15fe459d5ded12ee06c2c8f36fed66b42dedf2534
$decoded_url = urldecode($file_url);
$url_parts = explode('?', $decoded_url);
$file_name_base_parts = explode('&', $url_parts[1]);
$file_name_parts = explode('/', $file_name_base_parts[0]);
$file_name_with_extension_parts = explode('.', $file_name_parts[2]);
$acceptance_documents_entry = array(
'name' => $file_name_with_extension_parts[0],
'extension' => $file_name_with_extension_parts[1],
'url' => $file_url
);
array_push($acceptance_documents, $acceptance_documents_entry);
}
$acceptance_status = 0;
if ($entry[self::ACCEPTANCE_STATUS_FIELD_ID]){
$acceptance_status = ($entry[self::ACCEPTANCE_STATUS_FIELD_ID] === 'accept') ? 1 : -1;
}
$result = array(
'documents' => $acceptance_documents,
'expiration' => $entry[self::EXPIRATION_DATE_FIELD_ID],
'status' => $acceptance_status,
'decline_reason' => $entry[self::DECLINE_REASON_FIELD_ID]
);
return new WP_REST_Response($result);
}
public static function submit_customer_acceptance(WP_REST_Request $request){
$entry = GFAPI::get_entry($request['entry_id']);
if (is_wp_error($entry)){
return self::generate_error('Customer acceptance entry not found', 404);
}
$status = $request['actionType'];
$reason = $request['declineReason'];
if (!in_array($status, self::ACCEPTABLE_STATUS)){
return self::generate_wiaas_response('ACCEPTANCE_STATUS_MISSING', 'error');
}
$installation_declined = ($status === self::DECLINE_STATUS_LABEL);
$uploaded_files = json_decode($entry[self::UPLOADED_FILES_FIELD_ID]);
if ($installation_declined && $reason === ''){
return self::generate_wiaas_response('DECLINE_REASON_EMPTY', 'error');
}
if (!$installation_declined && (count($uploaded_files)===0)){
return self::generate_wiaas_response('ACCEPTANCE_NOT_UPLOADED', 'error');
}
$entry[self::DECLINE_REASON_FIELD_ID] = $reason;
$entry[self::ACCEPTANCE_STATUS_FIELD_ID] = $status;
if (!GFAPI::update_entry( $entry )){
return self::generate_wiaas_response('INTERNAL_SERVER_ERROR', 'error');
}
//Check if step is already completed, to not submit again
$gf_api = new Gravity_Flow_API($entry['form_id']);
$current_step = $gf_api->get_current_step($entry);
if ($current_step->get_name() !== self::USER_INPUT_STEP_NAME){
return self::generate_wiaas_response('ACCEPTANCE_STATUS_UPDATED', 'success');
}
if ( $current_step ) {
$current_step->purge_assignees();
$current_step->update_step_status( 'complete' );
}
$entry_id = $entry['id'];
$new_step_id = $current_step->get_id() + 1;
$new_step = $gf_api->get_step( $new_step_id, $entry );
$feedback = sprintf( esc_html__( 'Sent to step: %s', 'gravityflow' ), $new_step->get_name() );
$gf_api->add_timeline_note( $entry_id, $feedback );
$gf_api->log_activity( 'workflow', 'sent_to_step', $gf_api->form_id, $entry_id, $step_id );
gform_update_meta( $entry_id, 'workflow_final_status', 'pending' );
$new_step->start();
$gf_api->process_workflow( $entry_id );
if ($installation_declined){
return self::generate_wiaas_response('INSTALLATION_DECLINED', 'success');
}
return self::generate_wiaas_response('INSTALLATION_ACCEPTED', 'success');
}
public static function upload_file(WP_REST_Request $request){
$files = $request->get_file_params();
if (!$files[self::FILE_KEY_NAME]){
return self::generate_wiaas_response('NO_FILES_UPLOADED', 'error');
}
$entry = GFAPI::get_entry($request['entry_id']);
if (is_wp_error($entry)){
return self::generate_error('Customer acceptance entry not found', 404);
}
$form = GFAPI::get_form($entry['form_id']);
$form_upload_path = GFFormsModel::get_upload_path( $form['id'] );
$target_path = $form_upload_path . '/' . date('Y') . '/' . date('m') . '/';
wp_mkdir_p( $target_path );
GFCommon::recursive_add_index_file( $target_path );
$upload_file_field = GFAPI::get_field($form['id'], self::UPLOADED_FILES_FIELD_ID);
$file_name = sanitize_file_name($files[self::FILE_KEY_NAME]['name']);
$file_path_details = pathinfo($file_name);
if ( GFCommon::file_name_has_disallowed_extension( $file_name ) ) {
return self::generate_wiaas_response('INVALID_FILE_ACCEPTANCE', 'error');
}
$allowed_extensions = ! empty( $upload_file_field->allowedExtensions ) ? GFCommon::clean_extensions( explode( ',', strtolower( $upload_file_field->allowedExtensions ) ) ) : array();
if ( ! empty( $allowed_extensions ) ) {
if ( ! GFCommon::match_file_extension( $file_name, $allowed_extensions ) ) {
return self::generate_wiaas_response('INVALID_FILE_ACCEPTANCE', 'error');
}
}
$new_file_name = $file_path_details['filename'] . '-' . time() . '.' . $file_path_details['extension'];
// Bypasses security checks when running unit tests.
if ( defined( 'WP_TEST_IN_PROGRESS' ) && WP_TEST_IN_PROGRESS ) {
return self::generate_wiaas_response('FILE_UPLOADED', 'success');
}
if ( move_uploaded_file($files[self::FILE_KEY_NAME]['tmp_name'], $target_path . $new_file_name ) ) {
GFFormsModel::set_permissions( $target_path . $new_file_name );
} else {
return self::generate_wiaas_response('INTERNAL_SERVER_ERROR', 'error');
}
//Extract path relative to the root
//Last 6 strings (excluding last empty) are path relative to the root
$path_parts = explode('/', $target_path);
$relative_path = '';
$i = count($path_parts) - self::PATH_PARTS_TO_EXTRACT;
while($i < count($path_parts)-1){
$relative_path = $relative_path . $path_parts[$i] . '/';
$i++;
}
$file_url = self::BASE_NAME . $relative_path . $new_file_name;
$url_for_download = $upload_file_field->get_download_url($file_url);
$uploaded_files = json_decode($entry[self::UPLOADED_FILES_FIELD_ID]);
if ($uploaded_files === NULL){
$uploaded_files = [];
}
array_push($uploaded_files, $url_for_download);
$entry[self::UPLOADED_FILES_FIELD_ID] = json_encode($uploaded_files);
if (GFAPI::update_entry( $entry )) {
return self::generate_wiaas_response('FILE_UPLOADED','success');
}
return self::generate_wiaas_response('NOT_UPLOADED', 'error');
}
//Helper function
private static function generate_error($message, $code = 500){
$error = array(
'status' => $code,
'message' => $message,
);
$result = new WP_REST_Response($error);
$result->set_status($code);
return $result;
}
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);
}
} }

View File

@@ -23,6 +23,31 @@ class Wiaas_Delivery_Process {
add_filter( 'gform_entry_meta', array(__CLASS__, 'extend_gravity_form_entry_meta'), 10, 2 ); add_filter( 'gform_entry_meta', array(__CLASS__, 'extend_gravity_form_entry_meta'), 10, 2 );
add_action( 'gravityflow_workflow_complete', array(__CLASS__, 'maybe_complete_parent_process_step'), 5, 3 ); add_action( 'gravityflow_workflow_complete', array(__CLASS__, 'maybe_complete_parent_process_step'), 5, 3 );
add_action( 'gravityflow_workflow_complete', array(__CLASS__, 'maybe_complete_parent_order'), 10, 3 );
// Some temporary functions to make inbox page prettier
add_filter('gravityflow_inbox_submitter_name', array(__CLASS__, 'display_step_name_in_inbox'), 10, 3);
add_filter('gravityflow_approve_label_workflow_detail', array(__CLASS__, 'approval_step_approval_label'), 10, 2);
add_filter('gravityflow_reject_label_workflow_detail', array(__CLASS__, 'approval_step_reject_label'), 10, 2);
}
public static function approval_step_approval_label($label, $step) {
if ($step->get_name() === 'Complete step') {
return esc_html__( 'Complete step', 'wiaas' );
}
return $label;
}
public static function approval_step_reject_label($label, $step) {
if ($step->get_name() === 'Complete step') {
return esc_html__( 'Cancel', 'wiaas' );
}
return $label;
}
public static function display_step_name_in_inbox($name, $entry, $form) {
return $entry['wiaas_delivery_step_name'];
} }
/** /**
@@ -34,6 +59,29 @@ class Wiaas_Delivery_Process {
Gravity_Flow_Steps::register( new Wiaas_Delivery_Process_Step() ); Gravity_Flow_Steps::register( new Wiaas_Delivery_Process_Step() );
} }
/**
* Maybe complete parent order for completed delivery process
* @param $entry_id
* @param $form
*/
public static function maybe_complete_parent_order($entry_id, $form) {
$entry = GFAPI::get_entry($entry_id);
$order_id = $entry['wiaas_delivery_order_id'];
if (!isset($order_id)) {
return;
}
$process_entry_id = get_post_meta($order_id, 'wiaas_delivery_process_entry_id', true);
// order process entry completed, so complete order
if (absint($process_entry_id) === $entry_id) {
$order = wc_get_order($order_id);
$order->update_status('completed', 'Completed order delivery process.', true);
}
}
/** /**
* Retrieves delivery process instance for order * Retrieves delivery process instance for order
* *
@@ -134,6 +182,16 @@ class Wiaas_Delivery_Process {
), ),
); );
$entry_meta[ 'wiaas_delivery_step_name' ] = array(
'label' => 'Wiaas Delivery Step name',
'is_numeric' => false,
'update_entry_meta_callback' => null,
'is_default_column' => false, // this column will be displayed by default on the entry list
'filter' => array(
'operators' => array( 'is' ),
),
);
return $entry_meta; return $entry_meta;
} }

View File

@@ -18,6 +18,17 @@ class Wiaas_Order {
add_filter('woocommerce_rest_prepare_shop_order_object', array(__CLASS__, 'transform_rest_order'), 999, 3); add_filter('woocommerce_rest_prepare_shop_order_object', array(__CLASS__, 'transform_rest_order'), 999, 3);
add_filter('woocommerce_rest_orders_prepare_object_query', array( __CLASS__, 'wiaas_prepare_rest_orders_query'), 10, 2); add_filter('woocommerce_rest_orders_prepare_object_query', array( __CLASS__, 'wiaas_prepare_rest_orders_query'), 10, 2);
add_filter('woocommerce_new_order_note_data', array( __CLASS__, 'update_new_order_comment_date'), 10, 3);
}
public static function update_new_order_comment_date($comment_data, $order_data) {
$user = wp_get_current_user();
$comment_data['comment_author'] = $user->display_name;
$comment_data['comment_author_email'] = $user->user_email;
return $comment_data;
} }
/** /**
@@ -95,6 +106,8 @@ class Wiaas_Order {
$data = self::_append_wiaas_order_details($data, $order, $request); $data = self::_append_wiaas_order_details($data, $order, $request);
$data = self::_append_order_comments($data, $order, $request);
$response->set_data($data); $response->set_data($data);
return $response; return $response;
@@ -126,6 +139,7 @@ class Wiaas_Order {
private static function _append_commercial_lead_info($data, $order, $request) { private static function _append_commercial_lead_info($data, $order, $request) {
$data['commercial_lead'] = array( $data['commercial_lead'] = array(
'id' => 1,
'name' => 'Coor Service Management', 'name' => 'Coor Service Management',
'phone' => '123456789', 'phone' => '123456789',
'email' => 'rikard@co-ideation.com' 'email' => 'rikard@co-ideation.com'
@@ -226,6 +240,34 @@ class Wiaas_Order {
$data['delivery-process'] = Wiaas_Delivery_Process::get_order_delivery_process($order->get_id()); $data['delivery-process'] = Wiaas_Delivery_Process::get_order_delivery_process($order->get_id());
} }
return $data;
}
/** Append order comments if single order is requested
* @param $data
* @param $order
* @param $request
*/
private static function _append_order_comments($data, $order, $request) {
if (isset($request['id'])) {
$current_user = wp_get_current_user();
$comments = $order->get_customer_order_notes();
$data['comments'] = array();
foreach ($comments as $comment) {
$data['comments'][] = array(
'id' => $comment->comment_ID,
'content' => $comment->comment_content,
'username' => $comment->comment_author,
'date' => $comment->comment_date,
'is_owner' => $comment->comment_author === $current_user->display_name,
);
}
}
return $data; return $data;
} }
} }

View File

@@ -22,7 +22,7 @@
"inputs": null, "inputs": null,
"choices": [ "choices": [
], ],
"formId": 10, "formId": 1,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -63,7 +63,7 @@
"inputs": null, "inputs": null,
"dateType": "datepicker", "dateType": "datepicker",
"calendarIconType": "none", "calendarIconType": "none",
"formId": 10, "formId": 1,
"description": "", "description": "",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
@@ -93,17 +93,156 @@
"displayOnly": "" "displayOnly": ""
}, },
{ {
"type": "fileupload", "type": "radio",
"id": 7, "id": 8,
"label": "Acceptance document", "label": "acceptance",
"adminLabel": "", "adminLabel": "",
"isRequired": false, "isRequired": false,
"size": "medium", "size": "medium",
"errorMessage": "", "errorMessage": "",
"visibility": "visible", "visibility": "visible",
"inputs": null, "inputs": null,
"formId": 10, "choices": [
"description": "Upload your acceptance document", {
"text": "not-accepted",
"value": "not-accepted",
"isSelected": true,
"price": ""
},
{
"text": "accept",
"value": "accept",
"isSelected": false,
"price": ""
},
{
"text": "decline",
"value": "decline",
"isSelected": false,
"price": ""
}
],
"formId": 1,
"description": "",
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"conditionalLogic": "",
"productField": "",
"enableOtherChoice": "",
"enablePrice": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": ""
},
{
"type": "date",
"id": 9,
"label": "Expiration date",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"dateType": "datepicker",
"calendarIconType": "none",
"formId": 1,
"description": "",
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"choices": "",
"conditionalLogic": "",
"calendarIconUrl": "",
"dateFormat": "ymd_dash",
"productField": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": ""
},
{
"type": "text",
"id": 10,
"label": "Reason",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"formId": 1,
"description": "",
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"choices": "",
"conditionalLogic": "",
"productField": "",
"enablePasswordInput": "",
"maxLength": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": "",
"enablePrice": ""
},
{
"type": "fileupload",
"id": 12,
"label": "File",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"formId": 1,
"description": "Upload customer acceptance file",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
"inputMaskValue": "", "inputMaskValue": "",
@@ -120,20 +259,19 @@
"conditionalLogic": "", "conditionalLogic": "",
"maxFileSize": "", "maxFileSize": "",
"maxFiles": "", "maxFiles": "",
"multipleFiles": false, "multipleFiles": true,
"allowedExtensions": "", "allowedExtensions": "pdf,docx,doc,xlsx,xls,odt,ods,jpg,png,jpeg",
"productField": "", "productField": "",
"calculationFormula": "", "calculationFormula": "",
"calculationRounding": "", "calculationRounding": "",
"enableCalculation": "", "enableCalculation": "",
"disableQuantity": false, "disableQuantity": false,
"displayAllCategories": false, "displayAllCategories": false,
"useRichTextEditor": false, "useRichTextEditor": false
"displayOnly": ""
} }
], ],
"version": "2.3.2", "version": "2.3.2",
"id": 10, "id": 1,
"useCurrentUserAsAuthor": true, "useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false, "postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false, "postTitleTemplateEnabled": false,
@@ -142,6 +280,9 @@
"lastPageButton": null, "lastPageButton": null,
"pagination": null, "pagination": null,
"firstPageCssClass": null, "firstPageCssClass": null,
"is_active": "1",
"date_created": "2018-08-15 20:30:18",
"is_trash": "0",
"confirmations": [ "confirmations": [
{ {
"id": "5b5f75f7494b7", "id": "5b5f75f7494b7",
@@ -168,8 +309,8 @@
"feeds": { "feeds": {
"gravityflow": [ "gravityflow": [
{ {
"id": "22", "id": "1",
"form_id": "10", "form_id": "1",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -189,14 +330,12 @@
"schedule_date_field_offset": "0", "schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours", "schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"schedule_date_field": "6",
"type": "select", "type": "select",
"assignees": [ "assignees": [
"role|administrator", "role|administrator",
"assignee_user_field|2" "assignee_user_field|2"
], ],
"editable_fields": [
"5"
],
"routing": "", "routing": "",
"assignee_policy": "any", "assignee_policy": "any",
"highlight_editable_fields_enabled": "0", "highlight_editable_fields_enabled": "0",
@@ -204,9 +343,6 @@
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"display_fields_mode": "selected_fields", "display_fields_mode": "selected_fields",
"display_fields_selected": [
"5"
],
"default_status": "hidden", "default_status": "hidden",
"note_mode": "not_required", "note_mode": "not_required",
"assignee_notification_enabled": "0", "assignee_notification_enabled": "0",
@@ -260,23 +396,24 @@
"confirmation_messageEnable": "0", "confirmation_messageEnable": "0",
"confirmation_messageValue": "Thank you.", "confirmation_messageValue": "Thank you.",
"expiration": "0", "expiration": "0",
"expiration_type": "delay", "expiration_type": "date_field",
"expiration_date": "", "expiration_date": "",
"expiration_delay_offset": "7", "expiration_delay_offset": "7",
"expiration_delay_unit": "days", "expiration_delay_unit": "days",
"expiration_date_field_offset": "0", "expiration_date_field_offset": "0",
"expiration_date_field_offset_unit": "hours", "expiration_date_field_offset_unit": "hours",
"expiration_date_field_before_after": "after", "expiration_date_field_before_after": "after",
"expiration_date_field": "9",
"status_expiration": "expired", "status_expiration": "expired",
"destination_expired": "next", "destination_expired": "2",
"destination_complete": "next" "destination_complete": "next"
}, },
"addon_slug": "gravityflow", "addon_slug": "gravityflow",
"event_type": null "event_type": null
}, },
{ {
"id": "30", "id": "2",
"form_id": "10", "form_id": "1",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -362,7 +499,7 @@
"approval_notification_message": "Entry {entry_id} has been approved", "approval_notification_message": "Entry {entry_id} has been approved",
"approval_notification_disable_autoformat": "0", "approval_notification_disable_autoformat": "0",
"revertEnable": "0", "revertEnable": "0",
"revertValue": "22", "revertValue": 1,
"note_mode": "not_required", "note_mode": "not_required",
"expiration": "0", "expiration": "0",
"expiration_type": "delay", "expiration_type": "delay",
@@ -374,7 +511,7 @@
"expiration_date_field_before_after": "after", "expiration_date_field_before_after": "after",
"status_expiration": "rejected", "status_expiration": "rejected",
"destination_expired": "next", "destination_expired": "next",
"destination_rejected": "22", "destination_rejected": 1,
"destination_approved": "next" "destination_approved": "next"
}, },
"addon_slug": "gravityflow", "addon_slug": "gravityflow",
@@ -383,5 +520,5 @@
] ]
} }
}, },
"version": "2.3.2.6" "version": "2.3.2"
} }

View File

@@ -30,7 +30,7 @@
"text": "wpUser" "text": "wpUser"
} }
], ],
"formId": 12, "formId": 4,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -71,7 +71,7 @@
"inputs": null, "inputs": null,
"dateType": "datepicker", "dateType": "datepicker",
"calendarIconType": "calendar", "calendarIconType": "calendar",
"formId": 12, "formId": 4,
"description": "", "description": "",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
@@ -102,7 +102,7 @@
} }
], ],
"version": "2.3.2", "version": "2.3.2",
"id": 12, "id": 4,
"useCurrentUserAsAuthor": true, "useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false, "postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false, "postTitleTemplateEnabled": false,
@@ -111,17 +111,9 @@
"lastPageButton": null, "lastPageButton": null,
"pagination": null, "pagination": null,
"firstPageCssClass": null, "firstPageCssClass": null,
"notifications": [ "is_active": "1",
{ "date_created": "2018-08-09 15:36:00",
"id": "5b5f9ebc520f3", "is_trash": "0",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"confirmations": [ "confirmations": [
{ {
"id": "5b5f9ebc52a80", "id": "5b5f9ebc52a80",
@@ -134,11 +126,22 @@
"queryString": "" "queryString": ""
} }
], ],
"notifications": [
{
"id": "5b5f9ebc520f3",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"feeds": { "feeds": {
"gravityflow": [ "gravityflow": [
{ {
"id": "27", "id": "6",
"form_id": "12", "form_id": "4",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -245,5 +248,5 @@
] ]
} }
}, },
"version": "2.3.2.6" "version": "2.3.2"
} }

View File

@@ -30,7 +30,7 @@
"text": "wpUser" "text": "wpUser"
} }
], ],
"formId": 13, "formId": 2,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -70,7 +70,7 @@
"inputs": null, "inputs": null,
"dateType": "datepicker", "dateType": "datepicker",
"calendarIconType": "calendar", "calendarIconType": "calendar",
"formId": 13, "formId": 2,
"description": "", "description": "",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
@@ -111,7 +111,7 @@
"inputs": null, "inputs": null,
"dateType": "datepicker", "dateType": "datepicker",
"calendarIconType": "calendar", "calendarIconType": "calendar",
"formId": 13, "formId": 2,
"description": "", "description": "",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
@@ -141,7 +141,7 @@
} }
], ],
"version": "2.3.2", "version": "2.3.2",
"id": 13, "id": 2,
"useCurrentUserAsAuthor": true, "useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false, "postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false, "postTitleTemplateEnabled": false,
@@ -150,6 +150,9 @@
"lastPageButton": null, "lastPageButton": null,
"pagination": null, "pagination": null,
"firstPageCssClass": null, "firstPageCssClass": null,
"is_active": "1",
"date_created": "2018-08-09 15:35:59",
"is_trash": "0",
"confirmations": [ "confirmations": [
{ {
"id": "5b60b12baa00e", "id": "5b60b12baa00e",
@@ -176,8 +179,8 @@
"feeds": { "feeds": {
"gravityflow": [ "gravityflow": [
{ {
"id": "31", "id": "3",
"form_id": "13", "form_id": "2",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -286,8 +289,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "32", "id": "4",
"form_id": "13", "form_id": "2",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -377,7 +380,7 @@
"approval_notification_message": "Entry {entry_id} has been approved", "approval_notification_message": "Entry {entry_id} has been approved",
"approval_notification_disable_autoformat": "0", "approval_notification_disable_autoformat": "0",
"revertEnable": "0", "revertEnable": "0",
"revertValue": "31", "revertValue": 3,
"note_mode": "not_required", "note_mode": "not_required",
"expiration": "0", "expiration": "0",
"expiration_type": "delay", "expiration_type": "delay",
@@ -390,7 +393,7 @@
"expiration_date_field": "4", "expiration_date_field": "4",
"status_expiration": "rejected", "status_expiration": "rejected",
"destination_expired": "next", "destination_expired": "next",
"destination_rejected": "31", "destination_rejected": 3,
"destination_approved": "complete" "destination_approved": "complete"
}, },
"addon_slug": "gravityflow", "addon_slug": "gravityflow",
@@ -399,5 +402,5 @@
] ]
} }
}, },
"version": "2.3.2.6" "version": "2.3.2"
} }

View File

@@ -30,7 +30,7 @@
"text": "wpUser" "text": "wpUser"
} }
], ],
"formId": 9, "formId": 3,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -71,7 +71,7 @@
"inputs": null, "inputs": null,
"dateType": "datepicker", "dateType": "datepicker",
"calendarIconType": "none", "calendarIconType": "none",
"formId": 9, "formId": 3,
"description": "", "description": "",
"allowsPrepopulate": false, "allowsPrepopulate": false,
"inputMask": false, "inputMask": false,
@@ -101,7 +101,7 @@
} }
], ],
"version": "2.3.2", "version": "2.3.2",
"id": 9, "id": 3,
"useCurrentUserAsAuthor": true, "useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false, "postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false, "postTitleTemplateEnabled": false,
@@ -110,17 +110,9 @@
"lastPageButton": null, "lastPageButton": null,
"pagination": null, "pagination": null,
"firstPageCssClass": null, "firstPageCssClass": null,
"notifications": [ "is_active": "1",
{ "date_created": "2018-08-09 15:36:00",
"id": "5b5f68818822e", "is_trash": "0",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"confirmations": [ "confirmations": [
{ {
"id": "5b5f688188e90", "id": "5b5f688188e90",
@@ -133,11 +125,22 @@
"queryString": "" "queryString": ""
} }
], ],
"notifications": [
{
"id": "5b5f68818822e",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"feeds": { "feeds": {
"gravityflow": [ "gravityflow": [
{ {
"id": "20", "id": "5",
"form_id": "9", "form_id": "3",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -257,5 +260,5 @@
] ]
} }
}, },
"version": "2.3.2.6" "version": "2.3.2"
} }

View File

@@ -21,7 +21,7 @@
"visibility": "visible", "visibility": "visible",
"inputs": null, "inputs": null,
"numberFormat": "decimal_dot", "numberFormat": "decimal_dot",
"formId": "11", "formId": 5,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -71,7 +71,7 @@
"text": "wpUser" "text": "wpUser"
} }
], ],
"formId": "11", "formId": 5,
"description": "", "description": "",
"allowsPrepopulate": true, "allowsPrepopulate": true,
"inputMask": false, "inputMask": false,
@@ -102,7 +102,7 @@
} }
], ],
"version": "2.3.2.6", "version": "2.3.2.6",
"id": "11", "id": 5,
"useCurrentUserAsAuthor": true, "useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false, "postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false, "postTitleTemplateEnabled": false,
@@ -112,20 +112,8 @@
"pagination": null, "pagination": null,
"firstPageCssClass": null, "firstPageCssClass": null,
"is_active": "1", "is_active": "1",
"date_created": "2018-07-30 20:53:56", "date_created": "2018-08-09 15:36:00",
"is_trash": "0", "is_trash": "0",
"notifications": [
{
"id": "5b5f7ae4baced",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}",
"isActive": false
}
],
"confirmations": [ "confirmations": [
{ {
"id": "5b5f7ae4bb79e", "id": "5b5f7ae4bb79e",
@@ -138,11 +126,23 @@
"queryString": "" "queryString": ""
} }
], ],
"notifications": [
{
"id": "5b5f7ae4baced",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}",
"isActive": false
}
],
"feeds": { "feeds": {
"gravityflow": [ "gravityflow": [
{ {
"id": "28", "id": "7",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -164,7 +164,7 @@
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"target_form_id": "9", "target_form_id": 3,
"store_new_entry_idEnable": "1", "store_new_entry_idEnable": "1",
"new_entry_id_field": "6", "new_entry_id_field": "6",
"destination_complete": "next" "destination_complete": "next"
@@ -173,8 +173,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "33", "id": "8",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -196,7 +196,7 @@
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"target_form_id": "12", "target_form_id": 4,
"store_new_entry_idEnable": "0", "store_new_entry_idEnable": "0",
"new_entry_id_field": "", "new_entry_id_field": "",
"destination_complete": "next" "destination_complete": "next"
@@ -205,8 +205,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "34", "id": "9",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -228,7 +228,7 @@
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"target_form_id": "12", "target_form_id": 4,
"store_new_entry_idEnable": "0", "store_new_entry_idEnable": "0",
"new_entry_id_field": "", "new_entry_id_field": "",
"destination_complete": "next" "destination_complete": "next"
@@ -237,8 +237,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "29", "id": "10",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -258,7 +258,7 @@
"schedule_date_field_offset": "0", "schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours", "schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"target_form_id": "10", "target_form_id": 1,
"store_new_entry_idEnable": "1", "store_new_entry_idEnable": "1",
"new_entry_id_field": "7", "new_entry_id_field": "7",
"destination_complete": "next" "destination_complete": "next"
@@ -267,8 +267,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "36", "id": "11",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -290,7 +290,7 @@
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"target_form_id": "12", "target_form_id": 4,
"store_new_entry_idEnable": "0", "store_new_entry_idEnable": "0",
"new_entry_id_field": "", "new_entry_id_field": "",
"destination_complete": "next", "destination_complete": "next",
@@ -300,8 +300,8 @@
"event_type": null "event_type": null
}, },
{ {
"id": "35", "id": "12",
"form_id": "11", "form_id": "5",
"is_active": "1", "is_active": "1",
"feed_order": "0", "feed_order": "0",
"meta": { "meta": {
@@ -323,7 +323,7 @@
"schedule_date_field_before_after": "after", "schedule_date_field_before_after": "after",
"instructionsEnable": "0", "instructionsEnable": "0",
"instructionsValue": "", "instructionsValue": "",
"target_form_id": "12", "target_form_id": 4,
"store_new_entry_idEnable": "0", "store_new_entry_idEnable": "0",
"new_entry_id_field": "", "new_entry_id_field": "",
"destination_complete": "next" "destination_complete": "next"
@@ -334,5 +334,5 @@
] ]
} }
}, },
"version": "2.3.2.6" "version": "2.3.2"
} }

View File

@@ -100,6 +100,7 @@ class Wiaas_Delivery_Process_Step extends Gravity_Flow_Step {
'form_id' => $this->target_form_id, 'form_id' => $this->target_form_id,
'wiaas_delivery_process_id' => $this->get_entry_id(), 'wiaas_delivery_process_id' => $this->get_entry_id(),
'wiaas_delivery_order_id' => $entry['wiaas_delivery_order_id'], 'wiaas_delivery_order_id' => $entry['wiaas_delivery_order_id'],
'wiaas_delivery_step_name' => $this->get_name(),
); );
$customer_id_value = null; $customer_id_value = null;

View File

@@ -0,0 +1,27 @@
x\9C\AD[O\AF\E36\BF\E7S\E4\\E0\A5\FAc\C96\F0\CBK\98[\BB\D8C\D1\DBn \9D\B6\97\F9\FAK\91\92%Y\B4d\8F\DBA+&)\8A?\89\A4D=q\93\D7o\97\FF]\FC3\A3\B9\A9\EB\D0\C9\DBp\FD\EB?\97\FDp\FD\EFE\DCF
\FF]\D7\DF\FD~1榯\D6@-G \CFR!\E3\F5\B7.\AA\B37^J\F7\9C\BC\D4VC?\F4\B2\EB\F3w\9D\F0L\EF\A0\93\BD\B3v\E9\B1wd\C9;T\A6\D3\E2\D6o)\E3_\F2\CA\D0K^z\C7+C\EF\D6ʐ9\853\D2\FB\E7\C5X\A7o\AFo\E3\F5\F3\DF\D7_H\AF\9F\BF\FDrrzSw\A1\F0SO\C3]t\F8h&\F8\B0\A2\9F\F0\E77\F8}\98\C2\CF\C3$\C5]\8C\C0j\DC\D7<\BDɻxG6 \DF\F0\E3#\CA qr\FA\F5\F3\CB\E5\F9y\F9\89U\CC
\98+Ő\FBcz\B3\FE\F1\89\82\D2\EB\EE\A5\E9(\A4\F4\C4Z\8CRMâ\DD\D3\E9F\FE\98Íi\9Elk,\AF\AD\B1H\AD\DD`\E0S\D3`\D4U\DA\C5ʶC-Ԓ8\8B\A2\F1\CB\D2WO_|9\852\FF\E3L_\EF\F4\F5\88|Ú/g\D0\893\AD]ZOb9\95^\F8\E5l\ECZsdw)Iʜ\E9\E2\D5\FD\C8~$u\A5\CAz\E8\B6l\A9Fg\C5^va\C6F[\8EA\D5ڔ\B2\A3\85\B5\92sJ\9D
\EB\91
\99\E9\92]f\BF>cx\92nj!\BD\93&\95"\A9[\D9S+\B7\A6\D9L'\B7F\AChc9\88\97P\B2\93Б[\91\E0|f\F9._R\E3; \F1?\FF\C3\F5t\E6\FA
Z_\AE\F2\FA\87\F7\A6\83\84\BE\BE^\8C\C4֟\D7\92f=\F8\C2>\D2c\ABJ\9Fc\A4\C7V\95\BE\D3\E0zlU\E9\E5\98\CA\C7V\95^\F4\A9|l\D5\E8\CD\D8\C1g\A0\A7V\95>\B3\A7i\DA\D3d\F64M{\9A̞\A6iO\93\D9\D34\EDi \BC$\E3\C5V\95^\F6\E9x\B1U\A5]:^l\D5\E8;\ADq\BCԪ\D2\F7c2^jU\E91\A8.\F4ت\CE@\D4:\FAȼA\EEO\EF3\82*\92R\B2\F1շ\AA Z\C6\EC\E4\ABo\D50\D1Z\B0Ug\A0\BCɏ\C1'.5\9FLy\9F\CDT(\C3
\B69\94\8C0`k\C5PD\87^.\DET\F8
\B1Hj\E7\E45\BA\ED"\96&\A7\EF\DC\ECV\9C\EA\D7y!Ob\86\E2\CDJLA\B4qOÖ8=V\9C\92\98\A9\80Cj\B72\943`)CM=\86\T\00\B4S\C7\E6\D4
c\DDi\FB\BAՔ\98Q7x`\E4W\B5B\D8 #+\A5\DA?\86\C4\D4\FD`'Jy»\C1\E7\F8\AB
\B4#\90\88y
\B4\F8Db
\EF\F4\F6\E1d\DF~>\81\A8>`jIa\FD0\DE4H;\B6ж\A3[\DF+\CCi\A4\95=\FCQBx?}\FEQ\C1\9A\E9\D8z9\E3$\D4\F0\EC\F09]\FC\A9\815'r\94.\89s\A2\C9Wgn\DD\DA\DAi\009\89|ʗ\C2|&\B5v\B3\D2=jT\EB\A5:j\8B1|C\999\B58F#\9F\FEGj[\F9\88 ƥ[w\F8\D4N\D6+șƻ\E7ro\D4\E0\D4!.F\E5V\A4Q`\D5
t<\BE%\DFQ|{\9EŗI\F8\8E\DBS\96\F0U\AA\9C\EC/\97l\BE\E4C\CDʒ\D5\C1\FA
U\E8\FD\9E\F0ީ\8A/8\AD\DAtf\DE\F4L\87
W\A6zb\8E\DBXa\FBa\CE"\80\BBŕ\9D7U\E48\D4K\81\FF\92"\B4\DCVz\E0 f\9D\D5\E6>\D4\CB/\8D\8C[\93\95\90c\B9rYdi!=\B4\8Bl\F0B\C6e\E4 \A1\93:'>i\95.\C1r\FD\B5&\A7\9B\F5.^ߛn\B6`?< \CEN\82R)5\E0\88\CC\E8\F2ƕ\86\A9dK\ADPZ\93\E9u\97\FAW\84\B0\B3 38\DCٯIm\DC#\FA\E0 dmb\ADYt\B5G\B1
]\A93\CDE]u\9C \D7A\C48[\9DDlk(c\B3\81Y\EB\CEs\A19!b\BD\8D޲A\B0\BE\83\E6Û\D9;RG\BC\D3\E4\\97v\DAZ)%\EBa\BB3\9D\9F\B5;'\B2ۙ\90\98^\AE\A3\87\8FM8\D3uO\86
9\BA#\F90\FA{\96\ \8B\CBZ\80IVE\C0.d./rn\D8O\r\8D,\A3Tգ\86yF\B7\EBaԊ\AE\CFbV
܍\D8V>\9C\D5\E2\E0\92Ճ\E9\DE\F2\8Dߥ\E3\89\E0\E7F\B0\D9\EC#h\86\D3\F9<׹Kʼ݇\85\89?5\A08\93\CF&Y\D4\EE\EC\DC\88dD\B9<,\B32Jb\F8N\8B\E7\9D" e\E2^Jm n\8FA\00\C1Ji$\84%\F3a\88\B8\FC\F9$D\BC\C8\00Q=%7Z\95Y\81^\82 z8\D5\E7\F1#\A6\E1\DD\FE%\E4|\A0 (;Ȑ&u\92\ED\B5U\E8Z\CFL=f%\D7Q\CC\9DŬT\AA\99\BFɱ \CCf\DB\E0\8DG\CEc\A6\9C\E9\97߉:\DD;'\AB\8A˳\95?\9A\AA\83T\A8v\BB[\99\8E\87\A9\E4;
c\A0\B30\F1\83i$m\A2_\FB<<P\A2\A9o\93s̜?hc}ಪ\EAv.zI\F64;<ي\FD\B0\B1\8B\EEϚ\BAϲ\A9\AD9\B0n\ECʀ[YY(\C7X2)r%Q\B1\99\9D\EDΧǍ\F8^\B25:\D7\F9I\B3\B3\E3\F1'u\BB\92\8F\A3hg\AD\B2О\E2 \9F>\A2/k \99\F4\9C_r\DB<\82dxN\8E\F0\D5X)\AC\A6Kn\DCX'%\F3aИ\EEςƍhhv(\A3\BDM\9D\93\B7\B2\C6`\8D\E8в\81\m\D9J\FA}N\BE\8D\ABN\CFI\D6 w\80\B4\A9e#\DBQg\D0[\EC\FB\8E\D1K\D6\C33\9D\9FE\98\E9\8FY\A7N\DC\DDA\96\EC\BDh\BD4\91D'\F6&\F1\9B\85\FB\AE\D30\9B\96\C2%\B6\AA\85N-\96\8A\99\F2\AD*\BD\EC\B1J\E8\E9\B1U\A5\B1 \EC\9Ek\B4zt\87\95\81\9AZUz\9Bu\A9U\A57iQ\97ZUz\B0^ԞZUz\BC\83\B5\D0c\ABJ֋Elj\D5\E8՘ɩU\A5\D2"9\B5\AA\F4\99=UӞ*\B3\A7j\DASe\F6TM{\AA̞\AAiO\95\D9S5\ED\D9}"s\B5h\E8\A9Ug\A02\BD\00\B5\AA \BEL\EF\A8Ug\A02}`\C0V\9D\81\CA\F4~ Ԫ2\F82\BDg\A0V\9D\81\CA\F4\81\C16\C7\E0\CB\F4ɴ\90k\86"\E8\C1^+^\FB;\CA\F6\9C\C4S\85{N\E0\F1\D2=+\E5l\F1\BEj\BD\EF/\DFC2x[\F2\ED<:\B0Y\AAgHa0s\B1~cO_\97s\8DV\82\C2(\BC7\C3(X]\86\D1\C90\98\CEO\9E\B1\B2"\F7\ECu\A2wUקF \DE\D6\D0>yO\95
N8ޫ\A1ӨZ\B0
-\A7z\AD\8DY\C1|\A6\FB\B3\F8p"\F7\9E\EAi\F4f\FF\A6\98\96\DA#\96\94hk\96\D6e\E7P\B8m!Qv\BD\A7d\C7p\84\80\F2Ix+\C2XB^\85`Pɥ\F9\C0\AC:\F9\D2\889?\F9q\A5\A2@\EA\CFV{\B3P\89m\CA\F69\E6ጐ݇\D3thܟ\D6=\B3ۭ\D4\EE\95+\95\ED*㗒\F7]\A3a\F8\8EN-nL'\A7#r\FF\D42\CCf\F7\BB\CE\EC\E9FR\AD_\8D\B5N\C38Mܯ)\D9C\C3(pκ\FB\EF\D7l\C6\82\AE3Lu=^\C2\C8V\EA
\CA\EB3\CB\C2M\F8\CB\E8*\92\F8\ABF\93\ADqz\CF뷫\FA_\B2\93\E9\FC,\98\DCx\F6\9C\94\B9\BF\E3\D8߲+\88[\85\FC\B7x[\00+\9C\CE \E6\E9-\A9\99Tu^p\D7kZ.\B5\E4\DE;k\D6\C3X]\9FE\BA\B8\F7\CE\00\BB8O\F6"\E1\EAa\821G'u\B3Z\80\ABC\C0\F4\BD\F3\BE@\C9z\A6\F3\93\97\ECxvr\B4(\FD\EE\B1a\92\85K\A3K\ACK] \A4\9B\A5{
\E1*\AEꞮ$\A4\85T\9Ft%!\B4\9A\C8U-\A0Ƣ\A6\F6R3\C5\E8p\E1\B5_4\F7[!\BA\BA\E3\B6\AA3\AC{\CB&k֣3\931Źy\C9
\DC\E7\D4\C0\94\C8ػ\ADߗlW _\8DS\8E\86\83/U\AFߘ\F0\B8s\DEW\E3d:<\8A<\D3\F9Y\EC9\91{\83\83\E22u\BCP\FE~`N\F6\C9酖4\A3N\AFa\E2\CD \8C\FF\FD=ݭ\85\8B\85\CC.\8E\\CF\DFw\Rj\DF%
\86\EF(\BC\DC^\EA$\BC\9C\C8o=!WL\B6\9F\C6~\B7\\C2\D9Uz\EB\A9\C0>[\9DG\AF8q\EA(\83\B2\EC\FB\B2\89\92\F50\B4\DC^\EC$\B4սX\D7\CDĿ\8C\A8\E8\8A\E3B\93\FF\F8\A7\DCB/\C1\D0\D1:n\00\CA\E9\B1\FF\8FJ\F6èp\9B\AA\93\A8\94J\B5.\AF\A9";\F7\C7\CB\DArw\A1\F0\F4’\D5\C9\C3%^M\AA\E5\\F6L\E9ٲ\DF\FEč\97\BF6\nrk\94\AEf\C7=q\BBr{t\E4\8A՚\FD0r\E5\8E\E6$nk\85\9A\A8qɼ
~\A0

View File

@@ -9,6 +9,15 @@ class Wiass_REST_Delivery_Process_Api_Test extends Wiaas_Unit_Test_Case {
var $order_id, $api; var $order_id, $api;
/**
* Test REST Server
*
* @var WP_REST_Server
*/
protected $server;
protected $namespaced_route = '/wiaas';
function setUp() { function setUp() {
parent::setUp(); parent::setUp();
@@ -17,6 +26,41 @@ class Wiass_REST_Delivery_Process_Api_Test extends Wiaas_Unit_Test_Case {
$this->order_id = $order->get_id(); $this->order_id = $order->get_id();
wp_set_current_user(1); wp_set_current_user(1);
/** @var WP_REST_Server $wp_rest_server */
global $wp_rest_server;
$this->server = $wp_rest_server = new \WP_REST_Server;
do_action( 'rest_api_init' );
$original_valid_customer_acceptance = __DIR__ . '/../dummy-files/valid-customer-acceptance.odt';
$this->test_file_valid_customer_acceptance = '/tmp/valid-customer-acceptance.odt';
copy( $original_valid_customer_acceptance, $this->test_file_valid_customer_acceptance );
$original_invalid_customer_acceptance = __DIR__ . '/../dummy-files/invalid-customer-acceptance.txt';
$this->test_file_invalid_customer_acceptance = '/tmp/invalid-customer-acceptance.txt';
copy( $original_invalid_customer_acceptance, $this->test_file_invalid_customer_acceptance );
}
function test_register_route() {
$routes = $this->server->get_routes();
$this->assertArrayHasKey( $this->namespaced_route, $routes );
}
function test_endpoints() {
$the_route = $this->namespaced_route;
$routes = $this->server->get_routes();
foreach( $routes as $route => $route_config ) {
if( 0 === strpos( $the_route, $route ) ) {
$this->assertTrue( is_array( $route_config ) );
foreach( $route_config as $i => $endpoint ) {
$this->assertArrayHasKey( 'callback', $endpoint );
$this->assertArrayHasKey( 0, $endpoint[ 'callback' ], get_class( $this ) );
$this->assertArrayHasKey( 1, $endpoint[ 'callback' ], get_class( $this ) );
$this->assertTrue( is_callable( array( $endpoint[ 'callback' ][0], $endpoint[ 'callback' ][1] ) ) );
}
}
}
} }
/** /**
@@ -49,4 +93,429 @@ class Wiass_REST_Delivery_Process_Api_Test extends Wiaas_Unit_Test_Case {
$this->assertEquals($pending_step['status'], 'pending'); $this->assertEquals($pending_step['status'], 'pending');
$this->assertNotEmpty($pending_step['step_action']); $this->assertNotEmpty($pending_step['step_action']);
} }
/**
* @covers Wiass_REST_Delivery_Process_API::get_customer_acceptance
*/
function test_get_customer_acceptance_as_guest() {
wp_set_current_user(0);
$request = new WP_REST_Request( 'GET', '/wiaas/customer-acceptance/99191991919191');
$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_Delivery_Process_API::get_customer_acceptance
*/
function test_get_nonexisting_customer_acceptance() {
wp_set_current_user(1);
$request = new WP_REST_Request( 'GET', '/wiaas/customer-acceptance/911919191919' ); //non existing entry 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(), 404);
$error_data = $response->as_error();
$this->assertEquals($error_data->get_error_message(), 'Customer acceptance entry not found');
}
/**
* @covers Wiass_REST_Delivery_Process_API::get_customer_acceptance
*/
function test_get_valid_customer_acceptance() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'GET', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_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);
$response_data = $response->get_data();
$this->assertTrue(is_array($response_data));
$this->assertArrayHasKey('documents', $response_data);
$this->assertArrayHasKey('expiration', $response_data);
$this->assertArrayHasKey('status', $response_data);
$this->assertArrayHasKey('decline_reason', $response_data);
$this->assertTrue(is_array($response_data['documents']));
$uploaded_file = $response_data['documents'][0];
$this->assertTrue(is_array($uploaded_file));
$this->assertArrayHasKey('name', $uploaded_file);
$this->assertArrayHasKey('extension', $uploaded_file);
$this->assertArrayHasKey('url', $uploaded_file);
$this->assertEquals($uploaded_file['name'], 'file1');
$this->assertEquals($uploaded_file['extension'], 'docx');
$this->assertEquals($uploaded_file['url'], 'http://localhost/wp/index.php?gf-download=2018%2F08%2Ffile1.docx&form-id=1&field-id=12&hash=1be6c30f0eeff93563b352d15fe459d5ded12ee06c2c8f36fed66b42dedf2534');
$this->assertEquals($response_data['status'], 1); //1 means accept
$this->assertEquals($response_data['expiration'], "2020-01-01");
}
/**
* @covers Wiass_REST_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_customer_acceptance_as_guest() {
wp_set_current_user(0);
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/9191919191' );
$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_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_nonexisting_customer_acceptance() {
wp_set_current_user(1);
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/919191919191' );
$response = $this->server->dispatch( $request );
$this->assertNotNull($response);
$this->assertInstanceOf('WP_REST_Response',$response);
$this->assertTrue($response->is_error());
$this->assertEquals($response->get_status(), 404);
$error_data = $response->as_error();
$this->assertEquals($error_data->get_error_message(), 'Customer acceptance entry not found');
}
/**
* @covers Wiass_REST_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_customer_acceptance_with_invalid_status() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id );
$request->set_body_params(array(
'actionType' => 'invalid status',
'declineReason' => ''
));
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('error', $message['code']);
$this->assertEquals('ACCEPTANCE_STATUS_MISSING', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_customer_acceptance_with_accepted_status() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id );
$request->set_body_params(array(
'actionType' => 'accept',
'declineReason' => ''
));
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('success', $message['code']);
$this->assertEquals('INSTALLATION_ACCEPTED', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_customer_acceptance_with_declined_status_and_empty_reason() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id );
$request->set_body_params(array(
'actionType' => 'decline',
'declineReason' => ''
));
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('error', $message['code']);
$this->assertEquals('DECLINE_REASON_EMPTY', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::submit_customer_acceptance
*/
function test_submit_customer_acceptance_with_decline_status() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id );
$request->set_body_params(array(
'actionType' => 'decline',
'declineReason' => 'This is very reasonable reason'
));
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('success', $message['code']);
$this->assertEquals('INSTALLATION_DECLINED', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::upload_file
*/
function test_upload_customer_acceptance_file_as_guest() {
wp_set_current_user(0);
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/919199191/upload-file' );
$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_Delivery_Process_API::upload_file
*/
function test_upload_customer_acceptance_file_to_non_existing_entry() {
wp_set_current_user(1);
$original_valid_customer_acceptance = __DIR__ . '/../dummy-files/valid-customer-acceptance.odt';
$this->test_file_valid_customer_acceptance = '/tmp/valid-customer-acceptance.odt';
copy( $original_valid_customer_acceptance, $this->test_file_valid_customer_acceptance );
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/919199191/upload-file' );
$request->set_file_params( array(
'file' => array(
'file' => file_get_contents( $this->test_file_valid_customer_acceptance ),
'name' => 'valid-customer-acceptance.odt',
'size' => filesize( $this->test_file_valid_customer_acceptance ),
'tmp_name' => $this->test_file_valid_customer_acceptance,
),
) );
$response = $this->server->dispatch( $request );
$this->assertNotNull($response);
$this->assertInstanceOf('WP_REST_Response',$response);
$this->assertTrue($response->is_error());
$this->assertEquals($response->get_status(), 404);
$error_data = $response->as_error();
$this->assertEquals($error_data->get_error_message(), 'Customer acceptance entry not found');
}
/**
* @covers Wiass_REST_Delivery_Process_API::upload_file
*/
function test_upload_customer_acceptance_file_without_file() {
wp_set_current_user(1);
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/919199191/upload-file' );
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('error', $message['code']);
$this->assertEquals('NO_FILES_UPLOADED', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::upload_file
*/
function test_upload_invalid_customer_acceptance_file() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id . '/upload-file' );
$request->set_file_params( array(
'file' => array(
'file' => file_get_contents( $this->test_file_invalid_customer_acceptance ),
'name' => 'invalid-customer-acceptance.txt',
'size' => filesize( $this->test_file_invalid_customer_acceptance ),
'tmp_name' => $this->test_file_invalid_customer_acceptance,
),
) );
$request->set_header( 'Content-MD5', md5_file( $this->test_file_invalid_customer_acceptance ) );
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('error', $message['code']);
$this->assertEquals('INVALID_FILE_ACCEPTANCE', $message['message']);
}
/**
* @covers Wiass_REST_Delivery_Process_API::upload_file
*/
function test_upload_valid_customer_acceptance_file() {
wp_set_current_user(1);
$customer_acceptance_entry_id = self::create_pending_customer_acceptance_entry();
$request = new WP_REST_Request( 'POST', '/wiaas/customer-acceptance/' . $customer_acceptance_entry_id . '/upload-file' );
$request->set_file_params( array(
'file' => array(
'file' => file_get_contents( $this->test_file_valid_customer_acceptance ),
'name' => 'valid-customer-acceptance.odt',
'size' => filesize( $this->test_file_valid_customer_acceptance ),
'tmp_name' => $this->test_file_valid_customer_acceptance,
),
) );
$request->set_header( 'Content-MD5', md5_file( $this->test_file_valid_customer_acceptance ) );
$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);
$response_data = $response->get_data();
$this->assertArrayHasKey('messages', $response_data);
$this->assertArrayHasKey('data', $response_data);
$message = $response_data['messages'][0];
$this->assertArrayHasKey('code', $message);
$this->assertArrayHasKey('message', $message);
$this->assertEquals('success', $message['code']);
$this->assertEquals('FILE_UPLOADED', $message['message']);
}
public function tearDown() {
parent::tearDown();
if ( file_exists( $this->test_file_valid_customer_acceptance ) ) {
unlink( $this->test_file_valid_customer_acceptance );
}
if ( file_exists( $this->test_file_invalid_customer_acceptance ) ) {
unlink( $this->test_file_invalid_customer_acceptance );
}
$this->remove_added_uploads();
}
//===================================================================================
/**
* Helper function : creates customer acceptance entry
*/
private function create_pending_customer_acceptance_entry(){
$customer_acceptance_form_id = 1;
$customer_id_field_id = 2;
$actual_date_field_id = 6;
$acceptance_status_field_id = 8;
$expiration_date_field_id = 9;
$decline_reason_field_id = 10;
$files_uploaded_field_id = 12;
$input_values['input_' . $acceptance_status_field_id] = 'accept';
$input_values['input_' . $expiration_date_field_id] = "2020-01-01";
//$input_values['input_' . $files_uploaded_field_id] = json_encode(['http://path/to/file1.docx']);
GFAPI::submit_form($customer_acceptance_form_id, $input_values);
//this part is needed since form submit does not store files for some reason, probably files should be sent some other way
$entry = GFAPI::get_entries($customer_acceptance_form_id)[0];
$entry[$files_uploaded_field_id] = json_encode(['http://localhost/wp/index.php?gf-download=2018%2F08%2Ffile1.docx&form-id=1&field-id=12&hash=1be6c30f0eeff93563b352d15fe459d5ded12ee06c2c8f36fed66b42dedf2534']);
$entry['workflow_step'] = 1;
$entry['workflow_step_status_1'] = 'pending';
$entry['workflow_step_status_2'] = false;
$entry['workflow_timestamp'] = false;
$update = GFAPI::update_entry($entry);
return $entry['id'];
}
} }

View File

@@ -15,6 +15,8 @@ class Wiaas_Unit_Test_Case extends WP_UnitTestCase {
wiaas_db_update_setup_gravity(); wiaas_db_update_setup_gravity();
wiaas_db_update_enable_orders_access_management(); wiaas_db_update_enable_orders_access_management();
define('WP_TEST_IN_PROGRESS',true);
} }
function tearDown() { function tearDown() {

2
backend/composer.lock generated
View File

@@ -1,7 +1,7 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "302f569929ecdaf4d349b0bf764de74c", "content-hash": "302f569929ecdaf4d349b0bf764de74c",

View File

@@ -118,6 +118,7 @@ export const validateCredentials = (username, password) => {
// if(decodedAceessToken.data.wiaas_user_type === 'customer'){ // if(decodedAceessToken.data.wiaas_user_type === 'customer'){
localStorage.setItem('accessToken', response.data.token); localStorage.setItem('accessToken', response.data.token);
localStorage.setItem('username', username);
const serverTime = decodedAceessToken.nbf || 1; const serverTime = decodedAceessToken.nbf || 1;
// refreshToken = response.data.refreshToken; // refreshToken = response.data.refreshToken;
startRefreshTimer(dispatch, serverTime); startRefreshTimer(dispatch, serverTime);

View File

@@ -23,15 +23,12 @@ const recieveCustomerAcceptance = (json) => ({
customerAcceptance: json customerAcceptance: json
}); });
export const fetchCustomerAcceptance = (idOrder) => { export const fetchCustomerAcceptance = (idEntry) => {
return dispatch => { return dispatch => {
dispatch(requestCustomerAcceptance()); dispatch(requestCustomerAcceptance());
return htmlClient.fetch({ return htmlClient.fetch({
url: `${API_SERVER}/orders/api/getCustomerAcceptance`, url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}`,
method: 'post', method: 'get'
data: {
idOrder
}
}) })
.then(response => { .then(response => {
if (response.data) { if (response.data) {
@@ -48,18 +45,15 @@ const uploadAcceptanceAction = () => ({
type: UPLOAD_CUSTOMER_ACCEPTANCE type: UPLOAD_CUSTOMER_ACCEPTANCE
}); });
export const uploadAcceptance = (idOrder, file) => { export const uploadAcceptance = (idEntry, file) => {
return dispatch => { return dispatch => {
dispatch(uploadAcceptanceAction()); dispatch(uploadAcceptanceAction());
return htmlClient.uploadFile(file, { return htmlClient.uploadFile(file, {
url: `${API_SERVER}/orders/api/uploadAcceptanceDocument`, url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}/upload-file`
data: {
idOrder
}
}).then(response => { }).then(response => {
if (typeof response.data !== 'undefined' && 'messages' in response.data) { if (typeof response.data !== 'undefined') {
dispatch(updateMessages(response.data.messages, orderMessages)); dispatch(updateMessages(response.data.messages, orderMessages));
dispatch(fetchCustomerAcceptance(idOrder)); dispatch(fetchCustomerAcceptance(idEntry));
} }
}).catch(error => { }).catch(error => {
htmlClient.onError(error, dispatch); htmlClient.onError(error, dispatch);
@@ -77,14 +71,13 @@ const sendCustomerAcceptance = () => ({
type: SEND_CUSTOMER_ACCEPTANCE type: SEND_CUSTOMER_ACCEPTANCE
}); });
export const acceptDeclineInstallation = (idOrder, actionType, declineReason) => { export const acceptDeclineInstallation = (idEntry, actionType, declineReason) => {
return dispatch => { return dispatch => {
dispatch(sendCustomerAcceptance()); dispatch(sendCustomerAcceptance());
return htmlClient.fetch({ return htmlClient.fetch({
url: `${API_SERVER}/orders/api/acceptDeclineInstallation`, url: `${API_SERVER}/wp-json/wiaas/customer-acceptance/${idEntry}`,
method: 'post', method: 'post',
data: { data: {
idOrder,
actionType, actionType,
declineReason declineReason
} }
@@ -92,7 +85,7 @@ export const acceptDeclineInstallation = (idOrder, actionType, declineReason) =>
.then(response => { .then(response => {
if (response.data) { if (response.data) {
dispatch(updateMessages(response.data.messages, orderMessages)); dispatch(updateMessages(response.data.messages, orderMessages));
dispatch(fetchCustomerAcceptance(idOrder)); dispatch(fetchCustomerAcceptance(idEntry));
} }
}) })
.catch(error => { .catch(error => {

View File

@@ -25,6 +25,8 @@ import {
} from '../../constants/ordersConstants'; } from '../../constants/ordersConstants';
import HtmlClient from '../../helpers/HtmlClient'; import HtmlClient from '../../helpers/HtmlClient';
import { updateMessages } from '../notification/notificationActions'; import { updateMessages } from '../notification/notificationActions';
import { fromWCOrder } from '../../helpers/OrderHelper';
import moment from 'moment';
const htmlClient = new HtmlClient(); const htmlClient = new HtmlClient();
@@ -42,15 +44,12 @@ export const fetchOrderInfo = (idOrder) => {
return dispatch => { return dispatch => {
dispatch(requestOrderInfo()); dispatch(requestOrderInfo());
return htmlClient.fetch({ return htmlClient.fetch({
url: `${API_SERVER}/orders/api/getOrderInfo`, url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}`,
method: 'post', method: 'get'
data: {
idOrder
}
}) })
.then(response => { .then(response => {
if (response.data) { if (response.data) {
dispatch(recieveOrderInfo(response.data)); dispatch(recieveOrderInfo(fromWCOrder(response.data)));
} }
}) })
.catch(error => { .catch(error => {
@@ -63,22 +62,28 @@ const sendComment = () => ({
type: SEND_ORDER_COMMENT type: SEND_ORDER_COMMENT
}) })
export const addComment = (idOrder, comment) => { export const addComment = (idOrder, newComment) => {
return dispatch => { return dispatch => {
dispatch(sendComment()); dispatch(sendComment());
return htmlClient.fetch({ return htmlClient.fetch({
url: `${API_SERVER}/orders/api/addOrderComment`, url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}/notes`,
method: 'post', method: 'post',
data: { data: {
idOrder, note : newComment || 'Test comment',
comment customer_note: true,
} }
}) })
.then(response => { .then(response => {
if (response.data) {
dispatch(fetchOrderInfo(idOrder));
}
/*
if (response.data && response.data.messages) { if (response.data && response.data.messages) {
dispatch(updateMessages(response.data.messages, orderMessages)); dispatch(updateMessages(response.data.messages, orderMessages));
dispatch(fetchOrderInfo(idOrder)); dispatch(fetchOrderInfo(idOrder));
} }
*/
}) })
.catch(error => { .catch(error => {
htmlClient.onError(error, dispatch); htmlClient.onError(error, dispatch);

View File

@@ -50,13 +50,13 @@ export const orderMessages = {
SYSTEM_ALLOWED_LANGUAGES_EMPTY: 'There are no languages added in the system.', SYSTEM_ALLOWED_LANGUAGES_EMPTY: 'There are no languages added in the system.',
ALLOWED_LANGUAGE: 'Allowed languages are:', ALLOWED_LANGUAGE: 'Allowed languages are:',
ALLOWED_LANGUAGE_ERROR: 'There was an error while trying to detect the language:', ALLOWED_LANGUAGE_ERROR: 'There was an error while trying to detect the language:',
SERVER_ERROR: 'There seems to be a problem and the comment was not added!', ERROR_ADDING_COMMENT: 'There seems to be a problem and the comment was not added!',
ORDER_COMMENT_ADDED: 'Order comment updated!', ORDER_COMMENT_ADDED: 'Order comment updated!',
FILE_UPLOADED : 'File has been uploaded and needs to be validated!', FILE_UPLOADED : 'File has been uploaded and needs to be validated!',
NOT_UPLOADED : 'There seems to be a problem and the file was not uploaded!', NOT_UPLOADED : 'There seems to be a problem and the file was not uploaded!',
RE_UPLOAD_MAIL : 'Notify mail has been sent!', RE_UPLOAD_MAIL : 'Notify mail has been sent!',
ACCEPTANCE_NOT_UPDATED : 'Acceptance status not updated!', ACCEPTANCE_NOT_UPDATED : 'Acceptance status not updated!',
ACCEPTANCE_NOT_UPLOADED: 'You need to uploade the acceptance document before you can agree with the installation!', ACCEPTANCE_NOT_UPLOADED: 'You need to upload the acceptance document before you can agree with the installation!',
DECLINE_REASON_EMPTY : 'Please describe what is not to your satisfaction.', DECLINE_REASON_EMPTY : 'Please describe what is not to your satisfaction.',
INSTALLATION_DECLINED : 'The implementation is not satisfactory.', INSTALLATION_DECLINED : 'The implementation is not satisfactory.',
ERROR_MAIL_SENT : 'Notify mail was not sent!', ERROR_MAIL_SENT : 'Notify mail was not sent!',
@@ -81,7 +81,13 @@ export const orderMessages = {
EMPTY_VALUE: 'Field required: ', EMPTY_VALUE: 'Field required: ',
INSTALLATION_ACCEPTED: 'The implementation has been accepted!', INSTALLATION_ACCEPTED: 'The implementation has been accepted!',
ID_ORDER_NOT_SET: 'The id of the order is not set', ID_ORDER_NOT_SET: 'The id of the order is not set',
SUPPORT_MAIL_SENT: 'Support mail sent!' SUPPORT_MAIL_SENT: 'Support mail sent!',
NO_FILES_UPLOADED: 'You need to upload the acceptance document',
INTERNAL_SERVER_ERROR: 'Error occured. Please try again',
ACCEPTANCE_STATUS_MISSING: 'Acceptance action not selected',
ACCEPTANCE_STATUS_UPDATED: 'Acceptance status updated'
}; };
export const orderTexts = { export const orderTexts = {
@@ -161,7 +167,11 @@ export const orderTexts = {
INSTALLATION_DATE: 'Installation date', INSTALLATION_DATE: 'Installation date',
INSTALLATION_NOT_REQUIRED:'Installation is not required for this package', INSTALLATION_NOT_REQUIRED:'Installation is not required for this package',
PRELIMINARY_INSTALLATION_DATE_LABEL: 'Preliminary installation date', PRELIMINARY_INSTALLATION_DATE_LABEL: 'Preliminary installation date',
PROJECT: 'Project' PROJECT: 'Project',
BILLING_FIRST_NAME: 'Billing first name',
BILLING_LAST_NAME: 'Billing last name',
BILLING_MAIL: 'Invoice mail',
BILLING_ADDRESS: 'Billing address'
}, },
buttons: { buttons: {
ACCEPT_INSTALLATION: 'I agree', ACCEPT_INSTALLATION: 'I agree',

View File

@@ -44,7 +44,7 @@ class ProcessContainer extends Component {
componentDidMount() { componentDidMount() {
this.props.dispatch(fetchOrderInfo(this.props.idOrder)); this.props.dispatch(fetchOrderInfo(this.props.idOrder));
this.props.dispatch(getAllDataForInstallation(this.props.idOrder, usedForDirective, stepsNameForInstallation, fileType)); //this.props.dispatch(getAllDataForInstallation(this.props.idOrder, usedForDirective, stepsNameForInstallation, fileType));
const orderPackagePairs = []; const orderPackagePairs = [];
const isSchedulingDisabled = {}; const isSchedulingDisabled = {};
isSchedulingDisabled[this.props.idOrder] = true; isSchedulingDisabled[this.props.idOrder] = true;
@@ -52,7 +52,7 @@ class ProcessContainer extends Component {
if(this.props.orderInfo) { if(this.props.orderInfo) {
this.props.orderInfo.packages.forEach(orderPackage => { this.props.orderInfo.packages.forEach(orderPackage => {
orderPackagePairs.push(orderPackage.idOrder + '-' + orderPackage.idPackage); orderPackagePairs.push(this.props.orderInfo.id + '-' + orderPackage.id);
}); });
} }
this.setState({ this.setState({
@@ -71,11 +71,11 @@ class ProcessContainer extends Component {
if(installCompanies && isComponentDisabled && earliestInstallDate) { if(installCompanies && isComponentDisabled && earliestInstallDate) {
if(nextProps.orderInfo) { if(nextProps.orderInfo) {
const idOrder = nextProps.orderInfo.id;
nextProps.orderInfo.packages.forEach(orderPackage => { nextProps.orderInfo.packages.forEach(orderPackage => {
const idOrder = orderPackage && orderPackage.idOrder; const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.id : '';
const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.idPackage : '';
orderPackage.idOrderPackagePair = idOrderPackagePair; orderPackage.idOrderPackagePair = idOrderPackagePair;
areComponentsDisabled[idOrder] = this.checkIfComponentIsDisabled(orderPackage.idOrder, isComponentDisabled, earliestInstallDate); areComponentsDisabled[idOrder] = this.checkIfComponentIsDisabled(idOrder, isComponentDisabled, earliestInstallDate);
const availableCompanies = {}; const availableCompanies = {};
const selectedCompanies = {}; const selectedCompanies = {};
@@ -101,7 +101,7 @@ class ProcessContainer extends Component {
}); });
const isSchedulingDisabled = Object.assign({}, this.state.isSchedulingDisabled); const isSchedulingDisabled = Object.assign({}, this.state.isSchedulingDisabled);
isSchedulingDisabled[nextProps.orderInfo.info.id] = allPackagesScheduleInstallDisabled.every(isDisabled => {return isDisabled === true;}); isSchedulingDisabled[nextProps.orderInfo.id] = allPackagesScheduleInstallDisabled.every(isDisabled => {return isDisabled === true;});
this.setState({ this.setState({
isSchedulingDisabled, isSchedulingDisabled,
areComponentsDisabled, areComponentsDisabled,
@@ -126,16 +126,16 @@ class ProcessContainer extends Component {
return true; return true;
} }
calculatetTotalPrice(packages) { calculatetTotalPrice(packages, currency) {
let fixedPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageFixedPrice})); let fixedPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.price}));
let recurrentPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageRecuringPrice})); let recurrentPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.recurringPrice}));
let servicesPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageServicePrice})); let servicesPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.quantity * pkg.servicePrice}));
return { return {
fixedPrice, fixedPrice,
recurrentPrice: priceHelper.sumPrices([recurrentPrice, servicesPrice]), recurrentPrice: priceHelper.sumPrices([recurrentPrice, servicesPrice]),
periodUnit: packages[0].periodUnit, periodUnit: packages[0].periodUnit,
currency: packages[0].packageCurrency.currency currency: currency
} }
} }
@@ -158,15 +158,10 @@ class ProcessContainer extends Component {
if(this.state.packageNameFilter === 'all') { if(this.state.packageNameFilter === 'all') {
return true; return true;
}else{ }else{
return orderPackage.packageName === this.state.packageNameFilter; return orderPackage.name === this.state.packageNameFilter;
} }
} }
getProcess(process){
const processKeys = Object.keys(process) || [];
return processKeys.length > 0 ? process[processKeys[0]] : {};
}
getButtonClass() { getButtonClass() {
if(this.props.orderInfo) { if(this.props.orderInfo) {
return this.state.isSchedulingDisabled[this.props.orderInfo.id] ? 'schedule-inactive' : 'schedule-active'; return this.state.isSchedulingDisabled[this.props.orderInfo.id] ? 'schedule-inactive' : 'schedule-active';
@@ -187,18 +182,18 @@ class ProcessContainer extends Component {
</div> </div>
} }
{ {
(orderInfo && orderInfo.info && !isLoading) && (orderInfo && !isLoading) &&
<div> <div>
<WiaasBox <WiaasBox
customHeader={ProcessNavContainer} customHeader={ProcessNavContainer}
customHeaderParams={{ customHeaderParams={{
orderInfo: orderInfo.info, orderInfo: orderInfo,
packages: orderInfo.packages, packages: orderInfo.packages,
onViewChange: this.onViewChange, onViewChange: this.onViewChange,
getActiveView: this.getActiveView, getActiveView: this.getActiveView,
installationData: this.state installationData: this.state
}}> }}>
<OrderInfo totalPrice={this.calculatetTotalPrice(orderInfo.packages)} orderDetails={orderInfo} installationData={this.state}/> <OrderInfo totalPrice={this.calculatetTotalPrice(orderInfo.packages, orderInfo.currency)} orderDetails={orderInfo} installationData={this.state}/>
</WiaasBox> </WiaasBox>
{ {
this.state.activeView !== 'info' && this.state.activeView !== 'info' &&
@@ -211,7 +206,7 @@ class ProcessContainer extends Component {
<OrderProcess <OrderProcess
onViewChange={this.onViewChange} onViewChange={this.onViewChange}
orderStatus={orderInfo.status} orderStatus={orderInfo.status}
orderProcess={this.getProcess(orderInfo.process)}/> orderProcess={orderInfo.process}/>
} }
{ {
this.state.activeView === 'packages' && this.state.activeView === 'packages' &&
@@ -221,9 +216,10 @@ class ProcessContainer extends Component {
> >
{ {
orderInfo.packages.filter(this.filterPackages).map(orderPackage => orderInfo.packages.filter(this.filterPackages).map(orderPackage =>
<ProcessPackage key={orderPackage.idPackage} <ProcessPackage key={orderPackage.id}
onViewChange={this.onViewChange} onViewChange={this.onViewChange}
idCommercialLead={orderInfo.info.idCommercialLead} idCommercialLead={orderInfo.commercialLead.id}
currency={orderInfo.currency}
orderPackage={orderPackage}/> orderPackage={orderPackage}/>
) )
} }
@@ -231,18 +227,18 @@ class ProcessContainer extends Component {
} }
{ {
this.state.activeView === 'comments' && this.state.activeView === 'comments' &&
<OrderComments orderInfo={orderInfo.info} orderComments={orderInfo.orderComments} orderPackages={orderInfo.packages}/> <OrderComments orderInfo={orderInfo} orderComments={orderInfo.comments} orderPackages={orderInfo.packages}/>
} }
{ {
this.state.activeView === 'documents' && this.state.activeView === 'documents' &&
<OrderDocuments idOrder={orderInfo.info.id} /> <OrderDocuments idOrder={orderInfo.id} />
} }
</div> </div>
} }
{ {
(orderInfo && !orderInfo.info && !isLoading) && (!orderInfo && !isLoading) &&
<div className="no-rigths"> <div className="no-rigths">
{orderTexts.labels.NOT_AVAILABLE}! {orderTexts.labels.NOT_AVAILABLE}!
</div> </div>

View File

@@ -18,7 +18,7 @@ class OrderComments extends Component {
} }
addNewComment(){ addNewComment(){
this.props.dispatch(addComment(this.props.orderInfo.id, this.state.newComment)); this.props.dispatch(addComment(this.props.orderInfo.id, this.state.newComment, this.props.orderComments));
} }
onEditorChange(newComment){ onEditorChange(newComment){
@@ -26,11 +26,11 @@ class OrderComments extends Component {
} }
getOffset(isOwner){ getOffset(isOwner){
return isOwner ? 6 : 0; return (isOwner) ? 6 : 0;
} }
getClassByOwner(isOwner){ getClassByOwner(isOwner){
return isOwner ? 'mine' : ''; return (isOwner) ? 'mine' : '';
} }
render() { render() {
@@ -48,7 +48,7 @@ class OrderComments extends Component {
<Row key={'order-comment-' + index}> <Row key={'order-comment-' + index}>
<Col xl={{size:6, offset:this.getOffset(orderComment.isOwner)}}> <Col xl={{size:6, offset:this.getOffset(orderComment.isOwner)}}>
<div className={'order-comment ' + this.getClassByOwner(orderComment.isOwner)} key={'order-comment-' + index}> <div className={'order-comment ' + this.getClassByOwner(orderComment.isOwner)} key={'order-comment-' + index}>
<div className="order-comment-header">{orderComment.username} - {orderComment.addDate}</div> <div className="order-comment-header">{orderComment.username} - {orderComment.dateCreated}</div>
<div dangerouslySetInnerHTML={{__html: orderComment.comment}}></div> <div dangerouslySetInnerHTML={{__html: orderComment.comment}}></div>
</div> </div>
</Col> </Col>

View File

@@ -10,10 +10,10 @@ class OrderDocuments extends Component {
return ( return (
<div id="order-documents" className="order-documents"> <div id="order-documents" className="order-documents">
{ {
orderInfo.packages.map(orderPackage => <OrderDocumentsGroup key={'order-package-' + orderPackage.idPackage} documentsGroup={orderPackage} />) orderInfo.packages.map(orderPackage => <OrderDocumentsGroup key={'order-package-' + orderPackage.id} documentsGroup={orderPackage} />)
} }
{ {
orderInfo.orderDocuments && <OrderDocumentsGroup key={'order-package-0'} documentsGroup={{documents: orderInfo.orderDocuments, packageName: orderTexts.labels.OTHER_DOCS}} /> orderInfo.orderDocuments && <OrderDocumentsGroup key={'order-package-0'} documentsGroup={{documents: orderInfo.documents, packageName: orderTexts.labels.OTHER_DOCS}} />
} }
</div> </div>
); );

View File

@@ -57,6 +57,7 @@ class OrderDocumentsGroup extends Component {
return ( return (
<div> <div>
{ {
documentsGroup.documents &&
documentsGroup.documents.length > 0 && documentsGroup.documents.length > 0 &&
<WiaasBox mainTitle={documentsGroup.packageName}> <WiaasBox mainTitle={documentsGroup.packageName}>
{ {

View File

@@ -27,7 +27,7 @@ class OrderInfo extends Component {
setInstallationData(props) { setInstallationData(props) {
const acceptedDate = {}; const acceptedDate = {};
const proposedDate = {}; const proposedDate = {};
const idOrder = props.orderDetails.info.id; const idOrder = props.orderDetails.id;
const {isInstallationInPackage} = props.installationData; const {isInstallationInPackage} = props.installationData;
const {confirmationDates, areAllShippingDatesConfirmed} = props; const {confirmationDates, areAllShippingDatesConfirmed} = props;
const isPreliminaryInstallationDate = areAllShippingDatesConfirmed && idOrder in areAllShippingDatesConfirmed ? !areAllShippingDatesConfirmed[idOrder] : true; const isPreliminaryInstallationDate = areAllShippingDatesConfirmed && idOrder in areAllShippingDatesConfirmed ? !areAllShippingDatesConfirmed[idOrder] : true;
@@ -53,18 +53,28 @@ class OrderInfo extends Component {
const {acceptedDate, proposedDate, isPreliminaryInstallationDate, isInstallationInOrder} = this.state; const {acceptedDate, proposedDate, isPreliminaryInstallationDate, isInstallationInOrder} = this.state;
const orderPackages = installationData.packages; const orderPackages = installationData.packages;
const isInstallationInPackage = installationData.isInstallationInPackage; const isInstallationInPackage = installationData.isInstallationInPackage;
const orderInfo = this.props.orderInfo.info; const orderInfo = this.props.orderInfo;
return ( return (
<Container fluid={true} id="order-info-description"> <Container fluid={true} id="order-info-description">
<Row> <Row>
<Col xl="2"> <Col xl="2">
<div className="subtitle"><h6>{orderTexts.labels.ORDER_DATE}:</h6></div> <div className="subtitle"><h6>{orderTexts.labels.ORDER_DATE}:</h6></div>
<span>{orderInfo.orderDate}</span> <span>{orderInfo.dateCreated}</span>
<div className="subtitle"><h6>{orderTexts.labels.SOLD_BY}:</h6></div> <div className="subtitle"><h6>{orderTexts.labels.SOLD_BY}:</h6></div>
<span>{orderInfo.commercialLead}</span> <span>{orderInfo.commercialLead.name}</span>
</Col> </Col>
<Col xl="2">
<div className="subtitle"><h6>{orderTexts.labels.BILLING_FIRST_NAME}:</h6></div>
<span>{orderInfo.billing.firstName || '-'}</span>
<div className="subtitle"><h6>{orderTexts.labels.BILLING_LAST_NAME}:</h6></div>
<span>{orderInfo.billing.lastName || '-'}</span>
<div className="subtitle"><h6>{orderTexts.labels.BILLING_MAIL}:</h6></div>
<span>{orderInfo.billing.email || '-'}</span>
<div className="subtitle"><h6>{orderTexts.labels.BILLING_ADDRESS}:</h6></div>
<span>{orderInfo.billing.address || '-'}</span>
</Col>
<Col xl="2"> <Col xl="2">
<div> <div>
<div className="subtitle"><h6>{orderTexts.labels.REFERENCE}:</h6></div> <div className="subtitle"><h6>{orderTexts.labels.REFERENCE}:</h6></div>

View File

@@ -21,9 +21,9 @@ class PackageNav extends Component {
<div className={this.getClass('all')} onClick={()=>{onPackageFilter('all')}}>{orderTexts.buttons.ALL}</div> <div className={this.getClass('all')} onClick={()=>{onPackageFilter('all')}}>{orderTexts.buttons.ALL}</div>
{ {
packages.length > 0 && packages.length > 0 &&
packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.idPackage} packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.id}
onClick={()=>{onPackageFilter(orderPackage.packageName)}} onClick={()=>{onPackageFilter(orderPackage.name)}}
className={this.getClass(orderPackage.packageName)}>{orderPackage.packageName}</div>) className={this.getClass(orderPackage.name)}>{orderPackage.name}</div>)
} }
</Col> </Col>

View File

@@ -29,8 +29,8 @@ class PackageInfo extends Component {
} }
render() { render() {
const {orderPackage, onViewChange} = this.props; const {orderPackage, currency, onViewChange} = this.props;
const shouldShowPriceInfo = orderPackage.packageRecuringPrice > 0 || orderPackage.packageServicePrice > 0; const shouldShowPriceInfo = orderPackage.recurringPrice > 0 || orderPackage.servicePrice > 0;
return ( return (
<Container fluid={true} id="package-info" className="order-package-info"> <Container fluid={true} id="package-info" className="order-package-info">
@@ -41,7 +41,7 @@ class PackageInfo extends Component {
{orderTexts.labels.PACKAGE_PRICE}: {' '} {orderTexts.labels.PACKAGE_PRICE}: {' '}
{ shouldShowPriceInfo && { shouldShowPriceInfo &&
<i className="price-info-btn fa fa-info-circle" <i className="price-info-btn fa fa-info-circle"
id={'price-info-' + orderPackage.idPackage} id={'price-info-' + orderPackage.id}
onClick={this.toggle}></i> onClick={this.toggle}></i>
} }
</h6> </h6>
@@ -49,43 +49,43 @@ class PackageInfo extends Component {
</div> </div>
<div> <div>
{orderTexts.labels.TOTAL_DELVIERY_PRICE}: {' '} {orderTexts.labels.TOTAL_DELVIERY_PRICE}: {' '}
{(orderPackage.units * orderPackage.packageFixedPrice).toLocaleString() + ' ' + orderPackage.packageCurrency.currency} {(orderPackage.quantity * orderPackage.price).toLocaleString() + ' ' + currency}
</div> </div>
{ {
shouldShowPriceInfo && shouldShowPriceInfo &&
<div> <div>
{orderTexts.labels.TOTAL_RECURRENT_PRICE}:{' '} {orderTexts.labels.TOTAL_RECURRENT_PRICE}:{' '}
{(orderPackage.units * (orderPackage.packageRecuringPrice + orderPackage.packageServicePrice)).toLocaleString()} {orderPackage.packageCurrency.currency} {(orderPackage.quantity * (orderPackage.recurringPrice + orderPackage.servicePrice)).toLocaleString()} {currency}
</div> </div>
} }
{ shouldShowPriceInfo && { shouldShowPriceInfo &&
<Popover placement="bottom" <Popover placement="bottom"
isOpen={this.state.popoverOpen} isOpen={this.state.popoverOpen}
target={'price-info-' + orderPackage.idPackage} target={'price-info-' + orderPackage.id}
container={'price-info-' + orderPackage.idPackage} container={'price-info-' + orderPackage.id}
className="price-info-popover" className="price-info-popover"
toggle={this.toggle}> toggle={this.toggle}>
<PopoverHeader>{orderPackage.paymentType}</PopoverHeader> <PopoverHeader>{orderPackage.paymentType}</PopoverHeader>
<PopoverBody> <PopoverBody>
<div> <div>
{ orderPackage.packageRecuringPrice > 0 && { orderPackage.recurringPrice > 0 &&
<div className="package-price-recurrent"> <div className="package-price-recurrent">
<span className="price-info-title">{orderTexts.labels.RECURRENT_PRICE}: </span> <span className="price-info-title">{orderTexts.labels.RECURRENT_PRICE}: </span>
{(orderPackage.units * orderPackage.packageRecuringPrice).toLocaleString()} {orderPackage.packageCurrency.currency} / {orderPackage.periodUnit} {(orderPackage.quantity * orderPackage.recurringPrice).toLocaleString()} {currency} / {orderPackage.periodUnit}
{ {
orderPackage.packagePayPeriod > 0 && orderPackage.packagePayPeriod > 0 &&
<span> <span>
for {orderPackage.packagePayPeriod} {orderPackage.periodUnit} for {orderPackage.payPeriod} {orderPackage.periodUnit}
</span> </span>
} }
</div> </div>
} }
{ orderPackage.packageServicePrice > 0 && { orderPackage.servicePrice > 0 &&
<div className="services-price-recurrent"> <div className="services-price-recurrent">
<span className="price-info-title">{orderTexts.labels.SERVICES_PRICE}: </span> <span className="price-info-title">{orderTexts.labels.SERVICES_PRICE}: </span>
{(orderPackage.units * orderPackage.packageServicePrice).toLocaleString()} {orderPackage.packageCurrency.currency} / {orderPackage.periodUnit} {(orderPackage.quantity * orderPackage.servicePrice).toLocaleString()} {currency} / {orderPackage.periodUnit}
{ {
orderPackage.servicesContractPeriod > 0 && orderPackage.servicesContractPeriod > 0 &&
<span> <span>
@@ -101,7 +101,7 @@ class PackageInfo extends Component {
} }
</Col> </Col>
{ {
orderPackage.options.length > 0 && orderPackage.options && orderPackage.options.length > 0 &&
<Col xl="3"> <Col xl="3">
<div className="subtitle"><h6>{orderTexts.labels.OPTIONS}:</h6></div> <div className="subtitle"><h6>{orderTexts.labels.OPTIONS}:</h6></div>
{ {
@@ -112,7 +112,7 @@ class PackageInfo extends Component {
</Col> </Col>
} }
{ {
orderPackage.additionalPackages.length > 0 && orderPackage.additionalPackages && orderPackage.additionalPackages.length > 0 &&
<Col xl="3"> <Col xl="3">
<div className="subtitle"><h6>{orderTexts.labels.ADDITIONAL_PACKAGES}:</h6></div> <div className="subtitle"><h6>{orderTexts.labels.ADDITIONAL_PACKAGES}:</h6></div>
{ {

View File

@@ -7,7 +7,7 @@ class PackageName extends Component {
return ( return (
<div> <div>
<Link to={'/co-market/' + idCommercialLead + '/' + orderPackage.idPackage } className="package-name-link">{orderPackage.units + ' x ' + orderPackage.packageName}</Link> <Link to={'/co-market/' + idCommercialLead + '/' + orderPackage.id } className="package-name-link">{orderPackage.quantity + ' x ' + orderPackage.name}</Link>
</div> </div>
); );
} }

View File

@@ -6,13 +6,13 @@ import PackageName from './PackageName.jsx';
class ProcessPackage extends Component { class ProcessPackage extends Component {
render() { render() {
const {orderPackage, idCommercialLead} = this.props; const {orderPackage, currency, idCommercialLead} = this.props;
return ( return (
<WiaasBox customHeader={PackageName} customHeaderParams={{orderPackage, idCommercialLead}} className="order-package"> <WiaasBox customHeader={PackageName} customHeaderParams={{orderPackage, idCommercialLead}} className="order-package">
<Row> <Row>
<Col xl="12" lg="12" md="12" xs="12"> <Col xl="12" lg="12" md="12" xs="12">
<PackageInfo onViewChange={this.props.onViewChange} orderPackage={orderPackage}/> <PackageInfo onViewChange={this.props.onViewChange} orderPackage={orderPackage} currency={currency}/>
</Col> </Col>
</Row> </Row>
</WiaasBox> </WiaasBox>

View File

@@ -5,7 +5,6 @@ import {Row, Col, Button} from 'reactstrap';
import {fetchCustomerAcceptance, uploadAcceptance, acceptDeclineInstallation, badFile} from '../../../../actions/orders/customerAcceptanceActions'; import {fetchCustomerAcceptance, uploadAcceptance, acceptDeclineInstallation, badFile} from '../../../../actions/orders/customerAcceptanceActions';
import {setDialogContent, setDialogOpenFlag} from '../../../../actions/dialog/dialogActions'; import {setDialogContent, setDialogOpenFlag} from '../../../../actions/dialog/dialogActions';
import AcceptanceDeclineReason from './AcceptanceDeclineReason.jsx'; import AcceptanceDeclineReason from './AcceptanceDeclineReason.jsx';
import {API_SERVER} from '../../../../config';
import FileDownloader from '../../../../helpers/FileDownloader'; import FileDownloader from '../../../../helpers/FileDownloader';
import {orderTexts} from '../../../../constants/ordersConstants'; import {orderTexts} from '../../../../constants/ordersConstants';
import '../../style/CustomerAcceptance.css'; import '../../style/CustomerAcceptance.css';
@@ -26,15 +25,16 @@ class CustomerAcceptance extends Component {
} }
downloadDocument(document){ downloadDocument(document){
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}` //const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
const fileName = document.documentName + '.' + document.extension; const fileUrl = document.url;
const fileName = document.name + '.' + document.extension;
fileHandler.download(fileUrl, fileName); fileHandler.download(fileUrl, fileName);
} }
uploadFile(idOrder, acceptedFiles, rejectedFiles) { uploadFile(idEntry, acceptedFiles, rejectedFiles) {
if(acceptedFiles && acceptedFiles.length){ if(acceptedFiles && acceptedFiles.length){
const file = acceptedFiles[0]; const file = acceptedFiles[0];
this.props.dispatch(uploadAcceptance(idOrder, file)); this.props.dispatch(uploadAcceptance(idEntry, file));
} }
if(rejectedFiles && rejectedFiles.length) { if(rejectedFiles && rejectedFiles.length) {
@@ -59,9 +59,9 @@ class CustomerAcceptance extends Component {
} }
acceptDeclineInstallation() { acceptDeclineInstallation() {
const {idOrder} = this.props.step; const {idProcess} = this.props.step;
const {actionType, reason} = this.state; const {actionType, reason} = this.state;
this.props.dispatch(acceptDeclineInstallation(idOrder, actionType, reason)); this.props.dispatch(acceptDeclineInstallation(idProcess, actionType, reason));
this.setState({reason: ''}); this.setState({reason: ''});
} }
@@ -72,7 +72,7 @@ class CustomerAcceptance extends Component {
'-1' : orderTexts.labels.DECLINED '-1' : orderTexts.labels.DECLINED
} }
return messages[customerAcceptance.customerAccepted]; return messages[customerAcceptance.status];
} }
onEditorChange(reason) { onEditorChange(reason) {
@@ -107,8 +107,8 @@ class CustomerAcceptance extends Component {
} }
componentDidMount(){ componentDidMount(){
const {idOrder} = this.props.step; const {idProcess} = this.props.step;
this.props.dispatch(fetchCustomerAcceptance(idOrder)); this.props.dispatch(fetchCustomerAcceptance(idProcess));
} }
render() { render() {
@@ -121,14 +121,14 @@ class CustomerAcceptance extends Component {
customerAcceptance && customerAcceptance &&
<Row> <Row>
<Col className="aceeptance-message"> <Col className="aceeptance-message">
{this.getAcceptanceMessage(customerAcceptance)} <div className={'status-icon ' + this.getAcceptanceStatusClass(customerAcceptance.customerAccepted, customerAcceptance.daysDiff)}></div> {this.getAcceptanceMessage(customerAcceptance)} <div className={'status-icon ' + this.getAcceptanceStatusClass(customerAcceptance.status, customerAcceptance.daysDiff)}></div>
</Col> </Col>
</Row> </Row>
} }
{ {
(customerAcceptance && customerAcceptance.customerAccepted === -1) && (customerAcceptance && customerAcceptance.status === -1) &&
<Row> <Row>
<Col>{orderTexts.labels.REASON}: {customerAcceptance.customerDeclineReason}</Col> <Col>{orderTexts.labels.REASON}: {customerAcceptance.decline_reason}</Col>
</Row> </Row>
} }
<Row className="acceptance-docs"> <Row className="acceptance-docs">
@@ -137,19 +137,18 @@ class CustomerAcceptance extends Component {
multiple={false} multiple={false}
accept=".pdf,.docx,.doc,.xlsx,.xls,.odt,.ods,.jpg,.png,.jpeg" accept=".pdf,.docx,.doc,.xlsx,.xls,.odt,.ods,.jpg,.png,.jpeg"
activeClassName="upload-file-accept" activeClassName="upload-file-accept"
onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(step.idOrder, acceptedFiles, rejectedFiles)}}> onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(step.idProcess, acceptedFiles, rejectedFiles)}}>
<h5 className="drop-zone-text">{orderTexts.labels.UPLOAD_ACCEPTANCE_LABEL}</h5> <h5 className="drop-zone-text">{orderTexts.labels.UPLOAD_ACCEPTANCE_LABEL}</h5>
</Dropzone> </Dropzone>
</Col> </Col>
<Col xl="4" lg="7" md="8"> <Col xl="4" lg="7" md="8">
{ {
(customerAcceptance && customerAcceptance.acceptanceDocuments && customerAcceptance.acceptanceDocuments.length > 0) && (customerAcceptance && customerAcceptance.documents && customerAcceptance.documents.length > 0) &&
<div> <div>
{ {
customerAcceptance.acceptanceDocuments.map(document => <div key={'acceptance-documnet-' + document.idDocument}> customerAcceptance.documents.map((document, index) => <div key={'acceptance-documnet-' + index}>
<span className="document-link" <span className="document-link">
onClick={() => {this.downloadDocument(document)}}> <i className={'fa fa-file'}></i> <a target="_blank" href={document.url}> {document.name} ({document.extension}) </a>
<i className={'fa fa-file'}></i> {document.documentName} ({document.extension})
</span> </span>
<span className="document-status"> <span className="document-status">
{document.validation} <div className={'status-icon ' + document.validation}></div> {document.validation} <div className={'status-icon ' + document.validation}></div>
@@ -159,7 +158,7 @@ class CustomerAcceptance extends Component {
</div> </div>
} }
{ {
(customerAcceptance && !customerAcceptance.acceptanceDocuments) && (customerAcceptance && (!customerAcceptance.documents || customerAcceptance.documents.length === 0) ) &&
<div> <div>
{orderTexts.labels.NO_DOCUMENTS_UPLOADED} {orderTexts.labels.NO_DOCUMENTS_UPLOADED}
</div> </div>

View File

@@ -7,7 +7,7 @@ const completedOrdersStatuses = ['production', 'end-of-life'];
class OrderProcess extends Component { class OrderProcess extends Component {
isStepVisible(step) { isStepVisible(step) {
return (step.status === 'in-progress' || step.status === 'done') && step.isVisibleForCustomer === 1; return (step.status === 'pending' || step.status === 'complete') && step.isVisibleForCustomer === 1;
} }
render() { render() {
@@ -41,7 +41,7 @@ class OrderProcess extends Component {
<Row> <Row>
<Col xl="12" lg="12" md="12" xs="12" className="order-package-process"> <Col xl="12" lg="12" md="12" xs="12" className="order-package-process">
{ {
visibleSteps.map((step, index) => <ProcessStep isStepVisible={this.isStepVisible} stepNumber={visibleSteps.length - index} step={step} key={'step-' + step.idProcess + '-' + step.idProcessStep}/>) visibleSteps.reverse().map((step, index) => <ProcessStep isStepVisible={this.isStepVisible} stepNumber={visibleSteps.length - index} step={step} key={'step-' + step.idProcess + '-' + step.idProcessStep}/>)
} }
</Col> </Col>
</Row> </Row>

View File

@@ -11,7 +11,7 @@ const stepActions = {
class OrderStep extends Component { class OrderStep extends Component {
isActiveStep(status) { isActiveStep(status) {
return status === 'in-progress' ; return status === 'pending' ;
} }
getStepTitle(step, stepNumber) { getStepTitle(step, stepNumber) {

View File

@@ -8,8 +8,8 @@ class ValidateQuestionnaire extends Component {
componentDidMount(){ componentDidMount(){
const {idOrder, idProcessStep} = this.props.step; const {idOrder, idProcessStep} = this.props.step;
this.props.dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire')); //this.props.dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire'));
this.props.dispatch(fetchValidationComments(idOrder, idProcessStep, 'invalidQuestionnaireComment')); //this.props.dispatch(fetchValidationComments(idOrder, idProcessStep, 'invalidQuestionnaireComment'));
} }
findById(orderPackage, idOrderPackagePair){ findById(orderPackage, idOrderPackagePair){

View File

@@ -26,6 +26,7 @@ $link-line-height: 1.5rem;
.completed { .completed {
border-left: $border-width $production-status-color solid; border-left: $border-width $production-status-color solid;
background: $production-status-color;
} }
.end-of-life { .end-of-life {
@@ -131,7 +132,7 @@ $link-line-height: 1.5rem;
background: $canceled-status-color; background: $canceled-status-color;
} }
.production { .completed {
background: $production-status-color; background: $production-status-color;
} }
@@ -139,11 +140,15 @@ $link-line-height: 1.5rem;
background: $open-status-color; background: $open-status-color;
} }
.done { .complete {
background: $done-status-color; background: $done-status-color;
} }
.in-progress { .processing {
background: $in-progress-status-color;
}
.pending {
background: $in-progress-status-color; background: $in-progress-status-color;
} }

View File

@@ -45,11 +45,14 @@ class HtmlClient {
uploadFile(file, configParams = null) { uploadFile(file, configParams = null) {
let formData = new FormData(); let formData = new FormData();
formData.append('file', file, file.name); formData.append('file', file, file.name);
/*
if(configParams) { if(configParams) {
Object.keys(configParams.data).forEach((paramKey) => { Object.keys(configParams.data).forEach((paramKey) => {
formData.append(paramKey, configParams.data[paramKey]); formData.append(paramKey, configParams.data[paramKey]);
}); });
}
}*/
configParams.data = formData; configParams.data = formData;
const params = Object.assign({}, uploadParams(), configParams); const params = Object.assign({}, uploadParams(), configParams);

View File

@@ -1,4 +1,5 @@
import moment from 'moment'; import moment from 'moment';
import {fromWiaasProcessStep} from './ProcessHelper';
function formatDate(date) { function formatDate(date) {
return date ? moment(date).format("Do MMM, YYYY") : undefined; return date ? moment(date).format("Do MMM, YYYY") : undefined;
@@ -9,6 +10,10 @@ function formatAddress(addressObject) {
} }
export const fromWCOrder = (WCOrder) => { export const fromWCOrder = (WCOrder) => {
let processInfo = Object.assign({},WCOrder['delivery-process']);
if (WCOrder['delivery-process']){
processInfo.steps = WCOrder['delivery-process'].steps.map(step=>fromWiaasProcessStep(step));
}
return { return {
id: WCOrder.id, id: WCOrder.id,
number: WCOrder.number, number: WCOrder.number,
@@ -22,6 +27,12 @@ export const fromWCOrder = (WCOrder) => {
recurringPrice: 0, recurringPrice: 0,
status: WCOrder.status, status: WCOrder.status,
currency: WCOrder.currency, currency: WCOrder.currency,
billing:{
firstName: WCOrder.billing.first_name,
lastName: WCOrder.billing.last_name,
email: WCOrder.billing.email,
address: formatAddress(WCOrder.billing)
},
packages: WCOrder['line_items'].map(packageLine => { packages: WCOrder['line_items'].map(packageLine => {
return { return {
id: packageLine['product_id'], id: packageLine['product_id'],
@@ -40,6 +51,14 @@ export const fromWCOrder = (WCOrder) => {
dateCompleted: formatDate(packageLine['date_completed']), dateCompleted: formatDate(packageLine['date_completed']),
}; };
}), }),
process: processInfo,
comments: WCOrder.comments ? WCOrder.comments.map(comment => ({
id: comment.id,
comment: comment.content,
username: comment.username,
dateCreated: formatDate(comment.date),
isOwner: comment['is_owner']
})) : [],
deliveryAddress: formatAddress(WCOrder.shipping), deliveryAddress: formatAddress(WCOrder.shipping),
customer: WCOrder.customer, customer: WCOrder.customer,
commercialLead: WCOrder['commercial_lead'] commercialLead: WCOrder['commercial_lead']

View File

@@ -0,0 +1,19 @@
import moment from "moment";
export const fromWiaasProcessStep = (step) => {
return {
actionCode: step.action_code,
actualDate: step.actual_date,
comments: step.comments,
fullDesc: step.full_desc,
idOrder: step.order_id,
idProcess: step.step_form_entry_id, //not sure about this
idProcessStep: step.step_id, //not sure about this
isNewCommentVisible: 1, //TODO : get this from backend
isVisibleForCustomer: 1, //TODO : get this from backend
now: moment().format("Do MMM YY"),
shortDesc: step.short_desc,
status: step.status,
stepType: step.step_type,
}
};