+22
Under review

Sharing Virtual Column Code

mark 7 years ago updated by Bartosz Gumula 23 hours ago 77

I'm just trying to find a place to share virtual column code...

+2

We used this code to add vendor Paypal email address to the vendor view.

#if(!$unwrappedThis.getDefaultPaymentMethod().getCustomFields().get("Owner email"))
#else
$unwrappedThis.getDefaultPaymentMethod().getCustomFields().get("Owner email")
#end


Hello Mark, 


Did you use this to see the vendor PayPal address on the Vendor Payment Methods page? If so, under which Class Name?

+1

Alexandros:


We predominantly use it on the Vendor Invoice page. So when we have confirmed invoices, we can pull out PayPal addresses, export them and easily pay these invoices. But it also appears on the Vendor view page.


The page you're showing isn't where it shows up. From there we'd still have to click on PayPal >> Custom Fields >> Owner Email.

The class is "Vendor".

I used it in the vendors view to be able to download the vacations in JSON format through API (you mustn't use any space for formating otherwise it will ruin the json format). This is a disgusting workaround, but at least works:


#set($vendor = $utils.unwrap($this))
#set($json='')
#foreach($vacation  in $vendor.vacations)
#if ($json=='')#set($json='[')
#else#set($json=$json + ',')#end
#set($json = $json + '{"startDate":"' + $vacation.startDate + '", "endDate":"' + $vacation.endDate + '"}')
#end
#if ($json!='')#set($json=$json + ']')#end
$json


Thanks Mark and Viktor! Will test as soon as I get the chance.

We have this one to get the quote accepted date. I'm not sure where it came form. but it's very slow. We have to many projects. For each quote it has to get all the projects and that doesn't seem very effective.


#set($projectService = $utils.getService('com.radzisz.xtrf.service.ProjectService'))
#set($quoteName = $utils.unwrap($this).name)
#if($utils.unwrap($this).getStatus()=="ACCEPTED")
#foreach($project in $projectService.getAll())
#if($project.name.equals($quoteName))
$project.getCreatedOn()
#end
#end
#else
<font color="#d3d3d3"></color>$utils.unwrap($this).getStatus()</font>
#end

Why don't you search for the ProjectID? Quote ID and project ID is the same, and there is a function in the ProjectService named getByIdNumber. Try it.

I will give it a try. Is there any link to the documentation so that I can find the functions of project service?

I downloaded from an password safed place. Helpdesk will help you, just ask them.

I gave it a try:


#set($projectService = $utils.getService('com.radzisz.xtrf.service.ProjectService'))
#set($quoteId = $utils.unwrap($this).QuoteId)
$quoteId
#if($utils.unwrap($this).getStatus()=="ACCEPTED")
#set($project = $projectService.getByIdNumber($quoteId))
#if($project)
$project.getCreatedOn()
#end
#else
<font color="#d3d3d3"></color>$utils.unwrap($this).getStatus()</font>

#end


but now it's giving this error: 

line 5:Invalid method: getByIdNumber (in fact it may be valid method that returns null) Methods with similar name: getByIdNumber(String)

The quoteId had a correct value (I'm talking about smart projects)

I think you need to use IdNumber, not QuoteId

+3

And here's one to show the time to/from a job deadline in living color:

#set ($unwrappedUtils = $utils.unwrap($utils))
#set($now=$utils.sub($unwrappedUtils.currentDate.time,0))
#set ($deadline = $utils.unwrap($this).deadline)
#set($diff_ms=$utils.sub($deadline.time, $now))
#set($hours=$utils.div($diff_ms, 3600000))
#if ($hours<0) #set($hours=$utils.mul($hours, -1)) <font color="red">$utils.roundUp($hours,2) hours late</font>
#else
#if ($hours<2) <font color="orange">$utils.roundUp($hours,2) hours left</font>
#else $utils.roundUp($hours,2) hours left #end
#end
+2

This will show if the vendor does have an active portal account:


#set($acc =$utils.getService("com.radzisz.xtrf.service.providerPortal.ProviderPortalService").hasAccountInPortal($utils.unwrap($this).getId()))
#if($acc == true)
<font color="green">YES</font>
#else
<font color="red">NO</font>
#end


Does this only wok for Vendor Contact Persons, or overall Vendors too? We have a similar column, but when used in the Vendor view (not Vendor Contact Persons) some show with "???" in this field and I'm trying to figure out why.

Hi Meghan,

In your case this column still refers to Vendor Contact Person even if it is added on Vendors scope. Can you please check if the Vendor with "???" has any Vendor Contact Persons added? 


Regards,

Bartosz

Hi Bartosz, 

Thanks for your reply! I just checked, and the few that I looked at with "???" do indeed have contact persons associated. Do you have any other ideas?

Hello again Meghan,

I really can't think of another case it could fail to render an output other than missing Vendor CP without taking a look at particular case. Can you please create a support ticket for our Helpdesk with all the details (including View on which it happens and particular Vendors as well) so I can check why you're experiencing such issue? 


I've run some tests of the code you were provided with and it run perfectly fine with all the test cases, but maybe there's something missing - as I said, please share it with our HD so I can do some additional checks on the cases where it fails. 


Kind regards,

Bartosz

Thanks Bartosz! Actually Maksimilian just told me this on the my ticket related to this:


"This column was designed to be used on Vendor Contact Person so it will not display the data correctly when used on the Vendors view.
Please try using the Contact Person's view and see if the data is displayed properly for contact persons of vendors mentioned in your previous message."


The ticket is XHD-16337 which has the details you mention if you'd like to take a look - thanks! 


+1

Hello again Meghan,

Thanks for a ticket number, that was really helpful. I did some additional digging and I have to agree with Maksymilian - actually, I'm really wondering why it IS working at some cases, but that's the case for another time I believe. :) 


I've made some changes to your column to make it work on Vendors scope as well - it's uploaded as a new one to your production instance. Maksymilian will share all the details via support ticket. :) 


Kind regards,

Bartosz

Thanks so much Bartosz, I like the new column! After a little experimenting, it seems that the "???" appears for the other column (topic of this thread) when there is no default accounting contact (from the invoicing tab) assigned for a given vendor.

Hi Meghan,

I'm glad to hear that you like it!


Please feel free to ask if you have any other questions. 


Have a wonderful day,

Bartosz

+2

Copied from another thread


I think with these few steps you can get a long way:

1. use the javadoc for reference

2. use the velocity user guide for the coding language

3. most of the objects within xtrf are hard coupled, so every object (for instance quote) has enough functions to get you where you want, for instance getActivities() or getTasks(). 

4. if you cannot find the functions (in my case it was getting receivables for a quote) you could look at the index-all.html and search for receivable. Then you find getAllReceivables() and figure out how XTRF has their codebase made up.

5. Want to access a static method, use this code: 

#set($String='')
#set($RateOriginStatic=$String.class.forName('com.radzisz.xtrf.model.rate.RateOrigin'))

6. Use the $utils for all utils functionality (VelocityUtils in javadoc), think of creating instances, retrieving enums, set some formatting.

7. Sometimes you cannot access a field, try debugging by adding .class to the parent field and check if it is the correct Type. Is it a DynaBean object, use $utils.unwrap($field) to get the inner class.

8. If you need to access some object that ends with Service, you should create it using the $utils as well, for instance: 

#set($taskService = $utils.getService("com.radzisz.xtrf.service.TaskService")) 
+1

And some valueable when working with arrays.
If you need to know the size/length/count of the array use this:

#set($size = $list.size())

If you need to get a specific item in the list, use this. Start counting with 0.

#set($item = $list.get(0))

And to add items to an array, you need to use a dummy variable with #set:


#set($rdata=[])

#foreach( $receivable in $task.projectFinance.allReceivables) ## Go through all the receivables in the tasks
#set($add_to_row=$rdata.add($receivable.activityType.displayName)) ## Job type

#end

Hi Dennis,


What do you mean by the javadoc and  index-all.html ? 

Can you point me in the right direction to find these?

+1

You have to ask it from XTRF. This is on a secured page.

+1

Here is one to get a list of file names per task:


#set($t = $utils.unwrap($this))

#foreach($f in $t.getInputWorkfilesForStatistics())

$f.getName()<br>

#end


And this one with a little more detail, including no of words and pages:


#set($t = $utils.unwrap($this))

#foreach($f in $t.getInputWorkfilesForStatistics())

$f.getName() - $f.getFileStats().getWordCount() words - $f.getFileStats().getPageCount() page(s)<br>

#end


Hi,

Does anyone know how to get these fields into a virtual column in a job view:

- instructionsForAllJobs

- instructionsForJob


This would be a great help for us!

Thx.

Why do you need a virtual column for the internal job instruction? 

Well, if I add the "internal job instruction" column to the view, the instructionsforalljobs is not in there. And that's the column I need.

Hi,

Did you ever manage to get this working? We're struggling with the same at the moment. We need to retrieve some specific info from the Instructions for this job only field and show it in a virtual column on Project level, but we cannot figure out how to access it. If anyone could point us in the correct direction, it would be much appreciated!

There was another post about pulling word counts for reporting purposes. See this exchange here. Credit to Laszio.


http://xtrf.userecho.com/forums/8-questions-answers/topics/763-trying-to-export-number-of-words-translated/



+4

On the Projects module, this shows the margin of a given project. We have it set to be in red for less than %40


#if(${this.margin}<.4)<center><span style="color: #ff0000;">${this.marginDisplay}</span></center>#else<center>${this.marginDisplay}</center>#end

+1

Some views for the Vendor module -

Here are 2 different options for showing if Terms and Conditions are signed by each vendor:

1)  ${this.acceptanceOfTermsAndConditions.acceptanceType.displayName}

2) Uses green "OK" and red "NO" (but does not indicated if they were marked by PM as in option 1) 

#if(${this.acceptanceOfTermsAndConditions.acceptanceType.displayName}=='Not Accepted')<p style="text-align: center;"><span style="color: #ff0000;"><strong>NO</strong></span></p>#else<p style="text-align: center;"><span style="color: #00FF00;"><strong>OK</strong></span></p>#end

This shows the date that terms were accepted:


${this.acceptanceOfTermsAndConditions.acceptanceType.displayName}


+1

A slightly modified version of Jussi Rautio's earlier posted version, showing the deadline itself in color instead of time remaining/late. format. Also only adds the color for open projects.


#set ($unwrappedUtils = $utils.unwrap($utils))
#set($now=$utils.sub($unwrappedUtils.currentDate.time,0))
#set ($deadline = $utils.unwrap($this).deadline)
#set($diff_ms=$utils.sub($deadline.time, $now))
#set($hours=$utils.div($diff_ms, 3600000)) #if ($hours<0 && $utils.unwrap($this).status =="OPENED") #set($hours=$utils.mul($hours, -1)) <span style="color: #ff0000;">$utils.xtrfDateUtils.formatDateHour($utils.unwrap($this).deadline)</font>
#else
#if ($hours<2 && $utils.unwrap($this).status =="OPENED") <span style="color: #EB9100;">$utils.xtrfDateUtils.formatDateHour($utils.unwrap($this).deadline)</span>
#else $utils.xtrfDateUtils.formatDateHour($utils.unwrap($this).deadline)
#end
#end




Does anyone know the field name in Smart Projects for the name of a Step so I can build a virtual column for this missing column in job-level smart views? I searched high and low in the documentation and tried several field names that contained a combination with WorkflowStep..., but could never get the right info at job level. I am also not sure whether any combination with Workflow only relates to fields in Classic.


This is the field I am trying to make visible on job level:



Any ideas are much appreciated. Thank you.

Hi Sancho,


I have tried many times to retrieve these values by macro/virtual column, but the documentation doesn't contain anything for the jobs for Smart Projects. And as XTRF repeatedly say: Smart Projects shouldn't be handled through macro's. Though I still disagree, this is what we have to deal with.

There is one way though, but it's a tricky one and you should consider this carefully. Within the API, you can retrieve the jobs of a single project (or quote). I refer to /v2/projects/{projectId}/jobs. You could create a virtual column that calls your api and retrieve the jobs. Though this is a slow operation, it makes your requirement probably possible.

Thanks for your insight, Dennis. Much appreciated!

Hi all,

Does anyone know how to display a list of all file extensions or file names in Work File folder (from all tasks in Classic Project)?

Virtual Column in a project view.


Regards,

Maciej

Hi Maciej,


You can adapt my suggestion above to get the list at project level. Something like this:


#set($p = $utils.unwrap($this))
#foreach($t in $p.getTasks())
#foreach($f in $t.getInputWorkfilesForStatistics())
$f.getName()<br>
#end
#end


This is exactly what I was looking for!

Thank you!

Hello,

Would there be a way to similarly display files from the Reference File folder?

Related: can these methods be found in the Javadoc or is there separate documentation for Virtual Columns?

+1

Came up with this (it shows all files with their directory name, which isn't exactly what I was looking for but still works).

#set($t = $utils.unwrap($this))
#foreach($f in $t.getInputFiles())
$f.getCategorisedRelativeDirWithName()<br>
#end

Has the address for the API documentation changed? Previously it was: https://repo.xtrf.eu/soft/tools/apidocs/


I am trying to find the field names for these two Job Payables parameters. Any suggestions while I am without the current documentation? Support confirmed that virtual columns have to be created to retrieve this information.



+1

We have been assigned a specific url, just for us. Which is https://simplytranslate.s.xtrf.eu/api/doc

But I guess, when you log in, you have a different prefix, try to change the 'simplytranslate' part with the prefix you have, and it should work. You could also just use our link.


The screenshot you have added isn't showing up unfortunately.


Let's see whether the screenshot shows now.

Thanks for your reply, Dennis. Even though the API documentation link does not work for us, we were now told that a special customization disclaimer has to be confirmed before gaining access to the documentation. I guess XTRF has had a few issues with "home-made" customizations malfunctioning.

Did anyone have an idea?

Do you want to access it by API, or by macro/virtual column?

+1
Under review

Sancho,

First of all, please ask our Service Desk for the latest Javadoc package.


Secondly, no matter which version of Javadoc package you have and if I am not mistaken (and it has been a while since I last had to do with macros etc.), look for getActivities. Jobs were previously known as "Activities". ActivityCharge is what you should be looking for if you mean regular payable. You can then use methods like: getCalculationUnit, getRate, getQuantity etc.


Hope that helps.

+1

Good one.
I have looked it up in the documentation, and this are the exact names:

$project.getActivities() // array of Activity
$activity.getAllPayables() // array of BaseProjectActivityCharge (returns both CAT payables as regular payables)

$baseProjectActivityCharge.getQuantity() // BigDecimal 
$baseProjectActivityCharge.getRate() // BigDecimal

+1

Thank you very much, Dennis. Sorry for the late reply. Had a family emergency, but back in the office again. Hope I can reciprocate one of these days, but you are the API/Java king  :o)

You're welcome. I hope everything is fine with you and your family!

+1

Hello, 

We created a virtual column to show in the provider selection view the CAT Tool(s) used by each provider. Here is the code:

#set($p = $utils.unwrap($this))
 #foreach($t in $p.getCatToolsAsArray())
 $t.getDisplayName()<br>
#end

The type is obviously HTML, Class Name is Provider.

Thanks a lot for sharing. Very useful for the Assign Vendor popup window.


Thanks a lot! We also implemented this.

+1

Here is a slight modification for this, used in the Availability Requests page. We needed it so we could see if the providers who answered are using Memsource or Studio so we can then change the workflow accordingly.

Class: Availability Request
Name: Anything you like :)

Type: HTML

Code:


#set($p = $utils.unwrap($this).getProviderPriceProfile().getProvider())
#foreach($t in $p.getCatToolsAsArray())
$t.getDisplayName()<br>
#end


Hello,


Thank you very much for sharing this useful code.

Currently, we want to add a custom column to the vendors view that will show if a vendor has feedback or not.

This way it will be easy to spot if a vendor had problems in the past. However, I cannot find a way to do this.

Also the column feedback is not available in the standard vendor view.


Anyone that can help me on the right track?


Thank you in advance!

Hi,


Unless I am mistaken, I think feedback is added on a Job/Task/Project level and not on the actual provider. So, you would need to go through each job performed for every provider in the view and check if there has been feedback or not (and display it, if you want) which would be a very resources intense task.
If the evaluation is not sufficient for you, perhaps you can add a custom field like "Negative feedback received" and show that and then visit the provider's profile to check the feedback?

Hi Alexandros,

Thank you for your input.

A custom field might probably be the easiest solution. Thanks!

Hello everyone, sharing few more snippets of Velocity/Groovy code that could be helpful for someone.


Clients contact language - Apache Velocity, Client Class

${utils.unwrap($this).Preferences.locale}

+1

Archived projects password - Groovy, Project Class


if(unwrappedThis.isArchived()){
def projectArchivingData = unwrappedThis.getProjectArchivingData()
def archivePassword = projectArchivingData.getArchivedProjectFilePassword()
return archivePassword
} else return "Project is not archived"

I have been using this and it's been very helpful.

Quote Notes - Apache Velocity, Invoices Class

#set( $brc = ${utils.unwrap($this)})
#set( $proj = "FR-2000-000")
#set( $notes = "")
#foreach ($invTask in $brc.getTasks())
#if($invTask.getProject().getIdNumber() != $proj)
#set( $proj = $invTask.getProject().getIdNumber())
#set($null = $invTask.getProject().getQuote().getNotes())
#if ($null != "")
#set( $notes = $notes + $null)
#end
#end
#end
$notes

Quote Amount and Number - Apache Velocity, Invoices Class

#set( $brc = ${utils.unwrap($this)})
#set( $proj = "FR-2000-000")
#set( $amount = 0.00)
#foreach ($invTask in $brc.getTasks())
#if($invTask.getProject().getIdNumber() != $proj)
#set($new = $invTask.getProject().getCustomFields().getNumberField1())
#set($proj = $invTask.getProject().getIdNumber())
#set( $amount = $amount + $new)
$proj

#end
#end
#if ($amount == $brc.getTotalNetto())
Sum: $amount.setScale(2)
#elseif ($amount != 0)
Sum: $amount.setScale(2)
#end

These are great. Thanks!!

anyone happens to have the code to show discounts/surcharges of each task/receivable of a smart quote?

I believe that it looks something like this for tasks 

#set( $discount = 0.0)
#set($taskFinance = ${utils.unwrap($this).getProjectFinance()})
#foreach( $receivable in $taskFinance.getAllReceivables() )
#set( $discount = $discount + $receivable.getTotalDiscountOrSurchargeValue())
#end
$!discount

This should give you total amount of discount or surcharge for all receivables.


Example:

thanks a lot Janis! I'll give it a try and keep you informed!

Hi all,

Thank you sharing all this.

We have a little problem with the vendor invoices. Each PM creates their own vendor invoices, but XTRF does not capture the PM name of the person that created the vendor invoice. (With the client invoices it gets captured under "invoice signatory".)

Is there anyway to realize this with a virtual column? Can I capture the PM name from the project of the jobs on the vendor invoice with a virtual column?

Thanks in advance.

Wim

+1

Ok, after trying some things, I was able to figure it out. Here it is if someone else wants it:

#set($t = $utils.unwrap($this))
$t.getActivitiesList().get(0).getProjectManager().getFullName()

This will only get the name of the PM of the first job on the invoice.

If you want all the names of the PMs of all the jobs, you can do a for each loop.

Has anyone tried creating a virtual column that would display all tasks, deadlines and WC/WWC a vendor currently has in work? For example, in the Providers tab a column would display this info as: [WC] [project number] [deadline] [client] [task name].

Hi!

I am looking for a way to display the number of calculation units for each of the quotes.

The report "Client Calculation Units' does not work as, for some reason, it does not show rejected quotes. (already reported to XTRF). Probably it will be tagged as a feature not bug ;) 

Is anyone aware of a way to access the "All Payables Value" column when creating a custom column for use on Jobs views? I'd like to perform a calculation on that value and display the results as a Jobs-scope custom column.

In the UI it is simply called "All Payables Value" and provides a total of all payables before any surcharges or discounts have been applied.

I was able to resolve this. In case it is helpful for anyone else in the future, I just calculated the "All Payables Value" myself by cycling through each individual payable and adding the value up one at a time using the getTotalValue() method. This should give you the total value of all payables before surcharges/discounts/minimums.

Hi all, 

I am looking for an option to change the status of  many price profiles of a vendor, XTRF does not have multiple change there and API endpoint is also non existent.

Did anyone have had such an issue and managed to deal with it?