<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Me.Thoughts.ToString()</title>
	<atom:link href="http://kikosantos.net/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://kikosantos.net/tech</link>
	<description>NetSuite SuiteScript .Net Tech</description>
	<lastBuildDate>Fri, 01 Apr 2011 12:59:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Close Popup Window and Refresh Opener</title>
		<link>http://kikosantos.net/tech/2010/11/close-popup-window-and-refresh-opener/</link>
		<comments>http://kikosantos.net/tech/2010/11/close-popup-window-and-refresh-opener/#comments</comments>
		<pubDate>Sat, 20 Nov 2010 01:55:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>
		<category><![CDATA[close]]></category>
		<category><![CDATA[popup]]></category>
		<category><![CDATA[refresh]]></category>
		<category><![CDATA[suitelet]]></category>

		<guid isPermaLink="false">http://kikosantos.net/tech/?p=143</guid>
		<description><![CDATA[Here&#8217;s the scenario, you created a custom button in one of your page (say, Customer) and when clicked you want a popup window to open another page (say, Task). Sounds Easy Right? Your code in creating the button might be similar to this: var url = nlapiResolveURL(&#34;RECORD&#34;, &#34;task&#34;, null, false); var script = &#34;win = [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the scenario, you created a custom button in one of your page (say, Customer) and when clicked you want a popup window to open another page (say, Task). Sounds Easy Right? Your code in creating the button might be similar to this:</p>
<pre class="brush: jscript; title: ;">
var url = nlapiResolveURL(&quot;RECORD&quot;, &quot;task&quot;, null, false);
var script = &quot;win = window.open('&quot; + url + &quot;', 'win', 'resizable=0,scrollbars=0,width=950,height=700');&quot;;
form.addButton(&quot;custpage_newtask&quot;, &quot;New Task&quot;, script);
</pre>
<p>When you click the button, a popup window will open. The Create New Task page will be loaded in the newly opened window. All seems to be working fine until you click the Save button. The task will be saved but after the postback, the customer record will be loaded INSIDE the same popup window.</p>
<p>How to fix this? Calling a window.close() inside the saveRecord function of the Task&#8217;s client-side SuiteScript will do no good since saveRecord will trigger before the actual saving process. One possible workaround would be to add an afterSubmit function in our server-side SuiteScript that will redirect the page to a Suitelet. The suitelet will be a blank/white page when viewed but it will trigger the refresh of the opener and the closing of the popup window. Let me explain this via code:</p>
<p>The afterSubmit function of the Task can be like this:</p>
<pre class="brush: jscript; title: ;">
function afterSubmit(type)
{
    if (type == &quot;create&quot;)
    {
        var params = new Array();
        params[&quot;custpage_customerid&quot;] = 12345;
        nlapiSetRedirectURL(&quot;SUITELET&quot;, &quot;customscript_blankredirect&quot;, &quot;customdeploy_blankredirect&quot;, null, params);
    }
}
</pre>
<p>And the suitelet code can look like this:</p>
<pre class="brush: jscript; title: ;">
function main(request,response)
{
    var customerid = request.getParameter(&quot;custpage_customerid&quot;);

    var html = &quot;&quot;;
    html +=&quot; &amp;lt;html&amp;gt;&quot;;
    html +=&quot; &amp;lt;head&amp;gt;&quot;;
    html +=&quot; &amp;lt;script&amp;gt;&quot;;
    html +=&quot; window.opener.location='&quot; + nlapiResolveURL(&quot;RECORD&quot;,&quot;customer&quot;, customerid, null) + &quot;';&quot;;
    html +=&quot; window.close();&quot;;
    html +=&quot; &amp;lt;/script&amp;gt;&quot;;
    html +=&quot; &amp;lt;/head&amp;gt;&quot;;
    html +=&quot; &amp;lt;/html&amp;gt;&quot;;

    response.write(html);
}
</pre>
<p>There you go! Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2010/11/close-popup-window-and-refresh-opener/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I Do Not Trust a NetSuite Date</title>
		<link>http://kikosantos.net/tech/2010/10/why-i-do-not-trust-a-netsuite-date/</link>
		<comments>http://kikosantos.net/tech/2010/10/why-i-do-not-trust-a-netsuite-date/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 07:35:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[getfieldvalue]]></category>
		<category><![CDATA[nlapistringtodate]]></category>

		<guid isPermaLink="false">http://kikosantos.net/tech/?p=137</guid>
		<description><![CDATA[I learned this the hard way. Consider the following code: var so = nlapiLoadRecord(&#34;salesorder&#34;, &#34;3479274&#34;); var tranDate = so.getFieldValue(&#34;trandate&#34;); var adjustedDate = nlapiAddMonths(tranDate, 2); At first look all seems fine but the above code will throw this error as it passes through the third line: UNEXPECTED_ERROR TypeError: Cannot find function getTime. I didn’t call any [...]]]></description>
			<content:encoded><![CDATA[<p>I learned this the hard way. Consider the following code:</p>
<pre class="brush: jscript; title: ;">
var so = nlapiLoadRecord(&quot;salesorder&quot;, &quot;3479274&quot;);
var tranDate = so.getFieldValue(&quot;trandate&quot;);
var adjustedDate = nlapiAddMonths(tranDate, 2);
</pre>
<p>At first look all seems fine but the above code will throw this error as it passes through the third line:</p>
<p>UNEXPECTED_ERROR TypeError: Cannot find function getTime.</p>
<p>I didn’t call any getTime function. How come I’m having this error?</p>
<p>Debugging my code reveals that the .getFieldValue(&#8220;trandate&#8221;) part returns the date as string. It also follows the date formatting defined in the user preference. If the trandate of the SO is 12/15/2009 and your date formatting is set to DD-MONTH-YYYY, the resulting value would be “15-DECEMBER-2009”. Having said that now it’s obvious that doing nlapiAddMonths(“15-DECEMBER-2009”, 2) will definitely throw an error because the first parameter is not a valid date value.</p>
<p style="text-align: center;"><a title="date-formatting by unDevel0ped, on Flickr" href="http://www.flickr.com/photos/senselessfeats/5116601575/"><img class="aligncenter" src="http://farm5.static.flickr.com/4124/5116601575_27c1758d0d.jpg" alt="date-formatting" width="391" height="190" /></a></p>
<p>Luckily, NetSuite API has a nlapiStringToDate() method to solve this dilemma. Adding the method in our code solves our problem:</p>
<pre class="brush: jscript; title: ;">
var so = nlapiLoadRecord(&quot;salesorder&quot;, &quot;3479274&quot;);
var tranDate = nlapiStringToDate(so.getFieldValue(&quot;trandate&quot;));
var adjustedDate = nlapiAddMonths(tranDate, 2);
</pre>
<p>On a similar note, getting the value of a date field in a nlobjSearchResult object will also give the date as string following the format defined in the user preference.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2010/10/why-i-do-not-trust-a-netsuite-date/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>recalc: Inserting New Item Line Dynamically</title>
		<link>http://kikosantos.net/tech/2010/10/recalc-inserting-new-item-line-dynamically/</link>
		<comments>http://kikosantos.net/tech/2010/10/recalc-inserting-new-item-line-dynamically/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 09:21:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>
		<category><![CDATA[recalc]]></category>

		<guid isPermaLink="false">http://kikosantos.net/tech/?p=133</guid>
		<description><![CDATA[We can easily achieve this if the line will be added upon page load or if a button in the form is clicked. But the requirement is to add a new Item line after inserting another Item. How can we do this? This can be achieved via the client event function called recalc. According to [...]]]></description>
			<content:encoded><![CDATA[<p>We can easily achieve this if the line will be added upon page load or if a button in the form is clicked. But the requirement is to add a new Item line after inserting another Item. How can we do this?</p>
<p>This can be achieved via the client event function called <em>recalc</em>. According to <a href="http://www.netsuite.com">NetSuite</a> help, is an</p>
<blockquote><p>Event occurs after a line has been added to a sublist. This allows for any global actions that change whenever the contents of the sublist change.</p></blockquote>
<p>The function accepts one parameter, type, which is the sublist internal id.</p>
<p>As an example, the Sales Team requires us to add a discount item in the Sales Order whenever a customer orders a particular item. Below is what our recalc function looks like:</p>
<pre class="brush: jscript; title: ;">
function doRecalc(type)
{
    if (type == &quot;item&quot; &amp;amp;&amp;amp; nlapiGetRecordType() == &quot;salesorder&quot;)
    {
        if (nlapiGetCurrentLineItemValue(&quot;item&quot;, &quot;item&quot;) == SPECIAL_ITEM)
        {
            nlapiSelectNewLineItem(&quot;item&quot;);
            nlapiSetCurrentLineItemValue(&quot;item&quot;, &quot;item&quot;, DISCOUNT_ITEM, true, true);
            nlapiCommitLineItem('item');
        }
    }
}
</pre>
<p>Note that SPECIAL_ITEM and DISCOUNT_ITEM is the internal id of our sales item and discount item respectively.</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2010/10/recalc-inserting-new-item-line-dynamically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SuiteScript: Inventory Transfer via Code</title>
		<link>http://kikosantos.net/tech/2010/01/suitescript-inventory-transfer-via-code/</link>
		<comments>http://kikosantos.net/tech/2010/01/suitescript-inventory-transfer-via-code/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 09:43:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>

		<guid isPermaLink="false">http://www.kikosantos.net/tech/?p=129</guid>
		<description><![CDATA[Pre 2009.2, transferring inventory quantity from one location to another via SuiteScript can only be done through inventoryadjustment. First you have to add quantity to destination location. xfer.setLineItemValue(&#34;inventory&#34;, &#34;item&#34;, 1, ITEM_ID); xfer.setLineItemValue(&#34;inventory&#34;, &#34;location&#34;, 1, LOC_DESTINATION); xfer.setLineItemValue(&#34;inventory&#34;, &#34;adjustqtyby&#34;, 1, &#34;5&#34;); Then you have to deduct the quantity from the origin location xfer.setLineItemValue(&#34;inventory&#34;, &#34;item&#34;, 2, ITEM_ID); xfer.setLineItemValue(&#34;inventory&#34;, [...]]]></description>
			<content:encoded><![CDATA[<p>Pre 2009.2, transferring inventory quantity from one location to another via SuiteScript can only be done through <em>inventoryadjustment</em>. First you have to add quantity to destination location.</p>
<pre class="brush: jscript; title: ;">
xfer.setLineItemValue(&quot;inventory&quot;, &quot;item&quot;, 1, ITEM_ID);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;location&quot;, 1, LOC_DESTINATION);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;adjustqtyby&quot;, 1, &quot;5&quot;);
</pre>
<p>Then you have to deduct the quantity from the origin location</p>
<pre class="brush: jscript; title: ;">
xfer.setLineItemValue(&quot;inventory&quot;, &quot;item&quot;, 2, ITEM_ID);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;location&quot;, 2, LOC_ORIGIN);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;adjustqtyby&quot;, 2, &quot;-5&quot;);
</pre>
<p>Putting it all together, the code will roughly look like this:</p>
<p><span id="more-129"></span></p>
<pre class="brush: jscript; title: ;">
var xfer = nlapiCreateRecord(&quot;inventoryadjustment&quot;);
xfer.setFieldValue(&quot;account&quot;, SAMPLE_ACCOUNT);

// add qty to destination
xfer.setLineItemValue(&quot;inventory&quot;, &quot;item&quot;, 1, ITEM_ID);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;location&quot;, 1, LOC_DESTINATION);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;adjustqtyby&quot;, 1, &quot;5&quot;);

// deduct qty from origin
xfer.setLineItemValue(&quot;inventory&quot;, &quot;item&quot;, 2, ITEM_ID);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;location&quot;, 2, LOC_ORIGIN);
xfer.setLineItemValue(&quot;inventory&quot;, &quot;adjustqtyby&quot;, 2, &quot;-5&quot;);

var id = nlapiSubmitRecord(xfer, true);
</pre>
<p>With the 2009.2 update, users can directly create an <em>inventorytransfer</em> record. They just need to specify the origin (location) and the destination (tolocation) and NetSuite implicitly add the quantity specified to the destination and deduct the quantity from the origin.</p>
<pre class="brush: jscript; title: ;">
var xfer = nlapiCreateRecord(&quot;inventorytransfer&quot;);

xfer.setFieldValue(&quot;subsidiary&quot;, SUBSIDIARY_ID);
xfer.setFieldValue(&quot;account&quot;, SAMPLE_ACCOUNT);
xfer.setFieldValue(&quot;memo&quot;, &quot;Sample Inventory Transfer&quot;);

xfer.setFieldValue(&quot;location&quot;, LOC_ORIGIN);
xfer.setFieldValue(&quot;tolocation&quot;, LOC_DESTINATION);
xfer.setLineItemValue(&quot;invt&quot;,&quot;invtid&quot;,1, ITEM_ID);
xfer.setLineItemValue(&quot;invt&quot;,&quot;adjustqtyby&quot;, 1, &quot;5&quot;);

var id = nlapiSubmitRecord(xfer);
</pre>
<p>Pretty neat!</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2010/01/suitescript-inventory-transfer-via-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Show Field&#8217;s Internal ID</title>
		<link>http://kikosantos.net/tech/2009/11/show-fields-internal-id/</link>
		<comments>http://kikosantos.net/tech/2009/11/show-fields-internal-id/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 19:23:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>
		<category><![CDATA[configuration]]></category>

		<guid isPermaLink="false">http://www.kikosantos.net/tech/?p=112</guid>
		<description><![CDATA[NetSuite&#8217;s Field Help is a small pop-up window that displays a brief description of the field associated to it. To open it, simply click the field label. But do you know that the Field Help can also display the field&#8217;s Internal Id? What is this for? For SuiteScript developer, this is god sent. One doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>NetSuite&#8217;s Field Help is a small pop-up window that displays a brief description of the field associated to it. To open it, simply click the field label.</p>
<p style="text-align: center;"><a title="internal-id-01 by Kiko Santos, on Flickr" href="http://www.flickr.com/photos/senselessfeats/4075183197/"><img class="aligncenter" src="http://farm3.static.flickr.com/2600/4075183197_bfcb918447_o.png" alt="internal-id-01" width="439" height="260" /></a></p>
<p><span id="more-112"></span>But do you know that the Field Help can also display the field&#8217;s Internal Id? What is this for? For SuiteScript developer, this is god sent. One doesn&#8217;t need to go to the field configuration page to know the field&#8217;s Internal Id, he can just open the Field Help window to view this.</p>
<p>To make the Internal Id is the Field Help window visible, go to Home &gt;&gt; Set Preferences. Under the Defaults section, tick the &#8220;Show Internal IDs&#8221; checkbox then click the Save button.</p>
<p style="text-align: center;"><a title="internal-id-02 by Kiko Santos, on Flickr" href="http://www.flickr.com/photos/senselessfeats/4075183201/"><img class="aligncenter" src="http://farm3.static.flickr.com/2780/4075183201_121af6db74_o.png" alt="internal-id-02" width="474" height="170" /></a></p>
<p>That&#8217;s it! You can now view the field&#8217;s Internal Id in the Field Help window.</p>
<p style="text-align: center;"><a title="internal-id-03 by Kiko Santos, on Flickr" href="http://www.flickr.com/photos/senselessfeats/4075183203/"><img class="aligncenter" src="http://farm4.static.flickr.com/3500/4075183203_f2618b0779_o.png" alt="internal-id-03" width="383" height="202" /></a></p>
<p>Great things really do come in small packages.</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2009/11/show-fields-internal-id/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Implementation of nlapiStringToDate in 2009.2</title>
		<link>http://kikosantos.net/tech/2009/10/new-implementation-of-nlapistringtodate-in-20092/</link>
		<comments>http://kikosantos.net/tech/2009/10/new-implementation-of-nlapistringtodate-in-20092/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 18:02:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[netsuite]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[suitescript]]></category>

		<guid isPermaLink="false">http://www.kikosantos.net/tech/?p=108</guid>
		<description><![CDATA[All of a sudden, our users complained that one of our NetSuite process failed. They reported this error: TypeError: Cannot call method &#8220;getTime&#8221; of null (some_code.js$sys#791) I tried to debug the code using nlapiLogExecution can still couldn&#8217;t locate where the error occured. I up the ante by using the script debugger and found that the [...]]]></description>
			<content:encoded><![CDATA[<p>All of a sudden, our users complained that one of our <a href="http://www.netsuite.com" target="_blank">NetSuite</a> process failed. They reported this error:</p>
<p>TypeError: Cannot call method &#8220;getTime&#8221; of null (some_code.js$sys#791)</p>
<p>I tried to debug the code using nlapiLogExecution can still couldn&#8217;t locate where the error occured. I up the ante by using the script debugger and found that the error happens because the code is trying to call the getTime of a null object. Pretty self explanatory, but why did it happen? The code roughly looks like this:</p>
<pre class="brush: jscript; title: ;">
var billDateStr = rec.getFieldValue(&quot;custrecord_billdate&quot;)
var billDate = nlapiStringToDate(billDateStr);
var billTime = billDate.getTime();
</pre>
<p><span id="more-108"></span></p>
<p>This used to work fine. Notice that I didn&#8217;t test my billDateStr if it&#8217;s empty because I know that nlapiStringToDate will return the current date in case the date string that I passed is null or empty. NetSuite&#8217;s 2009.2 release handles this differently. Searching for answers in their help page, I found this article inside their release note:</p>
<blockquote><p>Starting with 2009.2, passing an empty string to the nlapiStringToDate(str) function returns null. Prior to this release, passing an empty string returned the current date. For example, in this snippet, the value of emptydate used to be the current date; now it is null.</p>
<pre class="brush: jscript; title: ;">
var emptydate = nlapiStringToDate('');
nlapiLogExecution('DEBUG', 'emptydate', emptydate);
</pre>
</blockquote>
<p>I wonder why they changed the implementation of nlapiStringToDate. Nevertheless, now I learned my lesson. Reading the release notes has its benefits.</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2009/10/new-implementation-of-nlapistringtodate-in-20092/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Document Outline for Client Script in Visual Studio 2005</title>
		<link>http://kikosantos.net/tech/2008/10/document-outline-for-client-script-in-visual-studio-2005/</link>
		<comments>http://kikosantos.net/tech/2008/10/document-outline-for-client-script-in-visual-studio-2005/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 20:39:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://www.kiko-santos.com/?p=19</guid>
		<description><![CDATA[One feature I like most in Visual Studio 2003 is their Document Outline Panel. I usually abuse this feature on my JavaScript code to easily see and jump through my functions. Though the Document Outline Panel is also included in Visual Studio 2005, it now doesn&#8217;t support outlining for JavaScript code. Good thing Evgeny Kleiman [...]]]></description>
			<content:encoded><![CDATA[<p>One feature I like most in Visual Studio 2003 is their Document Outline Panel. I usually abuse this feature on my JavaScript code to easily see and jump through my functions.</p>
<p><img src="http://farm4.static.flickr.com/3130/2926882630_a2115f47bd.jpg" alt="" width="500" height="338" /></p>
<p><span id="more-19"></span>Though the Document Outline Panel is also included in Visual Studio 2005, it now doesn&#8217;t support outlining for JavaScript code.</p>
<p><img src="http://farm4.static.flickr.com/3181/2926030443_c87aceb682.jpg" alt="" width="500" height="336" /></p>
<p>Good thing Evgeny Kleiman created an add-in for VS2005 that creates a treeview structure of the client script that is currently loaded in VS&#8217;s IDE much like the in VS2003. You can found this in the <a href="http://tech.groups.yahoo.com/group/vsnetaddin/message/3748" target="_blank">Visual Studio .Net Add-Ins Group at Yahoo! Groups</a>.  The file also contains the add-in&#8217;s source code but for those who just want the add-in file, you can <a href="http://www.fileden.com/files/2008/10/9/2135731/ScriptOutline.zip">download it here</a>.</p>
<p>Installation is straightforward.</p>
<p>1. Copy the <em>ScriptOutline.AddIn</em> and <em>ScriptOutline.dll</em> files in the addin folder of Visual Studio 2005</p>
<ul>
<li>For XP users:<br />
C:Documents and Settings&lt;username&gt;My DocumentsVisual Studio 2005Addins</li>
<li> For Vista users:<br />
C:Users&lt;username&gt;DocumentsVisual Studio 2005Addins</li>
</ul>
<p>2. Open Visual Studio 2005 then on the menu go to Tools &gt; Add-in Manager…</p>
<p><img src="http://farm4.static.flickr.com/3067/2926030493_1d36d4518a_m.jpg" alt="" width="240" height="184" /></p>
<p>3. Check the ScriptOutline Checkbox then click OK.</p>
<p><img src="http://farm4.static.flickr.com/3237/2926030525_a9ca622b86.jpg" alt="" width="500" height="324" /></p>
<p>4. The ScriptOutline panel will open. This panel, like any other panel, can be docked on any sides of the IDE.</p>
<p><img src="http://farm4.static.flickr.com/3285/2926882866_e931812bcd.jpg" alt="" width="500" height="380" /></p>
<p>Happy scripting!</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2008/10/document-outline-for-client-script-in-visual-studio-2005/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Import Yahoo! 360 Blog To WordPress</title>
		<link>http://kikosantos.net/tech/2008/06/import-yahoo-360-blog-to-wordpress/</link>
		<comments>http://kikosantos.net/tech/2008/06/import-yahoo-360-blog-to-wordpress/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 11:41:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://www.kiko-santos.com/?p=17</guid>
		<description><![CDATA[Before having my own domain for my blog, I was a huge fan of Yahoo! 360. I love its simplicity and its integration with other Yahoo services. But my enthusiasm slowly faded since Yahoo decides to pull the plug on Y360. Then I found WordPress and I fell in love again. Now my major problem [...]]]></description>
			<content:encoded><![CDATA[<p>Before having my own domain for my blog, I was a huge fan of <a href="http://360.yahoo.com">Yahoo! 360</a>. I love its simplicity and its integration with other Yahoo services. But my enthusiasm slowly faded since Yahoo decides to pull the plug on Y360. Then I found <a href="http://www.wordpress.com">WordPress</a> and I fell in love again. Now my major problem is how do I migrate all my Y360 entries into WP? The most obvious solution is to manually copy all my Y360 entries and paste it to WP one by one. If your post has comments and tags, you should do the same if you want it completely &#8220;save&#8221; the entry. But what if you have over 50 entries in Y360 with more than 20 comments each? What a nightmare.<br />
<span id="more-17"></span></p>
<p>I tried searching the web for a quick solution to this migration problem. Some suggested to import the rss feed of Y360 to WP. Unfortunately, Y360 feed only covers the last 10 posts of your blog and comments are not included in the feed as well. I hate to see all my Y360 posts go into waste so I decided on creating my own Y360 to WordPress tool a shot.</p>
<p>My plan is to leech the title, entry content, published date, tags and comments and their dates in the Y360 html page itself. Since I don&#8217;t have my own web hosting that supports ASP.Net [ donations are welcome <img src='http://kikosantos.net/tech/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ] I decided to make it a standalone Window App. As it turns out, the .Net framework doesn&#8217;t have a built-in HTML parser. I searched the web and came across <a href="http://www.codeplex.com/htmlagilitypack/">HtmlAgilityPack</a>. This is an open-source HTML Parser created in C# which promises to be an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT.</p>
<p>Capabilities:</p>
<ul>
<li>Converts a Yahoo! 360 blog to a single xml file and can be imported in a WordPress powered blog.</li>
<li>Aside from the entry title, entry date and entry content, this app can extract entry tags and comments (comment date, author, content)</li>
<li>Preserves the old formatting the 360 content</li>
<li>Maintains the images attached inside the blog entry.</li>
<li>Auto conversion of 360 dates to WP dates</li>
<li>Supports HTTP proxy server and domain name authentications</li>
</ul>
<p>Limitations</p>
<ul>
<li>Main image of the 360 blog entry (located the top of the entry just below the title) will not be included.</li>
<li>Can extract only the first 50 comments of an entry. Y360 paginates comments by groups of 50. Since the app only leeches the front page of an entry, comments located inside the next page are not included.</li>
<li>Slow extraction especially for blog with more than 50 entries. I tested it on my own Y360 blog with 25 entries and 112 comments and the whole process was completed in 3 minutes and 52 seconds</li>
</ul>
<p>As of this posting, I will only release the setup files. This will be sufficient for you to install the app in your machine. I am planning to also release the source code after I tidy up my codes a bit.</p>
<p>Go to my<a href="http://www.codeplex.com/y360towordpress/Release/ProjectReleases.aspx?ReleaseId=14480"> Y360 To WordPress page in codeplex to download the beta release</a>. The installation note and how to use the app are also located there. Feel free to post a comment for your feedback and suggestions regarding the app.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2008/06/import-yahoo-360-blog-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Querying the Latest Record</title>
		<link>http://kikosantos.net/tech/2008/05/querying-the-latest-record/</link>
		<comments>http://kikosantos.net/tech/2008/05/querying-the-latest-record/#comments</comments>
		<pubDate>Fri, 23 May 2008 15:58:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.kiko-santos.com/?p=15</guid>
		<description><![CDATA[It was my long standing problem when querying the latest history of a record. The scenario is that I have a parent table and its transaction log (say, history records) are stored in a child table linked by the parent&#8217;s primary key id. The parent table stores the main information regarding a transaction while the [...]]]></description>
			<content:encoded><![CDATA[<p>It was my long standing problem when querying the latest history of a record. The scenario is that I have a parent table and its transaction log (say, history records) are stored in a child table linked by the parent&#8217;s primary key id. The parent table stores the main information regarding a transaction while the child table stores historical data of what happened in the parent&#8217;s table info.</p>
<p style="center;"><img class="aligncenter" src="http://i72.photobucket.com/albums/i168/senselessfeats/tech/parent-children.gif" alt="parent-child relationship" width="432" height="172" /></p>
<p><span id="more-15"></span>Well, the first thing that I can think of was to create a sub-query of my child table, MAX it&#8217;s identity and GROUP BY the parent&#8217;s id.</p>
<pre class="brush: sql; title: ;">
select      p.*
        ,   c.details
        ,   c.date_created
from        (
            select      tmp.*
                    ,   c.details
            from        (
                        select      parent_id
                                ,   max(date_created) date_created
                        from        children
                        group by    parent_id
                        ) tmp
            inner join  children c
            on          tmp.parent_id = c.parent_id
            and         tmp.date_created = c.date_created
            ) c
inner join  parent p
on          c.parent_id = p.id
</pre>
<p>Though I am getting my desired result set, the code below is more efficient.</p>
<pre class="brush: sql; title: ;">
select      p.*
        ,   c.details
        ,   c.date_created
from        parent p
inner join  children c
on          p.id = c.parent_id
where       c.id =
            (
            select      max(c2.id)
            from        children c2
            where       c2.parent_id = p.id
            group by    parent_id
            )
</pre>
<p>Why didn&#8217;t I think of this one first? Classic example of <a href="http://www.apples4theteacher.com/holidays/columbus-day/short-stories/columbus-and-the-egg.html">Columbus&#8217; Egg</a>. Again, there is always a simple solution behind a <del datetime="00">complex</del> problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2008/05/querying-the-latest-record/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Cannot Modify Header Information</title>
		<link>http://kikosantos.net/tech/2008/05/php-cannot-modify-header-information/</link>
		<comments>http://kikosantos.net/tech/2008/05/php-cannot-modify-header-information/#comments</comments>
		<pubDate>Mon, 19 May 2008 03:28:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.kiko-santos.com/?p=14</guid>
		<description><![CDATA[I downloaded a very cool theme for this blog and luckily, I successfully installed it in my local instance of WordPress. Satisfying the OC in me, I immediately do some minor twicking to further personalize my page. I tested the page&#8217;s comment engine, posting, plugin and widget capabilities but was repeatedly bombarded with this error [...]]]></description>
			<content:encoded><![CDATA[<p>I downloaded a <a href="http://www.askgraphics.com/freetemplates/greybox-theme/" target="_blank">very cool theme</a> for this blog and luckily, I successfully installed it in my local instance of WordPress. Satisfying the OC in me, I immediately do some minor twicking to further personalize my page. I tested the page&#8217;s comment engine, posting, plugin and widget capabilities but was repeatedly bombarded with this error every time I click a button that causes the page to reload:</p>
<blockquote><p><strong>Warning:</strong> Cannot modify header information &#8211; headers already sent by (output started at / my_site/wp-content/themes/new_theme/functions.php:2) in <strong>/my_site /wp-includes/pluggable.php</strong> on line <strong>694</strong></p></blockquote>
<p><span id="more-14"></span></p>
<p>Having no professional experience in php, my first instinct is to google on the topic and I came across <a href="http://www.jaguarpc.com/forums/showthread.php?t=15064" target="_blank">this forum post</a>:</p>
<blockquote><p>mattsiegman: it will break if you have any space before your &lt;?</p></blockquote>
<p>The thread suggested different solutions but I tried the simplest one. I opened my functions.php file and found this:</p>
<pre class="brush: php; title: ;">
&lt;?php
if ( function_exists('register_sidebar') )
{
    register_sidebar(array(
        'before_widget' =&gt; '&lt;li id=&quot;%1$s&quot; class=&quot;widget %2$s&quot;&gt;',
        'after_widget' =&gt; '&lt;/li&gt;',
        'before_title' =&gt; '&lt;h2 class=&quot;widgettitle&quot;&gt;',
        'after_title' =&gt; '&lt;/h2&gt;',
</pre>
<p>I have a space (linebreak) on my first line, I deleted it, saved and refreshed my browser. Voila! The error was gone. See how complicated problems can be solved by simple solutions?</p>
]]></content:encoded>
			<wfw:commentRss>http://kikosantos.net/tech/2008/05/php-cannot-modify-header-information/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

