Suggestion with basic drools syntax - syntax

The following is a basic drools syntax:
$customer : Customer( )
Account( ) from $customer.accounts
As far as I know the first line create a new variable and assign it to the fact.
However I can't quite understand the second line especially what the "Account()" part means...

You have written class Customer, or must know it to understand what's going on here. Presumably it contains a Collection<Account> accounts (see note), which is (by the engine) retrieved one by one so that the rule fires for each Account object contained in Customer's object.
The rule will fire once for each Account object stored in any of the collections contained in all the Customer facts in working memory, with $customer being bound to the containing Customer.
You can bind another variable to Account.
Note: It could also contain a field Account accounts, but I hope the name was chosen carefully.

Related

How to match parameter to TWO entities simultaneously?

My bot asks: 'how do you (i.e. customer) want to pay for this product?'
Customer says: 'part in cash and the difference in 48x'
What the customer is saying above is that he wants to pay in cash and use financing. And that financing should consider 48 installments.
Entities:
paymentType: {cash, financed} ; Financed includes 48x as a synonym
numInstallments: {12x, 24x, 36x, 48x} ; 48x is the number of installments desired
Using the GUI only, how to do this:
IF user says '48x' THEN simultaneously add 'financed' to the paymentType list AND set numInstallments equal to '48x' ?
Apparently the GUI doesn't allow me to do that unless I'm doing something wrong (see below the screen which allows a parameter to be mapped to an entity and notice that this dropdown apparently allows selection of a single entity and not two, which is what I need).
How to solve this problem in an easy way through the GUI?
I don't know if what you have in mind is actually feasible in this case.
What you could do is keep the intent and entities as-is and then create several conditions in the page where you fill this parameters or another page (i think this is preferred).
In that page you can put different routes where your conditions are true that modify your parameters as you wish.
For example, after asking the user how they'd like to pay, you can have a route going to a "Set parameters" page which has several routes:
First route has a condition $session.params.numeroDeParcelas != null (you know the user has asked a specific number of installments, so handle the case by setting the parameters you need in this route (under parameters in the route write paymentType : "financed")
Second route has another condition, for example $session.params.numeroDeParcelas = null (you know the user hasn't asked for financing, so set the same parameter as before to "cash")
and so on, until you've exhausted your user cases (all payment methods, possibly all types of financing).
Pay attention: the routes are always evaluated in order so make sure to keep this in mind while writing/ordering them: be specific to avoid fulfilling the wrong one by mistake (e.g. by creating compound conditions, chaining parameter checks as in $session.params.numeroDeParcelas = null AND $session.params. numInstallments = "36x"

How to use IBM Watson Context variables without entities?

Hi all Watson Developers!
I have a question, exposing that I need to know a bit more about context variables!
A user enters "Who owns the boat DUO ?" and my Dialog then uses the Intent "#owner_of_boatname" That works!
I then want to store the boatname in a variable $boatname, to pass it on to my webhook, as the value "$boatname".
If I create an entity with a list containing all possible boatnames, then it works, but what if I do not have all boatnames, and just want to pick up the $boatname from the user, and pass in on to the weebhook ? How do I fill out the handler then ?
I've tried to just put in "DUO" as value to my webhook, and that works fine, so the webhook itself works - I just need to be able to transfer variables to it!
How ?
Thanks a lot
Lars ;-) enter image description here
The ideal solution for this question should use A.I model created in Watson Knowledge Studio to identify names in user's text and deploy it to Natural Language Understanding instance which you would use the extract the name.
However, we can make a simpler solution, we must assume that the name of the boat will always be at the end of user's input and we can use a regular expression on Watson Assistant to extrat the name. You have to create a node before you pass to the webhook just to identify that user will pass the name of the boat, for example:
Assistant: What is the name of your boat?
User: The name of my boat is boatname
The node that return "What is the name of your boat?" should jump to a node and wait to user request and the condition of this node should always be true. When the user says "The name of my boat is boatname" the node with the condition always true should have context variable with the following regex expression in value context area:
"<? input.text.extract('\s\"?(\w+)\"?$',0) ?>"
This regex rule identify the last word of a phrase with double quotes or not.
Once you have extracted the boat's name you can make the node request you webhook.
Here we are using the SpeL language to access the assistant payload to extrat the last word of a phrase. You can find more information about functions on context variables here here.

Using Exchange GetAddressEntryFromID method with LDAP msExchMailboxGuid

Outlook COM has a method under Application.Session.GetAddressEntryFromID method to grab an address entry without having to iterate through the entire Global or All Users address book.
The issue is it is expecting the ID that an entry has under the AddressLists object.
In Active Directory, there is no equivalent that gives me the same GetAddressEntryFromId string.
I was previously making a list of all users, minus rooms and resources, by going through the entire COM object, but that takes too long; 20mins.
I figured if I use AD, which is faster, with filters to find the users, then I can grab the GUID and when looking for info on the user, not have to go through the entire COM object to grab it, but it will happen locally to the executable being run.
The issue I am having, as an example, is that I have a user with the following ID;
00000000DCA740C8C042101AB4B908002B2FE18201000000000000002F6F3D45766572657374205265696E737572616E63652F6F753D436F72702D48512F636E3D526563697069656E74732F636E3D6A6E6700
In AD the msExchMailboxGuid has a value of
{4A49BD1C-62AE-4674-B097-C06528BDBEAE}
Not sure if these are the same, but I need to learn to better save it.
What else can I use, what can I do with the current time?
GAL entry id is constructed from the EX address (which is stored in the legacyDN attribute).
The entry id you have above contains the following:

Magento View 'Company Name' Instead Of First/Last Name

Can Magento view/manage our customers by their business name in addition to their contact names to find them easily? It is being used for B2B, so when emails go out they are pulling the customer’s name, instead of the company name which is more appropriate.
Is this a global setting?
thanks in advance.
Magento stores business name on the customer's address by default, so it's a little harder to get to.
There's no reason you cannot add another customer field to put the company name on the customer record itself. That way you'll have no problem accessing it, and can change other screens in the system to reflect it.
If you don't want to go to those lengths, you could always implement a method that pulls the company name from the default address, and save it into the session by default, for easier retrieval.
EDIT: Better idea.
Looking through the sales email templates, there are two methods that are used to grab a customer's name:
$order->getCustomerName();
$order->getBillingAddress()->getName();
I don't see any separate references to the company name, so you should be able to substitute these two methods for your own and get the desired outcome. You'll need to create your own module and override the models for customer/address and sales/order (others have covered this in depth elsewhere). Then create methods that look something like this:
public function getCustomerName() {
if($this->getBillingAddress()->getCompany()) {
return $this->getBillingAddress()->getCompany();
}
return parent::getCustomerName();
}
That's the example for sales order, modify accordingly for customer. Now your company names will be used whenever available, and when they aren't the fallback will be to the original implementation (customer name).
Hope that helps!
Thanks,
Joe
You are correct about the universal application. If you did want just the emails, the concern is whether you have access to your custom function where you need it. If there's no object handy, I'm not positive that you will be able to call just any method that you need to.
An approach that would work in this case would be to override the two objects mentioned below, but to instead add a getCompanyName method to them. That way, you'll have the right objects to call, and you can edit the emails specifically to taste.

CakePHP, organize site structure around groups

So, I'm not quite sure how I should structure this in CakePHP to work correctly in the proper MVC form.
Let's, for argument sake, say I have the following data structure which are related in various ways:
Team
Task
Equipment
This is generally how sites are and is quite easy to structure and make in Cake. For example, I would have the a model, controller and view for each item set.
My problem (and I'm sure countless others have had it and already solved it) is that I have a level above the item sets. So, for example:
Department
Team
Task
Equipment
Department
Team
Task
Equipment
Department
Team
Task
Equipment
In my site, I need the ability for someone to view the site at an individual group level as well as move to view it all together (ie, ignore the groups).
So, I have models, views and controls for Depart, Team, Task and Equipment.
How do I structure my site so that from the Department view, someone can select a Department then move around the site to the different views for Team/Task/Equipment showing only those that belong to that particular Department.
In this same format, is there a way to also move around ignoring the department associations?
Hopefully the following example URLs clarifies anything that was unclear:
// View items while disregarding which group-set record they belong to
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
http://www.example.com/Departments
// View items as if only those associated with the selected group-set record exist
http://www.example.com/Department/HR/Team/action/id
http://www.example.com/Department/HR/Task/action/id
http://www.example.com/Department/HR/Equipment/action/id
Can I get the controllers to function in this manner? Is there someone to read so I can figure this out?
Thanks to those that read all this :)
I think I know what you're trying to do. Correct me if I'm wrong:
I built a project manager for myself in which I wanted the URLs to be more logical, so instead of using something like
http://domain.com/project/milestones/add/MyProjectName I could use
http://domain.com/project/MyProjectName/milestones/add
I added a custom route to the end (!important) of my routes so that it catches anything that's not already a route and treats it as a "variable route".
Router::connect('/project/:project/:controller/:action/*', array(), array('project' => '[a-zA-Z0-9\-]+'));
Whatever route you put means that you can't already (or ever) have a controller by that name, for that reason I consider it a good practice to use a singular word instead of a plural. (I have a Projects Controller, so I use "project" to avoid conflicting with it.)
Now, to access the :project parameter anywhere in my app, I use this function in my AppController:
function __currentProject(){
// Finding the current Project's Info
if(isset($this->params['project'])){
App::import('Model', 'Project');
$projectNames = new Project;
$projectNames->contain();
$projectInfo = $projectNames->find('first', array('conditions' => array('Project.slug' => $this->params['project'])));
$project_id = $projectInfo['Project']['id'];
$this->set('project_name_for_layout', $projectInfo['Project']['name']);
return $project_id;
}
}
And I utilize it in my other controllers:
function overview(){
$this->layout = 'project';
// Getting currentProject id from App Controller
$project_id = parent::__currentProject();
// Finding out what time it is and performing queries based on time.
$nowStamp = time();
$nowDate = date('Y-m-d H:i:s' , $nowStamp);
$twoWeeksFromNow = $nowDate + 1209600;
$lateMilestones = $this->Project->Milestone->find('all', array('conditions'=>array('Milestone.project_id' => $project_id, 'Milestone.complete'=> 0, 'Milestone.duedate <'=> $nowDate)));
$this->set(compact('lateMilestones'));
$currentProject = $this->Project->find('all', array('conditions'=>array('Project.slug' => $this->params['project'])));
$this->set(compact('currentProject'));
}
For your project you can try using a route like this at the end of your routes.php file:
Router::connect('/:groupname/:controller/:action/*', array(), array('groupname' => '[a-zA-Z0-9\-]+'));
// Notice I removed "/project" from the beginning. If you put the :groupname first, as I've done in the last example, then you only have one option for these custom url routes.
Then modify the other code to your needs.
If this is a public site, you may want to consider using named variables. This will allow you to define the group on the URL still, but without additional functionality requirements.
http://example.com/team/group:hr
http://example.com/team/action/group:hr/other:var
It may require custom routes too... but it should do the job.
http://book.cakephp.org/view/541/Named-parameters
http://book.cakephp.org/view/542/Defining-Routes
SESSIONS
Since web is stateless, you will need to use sessions (or cookies). The question you will need to ask yourself is how to reflect the selection (or not) of a specific department. It could be as simple as putting a drop down selection in the upper right that reflects ALL, HR, Sales, etc. When the drop down changes, it will set (or clear) the Group session variable.
As for the functionality in the controllers, you just check for the Session. If it is there, you limit the data by the select group. So you would use the same URLs, but the controller or model would manage how the data gets displayed.
// for all functionality use:
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id
You don't change the URL to accommodate for the functionality. That would be like using a different URL for every USER wanting to see their ADDRESS, PHONE NUMBER, or BILLING INFO. Where USER would be the group and ADDRESS, PHONE NUMBER< and BILLING INFO would be the item sets.
WITHOUT SESSIONS
The other option would be to put the Group filter on each page. So for example on Team/index view you would have a group drop down to filter the data. It would accomplish the same thing without having to set and clear session variables.
The conclusion is and the key thing to remember is that the functionality does not change nor does the URLs. The only thing that changes is that you will be working with filtered data sets.
Does that make sense?

Resources