Odoo, how to override an action extending it's domain (not overriding) - odoo

In a module that I do NOT own is the following act_window.
<record id="act_465" model="ir.actions.act_window">
<field name="name">Act 465</field>
<field name="res_model">stock.move</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('available','=',True)]</field>
</record>
I would like to add the following AND criteria to the domain in my separate module:
('canceled', '!=', True)
I know I could OVERRIDE the act_window and the value of domain by [('available','=',True),('canceled', '!=', True)]. However doing so would totally remove what was already in place ('available','=',True). Meaning that if the owner of the base module change it's domain, I'll override his changes anyway.
Question
How could I EXTEND the domain by saying "I would like to add ('available','=',True) to the existing domain" ?

You can't, the action domain is a char field and there is no attribute to specify how to extend a specific record value.
It is possible to use the function tag in the XML data file to call the write method and update the domain or create a function to update the action domain with a given domain list as a parameter.
Use the function tag to update the domain as a string (we suppose that the domain is set, list of tuples provided as a string)
Example:
<function model="ir.actions.act_window" name="write">
<value eval="[ref('sale.action_quotations_with_onboarding')]"/>
<value model="ir.actions.act_window" eval="{'domain': obj().env['ir.actions.act_window'].browse(ref('sale.action_quotations_with_onboarding')).domain[:-1] + ', (\'invoice_status\', \'=\', \'to invoice\')]'}"/>
</function>
Create a function to update the domain as a list with a given domain as a parameter
Example:
class IrActionsActWindow(models.Model):
_inherit = 'ir.actions.act_window'
def update_domain(self, new_domain=None):
if new_domain:
self.write({'domain': safe_eval(self.domain) + new_domain})
Use the function to call the update_domain method:
<function model="ir.actions.act_window"
name="update_domain"
eval="[ref('sale.action_quotations_with_onboarding'), [('invoice_status', '=', 'to invoice')]]"/>

Related

CUBA : entity inheritance

Provided sample 'Entity Inheritance' has the following entity model:
- Customer
- Company extends Customer
- Person extends Customer
- Order
The OrderEdit screen show how to handle the inheritance for fields associated with a Customer that could be a Company or a Person. This is perfectly clear.
However, edit screens for Company and Person do not take inheritance into account : they simply duplicate 'email' field which is commonly inherited from Customer.
Given all inputs I had at this point, if I had to design these screens I would propose the following way.
1) CustomerEditFrame : with the email field, no datasource defined
2) PersonEditScreen:
- Person datasource
- map lastName and firstName fields on Person datasource
- embed CustomerEditFrame
- inject Person datasource in the CustomerEditFrame
3) CompanyEditScreen:
- Company datasource
- map industry field to Company datasource
- embed CustomerEditFrame
- inject Company datasource in the CustomerEditFrame
Then the CustomerEditFrame is responsible for editing the subset of fields it is aware of in a datasource referring either of the two subclasses. Would this design work ?
For the sake of completeness of documentation I think this should be covered by the sample, as it is common case. In addition, it would be a good sample for frame manipulation.
You are absolutely right that screens should take entity inheritance into account to eliminate duplication of code. I've forked the sample project here to demonstrate how it can be done using frames.
customer-frame.xml contains fields of the base entity and a datasource for it:
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
caption="msg://editCaption"
class="com.company.entityinheritance.gui.customer.CustomerFrame"
focusComponent="fieldGroup"
messagesPack="com.company.entityinheritance.gui.customer">
<dsContext>
<datasource id="customerDs"
class="com.company.entityinheritance.entity.Customer"
view="_local"/>
</dsContext>
<layout spacing="true">
<fieldGroup id="fieldGroup"
datasource="customerDs">
<column width="250px">
<field id="name"/>
<field id="email"/>
</column>
</fieldGroup>
</layout>
</window>
In the CustomerFrame controller there is a public method to set an instance to the datasource:
public class CustomerFrame extends AbstractFrame {
#Inject
private Datasource<Customer> customerDs;
public void setCustomer(Customer customer) {
customerDs.setItem(customer);
}
}
The Company editor company-edit.xml includes the frame instead of Customer fields:
<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
caption="msg://editCaption"
class="com.company.entityinheritance.gui.company.CompanyEdit"
datasource="companyDs"
focusComponent="customerFrame"
messagesPack="com.company.entityinheritance.gui.company">
<dsContext>
<datasource id="companyDs"
class="com.company.entityinheritance.entity.Company"
view="_local"/>
</dsContext>
<layout expand="windowActions"
spacing="true">
<frame id="customerFrame"
screen="demo$Customer.frame"/>
<fieldGroup id="fieldGroup"
datasource="companyDs">
<column width="250px">
<field id="industry"/>
</column>
</fieldGroup>
<frame id="windowActions"
screen="editWindowActions"/>
</layout>
</window>
In the Company editor controller, the frame is injected and an edited instance is passed to it:
public class CompanyEdit extends AbstractEditor<Company> {
#Inject
private CustomerFrame customerFrame;
#Override
protected void postInit() {
customerFrame.setCustomer(getItem());
}
}

How to get field value from a model from another model in Odoo?

I'm having some trouble to understand how to get field values from another model.
I added a custom field in res.partner module by making a custom module:
class custom_partner_fields(osv.osv):
_inherit = 'res.partner'
_columns = {
'RTN': fields.char('RTN Numerico'),
}
_defaults = {
}
custom_partner_fields()
Then I create a custom xml for the form view when creating a new customer and now I can see RTN field in the customer create form.
Now I want this new field to appear when making a new quotation/sale order.
I would like it to get its value when I select my customer (I believe onchange function should be use but don't know how to use that!),so what I did was create a custom module for it:
class custom_saleorder_fields(osv.osv):
_inherits = 'sale.order'
_columns = {
'partner_rtn': fields.char('RTN'),
}
custom_saleorder_fields()
I believe I need to use something like a function or relational field for this but what I've tried hasn't worked yet.
Then, I created the custom view form the sale order form view and adds my partner_field.
Now, I would like to know how can I access the specific RTN value from res.partner module from custom_saleorder_fields based on the selected customer.
On the other hand, the main purpose of this new value is to displayed in the sale workflow and also print it in a report.
You need to add relational field in sale order model.
Before applying code you should refer that documentation of odoo,
In the Odoo Field Doc you will know how fields.related works.
class custom_saleorder_fields(osv.osv):
_inherits = 'sale.order'
_columns = {
'partner_rtn': fields.related('partner_id','RTN',type="char",relation="res.partner",string="RTN",store=True,readonly=True),
}
custom_saleorder_fields()
bring modelA fields in modelB by relatiional fields
eg use many2one field in another model :
from openerp import models, fields, api
class partsproviderclass(models.Model):
_name='partsprovider.vechicle'
#_rec_name='parts_provider'
id=fields.Integer()
parts_provider=fields.Many2many('supplier.car', string="Parts provider")
parts_name=fields.Many2many('selection.selection',string="Parts Name")
parts_price=fields.Float(string="Price of the Part")
class selectionsxample(models.Model):
_name='selection.selection'
name=fields.Char('name',required=True)
value=fields.Char('value',required=True)

How to serialize additional edge information in QuickGraph?

I'm working with a graph dataset that could have edges of different logical meaning, like that:
"Bavaria" -[PART_OF]-> "Germany"
"Germany" -[NEIGHBOR_OF]-> "France"
I represent this domain by using the QuickGraph.TaggedEdge where TTag generic parameter is a string:
QuickGraph.BidirectionalGraph<IGeographicalUnit, TaggedEdge<IGeographicalUnit, string>>
This works perfectly until the moment I try to serialize my graph to .graphml form:
using (var w = XmlWriter.Create(#"C:\Temp\data.graphml"))
{
_graph.SerializeToGraphML<IGeographicalUnit, TaggedEdge<IGeographicalUnit, string>, BidirectionalGraph<IGeographicalUnit, TaggedEdge<IGeographicalUnit, string>>>(w);
}
Serialized edge data doesn't contain any tag information, only source and target:
<edge id="0" source="0" target="1" />
What I want is something like:
<edge id="0" source="0" target="1" tag="PART_OF" />
So, the question is, how can I enforce this tag to be serialized?
To solve this problem, I created my own edge implementation pretty similar to the TaggedEdge mentioned above:
public class DataEdge<TVertex> : Edge<TVertex>
{
[XmlAttribute("Tag")]
public string Tag { get; set; }
public DataEdge(TVertex source, TVertex target)
: base(source, target) { }
public DataEdge(TVertex source, TVertex target, string tag)
: this(source, target)
{
Tag = tag;
}
}
Then I replaced TaggedEdge occurrences with my DataEdge. After that, serialization produced the following XML output:
<edge id="0" source="0" target="1">
<data key="Tag">PART_OF</data>
</edge>
The problem is solved, but I hope that another solution exists that don't involve writing your own Edge implementations.

Solrj and Dynamic Fields

I'm have a solr schema with dynamic field of different types in. Eg in the schema.xml there are:
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
<dynamicField name="*_l" type="long" indexed="true" stored="true"/>
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
And I want to access these field using a SolrJ annotated POJO. I know I can have different Map references for each data type in the POJO like this:
...
#Field("*_s")
public Map<String, String> strings;
#Field("*_i")
public Map<String, Integer> integers;
...
But is it possible to have all dynamic fields stored in the same map? I was thinking something like:
...
#Field("*_s")
#Field("*_i")
public Map<String, Object> dynamicFields;
...
The only documentation I can find about SolrJ, POJOs and dynamic fields is an old feature request:
https://issues.apache.org/jira/browse/SOLR-1129
I worked out the matching of the 'pattern' value in the #Field annotation doesn't have to match what's in your schema.xml. So, I defined a map in my doc class:
#Field("*DF")
private Map<String, Object> dynamicFields;
and then in the schema.xml the dynamicFields have patterns postfixed by 'DF':
<dynamicField name="*_sDF" type="string" indexed="true" stored="true"/>
<dynamicField name="*_siDF" type="sint" indexed="true" stored="true"/>
<dynamicField name="*_tDF" type="date" indexed="true" stored="true"/>
Now all the dynamicField with different value types get stored and retrieved using solrServer.addBean(doc) and solrResponse.getBeans(Doc.class). This is with Solr 3.2.0 It wasn't working with 1.4..

How to Map Enum in NHibernate to Properly Create DB Field on Schema Export?

I've seen several questions related to properly mapping an enum type using NHibernate.
This article by Jeff Palermo showed me how to do that properly by creating a custom type. I use Schema Export to create my DB during my dev cycles, but this method breaks my export statement. Is there a way to specify the type of the column on export?
Here is my enum code:
public enum OperatorCode
{
CodeA,
CodeB,
CodeC,
CodeD
}
Here is my custom type:
public class OperatorCodeType:EnumStringType
{
public OperatorCodeType():base(typeof(OperatorCode),20)
{
}
}
Here is my property in my mapping file:
<property name="OperatorCode" column="OperatorCode" type="OperatorCodeType" />
And finally here is my class declaration for that property:
public virtual OperatorCode OperatorCode { get; set; }
Is it even possible to do this?
I have not tested it, but you can use the Column declaration within a property to specify the sql type. Example from the docs:
<property name="Foo" type="String">
<column name="foo" length="64" not-null="true" sql-type="text"/>
</property>
Granted this is a string, but you may want to try it with the type of OperatorCodeType, column sql-type as text or nvarchar or whatever works.
If you try it, let me know? Not near my dev machine at the moment.