Extension > Costly SQL NVARCHAR Assumption when Using Dapper

Any time we filter in SQL on a VARCHAR column, it's best to send the parameter as an ANSI string. That way it can use the index more effectively. Dapper assumes NVARCHAR, and not all fields are NVARCHAR in Disco. That looks like this: ``` var parameters = new { CommissionBeginDate = commissionBeginDate.Date, CommissionEndDate = commissionEndDate.Date, // BonusGroup = bonusGroup, // REPLACE with the line below BonusGroup = new DbString { IsAnsi = true, Length = 100, Value = bonusGroup }; }; var query = @"Select AssociateID,Sum(Amount) Amount From CRM_CommissionHistory Where [Group] = @BonusGroup And ComPeriodID in (Select recordnumber From CRM_CommissionPeriods Where Begindate >= @CommissionBeginDate And EndDate <= @CommissionEndDate And PeriodName='ClientWeekly') Group By AssociateID "; return dbHelper.Query<AssociateTeamRoyaltyBonus>(query, parameters).ToList(); ``` This will aid in the performance of the query. We mention it only because there are a lot expensive queries that go against the CRM_CommissionAssociateValues, CommissionPeriod, and Stats tables, that will benefit greatly from this addition.

How to Pass Binary Placement Information via API?

# Question How do I pass binary placement information via an API? # Answer For [custom content in **Cloudspark**](https://developers.directscale.com/docs/getting-started-with-front-end-development), the **NewApplication** object has a property named **Placements**. This property overrides the application placement that the caller can use to change the default placement during the enrollment process. DirectScale internal V1 and V2 APIs use the **NewApplication** object, but you can only call these from **CloudSpark**, not the Public API. The Public API has a version of the **Application** request object called [**CreateCustomer**](https://apigateway.directscale.com/docs/services/57fe6761cb00f20ae896cc68/operations/57fe7e33cb00f20ae896cc6b?); however, it does not expose the **Placements** property. In short, the Client Extension [**Application** object](https://helpabstractions.directscale.com/api/DirectScale.Disco.Extension.Application.html?q=application) contains all of the information required to enroll a new Associate as well as upgrade an Associate from a Retail Customer to a Distributor. This object has the [**Placements** properties](https://helpabstractions.directscale.com/api/DirectScale.Disco.Extension.Placement.html). You will have to [create a custom API endpoint](https://developers.directscale.com/docs/example-custom-api) that calls the method on the service inside the Extension.
ANSWERED

Extension > How do I place a person in a tree in custom code?

# Question How do I place a person in a tree in custom Extension code? # Answer Sometimes in code, you'll need to place a person in a tree. The Extension makes that possible quite easily, but the syntax isn't readily clear. ### A word of caution: > Trees are important to the business, so making mistakes here can result in a lot of work. Please make sure you're comfortable with tree structure, tree types, and that you know how to test and check the results of moves in Corp Admin. The concept of a **node** is used. This is a spot in the tree, and it "knows" about itself: who its parent is, and who it contains. The "ValidatePlacement" call you see is to make sure you don't create circular references. Here, we're placing in the "Enroller Tree". For Unilevel and Enroller tree, you need to specify the LegName as "LegName.Empty", not just "null", or you'll get a null reference exception. For Binary or Matrix trees, you can use the appropriate LegNames in that enumeration. ```csharp var _nodeId = new DirectScale.Disco.Extension.NodeId(_associate.AssociateId); var enrollernodeDetail = _treeService.GetNodeDetail(_nodeId, TreeType.Enrollment); try { _treeService.ValidatePlacements( new Placement[] { new Placement() { Tree = TreeType.Unilevel, NodeDetail = new NodeDetail() { NodeId = _nodeId, UplineId = enrollernodeDetail.UplineId, UplineLeg = LegName.Empty } } }); _treeService.Place(new Placement[] { new Placement() { Tree = TreeType.Unilevel, NodeDetail = new NodeDetail() { NodeId = _nodeId, UplineId = enrollernodeDetail.UplineId, UplineLeg = LegName.Empty } }; }); } ```

Q: Is there a way to see a list of datapoint filter names in the public apis?

![](https://lxteam.blob.core.windows.net/images/DevSite/2021-03-17%2013_55_43-%E2%97%8F%20Untitled-2%20-%20LearningExperience%20-%20Visual%20Studio%20Code.png) To get a list of Data Point Filters, like the ones shown in the preceding example, you can use the [Get Data Point Categories](https://apigateway.directscale.com/docs/services/57fe6761cb00f20ae896cc68/operations/5be5fe055c40b04cea138665?&pattern=categories) call. Request URL: `https://dsapi.directscale.com/v1/customers/datapoint-categories` This list is also provided here: [Data Point Categories (GADP)](https://developers.directscale.com/docs/get-associate-data-points-gadp)

Extension > Setting money-out provider

# Question How do I specify a payout provider for an associate in custom code? # Answer Using two options: 1. IMoneyOutService.AutoProvisionAccount (creates account and assigns to Associate) 2. IMoneyOutService.SetActiveOnFileMerchant (assigns associate to certain provider without provisioning account) This conversation helps describe the problem and solution: - When someone signs up how do we know what money out merchant they are going to use? If you have two money out merchants one for the US and one for Europe. when someone enrolls I need to send them to the correct money out merchant. - I'm not sure. There's probably a way to do it now. We don't have a method that just does that last part. Wouldn't you just hook submit_application and call this method with the right merchantId? - but I don't have the Associate Values yet. That is the exact reason I need it - Then you would call **IMoneyOutService.AutoProvisionAccount** which would set the values and make it active - I do not want to create their account (in the money-out provider's system) until commissions are earned. - Then **SetActiveOnFileMerchant** would work, and you pass in some default or empty associate values

How does the Text Number field get set when you're creating the customer via the public API?

# Question How does the **Text Number** field get set when you're creating the customer via the Public API? ![](https://lxteam.blob.core.windows.net/images/DevSite/textNumber.png) # Answer Using the [POST Create Customer](https://apigateway.directscale.com/docs/services/57fe6761cb00f20ae896cc68/operations/57fe7e33cb00f20ae896cc6b) endpoint, you can add the following field: ```json "TextPhone": "+1 801 555-1111", ``` Read more about the Public API in [Public API Overview](https://developers.directscale.com/docs/public-api-overview)

Commissions > How often does the system recalculate commissions? Is it on a new order? Or on a schedule? Does it recalculate only the open period or any un-locked period?

I got this from a client, and it's a common question. Here's the answer: For commissions, the system recalculates whenever there is a "commissionable event" (sale, sign-up, refund). So, when an associate creates an order, they are put on the "stats queue". Then, any person impacted by that order is recalculated. Usually this takes 2 minutes for the average company (it changes some based on distributor count and comp plan complexity). So, the updates are nearly real-time. The same is true for "projected commissions". If you look at the guts of the system, it's actually running independent stats jobs for current and future period stats. It uses the comp plan to calculate stats. You can see the settings in the "Commission" section of Advanced Settings for a little more info on it.

Custom Money Out Integration for ACH

# Use Cases 1. User enables new ACH money out option 1. Cloudspark: New CloudSpark page with a form that does the work? 2. Disco: Impersonate into CS, create a link into the web office page, or create a custom Disco page. 2. User updates ACH money out option 1. User fills out the same page as in use case 1. Data is replaced. 3. User wants to know where their payment is 1. User sees data on the page (as in use case 1) # Solution ## Software Structure Cambridge application needs to be developed in a NuGet package owned, maintained, and deployed by Cambridge. The Client Extension will reference this package during installation. The solution must be developed in the DirectScale Client Extension. Cloudspark elements will need to be added through the Admin tool. The outcome of the project will be clear documentation surrounding the setup and management of admin elements. ### Task 1 - Build Disco API to Set Cambridge Data on Disco **Custom API build in Disco** - Set the associate to the Cambridge account - Set the unique Beneficiary ID on that account ### Task 2 - Allow User to Enable and Manage ACH Money-out Option **Option 1** **Preferred:** Create a form that validates the fields and calls custom API (Task 1) to set that associate to Cambridge and adds their beneficiary ID to the database. **This form would be owned, hosted, and controlled by Cambridge. (Cambridge not ready for this option right now)** - DS enables SSO on the links to the page. - Cambridge develops DS SSO link - Dev team adds a custom page in Web Office that iFrames Cambridge page. - Call Custom API **Option 2** Create a custom page in the web office that validates the IBan and does the bank search calling out to Cambridge and calls an API in disco (Task 1) to set the Unique Beneficiary ID for that user. ### Task 3 - Implement the Money-out Interaction with Cambridge **Custom Money Out Merchant** Create a custom class inside that inherits from **AccountCommissionMerchant** and complete the different methods **PayCommissions** - This is the location that will tell Cambridge how much money each associate has earned and will return the status of those payments. **ProvisionAccount** - could inform the associate to go to the custom page and create their account ``` public class CustomHyperWalletMoneyOutMerchant : AccountCommissionMerchant { private const string ACCOUNT_NUMBER_KEY = "ActNum"; public CustomHyperWalletMoneyOutMerchant() : base( new MerchantInfo(5555, "CustomHyperWallet", "USD") , new List<CommissionMerchantCustomField> { new CommissionMerchantCustomField { DisplayText = "Account Number", Key = ACCOUNT_NUMBER_KEY, IsRequired = true } }) { } public override CommissionPaymentResults PayCommissions(int batchId, List<CommissionPayment> payments) { var results = new List<CommissionPaymentResult>(); foreach (var payment in payments) { // Be careful here! // We process the whole batch at once, so you have to provide the error handling so the statuses are correctly saved. // If half of the payments succeeded, but then an exception were thrown, disco would not receive the CommissionPaymentResults // and would be unaware that any of the payments went out. Try - catch handling is necessary try { if (payment.MerchantCustomFields.TryGetValue(ACCOUNT_NUMBER_KEY, out string accountNumber)) { // call out to merchant to process payment results.Add(new CommissionPaymentResult() { PaymentUniqueId = payment.PaymentUniqueId, // This one is important that you manually set this equal to the payment you just processed TransactionNumber = payment.PaymentUniqueId, Status = CommissionPaymentStatus.Paid, DatePaid = DateTime.Now, CheckNumber = 100, }); } else { results.Add(new CommissionPaymentResult() { PaymentUniqueId = payment.PaymentUniqueId, // This one is important that you manually set this equal to the payment you just processed Status = CommissionPaymentStatus.Failed, ErrorMessage = "Account not initialized" }); } } catch (Exception e) { results.Add(new CommissionPaymentResult() { PaymentUniqueId = payment.PaymentUniqueId, // This one is important that you manually set this equal to the payment you just processed Status = CommissionPaymentStatus.Failed, ErrorMessage = $"Exception ocurred while paying {payment.AssociateId} : {e.Message}" }) ; } } return new CommissionPaymentResults { Results = results }; } public override CommissionMerchantAccountFields ProvisionAccount(int associateID) { // Create an account for this associate, and any other custom values you need in PayCommissions return new CommissionMerchantAccountFields { CustomValues = new Dictionary<string, string> { { ACCOUNT_NUMBER_KEY, "Response account number" } } }; } } } ``` Read more: [Setting Up a Money Out Payment Provider](https://help.directscale.com/hc/en-us/articles/360053606693-Setting-Up-a-Money-Out-Payment-Provider) ### Task 4 - Credentials We discussed the Partner Key (DirectScale) being stored in the Nu Get package since it will not change. The client key and (another one) will need to be either passed in the constructor from the registration in the Client DLL OR stored in a DB table and retrieved. This may include CRUD for management of the creds.