some documentation about _onchange_spec() methose in odoo - odoo

in chapter 6 of the book Odoo Development Cookbook the author introduces the _onchange_spec () methode and he presented it as a follow :
This method will retrieve the updates that are triggered by the odification of which other field. It does this by examining the form view of the model (remember, onchange methods are normally called by the web client).
i need more details

Welcome to the stackoverflow community.
The main objective of the _onchange_spec () method is to call the onchange method from the server side.
In the example of the book you mention, it is explained that:
you can do the required computation yourself, but this is not always
possible as the onchange method can be added or modified by a
third-party addon module installed on the instance that you don 't
know about.
When called:
Passing no argument. This method will retrieve the updates that are triggered by the modification of which other field. It does this by examining the form view of the model.
How to Use it:
You must use it when you want to manually run an onchange method and compute something before creating the registry or updating it.
Example
#api.multi
def return_all_books(self):
self.ensure_one
wizard = self.env['library.returns.wizard']
#this is the manual change (update the member)
values = {'member_id': self.id}
#this examines the form to find the changes
specs = wizard._onchange_spec()
#This gets the values of the onchange
updates = wizard.onchange(values, ['member_id'], specs)
#Combine the results with the new manually added value
values.update(updates.get('value', {}))
record = wizard.create(values)
For another implementation you can check below.
you can see a implementation for testing here

Related

Aurelia Validation rule (bound to model) does not fire on subsequent activations of a view model

I am trying to expand on the Aurelia Contact Manager Tutorial. Specifically: adding email validation to the contact-details.html view. I have followed the examples in the Validation: Basics documentation and on first pass it worked as expected: Launch application, select a contact from the contact-list module, then update the email to something invalid by removing the '#', then tab away. The validation rule fires and the error message is displayed.
However, if after launching the application I select a first contact followed by a second, hence triggering a second activation of the contact-details module, then the validation rule does not fire.
I have tried a validationController.reset() on activate of the contact-detail and while this will remove any 'old' error messages, the on blur validation will still not fire.
I have tried the two different methods of creating the validation controller (using NewInstance.of(ValidationController) vs ValidationControllerFactory) but both yield the same result.
If, after navigating to a second contact and 'breaking' the validation, I then refresh the browser and reload the page then the validation works again. Until I choose another contact from the list which will then break it again.
I am new to Aurelia and JavaScript frameworks in general and I'm not sure if this is a bug or there is something extra required to handle re-routing to the same page.
That's a good question. There are a couple of things that may be catching you out. I've created a Gist which includes the necessary file modifications to get this working:
https://gist.github.com/freshcutdevelopment/170c2386f243e7095e276811dab52299
Gotchas
Because the view-model you're using for validation is not the backing view-model for the contact-detail.html view file you'll need a separate class which you'll apply the validation rules to. Although it sounds like you've already nailed this part, I'll include it for completeness. You can create this class like so:
export class Contact {
email= '';
}
You can then apply the validation rules to this class as follows:
ValidationRules
.ensure(a => a.email).required().email()
.on(Contact);
The last possible missing puzzle piece here is that you'll need to hook into the screen activation life-cycle hook deactivate() and reset the validation context. This will force the BootstrapValidationRenderer to remove the validation styles from your view.
deactivate(){
this.controller.reset();
}
Validation Workflow
The steps are as follows:
Inject the controller
Add the validation renderer to the controller
Create the validation model (only needed if the model you want to validate is not the view-model that backs your view)
Apply the validation rules to the model
Determine when to re-set and execute the validation (in this case on the deactivate life-cycle hook.
Apply the validation binding behavior to the view

How to update fields before the view is displayed in Odoo

I could not figure how I'm supposed to do the following scenario;
I've two fields in my inherited res.partner view "ExternalID" and "ExternalCode" all the fields are going to be editable until those two are filled. And after these two are filled everything is going to be read-only that's the easy part we can handle this by attrs. The problem is when these two fields are filled (they're being filled from an external app by odoo web API.) I need call an external web API before the form is loaded i^ve to update the read-only fields. I've tried placing a computed field and make it invisible so that it gets fired up when the view is being loaded and I thought I should update the other fields but it seems when I write a compute function it can only update the field that it is called from.
For Example;
external_api_call_field = fields.Char(compute='_get_values_from_api')
#api.multi
def _get_values_from_api(self):
for record in self:
#call api and do stuff
#set the values that we got from the external application
record.company_detailed_address="Sample address line"
the method gets triggered and seems to run all the way but when the form is loaded the address field is not filled.
I tried to call
self.write({'company_detailed_address' : 'Sample address line'})
which seems to work but the new value is not set directly you've to refresh the view
Any help or guidance is appreciated.
Regards.

New module for personal collection/receive with possibility to choose shop (pickup to store)

I want to add possibility for clients to receive orders personally in one of our shops. I tried to find some module which gives possibility to select in which shop they want to receive order but I haven't found anything for free. Because of that I want to create new module for it. What's more I'm totally new in prestashop and I don't know where to start or how to create this module. I spend two-three days reading how to do it and these are my assumptions:
New carrier module can be created by extending CarrierModule class.
I read some articles / documentation about hooks.
I have created my first carrier module by editing module attached in this article http://www.prestashop.com/blog/en/carrier_modules_functions_creation_and_configuration/.
What I achieved is that I installed module and used hook 'BeforeCarrier' to add some layout to page after selecting my carrier.
This is how my carrier should work:
It should be a part of carrier list so customer is able to select it.
If carrier is not selected nothing hapens. If carrier is selected by customer then button 'Choose shop' should be shown.
After pressing button 'Choose shop' new window should be show with addresses of our shops (instead of new window it may be placed somewhere in current page).
Window with shop adresses will contain list of addresses with radiobuttons and button to confirm selection.
After confirmation of selection window will be closed and address should be shown as a part of carreir.
E-mail with confirmation will contain information in which shop customer can collect order.
Suppose that addresses will be hardcoded in php code.
These are my questions:
I created new carrier module so I assume it works correctly (as described here http://www.prestashop.com/blog/en/carrier_modules_functions_creation_and_configuration/).
How to add new button 'Choose shop' near selected carrier?
Can I use hooks to add 'Choose shop' button?
Where should I remember choosen shop address? Has 'Carrier' class place for it?
How to add shop address to e-mails? Should I edit layouts? Does e-mail layout contain place for it or do I need to add new 'placeholder' for it?
How to show chosen address on admin side?
To describe my problem more detail I have created few scenario (see attachment).
I will be greatful for any help.
I've posted the same question on prestashop forum.
These example are usually old and poorly written. They lack structure. But for your purpose I suppose they're ok.
Use hookDisplayCarrierList($args). Check $args to see which carrier has been selected, then return <select> element which you
shop addresses. This hook is triggered every time a user selects a carrier and is return via Ajax. Therefore, you may not use ajax here.
You should include you javascript in a file. Use hookDisplayHeader to detect when to insert this file into your page:
public function hookDisplayHeader(){
$propExists = property_exists($this->context->controller, 'php_self');
if($propExists){
$controllerName = $this->context->controller->php_self;
if(in_array($controllerName, array('order', 'order-opc'))){
// $this->context->controller->addJS($this->_path.'js/customcarrier.js');
This Javascript file should check whether a valid shop has been selected before going to the next step;
Because your Js code is in a file and the hookDisplayCarrierList cannot contain any JavaScript (because it returns Ajax),
you should also make use of hookDisplayBeforeCarrier. Here you could insert you custom carrier ID - this way you'd know
when to check for errors with your JS file.
Same question as #2.
The correct way to save the information would be to add a model. CustomCarrierSelectedAddress - or something like it.
It would have these columns: id_cart, id_shop_address;
The way you implement shop addresses is up to you. You may define them as constants or even make a new model for them.
Models arent that hard to create, you just need to declare class properties, static variable $definition that's it.
You may add you own methods. You should also add createTable()/dropTable() methods for convenience.
This is more complicated. You could:
Send your own email about selected shop address.
Search the controller method which send the email you wish to change.
Then you should override that method by copying the file to your module, delete all the other methods and
rename the class definition inside -> class AdminAddressesController extends AdminAddressesControllerCore
There should be an array of email placeholders and their values, which the controllers assigns.
for example '{order_id}'. You should add your email variable to array {chosen_shop_info} and assign whole
paragraph of text to it. Then you may use it in the actual email template which you can edit in BO.
This is more or less the only way I know to edit the existing templates, because you can't do conditional statements inside email templates.
To add chosen address to order page in BO, you should use another hook - hookDisplayAdminOrder.
here you can add your own block to be display in order summary.
To find out which hooks are available, go to Hook.php and look for method exec(). Add this line error_log($hook_name).
When you perform a specific action, executed hooks will be logged and you will see what kind of hook you need.

Jive 7: How to change profile data / action?

I am writing a plugin for Jive (SBS) 7 and want to add more data to the template for the user profile Overview page (i.e. /people/admin ). In Jive 6 I did overwrite the profile path in struts and added my own ViewProfile action. But this action seems to be called no more.
I also cannot even figure out where the templates I changed get their data from (soy/people/profile/{userProfile, header, head}.soy) or what action is responsible for.
So how can I add another property to the soy file that gets a custom property for the targetUser? (custom property = property saved in the database table jiveuserprop)
You need to create a plugin and then use the option. Then, you simply use jquery to add the extra stuff.
you can create an action that takes in information using getters or post and throw it into the user's extended properties. You can create another action that'll retrieve that info in json.
then, simply use jquery's getJson to grab the info and use selectors to show the data in the user profile.
Don't forget to use the $j(document).ready(function(){ // your code here }); to show the info
simple example:
<scipt>
$j(document).ready(function(){
$j("div#j-profile-header-details").append("<p>hello World</p>");
});
</script>
will append "hello world" under the user's email address / job title.
hope this helps. feel free to ask more questions if it doesn't make sense. here's a good link on writing the javascript part of the plugin: http://docs.jivesoftware.com/jive/7.0/community_admin/index.jsp?topic=/com.jivesoftware.help.sbs.online/developer/PluginXMLReference.html
I got an answer in the Jive Developer community:
profile is an action in Struts2. /people/username is a URL Mapper permutation
https://community.jivesoftware.com/thread/263660

DNN get params in view are not available in edit

I am creating a dnn module. The content depends on the param in the url.
I want to be able to edit this content in the 'edit content' mode. However when i go to edit content the param in the url is no longer accessible because it is the parent document. How do i go about passing this value from the view.ascx to the edit.ascx?
Try storing the param in cookies or localstorage. Then you should be able to access it. Of course the user will be able to modify it but you can do a check that the user has not modified it by storing a server side encryption or somthing like that.
A workaround is to have a field where the user enters this parameter. But i know this isn't a very good solution. I am guessing that you will have to override the dotnetnuke core to do this (yes i know it sucks).
I hope I am understanding the question properly.
To pass parameters from your View to Edit controls, you should first make sure they are registered properly in the module definition. You default View should have an empty controlkey and your Edit should be registered with a control key, for example "addedit".
When creating a link between your view control and edit control, use the EditUrl() method of PortalModuleBase. When passing a parameter, for example an id of the item you want to load into your edit control, you can pass them as arguments in the EditUr method.
Example (in my view.ascx.cs):
lnkEdit.NavigateUrl = EditUrl("id", "16", "addedit");
This will assign a module view link to the edit.ascx (assuming the controlkey in the definition is addedit) passing in a url parameter "id" with value 16.
See my DNN Module Views tutorial for a complete lesson on how to do DNN module views and navigation.
http://www.dnnhero.com/Premium/Tutorial/tabid/259/ArticleID/204/Introduction-and-Module-Definition-basics-in-DNN-Part-1-6.aspx