How to domain/filter PO based on user allowed branch in odoo - odoo

I want to display PO based on allowed branch in odoo. So if you log in as user Ana with allowed branch = Singapore, then the PO that appear are only PO with the Singapore branch. Maybe someone knows and can give advice?
Thanks
Best Regards

you can use the domain field on a model to filter records based on certain criteria. This can be useful for restricting which records are visible to a user based on their allowed.

Another alterative to make a custom domain (maybe dificult because you need to access the current user)
I think you can define a new security rule, to discard PO with no match in the branch. but not sure if you can do user.branch_id or some other field distinct od id.
<record id="branch_po_rule" model="ir.rule">
<field name="name">PO own branch</field>
<field name="model_id" ref="model_purchase_order"/>
<field eval="True" name="global"/>
<field name="domain_force">('branch_id','=',user.branch_id))]</field>
</record>
But security rules are meant to do this kind of discriminations

Related

Odoo 16 Can't access another company

everyone! First of all, thanks in advance.
I've searched everywhere for a solution for my problem. Even when copying from the source code, it doesn't solve it.
I'm doing the Advanced B: ACL and Record Rules tutorial
When completing the sub-chapter on multi-company security, I can't do it.
My user can't get access to my new company
The problems I've encountered so far are:
The new company isn't in company_ids
When changing the Default Company and allowed companies, if:
The company is the new company
The only allowed company is the new company
Then, I get the error: Access Error: Access to unauthorized or invalid companies.
I don't know why my new company is invalid
I'm trying to access another company's records
This is my rule:
<record id="estate_private_companies_properties" model="ir.rule">
<field name="name">Privacy Plan Multi-Company</field>
<field name="model_id" ref="model_estate_property"/>
<field name="global" eval="True"/>
<field name="domain_force">[
('company_id', 'in', company_ids)
]</field>
</record>
EDIT:
Sorry for the confusion. I know the xml is not the problem
The problem is that my company is unauthorized or invalid and it doesn't show up in my company_ids
What the xml does is filter so you can only access the estate properties that are assigned to the currently active company (or companies). So it hasn't any effect on creating a company or making a company accessible.
If this is not the problem, please rephrase your question.
Make sure the user you test with has access to the company.
Login as the admin user
go to settings
Users & companies -> Users
select your user
in the user form you see a new field "Allowed Companies" which is only visible once you added a new company.
Make sure the new company is in this many2many list
login as your user

Odoo logged user data dont update for a login user

Please I need help with some custom rules configurations in Odoo 11.
Currently I'm doing a rule that allow an user only access to a certains product categories, for that I have a Many2many field which specify those categories:
product_category_ids = fields.Many2many('product.category')
Here is the rule that only allows access to that categories:
<record model="ir.rule" id="product_template_category_users">
<field name="name">product.template.category.users</field>
<field name="model_id" ref="product.model_product_template"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_unlink" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="domain_force">[('categ_id', 'child_of', user.product_category_ids.ids)]</field>
</record>
The rule works fine, but I have this problem:
Login with user "A" who has that rule
Login in another sesion with user "B" and update user "A"
adding a new category to categories field
Return with user "A" and the rule doesn't show the new category added, also reload page doesn't work.
The changes only apply in "A" user when I change the current company or reload the Odoo Service.
I think that it has to be something with the user storing data when the user login, maybe is some way to update that data and allow the rule to read it from "user". I need that the changes doing to users apply in real time to that connected users without have to change the current company or reload the Odoo service.
Thanks for helping.
This is strange that it should work, but only after changing current company or restarting the Odoo server.
Can you try your modifications on a blank database and/or a new database with demo data loaded? If possible, it would be good to test this on an entirely different server to see if the problem might lay there.
Perhaps you can also try modifying your force_domain like this:
['|', ('categ_id', 'in', user.product_category_ids.ids), ('categ_id', 'child_of', user.product_category_ids.ids)]
If anyone has the same problem, I solve it using this funcion every time i made a change in the product categories field of user
self.env['ir.rule'].clear_cache()
That code clear the cache of rules so the rules apply the new domain.
Add self.env['ir.rule'].clear_cache() into create() and write() method of your model.

For Admin, Manager i want show every record , for normal user I want show records created by that particular user only

How to filter records for tree view based on logged in user. For Admin, Manager i want show every record , for normal user I want show records created by that particular user only.
Below code sample I tried
For manager uid=12
For admin uid=1
<field name="domain">[('|',('create_uid','=',uid),('|',(uid,'=','1'),(uid,'=','12')))]</field>
Above code sample is throwing error
"ValueError: Invalid leaf ['|', ['create_uid', '=', 1], ['|', [1, '=',
'1'], [1, '=', '12']]]"
Row-level access rules are defined in the ir.rule model and can be created by adding a corresponding xml file to the module. The file is usually stored under security/ folder in your module directory.
For example I've taken user.purchase.records as the model
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="user_purchase_record_rule" model="ir.rule">
<field name="name">Records created by current user only</field>
<field name="model_id" ref="model_user_purchase_records"/>
<field name="domain_force">[('create_uid','=',user.id)]</field>
<field name="groups" eval="[(4,ref('base.group_user'))]"/>
</record>
</data>
</odoo>
Finally add this file path in your manifest.py file.
A domain it's composed by 3 elements, (field_in_your_model, operator, value), I don't know if you are working with a known model or it's your definition, but you got that error because uid it's a reserved word for odoo, not a field in a model.
And the best approach for your requirement its make rules, for your groups of users, something like sale groups:
Rule for Sale / User: Own Documents Only:
['|',('user_id','=',user.id),('user_id','=',False)]
I hop this answer can be helpful you.

OpenERP, error while creating a view filter

Im having problems with creating a filter on stock.picking object. Just recently i build a simple "privilege relay" - in each stock location you can define "Assigned User Group", thanks to that users that are in particular group can or cannot confirm moves for or out of the location.
Stock.picking:location_id -> assigned_user_group -> users
Now I would like to create a filter (later to be set default) on stock picking tree view that will show only the moves which locations (source location and destination location; i use them in stock.picking object) can be managed by a viewing user.
By far I wrote a filter that looks like that:
<record id="view_picking_internal_search_pl" model="ir.ui.view">
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
<field name="arch" type="xml">
<filter icon="terp-dialog-close" name="done" string="Done" domain="[('state','=','done')]" help="Pickings already processed" position="after">
<filter icon="terp-check" name="locgroup" string="Location Group" domain="[('user_id','in',[user.id for user in location_id.user_group.users])]" context="{'group_by':'date'}"/>
</filter>
</field>
</record>
I also added field location_id to the tree view.
But Im still getting an error (after choosing the filter) that even google doesnt know anything about:
TypeError: results.group_by is undefined
My questions are:
By looking on domain in filter field - what am i doing wrong?
Is something like that even possible?
I will gladly welcome any help.
Firstly, i think your domain is not correct, it could have been :
[('user_group.users.id', '=', uid)]
(because the first element of the tuple is a field on the model; and uid is a special value supplied in search views)
Next, This error :
TypeError: results.group_by is undefined
Seems to be a Javascript Error (coming from openerp-web interface), it often throws error like that when it receives unexpected values (when we make a mistake defining a view for example).
can you tell us if using the domain above solved your problem ?
NB: does your field user_group is a required field ? If not, i think the domain above won't display picking where user_group is not set, if you want to display picking where user_group is not set too, you can set a domain like that:
['|',('user_group.users.id', '=', uid), ('user_group','=',False)]
Regards

Solr returning different output fields for each document in result

Hello i've read the Solr wiki and searched here but didn't find a solution for my use-case:
We're indexing customer-data with different kind of contracts into a single document.
So each customer will result in a Solr document witth one or more different contracts.
The fields for each contract are added dynamically via import (e.g. contract_type_1_s, contract_type_2_s, ...; contract_change_date_1_dt, contract_change_date_2_dt, ...). So all fields with '2' are related to contract no 2.
With this the user is able to search for customers who have a contract of type one and none of type two and so on.
My use case is now to return only the fields of the contract which matched the query.
Here's an example:
<doc>
<field name="id">100</field>
<field name="customer_name">paul</field>
<field name="contract_type_1_s">inhouse</field>
<field name="contract_change_date_1_dt">2012-09-01T00:00:00Z</field>
</doc>
<doc>
<field name="id">101</field>
<field name="customer_name">fred</field>
<field name="contract_type_1_s">inhouse</field>
<field name="contract_change_date_1_dt">2012-09-01T00:00:00Z</field>
<field name="contract_type_2_s">external</field>
<field name="contract_change_date_2_dt">2012-09-01T00:00:00Z</field>
</doc>
<doc>
<field name="id">102</field>
<field name="customer_name">karl</field>
<field name="contract_type_1_s">external</field>
<field name="contract_change_date_1_dt">2012-09-01T00:00:00Z</field>
<field name="contract_type_2_s">inhouse</field>
<field name="contract_change_date_2_dt">2012-09-01T00:00:00Z</field>
</doc>
If the user now searches for customers with contract-type 'external' the documents with ids 101 and 102 are in the result. Now i want to return different fields of the contract which matched the query.
In this example these should be contract_change_date_1_dt for document 102 and contract_change_date_2_dt for document 101, since contract no 1 is external in document 102 and contract no 2 is external in document 101.
Is there a way to achive this behavior with build-in components?
I know that i can find out which fields matched the query with the highlight-component.
I endet up with following resolution, but it forces me to extend Solr:
Write a QParser to to identify needet fields, add them to the fl-param
Do a Highlighting-Query before returning the results to the Client
Iterate over all docs in result and add the fields which matched the query per doc into the result list
I Hope i made my problem clear. Any suggestions which is a good way to archive this are really appreciated.
greetings René
if someone needs a similar thing ;-)
I now managed to build up my custom result list in the following way:
Create a Custom QueryComponent (extending standard QueryComponent) to store the fields which are used in the query. In the prepare-method activate highlighting with the stored fields:
// Making params modifieable
ModifiableSolrParams modifiableParams = new ModifiableSolrParams(params);
req.setParams(modifiableParams);
modifiableParams.set(HighlightParams.FIELDS, queryFieldList);
modifiableParams.set(HighlightParams.HIGHLIGHT, "true");
modifiableParams.set(HighlightParams.FIELD_MATCH, "true");
modifiableParams.set(HighlightParams.SIMPLE_PRE, "");
modifiableParams.set(HighlightParams.SIMPLE_POST, "");
Create a Custom HighlightComponent (extending standard HighlightComponent) to build the result out of the std. result. In the process-method i now get the highlight info and extract the information i need:
NamedList<Object> rspValues = rb.rsp.getValues();
NamedList<Object> nlHl = (NamedList<Object>) rspValues.get("highlighting");
this.hlDocsAndFields = extractHighlightingInfo(nlHl);
For that i created a custom List, which is able to count the matches per contract (how much fields of contract_X_s are in the highlighted results).
This works fine.
I now stuck at the response writer who resolves the document-fields himself when he builds the response :-(
Has annyone a suggestion on changig/customizing the response writer?
greetings René
I now managed the whole thing.
I must not change the response writer at all :-)
I just had to store all fields which i resolved for each document and add them to the response:
rb.rsp.setReturnFields(globalResultFields);
greetings René