Updating Location and ShipQty in Acumatica Shipment Lines - web-services

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();
}

Related

Multiple events getting created on creating event in Teams with 100 members using Graph API

I am creating teams event using Graph API in my Azure function. For 10-30 members, I am able to create an event in MS Teams using Graph. It is sending an email notification also to the members for Join meeting.
When I tried with 50-100 members, multiple events getting created and multiple email notification also sending to each member.
Is there any member limitation or my code issue?
DateTime dStartDate = DateTime.Parse(session.SessionStartDateTime);
DateTime dEndDate = DateTime.Parse(session.SessionEndDateTime);
List<Microsoft.Graph.DayOfWeek> dayOfWeeks = new List<Microsoft.Graph.DayOfWeek>();
dayOfWeeks.Add(Microsoft.Graph.DayOfWeek.Monday);
dayOfWeeks.Add(Microsoft.Graph.DayOfWeek.Tuesday);
Event #event = new Event
{
Subject = "Test Meeting",
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = "Online Meeting - Test Meeting"
},
Start = new DateTimeTimeZone
{
DateTime = session.StartDateStartTime,
TimeZone = "Eastern Standard Time"
},
End = new DateTimeTimeZone
{
DateTime = session.StartDateEndTime,
TimeZone = "Eastern Standard Time"
},
Location = new Location
{
DisplayName = "Online"
},
Recurrence = new PatternedRecurrence
{
Pattern = new RecurrencePattern
{
Type = Weekly,
Interval = 1,
DaysOfWeek = dayOfWeeks
},
Range = new RecurrenceRange
{
Type = EndDate,
StartDate = new Date(dStartDate.Year, dStartDate.Month, dStartDate.Day),
EndDate = new Date(dEndDate.Year, dEndDate.Month, dEndDate.Day)
}
};
IsOnlineMeeting = true,
OnlineMeetingProvider = "TeamsForBusiness"
};
List<Attendee> attendees = new List<Attendee>();
if (session?.instructors?.Count > 0)
{
session.instructors.ForEach(s =>
{
attendees.Add(new Attendee
{
EmailAddress = new EmailAddress
{
Address = s.Email,
Name = s.Name
},
Type = AttendeeType.Required
});
});
}
if (session?.shoppers?.Count > 0)
{
session.shoppers.ForEach(s =>
{
attendees.Add(new Attendee
{
EmailAddress = new EmailAddress
{
Address = s.Email,
Name = s.Name
},
Type = AttendeeType.Required
});
});
}
#event.Attendees = attendees;
GraphServiceClient graph = GetAuthenticatedClient(session.tenantADInformation);
Event #event = PrepareEvent(session);
string Email = session.instructors.FirstOrDefault()?.Email;
var Event = await graph.Users[Email].Events
.Request()
.Header("Prefer", "outlook.timezone=\"" + session.TenantTimeZone + "\"")
.AddAsync(#event);
If it is 50-100 attendees then my Event is having Event.IsOnlineMeeting as false(even though I have set that to true) and Event.OnlineMeeting is coming as null.
Can anyone help?
I don't think exist any limitation in this case. Since the api allows us to create the event for the members, we can request it although there are many members. The only factor which may limit it is the max number of members in teams is 500. In addition to this, I think the api and the code can work fine.

How to remove column with ML.NET ColumnDropper

Guys I'm new in machine learning and I'm trying to use Microsoft.ML and in particular Transform part of the framework.
Can you somebody tell me what I'm doing wrong. I cannot remove a column from my dataset?
var loader = new Microsoft.ML.Data.TextLoader(TrainDataPath).CreateFrom<BloodDonateData>(useHeader: true, separator: ',');
int columnsCount = 5;
using (var environment = new TlcEnvironment())
{
Experiment experiment = environment.CreateExperiment();
ILearningPipelineDataStep pipelineDataStep = loader.ApplyStep(null,
experiment) as ILearningPipelineDataStep;
experiment.Compile();
loader.SetInput(environment, experiment);
experiment.Run();
ColumnDropper columnDropper = new ColumnDropper
{
Column = new string[] { "Time" },
Data = pipelineDataStep.Data
};
columnDropper.ApplyStep(pipelineDataStep, experiment);
var data = experiment.GetOutput(columnDropper.Data);
using (var cursor = data.GetRowCursor(a => true))
{
// print data..
}
}

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

SPAlert.Filter not working

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);
}
}
}
...

Listing Activities via Web Services

I'm trying to reproduce the Activities page in Microsoft CRM 4.0 via web services. I can retrieve a list of activities, and I believe I need to use ActivityPointers to retrieve the entities but have so far been unsuccessful. Would I need to loop through every single entity returned from the first query to retrieve the ActivityPointer for it? And if so, how would I then get the "Regarding" field or Subject of the activity (eg: email).
The code to retrieve the activities is:
var svc = GetCrmService();
var cols = new ColumnSet();
cols.Attributes = new[] { "activityid", "addressused", "scheduledstart", "scheduledend", "partyid", "activitypartyid", "participationtypemask", "ownerid" };
var query = new QueryExpression();
query.EntityName = EntityName.activityparty.ToString();
query.ColumnSet = cols;
LinkEntity link = new LinkEntity();
//link.LinkCriteria = filter;
link.LinkFromEntityName = EntityName.activitypointer.ToString();
link.LinkFromAttributeName = "activityid";
link.LinkToEntityName = EntityName.activityparty.ToString();
link.LinkToAttributeName = "activityid";
query.LinkEntities = new[] {link};
var activities = svc.RetrieveMultiple(query);
var entities = new List<ICWebServices.activityparty>();
RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse) svc.Execute(request);
//var pointers = new List<activitypointer>();
foreach (activityparty c in activities.BusinessEntities)
{
entities.Add(((activityparty)c));
//the entities don't seem to contain a link to the email which they came from
}
Not sure if I understand your problem, but the field "activityid" in the activitypointer object is the same activityid as the underlying activity (email, task, phonecall, etc). The regardingobjectid is the link to the regarding entity.
Heres what you need to get the equivalent of the Activities page
ColumnSet cols = new ColumnSet()
{
Attributes = new string[] { "subject", "regardingobjectid", "regardingobjectidname", "regardingobjectidtypecode", "activitytypecodename", "createdon", "scheduledstart", "scheduledend" }
};
ConditionExpression condition = new ConditionExpression()
{
AttributeName = "ownerid",
Operator = ConditionOperator.Equal,
Values = new object[] { CurrentUser.systemuserid.Value } //CurrentUser is an systemuser object that represents the current user (WhoAmIRequest)
};
FilterExpression filter = new FilterExpression()
{
Conditions = new ConditionExpression[] { condition },
FilterOperator = LogicalOperator.And
};
QueryExpression query = new QueryExpression()
{
EntityName = EntityName.activitypointer.ToString(),
ColumnSet = cols,
Criteria = filter
};
BusinessEntityCollection activities = svc.RetrieveMultiple(query);
foreach (activitypointer activity in activities)
{
//do something with the activity
//or get the email object
email originalEmail = (email)svc.Retrieve(EntityName.email.ToString(), activity.activityid.Value, new AllColumns());
}