Create Deep Entity SAPUI5 - Item Data Not Transmitted - odata

I used to the following tutorial to build a Fiori app with a deep entity (I used invoice header + items): https://blogs.sap.com/2017/07/18/steps-to-create-deep-insert-odata/
Everything works fine until I start debugging in the backend. The service sends the data correctly, in the backend, however, the items are missing. Backend code:
METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.
DATA custom_create_deep_entity TYPE zcl_xxx_mpc_ext=>ts_deep_entity.
CASE iv_entity_set_name.
WHEN 'xxxSet'.
CALL METHOD me->custom_create_deep_entity
EXPORTING
iv_entity_name = iv_entity_name
iv_entity_set_name = iv_entity_set_name
iv_source_name = iv_source_name
it_key_tab = it_key_tab
it_navigation_path = it_navigation_path
io_expand = io_expand
io_tech_request_context = io_tech_request_context
io_data_provider = io_data_provider
IMPORTING
er_deep_entity = custom_create_deep_entity.
copy_data_to_ref(
EXPORTING
is_data = custom_create_deep_entity
CHANGING
cr_data = er_deep_entity
).
ENDCASE.
ENDMETHOD.
METHOD custom_create_deep_entity.
DATA: lr_deep_entity TYPE zcl_xxx_mpc_ext=>ts_deep_entity,
lt_items TYPE zcl_xxx_mpc=>tt_zinvoiceitem,
ls_items TYPE zcl_xxx_mpc=>ts_zinvoiceitem.
io_data_provider->read_entry_data(
IMPORTING
es_data = lr_deep_entity ).
ls_header_input = VALUE #(
bukrs = lr_deep_entity-bukrs
wrbtr = lr_deep_entity-wrbtr
).
LOOP AT lr_deep_entity-items ASSIGNING FIELD-SYMBOL(<ls_item>).
"never reached because 'items' is empty
ENDLOOP.
er_deep_entity = VALUE #(
bukrs = ls_header_input-bukrs
wrbtr = ls_header_input-wrbtr
items = lr_deep_entity-items
).
ENDMETHOD.
Redefined DEFINE method in class MPC_EXT:
METHOD define.
super->define( ).
DATA:
lo_annotation TYPE REF TO /iwbep/if_mgw_odata_annotation,
lo_entity_type TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
lo_complex_type TYPE REF TO /iwbep/if_mgw_odata_cmplx_type,
lo_property TYPE REF TO /iwbep/if_mgw_odata_property,
lo_entity_set TYPE REF TO /iwbep/if_mgw_odata_entity_set.
lo_entity_type = model->get_entity_type( iv_entity_name = 'Zxxxxxx' ).
lo_entity_type->bind_structure( iv_structure_name = 'ZCL_XXX_MPC_EXT=>TS_DEEP_ENTITY' ).
ENDMETHOD.
Do I need to redefine any other methods that prohobit transferring the item data?
Thanks :)

How does the structure zcl_xxx_mpc_ext=>ts_deep_entity. looks like ?
Change the names of the navigations and the underlying structure name for the navigation according to the types mentioned in Types tab in ‘__MPC_EXT’ class of your project. [Source]
How does your payload look like while calling the Service ?
If the payload look's right you clearly have a problem with your structure ts_deep_entity

Review your ts_deep_entity. Make sure your deep structure or table type name inside is identical to your entity sets from segw data model.

Related

Complex type in a define method for `Upload` in UI5

I'm using FileUploader element and in backend, I redefined the DEFINE method.
The value, Mimetype, and filename fields are in a separated complex type inside the entity. I set the checkbox media for entity Data = true.
My define method:
SUPER->DEFINE( ).
LO_ENTITY = MODEL->GET_ENTITY_TYPE( IV_ENTITY_NAME = 'Data' ).
IF LO_ENTITY IS BOUND.
LO_ENTITY->GET_CMPLX_TYPE_PROPERTY( 'ComplexType' )->GET_COMPLEX_TYPE( )->GET_PROPERTY( 'Mimetype' )->SET_AS_CONTENT_TYPE( ).
ENDIF.
But I still get the error Invalid or no mapping to system data types.
Is complex type and media maybe not working?
I'm not sure about complex types but I recently solved this exact issue. Try the following code, it should work.
super->define().
DATA: lo_entity TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
lo_property TYPE REF TO /iwbep/if_mgw_odata_property.
lo_entity = model->get_entity_type( iv_entity_name = 'Data' ).
IF lo_entity IS BOUND.
lo_property = lo_entity->get_property( iv_property_name = 'value' ).
lo_property->set_as_content_type( ).
lo_property = lo_entity->get_property( iv_property_name = 'Mimetype' ).
lo_property->set_as_content_type( ).
lo_property = lo_entity->get_property( iv_property_name = 'filename' ).
lo_property->set_as_content_type( ).
ENDIF.

How would I use Automapper in this query?

Given
Dim postviewmodel As IEnumerable(Of be_PostsViewModel)
postviewmodel = _postRepository.SelectAll.Select(Function(S) New
be_PostsViewModel With {.PostIsPublished = S.PostIsPublished, .Id =
S.PostId, .PostSummary = S.PostSummary, .PostDateCreated =
S.PostDateCreated,
.PostCategory = S.PostCategory, .PostTitle =
S.PostTitle}).Where(Function(p)
p.PostIsPublished = True).Where(Function(a) Not
a.PostCategory.FirstOrDefault.CategoryName = "Lead Story")
.Skip((Page - 1) * PageSize).Take(PageSize)
How would I use Automapper so I don't do all thmapping of properties by hand? I am completely new to it and have been doing a lot of reading but don't quite understand how to actually do it. I know I have to create the map and then call Mapper.map. But what goes where in Mapper.map?
I would do this:
Mapper.CreateMap<Post, be_postsViewModel>();
Do that in your application startup (App_Start etc). Then in your code above:
postViewModel = _postRepository.SelectAll.Project.To(Of be_PostsViewModel)
However, I'd put the "Project.To" AFTER all of your Where/Skip/Take pieces. The projection is the last thing you want to do. Project.To creates that exact Select expression, passes it to the query provider to modify the SQL at its base.
Unless SelectAll doesn't return IQueryable, then you have other, larger problems.

How can I update table in Entity framework?

I am calling a web service from my MVC project and if it is successful then it returns process complete. This result, I am storing in variable called y.
var y = Here pass required parameters and if it is successfull store result in y
when I put breakpoint here and if process complete, I can see result in var y.
So if process complete I need to update my table. For this can I do like this ?
if( y = "Process complete")
{
update table code here
}
and I don't know how to update table in Entity Framework. Here I need to update table called table1 and set column2 = 1, column 3 = value of column 4 where column 1 = value of column 1.
What I know for this is :
UPDATE tableName
SET column2 = 1, column3 = context.FirstOrDefault().column4
WHERE column1 = context.FirstOrDefault(). column1
Update :
Hi i got to know how to write code to update table.But when i put break-point and come to savechanges method i am getting Property export is part of the objects key information and cannot be modified error.
This is the code i am using to update my table :
var rec = (from s in geton.table_1
where s.on_id == geton.table_1.FirstOrDefault().on_id
select s).FirstOrDefault();
rec.export = 1;
rec.on_date = geton.table_1.FirstOrDefault().on_date;
geton.SaveChanges();
A new entity can be added to the context by calling the Add method on DbSet. This puts the entity into the Added state, meaning that it will be inserted into the database the next time that SaveChanges is called.
For example:
using (var context = new YourContext())
{
var record = new TypeName { PropertyName = "Value" };
context.EntityName.Add(record );
context.SaveChanges();
}
For More Info :
http://msdn.microsoft.com/en-us/library/bb336792.aspx
http://msdn.microsoft.com/en-us/data/jj592676.aspx
http://www.entityframeworktutorial.net/significance-of-savechanges.aspx
Hi i got to know how to write code to update table.But when i put break-point and come to savechanges method i am getting Property export is part of the objects key information and cannot be modified error.
That sounds more like a Key error. Are you sure you have put a primary key on that table?
If not then EF just uses the whole table as the key essentially

Breeze import with entity extended property of ko.observableArray() throwing error

Running into an error during import for entities extended with a ko.observableArray() property, vs. being extended as a simple array [] type in the constructor.
var customerCtor = function () {
this.extendedProp = ko.observable(true);
//this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
this.extendedArray = []; // this works just fine
};
I created a test along-side the Breeze v1.3.6 DocCode: exportImportTests.js "stash entire cache locally and restore" as my starting point, and here is the new test:
test("w/extended Customer, stash entire cache locally and restore", 3, function () {
var em1 = newEm();
var store = em1.metadataStore;
// extend Customer with observables
var customerCtor = function () {
this.extendedProp = ko.observable(true);
this.extendedArray = ko.observableArray(); // causes error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
//this.extendedArray = []; // but this will work just fine?
};
store.registerEntityTypeCtor("Customer", customerCtor);
var expected = testData.primeTheCache(em1);
// grab first Customer, push value onto extendedArray prop
var custEntity = em1.getEntities(expected.customerType)[0];
custEntity.extendedArray().push('some-value'); // even when defined as [], Breeze re-writes field as ko.observable
var exportData = em1.exportEntities();
var stashName = "stash_everything";
window.localStorage.setItem(stashName, exportData);
var importData = window.localStorage.getItem(stashName);
var em2 = new EntityManager(); // virginal - so register ctor on this instance
var store2 = em2.metadataStore;
store2.registerEntityTypeCtor("Customer", customerCtor);
em2.importEntities(importData);
var entitiesInCache = em2.getEntities();
var restoreCount = entitiesInCache.length;
equal(restoreCount, expected.entityCount,
"should have restored expected number of all entities");
var restoredCustomer = em2.getEntities(expected.customerType)[0];
ok(restoredCustomer.extendedProp(), 'extended property present');
ok(restoredCustomer.extendedArray().length > 0, 'extended Array present and has data');
});
An em2.importEntities(importData); throws the error:
Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
at Error (<anonymous>)
at h [as extendedArray] (http://localhost:47595/Scripts/knockout-2.2.1.js:44:167)
at ctor.initializeEntityPrototype.proto.setProperty (http://localhost:47595/Scripts/breeze.debug.js:14634:31)
at updateTargetPropertyFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13062:24)
at aspectName (http://localhost:47595/Scripts/breeze.debug.js:13025:13)
at Array.forEach (native)
at updateTargetFromRaw (http://localhost:47595/Scripts/breeze.debug.js:13023:19)
at em._inKeyFixup (http://localhost:47595/Scripts/breeze.debug.js:12601:17)
at Array.forEach (native)
at importEntityGroup (http://localhost:47595/Scripts/breeze.debug.js:12568:28)
As Breeze always rewrites constructor fields (in my case for KO), defining as [] works. But not sure why this would happen when the property is pre-defined?
Anyone run into this, or have I missed a doc note somewhere?
We'll look at it.
Yes, Breeze assumes every property added in a constructor is supposed to be rewritten per the prevailing "model library" which, in your case, is KO. Therefore, no surprise that the array becomes a ko.observableArray.
Moreover, because such a property is presumed to be under Breeze's jurisdiction, we have to tie it into Breeze observability and serialization mechanisms which means we re-write it as a Breeze-flavored observable array. Such an array is a computed.
Evidently there is some problem with the way we're doing this for a property which is "unmapped". We'll look at that.
N.B.: I am assuming (and your code confirms) that the array property, extendedArray, is an "unmapped property" in the Breeze sense. That should be fine.
You should not mention mapped collection navigation properties in your constructor. There is no valid reason to do so that I can think of. The main reason to mention a mapped property in the constructor is (a) to give it a default value or (b) make it available to a custom (unmapped) computed property. There is no reasonable alternative default value for a collection navigation property (empty is the default) and it would be rare/avoidable to include it in a computed.

SOAPpy - create a Jira issue and define a component?

I can't figure how to create a jira issue and define its component with SOAPpy:
client = so.WSDL.Proxy(cfg_wsld)
auth_token = client.login(cfg_username, cfg_password)
issue_params = dict()
issue_params['project'] = project
issue_params['type'] = issue_type
issue_params['summary'] = summary
issue_params['description'] = summary
newissue = client.createIssue(auth_token, issue_params)
This sample works fine but I try to add components to it Jira will return missmatchTypeException.
I've tried all kinds of variants: passing arrays, strings, ints into it but it won't pick any of them up.
Most attempts (passing string, int, array of both) will cause TypeMissmatch, this causes NullPointerException inside Jira:
issue_params['components'] = {u'Разное': {'id': '11143', 'name': u'Разное'}}
I know the exact id of the issue type I want to use but how do I pass it properly? When I retrieve an issue with this type components returns as SOAPpy.Types.typedArrayType() but this still fails:
issue_params['components'] = so.Types.typedArrayType(data={'id': '11143', 'name': u'Разное'})
newissue = client.createIssue(auth_token, issue_params)
(<class 'SOAPpy.Errors.Error'>, <Error : Data must be a sequence>, None)
issue_params['components'] = so.Types.typedArrayType(data=[{'id': '11143', 'name': u'Разное'},])
This did the trick - data needs to be an array.

Resources