How to get field value from a model from another model in Odoo? - 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)

Related

Odoo add function to defaul create action

I've got this function
def add_default_docs(self):
for r in self:
id = self.id
labs_archive_journal_type_id = r.journal_type_id.id
archive_doc_name_ids = self.env['labs.archive.journal_type'].search([('id', '=', labs_archive_journal_type_id)]).archive_doc_name_ids
for n in archive_doc_name_ids:
self.env['labs.archive.document'].create({
"archive_journal_id": id,
"name": n.id
})
How could I call it when I press 'Create' button and create new record?
Whichever model you want to fire this function on creation on new model, inherit that model if that model is odoo built-in or if your own model, within that model definition inherit create method as following:
class ClassName(models.Model)
_inherit = 'model.name'
#api.multi
def create(self, vals):
records = super(ClassName, self).create(vals)
records.add_default_docs()
return records
If your model is defined in your own custom module, you can just insert this create function within that model definition, you won't need to inherit in new class.

Correct way to extend Prestashop 1.7

In PS 1.7 documentation, we can read multiple time that the PS override system is not recommended, an it's not allowed to publish module in the PS marketplace.
We have to only use hooks, and extend existing class, and I understood why.
But how to use the extended class instead of the core one in our custom theme ?
Let use a example :
I want to add a custom field for categories.
In a module I extend the CategoryCore class :
class Category extend CategoryCore{
private $bottom_description
...
}
Then to add the field in the category's admin page I can use some hook like displayBackOfficeCategory and actionBeforeAddCategory.
But I'm not sure for the front : the new variable have to be accessible in some theme templates files.
In my custom theme, in the category.tpl template, $category->bottom_description is undefined.
Fix this issue by overriding the CategoryController is easy,but how to do this only with hook ?
The only way I found is to use the actionFrontControllerSetMedia hook, like this :
function HookActionFrontControllerSetMedia(){
// get my custom Category object base on url
this->context->smarty->assign(["category_bottom_description"=>$category->buttom_description]);
}
This look tricky, and my new field is still not accessible in other context.
So what is the proper way to get this property available in my custom them ?
Ideally, the new property should be available every time we found a category object, like this : $category->bottom_description.
Do not forget to define a new field at category class because at the front you have not a class instance but an array which is converted within ObjectPresenter class. So follow this way. Extend your Category class and add all necessary definitions
class Category extends CategoryCore
{
public $bottom_description;
public function __construct($idCategory = null, $idLang = null, $idShop = null)
{
Category::$definition['fields']['bottom_description'] = array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml');
$this->bottom_description = 'bottom_description'; // just to add demo data
parent::__construct($idCategory, $idLang, $idShop);
}
}
and then the field bottom_description will be available in the category.tpl but like an array {$category.bottom_description}. Hope it will help you.

Yii Custom Validator creation

I am new to Yii framework, so please any one help me for this question
How to create custom validator class for the following validation,
I am having one table list , it is having listname and types on it, my validator want to check the list name to be unique for the specific type, for example,
listName Type
test1 1
test2 1
test3 2
when I insert a new list name validator, I want to retrieve the listnames and type and provide error if it is not unique for the specific type.
Well creating a custom validator method is really simple if that's what you are looking for.
You need a to add an element to rules() method in your Model (i.e protected/model/youTableName.php)
return array(
array('listName', 'uniqueForType', 'type')
);
Create a method to youTableName.php named by the validator name.
public function uniqueForType($field, $params)
{
$filedToCompare = $this->$field;
$fieldToCompareWith = $this->$params;
// Do your checking and comparing
if($weHaveAnError) {
$this->addError($field, printf("This listName already exists for type %s", $this->$params));
}
}
That should do the trick. Got that information form http://www.yiiframework.com/forum/index.php/topic/20399-conditional-validation-rule/

How to find all model names in a yii application?

I am using a Module in yii, and the module will be used when a property of an application model is true.
How can I get all the model names available in my application so that i can establish relations on conditional basis between application models having the property and the module?
You can use below method to get class name:
public function modelName()
{
return __CLASS__;
}
and call it like this:
$model = new State();
echo $model->getModelName();

ASP.NET MVC 2 RC model binding with NHibernate and dropdown lists

I have problem with model binding in my ASP.NET MVC 2 RC application that uses NHibernate for data access. We are trying to build the application in a Ruby on Rails way and have a very simple architecture where the domain entities are used all the way from the database to the view.
The application has a couple of domain entities which can be illustrated by the following two classes:
public class Product {
...
public Category Category { get; set; }
}
public class Category {
public int Id { get; set; }
public string Name { get; set; }
}
In the view that renders the edit form has the following statement to display a dropdown list:
<%= Html.DropDownListFor(model => model.Category.Id,
new SelectList(ViewData["categories"] as IList<Category>, "Id", "Name"),
"-- Select Category --" ) %>
Please disregard the use of "non-typed" view data to hold the category collection.
The action method that receives the form post is similar to to the following. Note that the TransactionFilter attribute adds NHibernate transaction handling and commits the transaction if no exceptions occur and validation succeeds.
[HttpPost]
[TransactionFilter]
public ActionResult Edit(int id, FormCollection collection) {
var product = _repository.Load(id);
// Update the product except the Id
UpdateModel(product, null, null, new[] {"Id"}, collection);
if (ModelState.IsValid) {
return RedirectToAction("Details", new {id});
}
return View(product);
}
My issue is that the product.Category.Id is set with the value selected in the form, e.g. Category.Id = "2". Using the default model binder results in the following type of NHibernate exception:
identifier of an instance of Name.Space.Entities.Category was altered from 4 to 2
That makes a lot of sense since the product already has a category assigned and only the primary key of that existing category is being changed. Another category instance should have been assigned instead.
I guess a custom ModelBinder can be created to handle this issue but is there a simpler way to make this work? Can (and should) the domain entities be modified to handle this?
I solved a similar problem with combo boxes on my edit page by changing the following line
#Html.DropDownListFor(x => x.Employee.Id, new SelectList(ViewBag.Employees, "Id", "DisplayName"))
by
#Html.DropDownListFor(x => x.Employee, new SelectList(ViewBag.Employees, "Id", "DisplayName"))
So I removed the '.Id' like Bryan suggested. Before the change, the model only contained the Id of the Employee and after the change, the Binder also loaded all the details of the employee into the model.
I've used similar techniques with Linq to SQL classes before with no problems. I don't think you'd need a custom ModelBinder for this. UpdateModel should be updating the Product class you are passing into it - not the Category sub-class attached to it. Check the html generated by the DropDownListFor helper. What is the name of the element? It should be the name of the foreign-key field in your Products table (e.g. "CategoryID" or "Product.CategoryID" not "Category.Id"). If it's "Category.Id" - try changing the first parameter of the DropDownListFor to either "model => model.Category" or "model => model.CategoryID" (or whatever the foreign key field is). This should cause UpdateModel to only update the foreign-key field in the Product class and not the Category class ID.
The solution we chose at the time was something similar to this:
TryUpdateModel(product, null, null, new[] {"Category"}, collection);
int categoryId;
if (int.TryParse(collection["Category.Id"], NumberStyles.Integer, CultureInfo.InvariantCulture, out categoryId) && categoryId > 0) {
product.Category = _categoryRepository.Load(categoryId);
}
else {
product.Category = null;
}
We simply tell the model binder to exclude the association property and handle that manually. Not pretty but worked at the time....