database design : Inventory with multiple item units ( wholesale and retail ) - database

I have designed a db for drug ( pharmacy ) store which will sell medicine both wholesale and retail. There are some medicine that can be sold in multiple units, for example, strip, capsule and vial of medicine. Basically, each medicine can be sold in more than one unit. Here is my db:
I have an inventory_movement records that record the specific stock used to fill each order. if a medicine’s base unit is set to vial, and It has some records with vial in the inventory_movement, and after a period of time, I want to sell that medicine with capsule unit, at this time, how do I record this to the inventory_movement ? And how do I calculate the stocks from inventory ?
If I update the item_unit record to set the data like following:
And I need to scan whole inventory_mocement table to update the base unit to the new one ( capsule ) and re-calculate the quantity with the multiplier. Is this reasonable ?
Is there any flaws in my design ? Does anyone have any ideas (or examples)?

"how do I record this to the inventory_movement?"
Simply book out the whole quantity (in this case 7) with the appr. unit_id, then add it back with the other unit_id.
And how do I calculate the stocks from inventory ?
If I were you, I would set up a new table only for the stocks (f. e. item_id, unit_id, qty), and with each movement I would decrease/increase the stock based on the quantity and unit_id. For this, I would change the item_unit table too like this: id, item_id, unit_id, multiplier, base_unit (bool). And the item_unit table would be only a master table, which holds the data, in wich tpye of packaging how many pieces there is.
So, you won't need to go over the movement table and you could calculate your stocks based on the item_unit table with the appr. multiplier.

Related

How to calculate the tax free amount of sales, based on date fields?

i need your help for a task that i have undertaken and i face difficulties.
So, i have to calculate the NET amount of sales for some products, which were sold in different cities on different years and for this reason different tax rate is applied.
Specifically, i have a dimension table (Dim_Cities) which consists of the cities that the products can be sold.
i.e
Dim_Cities:
CityID, CityName, Area, District.
Dim_Cities:
1, "Athens", "Attiki", "Central Greece".
Also, i have a file/table which consists of the following information :
i.e
[SalesArea]
,[EffectiveFrom_2019]
,[EffectiveTo_2019]
,[VAT_2019]
,[EffectiveFrom_2018]
,[EffectiveTo_2018]
,[VAT_2018]
,[EffectiveFrom_2017]
,[EffectiveTo_2017]
,[VAT_2017]
,[EffectiveFrom_2016_Semester1]
,[EffectiveTo_2016_Semester1]
,[VAT_2016_Semester1]
,[EffectiveFrom_2016_Semester2]
,[EffectiveTo_2016_Semester2]
,[VAT_2016_Semester2]
i.e
"Athens", "2019-01-01", "2019-12-31", 0.24,
"2018-01-01", "2018-12-31", 0.24,
"2017-01-01", "2017-12-31", 0.17,
"2016-01-01", "2016-05-31", 0.16,
"2016-01-06", "2016-12-31", 0.24
And of course there is a fact table that holds all the information,
i.e
FactSales_ID, CityID, SaleAmount (with VAT), SaleDate_ID.
The question is how to compute for every city the "TAX-Free SalesAmount", that corresponds to each particular saledate? In other words, i think that i have to create a function that computes every time the NET amount, substracting in each case the corresponding tax rate, based on the date and city that it finds. Can anyone help me or guide me to achieve this please?
I'm not sure if you are asking how to query your data to produce this result or how to design your data warehouse to make this data available - but I'm hoping you are asking about how to design your data warehouse as this information should definitely be pre-calculated and held in your DW rather than being calculated every time anyone wants to report on the data.
One of the key points of building a DW is that all the complex business logic should be handled in the ETL (as much as possible) so that the actually reporting is simple; the only calculations in a reporting process are those that can't be pre-calculated.
If your CITY Dim is SCD2 (or could be made to be SCD2) then I would add the VAT rate as an attribute to that Dim - otherwise you could hold VAT Rate in a "worker" table.
When your ETL loads your Fact table you would use the VAT rate on the CITY Dim (or in the worker table) to calculate the Net and Gross amounts and hold both as measures in your fact table

Database design for user daily food and workout table daily activity

I'm builing an app who manage foods and workout together. i'm not sure who to store user daily activity
Actually i have a table food :
id
name
energy
proteins
Table meals to store the meals made with some foods and store the total nutriments values :
id
name
cat
total_enery
total_proteins
Table meal_food to store the foods in the meal :
meal_id
food_id
nb_portion
Table Workout :
id
name
type
Table Exercices :
id
name
type
duration
Table workout_exercice
workout_id
exercice_id
Now my question is how could a design a table in order to store user
daily activity ? i need to store foods, meals, workout, exercice
I need for each day grab a food choose a portion or grab a meal already stored, a workout or an exercice.
I was strating doing something like this but i'm really really not sure here :
Table user_daily_activity
id
day
food_id
meal_id
food_id_portion
workout_id
exercice_id
Is it a good idea to try to group or should i need to separe things ? should i create tables like this to get more control ?
user_daily_food
user_daily_meal
user_daily_workout
user_daily_exercices
Assuming:
You can choose a specific portion for a food, or duration for an exercise, or choose one from an already pre-defined meal/workout routine.
You are interested in preserving a snapshot of the day, and can alter predefined meals and workout routines as necessary.
Then the simplest way would be to choose from the predefined meals and workout routines and store the results in daily activity:
id
day
food_id
food_id_portion
exercise_id
duration
If predefined meals and/or workout routines cannot change and/or you need to tie back to the original meals/workout routines (even if they can change), then I think you were left with the above tables you mentioned. You could store the results separately for simplicity/normalization, then union the results:
select food_id, food_id portion
from
(
select id, day, food_id, food_id_portion from user_daily_food
union all
select id, day, food_id, nb_portion from user_daily_meal
inner join meals on user_daily_meal.mealid = meals.mealid
) A
I would go with whatever produces the least redundancy, but that depends on the needs for the particular app.

SSAS- MDX Assign fact row to dimension member base on calculation

I am looking to calculate in the calc script something, so I can allocate a row from a fact table to a dimension member.
The business scenario is the following. I have a fact table that record customer credit and debit ( customer can do a lot of little loan) and a dimension Customer.I want to classify my customer base on his history of credit and debit on a given period.Classification of customer change over time.
Example
The rule is, if a customer balance (for a given period ) is over - 50 000, the classification is "large", if he have more than a record and have done a payement in the last 3 month he is a "P&P.If he doesn't own any money and have done a payement in the last 3 month its "regular".
My question is more about direction than a specific code,which way is the best to implement this kind of rule ?
Best Regards
Vincent Diallo-Nort
I'd create a fact table with a balance auto-updated status every day:
check the rolling balance yesterday plus today's records.
when the balance = 0, then remove a record.
Plus add a flow fact table with payments only.
Add measures:
LastChild aggregation for the first fact table.
Sum aggregation for the second fact table.
When it's done, you may apply a MDX calculation:
case
when [Measure].[Balance] > 50000
then "Large"
when [Measure].[Payments] + ([Date].[Calendar].CurrentMember.Lag(1),[Measure].[Payments]) + ([Date].[Calendar].CurrentMember.Lag(2),[Measure].[Payments]) > 0
then "P&P"
else "Regular"
end
In order to give you answer in detail you have to provide more information about your data structure.

SSAS cube with date range records

I have to build a cube based on date range records, and not sure about the best way to proceed.
Imagine say a cube of Cars and warranty periods. Each car has a start date, and an end of warranty periods. Then there may be extended warranty periods.. so imagine
CAR REG TYPE WARRANTY START WARRANTY END
CAR A PURCHASE 01/01/2016 31/01/2016
CAR A EXTENDED 01/01/2017 30/06/2017
CAR A EXTENDED 01/08/2017 30/01/2018 -- note, gap here
CAR B PURCHASE 01/01/2016 31/01/2016
CAR B EXTENDED 01/01/2017 30/06/2017
CAR B EXTENDED 01/08/2017 30/01/2018 -- note, gap here
So multiple items, with multiple date ranges. There is a main table (CARS) with car details (colour, model, etc).
Now I want to build a cube, which is reportable at month level, cars under warranty/warranty type, etc.
So plan 1 was to build a view which explodes the above out by a join to a date table, report by month, and feed this into a cube. But, the number of cars multiplied by the months covered leads to multi hundreds of milions of rows - which means sometimes the server runs out of TempDB space, and when it does run, the cube takes hours to build.
Is there a better way - such as a view for the car details, and then another view on the warranty table (how do I get SSAS to deal with months in a date range) - will the join in SSAS be more efficient than a join in a view in SQL?
Thanks all.
You can connect start and end columns to time dimension. And on the report you can use ":" operator to build date tange report.
More details you will find here: http://www.purplefrogsystems.com/blog/2013/04/mdx-between-start-date-and-end-date/
One approach which will work with drag-and-drop client tools like Excel or Power BI would be a many-to-many Date dimension. Since car A and B match, let's pretend there's a car C which has a warranty from 2015-07-30 to 2015-12-31.
Create a DimWarrantyDateRangeKey which represents a unique combination of dates during which a warranty is active. The surrogate key is WarrantyDateRangeKey. Certainly the ETL that builds this table will be a bit expensive, but given the size of your data I think it's a worthwhile investment that will produce better query performance than if your m2m bridge table has one row per active day per car.
Each car should be assigned one WarrantyDateRangeKey. Add the WarrantyDateRangeKey column to your fact tables...
CAR REG WarrantyDateRangeKey
A 1
B 1
C 2
m2mWarrantyDateRange
WarrantyDateRangeKey DateKey
1 20160101
1 20160102
1 ...
1 20170629
1 20170630
1 20170801
1 20170802
1 ...
1 20180129
1 20180130
2 20150701
2 20150702
2 ...
2 20151230
2 20151231
The tables relate together as follows...
FactTable -> DimWarrantyDateRange <- m2mWarrantyDateRange -> DimDate
Then in the cube you DimWarrantyDateRange should be a dimension, m2mWarrantyDateRange should be a measure group with a count measure. DimDate should be a dimension. Then you should relate DimDate to FactTable as a many-to-many (m2m) dimension using m2mWarrantyDateRange as the intermediate measure group.
Now in Excel or Power BI you should be able to filter to a particular date and it will filter down to the cars which had an active warranty on that day.

Difference among Dimension, Dimension attribute and Facts

So from what I've understand the best example of differences in (Dimension, Dimension Attribute, and Fact) would be something like this:
Dimensions - PRODUCT, ACCOUNT, CUSTOMER
Dimension attribute - ProductName, ProductNumber, CustomerName, CustomerNumber
Facts - usually measures. Dollar, Unit, Height
This is my attempt so it may be wrong. I want to hear your solutions?
A dimension is a collection of "reference information" about a measurable event. The Measurable event is a Fact.
So, if you have data say for example - Retail transactions, you would measure - transaction cost. So, your fact will have sales amount. Now, sales amount in itself does not make sense. You would need information like -
When was the sale done - Date dimension
Who made the transaction - Customer dimension
Which store was it made from - Store Dimension
What was brought - Product dimension
and so on. What information you want capture for each dimension is called the attributes. For Ex: A Customer dimension might have these attributes -
Customer Number
Customer Name
Customer Address
Customer Zip Code
Date Of birth
... and so on.
Dimensions: are qualitative data. These are objects of the subjects.
Dimension attributes : These are columns of dimension table.
Facts : are the quantitative data. The data which can be summed up , averaged or manipulated. If manipulation is done in the data then it would be to provide business insights. Manipulated data eg : time dimension can't be measured but hours calculated using time is a measurable fact.
Example : Consider e commerce company table(amazon) which is Subject
Dimensions:
Product , date , customer , vendor , location(** these all are Objects of subjects**)
Dimension attributes:
PRODUCT - (Product_id , Product_name , Product_class)
DATE - (Order_date , Shipment_Date , Delivery_date)
CUSTOMER - (Cust_id , Cust_name)
LOCATION -(State , city , town , zip_code)
Facts:
PRODUCT - Total number of products sold
DATE - Total number of products sold in last one month/ last one year / last one quater
CUSTOMER - Total amount paid by customer
LOCATION - Total sales done per region , per state , per city
- Total traffic(customer visited) in stores per region

Resources