SPAlert.Filter not working - sharepoint-2013

Can anybody help with SPAlert filters on Sharepoint 2013?
If I set Filter property on SPAlert instance the alert has not been sent
SPAlert newAlert = user.Alerts.Add();
SPAlertTemplateCollection alertTemplates = new SPAlertTemplateCollection(
(SPWebService)(SPContext.Current.Site.WebApplication.Parent));
newAlert.AlertType = SPAlertType.List;
newAlert.List = list;
newAlert.Title = alertTitle;
newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
newAlert.EventType = eventType;
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
var wsm = new WorkflowServicesManager(web);
var wss = wsm.GetWorkflowSubscriptionService();
var subscriptions = wss.EnumerateSubscriptionsByList(list.ID);
bool assotiationExist = false;
var guid = Constants.Workflows.ApprovalWF.Guid;
foreach (var subs in subscriptions)
{
assotiationExist = subs.DefinitionId == guid;
if (assotiationExist)
{
newAlert.Filter = "<Query><Eq><FieldRef Name=\"ApprovalStatus\"/><Value type=\"string\">Approved</Value></Eq></Query>";
}
}
newAlert.Update(false);

If I set Filter property on SPAlert instance the alert has not been sent
What do you need exactly ?
If you just want to change the filter (alert condition), did you simply try :
newAlert.AlertType = SPAlertType.List;
newAlert.List = list;
newAlert.Title = alertTitle;
newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
newAlert.EventType = eventType;
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
newAlert.Filter = "<Query><Eq><FieldRef Name=\"ApprovalStatus/New\"/><Value type=\"string\">Approved</Value></Eq></Query>";
newAlert.Update(false);
I have just added a /New in your filter query. Query filter in alert need to get a /New or a /Old in your field.
If your alert still doesn't work, it might be something else than the filter.

The problem was in line newAlert.EventType = eventType. eventType was SPEventType.Add. That was the reason of not sending alert after Workflow set the ApprovalStatus field to «Approved».
I’ve modified algourithm. Now eventType is SPEventType.Modify and I added new field "IsNewAlertSent" to list. When event fires the first time then I send email and set the "IsNewAlertSent" field
Final code is shown below.
class UserAlertManager:
..
newAlert.EventType = (eventType == SPEventType.Add? SPEventType.Modify: eventType);
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
..
if (assotiationExist)
{
newAlert.Filter = "<Query><Eq><FieldRef name=\"ApprovalStatus\"/><Value type=\"Text\">Approved</Value></Eq></Query>";
newAlert.Properties.Add("grcustomalert", "1");
}
..
newAlert.Update(false);
class GRCustomAlertHandler:
...
string subject = string.Empty;
string body = string.Empty;
bool grCustomAlert = Utils.IsSPAlertCustom(ahp.a);
if (ahp.eventData[0].eventType == (int)SPEventType.Modify && grCustomAlert)
{
SPListItem item = list.GetItemById(ahp.eventData[0].itemId);
var isNewAlertSentField = item.Fields.GetFieldByInternalName(Constants.Fields.IsNewAlertSent);
if (isNewAlertSentField != null && (item[Constants.Fields.IsNewAlertSent] == null || !(bool)item[Constants.Fields.IsNewAlertSent]))
{
...
Utils.SendMail(web, new List<string> { ahp.headers["to"].ToString() }, subject, body);
item[Constants.Fields.IsNewAlertSent] = true;
using (new DisabledItemEventScope())
{
item.SystemUpdate(false);
}
}
}
...

Related

test class for handler trigger is not covered

I did a trigger on content version ,but my handler class is not covered ,can you please explain to me why ?
please find below the code and screenshots for non covered lines
in my test class ,i created all data needed for the handler class i call the method with content version input
Trigger:
trigger contentversiontrigger on ContentVersion (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
if(trigger.isAfter && trigger.isInsert) {
Bytel_ContentVersionTriggerHandler.AlignAttachementsWithOpportunity(Trigger.New);
}
}
Trigger Handler
public with sharing class Bytel_ContentVersionTriggerHandler extends TriggerHandler {
public static void AlignAttachementsWithOpportunity(List<ContentVersion> contentVersion) {
Set<Id> contentDocumentIdSet = new Set<Id>();
String Contractid;
String Opportunityid;
for (ContentVersion cv : contentVersion) {
if(cv.ContentDocumentId != null)
{
contentDocumentIdSet.add(cv.ContentDocumentId);
}
}
list<ContentDocumentLink> cdl = [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN:contentDocumentIdSet];
id LinkedEntityId =cdl[0].LinkedEntityId ;
// List<Contract> contractList = [SELECT Id, name FROM Contract where Id =:cdl.LinkedEntityId];
list<contract> Contracts = [SELECT Id, name FROM Contract where Id =:LinkedEntityId ];
if (!Contracts.isEmpty())
{
Contractid=Contracts[0].Id;
}
// Id Contractid = [SELECT Id, name FROM Contract where Id ='8005t0000001UQFAA2' limit 1].Id;
system.debug('test trigger' +Contractid) ;
// String Contractid= String.valueof(contractList[0].Id);
system.debug('ContractId' +Contractid) ;
list<Contract> contractssecond=[SELECT id ,vlocity_cmt__OpportunityId__c FROM Contract WHERE id =:Contractid limit 1];
if (!contractssecond.isEmpty())
{
Opportunityid=contractssecond[0].vlocity_cmt__OpportunityId__c;
}
system.debug('Opportunityid' +Opportunityid) ;
Id conDoc = cdl[0].ContentDocumentId;
//if (Opportunityid!=Null & conDoc!=Null) {
if (Opportunityid!=Null ) {
//create ContentDocumentLink record
ContentDocumentLink conDocLink = New ContentDocumentLink();
conDocLink.LinkedEntityId = Opportunityid;
conDocLink.ContentDocumentId = conDoc; //ContentDocumentId Id from ContentVersion
conDocLink.shareType = 'V';
insert conDocLink;
}
}
}
Test class of handler
#isTest
public class Bytel_ContentVersionTriggerHandlerTest {
static testMethod void createattachememtns() {
insert Bytel_TestDataFactory.createByPassSettings(false); // Custom setting bypass profile
insert Bytel_TestDataFactory.createGlobalVariableSettings(); // Custom setting globalVaribale, parameter callout end-point
insert Bytel_TestDataFactory.createOpportunityRaisonEchecSettings();
insert Bytel_TestDataFactory.createOpportunityStatusSettings();
Account acc = new Account(
Name = 'Test Account',
TypeIdentifiant__c = 'SIREN',
SIREN__c = '123765982',
Statut__c = 'Prospect'
);
insert acc;
Opportunity opp = Bytel_TestDataFactory.createOpportunity(
'FILL AUTO',
'Etape10',
acc.Id,
null
);
opp.Tech_AccountIdToDelete__c = acc.id;
opp.ScoringFinancier__c = 'Vert';
opp.siren__c = '123765981';
insert opp;
Quote quote = new Quote(Name = 'devis1', OpportunityId = opp.Id);
insert quote;
Contract contract1 = new Contract(
vlocity_cmt__QuoteId__c = quote.Id,
vlocity_cmt__OpportunityId__c=opp.id,
AccountId = acc.id
);
insert contract1;
Contract contract2 = new Contract(
vlocity_cmt__QuoteId__c = quote.Id,
AccountId = acc.id,
vlocity_cmt__OpportunityId__c=opp.id
);
insert contract2;
Blob bodyBlob=Blob.valueOf('Unit Test ContentVersion Body to be insert in test class for testing the');
ContentVersion contentVersion_1 = new ContentVersion(
Title='SampleTitle',
PathOnClient ='SampleTitle.txt',
Type_de_Fichier__c='RIB',
VersionData = bodyBlob,
origin = 'H'
);
insert contentVersion_1;
Contract contra = [SELECT Id
FROM Contract WHERE Id = :contract1.Id LIMIT 1];
List<ContentVersion> contentVersion_2 = [SELECT Id, Title, ContentDocumentId
FROM ContentVersion WHERE Id = :contentVersion_1.Id ];
// ContentDocumentLink contentlink = new ContentDocumentLink();
// contentlink.LinkedEntityId = contra.id;
// contentlink.contentdocumentid = contentVersion_2.contentdocumentid;
// contentlink.ShareType = 'V';
// insert contentlink;
Bytel_ContentVersionTriggerHandler.AlignAttachementsWithOpportunity(contentVersion_2);
}
}
After a first look, I guess you forgot to add #isTest to your test method.
#isTest
static testMethod void createattachememtns() {
//Your Code
}

Search in agresso Query Engine

Is it possible to search/filter on columns with Agresso's QueryEngineService? I've been playing around with SearchCriteria.SearchCriteriaPropertiesList and TemplateResultOptions.Filter but without any luck. I havn't been able to locate any documentation on this matter either.
QueryEngineService.TemplateList templateList = QueryEngineService.GetTemplateList(null, null, Credentials);
var template = templateList.TemplateHeaderList.FirstOrDefault(x => x.Name == strViewName);
if (template == null)
return null;
QueryEngineService.SearchCriteria searchProp = QueryEngineService.GetSearchCriteria(template.TemplateId, false, Credentials);
QueryEngineService.TemplateResultOptions options = QueryEngineService.GetTemplateResultOptions(Credentials);
options.RemoveHiddenColumns = true;
QueryEngineService.InputForTemplateResult input = new QueryEngineService.InputForTemplateResult();
input.TemplateResultOptions = options;
input.TemplateId = template.TemplateId;
input.SearchCriteriaPropertiesList = searchProp.SearchCriteriaPropertiesList;
QueryEngineService.TemplateResultAsDataSet result = QueryEngineService.GetTemplateResultAsDataSet(input, Credentials);
return result.TemplateResult;
You can try to start with this:
List<SearchCriteriaProperties> searchCriteriaProperties = searchCriteria.getSearchCriteriaPropertiesList().getSearchCriteriaProperties();
SearchCriteriaProperties columnFilter = null;
for (SearchCriteriaProperties criteria : searchCriteriaProperties) {
if(criteria.getColumnName().equalsIgnoreCase("ColumnNameHere")) {
columnFilter = criteria;
columnFilter.setRestrictionType("=");
columnFilter.setFromValue("valueToAssign");
}
}
Next is add the columnFilter variable to an instance of the ArrayOfSearchCriteriaProperties() object by using the getSearchCriteriaProperties().add()
ArrayOfSearchCriteriaProperties filter = new ArrayOfSearchCriteriaProperties();
filter.getSearchCriteriaProperties().add(columnFilter);
You can now add the filter object to an instance of the InputForTemplateResult() object.
Working solution (for me)
QueryEngineService.SearchCriteria searchProp = QueryEngineService.GetSearchCriteria(template.TemplateId, false, Credentials);
foreach (QueryEngineService.SearchCriteriaProperties criteria in searchProp.SearchCriteriaPropertiesList)
{
if(criteria.ColumnName.Equals("column_name", StringComparison.OrdinalIgnoreCase))
{
criteria.RestrictionType = "=";
criteria.FromValue = "value";
}
}
//Rest of the code from question above

How to add dynamic values to field injections list with custom trigger to camunda properties panel?

I have two questions here
Is it possible to add dynamic lists values to field injection list input ?
Can I create a trigger for this so this can be initiated from any other input selection say a class selection will populate all fields
I was just looking into FieldInjection.js whether that can be extented for the same
Can someone please provide a hint or direction for this ?
Thanks.
For anyone interested in the answer, I was able to achieve the above goal by changing the set function of the Java Class select input as folllowing
few imports
var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
elementHelper = require('../../../../helper/ElementHelper')
var CAMUNDA_FIELD_EXTENSION_ELEMENT = 'camunda:Field';
function getExtensionFields(bo) {
return bo && extensionElementsHelper.getExtensionElements(bo, CAMUNDA_FIELD_EXTENSION_ELEMENT) || [];
}
then changing the set function to create extension element and push the field values as :
set: function(element, values, node) {
var bo = getBusinessObject(element);
var type = getImplementationType(element);
var attr = getAttribute(type);
var prop = {}
var commands = [];
prop[attr] = values.delegate || '';
var extensionElements = getExtensionFields(bo);
//remove any extension elements existing before
extensionElements.forEach(function(ele){
commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, ele));
});
if(prop[attr] !== ""){
var extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
var arrProperties = ["private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varOne","private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varTwo"]
var newFieldElem = "";
arrProperties.forEach(function(prop){
var eachProp = {
name:"",
string:"",
expression:""
}
var type = prop.split(" ")[1].split(".").reverse()[0];
var val = prop.split(" ")[2].split(".").reverse()[0];
eachProp.name = val;
if( type == "String"){
eachProp.string = "${" + val +" }"
}else if( type == "Expression"){
eachProp.expression = "${" + val +" }"
}
newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, eachProp, extensionElements, bpmnFactory);
commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newFieldElem ]));
});
}
commands.push(cmdHelper.updateBusinessObject(element, bo, prop));
return commands;
}
Cheers !.

Updating Location and ShipQty in Acumatica Shipment Lines

I'm having this weird problem in acumatica webservices, I'm updating existing Shipments in acumatica using webservices. My code is supposed to update the Location and ShippedQty but for no reason it updates all the items except the last one. It happens when the Shipment has multiple items. Please help me solve this problem, below is my code and an image of the Shipment screen with the last item not updated.
Thanks.
var commands = new List<Acumatica_LSOne_Integration.SO302000.Command>();
commands.Add(new SO302000.Value { Value = shipmentNbr, LinkedCommand = shipmentSchema.ShipmentSummary.ShipmentNbr });
commands.Add(new SO302000.Value { Value = shipmentType, LinkedCommand = shipmentSchema.ShipmentSummary.Type });
commands.Add(shipmentSchema.DocumentDetails.ShipmentNbr);
commands.Add(shipmentSchema.DocumentDetails.LineNbr);
commands.Add(shipmentSchema.DocumentDetails.InventoryID);
commands.Add(shipmentSchema.DocumentDetails.Warehouse);
commands.Add(shipmentSchema.DocumentDetails.Location);
commands.Add(shipmentSchema.DocumentDetails.OrderedQty);
var soLines = context.Submit(commands.ToArray());
List<Acumatica_LSOne_Integration.SO302000.Command> commandList = new List<Acumatica_LSOne_Integration.SO302000.Command>();
for (int index = 0; index < soLines.Length; index++)
{
string sShipNbr = soLines[index].DocumentDetails.ShipmentNbr.Value;
string sLineNbr = soLines[index].DocumentDetails.LineNbr.Value;
string sInventoryID = soLines[index].DocumentDetails.InventoryID.Value;
string sWarehouse = soLines[index].DocumentDetails.Warehouse.Value;
string sLocation = soLines[index].DocumentDetails.Location.Value;
string sOrderedQty = soLines[index].DocumentDetails.OrderedQty.Value;
commandList.Add(new SO302000.Key
{
ObjectName = shipmentSchema.DocumentDetails.ShipmentNbr.ObjectName,
FieldName = shipmentSchema.DocumentDetails.ShipmentNbr.FieldName,
Value = sShipNbr.Trim(), Commit = true
});
commandList.Add(new SO302000.Key
{
ObjectName = shipmentSchema.DocumentDetails.LineNbr.ObjectName,
FieldName = shipmentSchema.DocumentDetails.LineNbr.FieldName,
Value = sLineNbr.Trim(), Commit = true
});
commandList.Add(new SO302000.Value
{
Value = vLocation.Trim(),
LinkedCommand = shipmentSchema.DocumentDetails.Location
});
commandList.Add(new SO302000.Value { Value = sOrderedQty, LinkedCommand = shipmentSchema.DocumentDetails.ShippedQty,IgnoreError = true, Commit = true });
}
commandList.Add(shipmentSchema.Actions.ConfirmShipmentAction);
context.Submit(commandList.ToArray());
Sample Output:
I guessed that you have allowed negative quantity on your inventory, by default when an item has zero quantity on a particular warehouse the location will set as and a shipped quantity of zero and as I've seen you're code, check this line code
string sLocation = soLines[index].DocumentDetails.Location.Value;
if this soLine retreives a value as I guess this line is the cause why it won't update.
I've actually come up with a solution that works well using the Contract Based Web Services. Below is my sample code:
using (DefaultSoapClient soapClient = new DefaultSoapClient())
{
InitializeWebService(soapClient,sAUser,sAPass,vCompany,vBranchID);
Shipment shipmentToBeFound = new Shipment
{
Type = new StringSearch { Value = shipmentType },
ShipmentNbr = new StringSearch { Value = shipmentNbr },
};
Shipment shipment = (Shipment)soapClient.Get(shipmentToBeFound);
int iLineNbr = Int32.Parse(sLineNbr);
ShipmentDetail shipmentLine = shipment.Details.Single(
orderLineToBeUpdated =>
orderLineToBeUpdated.LineNbr.Value == iLineNbr);
shipmentLine.LocationID = new StringValue { Value = vLocation.Trim() };
shipmentLine.ShippedQty = new DecimalValue { Value = decimal.Parse(sOrderedQty) };
shipment = (Shipment)soapClient.Put(shipment);
soapClient.Logout();
}

model item passed into dictionary is of type 'system.Collections.Generic.List'1[System.String]',but dictionary is model B

I am trying to create a create combobox with performcallback, but I got the error. here this error "the model item passed into dictionary is of type 'system.Collections.Generic.Lost'1[System.String]', but this dix=ctionary requires a model item of type 'DIS_iDealer.Models.SalesMonitoringModel'"
I don't know which code exactly I need to paste but this is what I have:
view combobox :
#model DIS_iDealer.Models.SalesMonitoringModel
#Html.DevExpress().ComboBoxFor(m => m.mpmGroupLine.DESCRIPTION, settings =>
{
settings.Name = "Desc_ID_CB";
settings.Properties.IncrementalFilteringMode = IncrementalFilteringMode.Contains;
settings.Properties.DropDownStyle = DropDownStyle.DropDownList;
settings.CallbackRouteValues = new { Controller = "Report", Action = "cbPartialCategoryDetail" };
settings.Properties.CallbackPageSize = 50;
settings.Properties.ValueField = "DESCRIPTION";
settings.Properties.TextField = "DESCRIPTION";
settings.Width = 150;
settings.SelectedIndex = 0;
settings.Properties.ClientSideEvents.BeginCallback = "function(s,e){e.customArgs['group_Id'] = Category_Id_CB.GetValue()}";
settings.Properties.ValidationSettings.ErrorTextPosition = ErrorTextPosition.Right;
settings.Properties.ValidationSettings.ErrorDisplayMode = ErrorDisplayMode.ImageWithText;
settings.Properties.ValidationSettings.Display = Display.Dynamic;
}).BindList((List<string>)new DIS_iDealer.DataAccess.SalesMonitoringDAC().GetProductGroupDetail(Model.mpmGroupLine.GROUPID).ToList()).GetHtml()
controller :
namespace DIS_iDealer.Controllers
{
public class ReportController : BaseController
{
[HttpGet]
public ActionResult Report_SalesMonitoring_2()
{
SalesMonitoringModel mode = new SalesMonitoringModel();
//MPMPRODUCTGROUPLINE itemB = new MPMPRODUCTGROUPLINE();
/*List<string> mpmCate = mode.GetProductGroup();
if (mpmCate != null)
{
itemB.DESCRIPTION = mode.mpmGroupLine.DESCRIPTION;
}*/
ReportModels modelReport = new ReportModels();
if (TempData["ReportSalesMonitoring2"] != null)
{
modelReport = (ReportModels)TempData["ReportSalesMonitoring2"];
string reportParam = string.Empty;
foreach (string item in modelReport.ParameterReport)
{
reportParam += item;
}
ViewBag.IframeURL = modelReport.WebURL + reportParam;
}
return View(mode);
}
[ValidateInput(false)]
public ActionResult cbPartialCategoryDetail(string group_Id)
{
//SalesMonitoringModel model = new SalesMonitoringModel();
SalesMonitoringDAC model = new SalesMonitoringDAC();
List<string> itemDetail = model.GetProductGroupDetail(group_Id);
return PartialView("_cbPartialCategoryDetail", itemDetail);
}
}
}
Please let me know if you need more info. Thanks.