How to insert mant-to-many object - backand

I have two structures very similar to pests-owners, this is my structure:
{
"name": "Contratti",
"fields": {
"rischicontratti": {
"collection": "RischiContratti",
"via": "Contratti"
},
"intervento": {
"collection": "Interventi",
"via": "Contratto"
},
"Numero": {
"type": "string"
},
"Impresa": {
"object": "Imprese"
},
"Oggetto": {
"type": "string"
}
},
{
"name": "RischiContratti",
"fields": {
"Contratti": {
"object": "Contratti"
},
"Rischio": {
"object": "Rischi"
}
}
},
{
"name": "Rischi",
"fields": {
"rischicontratti": {
"collection": "RischiContratti",
"via": "Rischio"
},
"rischi_interventi": {
"collection": "rischi_interventi",
"via": "Rischio"
},
"Rischio": {
"type": "string"
}
}
When I'm inserting a Contratto I want to also insert all related Rischi. Is there a way to post all in one call? Or do I have to post first the Contratto and then loop each Rischi?

Related

Generated OpenAPI golang client doesn't seem to handle dates correctly?

I'm working on an API that provides a list of transactions. I'm writing it in Java/Kotlin Spring, but prefer golang for CLIs, so I'm generating a golang client for it. The API works well in the Swagger UI.
Kotlin API:
#GetMapping
fun listTransactions() : ResponseEntity<List<Transaction>> {
val transactions = ArrayList<Transaction>()
transactionRepository.findAll().mapTo(transactions) { fromEntity(it) }
return ResponseEntity.ok(transactions)
}
Kotlin Object:
data class Transaction(
val id: Long,
val transactionDate: Date, // Java SQL date
val postedDate: Date?, // Java SQL date
val amount: BigDecimal,
val category: Category,
val merchant: Merchant,
val merchantDescription: String?
)
Generated Schema:
{
"openapi": "3.0.1",
"info": {
"title": "BFI Swagger Title",
"description": "BFI description",
"version": "0.1"
},
"servers": [{
"url": "http://localhost:8080",
"description": "Generated server url"
}],
"paths": {
"/transaction": {
"get": {
"tags": ["transaction-router"],
"operationId": "listTransactions",
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Transaction"
}
}
}
}
}
}
},
"post": {
"tags": ["transaction-router"],
"operationId": "createTransaction",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateTransactionRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "OK",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Transaction"
}
}
}
}
}
}
},
"/hello": {
"get": {
"tags": ["category-router"],
"summary": "Hello there!",
"operationId": "hello",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Category"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"CreateTransactionRequest": {
"type": "object",
"properties": {
"transactionDate": {
"type": "string",
"format": "date-time"
},
"postedDate": {
"type": "string",
"format": "date-time"
},
"amount": {
"type": "number"
},
"categoryId": {
"type": "integer",
"format": "int64"
},
"merchantId": {
"type": "integer",
"format": "int64"
},
"merchantDescription": {
"type": "string"
}
}
},
"Category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"note": {
"type": "string"
}
}
},
"Merchant": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"note": {
"type": "string"
}
}
},
"Transaction": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"transactionDate": {
"type": "string",
"format": "date-time"
},
"postedDate": {
"type": "string",
"format": "date-time"
},
"amount": {
"type": "number"
},
"category": {
"$ref": "#/components/schemas/Category"
},
"merchant": {
"$ref": "#/components/schemas/Merchant"
},
"merchantDescription": {
"type": "string"
}
}
}
}
}
}
Golang Client Object:
type Transaction struct {
Id *int64 `json:"id,omitempty"`
TransactionDate *time.Time `json:"transactionDate,omitempty"`
PostedDate *time.Time `json:"postedDate,omitempty"`
Amount *float32 `json:"amount,omitempty"`
Category *Category `json:"category,omitempty"`
Merchant *Merchant `json:"merchant,omitempty"`
MerchantDescription *string `json:"merchantDescription,omitempty"`
}
All of this seems correct enough. However, when I use the OpenAPI client, it seems like deserialization isn't working correctly:
Error when calling `TransactionRouterApi.ListTransactions``: parsing time "\"2022-10-28\"" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "\"" as "T"
Full HTTP response: &{200 200 HTTP/1.1 1 1 map[Content-Type:[application/json] Date:[Sat, 29 Oct 2022 04:03:31 GMT]] {[{"id":1,"transactionDate":"2022-10-28","postedDate":"2022-10-28","amount":0.00,"category":{"id":1,"name":"test","note":"test"},"merchant":{"id":1,"name":"test","note":"test"},"merchantDescription":null},{"id":2,"transactionDate":"2022-10-28","postedDate":"2022-10-28","amount":0.00,"category":{"id":1,"name":"test","note":"test"},"merchant":{"id":1,"name":"test","note":"test"},"merchantDescription":null},{"id":3,"transactionDate":"2022-10-28","postedDate":"2022-10-28","amount":0.00,"category":{"id":1,"name":"test","note":"test"},"merchant":{"id":1,"name":"test","note":"test"},"merchantDescription":null}]} -1 [chunked] false false map[] 0x140001daf00 <nil>}
Response from `TransactionRouterApi.ListTransactions`: [{0x140000aa218 0001-01-01 00:00:00 +0000 UTC <nil> <nil> <nil> <nil> <nil>}]
Am I doing something incorrectly that results in deserialization failing? Or is this a client bug (seems doubtful, but who knows).
I've looked at the generation arguments I used and the schema available at my endpoint, and they both appear correct.
Script executed: openapi-generator-cli generate -g go -i http://localhost:8080/v3/api-docs
Two options:
Create a custom type and implement the Unmarshaler interface for the date fields.
Return valid RFC 3339 date/times from the API.

Unomi use of UpdatePoperties event to enrich profil

We are tring to enrich a profil using UpdateProperties event.
Something wrong, it didn't work.
Step of our process :
Search of the profil :
Use of the prive API /profiles/search
So we find a profil and get the profilId "60de10fe-e6ff-11ec-8fea-0242ac120002" for next step.
Enrich profil :
Use of the API public /context.json to post the json
{
"sessionId": null,
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"events": [
{
"itemType": "event",
"scope": "myScope",
"eventType": "updateProperties",
"properties": {
"update": {
"properties.age": "24"
},
"add": {
"properties.kids" : "1"
}
}
}
]
}
Response :
{
"profileId": "60de10fe-e6ff-11ec-8fea-0242ac120002",
"sessionId": null,
"profileProperties": null,
"sessionProperties": null,
"profileSegments": null,
"profileScores": null,
"filteringResults": null,
"processedEvents": 1,
"personalizations": null,
"trackedConditions": [
{
"parameterValues": {
"operator": "and",
"subConditions": [
{
"parameterValues": {
"formId": "zoneLeadFormEvent"
},
"type": "formEventCondition"
}
]
},
"type": "booleanCondition"
},
{
"parameterValues": {
"formId": "testFormTracking",
"pagePath": "/tracker/"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "searchForm"
},
"type": "formEventCondition"
},
{
"parameterValues": {
"formId": "advancedSearchForm"
},
"type": "formEventCondition"
}
],
"anonymousBrowsing": false,
"consents": {}
}
Validation of the profile changes
Get /cxs/profiles/60de10fe-e6ff-11ec-8fea-0242ac120002
So, the properties are not updated.
We use a rules the merge the profil on a custom identifier :
{
"metadata": {
"id": "update_with_custom_identifier",
"name": "UpdateWithCustomIdentifier",
"description": "Copy my properties to profile properties on update"
},
"condition": {
"parameterValues": {
"subConditions": [
{
"parameterValues": {
},
"type": "updatePropertiesEventCondition"
}
],
"operator": "and"
},
"type": "booleanCondition"
},
"actions": [
{
"parameterValues": {
"mergeProfilePropertyValue": "eventProperty::target.properties.myIdentifier",
"mergeProfilePropertyName": "mergeCustomIdentifier"
},
"type": "mergeProfilesOnPropertyAction"
},
{
"parameterValues": {
},
"type": "allEventToProfilePropertiesAction"
}
]
}
What's the good method ?
Thanks in advance

After running my logic app, it shows some error message as" "We couldn't convert to Number.\r\n "

I am collecting data from sensors and upload to AZURE cosmo. My logic app on AZURE keep failing and show the following message
{
"status": 400,
"message": "We couldn't convert to Number.\r\n inner exception: We
couldn't convert to Number.\r\nclientRequestId:xxxxxxx",
"source": "sql-ea.azconn-ea.p.azurewebsites.net"
}
Below are the input data from cosmo. I saw that the input data has shown "ovf" and "inf". I have tried convert the data type of that column to other data type like bigiant and numeric and resubmitted. Still did not fixed that.
{
"Device": "DL084",
"Device_Group": "DLL",
"Time": "2019-09-04T11:45:20.0000000",
"acc_x_avg": "ovf",
"acc_x_stdev": "inf",
"acc_y_avg": "3832.88",
"acc_y_stdev": "2850.45",
"acc_z_avg": "13304.38",
"acc_z_stdev": "2289.86",
"cc_volt": "3.900293",
"cp_volt": "1.940371",
"fp_volt": "0.718475",
"id": "xxxxxxxxxxxxxxxxxxxx",
"ls_volt": "4.882698",
"millis": "1073760.00",
"rs_rpm": "0.00",
"smp_volt": "1.070381"
}
I have also tried to convert the data to string. And it will show
"Failed to execute query. Error: Operand type clash: numeric is
incompatible with ntext"
The question is how can I eliminate this error? How can I know the error is definitely due to the "inf" and "ovf" error?
The logic app code is as below
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"Delete_a_document": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['documentdb']['connectionId']"
}
},
"method": "delete",
"path": "/dbs/#{encodeURIComponent('iot')}/colls/#{encodeURIComponent('messages')}/docs/#{encodeURIComponent(items('For_each')['id'])}"
},
"runAfter": {
"Insert_row": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"Insert_row": {
"inputs": {
"body": {
"Device": "#{item()['device']}",
"Device_Group": "#{items('For_each')['devicegroup']}",
"Time": "#{addHours(addSeconds('1970-01-01 00:00:00', int(items('For_each')['time'])), 8)}",
"acc_x_avg": "#items('For_each')['acc_x_avg']",
"acc_x_stdev": "#items('For_each')['acc_x_stdev']",
"acc_y_avg": "#items('For_each')['acc_y_avg']",
"acc_y_stdev": "#items('For_each')['acc_y_stdev']",
"acc_z_avg": "#items('For_each')['acc_z_avg']",
"acc_z_stdev": "#items('For_each')['acc_z_stdev']",
"cc_volt": "#items('For_each')['cc_volt']",
"cp_volt": "#items('For_each')['cp_volt']",
"fp_volt": "#items('For_each')['fp_volt']",
"id": "#{guid()}",
"ls_volt": "#items('For_each')['ls_volt']",
"millis": "#items('For_each')['millis']",
"rs_rpm": "#items('For_each')['rs_rpm']",
"smp_volt": "#items('For_each')['smp_volt']"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/datasets/default/tables/#{encodeURIComponent(encodeURIComponent('[dbo].[RCD]'))}/items"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"foreach": "#body('Query_documents')?['Documents']",
"runAfter": {
"Query_documents": [
"Succeeded"
]
},
"type": "Foreach"
},
"Query_documents": {
"inputs": {
"body": {
"query": "SELECT \t\t * \nFROM \t\t\tc \nWHERE \t\t\tc.devicegroup = 'DLL' ORDER BY c._ts"
},
"headers": {
"x-ms-max-item-count": 1000
},
"host": {
"connection": {
"name": "#parameters('$connections')['documentdb']['connectionId']"
}
},
"method": "post",
"path": "/dbs/#{encodeURIComponent('iot')}/colls/#{encodeURIComponent('messages')}/query"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Minute",
"interval": 30
},
"type": "Recurrence"
}
}
}
}

Pass an already existing Model to next in Loopback

There is Project model
{
"name": "Project",
"plural": "Projects",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"code": {
"type": "string"
},
"startDate": {
"type": "date",
"required": true
},
"endDate": {
"type": "date"
},
"value": {
"type": "number"
},
"infoEN": {
"type": "string"
},
"infoRU": {
"type": "string"
},
"infoAM": {
"type": "string"
},
"externalLinks": {
"type": [
"string"
]
}
},
"validations": [],
"relations": {
"industry": {
"type": "belongsTo",
"model": "Industry",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"service": {
"type": "belongsTo",
"model": "Service",
"foreignKey": "",
"options": {
"nestRemoting": true
}
},
"tags": {
"type": "hasAndBelongsToMany",
"model": "Tag",
"foreignKey": "",
"options": {
"nestRemoting": true
}
}
},
"acls": [],
"methods": {}
}
And it hasAndBelongsToMany tags
here is Tag model
{
"name": "Tag",
"plural": "Tags",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Now when the relation is created loopback api gives this api endpoint.
POST /Projects/{id}/tags
This creates a new tag into the tags collection and adds it to the project.
But what about adding an already existing tag to the project?
So I figured maybe I add before save hook to the Tag
Here I'll check if the tag exists and then pass the existing one for the relation.
Something like this.
tag.js
'use strict';
module.exports = function(Tag) {
Tag.observe('before save', function(ctx, next) {
console.log(ctx.instance);
Tag.find({name: ctx.instance.name})
next();
});
// Tag.validatesUniquenessOf('name', {message: 'name is not unique'});
};
#HaykSafaryan it just demo to show you how to use tag inside project
var app = require('../../server/server');
module.exports = function(project) {
var tag=app.models.tags
//afterremote it just demo. you can use any method
project.afterRemote('create', function(ctx, next) {
tag.find({name: ctx.instance.name},function(err,result)){
if(err) throw err;
next()
}
});
};
this is just example code to show you how to use update,create ,find ,upsertwithwhere etc. tag for validation you have to setup condition over here it will not take validation which you defined in tags models

TypeError: datastore.getRootCollection is not a function

I assumed a dstore that was created using dmodel was still a dstore and inherited all the dstore functionality. So there's a method listed called getRootCollection but when i try to run this method on the store it fails with an error (no such function)
Here is my code
<script>
require(
[
'dojo/_base/declare',
'dstore/Memory',
'dmodel/extensions/jsonSchema',
'dmodel/validators/StringValidator',
'dmodel/store/Validating',
"dmodel/Model"
],
function (declare, Memory, jsonSchema, StringValidator, Validating, Model) {
var vMem = (declare([Memory, Validating]))({
Model: jsonSchema(
{
"$schema": "http://json-schema.org/draft-04/schema",
"description": "my schema",
"type": "object",
"properties": {
"page": {
"type": "object",
"properties": {
"detailsCanvas": {
"description": "test value",
"type": "object",
"$ref": "#/definitions/details"
}
}
},
"elements": {
"type": "array",
"items": {
"title": "Element",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"positionX": {
"description": "The X coordinate",
"type": "number"
},
"elementSpecificProperties": {
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/label" }
]
}
}
}
}
},
"definitions": {
"details": {
"type": "object",
"properties": {
"height": {
"type": "string"
}
}
},
"label": {
"type": "object",
"properties": {
"value": {
"type": "string"
}
}
}
}
}
)
});
vMem.setData(
{
"page": {
"detailsCanvas": {
"height": "100px"
}
},
"elements": [
{
"id": "1",
"positionX": 20,
"elementSpecificProperties": {
"value": "value_1"
}
},
{
"id": "2",
"positionX": 5,
"elementSpecificProperties": {
"value": "value_2"
}
}
]
});
var blah = vMem.getRootCollection(); //type error - getRootCollection is not a function
});
</script>
getRootCollection() is part of the Tree model of dstore. You only mixin the dstore/Memory. So that is why you get that error. Checkout the documentation of dstore for more information.