Create a contract renewal summary table - dax

I have a Contract table that includes the following columns:
ID
Account
Service
Start Date
End Date
Amount ($)
1
Account A
Service 1
2021/05/18
2022/05/17
$100,000
2
Account A
Service 1
2022/05/18
2023/05/17
$105,000
3
Account B
Service 1
2021/04/13
2022/04/12
$80,000
4
Account B
Service 2
2022/09/15
2022/09/14
$50,000
Consider for this question, today's date is 2022/06/04 (June 4th, 2022). I'd like to create a new table using DAX that summarizes, for each Account and Service, the following:
Service renewal: the latest contract for each unique Account+Service has an End Date greater than today's date AND a previous contract for the same Account+Service exists whose End Date is within 1 day of the latest contract Start Date.
New Service sale: the latest contract for each unique Account+Service has an End Date greater than today's date AND no previous contract exists for the same Account+Service whose End Date is within 1 day of the latest contract Start Date. The Service is still considered new if the Account had purchased the same Service in a previous year.
Service cancellation: the latest contract for each unique Account+Service has an End Date less than today's date.
The new table could look like this (using data from the original Contracts table above):
Account
Service
Action
Most Recent Contract ID
Renewal Rate (%)
Account A
Service 1
Renew
2
105%
Account B
Service 1
Cancel
3
null
Account B
Service 2
New
4
null
In the new table (above) I'd like:
Action = Renew, Cancel or New based on the previously explained options
Renewal Rate = Active contract amount (whose End Date > Today's Date) / Previous adjacent contract amount
Most Recent Contract ID = contract ID of the most recent instance of the contract matching the Account+Service pair (even if the most recent contract was canceled whose End Date < Today's Date).

Related

How can I filter a table for the field values on the last(highest) date in a custom four week period, using DAX in Power BI?

I created a calculated table based on start and end dates to check which manager is responsible for a product per date.
Result:
The financial department uses a four week period to report. So 13 periods per year.
(not usable in a date table?)
Product number 8098 gets a different manager on the 23rd of januari this year.
So at the start manager C5104 is responsible and at the end of period one (202301) C5107 is responsible.
To get one responsible manager per period I'd like to filter the table in such a fashion that I get the numbers from the last date in a period. After filtering I don't need the [date] field anymore.
I hope I'm just missing something basic like the 'ELLEXCEPT' But I'm lost...
DISTINCT gives:
One row too many. I'd like to lose the row: 8098, C5104, 202301.
To keep only rows showing the manager per product at the end of a period.

Query to prevent booking overlap

I'm doing an app in Apex Oracle and trying to find a query that could prevent people from booking a room already booked. I managed to find a query that can prevent picking a date that starts or ends in between the booking time but I can't find how to prevent overlaping. By that I mean if someone books a conference room feb 2nd to feb 5th, someone can book the same room from feb 1st to feb 7th. That is what I'm trying to prevent. Thanks for the help!
Here's my first query
SELECT RES_ID_LOC FROM WER_RES
WHERE (CAST(RES_DATE_ARRIVE AS DATE) < CAST(TRY_RESERVE_START_DATE AS DATE) OR CAST(RES_DATE_DEPART AS DATE)
CAST(TRY_RESERVE_START_DATE AS DATE))
AND (CAST(RES_DATE_ARRIVE AS DATE) < CAST(TRY_RESERVE_END_DATE AS DATE) OR CAST(RES_DATE_DEPART AS DATE) > CAST(TRY_RESERVE_END_DATE AS DATE))
The main issue you'll have here is concurrency, namely (in chronological order)
User 1
runs overlap check query, see Room 5 is free, and inserts a row to book it
User 2
runs overlap check query, see Room 5 is free, and inserts a row to book it
User 1
commits
User 2
commits
and voila! You have a data corruption, even though the code all ran as you expected.
To avoid this, you'll need some way to lock a resource that multiple might want to book. Thus lets say you have a ROOMS table (list of available rooms) and a BOOKINGS table which is a child of ROOM.
Then your logic will need be something like:
select from ROOM where ROOM_NO = :selected_room for update;
This gives someone exclusive access to the room to check for bookings.
Now you can run your overlap check on that room against the BOOKINGS table. If that passes, then you insert your booking and commit the change to release the lock on the ROOMS row.
As an aside, take care with simply casting strings to dates, because you're at the whim of the format mask of the item matching that default of the database. Better to explicitly use a known format mask and TO_DATE

How to deal with reporting slowly changing dimensions

For a client I am creating a data warehouse in which we have some slowly changing dimensions (or facts if that is even a thing?). For example we want to report the annually recurring revenue (ARR) for subscriptions and we want to have both the currently active and the expired subscriptions in there. So that we can see the ARR over a timeline.
The data we retrieve looks like this:
subscription_id
account_id
ARR
start_date
end_date
1
1
10
01-01-2022
31-03-2022
2
2
20
01-01-2022
31-12-2022
3
1
5
01-04-2022
31-11-2022
So in this case the same account (account_id 1) renewed a subscription at the 01-04-2022. In the report of 2022 we want to see the ARR for all months in 2022. I've looked into slowly changing dimensions, however something I can not really see in that concept is how to report both the currently active license and the history in a dashboard. If we for example want to visualize the ARR in all of 2022 per month in a dashboarding tool we want to see both subscriptions for account_id 1 over the course of the year, not just the currently active one. This seems to be very tricky to do in most dashboarding tools.
To overcome this I've done the following. I created a calendar table with an interval of 1 month and I cross join it with the table above to generate a fact table. The end result would look like:
timestamp
account_id
ARR
01-01-2022
1
10
01-01-2022
2
20
01-02-2022
1
10
...
...
...
01-11-2022
1
10
01-11-2022
2
20
01-11-2022
2
20
This makes it really easy for the user of the reporting tool to filter on a specific month and show the ARR between the dates and over multiple subscriptions. It does however generate a lot of extra data, but at the moment the storage space is not an issue. And it makes it more of a transactional style table, but the ARR is not really a transaction (i.e. it is not really a sold product on a specific date).
My question is: Are there better ways of generating a fact table where the source data contains a date range?

Regular, repeating, interaction between an oracle and a smart contract

This is just an example. I'm building this dapp where I have a start date and an end date and every day I want to get a random number from an oracle. If at some point the sum of the numbers I get every day exceeds a threshold then an OK message returns to my backend. Let's assume we have a range of 7 days.
Day 1:
My backend sends a request to the "smart contract Number" and calls the requestOk () method.
The smart contract Number calls the gethNumber () method of the oracle smart contract and passes it the callback on which to return the response.
The oracle smart contract issues an updateN () event
The oracle service retrieves the data and returns it to the oracle smart contract by calling the UpdateNumber () method
The oracle smart contract uses the callback and returns the data to the smart contract Number
The smart contract Number checks if the number received that day is greater than a threshold. If it is greater, an ok message returns to the backande, otherwise the same procedure is performed for day 2, I take the new number and add it to the number of day 1. Finally I compare the sum (day number 1 + day number 2) with the threshold and so on.
Now my question is: can the operations I have to perform again for day 2 automatically start from the smart contract Number? I mean, is it possible to create a mechanism allows the smart contract Number to ask the oracle for a random number every day for a week? Or must it be my backend asking to do the same operations for day 2 and every day of the week?
Or must it be my backend asking to do the same operations for day 2 and every day of the week?
Yes.

How many times does a range of values contain the end of the month

I have a table that has 2 values.
Value a phone was activated and a value when phone was deactivated.
I want to find out how many times that phone was still active on the last day of any given month.
Table1
phone1 DateActivated DateDeactivated HowManyTimesLastDayOfMonth
123 3/1/2016 3/15/2016 0
456 3/10/2016 6/25/2016 3
789 5/25/2016 10/10/2016 5
To amplify my comment:
SELECT phone1, DateActivated, DateDeactivated,
MONTHS_BETWEEN(FIRST_DAY(DateActivated+1), FIRST_DAY(DateDeactivated+1)) HowManyTimesLastDay
FROM mytable;
I should have explained better. The reason you take first_day(DateActivated+1) is that the second date (going to the first day of the next month) needs to be sure that it's not a full month - so if the phone was activated on March 1 and deactivated on March 25th, it doesn't show a full month. The reason for FIRST_DAY(DateDeactivated + 1) is to make sure that in the event that the deactivation occurred on the last day of a month that that counted towards the total.

Resources