Show output values aka conversion-exit values in CDS? - abap

I've created a CDS view, which reads some data from 2 tables.
My problem is, that one of the columns has a conversion policy behind - so if I display the data with SE16n, it shows the "converted value" but within my cds view only the unconverted value is shown.
Is there an option to show converted values in CDS views?

No actually conversion exits are not supported in CDS. But with string conversions you can rebuild the conversion exits.
-> see Documentation

Use Virtual Elements
they can be used to calculate fields that are not available in CDS.
Steps
Add a placeholder field: cast( '' as abap.char(255)) AS after_conversion
Add Annotation #ObjectModel.virtualElement: true to your field
Add Annotation #ObjectModel.virtualElementCalculatedBy: 'ABAP:<z_class>'
Create the Class Z_CLASS
Use interface if_sadl_exit_calc_element_read
In Method calculate you can do the conversion
Here you can see a simple example

Related

ERROR: function regexp_matches(jsonb, unknown) does not exist in Tableau but works elsewhere

I have a column called "Bakery Activity" whose values are all JSONs that look like this:
{"flavors": [
{"d4js95-1cc5-4asn-asb48-1a781aa83": "chocolate"},
{"dc45n-jnsa9i-83ysg-81d4d7fae": "peanutButter"}],
"degreesToCook": 375,
"ingredients": {
"d4js95-1cc5-4asn-asb48-1a781aa83": [
"1nemw49-b9s88e-4750-bty0-bei8smr1eb",
"98h9nd8-3mo3-baef-2fe682n48d29"]
},
"numOfPiesBaked": 1,
"numberOfSlicesCreated": 6
}
I'm trying to extract the number of pies baked with a regex function in Tableau. Specifically, this one:
REGEXP_EXTRACT([Bakery Activity], '"numOfPiesBaked":"?([^\n,}]*)')
However, when I try to throw this calculated field into my text table, I get an error saying:
ERROR: function regexp_matches(jsonb, unknown) does not exist;
Error while executing the query
Worth noting is that my data source is PostgreSQL, which Tableau regex functions support; not all of my entries have numOfPiesBaked in them; when I run this in a simulator I get the correct extraction (actually, I get "numOfPiesBaked": 1" but removing the field name is a problem for another time).
What might be causing this error?
In short: Wrong data type, wrong function, wrong approach.
REGEXP_EXTRACT is obviously an abstraction layer of your client (Tableau), which is translated to regexp_matches() for Postgres. But that function expects text input. Since there is no assignment cast for jsonb -> text (for good reasons) you have to add an explicit cast to make it work, like:
SELECT regexp_matches("Bakery Activity"::text, '"numOfPiesBaked":"?([^\n,}]*)')
(The second argument can be an untyped string literal, Postgres function type resolution can defer the suitable data type text.)
Modern versions of Postgres also have regexp_match() returning a single row (unlike regexp_matches), which would seem like the better translation.
But regular expressions are the wrong approach to begin with.
Use the simple json/jsonb operator ->>:
SELECT "Bakery Activity"->>'numOfPiesBaked';
Returns '1' in your example.
If you know the value to be a valid integer, you can cast it right away:
SELECT ("Bakery Activity"->>'numOfPiesBaked')::int;
I found an easier way to handle JSONB data in Tableau.
Firstly, make a calculated field from the JSONB field and convert the field to a string by using str([FIELD_name]) command.
Then, on the calculated field, make another calculated field and use function:
REGEXP_EXTRACT([String_Field_Name], '"Key_to_be_extracted":"?([^\n,}]*)')
The required key-value pair will form the second caluculated field.

Formatting duration for display

In a SAP database there are values formatted as PxDTyH where x is the number of days and y is the number of hours. A value like P2DT0H is 2 days + 0 hours. I can see that via SE16:
Unfortunately, this is exactly displayed like that to the user, "3" corresponds to the index in the database (not seen in the screenshot above).
I'd like to see it displayed
without the index (changing the options "show keys within drop-down lists" did not have an effect)
instead of the technical name P2DT0H I'd like to see "2 days and 0 hours" (or similar)
Is there a way to process the data before it gets displayed in the combo box? The developers can't change the format in the database because it would change the API.
FYI: I'm just a tester, I don't know how to code in ABAP, but from knowledge of other programming languages, I'd say that the data can be converted before it's displayed. I don't need a fully-fledged answer, just a pointer to a SAP hook or event which enables writing a conversion function.
Probably, conversion routines can be an option for you. What you should do is to:
Take your domain (which is used for PxDTyH values) or create new one specially for this.
Create FM with name CONVERSION_EXIT_%NAME%_OUTPUT, and put conversion logic in there. Mandatory parameters INPUT and OUTPUT should exist.
Enter the %NAME% into Convers.routine field in domain properties.
Enable Check conversion exits checkbox in user parameters.
More info is here.

Sibling model function in Qt5

We had the following code to retrieve data of type TYPE through a model, which is a custom proxy model. This is required by the next QSortFilterProxyModel to make the decision about filtering of elements. The code is actually combined from 2 functions: in the project we usually have some arbitrary index related to some ROW and use it to retrive the data from another predefined column which contains TYPE data.
QModelIndex index = sourceModel()->index(row, COLUMN1, sourceParent); /* sourceParent is always'invalid' - retrieving data from top-level items*/
ModelIndex sibling = index.sibling(row, COLUMN2);
return sibling.data(Qt::EditRole).value<TYPE>();
This worked fine with Qt4 but when moved to Qt5 sibling became 'invalid'. I wonder what has happened, taking into account that the data is actually there, which I see, by changing the code to the following
return sourceModel()->index(sourceRow, COLUMN2, sourceParent).data(Qt::EditRole).value<TYPE>();
-works fine
Looking at the implementation of sibling(), I cannot tell what makes it return an invalid index in your case. Comparing with the Qt4 implementation, maybe it's around the IndexMap use.
But why don't you simply use your solution with sourceModel()->index(sourceRow, COLUMN2, sourceParent), since it already seems to be what you actually want to do?

Displaying dynamic kanban colors according to record state in OpenERP 7

could someone tell me in what way I can display the items in a view kanban with a specific color according to the state that is the record.
I'm trying something like this
<div t-attf-class="#{record.state=='scheduled' ? oe_kanban_color_#{kanban_getcolor(1)} : oe_kanban_color_#{kanban_getcolor(0)}">
but I looked ALL elements and not only those who are in the "scheduled".
Thanks :)
If you have copy/pasted exactly what you typed in the view definition, then your t-attf- class attribute is malformed, and all record will have the following class:
class="#{record.state=='scheduled' ? oe_kanban_color_1 : oe_kanban_color_0"
which, due to CSS class precedence, will cause them all to have the oe_kanban_color_1 style.
A few hints:
To avoid coloring some records, you can omit the oe_kanban_color_X entirely in some cases
You can use a t-att-class attribute to allow arbitrary Javascript expressions, depending on what you want to do. In contrast, t-attf-class only allows replacing placeholders.
When comparing field values with Javascript operators you normally want to use the value or raw_value of the field, rather that the Field object itself. value will only differ from raw_value when the value needs specific rendering, such as dates, numbers, etc.
The kanban_getcolor() function accepts any integer or string and returns one of the 10 default kanban color indexes.
Based on the above, the following might be closer to what you tried to do (note the t-att-class attribute:
<div t-att-class="record.state.value == 'scheduled' ?
'oe_kanban_color_1' :
'oe_kanban_color_0' ">
Alternatively, you could use t-attf-class and let kanban_getcolor() pick a color based on the state string:
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.state.value)}">
That last example is similar to what is done in many default kanban views in the official OpenERP distribution.

Filling parameter with value from Zeconfig_var table

I have the following selection parameter:
PARAMETERS: p_ver(2) AS LISTBOX VISIBLE LENGTH 5.
I would like to populate it with the results from a ZECONFIG_VAR table.
At what point would I do this. Selection Screen Output, Start of Selection, or other. I am trying to allow users the ability to decide what version of the web service they would like to call. The config table will have different url's for the different versions.
I have looked at this Answer and the tutorial provided does not make sense to me.
I would do it at the event INITIALIZATION
However, it may be even easier to just create a search-help, and assign it to p_ver using the following:
parameters: p_ver(2) visible lenghth 5 MATCHCODE OBJECT zshelpname.
Esti is right that you probably want to fill an internal table from the DB table during INITIALIZATION.
But to the populate the listbox parameter, you need to put the call to VRM_SET_VALUES in AT SELECTION-SCREEN OUTPUT.