Interface IQuoteConnector
This is the interface SuperOffice will call to integrate against an ERP system in the realm of quotes and orders. You don't have to implement all functions, use the capabilities to tell SuperOffice what the connector can and cannot do.
If an ERP system does not provide products, or if the ERP system is not available , the searches can be delegated to the built-in SuperOffice product registry by using the SuperOffice IProductRegisterCache object that is provided at startup. Currencies are specified in ISO three letter codes: USD, NOK, SEK, EUR, GBP, etc. See http://www.currency-iso.org/dl_iso_table_a1.xls for details. The user may click the TEST button in the configuration dialog, which calls the TestConnection method.Inherited Members
Namespace: SuperOffice.CRM
Assembly: SuperOffice.Plugins.dll
Syntax
public interface IQuoteConnector : IDisposable
Properties
CRMConnectionId
The id of this connection in the CRM system
Declaration
int CRMConnectionId { get; set; }
Property Value
Type | Description |
---|---|
int |
Methods
CanProvideCapability(string)
Check if one named capability can be provided (now) Using the PluginResponseInfo gives the connector the possibility to disable a capability, with a reason string that might be shown to the user.
Declaration
bool CanProvideCapability(string capabilityName)
Parameters
Type | Name | Description |
---|---|---|
string | capabilityName | Name of the capability, see CRMQuoteConnectorCapabilities |
Returns
Type | Description |
---|---|
bool | True if connector has this capability |
FindProduct(QuoteAlternativeContextInfo, string, string, string)
The connector should treat this as a freetext search, the user might want to enter several words and expect the system to search for through several fields like name, description, product code, extrafields, etc.
Since the return list is a potentially large return value, the connector or the ERP system should limit the number of matches returned to a few hundred. The dropdown fast searcher calls this function to populate the dropdown list.Declaration
ProductInfo[] FindProduct(QuoteAlternativeContextInfo context, string currencyCode, string userinput, string priceListKey)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | |
string | currencyCode | |
string | userinput | |
string | priceListKey | If the pricelist is empty, the function will search in all active pricelists. |
Returns
Type | Description |
---|---|
ProductInfo[] | An array of products matching the search words |
GetActivePriceLists(string)
Used by the admin client. Gets the available active PriceLists in a specific currency.
Declaration
PriceListInfo[] GetActivePriceLists(string isoCurrencyCode)
Parameters
Type | Name | Description |
---|---|---|
string | isoCurrencyCode | Iso currency like: USD or NOK. Case insensitive. |
Returns
Type | Description |
---|---|
PriceListInfo[] | Return empty array if there is no PriceList available in the currency. Return all pricelists if isoCurrencyCode is empty. |
GetAddresses(QuoteAlternativeContextInfo)
Gets two addresses:
- the invoice address - [0].
- the delivery address - [1].
Declaration
AddressInfo[] GetAddresses(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context |
Returns
Type | Description |
---|---|
AddressInfo[] | Returns null if no address was found. |
GetAllPriceLists(string)
Used by the admin client. Gets the all PriceLists in the given currency, including those inactive.
Declaration
PriceListInfo[] GetAllPriceLists(string isoCurrencyCode)
Parameters
Type | Name | Description |
---|---|---|
string | isoCurrencyCode | Iso currency like: USD or NOK. Case insensitive. |
Returns
Type | Description |
---|---|
PriceListInfo[] | Return empty array if there is no PriceList available. Return all pricelists if isoCurrencyCode is empty. |
GetCapabilities()
Return a set of capability name > status pairs that tell the system what capabilities this connector provides. Using the PluginResponseInfo gives the connector the possibility to disable a capability, with a reason string that might be shown to the user.
Declaration
Dictionary<string, bool> GetCapabilities()
Returns
Type | Description |
---|---|
Dictionary<string, bool> | List of all capabilities |
GetConfigurationFields()
This is a request for metadata needed to populate the Quote connection configuration admin dialog that takes in the information needed to create a connection to an ERP system. The values entered in the dialog are stored in the SuperOffice db and used when InitializeConnection(QuoteConnectionInfo, UserInfo, bool, Dictionary<string, string>, IProductRegisterCache) is called by the client.
Declaration
Dictionary<string, FieldMetadataInfo> GetConfigurationFields()
Returns
Type | Description |
---|---|
Dictionary<string, FieldMetadataInfo> | A list of field descriptions for the GUI to use when populating the config dialog. Make sure that the Rank is set. |
GetNumberOfActivePriceLists(string)
Is used to warn the user if there is no active pricelists in a given currency.
Declaration
int GetNumberOfActivePriceLists(string isoCurrencyCode)
Parameters
Type | Name | Description |
---|---|---|
string | isoCurrencyCode | Iso currency code like: USD or NOK. Case insensitive. |
Returns
Type | Description |
---|---|
int | Return all pricelists if isoCurrencyCode is empty. Return an empty array if there is no PriceList with the stated currency available. |
GetNumberOfProductImages(string)
Gets the number of images available for this product
Declaration
int GetNumberOfProductImages(string erpProductKey)
Parameters
Type | Name | Description |
---|---|---|
string | erpProductKey |
Returns
Type | Description |
---|---|
int | Count of images |
GetOrderState(QuoteAlternativeContextInfo)
After the order is created in the ERP system and the user wants to see what the current state of the order is this function gets called.
This new version will be displayed in the GUI. Requires that the Order-State capability is true.Declaration
OrderResponseInfo GetOrderState(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context |
Returns
Type | Description |
---|---|
OrderResponseInfo | If nothing has changed it should return null. To create a new QuoteVersion, set OrderResponseInfo.CRMQuoteVersion.QuoteVersionId to 0, and return a new version with a new alternative and quotelines describing the current state. |
GetProduct(QuoteAlternativeContextInfo, string)
Gets a product based on erpProductKey
Declaration
ProductInfo GetProduct(QuoteAlternativeContextInfo context, string erpProductKey)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | |
string | erpProductKey |
Returns
Type | Description |
---|---|
ProductInfo | Returns the product with the specified key. |
Exceptions
Type | Condition |
---|---|
ArgumentException | If the argument is null or empty , the function will throw an ArgumentException. |
Exception | If the product is not found , the function will throw an Exception. |
GetProductImage(string, int)
Gets the full size picture of the given product.
Declaration
string GetProductImage(string erpProductKey, int rank)
Parameters
Type | Name | Description |
---|---|---|
string | erpProductKey | |
int | rank | Which of the images to return, will in the first version only ask for the first. |
Returns
Type | Description |
---|---|
string | Returns the full size picture of the given product. Return NULL if no picture available. |
Exceptions
Type | Condition |
---|---|
ArgumentException | If the erpProductKey is null or empty , the function will throw an ArgumentException. |
Exception | If the product is not found , the function will throw an Exception. |
GetProducts(QuoteAlternativeContextInfo, string[])
See GetProduct for details
Declaration
ProductInfo[] GetProducts(QuoteAlternativeContextInfo context, string[] erpProductKeys)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | |
string[] | erpProductKeys |
Returns
Type | Description |
---|---|
ProductInfo[] | Return products based on an array of unique ERP keys; handy when you’ve found products through archiveproviders or other mechanisms that leave you holding an ERPKey |
GetQuoteLinesFromProduct(QuoteAlternativeContextInfo, string)
Given a product ERP Key, return one or more quote lines with the product data filled in, and some default values , typically quantity set to 1 (but not necessarily!) The quoteLineId will be provided by SuperOffice later.
Declaration
QuoteLineInfo[] GetQuoteLinesFromProduct(QuoteAlternativeContextInfo context, string erpProductKey)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | |
string | erpProductKey |
Returns
Type | Description |
---|---|
QuoteLineInfo[] | Return the QuoteLine(-s) with the product info filled in. |
Exceptions
Type | Condition |
---|---|
ArgumentException | If the erpProductKey is null or empty , the function will throw an ArgumentException. |
Exception | If the product is not found , the function will throw an Exception. |
GetQuoteList(string)
Gets a named list from the connector.
There are a few lists in the ERP system that we would like to show to the users: payment terms and types, delivery terms and types, and product classifications (product category, product family and product type). These lists can be supplied by the ERP connector using this interface. SuperOffice will take these values and convert the simple flat list of values into a SuperOffice list that appears in the GUI. If the ERP connector wants to supply a more complex nested list, then the ERP connector can implement a full MDO Provider. There are some lists in the system we would like the ERP system to provide data for, if it can: • ProductCategory • ProductFamily • ProductType • PaymentTerms • PaymentType • DeliveryTerms • DeliveryType If a quote list is NULL, then the GUI will fall back to a text input field, where the user can enter text. This text is passed to the ERP plugin unchanged. The Quote configuration API may also refer to custom list names which will be filled in by asking here. I.e. you will be asked for more lists than just the ones mentioned here, if you have added custom lists to the configuration dialog.Declaration
ListItemInfo[] GetQuoteList(string quoteListType)
Parameters
Type | Name | Description |
---|---|---|
string | quoteListType | The quoteListType parameter is case insensitive. |
Returns
Type | Description |
---|---|
ListItemInfo[] | Return array of QuoteListItems. Return NULL if the given list is not supported. |
GetSearchResults(SearchRestrictionInfo[])
Perform the advanced search and return results
Declaration
ProductInfo[] GetSearchResults(SearchRestrictionInfo[] restrictions)
Parameters
Type | Name | Description |
---|---|---|
SearchRestrictionInfo[] | restrictions | Array of restrictions chosen by the user; see SearchRestrictionInfo for details |
Returns
Type | Description |
---|---|
ProductInfo[] | Array (possibly empty) of hits, populated as fully as reasonably possible (should follow same policy as IProductProvider.FindProducts |
GetSearchableFields()
Get metadata about the fields that can be used as search criteria. Note that they do not have to be the same as the fields in the ProductInfo structure; but erpPriceListKey has to be supported.
Declaration
FieldMetadataInfo[] GetSearchableFields()
Returns
Type | Description |
---|---|
FieldMetadataInfo[] | Metadata structures |
Remarks
There are three levels of searching:
a) Quick search through IProductProvider.FindProduct - this is mandatory for all connectors that provide products
b) Advanced search through IProductSearchProvider - this is optional, and implements are more generic search,
but still with a fixed result type (ProductInfo array)
c) Implement an Archive Provider called FindProduct<Your connector name> - this is a fully custom provider
that can do whatever it wants, but it has to support a minimal result and restriction column set.
InitializeConnection(QuoteConnectionInfo, UserInfo, bool, Dictionary<string, string>, IProductRegisterCache)
Set up the connection to the ERP system. Will be called as part of SuperOffice client startup for each installed connection. Configuration data comes from the configuration dialog shown in the Admin client (GetConfigurationFields())
Declaration
PluginResponseInfo InitializeConnection(QuoteConnectionInfo connectionData, UserInfo user, bool isOnTravel, Dictionary<string, string> connectionConfigFields, IProductRegisterCache productRegister)
Parameters
Type | Name | Description |
---|---|---|
QuoteConnectionInfo | connectionData | Contains the configuration values defined in the Admin client. |
UserInfo | user | Information about the logged in user |
bool | isOnTravel | Is the user on Travel? |
Dictionary<string, string> | connectionConfigFields | {"name" = "value"}. The names are defined by the FieldMetadata. The values are what the user typed into the fields in the configure connection dialog. |
IProductRegisterCache | productRegister | Product caching object that allows connectors to stash product information in the SuperOffice database for off-line use. |
Returns
Type | Description |
---|---|
PluginResponseInfo | IsOk set to false if connector can’t provide service (no network); The connector is then ignored until the application restarts. |
OnAfterSaveQuote(QuoteAlternativeContextInfo)
Called after a sale containing a quote is saved or created. (Notice that new items have now gotten their ids in the CRM system.)
Declaration
void OnAfterSaveQuote(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The quote and its parts. Contact, Person, Project are read-only. Quote, QuoteRevision, QuoteAlternative parts can be changed before the save. |
OnAfterSentQuoteVersion(QuoteVersionContextInfo)
Called after a quote version is sent to the user's customer.
You may do extra work and return the modified the Quote Version info, but you cannot abort the sending process. Any mail or document generation in SuperOffice is independent of the connector.Declaration
QuoteSentResponseInfo OnAfterSentQuoteVersion(QuoteVersionContextInfo quoteContext)
Parameters
Type | Name | Description |
---|---|---|
QuoteVersionContextInfo | quoteContext | The Quote Version that was sent to the customer |
Returns
Type | Description |
---|---|
QuoteSentResponseInfo | URL and/or modified quote version info. |
OnBeforeCreateQuote(QuoteAlternativeContextInfo)
Called when a user is creating a quote. The Quote does not exist in database at this time; any changes in the returned QuoteResponseInfo will be saved and the GUI updated.
Declaration
QuoteResponseInfo OnBeforeCreateQuote(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The quote and its parts. |
Returns
Type | Description |
---|---|
QuoteResponseInfo | An updated quote. If returns IsOk = false, then quote creation is aborted. |
OnBeforeCreateQuoteAlternative(QuoteAlternativeContextInfo)
Called when a user is creating a quote alternative. The quote alternative does not exist in database at this time; any changes in the returned Quote alternative will be saved and the GUI updated.
Declaration
QuoteAlternativeResponseInfo OnBeforeCreateQuoteAlternative(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The quote and its parts. |
Returns
Type | Description |
---|---|
QuoteAlternativeResponseInfo | An updated quote alternative. If returns IsOk = false, then quote alternative creation is aborted. |
OnBeforeCreateQuoteVersion(QuoteVersionContextInfo)
Called when a user is creating a new quoteversion. The version does not exist in database at this time; any changes in the returned QuoteVersionResponseInfo will be saved and the GUI updated.
Declaration
QuoteVersionResponseInfo OnBeforeCreateQuoteVersion(QuoteVersionContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteVersionContextInfo | context | The quote and its parts. |
Returns
Type | Description |
---|---|
QuoteVersionResponseInfo | An updated quote version. If returns IsOk = false, then quoteversion creation is aborted. |
OnBeforeDeleteQuote(QuoteInfo, ISaleInfo, IContactInfo)
Called before a sale containing a quote is deleted. Clean up in the ERP system, if needed.
The connector cannot stop the quote being deleted in the CRM system.Declaration
void OnBeforeDeleteQuote(QuoteInfo quote, ISaleInfo sale, IContactInfo contact)
Parameters
Type | Name | Description |
---|---|---|
QuoteInfo | quote | The Quote being deleted |
ISaleInfo | sale | The sale the quote belongs to |
IContactInfo | contact | The main contact on the sale |
OnQuoteLineChanged(QuoteAlternativeContextInfo, QuoteLineInfo, string[])
Called when the user has changed a field in the Quote Line. The QuoteContext is readonly; QuoteLine may be changed in the return value. Response time must be fast since this method is called often (every time a field is changed).
Declaration
QuoteLineInfo OnQuoteLineChanged(QuoteAlternativeContextInfo context, QuoteLineInfo ql, string[] changedFields)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The alternative this quoteline belongs to |
QuoteLineInfo | ql | The changed quoteline |
string[] | changedFields | List of fields that were changed, in the format: "TableName.FieldName" |
Returns
Type | Description |
---|---|
QuoteLineInfo | The updated quote line |
Remarks
The connect can signal errors or warnings by setting the Status and Reason fields. This information will be displayed in the Quote Line dialog and in the quote-line archive.
PlaceOrder(QuoteAlternativeContextInfo)
Some ERP systems will be able to turn quotes into orders. The user selects a quote alternative to send to the ERP system and clicks OK in the CREATE ORDER dialog. After the Quote has been accepted/sold, then the user can check the delivery status with the ERP system.
Place the order in the ERP system. If the operation retuns successfully, the Quote will be locked (completed) in the CRM system and all updates will come from the ERP system thru the GetOrderState function. Requires that the Create-Order capability is true. If the Create-Order capability is false, then this function is not called.Declaration
PlaceOrderResponseInfo PlaceOrder(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The selected Quote Alternative, along with the version and lines |
Returns
Type | Description |
---|---|
PlaceOrderResponseInfo | The context, with any updates. The ERPOrderKey should be filled in with the id of the generated order. If the returned state in not OK, then the PlaceOrder call is aborted and the error message displayed. |
RecalculateQuoteAlternative(QuoteAlternativeContextInfo)
The user is finished with entering the quotelines, and wants to calculate the order discount (alternative discount) on this alternative. This method is called whenever the quote lines are changed in the alternative, or when the user clicks the RECALCULATE button.
Declaration
QuoteAlternativeWithLinesInfo RecalculateQuoteAlternative(QuoteAlternativeContextInfo context)
Parameters
Type | Name | Description |
---|---|---|
QuoteAlternativeContextInfo | context | The context as it appears to the user |
Returns
Type | Description |
---|---|
QuoteAlternativeWithLinesInfo | The updated alternative |
Remarks
The connector may signal problems with the quote by setting the Quote Alternative Status to Error, Warning or OkWithInfo, and fill in the alternative's Reason field with an explanation.
Use CalculateQuoteAlternativeWithLines(QuoteAlternativeWithLinesInfo) to help you calculate amounts.TestConnection(Dictionary<string, string>)
Check that the ERP connection is good. Return some status info that the Admin client can show to the user.
Testing if the connection data is sufficient to get a connection with the ERP system. The Connector should try to do some operations to check if the connection has sufficient rights to run. The connection has not been created yet.Declaration
PluginResponseInfo TestConnection(Dictionary<string, string> connectionData)
Parameters
Type | Name | Description |
---|---|---|
Dictionary<string, string> | connectionData | {"name" = "value"}. The names are defined by the FieldMetadata. The values are what the user typed into the fields in the configure connection dialog. |
Returns
Type | Description |
---|---|
PluginResponseInfo | Ok or not + a status or error message. This message is shown in a result dialog. |
UpdateQuoteVersionPrices(QuoteVersionContextInfo, HashSet<string>)
Fetch new prices from the pricelist for all the alternatives in the quote. This method is explicitly triggered by the user clicking the UPDATE PRICES button in the quote dialog.
The connector should update all the quotelines on all the alternatives with new list prices, minimum prices, cost prices, etc from the pricelist, and update the ERP discount suggestions.Declaration
QuoteVersionResponseInfo UpdateQuoteVersionPrices(QuoteVersionContextInfo context, HashSet<string> writeableFields)
Parameters
Type | Name | Description |
---|---|---|
QuoteVersionContextInfo | context | The quote version, with alternatives and quote lines |
HashSet<string> | writeableFields | Collection of quoteline fieldnames that are writeable according to the QuotelineConfiguration table. Fieldnames are all lowercase. |
Returns
Type | Description |
---|---|
QuoteVersionResponseInfo | Updated quote version, with alternatives and quote lines. |
Remarks
The system will call ValidateQuoteVersion(QuoteVersionContextInfo, QuoteAction) after calling this method to determine the new version state.
ValidateQuoteVersion(QuoteVersionContextInfo, QuoteAction)
Validates the version, looks for problems. Will typically change the Status and Reason fields, possibly change the State to NeedsApproval. Should validate all the alternatives and their quote-lines. The user is finished with entering the quote-lines, and wants to prepare the sending of the quote. This method gives the ERP system a chance to enforce its business rules.
This method is called whenever the user clicks the SEND button, the PLACE ORDER or closes the quote dialog. Quote Lines, Alternatives, Version and Quote fields can be changed in the return value. Use CalculateVersionWithAlternatives(QuoteVersionContextInfo) to help you calculate amounts.Declaration
QuoteResponseInfo ValidateQuoteVersion(QuoteVersionContextInfo context, QuoteAction action)
Parameters
Type | Name | Description |
---|---|---|
QuoteVersionContextInfo | context | The context as it appears to the user |
QuoteAction | action | The action that started this call; the context it is called in, like place order or send quote |
Returns
Type | Description |
---|---|
QuoteResponseInfo | The updated Context, with changes to State and UserExplanation if needed. |
Remarks
Validation should not change the prices on quotelines - it should ensure conformance to business rules.
A draft quote version will have state = DraftNotCalculated when called. The connector should set the version state to QuoteVersionStateInfo.DraftCalculated if the calculations were successful. Leave the state as DraftNotCalculated if the ERP system was not available or some other factor that made the calculation unsuccessful. The connector can trigger the approval workflow by setting the state to DraftNeedsApproval. When a user with the approval permission has approved or rejected the quote, the quote version state will be DraftApproved or DraftNotApproved. Note that recalculate may also be called when the quote is Approved, or Archived. In these cases, please leave the quote version state alone. The connector may signal problems with the quote by setting the Quote Version Status to Error, Warning or OkWithInfo, and fill in the version's Reason field with an explanation. The QuoteConnectorBase implementation of this method defines methods for validating ValidateQuoteLine(QuoteAlternativeContextInfo, QuoteLineInfo, bool)