FOS Elastic range price with discount - symfony

I want to get all the products by range price with discount.
this is what it looks like in sql:
WHERE (
CASE WHEN p.discount IS NOT NULL THEN ROUND(
p.unit_price * (100 - p.discount) / 100, 1)
ELSE p0_.unit_price END ) >= :min
AND (
CASE WHEN p.discount IS NOT NULL THEN ROUND(
p.unit_price * (100 - p.discount) / 100, 1)
ELSE p0_.unit_price END ) <= :max
is there a way to do the same with range condition?
$fieldRange = new \Elastica\Query\Range('unitPrice', array('gte' => 300, 'lte' => 1500));
here is my config:
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
indexes:
product:
properties:
unitPrice:
type: integer
discount:
type: keyword
attributeValues:
type: "nested"
properties:
value:
type: keyword
product:
type: keyword
persistence:
driver: orm
model: App\Entity\Product
provider: ~
listener: ~
finder: ~
here is the full query:
$query = new \Elastica\Query();
$query->setSize(0);
$boolQuery = new \Elastica\Query\BoolQuery();
/* filter checked */
$fieldQuery = new \Elastica\Query\Match();
$fieldQuery->setFieldQuery('attributeValues.value', 'Brand');
$domainQuery = new \Elastica\Query\Nested();
$domainQuery->setPath('attributeValues');
$domainQuery->setQuery($fieldQuery);
$fieldQuery2 = new \Elastica\Query\Match();
$fieldQuery2->setFieldQuery('attributeValues.value', 'Another Brand');
$domainQuery2 = new \Elastica\Query\Nested();
$domainQuery2->setPath('attributeValues');
$domainQuery2->setQuery($fieldQuery2);
$fieldRange = new \Elastica\Query\Range('unitPrice', array('gte' => 300, 'lte' => 1500));
$boolQuery->addMust($domainQuery);
$boolQuery->addMust($domainQuery2);
$boolQuery->addMust($fieldRange);
$query->setQuery($boolQuery);
$agg = new \Elastica\Aggregation\Nested('attributeValues', 'attributeValues');
$names = new \Elastica\Aggregation\Terms('value');
$cardinality = new \Elastica\Aggregation\Cardinality('unique_products');
$cardinality->setField('attributeValues.product');
$names->setField('attributeValues.value');
$names->setSize(100);
$names->addAggregation($cardinality);
$agg->addAggregation($names);
$query->addAggregation($agg);
$companies = $this->finder->findPaginated($query);
$asd = $companies->getAdapter()->getAggregations();
here is the result:
array(
"attributeValues" => array:2(
"doc_count" => 406,
"value" => array:3(
"doc_count_error_upper_bound" => 0,
"sum_other_doc_count" => 0,
"buckets" => array:42(
2 => array:3(
"key" => "Another Brand",
"doc_count" => 15,
"unique_products" => array:1(
"value" => 9
)
)
)
)
)
);
here is native request (just in case):
{
"size": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "attributeValues",
"query": {
"match": {
"attributeValues.value": {
"query": "Brand"
}
}
}
}
},
{
"nested": {
"path": "attributeValues",
"query": {
"match": {
"attributeValues.value": {
"query": "Another Brand"
}
}
}
}
},
{
"range": {
"unitPrice": {
"gte": 300,
"lte": 1500
}
}
}
]
}
},
"aggs": {
"attributeValues": {
"nested": {
"path": "attributeValues"
},
"aggs": {
"value": {
"terms": {
"field": "attributeValues.value",
"size": 100
},
"aggs": {
"unique_products": {
"cardinality": {
"field": "attributeValues.product"
}
}
}
}
}
}
}
}
a little explanation - I am making a smart filter that disables options when there are no products in it, which I calculate with this query. But I don't know how to calculate the price range with a discount (%) in elastica. I show how I do it in sql.

Related

Groovy to collect and remove duplicates from a complex json structure

this is my first question at Stack Overflow, so, firstly, Hello colleagues and many thanks in advance.
I have this json input message I'm dealing with, but I cannot find the key to get the message I need for further processing
{
"callId": "70f354ed47e643bc9d1cd6595e018f9b",
"errorCode": 0,
"apiVersion": 2,
"statusCode": 200,
"statusReason": "OK",
"time": "2022-08-01T07:56:34.631Z",
"results": [
{
"UID": "5abc8d08d8e148158610c7c6776c4ad5",
"groups": {
"organizations": [
{
"businessModels": [
{
"keys": [
"Company Code",
"Sales Org",
"Distribution Channel",
"Division"
],
"businessEntities": [
{
"codes": [
"HU50",
"HU50_HU50",
"HU50_HU50_10",
"HU50_HU50_10_10"
]
}
],
"id": "SalesArea_161185"
},
{
"keys": [
"ShiptoInc_SalesArea",
"ShiptoInc_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"100563692"
]
},
{
"codes": [
"HU50_HU50_10_10",
"100563691"
]
}
],
"id": "ShiptoInc_161185"
},
{
"keys": [
"Payer_SalesArea",
"Payer_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"960004763"
]
}
],
"id": "Payer_161185"
}
]
}
]
}
},
{
"UID": "d9f2b591f58e4aeebaa0b88175d4fe3c",
"groups": {
"organizations": [
{
"businessModels": [
{
"keys": [
"Company Code",
"Sales Org",
"Distribution Channel",
"Division"
],
"businessEntities": [
{
"codes": [
"HU50",
"HU50_HU50",
"HU50_HU50_10",
"HU50_HU50_10_10"
]
}
],
"id": "SalesArea_161185"
},
{
"keys": [
"ShiptoInc_SalesArea",
"ShiptoInc_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"100563692"
]
},
{
"codes": [
"HU50_HU50_10_10",
"100563691"
]
}
],
"id": "ShiptoInc_161185"
},
{
"keys": [
"Payer_SalesArea",
"Payer_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"960004763"
]
}
],
"id": "Payer_161185"
}
]
}
]
}
},
{
"UID": "74a9ccbc9b8549d1a7726ac1f77f7ea9",
"groups": {
"organizations": [
{
"businessModels": [
{
"keys": [
"ShiptoInc_SalesArea",
"ShiptoInc_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"100563692"
]
}
],
"id": "ShiptoInc_161185"
}
]
}
]
}
},
{
"UID": "d5ed356a3c2a48568ccacb8d9c7c5506",
"groups": {
"organizations": [
{
"businessModels": [
{
"keys": [
"Company Code",
"Sales Org",
"Distribution Channel",
"Division"
],
"businessEntities": [
{
"codes": [
"HU50",
"HU50_HU50",
"HU50_HU50_10",
"HU50_HU50_10_10"
]
}
],
"id": "SalesArea_161185"
},
{
"keys": [
"ShiptoInc_SalesArea",
"ShiptoInc_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"100563692"
]
},
{
"codes": [
"HU50_HU50_20_20",
"100563692"
]
},
{
"codes": [
"HU50_HU50_10_10",
"100563691"
]
}
],
"id": "ShiptoInc_161185"
},
{
"keys": [
"Payer_SalesArea",
"Payer_Id"
],
"businessEntities": [
{
"codes": [
"HU50_HU50_10_10",
"960004763"
]
}
],
"id": "Payer_161185"
}
]
}
]
}
}
],
"objectsCount": 4,
"totalCount": 4
}
For a known id ("Payer_161185" or "ShiptoInc_161185") and a given value ("100563692") we need to extract all repetitions of businessEntities.codes of all UIDs and after get the list, remove duplicates.
For example, for "ShiptoInc_161185", the desired output would be:
{ "salesAreas": ["HU50_HU50_10_10","HU50_HU50_20_20"]}
This output is the list of salesAreas for the given value 100563692 into all the id = ShiptoInc_161185
Other case that I would like to solve is:
How could I add the id instead of text salesAreas?. Something like this {"Payer_111":["HU50_HU50_10_10","HU50_HU50_30_20"],"Payer_222":["HU40_HU40_10_10","HU20_HU20_30_20"]}. This means the id wouldn't be provided, just the prefix Payer_
Your help is appreciated.
***I solved the second requirement
def data = new JsonSlurper().parseText(body);
def bModelsIdFiltered = data.results.groups.organizations.businessModels
.collect { it[0] }.flatten()
.findAll { it.id.contains('Payer_') }
def nList = [];
def rembM = bModelsIdFiltered.each{
it.businessEntities.codes.each { code ->
nList.add(code.plus(it.id))
}
}
println "nl " + nList;
def codesFiltered = nList
.findAll { '100563692' in it }
return codesFiltered;
If the structure is rigid and i understood the task correctly (namely, you should find codes that have value 100563692 in the same array), you can doing it like that:
class FindCodesSpec extends Specification {
def testString = '''<insert_your_string_here>'''
def flattenOnce(List array) {
return array.inject([]) { res, el -> res + el }
}
def findCodes(String message, String id, String code) {
def data = new JsonSlurper().parseText(message)
def bModelsIdFiltered = data.results.groups.organizations.businessModels
.collect { it[0] }.flatten()
.findAll { it.id == id }
def codesFiltered = flattenOnce(bModelsIdFiltered.businessEntities.codes)
.findAll { code in it }
def uniqueCodes = codesFiltered.flatten().unique() - code
return JsonOutput.toJson(['salesAreas': uniqueCodes])
}
def 'run test'() {
expect:
'''{"salesAreas":["HU50_HU50_10_10","HU50_HU50_20_20"]}''' == findCodes(testString, 'ShiptoInc_161185', '100563692')
}
}

using toJSON: How to get an array nested in a data.frame into a JSON object

I am trying to convert a data.frame into JSON text. How can I include an array in this data.frame? I.e. the variable characteristics needs to contain multiple elements. I do not succeed in this.
Here is my code:
data <- data.frame(sequenceNbr = c(1:3),
requestTypeCode = "MR001",
managementStartingDate = format(Sys.Date(),"%Y-%m-%d"),
TopicCode = "TH02",
Nbr = c("1760448", "6580364", "1391363"),
TypeCode = "R003008",
char1 = "CK001001", char2 = "CK001002",
stringsAsFactors = FALSE) %>%
group_by(sequenceNbr) %>%
nest( Assignment=c(TopicCode),
entity = c(Nbr),
ToControl = c(TypeCode),
characteristics = c(char1,char2)
)
data <- data %>%
mutate( Assignment = purrr::map(Assignment, as.list),
entity = purrr::map(entity, as.list))
json <- jsonlite::toJSON(list(`DefList`=data),
auto_unbox = TRUE, pretty = TRUE)
This gives as output
{
"DefList": [
{
"sequenceNbr": 1,
"requestTypeCode": "MR001",
"managementStartingDate": "2020-06-16",
"Assignment": {
"TopicCode": "TH02"
},
"entity": {
"Nbr": "1760448"
},
"ToControl": [
{
"TypeCode": "R003008"
}
],
"characteristics": [
{
"char1": "CK001001",
"char2": "CK001002"
}
]
},
{
"sequenceNbr": 2,
"requestTypeCode": "MR001",
"managementStartingDate": "2020-06-16",
"Assignment": {
"TopicCode": "TH02"
},
"entity": {
"Nbr": "6580364"
},
"ToControl": [
{
"TypeCode": "R003008"
}
],
"characteristics": [
{
"char1": "CK001001",
"char2": "CK001002"
}
]
}
]
}
What I want as output is this (there is a difference in the characteristics-element):
{
"DefList": [
{
"sequenceNbr": 1,
"requestTypeCode": "MR001",
"managementStartingDate": "2020-06-16",
"Assignment": {
"TopicCode": "TH02"
},
"entity": {
"Nbr": "1760448"
},
"ToControl": [
{
"TypeCode": "R003008"
}
],
"characteristics": [
"CK001001",
"CK001002"
]
},
{
"sequenceNbr": 2,
"requestTypeCode": "MR001",
"managementStartingDate": "2020-06-16",
"Assignment": {
"TopicCode": "TH02"
},
"entity": {
"Nbr": "6580364"
},
"ToControl": [
{
"TypeCode": "R003008"
}
],
"characteristics": [
"CK001001",
"CK001002"
]
}
]
}
It should also work when characteristics contains only one value. Any idea's? I think the data.frame structure is the limiting factor, since it cannot contain an array. I see in this post : https://blog.exploratory.io/working-with-json-data-in-very-simple-way-ad7ebcc0bb89 that it is correct JSON syntax, but I do not manage to obtain it. Thanks in advance for your help.

DevExtreme: Return Object from Spring Rest Api does not bind with dxDataGrid

Could any one help me how could I bind data object with DevExtreme's dxDataGrid using customstore.
My DTO is like:
[
data: {...},
totalCount: 100,
summary: [10,20,30]
]
But when i bind the data with dxDataGrid it just bind data but not totalCount.
I have found a solution for my problem.
[remoteOperations]="true"
I need remoteOperations = true to bind the totalCount along with data fetched from the server.
You don't need to send a totalCount, you have to use the summary section istead, look at this sample
$("#gridContainer").dxDataGrid({
dataSource: orders,
keyExpr: "ID",
showBorders: true,
selection: {
mode: "single"
},
columns: [{
dataField: "OrderNumber",
width: 130,
caption: "Invoice Number"
}, {
dataField: "OrderDate",
dataType: "date",
width: 160
},
"Employee", {
caption: "City",
dataField: "CustomerStoreCity"
}, {
caption: "State",
dataField: "CustomerStoreState"
}, {
dataField: "SaleAmount",
alignment: "right",
format: "currency"
}
],
summary: {
totalItems: [{
column: "OrderNumber",
summaryType: "count"
}]
}
});
Data Source
var orders = [{
"ID" : 1,
"OrderNumber" : 35703,
"OrderDate" : "2014-04-10",
"SaleAmount" : 11800,
"Terms" : "15 Days",
"TotalAmount" : 12175,
"CustomerStoreState" : "California",
"CustomerStoreCity" : "Los Angeles",
"Employee" : "Harv Mudd"
}, {
"ID" : 4,
"OrderNumber" : 35711,
"OrderDate" : "2014-01-12",
"SaleAmount" : 16050,
"Terms" : "15 Days",
"TotalAmount" : 16550,
"CustomerStoreState" : "California",
"CustomerStoreCity" : "San Jose",
"Employee" : "Jim Packard"
}....
]
For custom summaries you can use this
summary: {
totalItems: [{
name: "SelectedRowsSummary",
showInColumn: "SaleAmount",
displayFormat: "Sum: {0}",
valueFormat: "currency",
summaryType: "custom"
}
],
calculateCustomSummary: function (options) {
if (options.name === "SelectedRowsSummary") {
if (options.summaryProcess === "start") {
options.totalValue = 0;
}
if (options.summaryProcess === "calculate") {
if (options.component.isRowSelected(options.value.ID)) {
options.totalValue = options.totalValue + options.value.SaleAmount;
}
}
}
}
}
In the section if (options.summaryProcess === "calculate") { you can put your custom calc logic, in this case your total count.

CSS Color table based on input in each row

Would it be possible to color each table rows based on a input in a specific column for each row?
Example, if:
B1 = 1 // Red row
B2 = 1 // Red row
B3 = 3 // Blue row
B4 = 2 // Green row
B5 = 1 // Red row
And so on?
It's a datatable and there will automatically be filled new rows into the table, these should also be coloured after the system.
Demo
var dataSet = [['Dadar', 'lmsSenitaD', 'Atul salaskar', '9876543210', '', 'Not Joined', '10/01/2014', '', 'Come back and Join', 'Mobile', 'Times','1'],
['Aundh', 'Rashmi', 'Preeti Gupta', '9876543210', '', 'Not Joined', '10/01/2014', '', 'Will Discuss with Family', 'Online Campaign', 'Iksula','2'],
['Do#Home_Thane', 'Rashmi', 'Mitali Gupta', '9876543210', '', 'Joined - Old Date', '10/01/2014', '20/08/2014', 'Come back and Join', 'Online Campaign', 'Iksula','4']];
$(document).ready(function () {
$('#demo').html('<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"></table>');
$('#example').dataTable({
"data": dataSet,
"columns": [
{ "title": "Center" },
{ "title": "Call Executive" },
{ "title": "Name" },
{ "title": "Mobile" },
{ "title": "Phone" },
{ "title": "Status" },
{ "title": "Appt Date" },
{ "title": "Joined Date" },
{ "title": "Remark" },
{ "title": "Source" },
{ "title": "Publisher" },
{ "title": "css" },
]
,
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
var css = aData[aData.length - 1];
if (css == "1") {
$(nRow).addClass('gradeN');
}
else if(css == "2") {
$(nRow).addClass('gradeC');
}
else{
$(nRow).addClass('gradeM');
}
}

How to insert into mongoDB from HTML page

var productDB = new Meteor.Collection('products'); //Want to insert into this DB
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ); //Taking Paramters from Another DB
Template.dpVar.events = {
'click .addProduct' : function (e) {
e.preventDefault();
ProductParameters.forEach(function(){ **//This is my Question.How to insert into productDB the key values as {ProductParameters: Val of ProductParameters}**
console.log(ProductParameters);
var pvariable = {
pvariable: tmpl.find("#ProductParameters").value
};
productDB.insert(pvariable);
});
}
};
Problem:
I have created form from the Parameters of nodeDB.
I want to store the data from this new form in a new DB productDB.
I want to run a loop where all the ProductParameters are read from nodeDB and their corresponding values inserted in form by user are pushed into ProductDB as new Entry.
EDIT:
NodeDB has Templates:
db.nodes.insert([
{
"GEOLOCATION": {
"GEO_CODE": [],
"ACTIVE_GEOLOCATION": false
},
"META": {
"CATEGORY": "levis",
"DESCRIPTION": "dsad",
"PRIVACY": "PUBLIC",
"TEMPLATE_NAME": "B",
"TEMPLATE_GROUP": "Product",
"KEYWORDS": [
"sda"
],
"CREATEDBY": "",
"SUBCATEGORY": "Blue",
"PRODUCT_TEMPLATE_TYPE": "Consumable",
"UOM": "",
"TEMPLATE_SUBGROUP": ""
},
"VARIENTS": [
{
"COMMENT": "Demo",
"INDEX": 0,
"NAME": "Brand",
"IS_PARENT": false,
"DATATYPE": "Text",
"ACCESS": "PUBLIC",
"PARENT_VARIENT": "Parem",
"TYPE": "PERMANENT"
}
]
}
])
The form is generated only from the VARIENTS
The ProductDB would be {key,value} ={VARIENTS.NAME,value from UI}
There can be multiple VARIENTS as this contains only one "Brand"
instead of
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } );
add .fetch() at the end
var ProductParameters = nodeDB.find({"ACTIVE" : 1, "VARIENTS.ACCESS" : "PUBLIC"}, { "VARIENTS.NAME": 1, _id : 0 } ).fetch();

Resources