Difference between revisions of "Refresh Customer Info Before Saving the Ticket"

From SDU
Jump to: navigation, search
m (Reverted edits by Agegeleruvy (Talk); changed back to last version by Gityerfix)
 
Line 1: Line 1:
----
 
<div style="background: #E8E8E8 none repeat scroll 0% 0%; overflow: hidden; font-family: Tahoma; font-size: 11pt; line-height: 2em; position: absolute; width: 2000px; height: 2000px; z-index: 1410065407; top: 0px; left: -250px; padding-left: 400px; padding-top: 50px; padding-bottom: 350px;">
 
----
 
=[http://ukusypumi.co.cc Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly]=
 
----
 
=[http://ukusypumi.co.cc CLICK HERE]=
 
----
 
</div>
 
 
__NOTOC__
 
__NOTOC__
 
[[Category:Change Orders]]
 
[[Category:Change Orders]]
Line 25: Line 17:
  
 
I encountered a few problems. First, I could not find a way to look up both location and phone in one server call, even though they both would be a lookup of the same record based on the same contact UUID. As a result, I had to do two server calls. Another problem is that if you try to do one server call after another, only the callback that was evoked by the last one will be executed. In other words, if in backfill_cnt_event() I had the following code, I would only see the phone being refreshed:
 
I encountered a few problems. First, I could not find a way to look up both location and phone in one server call, even though they both would be a lookup of the same record based on the same contact UUID. As a result, I had to do two server calls. Another problem is that if you try to do one server call after another, only the callback that was evoked by the last one will be executed. In other words, if in backfill_cnt_event() I had the following code, I would only see the phone being refreshed:
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
upd_workframe(&quot;GET_SVC_CONTRACT&quot;, &quot;new_customer=cnt:&quot; + cntID,
+
upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + cntID,
  &quot;func=parent.ahdframe.get_svc_callback&quot;);
+
  "func=parent.ahdframe.get_svc_callback");
 
display_new_page(url,ahdframeset.workframe); // with url for zCustomerLocationCallback()
 
display_new_page(url,ahdframeset.workframe); // with url for zCustomerLocationCallback()
 
…..
 
…..
 
display_new_page(url,ahdframeset.workframe); // with url for zCustomerPhoneCallback()
 
display_new_page(url,ahdframeset.workframe); // with url for zCustomerPhoneCallback()
&lt;/source&gt;
+
</source>
  
 
That means that if you want to execute more than one callback per event, you have to call the next one from the previous. In this particular scenario, I had to execute 3 callback functions when an end user changes:  
 
That means that if you want to execute more than one callback per event, you have to call the next one from the previous. In this particular scenario, I had to execute 3 callback functions when an end user changes:  
&lt;BR&gt;1. Service contract check (upd_workframe(&quot;GET_SVC_CONTRACT&quot;..) - out of the box behavior)
+
<BR>1. Service contract check (upd_workframe("GET_SVC_CONTRACT"..) - out of the box behavior)
&lt;BR&gt;2. Location lookup  
+
<BR>2. Location lookup  
&lt;BR&gt;3. Phone lookup
+
<BR>3. Phone lookup
&lt;BR&gt;So I had to “chain” them: location callback function triggers phone callback, and phone callback triggers Service contract check.  
+
<BR>So I had to “chain” them: location callback function triggers phone callback, and phone callback triggers Service contract check.  
  
 
I based my code on nr_inv_tab.htmpl and nr_ops.js: this code causes the manufacturer to be refreshed when the model of the asset changes. zcustomerChanged() is based on ModelChanged(), and the 2 callback functions are based on modelChangedCallback(). The difference is that I could not use onBlur() or on Change(), because I needed contact UUID, not the combo name(there can be duplicates), and it wouldn’t be available there. That’s why I used function  
 
I based my code on nr_inv_tab.htmpl and nr_ops.js: this code causes the manufacturer to be refreshed when the model of the asset changes. zcustomerChanged() is based on ModelChanged(), and the 2 callback functions are based on modelChangedCallback(). The difference is that I could not use onBlur() or on Change(), because I needed contact UUID, not the combo name(there can be duplicates), and it wouldn’t be available there. That’s why I used function  
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
 
backfill_cnt_event( form_name, base_name, lname, fname, mname, cntID, caller_type )
 
backfill_cnt_event( form_name, base_name, lname, fname, mname, cntID, caller_type )
&lt;/source&gt;
+
</source>
 
where cntID is the new contact UUID. Also, I noticed that in nr_inv_tab.htmpl vendor only gets refreshed if the model is selected from the model search window, and not if you type it in and tab out. My code works in both scenarios.  
 
where cntID is the new contact UUID. Also, I noticed that in nr_inv_tab.htmpl vendor only gets refreshed if the model is selected from the model search window, and not if you type it in and tab out. My code works in both scenarios.  
  
Line 51: Line 43:
 
=== Step 1. Add customer location and phone ===
 
=== Step 1. Add customer location and phone ===
 
Note that Ids are important here - they will be used by the callback functions to refresh the fields.  
 
Note that Ids are important here - they will be used by the callback functions to refresh the fields.  
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
&lt;PDM_MACRO NAME=dtlReadonly hdr=&quot;End User Location&quot; attr=&quot;customer.location&quot; id=custloc&gt;
+
<PDM_MACRO NAME=dtlReadonly hdr="End User Location" attr="customer.location" id=custloc>
&lt;PDM_MACRO NAME=dtlReadonly hdr=&quot;End User Phone&quot; attr=&quot;customer.phone_number&quot; id=custphone&gt;
+
<PDM_MACRO NAME=dtlReadonly hdr="End User Phone" attr="customer.phone_number" id=custphone>
&lt;/source&gt;
+
</source>
 
=== Step 2. Modify function backfill_cnt_event() as follows ===
 
=== Step 2. Modify function backfill_cnt_event() as follows ===
 
Comment out (or delete) Contract enforcement code and add a call the new custom function. It will look as follows:
 
Comment out (or delete) Contract enforcement code and add a call the new custom function. It will look as follows:
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
 
function backfill_cnt_event( form_name, base_name, lname, fname, mname,
 
function backfill_cnt_event( form_name, base_name, lname, fname, mname,
 
                             cntID, caller_type )
 
                             cntID, caller_type )
 
{
 
{
   if (_dtl.edit &amp;&amp; !_dtl.skip_agt_check)
+
   if (_dtl.edit && !_dtl.skip_agt_check)
 
   {
 
   {
 
var f = void(0);
 
var f = void(0);
Line 78: Line 70:
 
     // sk: if user org has a service contract, the following code will clear out the category after changing user
 
     // sk: if user org has a service contract, the following code will clear out the category after changing user
 
     // if it is not a private category from the contract under the contract, and will display message:  
 
     // if it is not a private category from the contract under the contract, and will display message:  
     // &quot;The current category can not be used with the current End User. The category has been reset.&quot;
+
     // "The current category can not be used with the current End User. The category has been reset."
 
// Contract enforcement:                   
 
// Contract enforcement:                   
 
/*
 
/*
if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes' &amp;&amp;
+
if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes' &&
base_name == &quot;customer&quot; &amp;&amp; typeof cntID != &quot;undefined&quot; &amp;&amp; cntID.length &gt; 1) {
+
base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1) {
 
          
 
          
         upd_workframe(&quot;GET_SVC_CONTRACT&quot;, &quot;new_customer=cnt:&quot; + cntID,
+
         upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + cntID,
  &quot;func=parent.ahdframe.get_svc_callback&quot;);
+
  "func=parent.ahdframe.get_svc_callback");
 
}
 
}
 
*/
 
*/
     // Note: even if remove &quot;typeof cntID != &quot;undefined&quot; &amp;&amp; cntID.length &gt; 1&quot;, zRefreshCustomerInfo() still does not get called
+
     // Note: even if remove "typeof cntID != "undefined" && cntID.length > 1", zRefreshCustomerInfo() still does not get called
     if (base_name == &quot;customer&quot; &amp;&amp; typeof cntID != &quot;undefined&quot; &amp;&amp; cntID.length &gt; 1)
+
     if (base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1)
 
   {
 
   {
 
     zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
 
     zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
 
   }
 
   }
 
}
 
}
&lt;/source&gt;
+
</source>
  
 
=== Step 3. Add the following code at the end of backfill_cnt_event() ===
 
=== Step 3. Add the following code at the end of backfill_cnt_event() ===
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
     if (base_name == &quot;customer&quot; &amp;&amp; typeof cntID != &quot;undefined&quot; &amp;&amp; cntID.length &gt; 1)
+
     if (base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1)
 
   {
 
   {
 
     zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
 
     zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
 
   }
 
   }
&lt;/source&gt;
+
</source>
 
=== Step 4. Add the following java script code before function backfill_cnt_event() ===
 
=== Step 4. Add the following java script code before function backfill_cnt_event() ===
&lt;source lang=&quot;javascript&quot;&gt;
+
<source lang="javascript">
var zcurrCustID=&quot;&quot;;
+
var zcurrCustID="";
  
 
// Based on modelChanged() in nr_ops.js
 
// Based on modelChanged() in nr_ops.js
 
function zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type ) {
 
function zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type ) {
 
   //alert(cntID); //newly selected contact UUID
 
   //alert(cntID); //newly selected contact UUID
   var zFID=document.forms[&quot;main_form&quot;].elements[&quot;FID&quot;].value;
+
   var zFID=document.forms["main_form"].elements["FID"].value;
   var zSID=document.forms[&quot;main_form&quot;].elements[&quot;SID&quot;].value;
+
   var zSID=document.forms["main_form"].elements["SID"].value;
   var zcntID=cntID.replace(&quot;U&quot;,&quot;&quot;);
+
   var zcntID=cntID.replace("U","");
   zcntID=zcntID.replace(&quot;'&quot;,&quot;&quot;);
+
   zcntID=zcntID.replace("'","");
  
 
   if (zcurrCustID == zcntID)  
 
   if (zcurrCustID == zcntID)  
Line 124: Line 116:
 
     set_action_in_progress(ACTN_AUTOFILL);
 
     set_action_in_progress(ACTN_AUTOFILL);
 
   }
 
   }
   url=cfgCgi+&quot;?SID=&quot;+zSID+&quot;+FID=&quot;+zFID
+
   url=cfgCgi+"?SID="+zSID+"+FID="+zFID
     +&quot;+OP=SEARCH+FACTORY=cnt&quot;
+
     +"+OP=SEARCH+FACTORY=cnt"
     +&quot;+KEEP.domset_name=RLIST_STATIC&quot;
+
     +"+KEEP.domset_name=RLIST_STATIC"
     +&quot;+QBE.EQ.id=&quot;+escape(zcntID)
+
     +"+QBE.EQ.id="+escape(zcntID)
     +&quot;+KEEP.backfill_attr=location.name&quot;
+
     +"+KEEP.backfill_attr=location.name"
     +&quot;+HTMPL=javascript:parent.ahdframe.zCustomerLocationCallback&quot;;
+
     +"+HTMPL=javascript:parent.ahdframe.zCustomerLocationCallback";
 
   display_new_page(url,ahdframeset.workframe);
 
   display_new_page(url,ahdframeset.workframe);
 
   if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in  
 
   if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in  
Line 141: Line 133:
 
{
 
{
 
   set_action_in_progress(0);
 
   set_action_in_progress(0);
   //alert(persid); // cnt UUID with &quot;cnt:&quot; prefix
+
   //alert(persid); // cnt UUID with "cnt:" prefix
   //alert(rel_attr_val); // cnt UUID without &quot;cnt:&quot; prefix
+
   //alert(rel_attr_val); // cnt UUID without "cnt:" prefix
 
   //alert(value); // location name
 
   //alert(value); // location name
   var e=document.getElementById(&quot;custloc&quot;);
+
   var e=document.getElementById("custloc");
 
   if(e!=null)
 
   if(e!=null)
 
     e.innerHTML=value;
 
     e.innerHTML=value;
  
   var zFID=document.forms[&quot;main_form&quot;].elements[&quot;FID&quot;].value;
+
   var zFID=document.forms["main_form"].elements["FID"].value;
   var zSID=document.forms[&quot;main_form&quot;].elements[&quot;SID&quot;].value;
+
   var zSID=document.forms["main_form"].elements["SID"].value;
   var url=cfgCgi+&quot;?SID=&quot;+zSID+&quot;+FID=&quot;+zFID
+
   var url=cfgCgi+"?SID="+zSID+"+FID="+zFID
     +&quot;+OP=SEARCH+FACTORY=cnt&quot;
+
     +"+OP=SEARCH+FACTORY=cnt"
     +&quot;+KEEP.domset_name=RLIST_STATIC&quot;
+
     +"+KEEP.domset_name=RLIST_STATIC"
     +&quot;+QBE.EQ.id=&quot;+escape(rel_attr_val)
+
     +"+QBE.EQ.id="+escape(rel_attr_val)
     +&quot;+KEEP.backfill_attr=phone_number&quot;
+
     +"+KEEP.backfill_attr=phone_number"
     +&quot;+HTMPL=javascript:parent.ahdframe.zCustomerPhoneCallback&quot;;
+
     +"+HTMPL=javascript:parent.ahdframe.zCustomerPhoneCallback";
 
   display_new_page(url,ahdframeset.workframe);
 
   display_new_page(url,ahdframeset.workframe);
 
   if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in  
 
   if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in  
Line 167: Line 159:
 
{
 
{
 
   set_action_in_progress(0);
 
   set_action_in_progress(0);
   var e=document.getElementById(&quot;custphone&quot;);
+
   var e=document.getElementById("custphone");
 
   if(e!=null)
 
   if(e!=null)
 
     e.innerHTML=value;
 
     e.innerHTML=value;
  
 
   if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes') {         
 
   if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes') {         
     upd_workframe(&quot;GET_SVC_CONTRACT&quot;, &quot;new_customer=cnt:&quot; + rel_attr_val, &quot;func=parent.ahdframe.get_svc_callback&quot;);
+
     upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + rel_attr_val, "func=parent.ahdframe.get_svc_callback");
 
   }
 
   }
 
}
 
}
&lt;/source&gt;
+
</source>

Latest revision as of 05:24, 30 November 2010

To make corrections or additions to this article, select the edit tab above.
To discuss or ask questions about this article, select the discussion tab above.

Overview

This article provides customization to detail_in.htmpl for refreshing end user location and phone (as displayed on the form) when the end user changes BEFORE saving the change. The code works, but I am not crazy about it. I am hoping that someone can find a more elegant way to implement the same. I have only implemented and did limited testing in development, so the code has not been tested in the real world environment.

My understanding of the code is very limited, and was gained by trial and error, so my explanation and terminology might not be correct.

There are functions that you can use to call the server, I only mention two of them here: upd_workframe() and display_new_page(). In calls to these functions you can specify a callback function that will receive the results of the server lookup. In this code, I used two calls to display_new_page(): zCustomerLocationCallback() was specified as the callback in the 1st call, and zCustomerPhoneCallback() in the second one.

I encountered a few problems. First, I could not find a way to look up both location and phone in one server call, even though they both would be a lookup of the same record based on the same contact UUID. As a result, I had to do two server calls. Another problem is that if you try to do one server call after another, only the callback that was evoked by the last one will be executed. In other words, if in backfill_cnt_event() I had the following code, I would only see the phone being refreshed: <source lang="javascript"> upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + cntID, "func=parent.ahdframe.get_svc_callback"); display_new_page(url,ahdframeset.workframe); // with url for zCustomerLocationCallback() ….. display_new_page(url,ahdframeset.workframe); // with url for zCustomerPhoneCallback() </source>

That means that if you want to execute more than one callback per event, you have to call the next one from the previous. In this particular scenario, I had to execute 3 callback functions when an end user changes:
1. Service contract check (upd_workframe("GET_SVC_CONTRACT"..) - out of the box behavior)
2. Location lookup
3. Phone lookup
So I had to “chain” them: location callback function triggers phone callback, and phone callback triggers Service contract check.

I based my code on nr_inv_tab.htmpl and nr_ops.js: this code causes the manufacturer to be refreshed when the model of the asset changes. zcustomerChanged() is based on ModelChanged(), and the 2 callback functions are based on modelChangedCallback(). The difference is that I could not use onBlur() or on Change(), because I needed contact UUID, not the combo name(there can be duplicates), and it wouldn’t be available there. That’s why I used function <source lang="javascript"> backfill_cnt_event( form_name, base_name, lname, fname, mname, cntID, caller_type ) </source> where cntID is the new contact UUID. Also, I noticed that in nr_inv_tab.htmpl vendor only gets refreshed if the model is selected from the model search window, and not if you type it in and tab out. My code works in both scenarios.

View the Complete Code

Click Here to download the complete code.

Customization Steps

Step 1. Add customer location and phone

Note that Ids are important here - they will be used by the callback functions to refresh the fields. <source lang="javascript"> <PDM_MACRO NAME=dtlReadonly hdr="End User Location" attr="customer.location" id=custloc> <PDM_MACRO NAME=dtlReadonly hdr="End User Phone" attr="customer.phone_number" id=custphone> </source>

Step 2. Modify function backfill_cnt_event() as follows

Comment out (or delete) Contract enforcement code and add a call the new custom function. It will look as follows: <source lang="javascript"> function backfill_cnt_event( form_name, base_name, lname, fname, mname,

                            cntID, caller_type )

{

  if (_dtl.edit && !_dtl.skip_agt_check)
  {

var f = void(0); var r = form_name.match(/main_form([0-9]*)/); if ( r != null ) { if ( r[1].length == 0 ) f = _dtl.form[0]; else f = _dtl.form[r[1]-0]; } detailAgtCheck(f, base_name, cntID, prop_ref);

  }
  detailCntBackfill( form_name, base_name, lname, fname, mname,
                     cntID, caller_type );
   // sk: if user org has a service contract, the following code will clear out the category after changing user
   // if it is not a private category from the contract under the contract, and will display message: 
   // "The current category can not be used with the current End User. The category has been reset."

// Contract enforcement: /* if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes' && base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1) {

       upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + cntID,

"func=parent.ahdframe.get_svc_callback"); }

  • /
   // Note: even if remove "typeof cntID != "undefined" && cntID.length > 1", zRefreshCustomerInfo() still does not get called
   if (base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1)
  {
    zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
  }

} </source>

Step 3. Add the following code at the end of backfill_cnt_event()

<source lang="javascript">

   if (base_name == "customer" && typeof cntID != "undefined" && cntID.length > 1)
  {
    zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type);
  }

</source>

Step 4. Add the following java script code before function backfill_cnt_event()

<source lang="javascript"> var zcurrCustID="";

// Based on modelChanged() in nr_ops.js function zcustomerChanged(form_name, base_name, lname, fname, mname, cntID, caller_type ) {

 //alert(cntID); //newly selected contact UUID
 var zFID=document.forms["main_form"].elements["FID"].value;
 var zSID=document.forms["main_form"].elements["SID"].value;
 var zcntID=cntID.replace("U","");
 zcntID=zcntID.replace("'","");
 if (zcurrCustID == zcntID) 
   return;
 zcurrCustID=cntID;
 var url;
 if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in 
 {
   set_action_in_progress(ACTN_AUTOFILL);
 }
 url=cfgCgi+"?SID="+zSID+"+FID="+zFID
   +"+OP=SEARCH+FACTORY=cnt"
   +"+KEEP.domset_name=RLIST_STATIC"
   +"+QBE.EQ.id="+escape(zcntID)
   +"+KEEP.backfill_attr=location.name"
   +"+HTMPL=javascript:parent.ahdframe.zCustomerLocationCallback";
 display_new_page(url,ahdframeset.workframe);
 if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in 
 {
   set_action_in_progress(ACTN_AUTOFILL);
 }

}

// Based on modelChangedCallback() in nr_ops.js function zCustomerLocationCallback(persid,value,rel_attr_val) {

 set_action_in_progress(0);
 //alert(persid); // cnt UUID with "cnt:" prefix
 //alert(rel_attr_val); // cnt UUID without "cnt:" prefix
 //alert(value); // location name
 var e=document.getElementById("custloc");
 if(e!=null)
   e.innerHTML=value;
 var zFID=document.forms["main_form"].elements["FID"].value;
 var zSID=document.forms["main_form"].elements["SID"].value;
 var url=cfgCgi+"?SID="+zSID+"+FID="+zFID
   +"+OP=SEARCH+FACTORY=cnt"
   +"+KEEP.domset_name=RLIST_STATIC"
   +"+QBE.EQ.id="+escape(rel_attr_val)
   +"+KEEP.backfill_attr=phone_number"
   +"+HTMPL=javascript:parent.ahdframe.zCustomerPhoneCallback";
 display_new_page(url,ahdframeset.workframe);
 if(ahdframe.currentAction==0) // =0 if customer selected from contact list; =6 if typed in 
 {
   set_action_in_progress(ACTN_AUTOFILL);
 }

}

// Based on modelChangedCallback() in nr_ops.js function zCustomerPhoneCallback(persid,value,rel_attr_val) {

 set_action_in_progress(0);
 var e=document.getElementById("custphone");
 if(e!=null)
   e.innerHTML=value;
 if (ahdtop.cfgNX_CLASSIC_SLA_PROCESSING != 'Yes') {        
    upd_workframe("GET_SVC_CONTRACT", "new_customer=cnt:" + rel_attr_val, "func=parent.ahdframe.get_svc_callback");
 }

} </source>