Can jsprit solve the VRPC with negative demand or is VRPB better? - vehicle-routing

I need to use VRP and take into account that a client wants to either have a pick-up or a delivery. I know VRPB satisfies these requirements but that waits until the truck is empty before picking up from clients.
Is the VRPC able to deal with a negative demand? Which would make it a delivery.

After some looking around I found this link: https://discuss.graphhopper.com/t/negative-values-as-capacities/1310
You can use a PickUp class or a Delivery class and the code will do the rest.
So yes, it is supported.
Delivery delivery1 = Delivery.Builder.newInstance("1").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 7)).build();
Delivery delivery2 = Delivery.Builder.newInstance("2").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(5, 13)).build();
Delivery delivery3 = Delivery.Builder.newInstance("3").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 7)).build();
Delivery delivery4 = Delivery.Builder.newInstance("5").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 7)).build();
Pickup pickup1 = Pickup.Builder.newInstance("4").addSizeDimension(WEIGHT_INDEX, 1).setLocation(Location.newInstance(15, 13)).build();
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
vrpBuilder.addVehicle(vehicle);
vrpBuilder.addJob(delivery1).addJob(delivery2).addJob(delivery3).addJob(pickup1).addJob(delivery4);

Related

How to create an alert to notify an user when some amount % of threshold reached DailyAsyncApex Executions

On 2 occasions in the past month, we have managed to hit our daily limit on asynchronous apex executions. Salesforce temporarily increased our limit to 425000 but it will be scaled down to 250000 in a week's time. Once we reach the limit, a lot of the SF functions will fail and this has tremendously impacted both internal staff and external customers.
So to prevent this from happening in the future, we need to create some kind of alert in Salesforce to monitor our daily asynchronous apex method executions. Our maximum daily limit is 250000. The alert will need to create a P3 helpdesk ticket and notify couple of users say USER A and USER B once it reaches 70% threshold.
Kindly advise what is possible to achieve the same
Thanks & Regards,
Harjeet
There's a promising Limits method but it doesn't seem to work currently ("reserved for future use"): System.debug(Limits.getAsyncCalls() + ' / ' + Limits.getLimitAsyncCalls());
There's an idea you can upvote: https://success.salesforce.com/ideaView?id=0873A0000003VIFQA2 ;)
You could query SELECT COUNT() FROM AsyncApexJob WHERE ... but that sounds like a bad idea ;)
I think your best course of action is to use SF REST API. There's a "limits" resource you can fetch. You could do it from SF itself (bad idea because if you'd schedule it to run every hour then well, of course it will contribute to the limit consumption too ;)) or from some external app that'd connect to your SF...
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_limits.htm
You can quickly try it out for example in workbench.developerforce.com before you decide you do want to deep dive into coding it.
Of course if you have control over your batch jobs, queuable, schedulable & #future calls you could implement some rough counter of executions in a helper object for example... won't help you much if most of the jobs are coming from managed packages though...
Got 1 more idea but it's pretty hardcore - you should be able to make a REST API call from javascript. so you could create a simple VF page (even without any apex controller), put JS callout on it, have it check every 5 mins and do something if threshold is hit... But that means IT person would have to have this page open all the time (perhaps as a home page component)... Messy :)
I was having the exact same issue so I created a simple JsForce script in NodeJS to monitor the call to the /limits endpoint.
You can connect a Free Monitoring service like UpTimerobot.com or PingDom.com and get an email when you find the Word "Warning" >50% or "Error" > 80%.
async function getSfLimits() {
try {
//Let's login into salesforce
const login = await conn.login(SF_USERNAME, SF_PASSWORD+SF_SECURITY_TOKEN);
//Call the API
const sfLimits = await conn.requestGet('/services/data/v51.0/limits');
return sfLimits;
} catch(err) {
console.log(err);
}
}
https://github.com/carlosdevia/salesforcelimits

Microsoft Cognitive Services Face API : FaceNotFound while using Verify API

Following are the steps
Create a Person and add Face
Like to register person details and ensure the Face Id is persisted
Step 1. faceServiceClient.CreatePersonGroupAsync(groupId, groupName);
Step 2. p.PersonId = _faceServiceClient.CreatePersonAsync(groupId, p.Name).Result.PersonId;
Step 3.
var persistPersonFaceID = _faceServiceClient.AddPersonFaceAsync(groupId, p.PersonId, fStream).Result.PersistedFaceId;
Step 4. _faceServiceClient.TrainPersonGroupAsync(groupID);
Now, like to authenticate a person using the Image provided
Step a
var DetectedFaceID = _faceServiceClient.DetectAsync(firstFilestream, true, true).Result.FaceId;
Step b..
var res = _faceServiceClient.VerifyAsync(persistPersonFaceID, DetectedFaceID).Result;
On the call to VerifyAsync, It throws and error like following
{"error":{"code":"FaceNotFound","message":"Face '7a89ace1-a4b7-4c08-b718-4fec0e9e89d5' is not found."}}
Please do let me know if any of the above needs to be corrected
Possible Issues:
A persistPersonFaceID belongs to a group and I am trying to compare the face id which was retrieved by using Detect. If this is a problem, can you please suggest a resolution
/verify only takes faceIds currently, not persistedFaceIds you're getting back after persisting to a person object.
If I've understood your scenario correctly, you can use either /findsimiliars or /identify since you're persisting the known face.
With /identify you'd pass in DetectedFaceID and specify the groupId (API reference for /identify)
Adding this support for verify is something being planned and if you wouldn't mind I'd encourage you to add some votes to it on uservoice: /verify should also take persistedFaceIds

Google Distance Matrix Api: travel time with traffic

I am trying to get the travel time with traffic between 2 sets of lat/long coordinates. I can call the Google Distance Matrix API, but I am only getting travel time without traffic. The API notes which I have read say to use a parameter called departure_time. Here is the excerpt:
departure_time specifies the desired time of departure as seconds since midnight, January 1, 1970 UTC. The departure time may be specified by Maps for Business customers for to specify the departure_time to receive trip duration considering current traffic conditions. The departure_time must be set to within a few minutes of the current time.
I found this website to give me that time: epochconverter
However I am still getting the same travel time every time. Here is a sample request, the departure_time parameter would need to be updated (not that it matters).
https://maps.googleapis.com/maps/api/distancematrix/xml?units=imperial&departure_time=1408046331&origins=37.407585,-122.145287&destinations=37.482890,-122.150235
15 minutes is always returned.
Using "maps dot google dot com" a travel time of 19 mins is returned when traffic is taken into account.
If anyone can help me get the travel time with traffic from the Distance Matrix API, that would be greatly appreciated.
No need for business license, just need an API key from project on https://console.developers.google.com/ with Google distance Matrix enabled.
For results as on google map use traffic_model with values pessimistic,optimistic and do keep in mind "The departure_time must be set to within a few minutes of the current time" without that it will always return 15 minutes.
That feature appears to only be available to Maps for Business customers, according to the docs.
Even with business licence you can only query departure_time 5 minutes from now if you're using traveling mode is driving
https://developers.google.com/maps/documentation/distancematrix/
According to the google docs "departure_time" can only be used if "mode"(travel mode) is set to "Driving"(which is the default travelMode) and an Api KEY is included in your request.
There is also an optional parameter "trafficModel".
Here is an example url with proper parameters.
https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=40.6655101,-73.89188969999998&destinations=40.598566%2C-73.7527626&mode=driving&departure_time=now&traffic_model=optimistic&key=YOUR_API_KEY
To use distance matrix api as javascript code use it as mentioned in this doc.
https://developers.google.com/maps/documentation/javascript/distancematrix
**Imp:**There are many limitations with this API. Most of the features are available only for premium users.Read the above doc carefully.
Please try with below code.
var origin = new google.maps.LatLng(detectedLatitude,detectedLongitude);
var destination = new google.maps.LatLng(latitudeVal,langtitudeVal);
var service = new google.maps.DistanceMatrixService();var date = new Date();
date.setDate(date.getDate() + 1);
var DrivingOptions = {
departureTime: date,
trafficModel: 'pessimistic'
};
service.getDistanceMatrix(
{
origins: [origin],
destinations: [destination],
travelMode: 'DRIVING',
drivingOptions : DrivingOptions,
unitSystem: google.maps.UnitSystem.METRIC,
durationInTraffic: true,
avoidHighways: false,
avoidTolls: false
}, response_data);function response_data(responseDis, status) {
if (status !== google.maps.DistanceMatrixStatus.OK || status != "OK"){
console.log('Error:', status);
// OR
alert(status);
}else{
alert(responseDis.rows[0].elements[0].distance.text);
}});
Please refer this document click here
This API can solve your problem - https://distancematrix.ai/dev
It takes into consideration the traffic conditions, road constructions, and other restrictions when calculating travel time. And if you were using Google's API before for you will be easy, because you don't need to rewrite code.
Regarding the departure time, you will find the following in the documentation:
"departure_time — a desired time of the departure. You can specify the time as an integer in seconds since midnight, January 1, 1970, UTC. Alternatively, you can specify a value of now, which sets the departure time to the current time (correct to the nearest second). If neither time is specified, the departure_time defaults to now (that is, the departure time defaults to the current time). The departure_time must be set to the current time or some time in the future. It cannot be in the past. Results for a given request may vary over time due to the changes in the road network, updated average traffic conditions, and the distributed nature of the service. Results may also vary between nearly-equivalent routes at any time or frequency."
Follow these recommendations, and you won't have this problem. Besides, you can easily contact the developers and ask any questions concerning your situation.
Disclaimer: I work at a company that creates this API.
If you are using golang client, set DepartureTime to "now" in the input parameter DirectionsRequest of the Directions func.

VBScript Launch Default Mail Window

Just wondering if it is at all possible in classic ASP/VBScript to launch a new window of the default mail client.
I have tried the following:
set objOutlk = createobject("Outlook.Application")
set objMail = objOutlk.createitem(olMailItem)
But got nothing but an error: ActiveX cannot create object: Outlook.Application.
Any advice is much appreciated.
Rob.
If you want to provide a simple way to open the default mail client message of a user viewing your (asp) page just add a mailto: hyperlink:
Send Msg
The mailto: will trigger the browser to open the default (or configured) mail client.
You can append a query string defining the subject line and the mail body - in my example the subject is "Hello World" and the body text is "Hi there".
Notice the blanks are url-encoded to %20
After a little thought (thanks to some of you guys for the prompt) it made sense to run this client side and I used the following JScript:
<script type="text/javascript">
function send() {
alert("clicked")
var recpt = "info#example.ccTLD"
var subj = "FASTER BETTER SOONER: Look at Monash Rowville rail now"
var text = "<Enter your name and address here> %0D%0DMelbourne is growing and more people need transport. With concern about climate change and rising petrol prices, Melbourne's growth is not sustainable without more and better public transport.%0D%0DVictorians want more people catching public transport, cycling and walking; fewer trucks on our roads, more freight on rail; and fewer kilometres travelled by car and truck.%0D%0DPublic transport should: be fast, frequent, reliable, affordable and safe; grow as Melbourne grows; be available to all Melbournians; and be managed as an integrated, co-ordinated network.%0D%0DThis means bringing forward existing public transport projects, committing to new projects and accelerating programs to move freight off our roads and onto rail.%0D%0DIt also means looking very closely at the impact on greenhouse gas emissions of any new transport projects like tunnels and freeways.%0D%0DWe especially urge you to look at a feasibility study for a Monash Rowville rail line. %0D%0DAs Melbourne's population grows, better public transport will both reduce traffic congestion and provide a much needed antidote to spiralling petrol prices. "
var bcc = "people#example.ccTLD"
var content = new Array()
content[0] = "mailto:"
content[1] = recpt
content[2] = "?subject="
content[3] = subj
content[4] = "&body="
content[5] = text
content[6] = "&bcc="
content[7] = bcc
content = content.join("")
window.location = content
}
This seems to the results I expected.
Rob

Dynamics GP Web Service -- Returning list of sales order based on specific criteria

For a web application, I need to get a list or collection of all SalesOrders that meet the folowing criteria:
Have a WarehouseKey.ID equal to "test", "lucmo" or "Inno"
Have Lines that have a QuantityToBackorder greater than 0
Have Lines that have a RequestedShipDate greater than current day.
I've succesfully used these two methods to retrieve documents, but I can't figure out how return only the ones that meet above criteria.
http://msdn.microsoft.com/en-us/library/cc508527.aspx
http://msdn.microsoft.com/en-us/library/cc508537.aspx
Please help!
Short answer: your query isn't possible through the GP Web Services. Even your warehouse key isn't an accepted criteria for GetSalesOrderList. To do what you want, you'll need to drop to eConnect or direct table access. eConnect has come a long way in .Net if you use the Microsoft.Dynamics.GP.eConnect and Microsoft.Dynamics.GP.eConnect.Serialization libraries (which I highly recommend). Even in eConnect, you're stuck with querying based on the document header rather than line item values, though, so direct table access may be the only way you're going to make it work.
In eConnect, the key piece you'll need is generating a valid RQeConnectOutType. Note the "ForList = 1" part. That's important. Since I've done something similar, here's what it might start out as (you'd need to experiment with the capabilities of the WhereClause, I've never done more than a straightforward equal):
private RQeConnectOutType getRequest(string warehouseId)
{
eConnectOut outDoc = new eConnectOut()
{
DOCTYPE = "Sales_Transaction",
OUTPUTTYPE = 1,
FORLIST = 1,
INDEX1FROM = "A001",
INDEX1TO = "Z001",
WhereClause = string.Format("WarehouseId = '{0}'", warehouseId)
};
RQeConnectOutType outType = new RQeConnectOutType()
{
eConnectOut = outDoc
};
return outType;
}
If you have to drop to direct table access, I recommend going through one of the built-in views. In this case, it looks like ReqSOLineView has the fields you need (LOCNCODE for the warehouseIds, QTYBAOR for backordered quantity, and ReqShipDate for requested ship date). Pull the SOPNUMBE and use them in a call to GetSalesOrderByKey.
And yes, hybrid solutions kinda suck rocks, but I've found you really have to adapt if you're going to use GP Web Services for anything with any complexity to it. Personally, I isolate my libraries by access type and then use libraries specific to whatever process I'm using to coordinate them. So I have Integration.GPWebServices, Integration.eConnect, and Integration.Data libraries that I use practically everywhere and then my individual process libraries coordinate on top of those.

Resources