How to update fields before the view is displayed in Odoo - 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.

Related

Model binding fails from form on Razor Page using Tag Helpers

I have a model "behind" my page with a property that's a model of my search form. My form was working fine and then suddenly all the properties stopped binding and my Post action handler saw the search form model has having loads of nulls.
When you use Tag Helpers for a form and add input controls you can add your own name="myProperty" to each, or you can omit this and this attribute is auto-generated.
Imagine you have 10 inputs and you add a new one but forget to add a name attribute on this recent one, then the helper adds its own like "SearchForm.MyProperty".
The previous 10 end up with name="myProperty" but the last one is name="SearchForm.MyProperty".
In this situation model binding fails, presumably because these paths are mixed and the one matching SearchForm.MyProperty is more specific, making the others look like they should bind to properties on the page model.
Presumably when your supply your own names and they are all lacking the SearchForm. prefix then its smart enough to figure out to bind them all to SearchForm.
Fix could be not to supply your own name attributes to the inputs at all.
An improvement to Razor binding (to remove the surprise here) might be to always fail unless the names are prefixed accurately, though this would break existing code.

Xpages Scoped variable lost opening next page

I'm transitioning a corporate web page into a new xpage platform. It consists of a number of department-specific databases each with their separate ACL's with the old forms and docs, and one new xpage db front end presenting data from across the other db's read only. The content is regulations and resources for the rest of the organization to relate to.
The design consists of just a few custom controls which collects data sources dynamically via properties on the various department specific xpages. So like 30 xpages collecting data from separate db's utilizing the same handful of cc's
My scoped variable issue is related to my cc_dataViewLocal . This dataView presents the documents from the corresponding views in the source db's. To let the user know their present location in the application I pull in the name of the current view and display the name above the Data View as a headline on the DataView xpage:
<xp:text escape="true" id="computedField1" styleClass="ksHeading2">
<xp:this.value><![CDATA[#{javascript:getComponent("dataView1").getData ().getView()
}]]></xp:this.value>
</xp:text>
All documents from all databases are presented using the same documentDisplay xpage with a dynamic document data source. Thus this xpage does not have any properties but is referenced trough the data view xpage:
<xe:dataView id="dataView1" collapsibleCategory="false"
rows="50" style="font-size:8pt" rowStyle="font-size:8pt"
collapsibleDetail="true" pageName="/**ks_documentDisplay.xsp**"
var="rowHandle">
--
When I open a document from the data view in documentDisplay.xsp I want the same headline/name of the original view displayed there as well. To make that happen I try to catch the view name in a scoped variable in an afterPageLoad event in the data view xpage, to redisplay it on the documentDisplay xpage.
<xp:this.afterPageLoad>
<xp:setValue binding="#{sessionScope.ksView}">
<xp:this.value><![CDATA[#{javascript:getComponent
("computedField1").value}]] ></xp:this.value>
</xp:setValue>
</xp:this.afterPageLoad>
After all the view name is not part of the document data source, and I have no other handle to the parent view at this point as I can see.
--
When I display the scoped variable on the dataView xpage in a computed field it works fine:
<xp:text escape="true" id="computedField2"
styleClass="ksHeading1" value="#{sessionScope.ksView}">
However, when I try to display the same session variable in the documentDispay xpage using the same computed field coding it turns up empty. Like the sessionVariable is lost to the next xpage?
I started out with a viewScope, and tried both request and session with same results. What am I missing??
Any input greatly appreciated! Including workarounds but would like to get a grip on the scoped variables...:-)
Regards to all who read this somewhat long post and thanks in advance!
Vidar Solevag
Thanks again for pointing me in the right direction. The problem clearly was I wiped the sessionScope in some way or other, exactly how I still don't know.
But as often is the case the solution was to do something else to get the same thing done...
What I found not to work:
-Moving the event to onClientLoad didn't work it threw an exception "cannot handle". In addition my original approach afterPageLoad did't really work either as it didn't update properly as other dataViews were chosen via Navigator on the page. Also setting the variable via the "Set" option on the simpleAction list turned out to be a problem. I got several "Not allowed to set the value of a read only computed expression"
What I did that worked:
-I set the value not by "Set"Simple action but by "Excecute script" and code
sessionScope.ksView=context.getSubmittedValue(). This in the onClick event in Navigator that selects which Dataview to display On the DataView xpage Then the SessionScope remains alive all the way into the documentDisplay xpage and until a different Dataview is selected back in the Nav back on the DataView xpage.
Now using the same sessionScope as the viewName property on the xpage I also set the sessionScope initially on afterPageLoad to have a default value when page is first opened...
So thanks again, a lot of headbanging into the wall here but that's what you learn from I guess :-))

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.

JQGrid: Binding JSON data to MultiSelect Checkbox

I have JQGrid loading data from WCF OperationContract with paging and sorting working fine. I am using "multiselect: true" so that I get the checkbox column and ability to select multiple rows. I've implemented gridComplete:, onSelectAll: and onSelectRow: to capture when checkboxes are checked/unchecked and to maintain checked state upon pagination. I am able to save the checkbox state to the DB via another WCF method call.
What I cannot figure out how to do is load the saved checkbox state for each row along with the other fields specified in colModel:.
Any ideas? I realize I can make a separate WCF service call to get the values, loop through them and set state manually, but that seems like a huge waste and overly clunky.
Thanks in advance.
The simplest way, which I imagine me immediately after reading of your question, is to have additional hidden column (hidden: true property in the colModel for the column) and the checkboxes inside. You can load the selection state from the database an fill the hidden checkboxes. Inside of loadComplete or gridComplete you can use the information to select the rows.
If you would use loadComplete instead of gridComplete you can even eliminate the need to hold hidden row. The callback method loadComplete has data parameter which are initialized with the data originated from the ajax call. So if your server response contain more information as jqGrid need the data will be ignored by jqGrid, but you can see the data in the loadComplete and use the information to set row selection.

How to query the data from content type without using content query webpart in SharePoint2010.How can i?

I want to query the data from content type without using content query webpart. How could I do this?
My scenario is, I have a page layout, from the page layout I have created a page that contains some site columns values. After clicking on the save button I need to update the field in the page library column. How can I query the data in item updating event of the Site Pages Library.
Any help would be appreciated.
The ItemUpdating event method is passed an SPItemEventProperties parameter named property. This object contains information about the item responsible for firing the event handler. You can access this by calling properties.ListItem[Fieldname] or properties.AfterProperties[fieldname].
Something to note. The value of the SPItemEventProperties.BeforeProperties and SPItemEventProperties.AfterProperties as well as the properties of the SPItemEventProperties.ListItem, varies depending on the Event you are overriding and the type of SP List (List or Document Library). This chart shows these relationships.