Service - Sell Offer Plan: Difference between revisions

From Izara Wiki
Jump to navigation Jump to search
No edit summary
 
(49 intermediate revisions by the same user not shown)
Line 43: Line 43:
</syntaxhighlight>
</syntaxhighlight>


== LogicalResults ==
== LogicalResultsMain ==
[[Standard LogicalResults Per Service|LogicalResultsMain]]


Stores results for any requests to perform logical searches on sell offer data
== LogicalResultsData ==
[[Standard LogicalResults Per Service|LogicalResultsData]]


<syntaxhighlight lang="JavaScript">
== LogicalAwaitingStep ==
{
resultId: xxx // eg: filterMainId for a single logical element
dataId: xxx // one sellofferId
}
</syntaxhighlight>


* partition key: resultId
[[NPM module - izara-shared|AwaitingStep]]
* sort key: dataId


== PriceLogicals ==
== FindDataMain ==
[[Standard FindData Per Service|FindDataMain]]


Records ProcessLogical requests for pricing based elements, so when pricing flow completes can send message out for complexFilter service to receive.
== FindDataAwaitingStep ==
[[NPM module - izara-shared|AwaitingStep]]


<syntaxhighlight lang="JavaScript">
== FindDataSortedRequest ==
{
[[Standard FindData Per Service|FindDataSortedRequest]]
priceCalcId: "xx",
resultId: "xx",
logicalElement: {},
timestamp: "xx", //when record created
}
</syntaxhighlight>
 
* partition key: priceCalcId
* sort key: resultId
* priceCalcId comes from a hash of values sent into pricing flow
* is a temporary record, after processLogical complete can delete record


= Graph database =  
= Graph database =  
Line 96: Line 83:
},
},
currencyId: {
currencyId: {
immutable: true, // all added deliveryMethods must match
immutable: true, // all added deliveryMethods and sellOffers must match},
},
},
},
},
Line 142: Line 129:
{
{
properties: {
properties: {
oneTimeAmountSetting: {}, // "value"|"rate", do we add one time cost to the value before calculating, or is it a straight rate added after calculating
addToRateTableValuePerOrder: {}, // added once per order to the value before calculating delivery method price
oneTimeAmount: {}, // value of the one time amount
addToRateTableValuePerUnit: {}, // added once per orderQuantity to the value before calculating delivery method price
oneTimeAmountAccumulate: {}, // boolean true|false, if TRUE for combined orders then add oneTimeAmount for each included Sell Offer, if FALSE only gets added once
addToCalculatedValuePerOrder: {}, // added once per order to the value after calculating delivery method price
valueType: "xx", // quantity|productValue|productAttribute|sellOfferTerm, if set overwrites deliveryMethod defaultValueType
addToCalculatedValuePerUnit: {}, // added once per orderQuantity to the value after calculating delivery method price
valueId: "xx", // if set overwrites deliveryMethod defaultValueId
valueType: "xx", // orderQuantity|orderSubtotal|productAttributeId|sellOfferTermId, if set overwrites deliveryMethod defaultValueType
valueId: "xx", // if set overwrites deliveryMethod defaultValueId (used for productAttributeId|sellOfferTermId)
valueLanguageId: {}, // used for productAttributeId|sellOfferTermId, when finding attribute value need to set language to find
accumulateValue: true // default: true, if set to false will find the largest value out of all sellOffers in the order
},
},
}
}
Line 156: Line 146:
{
{
properties: {
properties: {
oneTimeAmountSetting: {}, // "cost"|"percentage", do we add a one time cost, or add a % to the order total
oneTimePercentage: {}, // increase paymentMethod price by percentage
oneTimeAmount: {}, // value of the one time amount
oneTimeAmount: {}, // increase paymentMethod price by set amount
},
},
}
}
</syntaxhighlight>
</syntaxhighlight>
* if both oneTimePercentage and oneTimeAmount are set, applies oneTimePercentage first
* applies on to orderSubtotal + deliveryPrice


==== sellOfferPlanSettings ====
==== sellOfferPlanSettings ====
Line 167: Line 159:
{
{
properties: {
properties: {
combineWins: {}, // true|false
combineWins: true, // true|false, default true
prices: {
sellOfferQuantity: [ // sellOfferQuantity type price settings, ordered low to high
{
upToValue: "xx.xx",
price: "xx.xx",
},
// ...
],
orderQuantity: [ // orderQuantity type price settings, ordered low to high
{
upToValue: "xx.xx",
price: "xx.xx",
},
// ...
]
orderValue: [ // orderValue type price settings, ordered low to high
{
upToValue: "xx.xx",
price: "xx.xx",
},
// ...
]
},


},
},
Line 200: Line 169:
<syntaxhighlight lang="JavaScript">
<syntaxhighlight lang="JavaScript">
{
{
relationshipType: "{SellOfferPlanLib.createHasSellOfferPlanGraphRelationshipType()}", // "has_sellOfferPlan"
relationshipType: "{HAS_SELLOFFERPLAN_GRAPH_REL_TYPE}", // "has_sellOfferPlan"
schema: {
schema: {
elementCanBeRemoved: true,
elementCanBeRemoved: false,
allPropertiesImmutable: true,
allPropertiesImmutable: true,
restrictProperties: true,
restrictProperties: true,
Line 272: Line 241:
relationshipType: "{SellOfferPlanLib.createIsDeliveryMethodGraphRelationshipType()}", // "is_deliveryMethod"
relationshipType: "{SellOfferPlanLib.createIsDeliveryMethodGraphRelationshipType()}", // "is_deliveryMethod"
schema: {
schema: {
elementCanBeRemoved: true,
elementCanBeRemoved: false,
allPropertiesImmutable: true,
allPropertiesImmutable: true,
restrictProperties: true,
restrictProperties: true,
Line 286: Line 255:
relationshipType: "{SellOfferPlanLib.createIsUserPaymentMethodGraphRelationshipType()}", // "is_userPaymentMethod"
relationshipType: "{SellOfferPlanLib.createIsUserPaymentMethodGraphRelationshipType()}", // "is_userPaymentMethod"
schema: {
schema: {
elementCanBeRemoved: true,
elementCanBeRemoved: false,
allPropertiesImmutable: true,
allPropertiesImmutable: true,
restrictProperties: true,
restrictProperties: true,
Line 314: Line 283:
logicalTag: "combineWins",
logicalTag: "combineWins",
comparison: "true",
comparison: "true",
},
{
type: "logical",
logicalTag: "maxPrice",
comparison: "lessThan",
value: "xx"
},
{
type: "logical",
logicalTag: "minPrice",
comparison: "lessThan",
value: "xx"
},
},
{
{
type: "complexFilter",
type: "complexFilter",
complexFilter: {
complexFilter: {
filterType: "userPaymentMethod",
filterType: "managerUserPaymentMethod",
// see [[Service - Payment Method Generic|Complex Filter requests]]
// see [[Service - Payment Method Manager|Complex Filter requests]]
}
}
},
},
Line 337: Line 294:
type: "complexFilter",
type: "complexFilter",
complexFilter: {
complexFilter: {
filterType: "deliveryMethod",
filterType: "managerDeliveryMethod",
// see [[Service - Delivery Method Standard|Complex Filter requests]]
// see [[Service - Delivery Method Manager|Complex Filter requests]]
}
}
},
},
...
...
]
]
}
}
</syntaxhighlight>
</syntaxhighlight>
<syntaxhighlight lang="JavaScript">
{
// finds all combinations where the plan has both a deliveryMethodId and paymentMethodId from the given lists of deliveryMethodId and paymentMethodIds
filterType: "planDeliveryPaymentCombination" //unique id is planDeliveryPaymentCombinationId
type: "group",
elements:
[
{
type: "logical",
logicalTag: "planDeliveryPaymentCombination",
paymentMethodIds: [],
deliveryMethodIds: []
},
{
//will find all PlanDeliveryPaymentCombinations for this sellOfferId
type: "logical",
logicalTag: "sellOfferId",
comparison: "equals",
value: {sellOfferId}
},
{
//will find all PlanDeliveryPaymentCombinations for listed sellOfferIds
type: "logical",
logicalTag: "sellOfferIds",
comparison: "equals",
value: [] // array of sellOfferIds
},
...
]
}
</syntaxhighlight>
* planDeliveryPaymentCombinationId = {sellOfferPlanId}_{sellOfferPlanDeliveryMethodLinkId}_{sellOfferPlanPaymentMethodLinkId}


== Translate Ids - userPaymentMethod and deliveryMethod to sellOfferPlan ==
== Translate Ids - userPaymentMethod and deliveryMethod to sellOfferPlan ==
Line 350: Line 342:
* only find sellOfferPlanIds that have has_userPaymentMethodLink or has_deliveryMethodLink relationships (ignore disabled)
* only find sellOfferPlanIds that have has_userPaymentMethodLink or has_deliveryMethodLink relationships (ignore disabled)
* bypasses link nodes (no complex filterType)
* bypasses link nodes (no complex filterType)
= Calc pricing use cases =
== Complex filter ==
Complex filter (filterType = sellOfferPlan) can find all sellOfferPlanIds that match a pricing comparison, eg minimumPrice < 100:
== Cart price ==
A cart has a fixed deliveryMethod and paymentMethod so no comparisons are needed across these, instead the array of sellOfferQuantities are sent to PriceCalc which returns the total price, per sellOffer price, orderQuantity, etc..
== Presenting a sellOffer's price options ==
* For a range of (or all) paymentMethodIds / deliveryMethodIds, deliverToLocationIds / orderQuantity are fixed.
== Presenting a product's price options ==
* For a range of (or all) paymentMethodIds / deliveryMethodIds, deliverToLocationIds / orderQuantity are fixed
= Handling SellOfferPlanPrice errors =
* If a SellOfferPlanPrice has an error it's status is set to error
* SellOfferPlanPrice's that are error do save into SellOfferPlanPriceRangePrice, so a SellOfferPlanPriceRange object can see all prices calculated, any requests at this level will need to filter out error prices
* SellOfferPlanPrice's that are error do not save into FilteredSellOfferPlanPrice, they are ignored as they cannot be filtered effectively
= Notes =
* A Sell Offer Plan can link to multiple payment/delivery links, but those multiple links should not point to the same delivery/userpaymentmethod nodes, try to catch/validate this when creating new link nodes


= Working documents =
= Working documents =

Latest revision as of 09:32, 6 August 2023

Overview

A user's plan that connects a user's sell offer to any number of delivery method links and payment method links, and also to the sell offer's prices.

Each sell offer will have one plan, the plan controls the sell offer's prices, and many sell offers can point to the same plan (if they all share the same prices), so any change in price will mean a new sell offer plan.

The plan also links to delivery methods and payment methods using link nodes, so sell offers that use the same sell offer plan must offer the same delivery method and payment methods and their link settings.

Many sell offer plans can use the same delivery method links and payment method links, so if multiple sell offers have the same delivery and payment method settings but different prices, they can share the links but with separate sell offer plans + pricing.

Repository

https://bitbucket.org/izara-market-products/izara-market-products-sell-offer-plan

DynamoDB tables

Standard Config Table Per Service

Configuration tags

{
	configTag: "DeliveryMethodManagerServiceName"
	configKey: "DeliveryMethodManagerServiceName"
	configValue: xxx // eg: "DeliveryMethodManager"
}
{
	configTag: "PaymentMethodManagerServiceName"
	configKey: "PaymentMethodManagerServiceName"
	configValue: xxx // eg: "PaymentMethodManager"
}
{
	configTag: "ProductGraphServiceName"
	configKey: "ProductGraphServiceName"
	configValue: xxx // eg: "ProductGraph"
}

LogicalResultsMain

LogicalResultsMain

LogicalResultsData

LogicalResultsData

LogicalAwaitingStep

AwaitingStep

FindDataMain

FindDataMain

FindDataAwaitingStep

AwaitingStep

FindDataSortedRequest

FindDataSortedRequest

Graph database

Service - Products Graph

Nodes

{
	nodeLabel: "{SellOfferPlanLib.SELLOFFERPLAN_GRAPH_NODE_LABEL}", // "sellOfferPlan"
	schema: {
		identifier: true,
		restrictProperties: true,
		restrictRelationships: true,
		properties: {
			sellOfferPlanId: {
				identifier: true, // create unique id from request params and uniqueMessageId
			},
			userId: {
				immutable: true, // a sellOfferPlan can only be used by one user (because links to their userPaymentMethods)
			},
			currencyId: {
				immutable: true, // all added deliveryMethods and sellOffers must match},
			},
		},
	}
}
{
	nodeLabel: "{SellOfferPlanLib.SELLOFFERPLAN_DELIVERYMETHODLINK_GRAPH_NODE_LABEL}", // "sellOfferPlanDeliveryMethodLink"
	schema: {
		identifier: true,
		restrictProperties: true,
		restrictRelationships: true,
		properties: {
			sellOfferPlanDeliveryMethodLinkId: {
				identifier: true, // create unique id from request params and uniqueMessageId
			},
		},
	}
}
{
	nodeLabel: "{SellOfferPlanLib.SELLOFFERPLAN_USERPAYMENTMETHODLINK_GRAPH_NODE_LABEL}", // "sellOfferPlanUserPaymentMethodLink"
	schema: {
		identifier: true,
		restrictProperties: true,
		restrictRelationships: true,
		properties: {
			sellOfferPlanUserPaymentMethodLinkId: {
				identifier: true, // create unique id from request params and uniqueMessageId
			},
		},
	}
}

Versioned data

sellOfferPlanDeliveryMethodLinkSettings

{
	properties: {
		addToRateTableValuePerOrder: {}, // added once per order to the value before calculating delivery method price
		addToRateTableValuePerUnit: {}, // added once per orderQuantity to the value before calculating delivery method price
		addToCalculatedValuePerOrder: {}, // added once per order to the value after calculating delivery method price
		addToCalculatedValuePerUnit: {}, // added once per orderQuantity to the value after calculating delivery method price
		valueType: "xx", // orderQuantity|orderSubtotal|productAttributeId|sellOfferTermId, if set overwrites deliveryMethod defaultValueType
		valueId: "xx", // if set overwrites deliveryMethod defaultValueId (used for productAttributeId|sellOfferTermId)
		valueLanguageId: {}, // used for productAttributeId|sellOfferTermId, when finding attribute value need to set language to find
		accumulateValue: true // default: true, if set to false will find the largest value out of all sellOffers in the order
	},
}

sellOfferPlanUserPaymentMethodLinkSettings

{
	properties: {
		oneTimePercentage: {}, // increase paymentMethod price by percentage
		oneTimeAmount: {}, // increase paymentMethod price by set amount
	},
}
  • if both oneTimePercentage and oneTimeAmount are set, applies oneTimePercentage first
  • applies on to orderSubtotal + deliveryPrice

sellOfferPlanSettings

{
	properties: {
		combineWins: true, // true|false, default true

	},
}

Relationships

{
	relationshipType: "{HAS_SELLOFFERPLAN_GRAPH_REL_TYPE}", // "has_sellOfferPlan"
	schema: {
		elementCanBeRemoved: false,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
  • links a user to one of their sell offer plans
{
	relationshipType: "{SellOfferPlanLib.createHasDeliveryMethodLinkGraphRelationshipType()}", // "has_deliveryMethodLink"
	schema: {
		elementCanBeRemoved: true,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
{
	relationshipType: "{SellOfferPlanLib.createDisabledDeliveryMethodLinkGraphRelationshipType()}", // "disabled_deliveryMethodLink"
	schema: {
		elementCanBeRemoved: true,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
{
	relationshipType: "{SellOfferPlanLib.createHasUserPaymentMethodLinkGraphRelationshipType()}", // "has_userPaymentMethodLink"
	schema: {
		elementCanBeRemoved: true,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
{
	relationshipType: "{SellOfferPlanLib.createDisabledUserPaymentMethodLinkGraphRelationshipType()}", // "disabled_userPaymentMethodLink"
	schema: {
		elementCanBeRemoved: true,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
  • many sell offer plans can link to one delivery method link, or one payment method link, this allows user to share settings in the link nodes across multiple sell offer plans
{
	relationshipType: "{SellOfferPlanLib.createIsDeliveryMethodGraphRelationshipType()}", // "is_deliveryMethod"
	schema: {
		elementCanBeRemoved: false,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}
{
	relationshipType: "{SellOfferPlanLib.createIsUserPaymentMethodGraphRelationshipType()}", // "is_userPaymentMethod"
	schema: {
		elementCanBeRemoved: false,
		allPropertiesImmutable: true,
		restrictProperties: true,
		properties: {
			originTimestamp: //timestamp the request to create/change this relationship was sent
		},
	}
}

Complex Filter requests

{
	filterType: "sellOfferPlan" //unique id is sellOfferPlanId
	type: "group",
	elements:
	[
		{
			type: "logical",
			logicalTag: "userId",
			comparison: "equals",
			value: "xx"
		},
		{
			type: "logical",
			logicalTag: "combineWins",
			comparison: "true",
		},
		{
			type: "complexFilter",
			complexFilter: {
				filterType: "managerUserPaymentMethod",
				// see [[Service - Payment Method Manager|Complex Filter requests]]
			}
		},		
		{
			type: "complexFilter",
			complexFilter: {
				filterType: "managerDeliveryMethod",
				// see [[Service - Delivery Method Manager|Complex Filter requests]]
			}
		},
		...

	]
}
{
	// finds all combinations where the plan has both a deliveryMethodId and paymentMethodId from the given lists of deliveryMethodId and paymentMethodIds
	filterType: "planDeliveryPaymentCombination" //unique id is planDeliveryPaymentCombinationId
	type: "group",
	elements:
	[
		{
			type: "logical",
			logicalTag: "planDeliveryPaymentCombination",
			paymentMethodIds: [],
			deliveryMethodIds: []
		},
		{
			//will find all PlanDeliveryPaymentCombinations for this sellOfferId
			type: "logical",
			logicalTag: "sellOfferId",
			comparison: "equals",
			value: {sellOfferId}
		},
		{
			//will find all PlanDeliveryPaymentCombinations for listed sellOfferIds
			type: "logical",
			logicalTag: "sellOfferIds",
			comparison: "equals",
			value: [] // array of sellOfferIds
		},
		...
	]
}
  • planDeliveryPaymentCombinationId = {sellOfferPlanId}_{sellOfferPlanDeliveryMethodLinkId}_{sellOfferPlanPaymentMethodLinkId}

Translate Ids - userPaymentMethod and deliveryMethod to sellOfferPlan

  • only find sellOfferPlanIds that have has_userPaymentMethodLink or has_deliveryMethodLink relationships (ignore disabled)
  • bypasses link nodes (no complex filterType)

Calc pricing use cases

Complex filter

Complex filter (filterType = sellOfferPlan) can find all sellOfferPlanIds that match a pricing comparison, eg minimumPrice < 100:

Cart price

A cart has a fixed deliveryMethod and paymentMethod so no comparisons are needed across these, instead the array of sellOfferQuantities are sent to PriceCalc which returns the total price, per sellOffer price, orderQuantity, etc..

Presenting a sellOffer's price options

  • For a range of (or all) paymentMethodIds / deliveryMethodIds, deliverToLocationIds / orderQuantity are fixed.

Presenting a product's price options

  • For a range of (or all) paymentMethodIds / deliveryMethodIds, deliverToLocationIds / orderQuantity are fixed

Handling SellOfferPlanPrice errors

  • If a SellOfferPlanPrice has an error it's status is set to error
  • SellOfferPlanPrice's that are error do save into SellOfferPlanPriceRangePrice, so a SellOfferPlanPriceRange object can see all prices calculated, any requests at this level will need to filter out error prices
  • SellOfferPlanPrice's that are error do not save into FilteredSellOfferPlanPrice, they are ignored as they cannot be filtered effectively

Notes

  • A Sell Offer Plan can link to multiple payment/delivery links, but those multiple links should not point to the same delivery/userpaymentmethod nodes, try to catch/validate this when creating new link nodes

Working documents

Sell Offer Plan