Extract EntityCustomData Info

Hi All.
Im having a hard time figuring out how to make a query to extract the data from the field EntityCustomData

FIELD
[{“Name”:“Apellido”,“Value”:“Morales”},{“Name”:“Direccion”,“Value”:“Pampa 3000”},{“Name”:“Barrio”,“Value”:“Belgrano”},{“Name”:“Entrecalles”,“Value”:null},{“Name”:“Email”,“Value”:“emorales@asd.com”},{“Name”:“Aniversario”,“Value”:“08/09/1982 0:00”},{“Name”:“Piso”,“Value”:“5”},{“Name”:“Departamento”,“Value”:“C”},{“Name”:“Nombre”,“Value”:“Ezequiel”}]

I tried with substring, mid, charindex, left, combining them but im not an sql pro.

Basically what i need its a Select that returns the different values. All in the same line.
In the example above would be:

Morales Pampa 3000 Belgrano Null emorales@asd.com 08/09/1982 5 C Ezequiel

Each of them in a different column but in the same line.

With this, i hope to make a report to see which are the clients who didnt buy recently.

Hope you can help me with this. Maybe one of you, already did this.

Thanks and Regards,

Easiest would be to use Custom Report Tag {REPORT ENTITY DETAILS:X} because it can parse the JSON data in that field.

Using SQL Server 2014 or less, this is very difficult to do with JSON data.

If you use SQL 2016, it has some support for JSON data to make it easier, and I have used it for various things, but Entity Data is not one of them.

I can look into how to get the data using a Query in SQL 2016, but you should look at Custom Reports first, since it will be quite simple in comparison.

[Customers:1, 1, 1,1]
>>Name|Phone|VIP|Business
{REPORT ENTITY DETAILS:E.Name.asc,EC.Phone,EC.VIP Level,EC.Business:(ET=Customers)}

Thanks Q.
Didnt think about this way.

So if i have this query

Select distinct EntityId,
EntityName,
EntityCustomData,
convert (varchar (10), date ,103)
from Tickets, TicketEntities
where entityid not in
(Select Distinct EntityId
from Tickets,TicketEntities
where TicketEntities.Ticket_Id=tickets.Id
AND DATE > ‘20170406’ AND DATE < ‘20170407’
AND EntityTypeId =‘1’)
AND DATE > ‘20170406’ AND DATE < ‘20170407’
AND EntityTypeId =‘1’
ORDER BY EntityId desc

i have to replace EntityCustomData, with the following? or how can i do it?

{REPORT ENTITY DETAILS:E.Name.asc,EC.Phone,EC.VIP Level,EC.Business:(ET=Customers)}

what i need is to see in the list, the customers who didnt buy between the dates.

Thanks for your help.

Regards,

Well, no, because something like E.Name.asc,EC.Phone would mean nothing to SQL.

Then you need {REPORT TICKET DETAILS:X}

[Customer Purchases:1,1,1,1]
{REPORT TICKET DETAILS:EN.Customers.asc,EC.Phone,T.TotalAmount,T.Date:(TCET=Customers)}

Not sure how to filter for the Date Range, or how to only show Entities who did NOT make a Purchase. I am not that good with Custom Reports.

Are you running SQL 2016? If so, I can put together something using a SQL statement that employs JSON parsing. If not, I won’t bother.

For Ex, EC.Phone. EC is Entity Custom Field in this case Field Name is Phone. So, it depend on how you define the field name.
For Date Range you can input the date in Report Screen.

1 Like

Yes, i understand.
Unfortunely,im not running sql server 2016. Im running 2012.
I have read about sql 2016 and json but i cant go that way.

The problem by doing inside the program is that i dont know how to filter the customers who didnt buy for example in march.

I want to list all the customers that didint make any purchase during march but are in the list of all my customers.

I guess i will try to parse the results in the sql query.

Thanks for your help!

Let me think about it some more and try some things. I have an idea to use SQL and Custom Report together.

For example, if you use {REPORT SQL DETAILS:X} to generate a list of Customer Names or Ids, then feed that list into {REPORT ENTITY DETAILS:X} to be able to use EC.<fieldName> for Custom Fields… it should work.

Im not pretty sure how can i do that… but ill give it a try!
Thanks Again

I’m preparing a REPORT SQL DETAILS tutorial.

Great Emre!
Thanks a lot!

Me First!!! :wink:

SQL to get Customers who have not made a purchase within the date range:

DECLARE @entityType varchar(50) = @1
DECLARE @startDateIn varchar(25) = @2
DECLARE @endDateIn varchar(25) = @3

DECLARE @startDate datetime = convert(varchar(25),@startDateIn,126)
DECLARE @endDate datetime = convert(varchar(25),@endDateIn,126)

SELECT ent.[Name] as [EntityName]
FROM [Entities] ent
WHERE ent.[Id] IN (

SELECT DISTINCT e.[EntityId]

FROM [TicketEntities] e
JOIN [EntityTypes] et on et.[Id]=e.[EntityTypeId]

WHERE 1=1
AND et.[Name]=@entityType
AND e.[EntityId] NOT IN (
	SELECT DISTINCT te.[EntityId]
	FROM [TicketEntities] te 
	JOIN [Tickets] t on t.[Id]=te.[Ticket_Id] 
	WHERE 1=1
	AND t.[Date]>=@startDate 
	AND t.[Date]<=@endDate
)

)
ORDER BY ent.[Name]

We can use that with {REPORT SQL DETAILS:X} either raw as above, or save it as a Script and supply the @@handle

##RAW

[Customer NOT Purchased:1,1,1,1]
>>Name|Phone|VIP|Business
{REPORT SQL DETAILS:
SELECT ent.[Name] as [EntityName]
FROM [Entities] ent
WHERE ent.[Id] IN (

SELECT DISTINCT e.[EntityId]

FROM [TicketEntities] e
JOIN [EntityTypes] et on et.[Id]=e.[EntityTypeId]

WHERE 1=1
AND et.[Name]='Customers'
AND e.[EntityId] NOT IN (
	SELECT DISTINCT te.[EntityId]
	FROM [TicketEntities] te 
	JOIN [Tickets] t on t.[Id]=te.[Ticket_Id] 
	WHERE 1=1
	AND t.[Date]>='2017-04-01' 
	AND t.[Date]<='2017-04-30'
)

)
ORDER BY ent.[Name]
:F.EntityName
}


##SQL Script with @@handler

DECLARE @entityType varchar(50) = @1
DECLARE @startDateIn varchar(25) = @2
DECLARE @endDateIn varchar(25) = @3

DECLARE @startDate datetime = convert(varchar(25),@startDateIn,126)
DECLARE @endDate datetime = convert(varchar(25),@endDateIn,126)

SELECT ent.[Name] as [EntityName]
FROM [Entities] ent
WHERE ent.[Id] IN (

SELECT DISTINCT e.[EntityId]

FROM [TicketEntities] e
JOIN [EntityTypes] et on et.[Id]=e.[EntityTypeId]

WHERE 1=1
AND et.[Name]=@entityType
AND e.[EntityId] NOT IN (
	SELECT DISTINCT te.[EntityId]
	FROM [TicketEntities] te 
	JOIN [Tickets] t on t.[Id]=te.[Ticket_Id] 
	WHERE 1=1
	AND t.[Date]>=@startDate 
	AND t.[Date]<=@endDate
)

)
ORDER BY ent.[Name]

[Customer NOT Purchased:1]
{REPORT SQL DETAILS:@@CustomerNotPurchasedList:'Customers','2017-04-01','2017-04-30':F.EntityName}


So now we need to convert the output of the above Report into a comma-separated list so we can feed it into {REPORT ENTITY DETAILS:X}. We do that by prefixing it with @ and defining the separator as , (comma) …

[Customer NOT Purchased:1,1,1,1]
@{REPORT SQL DETAILS:@@CustomerNotPurchasedList:'Customers','2017-04-01','2017-04-30':F.EntityName:,}

>>Name|Phone|VIP|Business
{REPORT ENTITY DETAILS:E.Name,EC.Phone,EC.VIP Level,EC.Business:(EN=$1)}

2 Likes

hehehe Q! you are awesome, I will try this and came back with the results!
Thanks for all!

Yeah awesome… I found a bug while preparing my tutorial. I’ll better fix that.

3 Likes

Here is another method that @emre reminded me of… {REPORT SQL DETAILS:X} can parse JSON data natively, so we don’t need to create a list and feed it into {REPORT ENTITY DETAILS:} at all.

##Report

[Customer NOT Purchased:1,1,1,1]
>>Name|Phone|VIP|Business
{REPORT SQL DETAILS:
SELECT ent.[Name] as [EntityName], ent.[CustomData]
FROM [Entities] ent
WHERE ent.[Id] IN (

SELECT DISTINCT e.[EntityId]

FROM [TicketEntities] e
JOIN [EntityTypes] et on et.[Id]=e.[EntityTypeId]

WHERE 1=1
AND et.[Name]='Customers'
AND e.[EntityId] NOT IN (
	SELECT DISTINCT te.[EntityId]
	FROM [TicketEntities] te 
	JOIN [Tickets] t on t.[Id]=te.[Ticket_Id] 
	WHERE 1=1
	AND t.[Date]>='2017-04-01' 
	AND t.[Date]<='2017-04-30'
)

)
ORDER BY ent.[Name]
:F.EntityName
,F.CustomData(Name=Phone)Value
,F.CustomData(Name=VIP Level)Value
,F.CustomData(Name=Business)Value
}

This cool feature works like this… check out the last bits of the Report:

,F.CustomData(Name=Phone)Value
,F.CustomData(Name=VIP Level)Value
,F.CustomData(Name=Business)Value

That means it will read the [CustomData] field in the DB, find JSON where the Name is equal to Phone, VIP Level, and Business, and return the Value when the Name matches.

1 Like

The same thing will work using a SQL Script @@handler

:warning: IMPORTANT: due to a recent fix, you will need to download the latest refresh of SambaPOS 5.1.62 which has a build date of [2017-04-11 12:43:00 AM].

##SQL Script : @@CustomerNotPurchasedData

:bulb: Notice at the top of the SELECT statement, we are retrieving the [CustomData] field as well as the [EntityName]

DECLARE @entityType varchar(50) = @1
DECLARE @startDateIn varchar(25) = @2
DECLARE @endDateIn varchar(25) = @3

DECLARE @startDate datetime = convert(varchar(25),@startDateIn,126)
DECLARE @endDate datetime = convert(varchar(25),@endDateIn,126)

SELECT ent.[Name] as [EntityName], ent.[CustomData]
FROM [Entities] ent
WHERE ent.[Id] IN (

SELECT DISTINCT e.[EntityId]

FROM [TicketEntities] e
JOIN [EntityTypes] et on et.[Id]=e.[EntityTypeId]

WHERE 1=1
AND et.[Name]=@entityType
AND e.[EntityId] NOT IN (
	SELECT DISTINCT te.[EntityId]
	FROM [TicketEntities] te 
	JOIN [Tickets] t on t.[Id]=te.[Ticket_Id] 
	WHERE 1=1
	AND t.[Date]>=@startDate 
	AND t.[Date]<=@endDate
)

)
ORDER BY ent.[Name]


##Report

:warning: IMPORTANT: notice there is a semi-colon ( ; ) after the @@handlerName instead of a colon ( : ) … this is necessary to not interfere with classic Report Parameters, and is specific only to REPORT SQL DETAILS report syntax.

###Customer NOT Purchased

[Customer NOT Purchased:1,1,1,1]
>>Name|Phone|VIP|Business
{REPORT SQL DETAILS:@@CustomerNotPurchasedData;'Customers','2017-04-01','2017-04-30'
:F.EntityName
,F.CustomData(Name=Phone)Value
,F.CustomData(Name=VIP Level)Value
,F.CustomData(Name=Business)Value
}

1 Like

@QMcKay fyi build dates are in my time zone (+3 GMT)

1 Like

Now QMcKay that is just freaky how you spue that code out!

Anyway almost a solution for my FIFO expiration of Credit Deposits on Accounts or Gift Cards as you have demonstrated some Date arithmetic. Still I think @emre is right current tools do not support FIFO but wondering if a new table may be the way to go…

Nice demo thanks from me.

2 Likes

Q, Emre, Thanks for your help.
I used the last way Q put here. After updating the Samba to the last version.
Its working great with the changes i had to made to adjust to the names of the fields.

How can i add the date? in my sql script i use this.

select
convert (varchar (10), date ,103)
from tickets

I need to add this at the end of each line to see which is the last date of each customer.

Thanks again!

Regards

select it like select convert (varchar (10), date ,103) as MyField and reference it in field list like F.MyField.

Did this, but its not working. Where do i have to put in the query Q did before?

Thanks!

Edit: Nevermind. I guess i did it, and its working now.

Edit2: Nevermind the nevermind… hehehe I can see the data now, but i have the same result for each day.

This is the script. (sorry to add like this, but i cant put the script)

In red the things i added.