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
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.
*
@@ -14,8 +32,25 @@ class Wiass_REST_Delivery_Process_API {
'methods' => 'GET',
'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() {
$current_user = wp_get_current_user();
@@ -62,4 +97,207 @@ class Wiass_REST_Delivery_Process_API {
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,8 +23,33 @@ class Wiaas_Delivery_Process {
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_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'];
}
/**
* Registers our Delivery Process Step Type as available Gravity Flow Step Type
*/
@@ -34,6 +59,29 @@ class Wiaas_Delivery_Process {
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
*
@@ -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;
}

View File

@@ -18,8 +18,19 @@ class Wiaas_Order {
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_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;
}
/**
* Assignees order to corresponding user organization when order is created.
*
@@ -94,6 +105,8 @@ class Wiaas_Order {
$data = self::_append_commercial_lead_info($data, $order, $request);
$data = self::_append_wiaas_order_details($data, $order, $request);
$data = self::_append_order_comments($data, $order, $request);
$response->set_data($data);
@@ -126,6 +139,7 @@ class Wiaas_Order {
private static function _append_commercial_lead_info($data, $order, $request) {
$data['commercial_lead'] = array(
'id' => 1,
'name' => 'Coor Service Management',
'phone' => '123456789',
'email' => 'rikard@co-ideation.com'
@@ -228,6 +242,34 @@ class Wiaas_Order {
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;
}
}
Wiaas_Order::init();

View File

@@ -1,387 +1,524 @@
{
"0": {
"title": "DELIVERY ACTION TYPE: Customer acceptance",
"description": "The customer must accept the implementation before further actions can be taken. If the customer isn't satisfied, the problems or discrepancies must be fixed in order to gen an acceptance.",
"labelPlacement": "top_label",
"descriptionPlacement": "below",
"button": {
"type": "text",
"text": "Submit",
"imageUrl": ""
},
"fields": [
{
"type": "workflow_user",
"id": 2,
"label": "customer-id",
"adminLabel": "customer-id",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "administrative",
"inputs": null,
"choices": [
],
"formId": 10,
"description": "",
"allowsPrepopulate": true,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "customer-id",
"noDuplicates": false,
"defaultValue": "",
"conditionalLogic": "",
"failed_validation": "",
"productField": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": "",
"enablePrice": "",
"gravityflowUsersRoleFilter": ""
},
{
"type": "date",
"id": 6,
"label": "Actual date",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"dateType": "datepicker",
"calendarIconType": "none",
"formId": 10,
"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": "fileupload",
"id": 7,
"label": "Acceptance document",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"formId": 10,
"description": "Upload your acceptance document",
"allowsPrepopulate": false,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"choices": "",
"conditionalLogic": "",
"maxFileSize": "",
"maxFiles": "",
"multipleFiles": false,
"allowedExtensions": "",
"productField": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": ""
}
],
"version": "2.3.2",
"id": 10,
"useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false,
"postTitleTemplate": "",
"postContentTemplate": "",
"lastPageButton": null,
"pagination": null,
"firstPageCssClass": null,
"confirmations": [
{
"id": "5b5f75f7494b7",
"name": "Default Confirmation",
"isDefault": true,
"type": "message",
"message": "Thanks for contacting us! We will get in touch with you shortly.",
"url": "",
"pageId": "",
"queryString": ""
}
],
"notifications": [
{
"id": "5b5f75f748cee",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"feeds": {
"gravityflow": [
{
"id": "22",
"form_id": "10",
"is_active": "1",
"feed_order": "0",
"meta": {
"step_name": "Upload acceptance file",
"description": "",
"step_type": "user_input",
"step_highlight": "0",
"step_highlight_type": "color",
"step_highlight_color": "#dd3333",
"feed_condition_conditional_logic": "0",
"feed_condition_conditional_logic_object": [],
"scheduled": "0",
"schedule_type": "delay",
"schedule_date": "",
"schedule_delay_offset": "",
"schedule_delay_unit": "hours",
"schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after",
"type": "select",
"assignees": [
"role|administrator",
"assignee_user_field|2"
],
"editable_fields": [
"5"
],
"routing": "",
"assignee_policy": "any",
"highlight_editable_fields_enabled": "0",
"highlight_editable_fields_class": "green-triangle",
"instructionsEnable": "0",
"instructionsValue": "",
"display_fields_mode": "selected_fields",
"display_fields_selected": [
"5"
],
"default_status": "hidden",
"note_mode": "not_required",
"assignee_notification_enabled": "0",
"assignee_notification_from_name": "",
"assignee_notification_from_email": "{admin_email}",
"assignee_notification_reply_to": "",
"assignee_notification_bcc": "",
"assignee_notification_subject": "Upload order acceptance file",
"assignee_notification_message": "A new entry requires your input.",
"assignee_notification_disable_autoformat": "0",
"resend_assignee_emailEnable": "0",
"resend_assignee_emailValue": "7",
"resend_assignee_email_repeatEnable": "0",
"resend_assignee_email_repeatValue": "3",
"in_progress_notification_enabled": "0",
"in_progress_notification_type": "select",
"in_progress_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"in_progress_notification_from_name": "",
"in_progress_notification_from_email": "{admin_email}",
"in_progress_notification_reply_to": "",
"in_progress_notification_bcc": "",
"in_progress_notification_subject": "",
"in_progress_notification_message": "Entry {entry_id} has been updated and remains in progress.",
"in_progress_notification_disable_autoformat": "0",
"complete_notification_enabled": "0",
"complete_notification_type": "select",
"complete_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"complete_notification_from_name": "",
"complete_notification_from_email": "{admin_email}",
"complete_notification_reply_to": "",
"complete_notification_bcc": "",
"complete_notification_subject": "",
"complete_notification_message": "Entry {entry_id} has been updated completing the step.",
"complete_notification_disable_autoformat": "0",
"confirmation_messageEnable": "0",
"confirmation_messageValue": "Thank you.",
"expiration": "0",
"expiration_type": "delay",
"expiration_date": "",
"expiration_delay_offset": "7",
"expiration_delay_unit": "days",
"expiration_date_field_offset": "0",
"expiration_date_field_offset_unit": "hours",
"expiration_date_field_before_after": "after",
"status_expiration": "expired",
"destination_expired": "next",
"destination_complete": "next"
},
"addon_slug": "gravityflow",
"event_type": null
"0": {
"title": "DELIVERY ACTION TYPE: Customer acceptance",
"description": "The customer must accept the implementation before further actions can be taken. If the customer isn't satisfied, the problems or discrepancies must be fixed in order to gen an acceptance.",
"labelPlacement": "top_label",
"descriptionPlacement": "below",
"button": {
"type": "text",
"text": "Submit",
"imageUrl": ""
},
{
"id": "30",
"form_id": "10",
"is_active": "1",
"feed_order": "0",
"meta": {
"step_name": "Approve customer acceptance",
"description": "",
"step_type": "approval",
"step_highlight": "0",
"step_highlight_type": "color",
"step_highlight_color": "#dd3333",
"feed_condition_conditional_logic": "0",
"feed_condition_conditional_logic_object": [],
"scheduled": "0",
"schedule_type": "delay",
"schedule_date": "",
"schedule_delay_offset": "",
"schedule_delay_unit": "hours",
"schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after",
"type": "select",
"assignees": [
"role|administrator"
],
"routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"assignee_policy": "any",
"instructionsEnable": "0",
"instructionsValue": "Instructions: please review the values in the fields below and click on the Approve or Reject button",
"display_fields_mode": "all_fields",
"assignee_notification_enabled": "0",
"assignee_notification_from_name": "",
"assignee_notification_from_email": "{admin_email}",
"assignee_notification_reply_to": "",
"assignee_notification_bcc": "",
"assignee_notification_subject": "",
"assignee_notification_message": "A new entry is pending your approval. Please check your Workflow Inbox.",
"assignee_notification_disable_autoformat": "0",
"resend_assignee_emailEnable": "0",
"resend_assignee_emailValue": "7",
"resend_assignee_email_repeatEnable": "0",
"resend_assignee_email_repeatValue": "3",
"rejection_notification_enabled": "0",
"rejection_notification_type": "select",
"rejection_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"rejection_notification_from_name": "",
"rejection_notification_from_email": "{admin_email}",
"rejection_notification_reply_to": "",
"rejection_notification_bcc": "",
"rejection_notification_subject": "",
"rejection_notification_message": "Entry {entry_id} has been rejected",
"rejection_notification_disable_autoformat": "0",
"approval_notification_enabled": "0",
"approval_notification_type": "select",
"approval_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"approval_notification_from_name": "",
"approval_notification_from_email": "{admin_email}",
"approval_notification_reply_to": "",
"approval_notification_bcc": "",
"approval_notification_subject": "",
"approval_notification_message": "Entry {entry_id} has been approved",
"approval_notification_disable_autoformat": "0",
"revertEnable": "0",
"revertValue": "22",
"note_mode": "not_required",
"expiration": "0",
"expiration_type": "delay",
"expiration_date": "",
"expiration_delay_offset": "",
"expiration_delay_unit": "hours",
"expiration_date_field_offset": "0",
"expiration_date_field_offset_unit": "hours",
"expiration_date_field_before_after": "after",
"status_expiration": "rejected",
"destination_expired": "next",
"destination_rejected": "22",
"destination_approved": "next"
},
"addon_slug": "gravityflow",
"event_type": null
"fields": [
{
"type": "workflow_user",
"id": 2,
"label": "customer-id",
"adminLabel": "customer-id",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "administrative",
"inputs": null,
"choices": [
],
"formId": 1,
"description": "",
"allowsPrepopulate": true,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "customer-id",
"noDuplicates": false,
"defaultValue": "",
"conditionalLogic": "",
"failed_validation": "",
"productField": "",
"multipleFiles": false,
"maxFiles": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false,
"displayOnly": "",
"enablePrice": "",
"gravityflowUsersRoleFilter": ""
},
{
"type": "date",
"id": 6,
"label": "Actual 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": "radio",
"id": 8,
"label": "acceptance",
"adminLabel": "",
"isRequired": false,
"size": "medium",
"errorMessage": "",
"visibility": "visible",
"inputs": null,
"choices": [
{
"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,
"inputMask": false,
"inputMaskValue": "",
"inputType": "",
"labelPlacement": "",
"descriptionPlacement": "",
"subLabelPlacement": "",
"placeholder": "",
"cssClass": "",
"inputName": "",
"noDuplicates": false,
"defaultValue": "",
"choices": "",
"conditionalLogic": "",
"maxFileSize": "",
"maxFiles": "",
"multipleFiles": true,
"allowedExtensions": "pdf,docx,doc,xlsx,xls,odt,ods,jpg,png,jpeg",
"productField": "",
"calculationFormula": "",
"calculationRounding": "",
"enableCalculation": "",
"disableQuantity": false,
"displayAllCategories": false,
"useRichTextEditor": false
}
],
"version": "2.3.2",
"id": 1,
"useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false,
"postTitleTemplate": "",
"postContentTemplate": "",
"lastPageButton": null,
"pagination": null,
"firstPageCssClass": null,
"is_active": "1",
"date_created": "2018-08-15 20:30:18",
"is_trash": "0",
"confirmations": [
{
"id": "5b5f75f7494b7",
"name": "Default Confirmation",
"isDefault": true,
"type": "message",
"message": "Thanks for contacting us! We will get in touch with you shortly.",
"url": "",
"pageId": "",
"queryString": ""
}
],
"notifications": [
{
"id": "5b5f75f748cee",
"to": "{admin_email}",
"name": "Admin Notification",
"event": "form_submission",
"toType": "email",
"subject": "New submission from {form_title}",
"message": "{all_fields}"
}
],
"feeds": {
"gravityflow": [
{
"id": "1",
"form_id": "1",
"is_active": "1",
"feed_order": "0",
"meta": {
"step_name": "Upload acceptance file",
"description": "",
"step_type": "user_input",
"step_highlight": "0",
"step_highlight_type": "color",
"step_highlight_color": "#dd3333",
"feed_condition_conditional_logic": "0",
"feed_condition_conditional_logic_object": [],
"scheduled": "0",
"schedule_type": "delay",
"schedule_date": "",
"schedule_delay_offset": "",
"schedule_delay_unit": "hours",
"schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after",
"schedule_date_field": "6",
"type": "select",
"assignees": [
"role|administrator",
"assignee_user_field|2"
],
"routing": "",
"assignee_policy": "any",
"highlight_editable_fields_enabled": "0",
"highlight_editable_fields_class": "green-triangle",
"instructionsEnable": "0",
"instructionsValue": "",
"display_fields_mode": "selected_fields",
"default_status": "hidden",
"note_mode": "not_required",
"assignee_notification_enabled": "0",
"assignee_notification_from_name": "",
"assignee_notification_from_email": "{admin_email}",
"assignee_notification_reply_to": "",
"assignee_notification_bcc": "",
"assignee_notification_subject": "Upload order acceptance file",
"assignee_notification_message": "A new entry requires your input.",
"assignee_notification_disable_autoformat": "0",
"resend_assignee_emailEnable": "0",
"resend_assignee_emailValue": "7",
"resend_assignee_email_repeatEnable": "0",
"resend_assignee_email_repeatValue": "3",
"in_progress_notification_enabled": "0",
"in_progress_notification_type": "select",
"in_progress_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"in_progress_notification_from_name": "",
"in_progress_notification_from_email": "{admin_email}",
"in_progress_notification_reply_to": "",
"in_progress_notification_bcc": "",
"in_progress_notification_subject": "",
"in_progress_notification_message": "Entry {entry_id} has been updated and remains in progress.",
"in_progress_notification_disable_autoformat": "0",
"complete_notification_enabled": "0",
"complete_notification_type": "select",
"complete_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"complete_notification_from_name": "",
"complete_notification_from_email": "{admin_email}",
"complete_notification_reply_to": "",
"complete_notification_bcc": "",
"complete_notification_subject": "",
"complete_notification_message": "Entry {entry_id} has been updated completing the step.",
"complete_notification_disable_autoformat": "0",
"confirmation_messageEnable": "0",
"confirmation_messageValue": "Thank you.",
"expiration": "0",
"expiration_type": "date_field",
"expiration_date": "",
"expiration_delay_offset": "7",
"expiration_delay_unit": "days",
"expiration_date_field_offset": "0",
"expiration_date_field_offset_unit": "hours",
"expiration_date_field_before_after": "after",
"expiration_date_field": "9",
"status_expiration": "expired",
"destination_expired": "2",
"destination_complete": "next"
},
"addon_slug": "gravityflow",
"event_type": null
},
{
"id": "2",
"form_id": "1",
"is_active": "1",
"feed_order": "0",
"meta": {
"step_name": "Approve customer acceptance",
"description": "",
"step_type": "approval",
"step_highlight": "0",
"step_highlight_type": "color",
"step_highlight_color": "#dd3333",
"feed_condition_conditional_logic": "0",
"feed_condition_conditional_logic_object": [],
"scheduled": "0",
"schedule_type": "delay",
"schedule_date": "",
"schedule_delay_offset": "",
"schedule_delay_unit": "hours",
"schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after",
"type": "select",
"assignees": [
"role|administrator"
],
"routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"assignee_policy": "any",
"instructionsEnable": "0",
"instructionsValue": "Instructions: please review the values in the fields below and click on the Approve or Reject button",
"display_fields_mode": "all_fields",
"assignee_notification_enabled": "0",
"assignee_notification_from_name": "",
"assignee_notification_from_email": "{admin_email}",
"assignee_notification_reply_to": "",
"assignee_notification_bcc": "",
"assignee_notification_subject": "",
"assignee_notification_message": "A new entry is pending your approval. Please check your Workflow Inbox.",
"assignee_notification_disable_autoformat": "0",
"resend_assignee_emailEnable": "0",
"resend_assignee_emailValue": "7",
"resend_assignee_email_repeatEnable": "0",
"resend_assignee_email_repeatValue": "3",
"rejection_notification_enabled": "0",
"rejection_notification_type": "select",
"rejection_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"rejection_notification_from_name": "",
"rejection_notification_from_email": "{admin_email}",
"rejection_notification_reply_to": "",
"rejection_notification_bcc": "",
"rejection_notification_subject": "",
"rejection_notification_message": "Entry {entry_id} has been rejected",
"rejection_notification_disable_autoformat": "0",
"approval_notification_enabled": "0",
"approval_notification_type": "select",
"approval_notification_routing": [
{
"assignee": "user_id|2",
"fieldId": "0",
"operator": "is",
"value": "",
"type": ""
}
],
"approval_notification_from_name": "",
"approval_notification_from_email": "{admin_email}",
"approval_notification_reply_to": "",
"approval_notification_bcc": "",
"approval_notification_subject": "",
"approval_notification_message": "Entry {entry_id} has been approved",
"approval_notification_disable_autoformat": "0",
"revertEnable": "0",
"revertValue": 1,
"note_mode": "not_required",
"expiration": "0",
"expiration_type": "delay",
"expiration_date": "",
"expiration_delay_offset": "",
"expiration_delay_unit": "hours",
"expiration_date_field_offset": "0",
"expiration_date_field_offset_unit": "hours",
"expiration_date_field_before_after": "after",
"status_expiration": "rejected",
"destination_expired": "next",
"destination_rejected": 1,
"destination_approved": "next"
},
"addon_slug": "gravityflow",
"event_type": null
}
]
}
]
}
},
"version": "2.3.2.6"
},
"version": "2.3.2"
}

View File

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

View File

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

View File

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

View File

@@ -21,7 +21,7 @@
"visibility": "visible",
"inputs": null,
"numberFormat": "decimal_dot",
"formId": "11",
"formId": 5,
"description": "",
"allowsPrepopulate": true,
"inputMask": false,
@@ -71,7 +71,7 @@
"text": "wpUser"
}
],
"formId": "11",
"formId": 5,
"description": "",
"allowsPrepopulate": true,
"inputMask": false,
@@ -102,7 +102,7 @@
}
],
"version": "2.3.2.6",
"id": "11",
"id": 5,
"useCurrentUserAsAuthor": true,
"postContentTemplateEnabled": false,
"postTitleTemplateEnabled": false,
@@ -112,20 +112,8 @@
"pagination": null,
"firstPageCssClass": null,
"is_active": "1",
"date_created": "2018-07-30 20:53:56",
"date_created": "2018-08-09 15:36:00",
"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": [
{
"id": "5b5f7ae4bb79e",
@@ -138,11 +126,23 @@
"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": {
"gravityflow": [
{
"id": "28",
"form_id": "11",
"id": "7",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -164,7 +164,7 @@
"schedule_date_field_before_after": "after",
"instructionsEnable": "0",
"instructionsValue": "",
"target_form_id": "9",
"target_form_id": 3,
"store_new_entry_idEnable": "1",
"new_entry_id_field": "6",
"destination_complete": "next"
@@ -173,8 +173,8 @@
"event_type": null
},
{
"id": "33",
"form_id": "11",
"id": "8",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -196,7 +196,7 @@
"schedule_date_field_before_after": "after",
"instructionsEnable": "0",
"instructionsValue": "",
"target_form_id": "12",
"target_form_id": 4,
"store_new_entry_idEnable": "0",
"new_entry_id_field": "",
"destination_complete": "next"
@@ -205,8 +205,8 @@
"event_type": null
},
{
"id": "34",
"form_id": "11",
"id": "9",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -228,7 +228,7 @@
"schedule_date_field_before_after": "after",
"instructionsEnable": "0",
"instructionsValue": "",
"target_form_id": "12",
"target_form_id": 4,
"store_new_entry_idEnable": "0",
"new_entry_id_field": "",
"destination_complete": "next"
@@ -237,8 +237,8 @@
"event_type": null
},
{
"id": "29",
"form_id": "11",
"id": "10",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -258,7 +258,7 @@
"schedule_date_field_offset": "0",
"schedule_date_field_offset_unit": "hours",
"schedule_date_field_before_after": "after",
"target_form_id": "10",
"target_form_id": 1,
"store_new_entry_idEnable": "1",
"new_entry_id_field": "7",
"destination_complete": "next"
@@ -267,8 +267,8 @@
"event_type": null
},
{
"id": "36",
"form_id": "11",
"id": "11",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -290,7 +290,7 @@
"schedule_date_field_before_after": "after",
"instructionsEnable": "0",
"instructionsValue": "",
"target_form_id": "12",
"target_form_id": 4,
"store_new_entry_idEnable": "0",
"new_entry_id_field": "",
"destination_complete": "next",
@@ -300,8 +300,8 @@
"event_type": null
},
{
"id": "35",
"form_id": "11",
"id": "12",
"form_id": "5",
"is_active": "1",
"feed_order": "0",
"meta": {
@@ -323,7 +323,7 @@
"schedule_date_field_before_after": "after",
"instructionsEnable": "0",
"instructionsValue": "",
"target_form_id": "12",
"target_form_id": 4,
"store_new_entry_idEnable": "0",
"new_entry_id_field": "",
"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,
'wiaas_delivery_process_id' => $this->get_entry_id(),
'wiaas_delivery_order_id' => $entry['wiaas_delivery_order_id'],
'wiaas_delivery_step_name' => $this->get_name(),
);
$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;
/**
* Test REST Server
*
* @var WP_REST_Server
*/
protected $server;
protected $namespaced_route = '/wiaas';
function 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();
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->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

@@ -14,7 +14,9 @@ class Wiaas_Unit_Test_Case extends WP_UnitTestCase {
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() {

2
backend/composer.lock generated
View File

@@ -1,7 +1,7 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#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"
],
"content-hash": "302f569929ecdaf4d349b0bf764de74c",

View File

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

View File

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

View File

@@ -24,7 +24,9 @@ import {
SET_SCHEDULING_DISABLED_FLAG
} from '../../constants/ordersConstants';
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();
@@ -42,15 +44,12 @@ export const fetchOrderInfo = (idOrder) => {
return dispatch => {
dispatch(requestOrderInfo());
return htmlClient.fetch({
url: `${API_SERVER}/orders/api/getOrderInfo`,
method: 'post',
data: {
idOrder
}
})
url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}`,
method: 'get'
})
.then(response => {
if (response.data) {
dispatch(recieveOrderInfo(response.data));
dispatch(recieveOrderInfo(fromWCOrder(response.data)));
}
})
.catch(error => {
@@ -63,22 +62,28 @@ const sendComment = () => ({
type: SEND_ORDER_COMMENT
})
export const addComment = (idOrder, comment) => {
export const addComment = (idOrder, newComment) => {
return dispatch => {
dispatch(sendComment());
return htmlClient.fetch({
url: `${API_SERVER}/orders/api/addOrderComment`,
method: 'post',
data: {
idOrder,
comment
}
})
url: `${API_SERVER}/wp-json/wc/v2/orders/${idOrder}/notes`,
method: 'post',
data: {
note : newComment || 'Test comment',
customer_note: true,
}
})
.then(response => {
if (response.data) {
dispatch(fetchOrderInfo(idOrder));
}
/*
if (response.data && response.data.messages) {
dispatch(updateMessages(response.data.messages, orderMessages));
dispatch(fetchOrderInfo(idOrder));
}
*/
})
.catch(error => {
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.',
ALLOWED_LANGUAGE: 'Allowed languages are:',
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!',
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!',
RE_UPLOAD_MAIL : 'Notify mail has been sent!',
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.',
INSTALLATION_DECLINED : 'The implementation is not satisfactory.',
ERROR_MAIL_SENT : 'Notify mail was not sent!',
@@ -81,7 +81,13 @@ export const orderMessages = {
EMPTY_VALUE: 'Field required: ',
INSTALLATION_ACCEPTED: 'The implementation has been accepted!',
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 = {
@@ -161,7 +167,11 @@ export const orderTexts = {
INSTALLATION_DATE: 'Installation date',
INSTALLATION_NOT_REQUIRED:'Installation is not required for this package',
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: {
ACCEPT_INSTALLATION: 'I agree',

View File

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

View File

@@ -18,7 +18,7 @@ class OrderComments extends Component {
}
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){
@@ -26,11 +26,11 @@ class OrderComments extends Component {
}
getOffset(isOwner){
return isOwner ? 6 : 0;
return (isOwner) ? 6 : 0;
}
getClassByOwner(isOwner){
return isOwner ? 'mine' : '';
return (isOwner) ? 'mine' : '';
}
render() {
@@ -48,7 +48,7 @@ class OrderComments extends Component {
<Row key={'order-comment-' + index}>
<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-header">{orderComment.username} - {orderComment.addDate}</div>
<div className="order-comment-header">{orderComment.username} - {orderComment.dateCreated}</div>
<div dangerouslySetInnerHTML={{__html: orderComment.comment}}></div>
</div>
</Col>

View File

@@ -10,10 +10,10 @@ class OrderDocuments extends Component {
return (
<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>
);

View File

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

View File

@@ -27,7 +27,7 @@ class OrderInfo extends Component {
setInstallationData(props) {
const acceptedDate = {};
const proposedDate = {};
const idOrder = props.orderDetails.info.id;
const idOrder = props.orderDetails.id;
const {isInstallationInPackage} = props.installationData;
const {confirmationDates, areAllShippingDatesConfirmed} = props;
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 orderPackages = installationData.packages;
const isInstallationInPackage = installationData.isInstallationInPackage;
const orderInfo = this.props.orderInfo.info;
const orderInfo = this.props.orderInfo;
return (
<Container fluid={true} id="order-info-description">
<Row>
<Col xl="2">
<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>
<span>{orderInfo.commercialLead}</span>
<span>{orderInfo.commercialLead.name}</span>
</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">
<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>
{
packages.length > 0 &&
packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.idPackage}
onClick={()=>{onPackageFilter(orderPackage.packageName)}}
className={this.getClass(orderPackage.packageName)}>{orderPackage.packageName}</div>)
packages.map((orderPackage) => <div key={'menu-package-' + orderPackage.id}
onClick={()=>{onPackageFilter(orderPackage.name)}}
className={this.getClass(orderPackage.name)}>{orderPackage.name}</div>)
}
</Col>

View File

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

View File

@@ -7,7 +7,7 @@ class PackageName extends Component {
return (
<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>
);
}

View File

@@ -6,13 +6,13 @@ import PackageName from './PackageName.jsx';
class ProcessPackage extends Component {
render() {
const {orderPackage, idCommercialLead} = this.props;
const {orderPackage, currency, idCommercialLead} = this.props;
return (
<WiaasBox customHeader={PackageName} customHeaderParams={{orderPackage, idCommercialLead}} className="order-package">
<Row>
<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>
</Row>
</WiaasBox>

View File

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

View File

@@ -7,7 +7,7 @@ const completedOrdersStatuses = ['production', 'end-of-life'];
class OrderProcess extends Component {
isStepVisible(step) {
return (step.status === 'in-progress' || step.status === 'done') && step.isVisibleForCustomer === 1;
return (step.status === 'pending' || step.status === 'complete') && step.isVisibleForCustomer === 1;
}
render() {
@@ -41,7 +41,7 @@ class OrderProcess extends Component {
<Row>
<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>
</Row>

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
import moment from 'moment';
import {fromWiaasProcessStep} from './ProcessHelper';
function formatDate(date) {
return date ? moment(date).format("Do MMM, YYYY") : undefined;
@@ -9,6 +10,10 @@ function formatAddress(addressObject) {
}
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 {
id: WCOrder.id,
number: WCOrder.number,
@@ -22,6 +27,12 @@ export const fromWCOrder = (WCOrder) => {
recurringPrice: 0,
status: WCOrder.status,
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 => {
return {
id: packageLine['product_id'],
@@ -40,6 +51,14 @@ export const fromWCOrder = (WCOrder) => {
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),
customer: WCOrder.customer,
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,
}
};