How to show/hide print menu(top) item by a condition? - odoo

I try to make an report, that print invoice only if it's type is 'in_invoice'
I use standard case
<report
id="account_att"
model="account.invoice"
string="Att"
report_type="qweb-pdf"
name="account.report_att"
attachment="('Att'+(object.number or '').replace('/','')+'.pdf')"
print_report_name="'Att for '+(object._get_printed_report_name())"
/>
How can I check if object type is 'in_invoice'?
I've tried to add
menu="(True if object.type == 'in_invoice' else False)"
But I get error while install - it seems, menu doesn't recieve object.
How can I change visibility?

Related

How to write/update some inherited fields in product category to multicompany

I was inherited some fields in product.category model and i want to show that some other fields on my other companies.. I am tried to give the answer on create function and Also tried on other Button But i can't write the values that i give in the main company to other companies.. Please Help me to find the Answer..
#api.model
def create(self, vals_list):
res = super(ProductCentralized, self).create(vals_list)
vals = []
vals.append({
'property_cost_method': res.property_cost_method,
'name':res.name,
'property_valuation': res.property_valuation,
'property_stock_valuation_account_id': res.property_stock_valuation_account_id,
'property_stock_journal': res.property_stock_journal,
'property_stock_account_input_categ_id': res.property_stock_account_input_categ_id,
'property_stock_account_output_categ_id': res.property_stock_account_output_categ_id,
})
res.sudo().create({'property_cost_method': self.property_cost_method,
'name': self.name,
'property_valuation': self.property_valuation,
'property_stock_valuation_account_id': self.property_stock_valuation_account_id,
'property_stock_journal': self.property_stock_journal,
'property_stock_account_input_categ_id': self.property_stock_account_input_categ_id,
'property_stock_account_output_categ_id': self.property_stock_account_output_categ_id})
return res
Please Help me to correct this code or using another button.. Thanks in Advance..
Consider changing the corresponding view : "res.partner.form" instead. You can find it this way : in App Settings, switch to debug mode by adding "?debug=1" in your url, reload the page, then go to the new Technical Menu-tab > View.
Then you can display your partner/company(id= 1344 ) fields, using :
For Back-Office :
<t t-esc="self.env['res.partner'].browse(1344).name" />
For Front-Office :
<t t-esc="request.env['res.partner'].browse(1344).name" />
Or you can display your product_template (id= 135 ) fields, using :
<t t-esc="self.env['product.template'].browse(135).property_valuation" />
Or you can display your stock fields, using :
<t t-esc="self.env['stock.quant'].search([('product_id','=','5')]).location_id.name" />

Empy list on return

I have this in my qweb report
<span t-esc="formatLang(get_routing_data(o)[-1]['total'] , digits=3)"/>
it works ok, but sometimes it returns an empty list and then i get error index tuple out of range. how can i avoid it?
You could set the return value of the call to get_routing_data into a variable and make check the value using t-if conditions before use it, like:
<t t-set="routing_data" t-value="get_routing_data(o)"/>
<span t-if="routing_data and len(routing_data) > 0 and routing_data[-1].get('total', False)" t-esc="formatLang(routing_data[-1]['total'], digits=3)"/>

Odoo search view filter using value from model

I've added a field to my products in Odoo called x_low_inventory_level. I would like to add a filter to the search view for the product tree that will only show products who have qty_available < x_low_inventory_level. Is this possible? I've tried adding this to the search view:
<filter string="Low Inventory" name="low_inventory" domain="[('qty_available', '<', x_low_inventory_level)]"/>
But I get an error:
https://my-instance.odoo.com/web/content/525-9a23e87/web.assets_backend.js:1715
Traceback:
Error: Failed to evaluate search criterions:
{"code":400,"message":"Evaluation Error","data":{"type":"local_exception","debug":"Local evaluation failure\nNameError: name 'x_low_inventory_level' is not defined\n\n{\"domains\":[[],\"[('qty_available', '<', x_low_inventory_level)]\"],\"contexts\":[{\"lang\":\"en_US\",\"tz\":false,\"uid\":1,\"params\":{\"action\":418,\"min\":1,\"limit\":80,\"view_type\":\"list\",\"model\":\"product.product\",\"menu_id\":84,\"_push_me\":false}},{}],\"group_by_seq\":[]}"}}
at Object.<anonymous> (https://my-instance.odoo.com/web/content/525-9a23e87/web.assets_backend.js:1715:1192)
at fire (https://my-instance.odoo.com/web/content/528-59c08d4/web.assets_common.js:541:299)
at Object.fireWith [as resolveWith] (https://my-instance.odoo.com/web/content/528-59c08d4/web.assets_common.js:546:198)
at Object.deferred.(anonymous function) [as resolve] (https://my-instance.odoo.com/web/content/528-59c08d4/web.assets_common.js:548:56)
at https://my-instance.odoo.com/web/content/525-9a23e87/web.assets_backend.js:1625:3
I think you cannot do that instead create a compute field with store =true.
This field for example is a boolean field. And use it in Search view but make sure to put store to true.
Hope you get the idea.
create Boolean field
is_low_inventory_level = fields.Boolean('qty_available is_low_inventory_level', default=False)
Then Use Function for return True or False
#api.onchange('qty_available','x_low_inventory_level')
def _onchange_qty_available(self):
if self.qty_available < x_low_inventory_level:
self.is_low_inventory_level = True
else:
elf.is_low_inventory_level = False
and in XML do something like this
<filter string="Low Inventory" name="low_inventory" domain="[('is_low_inventory_level', '!=', False)]"/>

Not getting records which created in One2many field on onchange in transient model

I am trying to create records in one2many field in one of my transient model on onchange of boolean field.
Eg.
Models
class test_model(models.TransientModel):
_name ="test.model"
is_okay = fields.Boolean("Okay?")
lines = fields.One2many("opposite.model","test_id",string="Lines")
#api.onchange('is_okay')
def onchnage_is_okay(self):
ids = []
for l in range(5):
record = self.env['opposite.model'].create({'name':str(l),'test_id':self.id})
ids.append(record.id)
self.lines = [(6,0,ids)]
class opposite_model(models.TransientModel):
_name ="opposite.model"
name = fields.Char("Name")
test_id = fields.Many2one("test.model",string="Test Model")
View
<record id="view_form" model="ir.ui.view">
<field name="name">view.form</field>
<field name="model">test.model</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Test Model">
<field name="is_okay" />
<field name="lines" />
<footer>
<button name ="click_okay" string="Okay" type="object"/>
</footer>
</form>
</field>
</record>
Now, problem is that when in check or uncheck the is_okay field it fills the records in the One2many field.
That is working fine.
But in my above view i have button which calls the method click_okay().
Eg.
#api.one
def click_okay(self):
print self.lines
So, print statement gives me blank recordset. But, i can see the 5 records in the view when i am changing is_okay field.
I am not getting any idea how to get those lines in method?
Any response would be appreciated?
It should work. That's wired behavior.
You may try with following alternative way using self.update()
#api.onchange('is_okay')
def onchnage_is_okay(self):
ids = []
for l in range(5):
record = self.env['opposite.model'].create({'name':str(l),'test_id':self.id})
ids.append(record.id)
self.update({
'lines' : [(6,0,ids)]
)}
No matter what odoo keep doing the same thing:
the problem is that odoo always passes this records to create method with command 1 but in odoo we cannot use this command in create method and this
why you lose this records in the call of method.
(1, id, values)
updates an existing record of id id with the values in values. Can not be used in create().
i don't know why you are creating this record in onchange event because this not recomanded if the user hit close instead of ok the record all ready created in database and every time he check the button will recreate this record again and again.
if you don't need to create this records in the onchange event what you should do is:
#api.onchange('is_okay')
def onchnage_is_okay(self):
ids = []
for l in range(5):
record = self.env['opposite.model'].new({'name': str(l)})
ids.append(record.id)
self.lines = ids
one thing here onchange will return the dictionnary to the form, the tree of the one2field must have all field that are passed in that dictionary in this case the tree must have field name if oppisite.model have for example another field like test_field if we pass {'name': value, 'test_field': value_2} if the tree have only name field value of test_field will be lost in create method.
but if you need like you are doing, you should work arround odoo and change the command to 4 in create a method:
#api.model
def create(self, vals):
"""
"""
lines = vals.get('lines', False)
if lines:
for line in lines:
line[0] = 4
line[2] = False
vals.update({'lines': lines})
return super(test_model, self).create(vals)

Search not working (as expected) for list-form PartyListForm - column loaded from mantle.party.PartyIdentification

I started by using PartyListForm in FindParty.xml. This list loads data related to parties, in my case with Supplier role. I added a new column with an ID from mantle.party.PartyIdentification, with specific partyIdTypeEnumId. The result is satisfactory, I have a list of Suppliers, with their names and respective IDs shown. The problem starts in the moment, when I want to let the user search through those IDs. It does not work. This is the definition of the column:
<field name="idValue">
<header-field title="Company ID" show-order-by="true">
<text-find size="30" hide-options="true"/>
</header-field>
<default-field>
<display text="${partyIdentification?.idValue?:'N/a'}" text-map="partyIdentification"/>
</default-field>
</field>
This is where the data (text-map="partyIdentification") comes from:
<row-actions>
<entity-find-one entity-name="mantle.party.PartyDetail" value-field="party"/>
<entity-find-one entity-name="mantle.party.PartyIdentification" value-field="partyIdentification">
<field-map field-name="partyId" from="partyId"/>
<field-map field-name="partyIdTypeEnumId" value="PtidICO"/>
</entity-find-one>
<entity-find-count entity-name="mantle.party.PartyInvoiceDetail" count-field="invCount">
<econdition field-name="partyId" operator="equals" from="partyId"/>
</entity-find-count>
</row-actions>
This is how it looks on the screen
#David's comment:
There is the original search commented out and my attempt:
<!--<service-call name="mantle.party.PartyServices.find#Party" in-map="context + [leadingWildcard:true, orderByField:'^organizationName', roleTypeId:'Supplier', pageSize:7]" out-map="context"/>-->
<service-call name="mantle.party.PartyServicesEnhancements.findEnhanced#Party" in-map="context + [leadingWildcard:true, orderByField:'^organizationName', roleTypeId:'Supplier', pageSize:7]" out-map="context"/>
I made a few changes by adding new components as a copy of existing ones, namely:
new view-entity with entity-name="FindPartyViewEnhanced" in package="mantle.party as copy of "FindPartyView" with these additions:
<member-entity entity-alias="IDNTF" entity-name="PartyIdentification" join-from-alias="PTY">
<key-map field-name="partyId" related="partyId" />
<entity-condition>
<econdition field-name="partyIdTypeEnumId" operator="equals" value="PtidICO"/>
</entity-condition>
</member-entity>
<alias entity-alias="IDNTF" name="idValue" field="idValue"/>
<alias entity-alias="IDNTF" name="partyIdTypeEnumId" field="partyIdTypeEnumId"/>
new service "findEnhanced" noun="Party" type="script" as a copy of find#Party service with new parameter added:
<parameter name="idValue"/>
new findPartyEnhanced.groovy (copy of findParty.groovy) with a single line added:
if (idValue) { ef.condition(ec.entity.conditionFactory.makeCondition("idValue", EntityCondition.LIKE, (leadingWildcard ? "%" : "") + idValue + "%").ignoreCase()) }
and finally, in the row actions of the screen, where the search is situated, this is what I ended up with:
<service-call name="mantle.party.PartyServicesEnhancements.findEnhanced#Party" in-map="context + [leadingWildcard:true, idValue:idValue, orderByField:'organizationName', roleTypeId:'Supplier', pageSize:7]" out-map="context"/>
Most probably, this is not the best solution, but it worked for me. Hopefully, it will help you as well.