Skip to content

Commit

Permalink
Openapi Spec for Cancellation Details (#1204)
Browse files Browse the repository at this point in the history
  • Loading branch information
nadaismail-stripe authored Sep 29, 2023
1 parent efac339 commit 695eebb
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 17 deletions.
3 changes: 1 addition & 2 deletions lib/stripe-force/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ class FeatureFlags < T::Enum
# DAY_PRORATIONS should only be enabled if CPQ Subscription Prorate Precision = 'Month + Day'
DAY_PRORATIONS = new('day_prorations')
AUTO_ADVANCE_PRORATION_INVOICE = new('auto_advance_proration_invoices')
PREBILLING = new('prebilling')
BACKDATED_AMENDMENTS = new('backdated_amendments')
FRONTEND_PRORATIONS = new('frontend_prorations')
INVOICE_RENDERING_TEMPLATE = new('invoice_rendering_template')
Expand All @@ -237,7 +236,7 @@ class FeatureFlags < T::Enum
STRIPE_REVENUE_CONTRACT = new('stripe_revenue_contract')
TERMINATION_METADATA = new('termination_metadata')
UPDATE_PRODUCT_ON_SYNC = new('update_product_on_sync')
BIDIRECTIONAL_SYNC_DEMO = new('bidirectional_sync_demo')
CUSTOM_BILLING_CANCELLATION_DETAILS = new('custom_billing_cancellation_details')
end
end

Expand Down
7 changes: 7 additions & 0 deletions lib/stripe-force/db/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,13 @@ def hidden_mapper_fields
hidden_mapper_fields << "subscription_schedule.default_settings.invoice_settings.rendering.template_version"
end

# TODO: remove this once cancellation reasons is implemented on the sub schedule
if !feature_enabled?(FeatureFlags::CUSTOM_BILLING_CANCELLATION_DETAILS)
hidden_mapper_fields << "subscription_schedule.cancellation_details.comment"
hidden_mapper_fields << "subscription_schedule.cancellation_details.feedback"
hidden_mapper_fields << "subscription_schedule.cancellation_details.feedback_option"
end

hidden_mapper_fields
end

Expand Down
6 changes: 3 additions & 3 deletions lib/stripe-force/translate/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1348,10 +1348,10 @@ def terminate_subscription_line_items(original_aggregate_phase_items, terminatio
end
end

log.info "order amendment revision map",
revision_map: revision_map.transform_values {|ci| ci.map(&:order_line_id) }
log.info "order amendment revision map", revision_map: revision_map.transform_values {|ci| ci.map(&:order_line_id) }

# now let's terminate the related line items
log.info "termination lines", termination_lines: termination_lines.map(&:order_line_id), termination_lines_count: termination_lines.count
termination_lines.each do |termination_line|
origin_order_line_id = T.must(termination_line.revised_order_line_id)
fifo_order_line_stack = revision_map[origin_order_line_id]
Expand All @@ -1365,7 +1365,7 @@ def terminate_subscription_line_items(original_aggregate_phase_items, terminatio
end

if termination_line.quantity > 0
raise Integrations::Errors::ImpossibleState.new("Order item quantity on termination lines should never be positive")
raise Integrations::Errors::ImpossibleState.new("Order Item quantity on termination lines should never be positive.")
end

log.info 'reducing quantity on line', termination_line: termination_line.order_line_id, reducing_quantity: termination_line.quantity
Expand Down
2 changes: 1 addition & 1 deletion lib/stripe-force/translate/price.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def create_price_for_order_item(sf_order_item)
sig { params(sf_object: Restforce::SObject, sf_product: Restforce::SObject, stripe_product: Stripe::Product, sf_order_item: T.nilable(Restforce::SObject)).returns(T.nilable(Stripe::Price)) }
def create_price_from_sf_object(sf_object, sf_product, stripe_product, sf_order_item=nil)
if ![SF_ORDER_ITEM, SF_PRICEBOOK_ENTRY].include?(sf_object.sobject_type)
raise StripeForce::Errors::RawUserError.new("Stripe price can only be created from an order item or pricebook entry.", salesforce_object: sf_object.sobject_type)
raise Integrations::Errors::ImpossibleInternalError.new("Stripe price can only be created from an order item or pricebook entry.")
end

log.info 'creating price', salesforce_object: sf_object
Expand Down
5 changes: 3 additions & 2 deletions lib/stripe-force/translate/utilities/salesforce_util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ def self.calculate_order_end_date(mapper, sf_order)

# https://jira.corp.stripe.com/browse/PLATINT-1514
cpq_order_end_date = extract_subscription_end_date_from_order(mapper, sf_order)
if !cpq_order_end_date.nil? && calculated_order_end_date != cpq_order_end_date
# the plus one day here is to include the last day
if !cpq_order_end_date.nil? && (calculated_order_end_date + 1.day) != cpq_order_end_date
log.info 'calculated order end date differs from CPQ provided end date', cpq_end_date: cpq_order_end_date, calculated_order_end_date: calculated_order_end_date
end

Expand Down Expand Up @@ -363,7 +364,7 @@ def self.get_non_anniversary_amendment_order_end_date(mapper, sf_order_amendment
# at this point we know:
# (1) feature NON_ANNIVERSARY_AMENDMENTS is enabled
# (2) the amendment order starts on a different day of the month than the initial order
# let's fetch the cpq order end date
# fetch the cpq order end date
amendment_end_date = extract_subscription_end_date_from_order(mapper, sf_order_amendment)
if amendment_end_date.nil?
raise Integrations::Errors::MissingRequiredFields.new(salesforce_object: sf_order_amendment, missing_salesforce_fields: [CPQ_QUOTE_SUBSCRIPTION_END_DATE])
Expand Down
61 changes: 60 additions & 1 deletion public/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@
"description": "",
"fields": [
{
"name": "Iterations",
"name": "iterations",
"value": "prebilling.iterations",
"description": "<p>This is used to determine the number of billing cycles to prebill.</p>",
"type": "integer",
Expand All @@ -1057,6 +1057,65 @@
"sfValueType": ""
}
]
},
{
"label": "Cancellation Details",
"name": "cancellation_details",
"description": "",
"fields": [
{
"name": "feedback option",
"value": "cancellation_details.feedback_option",
"description": "<p>Id of the customized feedback option that provide deeper insight into why the subscription was canceled.</p>",
"type": "string",
"defaultValue": "",
"requiredValue": "",
"hasOverride": false,
"staticValue": false,
"hasSfValue": false,
"hasRequiredValue": false,
"sfValue": "",
"sfValueType": ""
},
{
"name": "comment",
"value": "cancellation_details.comment",
"description": "Additional comments about why the user canceled the subscription, if the subscription was canceled explicitly by the user.",
"type": "string",
"defaultValue": "",
"requiredValue": "",
"hasOverride": false,
"staticValue": false,
"hasSfValue": false,
"hasRequiredValue": false,
"sfValue": "",
"sfValueType": ""
},
{
"name": "feedback",
"value": "cancellation_details.feedback",
"description": "The customer submitted reason for why they canceled, if the subscription was canceled explicitly by the user.",
"type": "string",
"defaultValue": "",
"requiredValue": "",
"hasOverride": false,
"staticValue": false,
"hasSfValue": false,
"hasRequiredValue": false,
"sfValue": "",
"sfValueType": "",
"enum": [
"too_expensive",
"missing_features",
"switched_service",
"unused",
"customer_service",
"too_complex",
"low_quality",
"other"
]
}
]
}
],
"formattedStripeSubscriptionItemFields": [
Expand Down
4 changes: 4 additions & 0 deletions scripts/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ def loud_sf_logging
@sf = sf = @user.sf_client
end

def cpq_consumption_rate(consumption_schedule_id)
sf_get(@sf.query("SELECT Id FROM #{CPQ_CONSUMPTION_RATE} WHERE #{CPQ_CONSUMPTION_SCHEDULE}=#{consumption_schedule_id}").first.Id)
end

def example_sf_order
sf_get(@sf.query("SELECT Id FROM #{SF_ORDER} ORDER BY CreatedDate DESC LIMIT 1").first.Id)
end
Expand Down
44 changes: 38 additions & 6 deletions sfdx/bin/openapi-spec-generator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,40 @@ const HTTPREQUEST = HTTPS.request(OPTIONS, HttpResponse => {
formattedStripeObjectsForMapper = manuallyAddSectionToParsedOpenSpec(
formattedStripeObjectsForMapper,
convertedObjectName,
'Prebilling',
'prebilling',
'Iterations',
'prebilling.iterations',
'Prebilling', // display name of section
'prebilling', // section value
'iterations', // display name of field
'prebilling.iterations', // field value
'<p>This is used to determine the number of billing cycles to prebill.</p>',
'integer'
);

// create cancellation reasons section and push fields to it
formattedStripeObjectsForMapper = manuallyAddSectionToParsedOpenSpec(
formattedStripeObjectsForMapper,
convertedObjectName,
'Cancellation Details', // display name of section
'cancellation_details', // section value
'feedback option', // display name of field
'cancellation_details.feedback_option',
'<p>Id of the customized feedback option that provide deeper insight into why the subscription was canceled.</p>',
'string'
);

cancellation_details_comment_field = getNewFieldObject(
"comment",
"cancellation_details.comment",
"Additional comments about why the user canceled the subscription, if the subscription was canceled explicitly by the user.",
"string");
cancellation_details_feedback_field = getNewFieldObject(
"feedback",
"cancellation_details.feedback",
"The customer submitted reason for why they canceled, if the subscription was canceled explicitly by the user.",
"string",
enumValues = ["too_expensive", "missing_features", "switched_service", "unused", "customer_service", "too_complex", "low_quality", "other"]);
formattedStripeObjectsForMapper['formattedStripe' + convertedObjectName + 'Fields']
.find(object => object.name == "cancellation_details").fields.push(cancellation_details_comment_field, cancellation_details_feedback_field);


// Push fields to 'Default settings Invoice settings' section
rendering_template_field = getNewFieldObject(
Expand Down Expand Up @@ -434,7 +461,7 @@ function combineDuplicateSections(stripeObjectMappings) {
}, []);
}

function getNewFieldObject(fieldName, fieldValue, description='', type='') {
function getNewFieldObject(fieldName, fieldValue, description='', type='', enumValues=[]) {
const fieldMap = {
name: fieldName,
value: fieldValue,
Expand All @@ -447,8 +474,13 @@ function getNewFieldObject(fieldName, fieldValue, description='', type='') {
hasSfValue: false,
hasRequiredValue: false,
sfValue: '',
sfValueType: ''
sfValueType: '',
};

if (enumValues.length > 0) {
fieldMap['enum'] = enumValues;
}

return fieldMap;
}

Expand Down
5 changes: 3 additions & 2 deletions test/controllers/test_configurations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,12 @@ class Critic::ConfigurationsControllerTest < ApplicationIntegrationTest
result = parsed_json

# initially the hidden mapper fields should contain values since no feature flag is enabled for the user
assert(2, result['hidden_mapper_fields'].count)
assert_equal(["subscription_schedule.default_settings.invoice_settings.rendering.template", "subscription_schedule.default_settings.invoice_settings.rendering.template_version"], result['hidden_mapper_fields'])
assert(4, result['hidden_mapper_fields'].count)
assert_equal(["subscription_schedule.default_settings.invoice_settings.rendering.template", "subscription_schedule.default_settings.invoice_settings.rendering.template_version", "subscription_schedule.cancellation_details.comment", "subscription_schedule.cancellation_details.feedback", "subscription_schedule.cancellation_details.feedback_option"], result['hidden_mapper_fields'])

# enable features
@user.enable_feature(FeatureFlags::INVOICE_RENDERING_TEMPLATE)
@user.enable_feature(FeatureFlags::CUSTOM_BILLING_CANCELLATION_DETAILS)
@user.save

get api_configuration_path, headers: authentication_headers
Expand Down

0 comments on commit 695eebb

Please sign in to comment.