Odoo 8: How to show projects of current company BUT not sub companies? - filtering

In odoo8 (Multi-company module is installed on it) I like to show the projects of the current company BUT NOT sub companies. when I add this line to the SearchView XML file:
<filter string="Company" domain="[('company_id', '=', 1)]"/>
It works correctly (1 is the root company id).
But when i change it to :
<filter string="Company" domain="[('company_id', '=', [user.company_id.id])]" />
I get this error:
Uncaught Error: Failed to evaluate search criterions:
{"code":400,"message":"Evaluation Error","data": {"type":"local_exception","debug":"Local evaluation failure\nNameError: name 'user' is not defined\n\n{\"domains\":[[],\"[('company_id', '=',[user.company_id.id])]\"],\"contexts\":
[{\"lang\":\"en_US\",\"tz\":\"America/Montreal\",\"uid\":1,\"search_default_Company\":1},\"{'group_by':'company_id'}\"],\"group_by_seq\":[\"{'group_by':'company_id'}\"]}"}}
I appreciate if you tell me how can I pass the id of current company to the filter.
Thanks,

You need to create a record rule for your model and not in the search view. in settngs/technical/security/record rules, you can seen many record rules.

Related

How can I create and update pages dynamically in Sulu CMS?

I have the following situation:
A database stores information about houses (address, number of rooms, date built, last selling price, etc.)
This database is being manipulated through an app (let's call that app the "backend house app") that cannot be directly integrated in a Sulu-driven app. I can access the stored data through an API that gives me JSON-representations of House-objects. I can also have the app launch some sort of call to a Sulu-driven app when a house is created, updated or deleted.
The Sulu-driven app (let's call that the "frontend house app") with templates for "house", "room", etc., is connected to a different database on a different server. This Sulu-driven app's website-environment shows house-pages with room-pages where some content is pre-filled through a connection to the "backend house app". Other content only exists on the database of the "frontend house app", like user comments, appraisals of interior design, etc., according to configured aspects of the Sulu-templates.
What I want to achieve, is a way to automate the creation, updating and deletion of "frontend house app"-pages based on activity in the "backend house app".
For instance, when a new house is added in the "backend house app", I want it to notify the "frontend house app" so that the "frontend house app" will automatically create the entire node-tree for the newly added house. Meaning: a "house"-page with the required data filled in, "room"-pages for each room, etc., so that the content manager of the "frontend house app" can see the entire tree of the newly added house in the workspace and can start manipulating content in the already available templates. In addition to automatically creating these pages, I also want to pre-set the rights to update and create, since the content manager of the "frontend house app" must not be able to create new rooms or change the name of the house, for instance.
I did not manage to get it working, I'll just add what I already done to show where I got stuck.
I started out with the following code, in a controller that extends Sulu's own WebsiteController:
$documentManager = $this->get('sulu_document_manager.document_manager');
$nodeManager = $this->get('sulu_document_manager.node_manager');
$parentHousesDocument = $documentManager->find('/cmf/immo/routes/nl/huizen', 'nl');
$newHouseDocument = $documentManager->create('page');
// The backendApi just gives a House object with data from the backend
// In this case we get an existing House with id 1
$house = $backendApi->getHouseWithId(1);
$newHouseDocument->setTitle($house->getName()); // For instance 'Smurfhouse'
$newHouseDocument->setLocale('nl'); // Nl is the only locale we have
$newHouseDocument->setParent($parentHouseDocument); // A default page where all the houses are listed
$newHouseDocument->setStructureType('house'); // Since we have a house.xml template
// I need to grab the structure to fill it with values from the House object
$structure = $newHouseDocument->getStructure();
$structure->bind([
'title' => $house->getName(),
'houseId' => $house->getId(),
]);
$newHouseDocument->setWorkflowStage(WorkflowStage::PUBLISHED); // You would expect this to automatically publish the document, but apparently it doesn't... I took it from a test I reverse-engineered in trying to create a page, I have no clue what it is supposed to change.
$nodeManager->createPath('/cmf/immo/routes/nl/huizen/' . $house->getId());
$documentManager->persist(
$newHouseDocument,
'nl',
[
'path' => '/cmf/immo/contents/huizen/' . Slugifier::slugify($house->getName()), // Assume for argument's sake that the Slugifier just slugifies the name...
'auto_create' => true, // Took this value from a test that creates pages, don't know whether it is necessary
'load_ghost_content' => false, // Idem
]
);
$documentManager->flush();
Now, when I fire the controller action, I first get the exception
Property "url" in structure "house" is required but no value was given.
I tried to fix this by just manually binding the property 'url' with value '/huizen/' . $house->getId() to $structure, at the point where I bind the other values. But this doesn't fix it, as apparently the url value is overwritten somewhere in the persist event chain, and I haven't yet found where.
However, I can, just for testing purposes, manually override the url in the StructureSubscriber that handles the mapping for this particular persist event. If I do this, something gets created in the Sulu-app-database - hurray!
My phpcr_nodes table lists two extra records, one for the RouteDocument referring to /cmf/immo/routes/nl/huizen/1, and one for the PageDocument referring to /cmf/immo/contents/huizen/smurfhouse. Both have the workspace_name column filled with the value default_live. However, as long as there are not also records that are complete duplicates of these two records except with the value default in the workspace_name column, the pages will not appear in the Sulu admin CMS environment. Needless to say, they will also not appear on the public website proper.
Furthermore, when I let the DocumentManager in my controller action try to ->find my newly created document, I get a document of the class UnknownDocument. Hence, I cannot have the DocumentManager go ->publish on it; an Exception ensues. If I visit the pages in the Sulu admin environment, they are hence unpublished; once I publish them there, they can be found by the DocumentManager in the controller action - even if I later unpublish them. They are no longer UnknownDocument, for some reason. However, even if they can be found, I cannot have the DocumentManager go ->unpublish nor ->publish - that just has NO effect on the actual documents.
I was hoping there would be a Sulu cookbook-recipe or another piece of documentation that extensively describes how to create fully published pages dynamically, thus without going through the 'manual labor' of the actual CMS environment, but so far I haven't found one... All help is much appreciated :)
PS: For the purposes of being complete: we're running Sulu on a Windows server environment on PHP 7.1; dbase is PostgreSQL, Sulu being a local forked version of release tag 1.4.7 because I had to make some changes to the way Sulu handles uploaded files to get it to work on a Windows environment.
EDIT: a partial solution for making a new house page if none exists already (not explicitly using the AdminKernel, but should of course be run in a context where the AdminKernel is active):
public function getOrCreateHuisPagina(Huis $huis)
{
$parent = $this->documentManager->find('/cmf/immo/routes/nl/huizen', 'nl'); // This is indeed the route document for the "collector page" of all the houses, but this doesn't seem to give any problems (see below)
try {
$document = $this->documentManager->find('/cmf/immo/routes/nl/huizen/' . $huis->id(), 'nl'); // Here I'm checking whether the page already exists
} catch(DocumentNotFoundException $e) {
$document = $this->setupPublishedPage();
$document->setTitle($huis->naam());
$document->setStructureType('huis_detail');
$document->setResourceSegment('/huizen');
$document->setParent($parent);
$document->getStructure()->bind([
'title' => $huis->naam(), // Not sure if this is required seeing as I already set the title
'huis_id' => $huis->id(),
]);
$this->documentManager->persist(
$document,
'nl',
[
'parent_path' => '/cmf/immo/contents/huizen', // Explicit path to the content document of the parnt
]
);
}
$this->documentManager->publish($document, 'nl');
return $document;
}
First of all I think the following line does not load what you want it to load:
$parentHousesDocument = $documentManager->find('/cmf/immo/routes/nl/huizen', 'nl');
It loads the route instead of the page document, so it should look like the following:
$parentHousesDocument = $documentManager->find('/cmf/immo/contents/nl/huizen', 'nl');
Regarding your error with the URL, instead of overriding the StructureSubscriber you should simple use the setResourceSegment method of the document, which does exactly what you need :-)
And the default_live workspace is wrong, is it possible that you are running these commands on the website kernel? The thing is that the WebsiteKernel has the default_live workspace as default, and therefore writes the content in this workspace. If you run the command with the AdminKernel it should land in the default workspace, and you should be able to copy it into the default_live workspace with the publish method of the DocumentManager.
I hope that helps :-)

Can I use FLP without default model ?

My json model url is '/destinations/XXX/Collection?time=' + (+new Date) I don't know how to configure it in minifest of Component.js , so I delete the sap.app.dataSources and sap.ui.models."" (the defalut model? ) , and the flp app gave me this error:
Failed to load U5 component for navigation intent
TypeError: Cannot read property 'metadataLoaded' of undefined
sap.ushell.renderers.fiori2.Shell.controller
What should I do ?
i have a couple of links that should get you up and running (I am assuming you are developping on webIDE in SAP HCP (is that correct?)):
How to setup destinations, you need extra properties: WebIDEUsage = odata_gen and WebIDEEnabled = true.
You should then go into your manifest.json and choose Descriptor Editor and choose Data Sources and under OData Services choose the + to add your service.
More information on manifest.json you can find here: Documentation on Manifest

How to check the workflow initiator is a member of a specific group in Alfresco?

The objective was to find out the workflow starter does the member of a specific group.
First, I need to get the member list inside a group.
A simple javascript that get the list of member inside a group, but it failed:
<scriptTask id="scripttask1" name="Script Task" scriptFormat="javascript" activiti:autoStoreVariables="true">
<script>var node = people.getGroup("GROUP_Marketing");
if(node) {
logger.log("Marketing member list: " + people.getMembers(node));
}
</script>
</scriptTask>
And I get this error:
SEVERE: Error while closing command context
org.activiti.engine.ActivitiException: problem evaluating script: sun.org.mozilla.javascript.EcmaError: ReferenceError: "people" is not defined. (<Unknown source>#1) in <Unknown source> at line number 1
So, may I know the correct method to determine the workflow starter does exist the member of a specific group?
The clean way would be to add an interceptor on the WorkflowService.
Intercept the result of the methods you need. At the very least "getDefinitions()". Possibly others too.
Complete post available here : https://forums.alfresco.com/comment/155580#comment-155580

Plone 4 - History for second workflow won't show in ##historyview

I have a dexterity content type in Plone 4.2.4. The versioning works fine with the default workflow for this content type, although it is not a workflow shipped with plone, but a custom made.
However, when I enable a second workflow for the same type, everything but the versioning works fine.
additional permissions managed by the second workflow are working
The state changes are working
The difference:
I used different state_variable names for the workflows, which seems to make sense, to have a catalogable field for the state of the second workflow.
I've tried to use the same state variable name, but that didn't help. I have the workflow variable review_history also set in the 2nd workflow and sufficient permissions in the context.
I am (mostly) shure, that I got the permission concept, but I have no clou, how permissions get calculated, when multiple workflows are involved.
Any idea, why the second workflow does not leave a trace in my content types history?
Thanks very much in advance.
Udate
I've reordered the workflows as Ida Ebkes suggested and did see, that all transitions from the 2nd workflow get stored properly. So it seems to be an issue with the historyview.
Since these workflows indeed describe concurrent behaviors of a content type, I really would like to stick with separate workflows and ideally different workflow state variables and catalog indexes.
What I now think needs to be done, is to tweak the historyview.
Here is how I did it. It works for plone 4.2.4 at least.
Since the problem was a display problem, I just had to tweak my historyviewlet. Therefore, I created a folder named viewlets in my product root and created a __init__.py and a configure.zcml file. Then i copied content_history.pt, history_view.pt, review_history.pt and content.py from plone/app/layout/viewlets/ (omelette) to the newly created folder.
The configure.zcml contains two view registrations:
<browser:view
for="*"
name="my-contenthistory"
class=".content.ContentHistoryView"
permission="zope2.View"
/>
<browser:page
for="*"
name="my-historyview"
template="history_view.pt"
permission="zope2.View"
/>
Furthermore, I copied the whole WorkflowHistoryViewlet class from content.py to a different class name. TransferHistory in this case. Then I changed mostly the part that corresponds to the workflow state variable, which was not review_state, but transfer_state. I further found that the initial usage of the 2nd workflow creates also a created entry in the history of the 2nd workflow, that I just filtered .
transfer_history = [x for x in transfer_history if x['action'] != None]
The I corrected the view name in history_view.pt to my new view name.
<div tal:replace="structure here/##my-contenthistory">Content History</div>
Finally, I added my class as parent to the ContentHistoryViewlet class in content.py
class ContentHistoryViewlet(WorkflowHistoryViewlet, TransferHistoryViewlet):
index = ViewPageTemplateFile("content_history.pt")
#memoize
def getUserInfo(self, userid):
[...]
def fullHistory(self):
history = self.workflowHistory() + self.revisionHistory() + self.transferHistory()
if len(history) == 0:
return None
history.sort(key=lambda x: x["time"], reverse=True)
return history
and registered the .zcml in the products configure.zcml
<include package=".viewlets" />
Then I modified content_history.pt and also changed the definition of action_id in the upper part of the file.
[...]
action_id python:item['action'] or item.get('review_state', False) or item.get('transfer_state', False);
[...]
After rebooting the monster and a product reinstall, all state changes from both workflows are shown in the my-historyview.

Using "seen" on a trail in KRL

I want to have a trail that helps keep track of values I want to persist for users. If a user has not entered their name, I want to display a form for them to enter their name to use for lookups.
I want to be able to check if the name is on the trail. If the name is on the trail then display the data for that user. If the name is not on the trail then I want to display a form for them to enter their name.
I am looking for some help on how I would accomplish this. It was suggested to encode a struct as json and pushing that on to a trail and then search for it. Some direction on how this would be done would be helpful. Would I use the following?
if seen ent:user_data with <regexp> then {
<get and show data>
} else {
<show form to user>
}
If you just want to save a simple string for later then you can do something like the following using an entity variable
in the pre block retrieve saved name from entity variable:
savedName = ent:userName || "";
in the postlude save or clear the entity variable:
set ent:userName userName;
clear ent:userName;
Example app => https://gist.github.com/722849
Example bookmarklet => http://mikegrace.s3.amazonaws.com/forums/stack-overflow/example-persistant-trail-bookmarklet.html
Example run on http://example.com results
first run on example.com
after clicking submit
reloading the page and running the app again
clearing trail by running on yahoo.com
running app on yahoo.com before saving name or after clearing
Note: When you want to save something else like an age, you can just use a different entity variable like
ent:userAge
The sky is the limit. ; )