<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom"><channel><title>Latest Blog entries</title><description/><item><guid isPermaLink="false">9ba70584-7b18-41ba-9770-56b768a1cbc5</guid><link>http://devnet.superoffice.com/Blog/?entryId=828</link><author>Jan.Andersen@superoffice.no</author><title>SuperOffice Outlook Ribbon Inactive</title><description>&lt;p&gt;For some strange reason I had a lot of problems installing the SuperOffice mail link on a Windows 7 (32bit) machine, Outlook 2010 SP1 and SuperOffice 6.3 SR-2&lt;/p&gt;&#xD;
&lt;p&gt;The main issue was that the Outlook Ribbon was loaded but set as inactive by Outlook. The following error appeared after enabling VSTO debugging:&lt;/p&gt;&#xD;
&lt;p&gt;"Could not load file or assembly Microsoft.Office.Interop.Outlook, Version = 12.0.0.0, Culture = neutral, PublicKeyToken = 71e9bce111e9429c&amp;nbsp;or one of its dependencies.&amp;nbsp;Manifest definition to the collection that was found does not match with the reference collection. (Exception from HRESULT: 0x80131040)"&lt;/p&gt;&#xD;
&lt;p&gt;If I looked under Outlook's Add-ins&amp;nbsp; I found out that the "SuperOfficeRibbon-Outlook.vsto" file was set as listed under inactive Application Add-ins.&lt;/p&gt;&#xD;
&lt;p&gt;I tried all the tricks in the book without getting somewhat closer to a solution.&lt;/p&gt;&#xD;
&lt;p&gt;The thing that finally solved the issue was this workaround:&lt;/p&gt;&#xD;
&lt;p&gt;1. Run the mail link installer file (default SuperOffice.MailLink.Setup.exe)&lt;/p&gt;&#xD;
&lt;p&gt;2. Copy or move the file Microsoft.Interopt.Outlook.dll (6.2.1.0) from "C:\Program Files\SuperOffice\SuperOffice 7 Windows\Mail link"&amp;nbsp;to e.g. "C:\Program Files\SuperOffice\SuperOffice 7 Windows"&lt;/p&gt;&#xD;
&lt;p&gt;3.Use the utility "gacutil.exe" to register the Microsoft.Interopt.Outlook.dll (6.2.1.0) file in the windows Global Assembly Cache (GAC)&amp;nbsp;using this command line : c:\temp\gacutil.exe /i "C:\Program Files\SuperOffice\SuperOffice 7 Windows\Microsoft.Interopt.Outlook.dll"&lt;/p&gt;&#xD;
&lt;p&gt;4. When this is a success you need to copy and/or replace the Microsoft.Interopt.Outlook.dll (12.0.0.0) with the Microsoft.Interopt.Outlook.dll (6.2.1) that&amp;rsquo;s part of our installer.&lt;/p&gt;&#xD;
&lt;p&gt;Note: The Microsoft.Interopt.Outlook.dll (12.0.0.0) is part of the Office 2007 system and the utility gacutil.exe is part of the windows SDK.&lt;/p&gt;&#xD;
&lt;p&gt;This must be seen as a workaround and not a permanent solution. Why the computer always asked for the Office 2007 version of the Microsoft.Interopt.Outlook.dll&amp;nbsp;and not the 2010 version is still a mystery.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Good Luck!&lt;/p&gt;</description><a10:updated>2012-05-15T13:39:24+02:00</a10:updated></item><item><guid isPermaLink="false">59a0c1b6-24e0-4770-96be-520728584d81</guid><link>http://devnet.superoffice.com/Blog/?entryId=827</link><author>ask@Superoffice.no</author><title>SQL Server 2000 and 2008 on the same server</title><description>&lt;p&gt;Recently I visited a customer who claimed they had everything in order before a planned upgrade from SuperOffice Sales &amp;amp; Marketing 6.2 to 7.1.&lt;br /&gt; When turning up at the customer`s location, I discovered that this wasn`t the case.&lt;/p&gt;&#xD;
&lt;p&gt;Installed on the running server, there was SQL Server version 8.0/2000 running several databases, so simply upgrading to SQL Server 2008 Express wasn`t an option.&lt;/p&gt;&#xD;
&lt;p&gt;After contacting the team at SuperOffice for advice, I ended up installing SQL Server 2008 Express alongside the existing 2000 SQL Server.&lt;/p&gt;&#xD;
&lt;p&gt;If you are planning to do this: When running the SQL Server 2008 Express, make sure to set the 2008 version a named instance (Please see the screenshot below).&lt;/p&gt;&#xD;
&lt;p&gt;Please bear in mind that running two databases on the same server may slow down the system or even drain the system for performance, so consider the hardware and the number of users connected to the server before installation.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;img src="http://www.symantec.com/connect/sites/default/files/u3098/4.png" alt="SQL Server 2008 Express" width="620" height="465" /&gt;&lt;/p&gt;</description><a10:updated>2012-05-11T11:36:54+02:00</a10:updated></item><item><guid isPermaLink="false">3d84c373-6792-4316-9b68-79ae2f0a2d64</guid><link>http://devnet.superoffice.com/Blog/?entryId=826</link><author>Jan.Andersen@superoffice.no</author><title>Ipv6 and Direct Access</title><description>&lt;p&gt;Direct Access from Microsoft was&lt;span&gt;&amp;nbsp;introduced in the Windows 7 Enterprise and Windows Server 2008 R2 operating systems, to allow remote users to securely access enterprise shares, web sites, and applications without connecting to a virtual private network (VPN). Direct Access&amp;nbsp;&lt;span&gt;establishes bi-directional connectivity with a user's enterprise network every time a user&amp;rsquo;s DirectAccess-enabled portable computer connects to the Internet even before the user logs on.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;If you tried to start SuperOffice while connected to Direct Access , the application would crash. This would only apply to SoCrm.exe and not SoAdmin.exe. The reason for that is we have a table in Superoffice called Activeuser which are used to check if the user is logged in from another place. This table is checked everytime a user starts SoCrm.exe. The table contains information about the user environment (username, netbiosname IP mm)&lt;/p&gt;&#xD;
&lt;p&gt;It is the IP address in this table which was pure IPv4. Meaning that if you started SoCrm.exe on a Ipv6 environment SuperOffice will fail to start. From Superoffic 7.1 we have solved this by checking both Ipv4 and Ipv6 address at startup. This means that SuperOffice 7,1 will support Ipv6 and Direct Access.&lt;/p&gt;</description><a10:updated>2012-05-09T11:38:13+02:00</a10:updated></item><item><guid isPermaLink="false">f5f44060-ee9a-4a24-a745-11ffbaa05adf</guid><link>http://devnet.superoffice.com/Blog/?entryId=825</link><author>marekv@superoffice.com</author><title>Soundex comes to NetServer</title><description>&lt;p&gt;As you may or may not know, we have a "sounds-like" algorithm in the SuperOffice products. It's our adaptation of a fairly well-known algorithm called "Metaphone" (https://en.wikipedia.org/wiki/Metaphone), which takes a string of arbitrary length and returns a transformed version of a fixed, shorter length. The transformation is such that strings that sound similar (are phonetically aproximately equal) will result in identical transformed strings.&lt;/p&gt;&#xD;
&lt;p&gt;We apply this algorithm to contact.name, project.name and selection.name, and store the resulting string in the soundEx field in each of those tables. The application is done transparently by both NetServer and the C++ code, so unless you're messing with our database on your own, it should be up to date.&lt;/p&gt;&#xD;
&lt;p&gt;You can use this to search for entities with similar names - that's what the CRM client does when it says "Oh, the company you're adding sounds like one you've got before"; this simply means that we got an exact match for the soundEx string.&lt;/p&gt;&#xD;
&lt;p&gt;So far so good - but the database servers (SQL Server, Oracle, Sybase, DB/2) all have their own implementations of a similar algorithm. And this is interesting because it can be applied to WHERE statements as a function, on any string field, not just where someone (us) planned for it.&lt;/p&gt;&#xD;
&lt;p&gt;In 7.1 we've added support for this function in NetServer, so you can access it in your custom SQL. As an example of what it might be good for, I wrote a little utility that helps us combine duplicate persons that arise when a sales rep registers a person for our Online product, and the automated sync later on adds the person as spelled in the Online database. Those spellings - by the sales rep, and by the person, may not always be the same, and so we end up with two records that &lt;strong&gt;sound much the same but are not identical&lt;/strong&gt;. A job for Soundex!&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #2b91af;"&gt;PersonTableInfo&lt;/span&gt;&amp;nbsp;p1&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;TablesInfo&lt;/span&gt;.GetPersonTableInfo();&#xD;
&lt;span style="color: #2b91af;"&gt;PersonTableInfo&lt;/span&gt;&amp;nbsp;p2&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;TablesInfo&lt;/span&gt;.GetPersonTableInfo();&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #2b91af;"&gt;ContactTableInfo&lt;/span&gt;&amp;nbsp;c1&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;TablesInfo&lt;/span&gt;.GetContactTableInfo();&#xD;
&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #2b91af;"&gt;Select&lt;/span&gt;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;S&lt;/span&gt;.NewSelect(&lt;span style="color: #a31515;"&gt;"Find&amp;nbsp;duplicates"&lt;/span&gt;);&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&amp;nbsp; s.JoinRestriction.InnerJoin(p1.ContactId.Equal(p2.ContactId),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;S&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;ArgumentFunctions&lt;/span&gt;.Soundex(p1.Firstname).Equal(&lt;span style="color: #2b91af;"&gt;S&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;ArgumentFunctions&lt;/span&gt;.Soundex(p2.Firstname))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .And(&lt;span style="color: #2b91af;"&gt;S&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;ArgumentFunctions&lt;/span&gt;.Soundex(p1.Lastname).Equal(&lt;span style="color: #2b91af;"&gt;S&lt;/span&gt;.&lt;span style="color: #2b91af;"&gt;ArgumentFunctions&lt;/span&gt;.Soundex(p2.Lastname))));&lt;/p&gt;&#xD;
&lt;pre&gt;s.RestrictionAnd(p1.PersonId.UnEqual(p2.PersonId));&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;Here we're looking for person records that belong to the same contact, have similar-sounding first and last names, and are not the same record (important detail...). Suppose we want to fetch these candidates as Row objects...&lt;/p&gt;&#xD;
&lt;pre&gt;s.ReturnFields.Add(p1,&amp;nbsp;p2,&amp;nbsp;c1);&#xD;
&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;(&lt;span style="color: blue;"&gt;var&lt;/span&gt;&amp;nbsp;qeh&amp;nbsp;=&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;QueryExecutionHelper&lt;/span&gt;(s))&#xD;
{&#xD;
	&lt;span style="color: blue;"&gt;while&lt;/span&gt;&amp;nbsp;(qeh.Reader.Read())&#xD;
	{&#xD;
		PersonRow personOne&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;PersonRow&lt;/span&gt;.GetFromReader(qeh.Reader,&amp;nbsp;p1);&#xD;
		PersonRow personTwo&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;PersonRow&lt;/span&gt;.GetFromReader(qeh.Reader,&amp;nbsp;p2);&#xD;
		ContactRow contact =&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ContactRow&lt;/span&gt;.GetFromReader(qeh.Reader,&amp;nbsp;c1);&#xD;
        }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;Note that the Soundex algorithm can be implemented differently by each database - so while this code will work on all of the databases we support, it may not give the exact same results. And you should never store the output from Soundex anywhere for later use, because the algorithms might change, the database might move to another server - who knows. But using it &lt;strong&gt;within a single SQL statement&lt;/strong&gt; should work just fine.&lt;/p&gt;&#xD;
&lt;p&gt;You could of course fetch all Person records and process them through the Metaphone algorithm in NetServer; that would give you a predictable result, independent of the database. It would also run orders of magnitude slower, since you'd be doing the processing outside the database. Your mileage may vary - but as a rule, keeping processing inside the database is good, that is what it's for.&lt;/p&gt;&#xD;
&lt;p&gt;Marek&lt;/p&gt;</description><a10:updated>2012-05-07T13:40:37+02:00</a10:updated></item><item><guid isPermaLink="false">e309717d-3aa2-4bcd-a2b1-52d416dadb79</guid><link>http://devnet.superoffice.com/Blog/?entryId=824</link><author>marekv@superoffice.com</author><title>SQL Server Bulk Copy - making Saint, Freetext and Rebuild go faster!</title><description>&lt;p&gt;There are times when we need to move a lot of data into a database. Examples are - Rebuild, import, generate prototype (actually the same code handles all of those); recreate freetext index; recreate Saint counters. In these cases, SQL Server has a secret weapon: "Bulk Copy".&lt;/p&gt;&#xD;
&lt;p&gt;Bulk Copy is a separate API that bypasses a lot of the normal functionality related to an INSERT statement. It's built for one thing only: blasting data into the database as fast as possible. There are some prerequisites that have to be in place, and perhaps the most significant one is that the table should have no indexes. It's much, much faster to load a table and &lt;strong&gt;then&lt;/strong&gt; create an index, than to update the index for each and every row.&lt;/p&gt;&#xD;
&lt;p&gt;You can read Microsofts info here: http://msdn.microsoft.com/en-us/library/ms130809.aspx&lt;/p&gt;&#xD;
&lt;p&gt;The speed improvement can be very large - we went from 6-7 hours to 20 minutes for a freetext regeneration.&lt;/p&gt;&#xD;
&lt;p&gt;So what do you have to do, to enjoy this? Not much, but there &lt;strong&gt;is&lt;/strong&gt; one thing... When you set up the Windows client, the default SQL Server ODBC driver often used is the on called, simply, "SQL Server". Why? Because it's there, it comes with Windows. But this driver does not have the Bulk Copy (BCP) stack, so bulk copy doesn't work with it.&lt;/p&gt;&#xD;
&lt;p&gt;If you instead use one of the Native Client drivers - which one doesn't matter - then SuperOffice will automatically use BCP whenever it's relevant. Try doing a Regenerate Freetext with Native Client and see how fast it goes.&lt;/p&gt;&#xD;
&lt;p&gt;We also use BCP for SoAdmin-Import, but the speed improvement is not quite so dramatic, since we can't really drop all the indexes on the destination tables, that would be a bit drastic. But it's still a bit faster than sending along INSERT's (even though we do use "saved statements", so we only sent the new values for each row).&lt;/p&gt;&#xD;
&lt;p&gt;Behind the scenes, the C++ code discovers that BCP is available, and switches into the special mode for those big, bulky operations. To use BCP we need to pack data into the binary format expected by SQL Server - the dictionary helps us do that - and send it off using the special API's.&lt;/p&gt;&#xD;
&lt;p&gt;Microsoft have made a BCP interface for ADO.NET as well, so if/when such bulky operations move into NetServer, we'll most probably use BCP there too.&lt;/p&gt;&#xD;
&lt;p&gt;PS. You can download the ODNC Native Client for free from Microsoft - look at https://www.microsoft.com/en-us/download/details.aspx?id=3522 or related links.&lt;/p&gt;&#xD;
&lt;p&gt;Marek&lt;/p&gt;</description><a10:updated>2012-05-07T10:39:30+02:00</a10:updated></item><item><guid isPermaLink="false">5834fe32-1281-41e6-bd38-6114abc2d801</guid><link>http://devnet.superoffice.com/Blog/?entryId=823</link><author>tony.poole@synergytechnology.co.uk</author><title>Dymo Business Card Scanner</title><description>&lt;p&gt;Hi Everyone&lt;/p&gt;&#xD;
&lt;p&gt;Has anyone created a link to the Dymo range of business card scanners to create businesses and people from the data on the card.&lt;/p&gt;&#xD;
&lt;p&gt;We have a client who is looking for the integration and befiore developing a solution I thought I would ask the community if they have a solution which is in existence.&lt;/p&gt;&#xD;
&lt;p&gt;Our client is using CRM 7&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Thanks for taking the team to read my request.&lt;/p&gt;</description><a10:updated>2012-05-07T00:55:09+02:00</a10:updated></item><item><guid isPermaLink="false">79395de4-66ca-490d-a7e4-f9c98ddf9ec5</guid><link>http://devnet.superoffice.com/Blog/?entryId=822</link><author>sverre@superoffice.com</author><title>Requests for projects</title><description>&lt;p&gt;NOTE: This article requires functionality from Customer Service version 7.1!&lt;/p&gt;&#xD;
&lt;p&gt;In SuperOffice Sales &amp;amp; Marketing, the Projects entity is kind of your one-size-fits-all entity: it can represent an automobile, a building, a server, a sold product or whatever else you would like. And to my knowledge, many S&amp;amp;M implementations are doing exactly that. In that context, it could make sense to be able to relate requests to projects. This would allow you to track all customer inquiries related to the &amp;ldquo;project&amp;rdquo;. With version 7.1 this has become quite easy to set up, and so I will demonstrate it in this blog.&lt;/p&gt;&#xD;
&lt;p&gt;First of all, we need to create a new database field to manage our relation. I would argue that in most cases, you would like to be able to relate multiple requests to a single project. Consequently, you need to create the relational field on the request. In 7.1 we have introduced three new types for extra fields: Sale relation, Project relation and Appointment relation. So, to create this field you must navigate to System design &amp;gt; Tables. Locate the &amp;ldquo;Request&amp;rdquo; table and create a new field of type &amp;ldquo;Project relation&amp;rdquo;:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="file:///C:/Users/hjelms.SUPEROFFICE_ASA/AppData/Local/Temp/WindowsLiveWriter1286139640/supfiles2DEE27DB/image3.png"&gt;&lt;img title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1740_2200.jpg" alt="image" width="512" height="285" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;After saving your new field, you need to click the &amp;ldquo;Restart netserver&amp;rdquo; button at the top to make NetServer reload the new dictionary. In the default &amp;ldquo;New request&amp;rdquo; screen, you will now get a new control in the &amp;ldquo;Extra fields&amp;rdquo; tab which allows you to choose a related project:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="file:///C:/Users/hjelms.SUPEROFFICE_ASA/AppData/Local/Temp/WindowsLiveWriter1286139640/supfiles2DEE27DB/image8.png"&gt;&lt;img title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1743_2194.jpg" alt="image" width="419" height="270" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When saving your request, you can see amongst the request fields that it is related to a project (bottom right):&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="file:///C:/Users/hjelms.SUPEROFFICE_ASA/AppData/Local/Temp/WindowsLiveWriter1286139640/supfiles2DEE27DB/image13.png"&gt;&lt;img title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1744_2192.jpg" alt="image" width="612" height="194" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The next natural thing to set up is a web panel inside Sales &amp;amp; Marketing which allows you to list these requests for a project. We do this by opening the admin client and navigating to Lists &amp;gt; Web panel and adding a new web panel:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="file:///C:/Users/hjelms.SUPEROFFICE_ASA/AppData/Local/Temp/WindowsLiveWriter1286139640/supfiles2DEE27DB/image17.png"&gt;&lt;img title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1747_2186.jpg" alt="image" width="368" height="462" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The URL should be: &lt;a title="http://sverre71/scripts/ticket.exe?_sf=0&amp;amp;action=listTableEntries&amp;amp;table=ticket&amp;amp;field.0=ticket.x_project&amp;amp;value.0=&amp;lt;prid&amp;gt;&amp;amp;login_secret=&amp;lt;usec&amp;gt;" href="http://.../scripts/ticket.exe?action=listTableEntries&amp;amp;table=ticket&amp;amp;field.0=ticket.x_project&amp;amp;value.0=%3Cprid%3E&amp;amp;login_secret=%3Cusec%3E"&gt;http://&amp;hellip;/scripts/ticket.exe?action=listTableEntries&amp;amp;table=ticket&amp;amp;field.0=ticket.x_project&amp;amp;value.0=&amp;lt;prid&amp;gt;&amp;amp;login_secret=&amp;lt;usec&amp;gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In this URL we are passing in the current project id as &amp;lt;prid&amp;gt; and the current user session as &amp;lt;usec&amp;gt;. This allows any S&amp;amp;M user to view this list without having a CS license:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="file:///C:/Users/hjelms.SUPEROFFICE_ASA/AppData/Local/Temp/WindowsLiveWriter1286139640/supfiles2DEE27DB/image26.png"&gt;&lt;img title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1748_2184.jpg" alt="image" width="612" height="395" /&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-05-04T10:41:33+02:00</a10:updated></item><item><guid isPermaLink="false">3d8f91ab-5323-40a6-ad0d-3a7d7c2f422f</guid><link>http://devnet.superoffice.com/Blog/?entryId=810</link><author>sverre@superoffice.com</author><title>Enabling caching of static content in Internet Information Server</title><description>&lt;p&gt;SuperOffice Customer Service, like many other web applications, use a mixture of &amp;ldquo;static&amp;rdquo; and &amp;ldquo;executed&amp;rdquo; content when the various webpages of the application are constructed. Static content is typically our .js and .css files (javascript and style sheets), and also all the images we use for icons, which executed content is the HTML page containing information about requests, customers, etc. While the static content never changes (until you upgrade to a new version), the executed content is updated frequently (requests change statuses, datetimes are changed, etc). Since the static content is&amp;hellip;static, there is technically no need to spend time downloading it to your browser all the time. However, since your browser cannot be sure whether it has changed or not, this is exactly what happens. So, to improve the responsiveness (=speed) of your system, you can enable browser-caching of this content. This blog will explain how to enable this in IIS and how you can verify that it works.&lt;/p&gt;&#xD;
&lt;p&gt;The best way to investigate what is loaded for your webpage is to open the &amp;ldquo;Developer tools&amp;rdquo; which is a part of most modern browsers. In my example, I use Chrome. A part of the developer tools is the network tab which shows what content the browser loads, and how long time it takes:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1734_2166.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1735_2167.jpg" alt="image" width="932" height="569" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Almost all pages in CS will look something like this. At the top we have the request for the actual webpage, which always takes the longest to load. After the browser gets this webpage back, it will see that it references a lot of .js, .css and image resources and will download these as well. The various bars in orange shows how long it takes to request them, and how long it takes to download them. Since any page in CS could include quite a few resources, the browser will in fact spend some time downloading this. Also, the browser will only download a limited set of resources in parallel. So, if our page requires 30 resources, and the browser only downloads 10 at a time, we have to wait for 3 sequential download sessions before we have all the content required to show the page. This takes time, especially if your location is physically far away from the server, and you get network latency on each request.&lt;/p&gt;&#xD;
&lt;p&gt;The solution to this is to enable content expiration on all these resources. This means that we configure IIS to tell the browser that it can cache these files, since they will not change for a specified timeframe. To do this, we need to go into the various resource folders (javascript, css, graphics) in IIS and click the icon named &amp;ldquo;HTTP response headers&amp;rdquo;. Then click &amp;ldquo;Set common headers&amp;rdquo;, and specify an expiration. In this case, I will set expiration to one day. This means that all requests a user will do during one day will be cached, but the next day the user will load the static content once more. This means that if we upgrade our system, and we have new static content, then this is likely to not cause a problem.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1736_2168.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1737_2169.jpg" alt="image" width="356" height="221" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;After you load the page again, at least twice, you should now be able to see in the network traffic window that all the resources are loaded from cache, and consequently the loading is instantly rather than taking some time with latency and loading. In my example, the main page now loads in 546ms in contrast to 710ms, which is in fact a 23% reduction in load time.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1738_2170.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1739_2171.jpg" alt="image" width="953" height="581" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Pleas be aware though, that with caching, you can also experience problems after an upgrade because the browser does not load the new files. Changing the cache-header in IIS after upgrading will not help, since the browser will not try to load the file again, and consequently will not be informed that caching now is turned off. Normally, the best solution is to make sure the users Ctrl-F5 their pages to force a reload, or have them clear the cache. If you use a 1-day caching as in my example, their browser will normally refetch the pages once a day anyway, and if you upgrade after working hours you should be fine. Or, of course, if you really want to be careful, you could disable caching a few days before actually upgrading, so that any cached content in any user's browser is expired before you upgrade. In general, I don't think this should pose a real problem.&lt;/p&gt;</description><a10:updated>2012-05-04T08:19:13+02:00</a10:updated></item><item><guid isPermaLink="false">805427f2-f349-4edc-8b20-214cbc3bf4cd</guid><link>http://devnet.superoffice.com/Blog/?entryId=809</link><author>Jens@superoffice.com</author><title>IIS Authentication and Single Sign-on for SM.web</title><description>&lt;p&gt;There are several reasons for using IIS Authentication.&amp;nbsp; Adding an extra layer of security or adding support for single sign-in are examples of such. There are several authentication settings that can be applied for web applications and sites in IIS.&amp;nbsp;&amp;nbsp; The default behaviour is that IIS allows anonymous access.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1713_2122.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1714_2123.jpg" alt="image" width="662" height="430" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Older versions of SuperOffice SM.web used ASP.NET forms authentication.&amp;nbsp; This has since 7.0 been replaced with our own authentication module: SoFormsAuthentication.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://www.websequencediagrams.com/cgi-bin/cdraw?lz=cGFydGljaXBhbnQgIldlYiBCcm93c2VyIiBhcyBjCgASDUludGVybmV0IEluZm9ybWF0aW9uIFNlcnYAKAdpaXMAIw5TTS53ZWIARgVzCgpjLT5paXM6IERlZmF1bHQuYXNweAphY3RpdmF0ZQA4BQppaXMAHgdBbm9ueW1vdXMgb2tcbnNob3cgcGFnZQAcBgAsGXMKZGUARQ1vcHQgTm90IEF1dGhldGljYXRlZCB3aXRoIFN1cGVyT2ZmaWNlCgBNBlNvRm9ybXMAJgVuACcFaW9uXG5SZWRpcmVjdCB0byBMb2dpbgCBMwZzLQCBSAcACQsAcgtzAIFHEy0-YwAiDQCBcwljAIEnEACCIwlQT1NUAEsXYwCCLg4AghEqAEQQAIIkGgCCEgcAggcLAIIBKwCDWg1lbmQKAIIpCgCDdQ0AghsaAIQJBWMAFRoAhC4FCg&amp;amp;s=vs2010" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Disabling anonymous authentication or denying anonymous users access to SM.web will require IIS to autheticate before passing the request on to SM.web&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1715_2124.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1716_2125.jpg" alt="image" width="625" height="430" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;If no valid credentials is provided to IIS, a responce of 401 requesting credentials are returned to the browser.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://www.websequencediagrams.com/cgi-bin/cdraw?lz=cGFydGljaXBhbnQgIldlYiBCcm93c2VyIiBhcyBjCgASDUludGVybmV0IEluZm9ybWF0aW9uIFNlcnYAKAdpaXMAIw5TTS53ZWIARgVzCgpjLT5paXM6IERlZmF1bHQuYXNweAphY3RpdmF0ZQA4BW9wdCBJSVMgQW5vbnltb3VzIGRpc2FibGVkCmlpcwA4B0lzIHVzZXIgYXV0aGVudGljYXRlZD8AGwZjOiBFcnJvciBjb2RlIDQwMVxuQQAdCmlvbiBjaGFsbGVuZ2UAcApjCmRlAHoNYwBEBU9idGFpbiBjcmVkZW50aWFsABQFaWlzOgCBNQwgKHdpdGgAGgwpAEMMYwCBUw5lbgCBQwcAgW4ZcwB9EG9wdCAAgTkLZWQgAGwFSUlTCgBCBlRyeQCBfw0gU3VwZXJPZmZpY2VcbgAlCCBDAIE9C2VuZACCZwVObwBVBwBODQA1CwBcB1NvRm9ybXMAgj0OXG5SZWRpcmVjdCB0byBMb2dpbgCDTQZzLQCDYgcACQsAglcLcwCDZg4Ag1UFAIM1BQA4CwCDAhoAhD0JUE9TVABLFwCCZg8AgmkIACIQAIJaGgCCUwcAgmsMAIFgKgCFUg1lbmQKAIIHCgCFbQ0AgXkaAIVDCAAXGACCMgUK&amp;amp;s=vs2010" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Internet Explorer will try to grab the credentials of the logged in user or fall back to the default behaviour of all other browsers; provide a browser-specific authentication dialog.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1717_2126.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1718_2127.jpg" alt="image" width="387" height="177" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Custom errors must be removed for 401 error codes for this to work.&amp;nbsp; The final release of 7.1 is updated with this configuration. Installations prior to this requires that custom errors are disabled for the 401 error message.&amp;nbsp; This can be carried out by manually modifying the web.config file with a tool like Notepad++&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1719_2128.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1720_2129.jpg" alt="image" width="407" height="430" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Both the &amp;lt;remove&amp;hellip;&amp;gt; and &amp;lt;error&amp;hellip;&amp;gt; nodes needs to be removed or commented out like the example above.&lt;/p&gt;&#xD;
&lt;p&gt;The SM.web login page is by-passed if a valid SuperOffice user is mapped to the current Active Directory.&amp;nbsp; If there are no such mappings, the SuperOffice login dialog is displayed.&amp;nbsp; Such mappings needs to be made using the SoAdmin.exe windows administration client.&lt;/p&gt;&#xD;
&lt;p&gt;There can be situations where the SuperOffice Extentions web service needs to be modified to support windows authentication.&amp;nbsp; This can be performed by modifying the binding in the web.config file.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1721_2130.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1722_2131.jpg" alt="image" width="575" height="430" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-04-24T15:48:07+02:00</a10:updated></item><item><guid isPermaLink="false">6740bb5c-6bcb-456c-9ad4-7e7942a6e8b5</guid><link>http://devnet.superoffice.com/Blog/?entryId=808</link><author>frode@enkelt.no</author><title>Using friendly name in your outgoing e-mails in CS mailboxes</title><description>&lt;p&gt;One of the small things you can do to make sure your Customer Service installation is set up in a professional way is to make sure the outgoing e-mails use a userfriendly name in its From field.&lt;/p&gt;&#xD;
&lt;p&gt;Here is an example of something you want to avoid. You can see that the e-mail has been sent from support@example.com.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1705_2109.jpg" alt="" width="545" height="95" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Looks kinda...not cool, doesn't it?&lt;/p&gt;&#xD;
&lt;p&gt;How about setting up your CS so that it looks like this instead?&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1707_2105.jpg" alt="" width="542" height="93" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;A bit better, isn't it? How about I tell you it's EASY!&amp;nbsp;In order to make this happen you only need to give your mailbox a well formed name.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1708_2111.jpg" alt="" width="548" height="166" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Just put the friendly name in parentheses behind the e-mail address, like shown above,&amp;nbsp;and you are good to go!&lt;/p&gt;</description><a10:updated>2012-04-23T19:56:36+02:00</a10:updated></item><item><guid isPermaLink="false">5ef4074c-9086-41a1-ba2e-0ccbadc2598a</guid><link>http://devnet.superoffice.com/Blog/?entryId=807</link><author>frode@enkelt.no</author><title>Adding a Requests pane in your diary using Custom Archive Provider</title><description>&lt;p&gt;Hey, did you know that it is possible to add new tabs in the Sales &amp;amp; Marketing client by just dropping a .xml file in a magic folder?&lt;/p&gt;&#xD;
&lt;p&gt;Here is an example where we show the associates active Customer Service tickets in Sales &amp;amp; Marketing.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1697_2089.jpg" alt="" width="578" height="499" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In a standard Sales &amp;amp; Marketing installation you only have the first two tabs. The third one, Requests, is added here.&lt;/p&gt;&#xD;
&lt;p&gt;To accomplish this you need to create a subfolder under your "SuperOffice 7 Windows" folder called "SoCrm Custom Archives", and add your .xml file to it.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1698_2091.jpg" alt="" width="612" height="133" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;I'll not go into the details here on how to create the XML file - Conrad does a much better job than me in the article "&lt;a href="/Developer/Articles/?clubId=3&amp;amp;entryid=1465"&gt;How to create custom archives (...)&lt;/a&gt;"&amp;nbsp;or in the blogpost "&lt;a href="/Blog/?entryId=799"&gt;Developing custom archives for Win?&lt;/a&gt;".&lt;/p&gt;&#xD;
&lt;p&gt;You can also view the &lt;a href="/Developer/Videos/Video-Player/?clubId=3&amp;amp;videoId=109&amp;amp;categoryId=65"&gt;video of Tonys talk at Expander World 2011&lt;/a&gt;.&lt;/p&gt;&#xD;
&lt;p&gt;In the example in the screenshot at the top I used the following XML, and saved it as DiaryTicket.config.&lt;/p&gt;&#xD;
&lt;pre class="brush: xml;light: true; fontsize: 100; first-line: 1; "&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&#xD;
&amp;lt;archives&amp;gt;&#xD;
  &amp;lt;!-- DiaryTicket:  --&amp;gt;&#xD;
  &amp;lt;archive providername="ticket" guiname="diaryticket" hostname="DiaryArchive"&amp;gt;&#xD;
    &amp;lt;custom &#xD;
      storagekey="DiaryTicket"&#xD;
      windowname="[SR_ARCHIVE_TICKETS]" &#xD;
      protocol="diaryticket" &#xD;
      tooltip="My tickets" &#xD;
      &amp;gt;&#xD;
    &amp;lt;/custom&amp;gt;&#xD;
    &amp;lt;view columnspacer="false" debugcolumns="true" columnheader="true" reconfigure="true" fielddataviewer="true"&amp;gt;&amp;lt;/view&amp;gt;&#xD;
    &amp;lt;toolbar export="true" countinfo="true" liveupdate="false"&amp;gt;&amp;lt;/toolbar&amp;gt;&#xD;
    &amp;lt;live contact="true" person="true"&amp;gt;&amp;lt;/live&amp;gt;&#xD;
    &amp;lt;columns&amp;gt;&#xD;
      &amp;lt;column name="ticketId" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="createdAt" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="lastChanged" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="title" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="status" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="customer/personContact/name" default="true"/&amp;gt;&#xD;
      &amp;lt;column name="customerName" default="true" /&amp;gt;&#xD;
      &amp;lt;column name="person/fullName" default="true" displaytypeoverride="navigator"/&amp;gt;&#xD;
      &amp;lt;column name="ejCategory/name" default="true"/&amp;gt;&#xD;
    &amp;lt;/columns&amp;gt;&#xD;
  &amp;lt;/archive&amp;gt;&#xD;
&amp;lt;/archives&amp;gt;&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;Enjoy!&lt;/p&gt;</description><a10:updated>2012-04-18T19:42:13+02:00</a10:updated></item><item><guid isPermaLink="false">64d269af-8df6-438c-9b8e-27cdb123e746</guid><link>http://devnet.superoffice.com/Blog/?entryId=806</link><author>Christian.Falch@superoffice.com</author><title>NetServer API: Creating users that can log in to the client</title><description>&lt;p&gt;When working with an external web service I was faced with the task of creating a new user that could log in to the web client. I had information about the user&amp;rsquo;s company name, email and phone (in addition to his/her name of course).&lt;/p&gt;&#xD;
&lt;p&gt;Doing this using the NetServer Service APIs wasn&amp;rsquo;t hard at all. The biggest problem was the fact that I only had the name of the user&amp;rsquo;s company, not the Id &amp;ndash; the ContactAgent does not have a GetContactByName-method &amp;ndash; so I chose to use row objects to get the user&amp;rsquo;s company:&lt;/p&gt;&#xD;
&lt;pre&gt;	var byNameSearch = new ContactRows.CustomSearch();&#xD;
	byNameSearch.Restriction = byNameSearch.TableInfo.Name.Equal(&#xD;
		S.Parameter(contactName));&#xD;
&#xD;
	ContactRows byNameResults = ContactRows.GetFromCustomSearch(byNameSearch);&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;This query should (and must) return one and only one row, so I add my own sanity check before moving on:&lt;/p&gt;&#xD;
&lt;pre&gt;	if(byNameResults.Count == 1)&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;Now I can create my person using the NetServer PersonAgent and set its first and last name.&lt;/p&gt;&#xD;
&lt;pre&gt;	// Create person&#xD;
	PersonEntity person = personAgent.CreateDefaultByContactId(contactId);&#xD;
	// Set name&#xD;
	person.Firstname = firstname;&#xD;
	person.Lastname = lastname;&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;I&amp;rsquo;d like to add phone and email as well, this is easy using the entity&amp;rsquo;s properties directly:&lt;/p&gt;&#xD;
&lt;pre&gt;	person.Emails = new EntityElement[]{ new EntityElement(){Value=email} };&#xD;
	person.MobilePhones = new EntityElement[]{ new EntityElement(){Value=phone}};&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;I&amp;rsquo;m now ready to save my person:&lt;/p&gt;&#xD;
&lt;pre&gt;	person = personAgent.SavePersonEntity(person);&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;Ok. So now I have a new person connected to my company, and I should be ready to create a user that is able to log in to using the client. Starting with a UserAgent I can create a new user from the newly added person:&lt;/p&gt;&#xD;
&lt;pre&gt;	User user = userAgent.CreateDefaultUserFromUserTypeAndPersonId(&#xD;
		UserType.InternalAssociate, person.PersonId);&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;The new user must have a set of regular credentials:&lt;/p&gt;&#xD;
&lt;pre&gt;	user.Credentials = new Credential[]{&#xD;
		new Credential(){&#xD;
			Type=new CredentialType(){Type="CRM5/PASSWORD"}, &#xD;
			Value = pwd&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&#xD;
	};&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;In addition I need to grant the user login rights by activating the user&amp;rsquo;s relevant licenses, in this case &amp;ldquo;superoffice.web&amp;rdquo; and &amp;ldquo;superoffice.user&amp;rdquo; (superoffice.web depends on superoffice.user):&lt;/p&gt;&#xD;
&lt;pre&gt;	user.GetModuleLicenseLink(&#xD;
		SuperOffice.License.SoLicenseNames.Web).Assigned = true;&#xD;
&#xD;
	user.GetModuleLicenseLink(&#xD;
		SuperOffice.License.SoLicenseNames.User).Assigned = true;&#xD;
	&lt;/pre&gt;&#xD;
&lt;p&gt;Save the user, and I&amp;rsquo;m done!&lt;/p&gt;&#xD;
&lt;pre&gt;userAgent.SaveUser(user);&lt;/pre&gt;&#xD;
&lt;p&gt;Thanks for &amp;ldquo;watching&amp;ldquo;&lt;/p&gt;</description><a10:updated>2012-04-19T13:56:30+02:00</a10:updated></item><item><guid isPermaLink="false">68af21f0-7afe-4f1c-a2fb-c25d1d9fecf1</guid><link>http://devnet.superoffice.com/Blog/?entryId=805</link><author>Kenneth.Knashaug@Superoffice.no</author><title>Converter</title><description>&lt;p&gt;I recomend everyone who&amp;nbsp;are going to upgrade from eJournal 4.x to Seven to make sure that there are no deleted companies related to contacts in the source (old DB). If so you can end up with several tickets with no contact related after the converting job is done!&lt;/p&gt;&#xD;
&lt;p&gt;Be aware :)&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><a10:updated>2012-04-17T14:03:13+02:00</a10:updated></item><item><guid isPermaLink="false">77fc311d-a495-4543-8b1d-0e19484b955d</guid><link>http://devnet.superoffice.com/Blog/?entryId=804</link><author>Kenneth.Knashaug@Superoffice.no</author><title>Converting from eJournal 4.x to Seven</title><description>&lt;p&gt;Before starting the converter it is important to be sure to manually delete all extratables in the SuperOffice database. This is typcally an issue where you've done a testupgrade and are going to use the same database as the production environment at a later time. (DBClient will not remove extratables for you)&lt;/p&gt;&#xD;
&lt;p&gt;If you start the converter without manually deleting these tables you can be sure to get a surprise after you have done the upgrade and start Customer Service for the first time :)&lt;/p&gt;</description><a10:updated>2012-04-11T12:28:05+02:00</a10:updated></item><item><guid isPermaLink="false">4da42dea-f460-4007-90b4-ee4be475f9c5</guid><link>http://devnet.superoffice.com/Blog/?entryId=803</link><author>Hans.Wilhelmsen@Superoffice.no</author><title>Tracking deleted entities in SuperOffice. Better!</title><description>&lt;p&gt;Hey everyone!&lt;/p&gt;&#xD;
&lt;p&gt;Please be gentle as this is my first blog here on Devnet :)&lt;/p&gt;&#xD;
&lt;p&gt;Deleting contacts and contact persons can be a nuisance, especially if they're not intended. This is often followed by backups and trying to find out what/who/when did it.&lt;/p&gt;&#xD;
&lt;p&gt;After having talked to countless of customers whom have had entities deleted in SuperOffice by mistake I've always wondered why tracking it had to be done through searching in the TravelTransactionLog (if you're lucky and it's actually turned on).&lt;/p&gt;&#xD;
&lt;p&gt;I'm aware that the SDK contains examples of how to deal with this by putting deleted people into Projects, but sometimes you just wanted it written down in an old skool log.&lt;/p&gt;&#xD;
&lt;p&gt;There is also most certainly tons of things that can be done better and possibly easier, but I'm fairly new to SuperOffice scripting, so I'll gladly take constructive critisism.&lt;/p&gt;&#xD;
&lt;p&gt;There's not much commenting going on in this script, so feel free to ask if theres anything you're curious about.&lt;/p&gt;&#xD;
&lt;p&gt;The script is currently configured to log everything deleted to C:\SO_ARC\deleted.txt, but this is easily edited.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;pre class="brush: vb;fontsize: 75; first-line: 1; "&gt;Sub OnContactBeforeDelete(id)&#xD;
&#xD;
Dim CountMembers&#xD;
CountMembers = CurrentContact.GetPersons().Count&#xD;
&#xD;
Dim objFSO, objFolder, objShell, objTextFile, objFile&#xD;
Dim strDirectory, strFile, strText&#xD;
strDirectory = "C:\SO_ARC\DATA"&#xD;
strFile = "\deleted.txt"&#xD;
userid = database.userassociateid&#xD;
strText = DateAdd("s",0,Now()) &amp;amp; " Contact: " &amp;amp; currentcontact.name &amp;amp; " with " &amp;amp; CountMembers &amp;amp; " contact person(s) was deleted by User: " &amp;amp; database.getassociate(userid).fullname&#xD;
&#xD;
&#xD;
Set objFSO = CreateObject("Scripting.FileSystemObject")&#xD;
&#xD;
&#xD;
If objFSO.FolderExists(strDirectory) Then&#xD;
   Set objFolder = objFSO.GetFolder(strDirectory)&#xD;
Else&#xD;
   Set objFolder = objFSO.CreateFolder(strDirectory)&#xD;
End If&#xD;
&#xD;
If objFSO.FileExists(strDirectory &amp;amp; strFile) Then&#xD;
   Set objFolder = objFSO.GetFolder(strDirectory)&#xD;
Else&#xD;
   Set objFile = objFSO.CreateTextFile(strDirectory &amp;amp; strFile)&#xD;
End If &#xD;
&#xD;
set objFile = nothing&#xD;
set objFolder = nothing&#xD;
&#xD;
Const ForAppending = 8&#xD;
&#xD;
Set objTextFile = objFSO.OpenTextFile _&#xD;
(strDirectory &amp;amp; strFile, ForAppending, True)&#xD;
&#xD;
&#xD;
objTextFile.WriteLine(strText)&#xD;
objTextFile.Close&#xD;
&#xD;
&#xD;
End Sub&#xD;
&#xD;
&#xD;
&#xD;
Sub OnPersonBeforeDelete(id)&#xD;
Dim objFSO, objFolder, objShell, objTextFile, objFile&#xD;
Dim strDirectory, strFile, strText&#xD;
strDirectory = "C:\SO_ARC\DATA"&#xD;
strFile = "\deleted.txt"	&#xD;
userid = database.userassociateid&#xD;
strText = DateAdd("s",0,Now()) &amp;amp; " Person: " &amp;amp; database.getperson(id).firstname &amp;amp; " " &amp;amp; database.getperson(id).lastname &amp;amp; " was deleted by User: " &amp;amp; database.getassociate(userid).fullname&#xD;
&#xD;
&#xD;
Set objFSO = CreateObject("Scripting.FileSystemObject")&#xD;
&#xD;
&#xD;
If objFSO.FolderExists(strDirectory) Then&#xD;
   Set objFolder = objFSO.GetFolder(strDirectory)&#xD;
Else&#xD;
   Set objFolder = objFSO.CreateFolder(strDirectory)&#xD;
End If&#xD;
&#xD;
If objFSO.FileExists(strDirectory &amp;amp; strFile) Then&#xD;
   Set objFolder = objFSO.GetFolder(strDirectory)&#xD;
Else&#xD;
   Set objFile = objFSO.CreateTextFile(strDirectory &amp;amp; strFile)&#xD;
End If &#xD;
&#xD;
set objFile = nothing&#xD;
set objFolder = nothing&#xD;
&#xD;
' 8 = append text&#xD;
Const ForAppending = 8&#xD;
&#xD;
Set objTextFile = objFSO.OpenTextFile _&#xD;
(strDirectory &amp;amp; strFile, ForAppending, True)&#xD;
&#xD;
&#xD;
objTextFile.WriteLine(strText)&#xD;
objTextFile.Close&#xD;
&#xD;
&#xD;
End Sub&lt;/pre&gt;&#xD;
&lt;p class="brush: vb;fontsize: 75; first-line: 1; "&gt;This script should generate the following log when deleting a company with 4 contact persons in SuperOffice:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;11.04.2012 09:33:17 Contact: Test Company with 4 contact person(s) was deleted by User: Hans Wilhelmsen&lt;br /&gt;11.04.2012 09:33:17 Person: Person1 was deleted by User: Hans Wilhelmsen&lt;br /&gt;11.04.2012 09:33:17 Person: Person2 was deleted by User: Hans Wilhelmsen&lt;br /&gt;11.04.2012 09:33:17 Person: Person3 was deleted by User: Hans Wilhelmsen&lt;br /&gt;11.04.2012 09:33:17 Person: Person4 was deleted by User: Hans Wilhelmsen&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;There should be no problem making the log contain more properties details on the entity deleted.&lt;/p&gt;&#xD;
&lt;p&gt;The script can also be found here: &lt;a href="http://snah.no/trackdelete.txt"&gt;http://snah.no/trackdelete.txt&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-04-11T09:50:58+02:00</a10:updated></item><item><guid isPermaLink="false">e851c09e-6b6a-453d-b92c-2c512a406fee</guid><link>http://devnet.superoffice.com/Blog/?entryId=802</link><author>Jennifer.Lund@Superoffice.com</author><title>10 Tips to Outstanding Customer Service</title><description>&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1674_2036.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border: 0px;" title="customer service 510" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1675_2037.jpg" alt="customer service 510" width="246" height="239" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;April is international customer service month.&amp;nbsp; According to &lt;a href="http://www.hyken.com/customer-loyalty-month/" target="_blank"&gt;Shep Hyken&lt;/a&gt;, &amp;ldquo;An amazing customer service experience comes down to this.&amp;nbsp; Sell a product or service that works and be nice to the customer about it.&amp;nbsp; It&amp;rsquo;s that simple.&amp;rdquo;&amp;nbsp; Easy enough to say, maybe a little bit more challenging to put into play from some businesses.&lt;/p&gt;&#xD;
&lt;p&gt;If you&amp;rsquo;re a B2B, here are 10 ideas on how to deliver outstanding customer service and get your customers to &amp;ldquo;shout from the mountaintop&amp;rdquo; about how great you are.&lt;/p&gt;&#xD;
&lt;p&gt;1.&amp;nbsp; &lt;strong&gt;Provide multiple ways for your customers to get in touch with you.&amp;nbsp;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;In today&amp;rsquo;s day and age, it can still be difficult to get in touch with the customer service department just to&amp;nbsp; help you solve a small issue.&amp;nbsp;&amp;nbsp;Providing different ways for customers to easily communicate directly with your business is critical.&amp;nbsp;The goal should be that every customer should be able to reach you via phone, email, chat, web, etc.&amp;nbsp;&amp;nbsp;And make sure they don&amp;rsquo;t have to wait more than is necessary to talk to you.&lt;/p&gt;&#xD;
&lt;p&gt;2.&amp;nbsp; &lt;strong&gt;Acknowledge that you&amp;rsquo;ve received their request&lt;/strong&gt;. Most people will wait on end to try to get a customer service representative on the phone because this inherently means that if they talked to someone this means that the request is being worked on. Unfortunately, this isn&amp;rsquo;t always the case. Whether you receive&amp;nbsp; a request by phone or email or web, send the customer an acknowledgement of the case, including a case number and a contact person. We all like to know that we were heard.&lt;/p&gt;&#xD;
&lt;p&gt;3.&amp;nbsp; &lt;strong&gt;Encourage immediate problem solving with with customers&lt;/strong&gt;. When a customer contacts you with an issue (via one of the channels in #1), get the right people to deal with the issue immediately. Don&amp;rsquo;t waste time by filing the problem for later, or discussing it in another meeting.&amp;nbsp;Customers expect immediate gratification and their expectation should be fulfilled to the best of your ability.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;4.&amp;nbsp; &lt;strong&gt;Never assume the customer remembers what you told them previously.&lt;/strong&gt;&amp;nbsp;Your customers are paying you to help them.&amp;nbsp; And what you deliver is rarely the customer&amp;rsquo;s only focus.&amp;nbsp;Keep track of all your customer&amp;rsquo;s conversations and presume that you will need to refresh their memory on events, key decisions, etc.&amp;nbsp;Help them by sending summaries via email and what actions were taken to help fix the situation.&amp;nbsp;Doing this will increase the effectiveness of your interactions and make your customer feel appreciated.&lt;/p&gt;&#xD;
&lt;p&gt;5.&amp;nbsp; &lt;strong&gt;Never assume you&amp;rsquo;re meeting your customers&amp;rsquo; needs. &lt;/strong&gt;Even if things seem like they might be going well, they might not be. What you don&amp;rsquo;t do in a customer relationship defines you just as much as what you do. Your customers have more to do than simply tell you when you are not doing well, or when you are not meeting expectations. Check-in frequently with your customers to ensure you are meeting their needs, and conduct anonymous customer satisfaction surveys to get additional feedback.&lt;/p&gt;&#xD;
&lt;p&gt;6.&amp;nbsp; &lt;strong&gt;Give them new ideas and inspiration to improve their business.&amp;nbsp;&lt;/strong&gt; A work day is filled with so much to do most people don&amp;rsquo;t have the time to look up and breathe, much less find the time to find new ideas and inspiration.&amp;nbsp;Become a trusted advisor to your customers.&amp;nbsp; Give them tips and tricks to help them get more out of their day or ideas on how to generate or save more money.&amp;nbsp; This is an extra service that you can provide to your customers &amp;ldquo;just because&amp;rdquo; and goes a long way in creating customer loyalty.&lt;/p&gt;&#xD;
&lt;p&gt;7.&amp;nbsp; &lt;strong&gt;Find every opportunity possible to thank your customers for their business.&lt;/strong&gt;&amp;nbsp;Customer loyalty is not a given.&amp;nbsp;&amp;nbsp; Surprise your customers with your gratitude! Every time you send an invoice, visit a customer, or hit a milestone together, you have an opportunity to say thank you. &amp;nbsp;Birthdays and major holidays are a great time to thank you customers for their business.&lt;/p&gt;&#xD;
&lt;p&gt;8.&amp;nbsp; &lt;strong&gt;The customer is always right&lt;/strong&gt;.&amp;nbsp; If you&amp;rsquo;ve missed your customer&amp;rsquo;s expectations, own up to it and then do whatever is necessary to fix it and follow up relentlessly until it&amp;rsquo;s fixed. Once the solution is in place, make sure you regularly follow up to ensure that the solution works and that your customer is satisfied.&amp;nbsp;This same thing applies if you had sold to a customer that you have never sold to before.&lt;/p&gt;&#xD;
&lt;p&gt;9.&amp;nbsp; &lt;strong&gt;Make sure you deliver on your promises.&lt;/strong&gt;&amp;nbsp; Customers want a partner that they can count on.&amp;nbsp;Only make promises that you can keep.&amp;nbsp; Although this can be a challenge, set your customer&amp;rsquo;s expectations low and then work hard to always exceed those expectations.&amp;nbsp;&amp;nbsp; Deliver what you promise to your customers and you will begin to build trust with them.&amp;nbsp; Fail to deliver on what you promise time and time again and watch your relationship erode to nothing.&lt;/p&gt;&#xD;
&lt;p&gt;10.&amp;nbsp; &lt;strong&gt;Understand your customers and their needs.&lt;/strong&gt;&amp;nbsp; It&amp;rsquo;s important not to talk past your customers or try to sell them something that they don&amp;rsquo;t need.&amp;nbsp; Show them that you really care about them by asking good questions. Before you walk into a meeting with them, create a list of &amp;ldquo;top 15-20 questions&amp;rdquo; that you want to ask in order to get a good understanding of them and their business.&amp;nbsp; You don&amp;rsquo;t have to ask all of them, but your forethought and willingness to listen will really go a long way in building rapport and trust.&lt;/p&gt;&#xD;
&lt;p&gt;So here are 10 tips&amp;hellip;read them, discuss them, and make them yours.&amp;nbsp; Even add some of your own.&amp;nbsp; It&amp;rsquo;s important to note that &amp;ldquo;outstanding customer service&amp;rdquo; means being better than average.&amp;nbsp;&amp;nbsp; If your customer service is on par with your competitors, your business is nothing special.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And providing &amp;ldquo;outstanding customer service&amp;rdquo; has to be more than just one time.&amp;nbsp; It needs to be all of the time, day in and day out.&amp;nbsp; Anyone can provide just one day of good customer service.&amp;nbsp; What sets you apart from the others is the level and consistency of great customer service you can provide to your customers.&lt;/p&gt;</description><a10:updated>2012-04-08T13:13:56+02:00</a10:updated></item><item><guid isPermaLink="false">1e2ca262-c9e2-4037-9e05-6c0d82216e49</guid><link>http://devnet.superoffice.com/Blog/?entryId=801</link><author>tony.poole@synergytechnology.co.uk</author><title>Integration to Eloqua</title><description>&lt;p&gt;Hi Everyone&lt;/p&gt;&#xD;
&lt;p&gt;Has anyone integrated SuperOffice to a product called Eloqua, its an online marketing tool for small to large companies and handles the marketing departments requirements from beginning to end.&lt;/p&gt;&#xD;
&lt;p&gt;It's integrated to Sage, Salesforce and Dynamics CRM plus many others and we have had two customers ask if we integrate out of the box?&lt;/p&gt;&#xD;
&lt;p&gt;Can anyone assist with information on this please.&lt;/p&gt;&#xD;
&lt;p&gt;Thanks and have a great easter weekend.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;Tony Poole&lt;/p&gt;</description><a10:updated>2012-04-05T15:44:30+02:00</a10:updated></item><item><guid isPermaLink="false">f03f1215-29cc-481c-93d9-802ee3be76e1</guid><link>http://devnet.superoffice.com/Blog/?entryId=800</link><author>jan.lovfold@superoffice.no</author><title>Light-weight import routine</title><description>&lt;p&gt;Hi Guys!&lt;/p&gt;&#xD;
&lt;p&gt;Have you ever needed to schedule an import of a text-file into S&amp;amp;M? Or do you have a customer that needs to run an unattended import outside opening hours?&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;These are questions I often encountered during my years as a technical consultant. Of course, our import tool in SO Admin has its limitations.. but often it is more than good enough to cover your needs! In those cases it may often be 'over kill' to implement a large import engine to make just a small job once in while. I therefore made this light-weight import script that will be handy to use, if the customer needs are 'light weight'.&lt;/p&gt;&#xD;
&lt;p&gt;But beware.. this will under no circumstances be a replacement for all the lovely 3.party sync engines out there. The script does not provide extensive logging, error handling, &amp;nbsp;a separate GUI or 2-way sync. So if your customer needs to sync large data quantities with ex. an ERP system, you should not use this routine.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;I have split the script into sections, and described its functionality below:&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;First of, we connect to the database, and declare some variables.&lt;/p&gt;&#xD;
&lt;p&gt;The script below is made for SuperOffice 6, so remember to use the SafeCredentials instead, if you want to use this with SuperOffice S&amp;amp;M. (objsodb.login objSODB.SafeCredentials, "")&lt;/p&gt;&#xD;
&lt;p&gt;'---------connect to the database, and log in------------&lt;/p&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;dim objdb&lt;br /&gt;set objdb = CreateObject("superofficedb.database")&lt;br /&gt;dim imp_msg&lt;br /&gt;dim imp_msg_mail&lt;br /&gt;imp_msg = ""&lt;/p&gt;&#xD;
&lt;p&gt;If Not (objDB is Nothing) Then&lt;br /&gt; objdb.login "adm", "adm"&lt;br /&gt;'-------------------------------------------------------&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Now when we are successfully logged in, the import may start. Prior to this you should have your import setup in SuperOffice Admin =&amp;gt; import, and saved the import description file as a .dsc file. The .dsc file has to reside inside the same directory as the import script. As you can see you can make several import description files, and place them all into this section.&lt;/p&gt;&#xD;
&lt;p&gt;'-----------Importerer customers-------------------------&lt;/p&gt;&#xD;
&lt;p&gt;if (objdb.import("B2B_companies.dsc"))=false then&lt;br /&gt; imp_msg = imp_msg &amp;amp; "companies" &amp;amp; vbnewline &lt;br /&gt; end if&lt;/p&gt;&#xD;
&lt;p&gt;if (objdb.import("import_persons.dsc"))=false then&lt;br /&gt;imp_msg = imp_msg &amp;amp; "Persons" &amp;amp; vbnewline &lt;br /&gt;end if&lt;/p&gt;&#xD;
&lt;p&gt;else&lt;/p&gt;&#xD;
&lt;p&gt;imp_msg = "Cannot connect to database"&lt;br /&gt;end if&lt;br /&gt;set objso = nothing&lt;/p&gt;&#xD;
&lt;p&gt;'-------------------------------------------------&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;After the import has completed, we want to check if any of the imports have failed. Our variable imp_msg will be populated with data if any imports have failed, and will then store this information in a new variable, imp_msg_mail (this will be used later on in the script)&lt;/p&gt;&#xD;
&lt;p&gt;Note that the script ONLY warns if the import has failed, but does not give an indication on what row it actually fails on. This is one of the huge weaknesses, and should be concidered before choosing this solution.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;'----------Check if imports have failed/succeeded--------------&lt;br /&gt;if imp_msg="" THEN&lt;br /&gt;'msgbox "B2C import OK!"&lt;br /&gt;imp_msg_mail = "B2B import OK!"&lt;br /&gt;ELSE&lt;br /&gt;'msgbox "F&amp;oslash;lgende import filer feilet:" &amp;amp; vbnewline &amp;amp; imp_msg&lt;br /&gt;imp_msg_mail = "F&amp;oslash;lgende import filer feilet:" &amp;amp; vbnewline &amp;amp; imp_msg&lt;br /&gt;end if&lt;br /&gt;'--------------------------------------------------------------&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;When the import is done, we also want to clean up after us, so that the import directory is ready to receive a new import file. But we want to keep the import file as a history item, so our script will create a DONE folder, move the import file into this folder, and rename it according to the current date.&lt;/p&gt;&#xD;
&lt;p&gt;'----------Move the file to the DONE directory-------------------&lt;br /&gt;dim impdate&lt;br /&gt;impdate = year(date) &amp;amp; Right("0" &amp;amp; month(date) , 2) &amp;amp; Right("0" &amp;amp; day(date) , 2)&lt;br /&gt;Set objFSO = CreateObject("Scripting.FileSystemObject")&lt;/p&gt;&#xD;
&lt;p&gt;if objFSO.fileexists("\\&amp;lt;server&amp;gt;\SuperOffice\SO_Temp\Import\L20043_*.TXT") THEN&lt;br /&gt;objFSO.CreateFolder "\\&amp;lt;server&amp;gt;\SuperOffice\SO_Temp\Import\DONE\Companies_" &amp;amp; impdate&lt;br /&gt;objFSO.MoveFile "\\&amp;lt;server&amp;gt;\SuperOffice\SO_Temp\Import\Companies*.txt" , "\\&amp;lt;server&amp;gt;\SuperOffice\SO_Temp\Import\DONE\Companies_" &amp;amp; impdate&lt;br /&gt;end if&lt;br /&gt;'---------------------------------------------------------&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;At last, we want to tell the correct people that the import was successful (or not). The script simply uses CDO to send the mail (this has to be installed in the server where the script is running)&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;'---------Sending email report---------------------------&lt;br /&gt;EMAILreport_ = 1&lt;br /&gt;Const SMTPServerAddress_ = "&amp;lt;mail server&amp;gt;"&lt;br /&gt;Const RecepientsAddress_ = "it@company.com"&lt;br /&gt;Const FromAddress_ = "no-reply@company.com"&lt;br /&gt;Subject_ = "Import result " &amp;amp; Date()&lt;br /&gt;'If SMTP authentication is required, change SMTPauthentication_ value to 1:&lt;br /&gt;SMTPauthentication_ = 0&lt;br /&gt;Const SMTPuserName_ = "&amp;lt;username"&lt;br /&gt;Const SMTPuserPassword_ = "&amp;lt;password&amp;gt;"&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt; Set objEmail = CreateObject("CDO.Message")&lt;br /&gt; objEmail.From = FromAddress_&lt;br /&gt; objEmail.To = RecepientsAddress_&lt;br /&gt; objEmail.Subject = Subject_&lt;br /&gt; objEmail.TextBody = imp_msg_mail&lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2&lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = SMTPServerAddress_&lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25&lt;br /&gt; If SMTPauthentication_ = 1 Then &lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1&lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = SMTPuserName_&lt;br /&gt; objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = SMTPuserPassword_&lt;br /&gt; End If &lt;br /&gt; objEmail.Configuration.Fields.Update&lt;br /&gt; objEmail.Send&lt;br /&gt;'---------------------------------------------------&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Conclusion:&lt;/p&gt;&#xD;
&lt;p&gt;This is a light weight method of making easy imports, thats it. A simple method, for simple needs.&lt;/p&gt;&#xD;
&lt;p&gt;Happy easter everybody!!&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;/div&gt;</description><a10:updated>2012-04-03T15:05:02+02:00</a10:updated></item><item><guid isPermaLink="false">1cb0e9a4-899e-47ae-93c0-f2ef8121aa19</guid><link>http://devnet.superoffice.com/Blog/?entryId=799</link><author>Conrad.Weyns@superoffice.com</author><title>Developing Custom Archives for Win?</title><description>&lt;p&gt;If you are developping a custom archive for Win, I for one am very curious to learn about it.&lt;br /&gt;Let us know how you are getting on and what your problems/wishes are.&lt;br /&gt;Visit us and give us a demo!&lt;/p&gt;&#xD;
&lt;p&gt;A few utilities are available and may be of some help:&lt;/p&gt;&#xD;
&lt;p&gt;1. Preferences for Fuctions/Enable developer mode for custom archive (SoAdmin only).&lt;br /&gt;Will put up a Archive utils menu in SoCrm.&amp;nbsp;&lt;br /&gt;This will also activate a few extra context menus in all netserver based archives as well as pull in a few debug settings in all archives.&lt;/p&gt;&#xD;
&lt;p&gt;Column-context menu:&lt;br /&gt;&amp;nbsp; &amp;nbsp;- Reconfigure &amp;nbsp;(particularly usefull when trying to make the best out of xml configurations)&lt;br /&gt;&amp;nbsp; &amp;nbsp;- Field data viewer (very usefull as it shows you what the archive control sees/uses of data)&lt;br /&gt;&amp;nbsp; &amp;nbsp;- Show archive details (dialog displaying static info)&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;In the Archive utils menu there is an item named "Show utilities in row context menus".&lt;br /&gt;This will duplicate the 3 items just described in a row context menu.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;2. Hold down Ctrl+Shift key while chosing to Configure columns or sort order will show an extra tab for &amp;nbsp;"Column meta data".&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1663_2014.jpg" alt="" width="612" height="401" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This is currently read only data that will give you an idea of what the archive control think it knows about columns merged with the configuration data from the xml files.&lt;br /&gt;This is always available.&amp;nbsp;&lt;br /&gt;I'd like to be able to use it to turn On/Off hidden columns with.&lt;br /&gt;Win's own "SoCrm Archives.config" file is managable but the config files we share with web, SoArchiveColumnList.config and SoArchiveCriteriaList.config, leave a lot to be desired! (I am dyplomatic now :-)&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;3. Hold down Ctrrl+Shift key when clicking Add criteria mini buttons in Dynamic selections and the Find system will show a Criteria meta data viewer for the target archive.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1664_2016.jpg" alt="" width="612" height="301" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;These are column that a provider can restrict by.&lt;br /&gt;Always availabe and very usefull to get to the bottom of restriction issues.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;4. In 7.1 you can now turn on db sorting in the refresh/cancel phase.&lt;br /&gt;Add dbsorts="true" to the view section of your archive configuration.&lt;br /&gt;But only do so if you know that you can truly sort correctly on all columns with canOrdeBy=true.&lt;br /&gt;This has some convincing advantages.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;There is quite a bit of information at the top of our "SoCrm archives.config" file abour sections and attributes.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Except for the &amp;lt;custom&amp;gt;&amp;lt;/custom&amp;gt; section, you can make changes to all attributes in a configuration, then use the Reconfigure context menu item to force the archive to adopt your changes. Very usefull!&lt;/p&gt;&#xD;
&lt;p&gt;Happy Easter!&lt;br /&gt;/conrad&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><a10:updated>2012-04-02T11:11:29+02:00</a10:updated></item><item><guid isPermaLink="false">a281c358-07a3-44c2-a345-116893bc1432</guid><link>http://devnet.superoffice.com/Blog/?entryId=798</link><author>Jens@superoffice.com</author><title>Mapping SuperOffice users to Active Directory in 7.0 SR3 and 7.1</title><description>&lt;p&gt;The new implementation is based on searching in the Active Directory &amp;ndash; rather than first looking up all groups and then loading all users in the selected group. A set of additional configuration options has been added as well. This configuration is required when the user executing SoAdmin has limited rights to the domain or if there is a complex domain infrastructure in place. This will typically be the case in large organizations, organizations with multiple domain controllers, when using hosting providers or in Citrix environments.&lt;/p&gt;&#xD;
&lt;p&gt;This advanced configuration has to be tweaked manually in the SuperOffice.config file. These settings are not added by default when installing the windows client, so they have to be added manually.&lt;/p&gt;&#xD;
&lt;p&gt;The SuperOffice.config is a SuperOffice NetServer .NET Application Configuration file. Always keep a copy of your SuperOffice.config file before editing and using a tool like Notepad++ that gives syntax highlighting for xml-files is always recommended when editing these files. The editor must be run as administrator when User Account Control (UAC) is enabled.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1641_1986.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1642_1987.jpg" alt="image" width="604" height="460" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The SoAdmin.exe administration client uses user-administration implemented within NetServer. This implementation is plug-in based and the plug-in implementing the Active Directory support is called ActiveDirectoryCredentialPlugin. Two areas of the SuperOffice.config file need to be modified in order to provide detailed configuration for this plugin.&lt;/p&gt;&#xD;
&lt;p&gt;The first part is to declare the existence of this configuration section. This has to be added within the SuperOffice &amp;lt;sectionGroup&amp;gt; declaration. A new section group security and a new section ActiveDirectoryCredentialPlugin has to be added.&lt;/p&gt;&#xD;
&lt;pre&gt;&amp;lt;sectionGroup name="Security"&amp;gt; &#xD;
  &amp;lt;section name="ActiveDirectoryCredentialPlugin" &lt;br /&gt;                type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" &lt;br /&gt;    /&amp;gt; &#xD;
&amp;lt;/sectionGroup&amp;gt; &#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1643_1988.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1644_1989.jpg" alt="image" width="673" height="364" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Secondly, the actual configuration has to be added as well.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1645_1990.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1646_1991.jpg" alt="image" width="673" height="343" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;table border="1" cellspacing="0" cellpadding="0"&gt;&#xD;
&lt;tbody&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="92"&gt;&#xD;
&lt;p&gt;Domain&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;td valign="top" width="549"&gt;&#xD;
&lt;p&gt;The domain to use when looking up users. A value for this need to be provided when this is different from the domain of the logged in user. The domain needs to be provided when logging in as a local user.&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="92"&gt;&#xD;
&lt;p&gt;User&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;td valign="top" width="549"&gt;&#xD;
&lt;p&gt;The user to use when looking up in this domain. This is required when the logged in user has insufficient privileges on the domain.&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="92"&gt;&#xD;
&lt;p&gt;Password&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;td valign="top" width="549"&gt;&#xD;
&lt;p&gt;Required when providing user.&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;tr&gt;&#xD;
&lt;td valign="top" width="92"&gt;&#xD;
&lt;p&gt;Container&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;td valign="top" width="549"&gt;&#xD;
&lt;p&gt;Introduced in in 7.1 RC, see explanation below.&lt;/p&gt;&#xD;
&lt;/td&gt;&#xD;
&lt;/tr&gt;&#xD;
&lt;/tbody&gt;&#xD;
&lt;/table&gt;&#xD;
&lt;p&gt;SuperOffice NetServer uses the Microsoft .NET library System.DirectoryServices.AccountManagement when searching Active Directory. The minimum required permissions to Active Direacory is Read and List content. The best way to verify that the right permissions are available is to use the ADSI Edit Snap-in to MMC.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1647_1992.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; margin-left: 0px; margin-right: 0px; padding-top: 0px; border-width: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1648_1993.jpg" alt="image" width="562" height="389" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;You can select the root note of Active Directory, Properties, Advanced, and Effective Permissions, select the user that is accessing Active Directory and verify that the user has List content and Read permissions.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1649_1994.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1650_1995.jpg" alt="image" width="604" height="558" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;SuperOffice 7.1 (from RC and beyond) has additional improvements. Some of the error messages are replaced by warnings logged by NetServer. Support for specifying container is introduced as well.&lt;/p&gt;&#xD;
&lt;p&gt;Logging warnings to file must be turned on in order to see the warnings produced by NetServer. Logging warnings to file should be the first action if a problem with Active Directory integration is observed.&lt;/p&gt;&#xD;
&lt;p&gt;The first step is to actually make sure that LogWarning is turned on&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1651_1996.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1652_1997.jpg" alt="image" width="673" height="364" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Then the logging to file needs to be turned on to a folder where the logged in user has write permissions.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1653_1998.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1654_1999.jpg" alt="image" width="673" height="364" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;If something goes wrong, like if an invalid user is specified, a log file with today&amp;rsquo;s date will be produced.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1655_2000.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1656_2001.jpg" alt="image" width="654" height="308" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The error message returned from the system will be in this file:&lt;/p&gt;&#xD;
&lt;pre&gt;Level: Warning &#xD;
At: 14:58:50 &#xD;
Element: &#xD;
Message: Logon failure: unknown user name or bad password. &#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;Customers have experienced situations with complex domain infrastructures where the Container property has to be specified as well &amp;ndash; even if the user is to access the domain at root level. The Container can also be used to limit the surface area of active directory made available to SoAdmin.&lt;/p&gt;&#xD;
&lt;p&gt;Limiting users to a particular organization unit can be an example of this.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1657_2002.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1658_2003.jpg" alt="image" width="673" height="241" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;By specifiying the full name of this Organization Unit in the SuperOffice.config file, searches will be restricted to this node.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1659_2004.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/30508/1660_2005.jpg" alt="image" width="673" height="364" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-04-24T15:48:40+02:00</a10:updated></item><item><guid isPermaLink="false">11c42674-8ee4-4981-a72c-7238ba8e2eec</guid><link>http://devnet.superoffice.com/Blog/?entryId=796</link><author>sverre@superoffice.com</author><title>Showing user-defined fields in Customer Service</title><description>&lt;p&gt;Ok, so one of the things we still need to do is to merge together the old SuperOffice version of extra fields (udefs) and the old eJournal version of extra fields/tables. It’s on the TODO list, but it requires some thinking first. Anyway, in case you did not know it, while you wait, it IS possible today to show user-defined fields from Sales &amp;amp; Marketing in Customer Service. This is thanks to the dot-syntax provider in the bottom, which allows you to show fields from any regular join. Let’s say you have an extra field on contact called “Magic”:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1631_1970.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1632_1971.jpg" width="446" height="321"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Now, from the template variable, you can see that this became short string 5, which means it is in the table “UDCONTACTSMALL”, column “string05”. Now, we can edit the profile for viewing companies:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1633_1972.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1634_1973.jpg" width="478" height="249"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Click the wrench key in the top right corner of the card showing company information, which enter the “Edit profile” mode for this UI control. Then, add a new field by entering a label (e.g. “Magic”), and the dot-syntax fieldname (“contact.userdef_id.string05”):&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1635_1974.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1636_1975.jpg" width="476" height="242"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Click “Add” to add the field, and then “Ok” to save the profile. You should now have the regular “View company” screen with the user-defined field like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1637_1976.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1638_1977.jpg" width="473" height="252"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Of course, you could also do this in the “View request” screen, by entering the field as “ticket.cust_id.contact_id.userdef_id.string05”. This could be useful for instance to show whether the related company of the related contact person of the request has a support agreement, or something like that.&lt;/p&gt;</description><a10:updated>2012-03-30T09:06:53+02:00</a10:updated></item><item><guid isPermaLink="false">821fbc3a-1311-4d83-95ae-b5b95f4cccd0</guid><link>http://devnet.superoffice.com/Blog/?entryId=795</link><author>sverre@superoffice.com</author><title>Creating a printable-report of a customer&amp;rsquo;s requests</title><description>&lt;p&gt;A typical need for an account manager when visiting a customer is to bring a list of open or all requests that customer has had &amp;ndash; on paper. There are multiple ways of doing this in CS, but here is a simple example of how such a report can be implemented in ejScript, and then anchored as an extra menu button in the &amp;ldquo;View company&amp;rdquo; screen.&lt;/p&gt;&#xD;
&lt;p&gt;I will create a report which prints all requests and also the messages. Generally, there are two ways of doing this. I could query the requests, and then for each request I could query the messages for that request. This is a clean way of doing it, but not very efficient, since we end up doing lots of queries (depending of the number of requests).&lt;/p&gt;&#xD;
&lt;p&gt;So, a somewhat more complex but much fast approach is to query all messages, left joined with the request fields as well, and then use our StatLib to simplify the iteration when we print the information. This way, we will only make one single query towards the database to get our result.&lt;/p&gt;&#xD;
&lt;p&gt;In order to implement this, you will need &amp;ldquo;Expander tools&amp;rdquo;. Go to &amp;ldquo;System design &amp;gt; ejScript&amp;rdquo;, and create a new script. Give it a good include-name, so that we can easily implement the extra menu for it aftwards. Then, write the following code:&lt;/p&gt;&#xD;
&lt;pre&gt;#setLanguageLevel 3;&lt;/pre&gt;&#xD;
&lt;pre&gt;print("&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;style&amp;gt;\r\n");&lt;br /&gt;print("* { font-family: Verdana; font-size: 12pt; }\r\n");&lt;br /&gt;print("H1 { display: block; background-color: #e0e0e0; font-size: 14pt; }\r\n");&lt;br /&gt;print("H2 { font-size: 12pt; font-weight: bold; text-decoration: underline; }\r\n");&lt;br /&gt;print("&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;\r\n");&lt;br /&gt;String companyId = getCgiVariable("companyId");&lt;/pre&gt;&#xD;
&lt;pre&gt;SearchEngine se;&lt;br /&gt;se.addField("ej_message.ticket_id"); // Col: 0&lt;br /&gt;se.addField("ej_message.id"); // Col: 1&lt;br /&gt;se.addField("ej_message.author"); // Col: 2&lt;br /&gt;se.addField("ej_message.created_at"); // Col: 3&lt;br /&gt;se.addField("ej_message.html_body"); // Col: 4&lt;br /&gt;se.addField("ej_message.body"); // Col: 5&lt;br /&gt;se.addField("ej_message.ticket_id.title"); // Col: 6&lt;br /&gt;se.addField("ej_message.ticket_id.created_at"); // Col: 7&lt;br /&gt;se.addCriteria("ej_message.ticket_id.cust_id.contact_id", &lt;br /&gt;  "OperatorEquals", companyId, "OperatorAnd", 0);&lt;br /&gt;se.addCriteria("ej_message.ticket_id.status", "OperatorLte", "3", &lt;br /&gt;  "OperatorAnd", 0);&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;StatLib sl;&lt;br /&gt;sl.setSearchEngine(se);&lt;br /&gt;sl.addGroup(0, true);&lt;br /&gt;sl.addGroup(1, false);&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;StatResult sr;&lt;br /&gt;sl.execute(sr);&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;for (sr.rewind(); !sr.eof(); sr.next())&lt;br /&gt;{&lt;br /&gt;  if (sr.atGroupBegin(0))&lt;br /&gt;    print("&amp;lt;h1&amp;gt;Request " + sr.getField(0) + " (" + &lt;br /&gt;      DateTime(sr.getField(7)).toString("DD2.MM2.YY4") + "): " + &lt;br /&gt;      sr.getField(6) + "&amp;lt;/h1&amp;gt;");&lt;br /&gt;    print("&amp;lt;h2&amp;gt;" + sr.getField(2) + " wrote at " +&amp;nbsp;&lt;br /&gt;      DateTime(sr.getField(3)).toString("DD2.MM2.YY4 HH24:MI2") + "&amp;lt;/h2&amp;gt;");&lt;/pre&gt;&#xD;
&lt;pre&gt;  String body;&lt;br /&gt;  if (sr.getField(4) != "")&lt;br /&gt;    body = htmlConvToText(sr.getField(4));&lt;br /&gt;  else&lt;br /&gt;    body = sr.getField(5);&lt;br /&gt;  print(body);&lt;br /&gt;}&lt;br /&gt;print("&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;");&lt;/pre&gt;&#xD;
&lt;p&gt;As you can see, this code will list all requests (sorted by id descending) with all messages (sorted ascending) for the company with the id passed in as parameter &amp;ldquo;customerId&amp;rdquo;. We can now create an extra menu for this:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1625_1963.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1626_1964.jpg" alt="image" width="399" height="269" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In the URL field, enter &amp;ldquo;&amp;amp;action=doScript&amp;amp;includeId=company-request-report&amp;amp;companyId=&amp;rdquo;. This is a screenshot from 7.1. If you have an older version, you should prefix that string with &amp;ldquo;/scripts/blogic.exe?_sf=0&amp;rdquo;. You will now get an extra menu at the top of the &amp;ldquo;View company&amp;rdquo; screen like this:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1627_1965.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1628_1966.jpg" alt="image" width="448" height="130" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Clicking the &amp;ldquo;Request report&amp;rdquo; link will open in a new browser window/tab, and show our report:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1629_1967.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1630_1968.jpg" alt="image" width="455" height="412" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-03-29T09:05:08+02:00</a10:updated></item><item><guid isPermaLink="false">250554ca-f109-4d82-b21f-888a96efca14</guid><link>http://devnet.superoffice.com/Blog/?entryId=794</link><author>frode@enkelt.no</author><title>Sending SMS using ejScript</title><description>&lt;p&gt;Hi, this post will show you how to use ejScript to send an SMS to a cellphone.&lt;/p&gt;&#xD;
&lt;p&gt;Before you can send SMS via ejScript you need to configure Customer Service with an SMS account. This is done under Settings-&amp;gt;System-&amp;gt;SMS. Here is an example where I use the Norwegian provider PSWinCom.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1610_1924.jpg" alt="" width="612" height="270" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In its absolutely simplest form you need either four or five lines of ejScript to send an SMS. You can either use the Email class (4 lines) or the Message class (5 lines). Using the Message class is preferred if you also want to log the sent SMS in CS.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1611_1926.jpg" alt="" width="384" height="212" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The scripts above is all you need to send an SMS. Lets use this in a slightly bigger example. We are going to write a script that is going to be executed from a button in the Person(Contact) screen.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1615_1934.jpg" alt="" width="612" height="189" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Go to System Design-&amp;gt;Script and create a new script:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1612_1928.jpg" alt="" width="503" height="590" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This script expects there to be a &amp;amp;personId= in the URL. It will display an errormessage if no personId is given, or if the person does not have a cellphone number.&lt;/p&gt;&#xD;
&lt;p&gt;Next it creates a new Ticket and Message. The ticket and message is populated with some values before they are saved, and the message is sent as SMS.&lt;/p&gt;&#xD;
&lt;p&gt;The last setVariable() call makes sure we refresh the screen.&lt;/p&gt;&#xD;
&lt;p&gt;This script can be executed from a custom button on the person(contact) screen using an Extra menu button. Go to System Design-&amp;gt;Extra menus and add a new item under Contact:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1613_1930.jpg" alt="" width="181" height="244" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The definition for the "Send SMS" button looks like this;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1614_1932.jpg" alt="" width="454" height="246" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Notice that the URL contains an includeId=sendSms. This value must match the Include name of your script.&lt;/p&gt;&#xD;
&lt;p&gt;And that is how you send SMS from ejScript :)&lt;/p&gt;</description><a10:updated>2012-03-25T17:02:12+02:00</a10:updated></item><item><guid isPermaLink="false">81d6956b-b817-40d6-93cb-7b9670db179b</guid><link>http://devnet.superoffice.com/Blog/?entryId=793</link><author>ronny.eriksson@superoffice.se</author><title>List field resizing in S&amp;M Gui...</title><description>&lt;p&gt;&lt;span lang="EN-US"&gt;This is probably a bit of a hot potato but i would like to see if i'm the only one that thinks this is not so very User-friendly.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;So I'm putting this as a blog to see your comments of it.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;Don't know how many of you have looked at it but this is probably the way a new user, and even old users, would handle a width size change of fields in tabs in S&amp;amp;M.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;Let&amp;rsquo;s say you are on the Company card and the Activities tab.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;In the Activity tab you would like to change the width of two fields, the Date field and the Project field.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;So you start by changing the Date field to the size you want by expanding the field to the right like you would in excel. OK that's good, the field is the size you want. But now you got a new problem, the Type field is now to small, since S&amp;amp;M didn't only change the Date field width, it also changed the Type field. So you change the Type field to the size you want and then it is okay again. The Text field next to Type field is still ok in width.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;Now you start to change the Project field, which is next to the Contact field which is next to the Text, Done. Oups, now the Contact field is too small. This is because you have learned that you change the width on the field you expand against and you don't want to change the width of the sales field, which is to the left of the Project field. So now you have to change the Contact field and now it has to be Okay right... No now the Text field is to small...&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;At that time you give up, because you hair is on fire...&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;When you cooled down and after some more fires, you learn that in order to change any field you have to start to by planning the change from the right or left most field in order to be able to change the field in the middle. Talk about time consuming for changing ONE field in a tab.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;I know that this is probably because we don't do Horizontal scrolling in Tabs because all fields must be shown in one area.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;But does it have to be this hard to change one or specially two fields.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span lang="EN-US"&gt;There has to be a better way of handling this, or isn't it, is this really the best way to handle width size changes on fileds in tabs in S&amp;amp;M?&lt;/span&gt;&lt;/p&gt;</description><a10:updated>2012-03-20T13:46:10+01:00</a10:updated></item><item><guid isPermaLink="false">1fb94116-8a96-469f-8654-57d4ddd6f928</guid><link>http://devnet.superoffice.com/Blog/?entryId=792</link><author>hc@superoffice.com</author><title>CRM Online hits the Sky!</title><description>&lt;p&gt;First of all, let me congratulate Tony and Devnet with this new site. Easy to navigate in, easy to read and easy to write and a great tool to continue the work of growing the SuperOffice partner community.&lt;/p&gt;&#xD;
&lt;p&gt;Then a few words about how we are doing with SuperOffice CRM Online. As you might already know, the new international business unit called SuperOffice Online AS is now formally registered. Our goal is to grow&amp;nbsp;from 700 current customers up to 5.000 customer in our home markets - The Nordics, Germany, Switzerland, Benelux and the UK. By building a strong and dedicated Online team we can together with RnD and other SuperOffice subsidiaries, build a strong offering to the market with&amp;nbsp;saas-CRM og CRM in the Cloud.&lt;/p&gt;&#xD;
&lt;p&gt;As of now, we have Sille Antonsen (formerly QuestBack) on board as a Business Developer for improving our Online services. She is posting great blog posts already on DevNet, as you can see. We have experienced SuperOffice consultant Gunhild Moen Skaberg on Customer Care to help us create great videos and improve our customer experience. We have a&amp;nbsp;young and energetic&amp;nbsp;sales team for Norway with Magnus Thingn&amp;aelig;s (team leader), Veronica Falch and J&amp;oslash;rgen Bordvik. Then&amp;nbsp;this month we have gone international with Vinh Ma as Online Sales for Denmark and Duncan Kennedy as Online Sales for the UK.&lt;/p&gt;&#xD;
&lt;p&gt;We are now looking for Online Sales for Benelux, Sweden and Germany in addition to an Online Makreting resource. All positions based in Oslo. &amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;The last couple of months RnD, Operations and Visma IT have put a lot of effort in getting CRM Online both stable and up to speed. I am now convinced that reaching our next goal will be reached and on the way we will have fun. As a partner of SuperOffice we are ready to support you in your effort in finding, cathcing and keeping more Online customers. It is and will be, well worth the effort.&lt;/p&gt;&#xD;
&lt;p&gt;Feel free to visit us in "the Cloud" next you come by SuperOffice HQ in Oslo.&lt;/p&gt;</description><a10:updated>2012-03-20T00:24:16+01:00</a10:updated></item><item><guid isPermaLink="false">aca47cbd-e77f-456f-bf6f-401b47b630f9</guid><link>http://devnet.superoffice.com/Blog/?entryId=791</link><author>Sille.Antonsen@superoffice.com</author><title>Every day choices</title><description>&lt;p&gt;During workhours we have to make a lot of choices. When I am asked to make a choice, am I fully aware of all my options and possible outcomes? Or should I even reflect on if I have to make the choice at all?&lt;/p&gt;&#xD;
&lt;p&gt;I enjoy watching and listening to &lt;a href="http://www.ted.com" target="_blank"&gt;TED&lt;/a&gt;, a &amp;ldquo;nonprofit devoted to Ideas worth Spreading&amp;rdquo;. They consider themselves &amp;ldquo;a global community (&amp;hellip;) welcoming people from every discipline and culture who seek a deeper understanding of the world&amp;rdquo;. From time to time I come across talks that inspires me, makes me think of my day-to-day routines a bit differently or just allows me to see the things I care about in a slightly new perspective. One of the talks that enlightened me was Sheena Iyengar and the way she talks about &amp;ldquo;&lt;a href="http://www.ted.com/talks/sheena_iyengar_choosing_what_to_choose.html" target="_blank"&gt;How to make choosing easier&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;&#xD;
&lt;p&gt;When Iyengar asks if I know how many choices I make a day, it struck me that I most likely really don&amp;rsquo;t pay attention. Am I really aware why I make the choices I make, why I choose to make the choices that I make and why I let myself be pushed into all the situations where I think I have to make choices?&lt;/p&gt;&#xD;
&lt;p&gt;I have to admit that I am not very observant when it comes to choosing, either personally and professionally. And based on that not so pleasant conclusion about myself, it becomes quite clear to me that being choosy about choosing has its clear upsides.&lt;/p&gt;&#xD;
&lt;p&gt;In a more perfect world, I think I actually would prefer to be faced with less alternatives, more well formulated options and clear focus on the upsides for me to make a choice.&lt;/p&gt;&#xD;
&lt;p&gt;As I work with CRM, where customer relationship management is the key, how can we learn something from Sheena Iyengar and her way of pointing out how choice overload reduces engagement, decision quality and satisfaction? If I for instance work with a sales process where I want to point out the clear upsides of choosing SuperOffice CRM Online, how should I formulate the arguments to make it easy for a potential customer to choose to become a loyal evangelist?&lt;/p&gt;&#xD;
&lt;p&gt;When you are faced with too many choices (choice overload), people actually delay to choose, or simply hurry up and &amp;ldquo;just choose something&amp;rdquo; even though it might not the best choice. And we even end up choosing the things that will make us less satisfied. Or worst of all, we choose not to choose.&lt;/p&gt;&#xD;
&lt;p&gt;We will actually choose against our own best interest&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;So, how can we learn from this and &amp;ldquo;simply&amp;rdquo; make it easier for your potential customers to choose the service you are selling? According to Iyengar you can:&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;Cut&lt;br /&gt;Less is more. In your sales pitch or marketing message, practice to explain the difference between this and that. If you cannot explain it or there simply is no real value in the difference, cut!&lt;/li&gt;&#xD;
&lt;li&gt;Concretize&lt;br /&gt;Make it more real, exemplify pain and solutions and make people imagine the upside by choosing what you recommend.&lt;/li&gt;&#xD;
&lt;li&gt;Categorize&lt;br /&gt;Everyone finds it is simpler to think in relevant categories. So, instead of showing everything your service can do, you can categorize features, functionalities and options.&lt;/li&gt;&#xD;
&lt;li&gt;Condition for complexity&lt;br /&gt;Gradually increase complexity when presenting value and solutions. Start with less choices and then increase. Start off easy and teach the potential customer how to choose.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;Lesson learned from this? I don&amp;rsquo;t work directly with sales&amp;hellip; I don&amp;rsquo;t have to make the cold calls. It is easy for me to say &amp;ldquo;just focus on value when talking to prospects&amp;hellip;&amp;rdquo;. Still, the areas pointed out by Iyengar are valid in all kinds of customer communication.&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Work to reduce the choice overload problem when communicating with leads, suspects, prospects and customers. This is just as important in a customer meeting as it is in a cold call, for marketing and for product development. It is even important when communicating with employees.&lt;/li&gt;&#xD;
&lt;li&gt;Try not to enter the feature functionality discussion since this will increase the number of details in a choice. Rather try to focus on the value of solving their pains and needs.&lt;/li&gt;&#xD;
&lt;li&gt;Listen to the customer and concretize. This might actually speed up the process and make it simpler for the customer to picture how they will use what you sell.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;The key is to be choosy about choosing. Sometimes we need to be choosy on behalf of others.&lt;/p&gt;</description><a10:updated>2012-03-20T08:42:28+01:00</a10:updated></item><item><guid isPermaLink="false">97f19a97-e46a-4e0c-85b8-8378fe77c73b</guid><link>http://devnet.superoffice.com/Blog/?entryId=790</link><author>Vidar.Utne@SuperOffice.com</author><title>7.1 Beta 3 Upgrade - R&amp;D is getting a hang on the installers :-)</title><description>&lt;p&gt;I know there is partners and customers out in the SuperOffice Community that stil has not touched 7.1.&amp;nbsp; I must admit that the upgrade to 7.1 Beta 2 was a bit of a challenge - but I must also tell that the upgrade to Beta 3 was one of the smootest upgrades I have ever gone trough (and I have been trough a few)&lt;/p&gt;&#xD;
&lt;p&gt;Windows version was a few next clicks and a restart, and the upgrade of the 7.1 Beta3 for web was so easy I think my mother could have performed it.&amp;nbsp; Start the instalation, confirm the settings and an IIS reset.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;There is still some challenges beeing a beta customer (SuperOffice tries to be as early as possible in testing our own software in production) , but at present we got most of our 3rd party products up and running - and there is only a few new issues coming up.&lt;/p&gt;&#xD;
&lt;p&gt;With 7.1 the performance of the SuperOffice product&amp;nbsp;has improved quite a lot, and especially the Mail link is a fantastic improvment.&amp;nbsp; Some users need some time to get used to the Maillink beeing completly in Outlook.&amp;nbsp; We also see that users are not used to adjusting the preferences themself, so we need to improve a bit on training and documentation to the end users.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><a10:updated>2012-03-15T23:48:32+01:00</a10:updated></item><item><guid isPermaLink="false">7f314014-d600-44ec-b4dd-5c89ff39030b</guid><link>http://devnet.superoffice.com/Blog/?entryId=789</link><author>a.hesselberth@superoffice.com</author><title>Windows Authentication on satellite with different domains</title><description>&lt;p&gt;Yesterday I had an interesting case. One of our larger satellite customers called me. They have a central database on domain A and a Satellite on Domain B and another satellite on Domain C.&lt;/p&gt;&#xD;
&lt;p&gt;For the Central users they activated Windows Authentication so SuperOffice is starting automatically. They want the same for the satellite users. This can be very challenging because you can't modify the users on the satellite and you can't see the Active directory from Domain B and C in the admin from the central database. I told the customer that this will be very difficult and probably impossible.&lt;/p&gt;&#xD;
&lt;p&gt;After one hour I called the customer back to give him a status update and he told me he managed to solve this! (I was flabbergasted). He installed the admin client from the central database on a PC in Domain B and C. After this he started the admin and selected the satellite users. Because he was able to see the Active Directory from Domain B and C he was able to connect the AD users to the SuperOffice users.&lt;/p&gt;&#xD;
&lt;p&gt;It is great to have these kind of users who think outside the box and it is fun to learn these tricks from the customer.&lt;/p&gt;</description><a10:updated>2012-03-15T11:30:25+01:00</a10:updated></item><item><guid isPermaLink="false">7cc02b41-6bb3-437a-b015-56236cab453b</guid><link>http://devnet.superoffice.com/Blog/?entryId=788</link><author>Sille.Antonsen@superoffice.com</author><title>Standardized customer program &amp;ndash; without losing the personal touch</title><description>&lt;p&gt;&lt;strong&gt;Ever heard Sales talk about the importance of having personal contact with prospects and customers in order to get the sale and keeping customers? And at the same time heard the argument that there just is not enough time to both chase new customers and take care of existing customers? &lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Perhaps Sales should be relieved from the pressure of following up all the time, and rather we should create standardized customer programs to follow up customers on a regular basis? That way we could ensure that all customers get relevant and timely information. There is just one challenge to this. The personal touch achieved in communication between Sales and the customers can be a very important factor when working to reduce churn and increasing customer intimacy. &lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Then again &amp;ndash; why not do both? Create a customer program and leave room for personal communication!&lt;/p&gt;&#xD;
&lt;p&gt;A recent blog post on &lt;a href="http://www.friendsoffeedback.com/how-to-get-rid-of-your-customers/" target="_blank"&gt;Friends of Feedback&lt;/a&gt;&amp;nbsp;refers from a study conducted by Rockefeller Cooperation the importance of caring about your customers in order to increase retention.&lt;/p&gt;&#xD;
&lt;p&gt;SuperOffice Online, as many companies, focuses daily on customer care and adapting business processes by using the company resources in the most efficient manner. This can be a challenge for more reasons that can be mentioned here, but two things stand out as important to focus on:&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Standardize the sales process&lt;/strong&gt;&lt;br /&gt;Setting the expectations in a sales process is vital for a long term successful customer experience. Use a standardized sales process with a communication plan, templates for content and time frames and automated tasks for following up to make it easier for your sales organization to succeed selling. You can use SuperOffice to build a sales guide for this.&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Standardize the customer program&lt;br /&gt;&lt;/strong&gt;Follow up the expectations set during the sales process to ensure a continuous successful customer experience. You can continue the sales guide in SuperOffice also to include the standardized customer program. Then you can create and include a personalized communication plan, content templates and schedule task to make it simpler for your customer care department to follow up.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;It is more or less impossible to argue that implementing the two steps above is a bad idea, and especially the first step is often used in sales organizations with great success.&lt;/p&gt;&#xD;
&lt;p&gt;My experience is that step two a bit harder to implement in a sales focused organization. Is it because it is more &amp;ldquo;Marketing&amp;rdquo; than &amp;ldquo;Sales&amp;rdquo;? Is it because it is not as easy to see a direct income from activities that don&amp;rsquo;t generate a sale? Is it because the responsibility and reporting is removed from sales and handed over to a customer care department?&lt;/p&gt;&#xD;
&lt;p&gt;Whatever the reason is &amp;ndash; it is important to focus on customer care and customer intimacy. Make your customers feel special and make yourself available for your customers.&lt;/p&gt;&#xD;
&lt;p&gt;This can be achieved if your company has a customer care program, and by standardizing a program you ensure that all customers are followed up and taken care of. And there is another potential huge upside to this.&lt;/p&gt;&#xD;
&lt;p&gt;If your Sales staff is relieved of all the day-to-day stress to follow up by executing the customer program, they can use their energy on the personal touch, the extras, the finesse and surprises they are able to provide to customers. If your Sales team is happy, your customers will be happy and &amp;ldquo;&lt;a href="http://www.deliveringhappiness.com/focus-on-making-your-staff-happy/" target="_blank"&gt;People work best when they are happy&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;&#xD;
&lt;p&gt;There may be no need to say this &amp;ndash; but remember to document all steps in the sales process and customer care program in your CRM system. Only by doing this you will be able to reveal the areas in need of improvement.&lt;/p&gt;</description><a10:updated>2012-03-13T15:14:15+01:00</a10:updated></item><item><guid isPermaLink="false">eb3d43a7-abdf-470c-b058-8a0f5029b358</guid><link>http://devnet.superoffice.com/Blog/?entryId=785</link><author>sverre@superoffice.com</author><title>Using email filters to process emails with a fixed format</title><description>&lt;p&gt;A typical scenario for using CS could be that you have a contact-us web form somewhere (or any other software driven service) which sends email into CS. Now, by default, the created request in CS will be connected to a customer based on the originating email address of the email, which easily can be something like &lt;a href="mailto:&amp;ldquo;webform@liberty.com"&gt;&amp;ldquo;webform@liberty.com&lt;/a&gt;&amp;rdquo;. Clearly, this is not what we want. We want the request to be connected to the customer who filled out the form, and supplied his or her name and email address in the form. Fortunately, this is possible to do with email filters, without having to do any programming.&lt;/p&gt;&#xD;
&lt;p&gt;Lets say that the inbound email has the following format, where each line is filled out with a field from the form:&lt;/p&gt;&#xD;
&lt;div style="font-family: 'Courier New'; border: black solid 1px;"&gt;Name: Sverre Hjelm&lt;br /&gt;Email: sverre.hjelm@superoffice.com&lt;br /&gt;Phone: +47 90 99 41 48&lt;br /&gt;Message: I would like to be contacted regarding your software.&lt;/div&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Now, we want our email filter to find these lines, and update/insert information in our database with the values to the right. In order to process these lines and extract the section we want, we need to use something called Regular Expressions (or RegExp&amp;rsquo;s for short). Regular expressions can be insanely complicated, but in this example they will be quite simple. For more information on RegExp&amp;rsquo;s, there is a lot of information available on the net. In short, RexExp&amp;rsquo;s allow you to search for text matching a given pattern, and extract parts of that text. In our example above, we would like to search for lines starting with &amp;ldquo;Name: &amp;ldquo;, and then extract whatever follows on that line.&lt;/p&gt;&#xD;
&lt;p&gt;To create a new Email filter, go to Settings &amp;gt; E-mail &amp;gt; E-mail filters and click &amp;ldquo;New e-mail filter&amp;rdquo;. On the first page, you must give your filter a description, a prioritiy and a searchstring. The priority is used when multiple filters match on an email. We will start with the filters with priority 1, then 2, etc. When a filter matches against the incoming email, it will be executed, and the search stops. No other filter will be executed. In our case, we could choose &amp;ldquo;All incoming email&amp;rdquo; if we had a dedicated mailbox for these emails. Otherwise, we need to find our emails somehow. The easiest way is probably to match on the subject line, which normally will be predictable and constant for all emails coming from our form. We do this by searching for &amp;ldquo;Subject: &amp;hellip;&amp;rdquo; in the email headers:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1560_1798.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1561_1799.jpg" alt="image" width="529" height="142" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Now we have a filter which will execute whenever we receive an email from our web form. The second part is to specify what we want to execute, i.e. how we want to process this email. First of all, we would like to connect this request to any matching customer in the database with the supplied e-mail address. The regular expression for extracting the e-mail address from the message content above is this: &amp;ldquo;^Email: (.*)&amp;rdquo;. The leading carret tells us to match beginning-of-line, which will help us with not getting any false positives. The &amp;ldquo;(.*)&amp;rdquo; section will find any text on the line and extract that. To use this text to look up the customer, we must specify this on the pane named &amp;ldquo;Set links&amp;rdquo; on the filter:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1562_1800.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1563_1801.jpg" alt="image" width="445" height="85" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Now, if a customer with the given address (&lt;a href="mailto:&amp;ldquo;sverre.hjelm@superoffice.com"&gt;&amp;ldquo;sverre.hjelm@superoffice.com&lt;/a&gt;&amp;rdquo; in this example) exists, then the request will be connected to that customer. However, if the customer does not exist, then we will be connected to a new/empty customer. In order to set the name, phone and address of that new customer card with the values in the email, we must use the &amp;ldquo;Set values&amp;rdquo; tab:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1564_1802.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1565_1803.jpg" alt="image" width="470" height="117" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;By not ticking the &amp;ldquo;Replace&amp;rdquo; checkbox, we will not overwrite any existing data in case we found a customer based on the email address (the &amp;ldquo;Set values&amp;rdquo; functionality is active in any case). It is possible to specify a lot of other properties on email filter as well, such as overriding category, priority, reply template, etc, but I&amp;rsquo;ll leave that for another article.&lt;/p&gt;&#xD;
&lt;p&gt;Finally, we need to connect this filter to one or more mailboxes. Normally, it makes sense to only connect the filter to the mailbox where these e-mails are received:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1566_1804.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1567_1805.jpg" alt="image" width="465" height="106" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;That is all. Saving this filter should make it operative. If you do this, and it does not work, try ticking the option &amp;ldquo;Include debug information in the message&amp;rdquo; on the &amp;ldquo;Properties&amp;rdquo; tag. It will include some more information on how the filter executed in the message of the request, which might point you in the right direction.&lt;/p&gt;</description><a10:updated>2012-03-07T13:12:11+01:00</a10:updated></item><item><guid isPermaLink="false">860d622f-ae7e-4618-a9fe-4f12adbf60d2</guid><link>http://devnet.superoffice.com/Blog/?entryId=784</link><author>sverre@superoffice.com</author><title>Creating a webpanel in Customer Service</title><description>&lt;blockquote&gt; &lt;p&gt;A powerful feature of Sales &amp;amp; Marketing is the possibility of quickly creating a webpanel, such as another section tab in the Contact screen, to show some information from another system (or the internet) about the current company. The same is possible in Customer Service, but the configuration is quite different. As with many other options, the flexibility in CS is based on a quite general flexibility of the framework.&lt;/p&gt; &lt;p&gt;First of all, to modify the “View company” screen to the extent that we desire here, we need in fact make our own screen. Fortunately, the default screen you get out-of-the-box is a screen based on the Screen designer, and all you need to do is to make a copy of this one:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1552_1790.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1553_1791.jpg" width="244" height="221"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The reason for why you have to make a copy, is that when you upgrade your installation, we will upgrade the System screens to the latest version. In the modified screen, we can add a new Pane for our webpanel and then inside the Pane we will use the “Ejscript element” to create our webpanel (element 11-13 in the list):&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1554_1792.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1555_1793.jpg" width="276" height="341"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For the Pane, you don’t really need much configuration. Set “title = My webpanel” to get a nice label for the tab. For the Ejscript element, we need a bit more configuration. The reason I chose this type of element is because I want to hook into the resizing model of the CS screens. This allows me to resize the webpanel to the maximum available size inside the Pane whenever we show or resize this screen. For the webpanel, I use a standard HTML iframe. In this example, the URL is hardcoded to our website, but of course you could use any arguments to create this url, such as passing in the name or id of the current company. Notice how I give the iframe an ID which needs to be unique for this page. This is to make the resizing work, since it needs to be able to find the iframe element. Finally, to set the size of the element, I can use a javascript function already present in the CS libraries: eJournal_setElementSize. So, in the Ejscript element, I enter the following code in the “Body” pane:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1556_1794.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1557_1795.jpg" width="538" height="224"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Do not worry if you do not understand all the details of this code. The most important point is that with relatively few customizations, you can add webpanels to screens in CS. Here is my final company screen:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1558_1796.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1559_1797.jpg" width="653" height="396"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;</description><a10:updated>2012-03-07T12:01:15+01:00</a10:updated></item><item><guid isPermaLink="false">ea9642c6-abc8-42b5-9f60-8a1886e67cf0</guid><link>http://devnet.superoffice.com/Blog/?entryId=783</link><author>frode@enkelt.no</author><title>Adding button to Company screen to toggle XStop in CS</title><description>&lt;p&gt;In Customer Service there are sooo many cool ways to extend it. In this smaller blogpost I'll show how you can add a button to the standard Company screen in CS that can toggle on/off the Stop-sign. The approach used here is maintenance friendly, meaning that when you upgrade Customer Service this will keep on working.&lt;/p&gt;&#xD;
&lt;p&gt;Ok, so here is the goal;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1542_1771.jpg" alt="" width="589" height="253" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;We want to add a button to the screen, and when it is clicked we want to toggle the Stop-flag.&lt;/p&gt;&#xD;
&lt;p&gt;First we start by creating the actual script that does the change. Go to System design-&amp;gt;Scripts, and add a new script. Here you see I've given it "togglestop" as the Include name. This is how I'm going to reference my script later.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1547_1781.jpg" alt="" width="569" height="215" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The actual script looks like this;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1544_1777.jpg" alt="" width="580" height="303" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;It expects the URL to contain a &amp;amp;contactId= variable. We'll make sure it does that a bit later.&lt;/p&gt;&#xD;
&lt;p&gt;Next it uses a NetServer agent to find the contact, change the XStop value, and save the change.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Lastly it opens up the same page again.&lt;/p&gt;&#xD;
&lt;p&gt;Ok, so the next step is to add this script behind a new button on the standard Company screen. To do this we go to System design-&amp;gt;Extra menus. Here we choose to add a new menu to Company.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1545_1775.jpg" alt="" width="204" height="269" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;...and here is the actual definition of the extramenu;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1546_1773.jpg" alt="" width="441" height="266" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;We've given it a nice label - Toggle Stopsign, and reuse one of the icons that ships with Customer Service. The important fields here are "URL" where we tell it to execute the script called "togglestop". Also notice the "&amp;amp;contactId=" at the end of the URL. Since we've checked the "Append ID" checkbox CS will put the current contact_id at the end of the URL for us.&lt;/p&gt;&#xD;
&lt;p&gt;Save the extramenu and you are good to go. If you now open up the Company screen you should see the button, and clicking it should enable and disable the Stopsign.&lt;/p&gt;&#xD;
&lt;p&gt;Notice that we haven't really altered the standard screen directly, so when Customer Service is upgraded in the future this button+script will be included even if the Company screen is updated :)&lt;/p&gt;</description><a10:updated>2012-03-03T01:52:10+01:00</a10:updated></item><item><guid isPermaLink="false">45d959b6-07f6-428d-bfcf-d90c8c0a51b5</guid><link>http://devnet.superoffice.com/Blog/?entryId=782</link><author>frode@enkelt.no</author><title>Using the SearchEngine class in ejScript</title><description>&lt;p&gt;This blogpost will give you an overview on how to use the SearchEngine class in ejscript. SearchEngine is probably one of the most commonly used ejscript classes.&lt;/p&gt;&#xD;
&lt;p&gt;The ejscript language is documented &lt;a href="http://techdoc.superoffice.com/ejScript.html" target="_blank"&gt;here&lt;/a&gt;. Search for '/SearchEngine/' to find the part where the different methods are described.&lt;/p&gt;&#xD;
&lt;p&gt;The SearchEngine is one of the core-classes in ejscript, and has existed for a long time. Back in the day when Customer Service was still called Ejournal 4.x the SearchEngine would use T-SQL and ODBC to talk to the database. During the conversion from Ejournal 4.x to Customer Service 7.x the SearchEngine switched over to use the SuperOffice NetServer webservices to read from and write to the database. This has a few advantages. SearchEngine no longer needs to worry about what type of database engine SuperOffice is running on. It doesn't really care if it is Oracle or MSSQL. One other advantage, which is important for consultants to know about, is that all queries that pass through the webservices are subjected to various businessrules in SuperOffice. For instance, the webservices will make sure that all Sentry rules are respected, and will not give out information the user is not allowed to see.&lt;/p&gt;&#xD;
&lt;p&gt;But even if there are advantages to SearchEngine talking via the webservices there are also some drawbacks. One is that NetServer (i.e. the webservices) doesn't handle aggregated functions. So if you want to do a COUNT, SUM, MAX etc then you need to bypass NetServer and use the old ODBC+SQL approach. This is simple to do, and you'll see how it works a bit further down.&lt;/p&gt;&#xD;
&lt;p&gt;For now, lets do a simple query. When you play around with ejscript it is easy to just go to System Design-&amp;gt;Script, and create a temporary script there. You can test it immediately by using the "Execute script" button.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1525_1740.jpg" alt="" width="274" height="209" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This query corresponds to the T-SQL statement:&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp; SELECT name FROM crm7.associate ORDER BY name ASC&lt;/p&gt;&#xD;
&lt;p&gt;Here we first create a SearchEngine named 'se'. Next we tell it to query the crm7.associate table for the 'name' field. The addOrder(string, bool) is used to sort the list alphabetically.&lt;/p&gt;&#xD;
&lt;p&gt;Then, in a for-loop we call se.execute() to run the actual query. That will perform the search, and populate the SearchEngine with the result. The for-loop will then call se.next() for each result until se.eof() (i.e. end-of-file) is reached. For each result we call print() to write the found value to the screen.&lt;/p&gt;&#xD;
&lt;p&gt;As a new-line character I print out "\r\n". Alternatively, if you've checked the "Show result of running script as HTML" checkbox you can print &amp;lt;br /&amp;gt; to get a newline.&lt;/p&gt;&#xD;
&lt;p&gt;Usually when you do a search you also want to filter the values. Lets say we only want the associates that have a corresponding ejuser.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1526_1742.jpg" alt="" width="374" height="192" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Here we add a line with .addCriteria(string, string, string, string, int). The first variable is the field we want to filter on, the second is the type of operator, and the third is the value.&lt;/p&gt;&#xD;
&lt;p&gt;The operators you can use as the second variable are "OperatorEquals", "OperatorGte", "OperatorNotEquals", "OperatorLt", "OperatorLte", "OperatorGt", "OperatorGte", "OperatorLike", "OperatorNotLike", "OperatorContains", "OperatorBeginsWith", "OperatorEndsWith", "OperatorIn", "OperatorNotIn", "OperatorIs", "OperatorOracleLeftJoin" and "OperatorIsNot".&lt;/p&gt;&#xD;
&lt;p&gt;The fourth and fifth variables are used when you have more than one .addCriteria call, and is used to control how &amp;nbsp;you wrap the parentheses and AND/OR between each criteria. The fourth operator can be either "OperatorAnd" or "OperatorOr", "OperatorNotAnd" and "OperatorNotOr".&lt;/p&gt;&#xD;
&lt;p&gt;One neat feature with the SearchEngine is the so called "dot-syntax". It refers to the fact that we can use dots to join tables. Here is an example where we search for all contacts with a given category, and use the dot-syntax to display the full name of the Our Contact.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1534_1755.jpg" alt="" width="411" height="196" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Notice here the way we use "contact.associate_id.person_id.fullName" to "dot" our way from the contact table via the associate table over to the person table. The keen observer will notice that I'm displaying a field called fullName, even if there is no such field in the physical database.&amp;nbsp;This is because there are a few "virtual fields" that we can use. fullname, emailAddress and direct/formattedNumber are a few examples of these fields.&lt;/p&gt;&#xD;
&lt;p&gt;In T-SQL there is a TOP operator which is used to limit the number of rows returned, and SearchEngine has a method for this as well. If you want to limit the number of rows you can call se.setLimit(15);&lt;/p&gt;&#xD;
&lt;p&gt;In T-SQL you also have the DISTINCT keyword. This actually has two corresponding methods; .setDBDistinct(bool) and .setDistinct(string).&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1535_1757.jpg" alt="" width="460" height="304" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;These will give the same result, but notice that when using .setDBDistinct(true) you also need to set .bypassNetServer(true) for it to have any effect.&lt;/p&gt;&#xD;
&lt;p&gt;If you want to use any aggregated functions like COUNT, SUM or AVG then you need to use .bypassNetServer(true) since the NetServer webservices does not support this. If you forget you'll get an error saying&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp; Original exception: NetServerException:&lt;br /&gt;&amp;nbsp; Can't use field functions when querying NetServer&lt;/p&gt;&#xD;
&lt;p&gt;In order for .bypassNetServer(true) to be allowed to be used on the database you need to enable it in the crm7.registry table with this;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp; UPDATE crm7.registry SET value = 1 WHERE reg_id = 235&lt;/p&gt;&#xD;
&lt;p&gt;Here is an example calculating the average amount on open sales for each associate;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1536_1759.jpg" alt="" width="379" height="196" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Notice how we use two variables on the second call to .addField(string, string). The second variable is the function name. And since we use an aggregated function we also need to add the GROUP BY statements using se.setGroup(true).&lt;/p&gt;&#xD;
&lt;p&gt;Maybe you've noticed that in all the examples above I've used se.getField(0) and se.getField(1) when retrieving the values found. The numbers correspond to the order the .addField() methods have been added. A better way is actually to not use numbers, but rather use the full fieldname instead. It does add a bit more text to your script, but is probably easier to maintain than using the index numbers.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1537_1761.jpg" alt="" width="294" height="104" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;In addition to &lt;em&gt;searching&lt;/em&gt; for data you can also use the SearchEngine class to &lt;em&gt;write&lt;/em&gt; data to the database. Best-practice is actually to use the NetServer agent classes for writing to the database, but it is often convenient to use a SearchEngine instead.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1533_1753.jpg" alt="" width="407" height="187" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Here we use se.addData to indicate where and what we want to write to the database. And since we don't want to make the same change to every row in the table we use addCriteria() to ensure we only change one row. Finally we call se.update() to perform the update.&lt;/p&gt;&#xD;
&lt;p&gt;NB - writing to the database this way does not log the change to the crm7.traveltransactionlog table, and should therefore be avoided in environments with satellites and travelusers.&lt;/p&gt;&#xD;
&lt;p&gt;Here is an example of how to delete something from the database. Again - best-practice is to use the NetServer agent classes to remove data since they also remove data from related tables and log changes to the traveltransactionlog.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1538_1763.jpg" alt="" width="410" height="168" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Even though all the examples above have been written in System Design-&amp;gt;Scripts this doesn't mean that this is the only place you use SearchEngine. Most often it is used in a custom screen. Either in one of the loadevents, or in the creation script for one of the elements on the screen. I'll leave you with an example where I have added a Listbox to a custom screen, and use a SearchEngine to fill it with items.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1539_1767.jpg" alt="" width="251" height="287" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1540_1765.jpg" alt="" width="487" height="446" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Oh, and one final thing. Notice how I've capitalized the T in the table Task? The table- and fieldnames you give the SearchEngine must match the same casing as is used in the crm7.conceptualtable and crm7.conceptualfield tables. Most of them are just lowercase, but there are a few that start with a capital letter.&lt;/p&gt;&#xD;
&lt;p&gt;This has been a walkthrough of some of the most common usages of the SearchEngine class. The SearchEngine has lots of other methods that I haven't covered here, so feel free to explore the documentation linked at the top of the blogpost.&lt;/p&gt;&#xD;
&lt;p&gt;Good luck!&lt;/p&gt;</description><a10:updated>2012-04-25T12:19:10+02:00</a10:updated></item><item><guid isPermaLink="false">ff1ca3ac-5a07-4642-80bc-43d2bafe699d</guid><link>http://devnet.superoffice.com/Blog/?entryId=781</link><author>frode@enkelt.no</author><title>Creating a simple screen with chart</title><description>&lt;p&gt;This blogpost will give a brief introduction to customizing Customer Service. The Chart component used here requires version 7.1. The intended audience are consultants who have done little or no CS customizations before.&lt;/p&gt;&#xD;
&lt;p&gt;The goal of the exercise is to create a custom screen that displays some saledata as a graph on a custom screen, and modifying the menu on the left side.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1519_1727.jpg" alt="" width="612" height="330" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;To do this we first create a new screen by going to System Design-&amp;gt;Screens, and click New Screen.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1521_1731.jpg" alt="" width="455" height="217" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;As a minimum we need to give the new screen a Name. You can call it whatever you like, but note that this will be used as the heading on your screen later.&lt;/p&gt;&#xD;
&lt;p&gt;Note that I've also added an ID string. This is not needed, but could be considered best practice. When you later need to reference your screen it is better to refer to it by this name than by an id number. This is specially useful when you export your screen from one Customer Service installation to another. So go ahead and give it a friendly name in the ID string field.&lt;/p&gt;&#xD;
&lt;p&gt;When you click Ok you get to a new screen where you can begin to add elements to your newly created screen. Click on the "New element" button, and choose to add a type called Chart.&lt;/p&gt;&#xD;
&lt;p&gt;Next, click the Apply button. This is a trick to get the Help pane filled with information about the elementtype you just selected. Go ahead, just take a look at the Help pane to read about the Chart element.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;As described in the helptext I've added two configuration values on the "Simple values" tab. I've given it a Title, and a graphtype. The "Simple values" pane is used for what we refer to as key-value pairs.&lt;/p&gt;&#xD;
&lt;p&gt;Key-value pairs is written like this;&lt;/p&gt;&#xD;
&lt;p&gt;key = value&lt;br /&gt;key2 = value2&lt;br /&gt;key3 = value3&lt;/p&gt;&#xD;
&lt;p&gt;and so on. Each line is interpreted independently from the other lines. After saving a screen with these Simple-values it will put the keys in alphabetical order.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1522_1733.jpg" alt="" width="468" height="228" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Ok - so, now we have a simple screen with the beginnings of a chart. But it does still not know which data to display. That is what we are going to do next.&lt;/p&gt;&#xD;
&lt;p&gt;On the Creation Script tab we write some ejscript that will be executed as the Chart-element is being created. You'll see that there is some scriptcode there initially. We are going to extend that code. Here is a screenshot with all the code added.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1523_1735.jpg" alt="" width="498" height="482" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Let's go through the code to understand what it does.&lt;/p&gt;&#xD;
&lt;p&gt;The first line usually starts with the addHtmlElement() function call. I add "HtmlElement chart = " before the functioncall to get a reference to the actual Chart-element.&lt;/p&gt;&#xD;
&lt;p&gt;Next we create a SearchEngine object. This is used to perform a search for some data from the database. By calling addField() we decide which fields to search for, and by using addCriteria we decide which data to include.&lt;/p&gt;&#xD;
&lt;p&gt;The T-SQL created from the SearchEngine above corresponds to;&lt;/p&gt;&#xD;
&lt;p&gt;SELECT&lt;br /&gt;&amp;nbsp; ass.name,&lt;br /&gt;&amp;nbsp; SUM(s.amount)&lt;br /&gt;FROM crm7.sale s&lt;br /&gt;LEFT JOIN crm7.associate ass ON s.associate_id = ass.associate_id&lt;br /&gt;WHERE s.status = 1&lt;br /&gt;GROUP BY s.status, ass.name&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Notice also that we're setting se.bypassNetServer(true). This is needed since we use the SUM function. Since NetServer does not support aggregated functions we need to tell CS "don't use the webservices to access the database, use pure T-SQL instead."&lt;/p&gt;&#xD;
&lt;p&gt;Note; In order for .bypassNetServer(true) we need to allow it with a correctly set value in the database first. In the crm7.registry table you need to set the value to 1 where reg_id = 235.&lt;/p&gt;&#xD;
&lt;p&gt;UPDATE crm7.registry SET value = 1 WHERE reg_id = 235&lt;/p&gt;&#xD;
&lt;p&gt;Next we execute the SearchEngine and loop over the data returned. Inside the loop we create a Map for each row returned. We add some key-value pairs on the map, and lastly add the map to our chart-graph.&lt;/p&gt;&#xD;
&lt;p&gt;Click OK to save your changes, and then you are returned to the Screen screen. To test your current screen click the Show screen button. If you get any errors you need to edit your Chart element. Click the yellow edit-icon to do that.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1520_1729.jpg" alt="" width="518" height="270" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When your screen works (i.e. displays a functional column-chart) it's time to add a way for your users to find the screen. This can be done by addind a link to it in the menu in the left hand side of the screen.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1541_1769.jpg" alt="" width="160" height="229" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Go to System design-&amp;gt;System scripts, and click Main Menu. On that blank screen you can add the following script:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1524_1737.jpg" alt="" width="612" height="112" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This three-line-script adds a new Group (i.e. a big button) at position 0, which is at the top of the menu. The last line adds one clickable link in that group. The text displayed to the user is the first parameter, and the second is the URL to open.&lt;/p&gt;&#xD;
&lt;p&gt;The URL is built up by using the getProgramBlogic() function. This is another best-practice. You don't want to hardcode say "http://myserver/scripts/blogic.exe?_sf=0", but would rather have CS calculate it for you. Then, if either the hostname is changed, or the .exe extension is changed to the new .fcgi extension in 7.1 it'll still just work.&lt;/p&gt;&#xD;
&lt;p&gt;After the getProgramBlogic() function call we append "&amp;amp;action=doScreenDefinition&amp;amp;idString=opensales". This means "go to the custom screen with the name opensales". See, here we reference the ID string we used earlier. The last two numbers means "put it in the first group as the first item".&lt;/p&gt;&#xD;
&lt;p&gt;Click OK, and you should be done! On the upperleft side you should now have a link called "Open sales chart" which should take you to your new screen.&lt;/p&gt;&#xD;
&lt;p&gt;And that's it :)&lt;/p&gt;</description><a10:updated>2012-03-03T01:05:38+01:00</a10:updated></item><item><guid isPermaLink="false">5ca40f95-99a4-4522-8305-8ad6cf92376a</guid><link>http://devnet.superoffice.com/Blog/?entryId=780</link><author>Jennifer.Lund@Superoffice.com</author><title>Selecting the right CRM software for you</title><description>&lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1513_1714.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Question-Mark-Red 680x356" border="0" alt="Question-Mark-Red 680x356" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1514_1715.jpg" width="244" height="130"&gt;&lt;/a&gt;  &lt;p&gt;Because there are as many CRM solutions as there are businesses that need them, it's easy to get lost in all the mumbo jumbo and watch what was supposed to be a very simple CRM project turn into a monster so difficult to handle and manage that it eventually fails. Studies show that 70% of all CRM projects fail.  &lt;p&gt;Our guide, the &lt;strong&gt;5 Tips to CRM success&lt;/strong&gt;, identifies 5 critical success factors you should keep in mind when choosing a CRM system.&amp;nbsp;&amp;nbsp; &lt;p&gt;1. &lt;strong&gt;Assess Your current situation &lt;/strong&gt; &lt;p&gt;It’s very easy to think that CRM can solve everything and immediately increase business revenues, but unfortunately, it can’t – not without some forethought at least.&amp;nbsp; Before starting, you have to assess your current situation: &lt;ul&gt; &lt;li&gt;What does your business look like?&lt;/li&gt; &lt;li&gt;What are some of your immediate business productivity challenges?&lt;/li&gt; &lt;li&gt;How do you want to solve them?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;2. &lt;strong&gt;Choose the right CRM solution for your business &lt;/strong&gt; &lt;p&gt;Not all CRM’s are created a like and the right one for you depends on your business and your IT needs. &lt;p&gt;3. &lt;strong&gt;Keep it Simple &lt;/strong&gt; &lt;p&gt;Here’s where bigger is not always better.&amp;nbsp;&amp;nbsp; The single most important CRM success criterion is how much the individual user in an organization is able to use and how well the solution is linked to the specific business process. &lt;p&gt;4. &lt;strong&gt;Make usability a key criteria &lt;/strong&gt; &lt;p&gt;People don’t like change.&amp;nbsp;&amp;nbsp; If a CRM solution takes to much effort to learn and use, sales people will resist incorporating the extra work. &lt;p&gt;5. &lt;strong&gt;Get some initial implementation assistance &lt;/strong&gt; &lt;p&gt;No matter how easy a solution says that it is, it’s still always smart to get some professional help – especially if you’re just starting out with CRM and have no or limited IT staff.&amp;nbsp; Initial CRM assistance helps you to get up and running a lot faster and ensures that you get started on the right foot. &lt;p&gt;For more information, &lt;a href="http://www.superoffice.com/Web/Secure-download-forms/5-Tips-to-CRM-Success/?filepath=/SecureFiles/COM/Documents/SUO_5tips_AS.pdf" target="_blank"&gt;download&lt;/a&gt; the guide here.  </description><a10:updated>2012-03-01T08:55:18+01:00</a10:updated></item><item><guid isPermaLink="false">3efbbb7b-037a-47dc-af14-f4a7ed3f673f</guid><link>http://devnet.superoffice.com/Blog/?entryId=779</link><author>Anders.Lien@Superoffice.no</author><title>Registering a request on behalf of a third party using Customer Centre</title><description>&lt;p&gt;In the Customer Center solution used by SuperOffice Support, there is an option in the request registration form to register a request on behalf of a third party. This can be used by partners to register requests on behalf of their customers, or a person in connected to a child company registering a request on behalf of their parent company. This blog post will describe how this can be implemented using some simple customizations to the standard customer centre templates in SuperOffice 7.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Database changes&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;There is no built in field / table for registering end customers in CS, so the first thing that has to be done is to create an Contact relation on the Request table, that will store the end customer information.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1505_1702.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1506_1703.jpg" alt="image" width="472" height="323" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Remember to always restart Netserver after adding fields to the database.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Adding fields to new request form&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The next step is to do add some HTML to registration form. Open up the &lt;strong&gt;newTicket.html&lt;/strong&gt; template in your preferred language ( templates/[lang]/customer/newTicket.html), and find the section where the name and email fields are created, before the category markup:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1507_1704.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1508_1705.jpg" alt="image" width="601" height="331" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This code displays input fields for customer name and email if the customer is not authenticated, and below that lists any external categories. I like to display the customers name and email even though authenticated, in that case add the following after line 56.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;&amp;lt;label&amp;gt;Your name&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input disabled="disabled" type="text" name="custName" value="%customer.name%"&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;&amp;lt;label&amp;gt;E-mail&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input disabled="disabled" type="text" name="custEmail" maxlength="255" value="%customer.email%"&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;Now, add input elements for registering end customer information.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;&amp;lt;label&amp;gt;Register on behalf of end customer&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input type="checkbox" name="endCust" value="1"&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;&amp;lt;label&amp;gt;End customer name&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input type="text" name="endCust_name" value=""&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;&amp;lt;label&amp;gt;End customer email&amp;lt;/label&amp;gt;&lt;br /&gt;&amp;lt;input type="text" name="endCust_email" value=""&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Your form should look something like this:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1509_1706.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/34870/1510_1707.jpg" alt="image" width="381" height="440" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Saving end customer on request&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When saving end customer information, we&amp;rsquo;ll copy the functionality from the standard form. If the end customer exists (based on email), we&amp;rsquo;ll use the existing customer, and ignore the End customer name if that differs from what&amp;rsquo;s already in the database. If the email address is not in the database, we&amp;rsquo;ll create a new customer.&lt;/p&gt;&#xD;
&lt;p&gt;The easiest way to save the end customer information is by a bit of ejScript in the ticketPosted.html file. The ticketPosted.html template is displayed after the request has been saved, so we have a request id to save our end customer information to. Add the following script to the end of the file:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;%EJSCRIPT_START%&lt;br /&gt;&amp;lt;%&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;Integer ticketId = getParserVariable("ticket.id").toInteger();&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;Bool saveEndCustomer = (getCgiVariable("endCust") == "1");&lt;br /&gt;String endCustName = getCgiVariable("endCust_name");&lt;br /&gt;String endCustEmail = getCgiVariable("endCust_email");&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;if (saveEndCustomer &amp;amp;&amp;amp; endCustEmail.isValidEmail())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; Ticket ticket; &lt;br /&gt;&amp;nbsp; ticket.load(ticketId);&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; Customer endCustomer;&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; if (endCustomer.findFromEmail(endCustEmail))&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ticket.setValue("x_end_customer", endCustomer.getValue("id"));&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; else&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; endCustomer.setValue("name", endCustName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; endCustomer.setValue("email", endCustEmail);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; endCustomer.save();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ticket.setValue("x_end_customer", endCustomer.getValue("id"));&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp; ticket.save();&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: x-small;"&gt;%&amp;gt;&lt;br /&gt;%EJSCRIPT_END%&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;That&amp;rsquo;s it, now we have a (basic) working implementation!&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Next steps&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Here are a few things that could be implemented as next steps:&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Validation: what happens if a customer enter an invalid email address&lt;/li&gt;&#xD;
&lt;li&gt;Remember end user information if &amp;ldquo;Register request&amp;rdquo; is pressed and there are validation errors&lt;/li&gt;&#xD;
&lt;/ul&gt;</description><a10:updated>2012-02-29T12:07:37+01:00</a10:updated></item><item><guid isPermaLink="false">442f5baf-d2c7-4b0b-8a8f-9ba3af757ddf</guid><link>http://devnet.superoffice.com/Blog/?entryId=778</link><author>Jennifer.Lund@Superoffice.com</author><title>Website leads don&amp;rsquo;t suck&amp;ndash;It&amp;rsquo;s all in the attitude</title><description>&lt;p&gt;&lt;img style="vertical-align: bottom;" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1504_1700.jpg" alt="Download buton" width="150" height="46" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Sales people can often be resistant to following up on website leads who have downloaded a report or completed a survey because those leads are not as &amp;ldquo;real&amp;rdquo; as those who filled in a hard &amp;ldquo;contact me&amp;rdquo;form.&amp;nbsp; The question is -- Should business buyers who request product information on your website be treated like any other sales lead?&amp;nbsp;&amp;nbsp; According to Wheelhouse, a B2B lead generation company, yes in some way and no in others.&amp;nbsp; Here are a few tips to make the most out of an inbound marketing lead:&lt;/p&gt;&#xD;
&lt;p&gt;1.&amp;nbsp; &lt;strong&gt;Have a defined follow up process and make sure to follow up fast&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Things happen fast on the internet. If the rule for follow up on the phone leads is two hours; make the follow up for the internet leads instant. The first person to get back to the customer has the best opportunity to win.&lt;/p&gt;&#xD;
&lt;p&gt;2.&amp;nbsp; &lt;strong&gt;Get personal&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When you receive a website lead, you don&amp;rsquo;t want treat them like a cold call or someone who walked in off the street. A business buyer researching products online has gone through a process of research and comparison before submitting a request for more information (i.e. submitting a lead.) When you first contact them, make sure you&amp;rsquo;ve studied the lead you received ahead of time, and approach your prospect as someone who is informed.&lt;/p&gt;&#xD;
&lt;p&gt;3.&amp;nbsp; &lt;strong&gt;Don&amp;rsquo;t give up on the lead so quickly and easily&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;It&amp;rsquo;s very easy when you hit your first wall with an Internet lead to claim that it&amp;rsquo;s just a bad lead, especially if you&amp;rsquo;re paying for that lead. But unlike leads for consumer products, which might include dream shoppers looking at cars or houses they really don&amp;rsquo;t intend to buy, business buyers rarely, if ever, have the luxury of submitting a lead for fun. Approach every lead as though they&amp;rsquo;re a golden opportunity and apply your thorough and relentless follow up process every time, and you&amp;rsquo;ll greatly increase your odds of success. After all, you would never want to lose that sale because you gave up before your competitor did.&lt;/p&gt;&#xD;
&lt;p&gt;4.&amp;nbsp; &lt;strong&gt;Always ask for another referral&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;It&amp;rsquo;s important to view an Internet lead as far more than the one person listed on the lead. An Internet lead is your entrance into a big opportunity and you&amp;rsquo;ll want to view the person listed on the lead as the one who is going to facilitate introductions for you. There is almost always more than one decision maker when it comes to a business product purchasing decision. So whether the person listed on your leads turns out to not be your champion or not, don&amp;rsquo;t stop there. Always work on getting to know who else will influence the decision to buy from you.&lt;/p&gt;&#xD;
&lt;p&gt;5.&amp;nbsp; &lt;strong&gt;Get them into your lead nurturing program&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;According to the National Sales Association, 80% of all sales are made on the 5th - 12th contact so don't expect them to buy as soon as you start your first phone conversation.&amp;nbsp; If they're not that interested at the moment, it doesn't mean that they won't be interested at some point of time in the future.&amp;nbsp; Make sure you get their email permission and start communicating with them via email to get them warmed up and towards a future sales process with you.&lt;/p&gt;&#xD;
&lt;p&gt;Inbound leads are awesome.&amp;nbsp; Instead of cold calling or other forms of sales prospecting, generating leads through inbound marketing makes the sales team&amp;rsquo;s job way easier.&amp;nbsp; if a person is an inbound lead, it means that they have visited your website because that is where they submitted their contact information.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;This means that they should have some idea about your business and your product or service which saves sales a ton of time and allows you to establish credibility and trustworthiness earlier in the conversation.&lt;/p&gt;&#xD;
&lt;p&gt;What&amp;rsquo;s your experience with your own website leads?&amp;nbsp;&amp;nbsp; Share your thoughts with us.&lt;/p&gt;</description><a10:updated>2012-02-29T08:35:27+01:00</a10:updated></item><item><guid isPermaLink="false">aeae61b2-6964-4352-8160-347b21c06675</guid><link>http://devnet.superoffice.com/Blog/?entryId=777</link><author>sverre@superoffice.com</author><title>Quickly create fancy charts with CS 7.1</title><description>&lt;p&gt;As you may have noticed, in Customer Service 7.1 we have introduced a new chart library. It is used for the new start page, as well as the eMarketing report and also a freshen-up of the old requests report. However, the chart library has also been made available as a custom control for your own screens. We have created a few methods for it which allows you to quickly create your own custom charts as custom screens in CS, which of course then can be embedded as web panels wherever you would like.&lt;/p&gt;&#xD;
&lt;p&gt;To get started, you need to create a new custom screen, and then add the Chart-control as the only element:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1486_1670.jpg"&gt;&lt;img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1487_1671.jpg" alt="image" width="244" height="227" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;You then need to specify the configuration for the Chart control. Nothing much here, just the type (other options are &amp;ldquo;column&amp;rdquo;, &amp;ldquo;bar&amp;rdquo;, &amp;ldquo;line&amp;rdquo;):&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1488_1672.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1489_1673.jpg" alt="image" width="360" height="194" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;And finally, the easiest way to populate the chart with data is in the Creation-script where we query our stuff and call a method on the chart control:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1490_1674.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1491_1675.jpg" alt="image" width="437" height="299" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This simple code will show you the number of requests pr. category:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1492_1676.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1493_1677.jpg" alt="image" width="412" height="315" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;On the chart component, you can call &amp;ldquo;increaseValue&amp;rdquo;, with a &amp;ldquo;key&amp;rdquo; and a &amp;ldquo;delta&amp;rdquo; (how much to increase with). It will increase the value for the given key (or set it if it is the first time encountered). You can also call &amp;ldquo;setValue&amp;rdquo; with &amp;ldquo;key&amp;rdquo; and &amp;ldquo;value&amp;rdquo;. This is used if you have calculated the values yourself, and only need to set them once. Also, if your keys are not so readable (for instance dates in a strict format), you can call &amp;ldquo;addLabel&amp;rdquo; with &amp;ldquo;key&amp;rdquo; and &amp;ldquo;label&amp;rdquo; to configure the text to use in the chart.&lt;/p&gt;&#xD;
&lt;p&gt;The following example will give you the number of messages created pr. support agent the last 48 hours:&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;HtmlElement myChart = addHtmlElement(getScreenElementId(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementName(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementType(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementConfig(screenElementIndex));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine se;&lt;br /&gt;se.addField("ej_message.created_by.username");&lt;br /&gt;se.addCriteria("ej_message.created_at", "OperatorGte", getCurrentDateTime().addHour(-48).toString(), "OperatorAnd", 0);&lt;br /&gt;for (se.execute(); !se.eof(); se.next())&lt;br /&gt;&amp;nbsp; myChart.setFieldValue("increaseValue", Map("key=" + se.getField(0) + "\ndelta=1"));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;With the unification of the CS and S&amp;amp;M databases, we can also easily access other stuff, such as sales. The following example gives you amount of sold pr. associate this year (assuming that all sales are in the same currency):&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;HtmlElement myChart = addHtmlElement(getScreenElementId(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementName(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementType(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementConfig(screenElementIndex));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;DateTime limit = getCurrentDateTime();&lt;br /&gt;limit.moveToYearStart();&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine se;&lt;br /&gt;se.addField("sale.associate_id.name");&lt;br /&gt;se.addField("sale.amount");&lt;br /&gt;se.addCriteria("sale.status", "OperatorEquals", "2", "OperatorAnd", 0);&lt;br /&gt;se.addCriteria("sale.saledate", "OperatorGte", limit.toString(), "OperatorAnd", 0);&lt;br /&gt;for (se.execute(); !se.eof(); se.next())&lt;br /&gt;&amp;nbsp; myChart.setFieldValue("increaseValue", Map("key=" + se.getField(0) + "\ndelta=" + se.getField(1)));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;And finally, a column chart (change chart type to &amp;ldquo;column&amp;rdquo;), which shows the number of booked meetings of type &amp;ldquo;Customer Meeting&amp;rdquo; this month for the associates. This is the chart you put on the wall for your monthly book-a-meeting competition:&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;HtmlElement myChart = addHtmlElement(getScreenElementId(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementName(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementType(screenElementIndex),&lt;br /&gt;&amp;nbsp; getScreenElementConfig(screenElementIndex));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;DateTime start = getCurrentDateTime();&lt;br /&gt;start.moveToMonthStart();&lt;br /&gt;DateTime end = getCurrentDateTime();&lt;br /&gt;end.moveToMonthEnd();&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine se;&lt;br /&gt;se.addField("appointment.registered_associate_id.name");&lt;br /&gt;se.addCriteria("appointment.do_by", "OperatorGte", start.toString(), "OperatorAnd", 0);&lt;br /&gt;se.addCriteria("appointment.do_by", "OperatorLte", end.toString(), "OperatorAnd", 0);&lt;br /&gt;se.addCriteria("appointment.task_idx.name", "OperatorEquals", "Customer Meeting", "OperatorAnd", 0);&lt;br /&gt;se.addCriteria("appointment.registered_associate_id", "OperatorGt", "0", "OperatorAnd", 0);&lt;br /&gt;for (se.execute(); !se.eof(); se.next())&lt;br /&gt;&amp;nbsp; myChart.setFieldValue("increaseValue", Map("key=" + se.getField(0) + "\ndelta=1"));&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1494_1678.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1495_1679.jpg" alt="image" width="446" height="336" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-02-29T08:31:55+01:00</a10:updated></item><item><guid isPermaLink="false">299297bb-4f36-4997-9f23-c8dc4ce57d32</guid><link>http://devnet.superoffice.com/Blog/?entryId=775</link><author>Jennifer.Lund@Superoffice.com</author><title>Delivering WOW through service</title><description>&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1484_1653.jpg"&gt;&lt;img style="border: 0px currentColor; padding-top: 0px; padding-right: 10px; padding-left: 0px; float: left; display: inline; background-image: none;" title="zappos" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/60/36760/1485_1654.jpg" alt="zappos" width="161" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Every once in a great while, I come upon a book which I think is so inspiring that I feel like I should shout about it from the rooftops in the hopes that other people will read it and also be just as inspired.&amp;nbsp; The book I&amp;rsquo;m talking about is called &amp;ldquo;Delivering Happiness&amp;rdquo; by Zappos CEO, Tony Hsieh (pronounced &amp;lsquo;Shay&amp;rsquo;).&lt;/p&gt;&#xD;
&lt;p&gt;There are 2 parts to the book.&amp;nbsp; The first part gives a very interesting and humorous account of the journeys of an entrepreneur &amp;ndash; all from starting a worm farm at the age of 8 to creating LinkExchange, which he sold to Microsoft for $265m to the start, near death and exit with Zappos, which sold to Amazon when it was valued at almost $1.2b on the day of closing.&lt;/p&gt;&#xD;
&lt;p&gt;Part 2 of the book is where Tony begins to talk about the building of the Zappos culture &amp;ndash; the thought that happy employees are what&amp;rsquo;s needed in order to run a good business and where he talks about Zappos&amp;rsquo; 10 core values, of which the first is &amp;ldquo;Deliver WOW through service.&amp;rdquo;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;It&amp;rsquo;s the WOW part that really inspired me because it started from the top and then infiltrated throughout the whole company from top to bottom.&lt;/p&gt;&#xD;
&lt;p&gt;What is WOW?&amp;nbsp; From the Zappos.com site, &amp;ldquo;Anything worth doing is worth doing with WOW.&amp;nbsp; To WOW, you must differentiate yourself, which means doing something a little unconventional and innovative.&amp;nbsp; You must do something that&amp;rsquo;s above and beyond what&amp;rsquo;s expected.&amp;nbsp; And whatever you do you must have an emotional impact on the receiver.&amp;nbsp; We are not an average company, our service is not average, and we don&amp;rsquo;t want our people to be average.&amp;nbsp; We expect every employee to deliver WOW.&amp;rdquo;&lt;/p&gt;&#xD;
&lt;p&gt;In today&amp;rsquo;s market, where products are almost the same, how can a company differentiate itself and gain loyal customers?&amp;nbsp; Here are four ways to get started:&lt;/p&gt;&#xD;
&lt;p&gt;1.&amp;nbsp; &lt;strong&gt;Send your new customers a welcome letter&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This is where you congratulate your new customer for making the purchase and then in detail, describe exactly what will happen next, as well as any action (if any) they need to take and when.&amp;nbsp; It&amp;rsquo;s important to set expectations after the sale and you don&amp;rsquo;t&amp;rsquo; want any misunderstandings to cause them to regret buying.&amp;nbsp; Send an unexpected bonus too, perhaps a nice notebook to write in or a book to read.&amp;nbsp; You want your new customer to be happy because you&amp;rsquo;ve exceeded his expectations.&lt;/p&gt;&#xD;
&lt;p&gt;2. &lt;strong&gt; Follow up&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Following up after each sale with a series of emails and the occasional phone call will let your new customers know how you care about them, as well as provide added reassurance that they&amp;rsquo;ve made a good decision in buying from you.&amp;nbsp; An email newsletter is another great way to keep in touch with existing customers, and to let them know about new products and services they might be interested in.&lt;/p&gt;&#xD;
&lt;p&gt;3.&amp;nbsp; &lt;strong&gt;Send some unexpected goodies&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;They don&amp;rsquo;t have to be expensive &amp;ndash; perhaps a helpful article or checklist relevant to their purchase.&amp;nbsp; Don&amp;rsquo;t try to sell anything when you send these.&amp;nbsp; Everyone loves receiving unexpected gifts and this is a great way to keep customers coming back for more.&amp;nbsp; It&amp;rsquo;s also a nice way to say thank you to loyal customers.&lt;/p&gt;&#xD;
&lt;p&gt;4.&amp;nbsp; &lt;strong&gt;Talk about them to others&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Write up a case study (with permission) and include it in your newsletter and/ or your blog.&amp;nbsp; This provides a great showcase of your product or expertise as well as being a great promotion for your client.&lt;/p&gt;&#xD;
&lt;p&gt;These are just a few ways to quickly deliver WOW to your customers.&amp;nbsp; What does WOW mean to you and how do you think that it could come to life in a business setting?&amp;nbsp; I&amp;rsquo;d love to hear your thoughts.&lt;/p&gt;</description><a10:updated>2012-02-24T19:46:32+01:00</a10:updated></item><item><guid isPermaLink="false">d277ee37-6430-4f43-9b4f-413c4f456029</guid><link>http://devnet.superoffice.com/Blog/?entryId=774</link><author>sverre@superoffice.com</author><title>Using map as a substitute for custom structs or classes</title><description>&lt;p&gt;A shortcoming of ejScript is the lack of support for custom structs or classes. Let&amp;rsquo;s say you would like to store a bunch of persons in memory for easy access, so that when you do your reporting or something else, you can easily lookup that person and get the firstname, lastname or any other property. In c# you would probably create a Person class, and then instantiate a Dictionary of Person, using the person_id as the key, and then load from the database.&lt;/p&gt;&#xD;
&lt;p&gt;Implementing custom structs is not something we are likely to implement in ejScript any time soon (because of it&amp;rsquo;s complexity). However in 7.1, we have added a couple of new functions which might solve many of the cases where you would like a struct: Map.toJson() and Map.fromJson(). They somewhat resemble the old pack()/unpack() functions of Perl. Basically they allow you to take the contents of a Map (which with it&amp;rsquo;s name-value structure resembles a simple struct) and pack it into a string in json-format. This string can then easily be stored in another map. Reversely, you can get this string, and initialize a map from it, unpacking the various fields to name-value pairs again.&lt;/p&gt;&#xD;
&lt;p&gt;Here is a simple example which first loads persons from the database and store their firstname and lastname in a map, and then packs that map into a larger map where the person_id is the key. After all the persons have been loaded from the database, we iterate our main map (i.e. our Dictionary of Persons), unpack each person into a temporary map which allows us to access each field (which in this case are just printed):&lt;/p&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;Map persons;&lt;br /&gt;SearchEngine query;&lt;br /&gt;query.addField("person.person_id");&lt;br /&gt;query.addField("person.firstname");&lt;br /&gt;query.addField("person.lastname");&lt;br /&gt;for (query.execute(); !query.eof(); query.next())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; Map personMap;&lt;br /&gt;&amp;nbsp; personMap.insert("firstname", query.getField("person.firstname"));&lt;br /&gt;&amp;nbsp; personMap.insert("lastname", query.getField("person.lastname"));&lt;br /&gt;&amp;nbsp; persons.insert(query.getField("person.person_id"), personMap.toJson());&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span style="font-family: 'Courier New';"&gt;for (persons.first(); !persons.eof(); persons.next())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; Map personMap;&lt;br /&gt;&amp;nbsp; personMap.fromJson(persons.getVal());&lt;br /&gt;&amp;nbsp; print("Firstname: " + personMap.get("firstname") + ", Lastname: " + personMap.get("lastname") + "\r\n");&lt;br /&gt;}&lt;/span&gt;&lt;/pre&gt;</description><a10:updated>2012-02-27T10:53:17+01:00</a10:updated></item><item><guid isPermaLink="false">3cff0e62-f843-4ae3-8c06-bd586cf8d6ad</guid><link>http://devnet.superoffice.com/Blog/?entryId=772</link><author>sverre@superoffice.com</author><title>ejScript improvements for reports and charting</title><description>&lt;p&gt;A very powerful class I use quite often for reports and charting is the Map class. The idea is that you can iterate any dataset and increment the numeric value stored in your map for a given key. If the map does not yet contain your key, you set the initial value (for instance to &amp;ldquo;1&amp;rdquo; if you are just counting). Finally, to show the results, you iterate the map and show the key and the value, which for instance will give you a list of tickets-per-category distribution:&lt;/p&gt;&#xD;
&lt;p style="font-family: 'Courier new';"&gt;Support: 2&lt;br /&gt; Support/Hardware: 2&lt;br /&gt; Support/Software: 7&lt;/p&gt;&#xD;
&lt;p&gt;A free effect of using the map is that all keys are sorted alphabetically when you iterate the map with Map.first and Map.next.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Here is the example code for getting the results above:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine query;&lt;br /&gt;Map map;&lt;br /&gt;query.addField("ticket.category.fullname");&lt;br /&gt;for (query.execute(); !query.eof(); query.next())&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; String key = query.getField(0);&lt;br /&gt;&amp;nbsp; String value = map.get(key);&lt;br /&gt;&amp;nbsp; if (value == "")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value = "0";&lt;br /&gt;&amp;nbsp; value = Integer(value.toInteger() + 1).toString();&lt;br /&gt;&amp;nbsp; map.insert(key, value);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;for (map.first(); !map.eof(); map.next())&lt;br /&gt;&amp;nbsp; print(map.getKey() + ": " + map.getVal() + "\r\n");&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;This works well, however the section where we get the value from the map, check if it exists, sets it to 0, and increase is somewhat cumbersome. With version 7.1 we have added a new function to Map which makes the code nicer: increaseValueForKey. The function exists in an integer and a float version. With this, we can write the same code like this:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine query;&lt;br /&gt;Map map;&lt;br /&gt;query.addField("ticket.category.fullname");&lt;br /&gt;for (query.execute(); !query.eof(); query.next())&lt;br /&gt;&amp;nbsp; map.increaseValueForKey(query.getField(0), 1);&lt;br /&gt;&lt;br /&gt;for (map.first(); !map.eof(); map.next())&lt;br /&gt;&amp;nbsp; print(map.getKey() + ": " + map.getVal() + "\r\n");&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Better readability and less risk of bugs. The second parameter to the function is how much to increment with. For counting, you will increase with 1, however let&amp;rsquo;s say you would like sum of sold sales per customer business:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;SearchEngine query;&lt;br /&gt;Map map;&lt;br /&gt;query.addField("sale.contact_id.business_idx.name");&lt;br /&gt;query.addField("sale.amount");&lt;br /&gt;query.addCriteria("sale.status", "OperatorEquals", "2", "OperatorAnd", 0); // Sold&lt;br /&gt;for (query.execute(); !query.eof(); query.next())&lt;br /&gt;&amp;nbsp; map.increaseValueForKey(query.getField(0), query.getField(1).toFloat());&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;for (map.first(); !map.eof(); map.next())&lt;br /&gt;&amp;nbsp; print(map.getKey() + ": " + map.getVal() + "\r\n");&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;(Not taking into consideration various currencies)&lt;/p&gt;&#xD;
&lt;p&gt;Finally, one limitation of the reports above is that they do not list contents for keys which have no values. I.e. the first report will not list categories which does not have requests. This is a very common situation, which you will also get from any CrystalReports-like reporting tool which execute a query, and where the result will be limited by the categories which actually have requests in them. With the map-approach however, this is quite easy to remedy. Just do another query prior to the first one, where you query all the categories and insert them into the map:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: 'Courier New';"&gt;categories.addField("ej_category.fullname");&lt;br /&gt;for (categories.execute(); !categories.eof(); categories.next())&lt;br /&gt;&amp;nbsp; map.insert(categories.getField(0), "0");&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This will &amp;ldquo;fill out&amp;rdquo; the map with every category and the initial value &amp;ldquo;0&amp;rdquo;. The second query will then increment this number for each request in a given category. Finally, when iterating the map and printing for all keys, you will also get some categories with the value 0, because they have no requests in them.&lt;/p&gt;</description><a10:updated>2012-02-27T10:53:59+01:00</a10:updated></item><item><guid isPermaLink="false">b534142c-469e-43ff-b37b-a02753554749</guid><link>http://devnet.superoffice.com/Blog/?entryId=771</link><author>sverre@superoffice.com</author><title>Setting background color for rows in grid</title><description>&lt;p&gt;Sometimes it is desirable to customize the background color of a row in a grid, for instance to emphasize requests which have passed their deadline. The easiest way to do this in a custom screen is to use a static table (“Static Table v2”), and the populate it with data yourself, setting the color as desired. (The main difference between a “DataTable” and a “StaticTable” is that the former is self-populating from the tables and field you specify, while the latter needs to be populated manually). Populating a static table is done by calling setFieldValue() with arguments “addRow” and “addCell” for all the content you wish to add. Here is an example which will use red background for all open requests with a passed deadline. I have created a screen with only one element (“Static Table v2”) which the following configuration:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1470_1536.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1471_1537.jpg" width="244" height="209"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;…and this Creation script:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1472_1538.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1473_1539.jpg" width="330" height="341"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here is the resulting screen:&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1474_1540.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/66/36166/1475_1541.jpg" width="472" height="322"&gt;&lt;/a&gt;&lt;/p&gt;</description><a10:updated>2012-02-20T11:49:18+01:00</a10:updated></item><item><guid isPermaLink="false">bd520951-768f-40eb-bc9f-5d76ba04cdae</guid><link>http://devnet.superoffice.com/Blog/?entryId=770</link><author>tor.thorbergsen@superoffice.com</author><title>Laws of acquisition</title><description>&lt;h1&gt;Laws of acquisition&lt;/h1&gt;&#xD;
&lt;p&gt;I work for a company that wants to be &amp;laquo;funky&amp;raquo;. We want to have funky products that the users love to use. It&amp;rsquo;s in our DNA, we have always had this focus. Maybe we don&amp;rsquo;t always get it right, but we try, and when we fail, we try again.&lt;/p&gt;&#xD;
&lt;p&gt;Some of our competitors &amp;hellip; let&amp;rsquo;s just say that they don&amp;rsquo;t have this focus. Technology and &amp;ldquo;plumbing&amp;rdquo; (how to get data from the database to the business layer) is what they focus on. The brains in the outfit do those parts, while the weakest developers have to do the user interface.&lt;/p&gt;&#xD;
&lt;p&gt;They have no design. They have little or no alignment, or think that alignment = design. Labels that are cryptic at best. Many, many fields you have to fill out. Everything you do is cumbersome; the system constantly demands your attention, interrupting your flow, derailing you from your purpose, bleeding your energy from you.&lt;/p&gt;&#xD;
&lt;p&gt;Note that what I&amp;rsquo;m talking about here are those competitors who don&amp;rsquo;t care about the &lt;strong&gt;normal&lt;/strong&gt; user&amp;rsquo;s experience. However, most of them come, get some fame and then fade away until they get bought up and finally buried.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;And don&amp;rsquo;t get me wrong, technology is also important, we in SuperOffice have a platform that has survived for 20 years because we thought big from the beginning, and because we spend a (surprisingly) large amount of time investing in it.&lt;/p&gt;&#xD;
&lt;p&gt;But over the years I have come to realize that there are some &amp;ldquo;laws of economics&amp;rdquo;, or rather some &amp;ldquo;laws of acquisition&amp;rdquo; (or just &amp;ldquo;laws of buying&amp;rdquo;) that affect how long a software company with no focus on user experience will survive, and I want to share my thoughts about them with you:&lt;/p&gt;&#xD;
&lt;h2&gt;Law 1: Users aren&amp;rsquo;t buyers&lt;/h2&gt;&#xD;
&lt;p&gt;People have always cared about the user experience, and this we can see by Apples success in the private market. But how come there is so much software with a &amp;hellip;bad user experience in the business market? It is a fact that in the business market, software is often bought by someone other than the users. When the bean counters are choosing, we all know what is prioritized.&lt;/p&gt;&#xD;
&lt;h2&gt;Law 2: The buyer need only to like his part of the system&lt;/h2&gt;&#xD;
&lt;p&gt;But, there are other factors as well. In one company I worked for, we had to use a system for keeping track of how many hours we worked each day. The system was unbelievably user &lt;strong&gt;un&lt;/strong&gt;-friendly. I really should have made a report, enumerating in detail all the weird and insane ways this system abused its users, but I didn&amp;rsquo;t have the stomach for the job. How did it come about that thousands of workers had to battle with this system weekly for years? Simply; the system&amp;rsquo;s main part, the accounting part, was splendid, and for the few who used that part every day, and all day, the system worked great. (Not intuitively, maybe, but &lt;strong&gt;you don&amp;rsquo;t need intuitive when you work with a system every day&lt;/strong&gt;. Intuitive you need when you are using a system seldom, like once a week or month, or maybe a few times a year.) Anyway, guess who selected the system? Obviously, the few who used the good accounting part.&lt;/p&gt;&#xD;
&lt;p&gt;I studied a competitor of us once, and actually got a great demonstration from the lead salesman in that company. My analysis was that the input part of the system was severely malfunctioning, but the reports where fantastic. So when he was demoing the software, the basic sales pitch was to show the management the reports and avoid showing the normal users the crappy input pages. When I told him I loved the reports, he replied by stating that &amp;ldquo;&lt;strong&gt;if only the users would enter the data&lt;/strong&gt; like they were supposed to, the reports would truly be great&amp;hellip;&amp;rdquo;&lt;/p&gt;&#xD;
&lt;h2&gt;Law 3: The larger the system, the more distance between buyer and user.&lt;/h2&gt;&#xD;
&lt;p&gt;That system had a few really big customers, and when you think about this, you will see that the larger the system, the greater impact this law has, because then the buyers&amp;rsquo; company has many layers of management between the decision makers and the users.&lt;/p&gt;&#xD;
&lt;h2&gt;Law 4: The smartest user gets to select which system to buy&lt;/h2&gt;&#xD;
&lt;p&gt;Also, a lot of companies do a fundamental error when they want to select a new system. Imagine that you are the boss and you need a new system that your 20 employees shall use daily in the operation. You know that you need some buy-in from the users too, but which of your employees do you choose to help you select the new system? Normal distribution dictates that you have a few smart ones and a few &amp;hellip;slow ones. And guess who always is asked to select the system? It&amp;rsquo;s the smart one who repeatedly has proved an interest for computers. But there is a problem. The genius will select a system that is &lt;em&gt;advanced&lt;/em&gt;. He will select a system for himself, that can fulfill most of his wishes. This system will make the slower users despair and the other normal users hate the system, but man, those reports are fantastic!&lt;img style="float: right;" src="http://media-cdn.tripadvisor.com/media/photo-s/02/2b/81/73/bath-tub-with-handle.jpg" alt="" width="275" height="206" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;There is this story I like to tell about when the bathtub was introduced to the hotels in the US. (These things come in trends, nowadays all hotels want to be a &amp;ldquo;spa-hotel&amp;rdquo; J. ) However, the hotels got some new problems, sometimes guests, especially old or handicapped guests had a hard time getting out of the tub. And, as you can imagine, this ended up with a very embarrassing episode for both the hotel staff and the guests.&lt;/p&gt;&#xD;
&lt;p&gt;Well, the hotels soon figured out a solution to this problem, the wall mounted handle bar.&lt;/p&gt;&#xD;
&lt;p&gt;The thing that surprised the hotels, was that everyone used the handle bars to get out of the tub, not just the old or disabled. For me, this story shows that making something user friendly doesn&amp;rsquo;t necesarrily slow down the best users, it can actually make them more effective too.&lt;/p&gt;&#xD;
&lt;h2&gt;Law 5: We want systems that play nice with the other systems&lt;/h2&gt;&#xD;
&lt;p&gt;The last 10-15 years has seen a silent revolution of systems connecting to each other. While in the early 90&amp;rsquo; it was normal to punch in the same data two and sometimes three times into different systems nowadays this happens more and more seldom. Companies simply can&amp;rsquo;t afford to have salesmen do such unproductive and error-prone work.&lt;/p&gt;&#xD;
&lt;p&gt;So when a company wants to upgrade its main software systems, they always want to consider the one big packet based on the idea that the various parts will interface well with each other. While this might be true, it will also mean that some of the parts might be bad. A lot of companies have experienced this and they search for the &amp;ldquo;best-of-breed&amp;rdquo; systems that also can integrate with the other systems they have.&lt;/p&gt;&#xD;
&lt;h2&gt;Law 6: We want the Mercedes&lt;/h2&gt;&#xD;
&lt;p&gt;I worked at a company once that had many systems, and the flagship of the company was a very advanced system. It was very costly, both in acquisition, training and in yearly licenses. It was designed to be extremely efficient, so for the 10 or 20 users who actually used it daily it was wonderful. Now, the funny thing was that it had a few thousand customers, and I don&amp;rsquo;t think any of the other users managed to use it at all. This was because it was a system that they used intensely in parts of their projects, but then left alone for long periods of time, typically 6 months or more.&lt;/p&gt;&#xD;
&lt;p&gt;Why, then, did they keep paying for this system that they couldn&amp;rsquo;t use? The explanation was simple; because they considered it to be the best. And since this system was very important in the planning stages of their projects, they didn&amp;rsquo;t want anything other than the best.&lt;/p&gt;&#xD;
&lt;h2&gt;Law 7: Nobody ever got fired for buying IBM&lt;/h2&gt;&#xD;
&lt;p&gt;It&amp;rsquo;s an old saying that nowadays applies mostly to Microsoft, and perhaps soon to Apple and Google. When in doubt, the middle management will go for the biggest, apparently safest vendor. Problem is, the biggest, apparently safest vendor knows this and tries to use it by inserting as much doubt about as possible about the others.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h2&gt;Is there any hope?&lt;/h2&gt;&#xD;
&lt;p&gt;You can see how these laws at work very well in the ERP market. User interface doesn&amp;rsquo;t have to be intuitive; it just has to be effective (fast entering of data is important.) And user interface in the ERP market is seldom neither beautiful nor intuitive. It could be way better, but I think they are afraid that this would be at the expense of efficiency. But, as the bathtub handle story shows; this does not have to be the case.&lt;/p&gt;&#xD;
&lt;p&gt;In the CRM market however, &lt;strong&gt;we are blessed with users that are salesmen&lt;/strong&gt;. And much can be said about salesmen, most of it untrue, but one thing is for sure, they are not a patient breed. Since most of them are paid a commission, &lt;strong&gt;salesmen will only use their time to enter data that they consider useful to themselves&lt;/strong&gt;. Management can bully them to enter other data some of the time, but fighting human nature is a losing proposition. When the going gets tough, the salesman will focus on the things that will bring in the money, and the management&amp;rsquo;s reports will be brutally down-prioritized.&lt;/p&gt;&#xD;
&lt;p&gt;So, &lt;strong&gt;if a company buys a CRM system that the salesmen consider a waste of time, it will fail&lt;/strong&gt;. Then, after a time, management will understand that paying for licenses and upgrades is a waste of good money, and stop doing that. Some years will pass, typically some of the salesmen leave and some new ones come in, and then they will try again. Hopefully this time with SuperOffice.&lt;/p&gt;</description><a10:updated>2012-02-22T14:59:41+01:00</a10:updated></item><item><guid isPermaLink="false">79657a5d-25b2-4481-904b-ba4dea04c691</guid><link>http://devnet.superoffice.com/Blog/?entryId=769</link><author>margrethe@superoffice.com</author><title>Compability reports on techdoc.superoffice.com</title><description>&lt;p&gt;On the CRM 7 site we have now published our compability test reports for both CRM 6 and CRM 7.&lt;/p&gt;&#xD;
&lt;p&gt;Please note that a "Test Passed" status is a 90% assurance that this product will work as intented in the environment tested.&lt;/p&gt;&#xD;
&lt;p&gt;You may open the Excel report to see our comments and also if it's marked as Failed you will see&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1407_1385.jpg" alt="" width="612" height="194" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Sheet 2 gives you the Compability test results, here you will be able to filter by SuperOffice product and get our comments:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1406_1387.jpg" alt="" width="612" height="337" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;If failed you will at the bottom see why, it could be a "minor" issue&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1405_1389.jpg" alt="" width="612" height="93" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;We would off course love your feedback.&lt;/p&gt;&#xD;
&lt;p&gt;And if you're missing an enviornment, please let us know here or by email to techdoc@superoffice.com&lt;/p&gt;</description><a10:updated>2012-02-01T10:16:16+01:00</a10:updated></item><item><guid isPermaLink="false">5d72bed3-f97f-43a7-9146-a3389816abc9</guid><link>http://devnet.superoffice.com/Blog/?entryId=768</link><author>Conrad.Weyns@superoffice.com</author><title>Just wasting time I guess&amp;hellip;</title><description>&lt;p&gt;WLW Test 1&lt;br&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1396_1368.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="tfs throws me out" border="0" alt="tfs throws me out" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1397_1369.jpg" width="244" height="236"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1399_1373.jpg"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="IMG_0221" border="0" alt="IMG_0221" src="http://devnet.superoffice.com/EPiServerCommunity/Modules/ImageGallery/Thumbnails/70/30670/1400_1374.jpg" width="184" height="244"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;No comments…&lt;/p&gt;</description><a10:updated>2012-01-31T08:10:30+01:00</a10:updated></item><item><guid isPermaLink="false">e800245c-e0b0-41b8-b3c7-85972e52d365</guid><link>http://devnet.superoffice.com/Blog/?entryId=766</link><author>frode@enkelt.no</author><title>Adding messagecount to tab in View Ticket</title><description>&lt;p&gt;We've seen that one of the early-warning signs for when a ticket is going to become a support-problem are the number of messages it contains. Whenever a ticket has way more messages than usual it normally means that something is wrong.&lt;/p&gt;&#xD;
&lt;p&gt;So, to give this variable more focus we've slightly altered our "View Ticket" screen so that the number of messages is displayed in the title of the pane.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1387_1353.jpg" alt="" width="189" height="229" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Here is a short review of the changes we did.&lt;/p&gt;&#xD;
&lt;p&gt;- Go into System Design-&amp;gt;Screens and find the System Screens-&amp;gt;View Ticket screen.&lt;/p&gt;&#xD;
&lt;p&gt;- Find the pane that contains the list of messages.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1390_1347.jpg" alt="" width="369" height="454" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;- Click on the edit-icon, and flip over to the "Creation script" pane. It contains the ejscript that is run when the screen element is being created.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1389_1349.jpg" alt="" width="442" height="100" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The addHtmlElement takes in four variables, the last one being a Map of configuration values. We want to slightly alter that map so that the Title is changed.&lt;/p&gt;&#xD;
&lt;p&gt;Here is the new code. It creates a SearchEngine that builds up a query to get the number of messages for the current ticket - similar to "SELECT COUNT(*) FROM crm7.ej_message WHERE ticket_id = x".&lt;/p&gt;&#xD;
&lt;p&gt;Then it finds the existing panetitle, and adds the number of messages within parentheses.&lt;/p&gt;&#xD;
&lt;p&gt;- Alter the code to the one in the screenshot.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/50/30850/1388_1351.jpg" alt="" width="544" height="416" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When you click OK the change is saved and the change is complete.&lt;/p&gt;</description><a10:updated>2012-01-29T19:58:11+01:00</a10:updated></item><item><guid isPermaLink="false">5f65addb-40af-48e0-be83-4d633cdb4c4b</guid><link>http://devnet.superoffice.com/Blog/?entryId=765</link><author>frode@businessanalyze.com</author><title>SuperOffice Analyze PRO - An  amazing dashboard designer</title><description>&lt;p&gt;&lt;span&gt;SuperOffice Analyze is an overarching dashboard solution for reports and analyzes from the SuperOffice CRM-system. The dashboards are transparent and role based to ensure focus on the right metrics with the ability to react to changing business needs.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;h2&gt;Self Service Analytics&lt;/h2&gt;&#xD;
&lt;p&gt;&lt;span&gt;The solution's powerful data visualization capabilities allows the business user to view their own data in a simple and meaningful way. It meets the business users' need for ease of use and flexibility on the one hand, and IT's need for standards and control on the other.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;h2&gt;Value quickly delivered&lt;/h2&gt;&#xD;
&lt;p&gt;&lt;img style="float: right;" src="http://www.businessanalyze.com/images/stories/screens/soa/tapt.PNG" alt="tapt" width="250" height="169" /&gt;&lt;span&gt;SuperOffice Analyze is a predefined analytics package with very short implementation time. Just start clicking and become instantly productive.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;SuperOffice Analyze provides historical, current and predictive views of your business, helping you:&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Improve sales efficiency and secure revenues.&lt;/li&gt;&#xD;
&lt;li&gt;Simplify management of sales team &amp;amp; processes.&lt;/li&gt;&#xD;
&lt;li&gt;Increase predictability with better prognosis.&lt;/li&gt;&#xD;
&lt;li&gt;Improve quality in decision making.&lt;/li&gt;&#xD;
&lt;li&gt;Create focus, inspiration and enthusiasm around important areas (KPIs) for the company, helping implementing processes, plans &amp;amp; strategies.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h2&gt;SuperOffice Analyze PRO&lt;/h2&gt;&#xD;
&lt;p&gt;The best fit for consultants and technical who want to integrate data from SuperOffice and other sources.&lt;/p&gt;&#xD;
&lt;p&gt;What's in it?&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Visualize data from more-fields in SuperOffice&lt;/li&gt;&#xD;
&lt;li&gt;Create new data tables to visualize data from other sources than SuperOffice&lt;/li&gt;&#xD;
&lt;li&gt;Create new data tables in order to visualize data not included in the SuperOffice Analyze package&lt;/li&gt;&#xD;
&lt;li&gt;Utilize Business Analyze WYSIWYG Dashboard Editor to modify existing dashboards and create new ones&lt;/li&gt;&#xD;
&lt;li&gt;Includes 1 licenses for Designer and Data central&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;More information about the capabilities in the &lt;a title="Analyze PRO" href="http://www.businessanalyze.com/analyze-pro/analyze-pro" target="_blank"&gt;Analyze PRO here&lt;/a&gt;.&lt;/p&gt;</description><a10:updated>2012-01-25T17:40:52+01:00</a10:updated></item><item><guid isPermaLink="false">68d6a9b0-6f00-450f-8ae6-3ec18c73d8e5</guid><link>http://devnet.superoffice.com/Blog/?entryId=756</link><author>tony@devnet.superoffice.com</author><title>Publishing Blog Posts on DevNet Using Windows Live Writer</title><description>&lt;h3&gt;Download Windows Live Writer&lt;/h3&gt;&#xD;
&lt;p&gt;First and foremost, if you haven&amp;rsquo;t got it already, download Microsoft Windows Live Writer (WLW) from the &lt;a href="http://www.live.com"&gt;http://www.live.com&lt;/a&gt; web site. This application is like Microsoft Word for Blogs, and allows you to save your blog posts for future edits and reposting.&lt;/p&gt;&#xD;
&lt;p&gt;WLW is an application bundled up in its Windows Live Essentials, which can be found here:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://explore.live.com/windows-live-essentials-other-programs" href="http://explore.live.com/windows-live-essentials-other-programs"&gt;http://explore.live.com/windows-live-essentials-other-programs&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;h3&gt;Get Your DevNet User ID&lt;/h3&gt;&#xD;
&lt;p&gt;Once WLW is installed, you&amp;rsquo;re going to want to create a new account in the application and associate that with your SuperOffice DevNet user account. To accomplish that, you are going to need to get your User ID. Thankfully, getting your id is really simple. Just logon to the site and you will be redirected to your &amp;ldquo;My Page&amp;rdquo;. On your &amp;ldquo;My Page&amp;rdquo;, hover your mouse over the Edit Settings text link and note your User ID in the status bar of your browser.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1285_1097.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="GetUserID" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1286_1098.jpg" alt="GetUserID" width="575" height="522" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h3&gt;Create a New Account in WLW&lt;/h3&gt;&#xD;
&lt;p&gt;With your DevNet User ID in hand, click the Blog Accounts drop down and select the Add blog account on the Home tab.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1287_1099.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="AddNewAccount" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1288_1100.jpg" alt="AddNewAccount" width="572" height="240" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;This will bring up a dialog where you must choose the type of blog you are going to use. Select the last option, &amp;ldquo;Other Services&amp;rdquo;, then click Next.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1289_1101.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="WhatBlogServices" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1290_1102.jpg" alt="WhatBlogServices" width="458" height="389" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;In the Add a blog account dialog, enter in the SuperOffice DevNet address, appending &amp;ldquo;/Blog/?userid=0000&amp;rdquo;, replacing 0000 with your real user id.&lt;/p&gt;&#xD;
&lt;p&gt;Fill in the User name and Password fields, optionally check to remember your password, then click Next.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1291_1103.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="AddABLogAccount" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1292_1104.jpg" alt="AddABLogAccount" width="455" height="389" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;The application will process your information, connect to the site, authenticate the user and then check the configuration settings. It&amp;rsquo;s interesting that in this next screenshot it shows the application attempting to get the blogs categories. Unfortunately this doesn&amp;rsquo;t always work, but I&amp;rsquo;ll point out how to fix that very soon.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1293_1105.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="Processing" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1294_1106.jpg" alt="Processing" width="457" height="389" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;The next prompt to Download Themes is very important. You must &lt;span style="text-decoration: underline;"&gt;&lt;strong&gt;select NO&lt;/strong&gt;&lt;/span&gt;, otherwise the setup process will fail.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1295_1107.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="WlwSetupSettings_SayNo" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1296_1108.jpg" alt="WlwSetupSettings_SayNo" width="533" height="462" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Finally, you are presented with the dialog that your account has been setup and you are almost done. Give it a memorable name and click Finish.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1299_1111.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="BlogHasBeenSetUp" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1300_1112.jpg" alt="BlogHasBeenSetUp" width="457" height="390" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;Click on the Categories drop down and make sure that you see the two DevNet categories &amp;ldquo;Developer&amp;rdquo; and &amp;ldquo;Technical&amp;rdquo;. If you do not, click the Refresh button and they should appear.&lt;/p&gt;&#xD;
&lt;p&gt;This is a very important step, so that you can signal to the website, under which Center, or Club, you would like your blog post to appear. If you don&amp;rsquo;t select one, the blog post will only be visible to you on your My-Page.&lt;/p&gt;&#xD;
&lt;p&gt;The general rule is, if the blog post contains just technical information related to installation, maintenance or upgrades or SuperOffice, or anything technically related, then your should select the Technical category. If you blog post contains code snippets and has to deal only with the SuperOffice or related API&amp;rsquo;s, then select Developer. If your post contains content that can be considered both Technical and Developer orientated, then select them both and the blog post will appear under each Center.&lt;/p&gt;&#xD;
&lt;p&gt;If you do not select either, the post will only appear on the front page and your My-Page.&lt;/p&gt;&#xD;
&lt;p&gt;Unfortunately, due to our use of Categories as "Blog is visible in this club", you can not adding tags to your posts here in WLW. To add tags you must open the post in the online editor on the website and add the tags in the dialog. Adding tags does have a few benefits, including the discoverability and visibility in the tag-cloud, so please do use them.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1297_1109.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="RefreshCategories" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1298_1110.jpg" alt="RefreshCategories" width="604" height="396" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h3&gt;Syntax Highlighting&lt;/h3&gt;&#xD;
&lt;p&gt;To be compatible with the scripts and markup we&amp;rsquo;re using on the site to support syntax highlighting, I recommend using PreCode, the Code Snippet Manager application is located on Codeplex at&amp;nbsp; &lt;a title="http://precode.codeplex.com/" href="http://precode.codeplex.com/"&gt;http://precode.codeplex.com/&lt;/a&gt;. It works nicely against the &amp;lt;pre&amp;gt; syntax we&amp;rsquo;re using and hope you will find it useful. It certainly makes differentiating between normal paragraphs and code much easier.&lt;/p&gt;&#xD;
&lt;p&gt;There seems to be one caveat to using this though, and it&amp;rsquo;s not necessarily this editors problem but an issue without code snippets on the web site. They don&amp;rsquo;t like to be edited.&amp;nbsp; So just try and make sure the snippet is perfect before committing it, otherwise you&amp;rsquo;ll find yourself clicking the HTML toolbar item in the TinyMCE editor and tweaking the angle brackets trying to make it look nice again.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1304_1116.jpg"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="Precode" src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/8/35608/1305_1117.jpg" alt="Precode" width="604" height="486" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h3&gt;In Conclusion&lt;/h3&gt;&#xD;
&lt;p&gt;The only thing left now is to write away. Pick a topic near and dear to your heart &amp;ndash; that concerns SuperOffice of course, and publish at will.&lt;/p&gt;&#xD;
&lt;p&gt;Your contributions to the community will quite possibly reward you will feedback in the comments, and will most certainly reward you will Citizen Points and your SuperOffice DevNet standings.&lt;/p&gt;&#xD;
&lt;p&gt;Good luck to you and thanks for your interest in becoming a DevNet Rockstar.&lt;/p&gt;</description><a10:updated>2012-03-20T13:04:20+01:00</a10:updated></item><item><guid isPermaLink="false">36ea381b-8091-4d35-9c1c-bc229c02e323</guid><link>http://devnet.superoffice.com/Blog/?entryId=755</link><author>margrethe@superoffice.com</author><title>Product Issue Center = Bug/wish overview and release notes</title><description>&lt;p&gt;Did you all see the Product Issue Center, the link down on the third column &lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1268_1054.jpg" alt="" width="612" height="161" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Here you will find a overview of all logged bugs and wishes from CRM 7 and up, and you may also search for our logged issues.&lt;/p&gt;&#xD;
&lt;p&gt;On the right side you find the Top 5 list, the blue heading is clickable and will bring up the list where you choose the different product/areas.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1272_1059.jpg" alt="" width="300" height="200" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Below you find the list of your reported and your tracked bugs. You may choose to track the status of all bugs, there's a small checkbox below each bug report when you open it up.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1271_1061.jpg" alt="My bugs" width="267" height="226" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This is also where you find our release notes:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/74/30574/1270_1063.jpg" alt="Release notes" width="260" height="117" /&gt;&lt;/p&gt;</description><a10:updated>2012-01-19T09:31:53+01:00</a10:updated></item><item><guid isPermaLink="false">ea4c0888-22c3-4744-9423-2870293659a3</guid><link>http://devnet.superoffice.com/Blog/?entryId=661</link><author>Christian.Mogensen@superoffice.com</author><title>TFS and Specifications</title><description>&lt;p&gt;Here at SuperOffice R&amp;amp;D we have always used specifications to plan work on new features. We have a long tradition of doing lots of design + prototyping work up front. User Experience Design is one of our a core strengths, and good UX takes a fair amount of work before you give it to the team to implement.&lt;/p&gt;&#xD;
&lt;p&gt;So when we moved over to TFS we were trying to figure out how to integrate our spec-driven design workflow into the TFS pipeline that the development teams wanted to use.&lt;/p&gt;&#xD;
&lt;p&gt;The problem we faced was two-fold:&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;We like to use lots of illustrations in our specifications, which TFS work items supports using attachments, but not in-line with the text. &lt;br /&gt;You can imagine what this blog post would be like with all the pictures on separate pages instead of in-line with the text &lt;img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://devnet.superoffice.com/blog/content/binary/Windows-Live-Writer/27c10d1a472e_8476/wlEmoticon-smile_2.png" alt="Smile" /&gt;&lt;/li&gt;&#xD;
&lt;li&gt;We like to update the specifications as we uncover new details &amp;ndash; so having a diff and a list of chapters with changes is useful. The specification is not a static thing.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;The solution we came up with has four parts:&lt;/p&gt;&#xD;
&lt;ol&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Specification documents &lt;/strong&gt;are worked on as before, with rich text and screen mockups. The DOCX files are checked into TFS. The design team edits + updates the files as they have always done.&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Custom Word Ribbon &lt;/strong&gt;to make it easy to create work items based on chapters in a DOCX file. The ribbon inserts the work item id into the text.&lt;/li&gt;&#xD;
&lt;li&gt;&lt;strong&gt;Regularly scheduled document splitter task &lt;/strong&gt;on the TFS server that grabs the latest DOCX files, converts each file to HTML and splits it into chapter sized chunks of HTML.&amp;nbsp; The system also computes the diff whenever a fragment changes, and posts the diff to the work-item history, so developers + QA can easily see what changed in the spec.&lt;/li&gt;&#xD;
&lt;li&gt;The &lt;strong&gt;User Story work item &lt;/strong&gt;uses a web-control to display the corresponding HTML fragment. This makes it easy for the developer to view the feature description and the illustrations in context.&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h1&gt;Specification Documents&lt;/h1&gt;&#xD;
&lt;p&gt;These are just word documents with pictures and headings.&lt;/p&gt;&#xD;
&lt;p&gt;Typically we will have a structure like this:&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Introduction&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A &lt;/span&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Screen&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Dialog&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Sub Dialog&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B&lt;/span&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B Screen&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B special consideration&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Tech Details&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;Each chapter maps to a user story (roughly). Each chapter starts with a picture or illustration of the desired part of the feature. Sometimes a feature will exist in multiple variations (basic, plus, full-blown) with more stuff added each time. In these cases the additions are highlighted in the pictures.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1072.jpg" alt="image_thumb_1.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The advantage of working with a MSWord document rather than the user story items directly is that context and &lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1073.jpg" alt="image_thumb.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Word has a new ribbon we&amp;rsquo;ve built for making user-stories + test cases based on the document contents.&lt;/p&gt;&#xD;
&lt;p&gt;We select a root User Story using the ribbon. We typically have a special user story to represent the spec as a whole that all chapter stories are linked to as children.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1074.jpg" alt="image_thumb_6.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This tree of work items can be seen in TFS using the new hierarchy queries:&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1075.jpg" alt="image_thumb_8.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This makes the user stories easier to find, and makes it easy to get a look at the progress made within a spec.&lt;/p&gt;&#xD;
&lt;p&gt;You don&amp;rsquo;t have to do this kind of hierarchy &amp;ndash; but we find it gives us a bit more structure.&lt;/p&gt;&#xD;
&lt;p&gt;Anyway &amp;ndash; having selected the work item that new work items will be parented to, we can go through the spec with the team, using the ribbon to create User Stories out of chapters.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1076.jpg" alt="image_thumb_4.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;When we come to a new chapter heading, we place the cursor in the chapter and click the CREATE USER STORY button.&lt;/p&gt;&#xD;
&lt;p&gt;This displays the simplified USER STORY DIALOG. Most values are copied from the parent user story (Assigned To, Area, Iteration).&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1077.jpg" alt="image_thumb_5.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Clicking OK creates the work item in TFS. The work item id is inserted into the heading, so that document splitter can match the chapter with the work item.&lt;/p&gt;&#xD;
&lt;p&gt;The work items are used for prioritizing and scheduling. Previously we would mark certain chapters in the spec as &amp;ldquo;for later&amp;rdquo;; now we can leave the spec alone and just edit the work item &amp;ldquo;Priority&amp;rdquo; field instead.&lt;/p&gt;&#xD;
&lt;p&gt;When the review is finished, the headings have all been decorated with work items.&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Introduction&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A #123&lt;/span&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Screen #124&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Dialog #125&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature A Sub Dialog #126&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B&lt;/span&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B Screen #127&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Feature B special consideration #128&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="background-color: #ffff00; font-family: Comic Sans MS;"&gt;Tech Details #129&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;The review ends and the updated specification document is checked in to TFS.&lt;/p&gt;&#xD;
&lt;p&gt;Checking the document into TFS triggers a server task.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h1&gt;Regularly Scheduled Doc Splitter Task&lt;/h1&gt;&#xD;
&lt;p&gt;A dusty server sits in a rack and runs a scheduled task every 10 minutes:&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Sync the Documents folder from TFS to the local file system.&lt;/li&gt;&#xD;
&lt;li&gt;Run a through all the documents in the Documents folder:&lt;/li&gt;&#xD;
&lt;li&gt;If a document has changed in the last 15 minutes:&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;Convert the document to HTML&lt;/li&gt;&#xD;
&lt;li&gt;Run through the HTML document and split each chapter into a separate HTML file. Use the id found in the chapter title as the filename. &lt;br /&gt;e.g. &amp;ldquo;Add System Event Dialog #1574&amp;rdquo; &amp;ndash;&amp;gt; 1574.html&lt;/li&gt;&#xD;
&lt;li&gt;Compare the new chapter HTML document with the previous version.&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;If there is a diff, write the diff to the TFS work item history.&lt;/li&gt;&#xD;
&lt;li&gt;If there is a diff, change the TFS work item state to &amp;ldquo;Spec Changed&amp;rdquo;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;li&gt;Overwrite the previous version with the new chapter HTML document.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;The chapter-sized HTML files are copied to a a website folder, where a simple ASP.net page takes a work-item-id as a parameter, and redirects to the page if the page file exists. You could link directly to the chapter files, but then you get ugly error messages when the file doesn&amp;rsquo;t exist. We prefer the intermediate step &amp;ndash; so we can do something more useful (like display the user story description when there is no chapter file present).&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h1&gt;User Story Web Control&lt;/h1&gt;&#xD;
&lt;p&gt;The Work Item Template for &lt;strong&gt;User Story&lt;/strong&gt; has been altered &amp;ndash; we have added a new tab for Specifications which contains a single large web-control.&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1078.jpg" alt="image_thumb_9.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;The web-control passes the work-item id in the URL.&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1079.jpg" alt="image_thumb_7.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;The website digs out the file with the work-item id in the filename and redirects to it, giving the developer this view:&lt;/p&gt;&#xD;
&lt;p align="center"&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1080.jpg" alt="image_thumb_2.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;This web panel displays the images and text from the corresponding chapter in the spec.&lt;/p&gt;&#xD;
&lt;p&gt;The history tab tracks the work item changes and also shows the changes in the spec:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="/EPiServerCommunity/Modules/ImageGallery/Thumbnails/20/30520/1081.jpg" alt="image_thumb_3.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;h1&gt;Summary&lt;/h1&gt;&#xD;
&lt;p&gt;This is a simple and straightforward way for us to get our specification workflow plugged into TFS without forcing too many changes on how we work with our designs.&lt;/p&gt;&#xD;
&lt;p&gt;The web panels give us read-only access to the specification.&amp;nbsp; In an ideal world we would be able to directly edit the spec in the work item, but not having this hasn&amp;rsquo;t stopped the spec viewer from being useful.&lt;/p&gt;&#xD;
&lt;p&gt;Having the relevant part of the specification easily available and up-to-date is vital if the result is going to resemble the design. When the design sketches + descriptions are in easy reach of the developer, the work that is handed over to QA is much closer to what QA is testing for.&lt;/p&gt;&#xD;
&lt;p&gt;The QA team can develop test plans based on the spec chapters when the spec broken into small User Story pieces.&lt;/p&gt;&#xD;
&lt;p&gt;We have discovered that we are writing our specs differently &amp;ndash; we are breaking features into smaller pieces. When we have several variations of a feature, each variation gets a separate chapter &amp;ndash; this makes backlog management simpler.&lt;/p&gt;</description><a10:updated>2012-01-11T16:51:36+01:00</a10:updated></item></channel></rss>
