Microsoft Dynamics AX 2012 R3 XDS Security on Finacial Dimesion - sql-server

I'm trying to create an AX security framework for one of my client. The key task here is to enable Branch Accounting in AX 2012 R3 environment. Which means i'm required to filter different transactions / customers / vendors / Transfer orders on the basis of Location & Financial dimension BU respectively such as Each Branch (location) should see records of there respective branch.
I created my custom security roles enabled XDS framework on them, it was easy in the case of customer, vendor etc for which I had an Location wise field.
But in case of transactions i.e 'LedgerJournalTrans' Table I am not able to filter on the basis of Financial dimension. As the field LedgerDimesion is a combination of different dimensions its hard to use it in a AOT query.
If any one give an insight on how to filter transactions or any other records on the basis of Financial dimension combinations ?
Note: I've already studied the white paper to filter through dimensions on XDS but the example mentioned there is based on the myDepartment table and methods which I cannot use in my scenario
Link to White Paper for reference

You have to create a query or view to get values for each ledger dimension.
You can get this info by joining DimensionAttributeValueGroupCombination (this has ledger dimension id), DimensionAttributeLevelValue (field DisplayValue is the dimension value), DimensionAttributeValue (DimensionAttribute RecId).
Now you can use this view or modify it to filter by dimenison values.
MyDepartments temp table has a method named XDS which is automatically called to fill the data. Refresh of this table can be per session or per invocation.
You can use this to make your own user based filter data.

You can add some code in the init() method of your Query that you use in Your XDS policy.
the code should get the ledgerdimension field and get the dimension value that you want to filter based on the user dimension mapping.

Related

How to write a DAX formula on an RLS SSAS?

I have a data model that is like this:
Joins are done between tables on storenumber and storename.
I would like to give access to the stores staff but they only see the sales of their own store. I added their mail in the table Y2_Stores.
The sales data are in the table Y2_Sales.
In analysis services I added a role "Stores" in read, in Membership I added the email addresses of the stores, on the line filters I put that but I see in the microsoft documentation that it is necessary to make a formula with the functions LOOKUPVALUE() and USERNAME() but I do not know how to build this formula..
I tried this formula in Y2_Sales line:
=Y2_Sales[storenumber]=LOOKUPVALUE(Y2_Stores[storenumber],
Y2_Stores[email], USERNAME(),
Y2_Stores[storenumber],
Y2_Sales[detail_number])
I tried this too:
Y2_Stores[email] = USERPRINCIPALNAME()
Can you help me to write the correct DAX formula?
Thanks a lot
UPDATE :
I added the Y2_StoreEmployee table with storenumber | email and made a relation on storenumber in double direction to the Y2_Stores table :
Relationships:
I created a role with this formula:
There should be a table related to Store, eg StoreEmployee, with (StoreNumber,Email), configured for bidirectional cross filtering with Store. Then the RLS filter filter is on StoreEmployee and is just Email=USERPRINCIPALNAME().
So each user sees only their own rows in StoreEmployee, that creates a filter that propagates to Store, and then to the Sales, Inventory, and Images.

Which DB to choose in case queries are not defined. Filtering based on multiple columns

We have a Admin Portal which is used to manage the sites. In one tenant we have say around 20 - 30 million sites. We show say the following site details -
**Site Name Site Url Site Owner StorageUsed StorageQuota Site Visits Site Viewed NumOfFiles CreatedBy CreationSource**
Now we give functionality of sorting on one of the column but user can filter by any number of column and in any order (order won't matter in our case). For example an incoming query could be some thing like -
Where owner = "owner1" and createdby = "owner2" and siteVisits> 1000
order by SiteUrl
Or
Where CreationSource = "Chrome" and StorageUsed > 1000 and SiteOwner = "owner3" and StoragetQuota > 2000
order by SiteName
Choose any combination. Now you see we don't have defined queries here and user can come, can filter on any column and sort by any column. Currently we are using SQL and we have index on every filterable and sortable columns. We can't use Composite index here as we just can't go and create index for each and every combination. Even if we restrict user that you can only filter in a particular order say left to right, there will be so many combinations and hence indexes and may be more columns will be added to this table(rare though) but will increase the number of indexes exponentially. Can't afford it. We know that SQL server uses Hash / Merge join which is not exactly O(n*m) and are better.
Now is there anything else we can do here? We are really open to explore any other known DB to solve this problem. We explored ES but for did not see any benefit there.
if you don't want to create the query using dynamic sql and have to deal with security (sql injection) and performance, take a look at SSAS and create a cube.
Two dimensions (site and storage) and one fact table.

How to move from Excel to designing a Data Warehouse Model

I just started in Data Warehouse modeling and I need help for the modeling of a problem.
Let me tell you the facts: I work on flight data (aeronautical data),
so I have two Excel (fact) files, linked together, one file 'order' and the other 'services'.
the 'order' file sets out a summary of each flight (orderId, departure date, arrival date, City of departure, City of arrival, total amount collected, etc.)
the 'services' file lists the services provided by flight (orderId, service name, quantity, amount / qty, etc.)
with a 1-n relationship (order-services) each order has n services
I already see some dimensions (Time, Location, etc ...). However, I would like to know how I could design my Data Warehouse, knowing that I have two fact files linked together by orderId.
I thought about it, and the star and snowflake schema do not work in my case (since I have two fact tables) and the galaxy schema requires to have dimensions in common, but I block it, is that I put the order table as a dimension and not as a fact table or I should rather put the services table as a dimension, but these are fact tables. I get a little confused.
How can I design my model?
First of all realize that in a star schema it is not a problem to have more fact tables that are connected - see the discussion here.
So the first draw will simple follow your two fact tables with the native provided dimensions.
Order is in one context a fact table, in other context a dimensional table for the service table.
Dependent on your expected queries you could find useful to denormalize some dimensions of the order table in the service table. So the service will have defined the departure date, arrival date etc. dimensions.
This will be done at the load time in the ETL job.
I will be somehow careful to denormalize the measures from order to service - which will basically eliminate the whole order table.
There will be no problem with the measure total amount collected if this is a redundant sum of the service amounts - you may safely get rid of it.
But you will need for sure the number of flights or number of people transported - those measure are better defined in the order fact table; you can not simple replicate them in the N rows for each service.
A workaround is possible, if you define a main service for each order and those measures are defined only in this row - in other rows the value is NULL. This could lead to unexpected results if queried naively, e.g. for number of flights per service.
So basically I'd start with the two fact tables and denormalize some dimensions to the services if this would help to optimize the queries.
I would start with one fact table of Services. This fact would include all of the dimensions you might associate with the Order including a degenerated dimension of OrderId.
Once this fact is built out and some information products are consuming it, return to the Order and re-evaluate it to see if there are any reporting needs which are not being served, or questions which are difficult to answer with the Services fact.
Joining two facts together is always a bad idea. Performance is terrible. You are always better off bring the dimensions from, in your case, Order to Services. Don't forget to include the context of the dimension in the column name and a corresponding role-playing dimension view for this context. E.G. OrderArrivalCity, OrderDepartureDate, OrderDepartureTime.
You can also get yourself a copy of Ralph Kimball's The Data Warehouse Toolkit

Loading Fact tables from SCD1 and SCD2 Dimension in SSIS

I am finding it difficult to understand how you get the history data from a fact table join to a Dimension that has Type2 and Type1 for historic records that have changed. Currently I have a Surrogate Key and Business Key in the Dim. The Fact Table has the Surrogate Key the Fact table and I am using SSIS Lookup Component currently to bring back the row that has the CurrentFlag set to Yes.
However I am joining on the Business Key in the Lookup and returning the Surrogate. Which I know is the main reason I can't get history, however if I Join on the Business Key as I am currently doing and return the Business Key also, SSIS component will only bring back just one row, regardless of how many versions of history you have against that Business Key.
What I want to know or have been told is to use lookups to populate fact tables, however this doesn't seem to really give me the history as it will only return one row regardless. So I Just want to know how to return historic date between a fact and a dimension in SSIS.
Thank you
There's a few caveats when it comes to historical dimensions. Your end users will need to know what it is you are presenting, and understand the differences.
For example, consider the following scenario:
Customer A is located in Las Vegas in January 2017. They place an order for Product 123, which at that time costs $125.
Now, it's August. In the meantime, the Customer moved to Washington D.C. in May, and Product 123 was updated in July to cost $145.
Your end users will need to inform you what they want to see. In case you are not tracking history whatsoever, and simply truncate and load everything on a daily basis, your order report would show the following:
Customer A, located in Washington D.C. placed an order for $145 in January.
If you implement proper history tracking, and implemented logic to identify the start- and end-date of a row in a dimension, you would join the fact table to the dimension using the natural key as well as the proper date interval. This should return you a single value for every dimension row in the fact table. IF it returns more, you have overlapping dates.
Can you show us the logic where you receive only a single value from the lookup, even though you have more records?

Indicating primary/default record in database

I've been struggling with how I should indicate that a certain record in a database is the "fallback" or default entry. I've also been struggling with how to reduce my problem to a simple problem statement. I'm going to have to provide an example.
Suppose that you are building a very simple shipping application. You'll take orders and will need to decide which warehouse to ship them from.
Let's say that you have a few cities that have their own dedicated warehouses*; if an order comes in from one of those cities, you'll ship from that city's warehouse. If an order comes in from any other city, you want to ship from a certain other warehouse. We'll call that certain other warehouse the fallback warehouse.
You might decide on a schema like this:
Warehouses
WarehouseId
Name
WarehouseCities
WarehouseId
CityName
The solution must enforce zero or one fallback warehouses.
You need a way to indicate which warehouse should be used if there aren't any warehouses specified for the city in question. If it really matters, you're doing this on SQL Server 2008.
EDIT: To be clear, all valid cities are NOT present in the WarehouseCities table. It is possible for an order to be received for a City not listed in WarehouseCities. In such a case, we need to be able to select the fallback warehouse.
If any number of default warehouses were allowed, or if I was assigning default warehouses to, say, states, I would use a DefaultWarehouse table. I could use such a table here, but I would need to limit it to exactly one row, which doesn't feel right.
How would you indicate the fallback warehouse?
*Of course, in this example we discount the possibility that there might be multiple cities with the same name. The country you are building this application for rigorously enforces a uniqueness constraint on all city names.
I understand your problem, but have questions about parts of it, so I'll be a bit more general.
If at all possible I would store warehouse/backup warehouse data with your inventory data (either directly hanging of warehouses, or if it's product specific off the inventory tables).
If the setup has to be calculated through your business logic then the records should hang off the order/order_item table
In terms how to implement the structure in SQL, I'll assume that all orders ship out of a single warehouse and that the shipping must be hung off the orders table (but the ideas should be applicable elsewhere):
The older way to enforce zero/one backup warehouses would be to hang a Warehouse_Source record of the Orders table and include an "IsPrimary" field or "ShippingPriority" then include a composite unique index that includes OrderID and IsPrimary/ShippingPriority.
if you will only ever have one backup warehouse you could add ShippingSource_WareHouseID and ShippingSource_Backup_WareHouseID fields to the order. Although, this isn't the route I would go.
In SQL 2008 and up we have the wonderful addition of Filtered Indexes. These allow you to add a WHERE clause to your index -- resulting in a more compact index. It also has the added benefit of allowing you to accomplish some things that could only be done through triggers in the past.
You could put a Unique filtered index on OrderID & IsPrimary/ShippingPriority (WHERE IsPrimary = 0).
Add a comment or such if you want me to explain further.
re: how I should indicate that a certain record in a database is the "fallback" or default entry
use another column, isFallback, holding a binary value. I'm assuming your fallback warehouse won't have any cities associated with it.
As I see it, the fallback warehouse after all is just another warehouse and if I understood, every record in WarehouseCities has a reference to one record in Warehouses:
WarehouseCities(*)...(1)Warehouses
Which means that if there are a hundred cities without a dedicated warehouse they all will reference the id of an specific fallback warehouse. So I don't see any problem (which makes me thing I didn't understand the problem), even the model looks well defined.
Now you could identify if a warehouse is fallback warehouse with an attribute like type_warehouse on Warehouses.
EDIT after comment
Assuming there is only one fallback warehouse for the cities not present in WarehouseCities, I suggest to keep the fallback warehouse as just another warehouse and keep its Id (WarehouseId) as an application parameter (a table for parameters maybe?), of course, this solution is programmatically and not attached to your database platform.

Resources