<record model="ir.actions.act_window" id="action_purchase_orders">
<field name="name">Purchase Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('id', 'in', purchase_order_ids.ids)]</field> <------- This is not working.
</record>
<record id="purchase.form" model="ir.ui.view">
<field name="name">purchase.form</field>
<field name="model">purchase.form</field>
<field name="arch" type="xml">
<form string="Purchase Form">
<sheet>
<div class="oe_button_box" name="button_box">
<button type="action" name="%(action_purchase_orders)d" class="oe_stat_button" icon="fa-list-alt"
attrs="{'invisible':[('purchase_order_count', '=', 0)]}">
<field name="purchase_order_count" invisible="1"/>
<field name="purchase_order_ids" string="Purchase Orders" widget="statinfo" help="Purchase orders"/>
</button>
...
class PurchaseForm(models.Model):
_name = 'purchase.form'
#api.depends('purchase_order_ids')
def _purchase_order_count(self):
for pp in self:
pp.purchase_order_count = len(pp.purchase_order_ids)
purchase_order_ids = fields.Many2many('purchase.order', 'purchase_form_purchase_order_rel', 'purchase_form_id', 'purchase_order_id', 'Purchase Orders', states=READONLY_STATES)
purchase_order_count = fields.Integer(compute='_purchase_order_count', string='# of Purchase Orders')
Error:
Uncaught Error: NameError: name 'purchase_order_ids' is not defined
http://localhost:8069/web/content/801-4161526/web.assets_backend.js:144
Traceback:
Error: NameError: name 'purchase_order_ids' is not defined
at PY_ensurepy (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:144:65)
at Object.py.evaluate (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:259:8)
at Object.py.evaluate (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:267:99)
at Object.py.evaluate (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:268:194)
at Object.py.eval (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:272:284)
at http://localhost:8069/web/content/801-4161526/web.assets_backend.js:377:110
at iterator (http://localhost:8069/web/content/800-e6de2a4/web.assets_common.js:14:183)
at Function.<anonymous> (http://localhost:8069/web/content/800-e6de2a4/web.assets_common.js:17:8)
at _.(anonymous function) [as reduce] (http://localhost:8069/web/content/800-e6de2a4/web.assets_common.js:69:526)
at eval_contexts (http://localhost:8069/web/content/801-4161526/web.assets_backend.js:375:136)
You cannot do that in the action_purchase_orders view action, you cannot use a field in the right side of domain tuples, because there will be no context to supply that value. To get it done you will need to change your button to be of type object and using a python method associated return the action dict with the desired domain values evaluated so the domain only contain values for their right side tuples. Like(see the new type and name for the button):
<button type="object" name="action_purchase_orders" class="oe_stat_button" icon="fa-list-alt" attrs="{'invisible':[('purchase_order_count', '=', 0)]}">
<field name="purchase_order_count" invisible="1"/>
<field name="purchase_order_ids" string="Purchase Orders" widget="statinfo" help="Purchase orders"/>
</button>
In your purchase.form model define the method action_purchase_orders, like:
#api.multi
def action_purchase_orders(self):
self.ensure_one()
return {
'name': _('Purchase Orders'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'purchase.order',
'target': 'new',
'domain': [('id', 'in', self.purchase_order_ids.ids)]
'context': self.env.context.copy(),
}
Add relation to purchase.order
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
purchase_form_ids = fields.Many2many('purchase.form', 'purchase_form_purchase_order_rel', 'purchase_order_id', 'purchase_form_id', 'Purchase Orders')
and change action view to
<record model="ir.actions.act_window" id="action_purchase_orders">
<field name="name">Purchase Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">purchase.order</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('id', 'in', purchase_form_ids.ids)]</field>
</record>
Related
below is my attempt to add a timestamp to when user submits form.
renderTimeStamp = ({ input, label }) => {
return (
{label}
<input {Date.now()} />
);
};
<Field
name="timestamp"
component={this.renderTimeStamp}
placeholder={moment().format()}
label="Time Stamp"
/>
I managed to configure everything as expected with Formik, and the AJAX requests seems fine (it shows me the success message if I enable it), but the Netlify form section is still empty (even if the form is listed and acknowledged by Netlify).
This is my contact component:
(I think the problem is on my ajax code under the onSubmit function)
import React from 'react'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import Layout from "../components/layout"
import SEO from "../components/seo"
const ContactForm = () => (
<Layout>
<SEO title="Form with Formik" />
<main class="page-contact-form">
<h1>Do your booking</h1>
<Formik
initialValues={{ email: '', name: '', start: '', end: '', message: '' }}
validate={values => {
let errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={(values) => {
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: ({
"form-name": "contact",
...values
})
}).then(() => alert("Thank you!"))
}}
>
{({ isSubmitting }) => (
<Form name="contact" data-netlify="true" action="/grazie">
<input type="hidden" name="form-name" value="contact" />
<label>Name and Surname: <br />
<Field type="text" name="name" placeholder="Nome Cognome" />
<ErrorMessage name="name" component="div" />
</label>
<br />
<label>Email: <br />
<Field type="email" name="email" placeholder="Richiesto" />
<ErrorMessage name="email" component="div" />
</label>
<br />
<label>Start and End <br />
<Field type="date" name="start" />
<ErrorMessage name="start" />
<Field type="date" name="end" />
<ErrorMessage name="end" />
</label>
<br />
<label>
Message: <br />
<Field type="text" name="message" />
<ErrorMessage name="message" />
</label>
<br />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
</main>
</Layout>
)
export default ContactForm
In the fetch function in onsubmit, it looks like you're sending an object, but the content type is url encoded? Perhaps you need to serialize your object into url encoded format first. There's a host of solutions for that in this question. If you go with the top suggestion:
// https://stackoverflow.com/a/1714899/10340970
const serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
...
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: serialize({
"form-name": "contact",
...values
})
In Bill Of Materials we can make product from other products. as you can see in picture 1 there is Test Product made from 2 other product.
in Sale Order line I made button that opens this form with Product Price and Qty
But the goal is to open form where i can manage products that Test Product are build from and change qty and price there.
<record id="view_order_line_form_view" model="ir.ui.view">
<field name="name">sale.order.line.forma</field>
<field name="model">sale.order.line</field>
<field name="arch" type="xml">
<form string="Sales Order Lines">
<field name="product_id" />
<field name="product_uom_qty" string="Qty" placeholder="Qty"/>
<field name="price_unit" string="Price"/>
</form>
</field>
</record>
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
#api.multi
def button_details(self):
context = self.env.context.copy()
context['view_buttons'] = True
view_id = self.env.ref('cfg.view_order_line_form_view').id
view = {
'name': _('Details'),
'view_type': 'form',
'view_mode': 'form',
'res_model': 'sale.order.line',
'views' : [(view_id,'form')],
'type': 'ir.actions.act_window',
'target': 'new',
'readonly': True,
'res_id': self.id,
'context': context
}
return view
I'm new to odoo, I need to delete some fields that appear when click add a custom filter in a fleet module in odoo 10, and how to add custom filters and delete existing ones?
Thank you for any help.
You can use field_get() to change field attribute "selectable", which is used in search_menu.js in web module to decide what fields to show when clicking "Add Custom Filter. Try this:
selectable_fields = ['field1',...]
#api.model
def fields_get(self, allfields=None, attributes=None):
res = super(YourModel, self).fields_get(allfields, attributes=attributes)
not_selectable_fields = set(self._fields.keys()) - set(self.selectable_fields)
for field in not_selectable_fields:
res[field]['selectable'] = False
return res
Related code in search_menu.js:
get_fields: function () {
if (!this._fields_def) {
this._fields_def = data_manager.load_fields(this.searchview.dataset).then(function (data) {
var fields = {
id: { string: 'ID', type: 'id', searchable: true }
};
_.each(data, function(field_def, field_name) {
if (field_def.selectable !== false && field_name !== 'id') {
fields[field_name] = field_def;
}
});
return fields;
});
}
return this._fields_def;
},
Add this filter to your code.
For example: To add filter in Sale Order Line.
<record id="inherit_so_line_filter_view" model="ir.ui.view">
<field name="name">sale.order.list.available</field>
<field name="model">sale.order.line</field>
<field name="inherit_id" ref="sale.view_sales_order_line_filter"/>
<field name="arch" type="xml">
<search>
<filter string="Pending" domain="[('remian_qty','>',0)]" name = "qty_available"/>
<filter string="Lost" domain="[('remian_qty','=',0)]" name = "qty_lost"/>
</search>
</field>
</record>
For example: To add filter using xpath in Sale Order.
<record id="view_sale_order_inherit_search" model="ir.ui.view">
<field name="name">sale.order.search.filter</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.sale_order_view_search_inherit_quotation"/>
<field name="arch" type="xml">
<xpath expr="//search" position="inside">
<filter string="Total < 1000" name="total_under_1000" domain="[('amount_total', '<', 1000)]"/>
<filter string="Total >= 1000" name="total_above_1000" domain="[('amount_total', '>=', 1000)]"/>
</xpath>
</field>
</record>
Inherit the existing filter like this:
<record id="any_id_name" model="ir.ui.view">
<field name="name">model.nameinsearchview</field>
<field name="model">model.name</field>
<field name="inherit_id" ref="external_id/>
<field name="arch" type="xml">
<filter name="that_field_name_in_exisiting_filter_view" position="replace">
</filter>
</field>
</record>
that's it. Now this will replace the existing code.
first cusrom field file-
StepDescription.php
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('textarea');
/**
* Description of StepTitle
*
* #author admin
*/
class JFormFieldStepDescription extends JFormFieldTextarea {
public $type = 'StepDescription';
function getLabel() {
return parent::getLabel();
}
function getInput() {
$this->name .= '[]';
if (empty($this->value)) {
$this->value = '';
return parent::getInput();
} else {
$arr = array();
$values = $this->value;
$this->value = null;
foreach ($values as $key => $value) {
$this->value = $value;
$arr[] = parent::getInput();
}
return $arr;
}
}
}
second custom field file-
StepTitle.php
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
jimport('joomla.form.helper');
JFormHelper::loadFieldClass('text');
/**
* Description of StepTitle
*
* #author admin
*/
class JFormFieldStepTitle extends JFormFieldText {
function getLabel() {
return parent::getLabel();
}
function getInput() {
$this->name .= '[]';
if (empty($this->value)) {
$this->value = '';
return parent::getInput();
} else {
$arr = array();
foreach ($this->value as $key => $value) {
$this->value = $value;
$arr[] = parent::getInput();
}
return $arr;
}
}
}
here is the form i am using
content.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- $Id: login.xml 22059 2011-09-10 05:20:13Z infograf768 $ -->
<form>
<fieldset name="content"
label="Content"
>
<field name="jobname" type="text"
label="Job name"
size="25"
class="inputbox jobname"
required="true"
/>
<field name="projectortip" type="list"
label="Project or Tip"
class="selectbox"
required="true"
>
<option value="">Select</option>
<option value="1">Project</option>
<option value="2">Tip</option>
</field>
<field name="costestimate" type="text"
label="Cost estimate"
size="25"
class="inputbox"
/>
<field name="category" type="list"
label="Category"
class="selectbox"
required="true"
>
<option value="">Select</option>
<option value="1">cat1</option>
<option value="2">cat2</option>
</field>
<field name="timetaken" type="text"
label="Time Taken"
size="25"
class="inputbox"
/>
<field name="comment" type="checkbox"
label="Allow members to make comments"
default = "false"
class="checkbox"
/>
<field name="difficultylevel" type="list"
label="Difficulty Level"
class="selectbox"
required="true"
>
<option value="">Select</option>
<option value="1">easy</option>
<option value="2">medium</option>
<option value="3">hard</option>
</field>
<field name="emailcomment" type="checkbox"
label="Email me all member comments"
default = "false"
class="checkbox"
/>
<field name="metadata" type="textarea"
label="Metadata"
class="textarea"
/>
<field name="background_information" type="textarea"
label="Background Information"
class="textarea"
/>
<field name="tools_used" type="textarea"
label="Tools Used"
class="textarea"
/>
<field name="material_used" type="textarea"
label="Material Used"
class="textarea"
/>
</fieldset>
<fieldset name="step" label="Step" >
<field name="step_title" type="StepTitle"
label="Step Title"
required="true"
class="step_title"
/>
<field name="step_description" type="StepDescription"
label="Step Description"
class="step_description"
required="true"
/>
</fieldset>
<fieldset>
<field name="id" type="hidden" />
<field name="return" type="hidden" />
</fieldset>
</form>
StepTitle is inputbox and StepDescription is textarea but both StepTitle and StepDescription are displayed as a inputbox in frontend component form. And this problem is not in local but only when i use these same files on server.
It was a problem with file name. StepTitle.php and StepDescription works in localhost in windows machine, but in linux server file name must be in smallcase. so smallcase filenames like steptitle.php and stepdescription.php solved my problem.