Database design: Custom fee/billing charge rates - c#

A user can have custom billing rates, which may differ from one user to another.
You would most likely have a default billing fee table, that would look something like this
FEE
Id
FeeTypeId
FixedCharge
VariableCharge
When you charge the customer you might send them an invoice etc and then you have a table that stores the billed/charge amount that might look like this!
USER_TRANSACTION_CHARGE
Id
UserId
FeeId
ChargeName
ChargeAmount
DateTime
How do you design it for custom billing rates per specific user?

It doesn't look as if your FEE table has any history. It is a common legal requirement to be able to produce invoices up to 7 or 10 years ago. A FEE record can change, so what does that do to the link (feeid) in the invoice table?
FEE: Id, FeeTypeId, FixedCharge, VariableCharge
USER_FEE: Id, UserId, FeeTypeId, FixedCharge, VariableCharge
You could create a USER_FEE table that "overlays" the FEE table for a specific User. So for each given FeeTypeId, a user may have an overlay in USER_FEE or could just fall back to FEE.
As for USER_TRANSACTION_CHARGE, I seriously challenge the link column FeeId in there, unless you maintain history against FEE, which FeeId + DateTime would link to. I would drop that table to just
Id, UserId, ChargeName, ChargeAmount, DateTime
Where I assume ChargeName is somehow linked to FeeTypeId?
And ChargeAmount is whatever has been worked out from Fixed/VariableCharge
So in essence, the (USER_)FEE tables are used to look up the values, but beyond that, they are stored as values without a backlink to the (USER_)FEE table, since this appears to be a simple system without versioning.

Keep the table of default fees and add a cross-reference the lists user, feeType, and the override. At billing time determine the fee with a resolution (http://database-programmer.blogspot.com/2008/04/advanced-table-design-resolutions.html) That blog entry actually uses as its example a time-billing system, close to what you are doing.
Beware of false normalization -- by which I mean you should materialize the actual fee and save it permanently on the invoice. This is because at the time an invoice is created the actual fee charged becomes a historical fact about the transaction, and so it is not denormalizing to save it as such. The foreign key is there only to identify the item/activity/feeType, not for the purposes of obtaining the fee, the fee is saved onto the invoice and kept forever.

The default fee should be independant of what was actually charged, so the User_Transaction_Charge has to lose the FeeID foreign key.
If you need to store the components used to generate the User_Transaction_Charge, store them within the Charge or as a separate entity.
DEFAULT_FEE
Id
UserId
FeeTypeId
FixedCharge
VariableCharge
and
USER_TRANSACTION_CHARGE
Id
UserId
ChargeName
ChargeAmount
DateTime
USER_TRANSACTION_CHARGE_FEE
Id
UserTransactionChargeId
FixedAmount
VariableRate
or
USER_TRANSACTION_CHARGE
Id
UserId
ChargeName
ChargeAmount
FixedAmount
VariableRate
DateTime

Related

one to many relationship based on date

I wrote an windows form app in c# that makes a presence/delay log for employees and now I'm trying to add a feature to that app which does the following :
Takes the log of that day (who is present and who came late to work) from it's database and assign it to the date of that day, so i'd be able to view one each separate day who was present and who came late to work.
To make it more clear :
Workers table : where 1 means the employee is present or delayed
ID--name----------presence-----delay
1--sam--------------1----------0---
2--jack-------------0----------0---
3--ted--------------1----------1---
Date table :
Day---------------present----delay-----absent
14/10/2012---------sam--------ted-------jack
------------------------ted-----------------------
and so on, i hope i made my idea clear.
how will the second table look like and how will the relation be ?
how will i view the result like the one in the date table ?
--Person-- --Presence-- --Delay--
ID ID ID
Name Date Date
// other info PersonID PersonID
IsPresent
First of all, you should hold Person table separately and use it's ID in other tables. I strongly recommend reading about data redundancy and database normalization. PersonID in the other tables refer to ID in Person table.
I think Presence should be logged for each day. Delay should be logged if only the Person shown up late that day.
you may want to do something like this, may not be 100% but should get you going in the right direction. Run into any other questions let me know will help as i can
table: Employees { Id, Name }
table: Logs {EmployeeId, DateCreated, OnTime (bit false if late)}
select Name
Status = CASE WHEN OnTime = 1 THEN "On Time"
WHEN OnTime is null THEN "Absent"
ELSE "Late"
from Employees as e
left join Logs as l
on e.Id = l.EmployeeId
Where l.DateCreated = #aDate
or l.DateCreated is null
to show the data the way you are looking to would then become a task for the report engine or a pivot table depending on the requirements

Schedule Table Design

I am working on doctor scheduler page requirement. The below is the screen for showing a usual weekdays schedule for a doctor.
The doctor may visit only few days on a week and only between a period of time
A doctor may be on leave some day. They add that entry
I need to design the database table to handle above scheduling.
I have no idea how a database table can be designed for 7 days with hours and doctors mapped.
The most important thing is for a given week i should be able to check the doctor availability.
I created a DoctorLeave table below to handle only doctor leave days
DoctorId, LeaveDate, Comment
But, How do i design scheduler table? Any idea/suggestions pls
I’d go with a structure that looks like this
-Doctor_ID
-Patient_ID
-Activity_Start
-Activity_End
-Activity_Type_ID
For activity type I’d create a lookup table that could look like this
Activity_Type_ID Activity_Description
1. Working with patients
2. Absent
Your table for scheduling should be simple. All you need are doctor_id, patient_id, begin_time, end_time (both fields containing both date and time). Then your query or UI code figure out which day of the week those lie on and how to display them on a schedule table, etc.
You should create a separate table for doctor unavailability. doctor_id, leave_begins, leave_ends (both as dates and times if necessary). Once again, use your queries or UI code to figure out conflicts during appointment scheduling.

How to represent aggregate entities using Code-First?

I have recently started developing using ASP.NET and am struggling to grasp Code-First. I am working on a project for an internship and have very little database knowledge except for one class I've taken. I am in no way asking for a complete solution or being lazy.
I've been trying for a couple days to create a solid ER diagram and I'm fairly certain the one below will represent all of the information I need to store. Please let me know if you see any ways this can be improved.
What I'm trying to do:
For this project an administrator will create rooms with attributes listed below. The admin will then assign time-slots that represent between what hours the room will be available and what days of the week it will be available.
The users will fill out their basic information and fill out a form representing what times they are available.
After all the users have registered the admin will run a scheduling algorithm to come up with the closest to a most efficient schedule that it can (because it's NP hard).
The assigned relation represents user time slots that are related to room time slots in order to produce a table of what users are assigned to what rooms at what times.
I'm using Visual Studio 2012.
Questions
How would I represent these aggregate entities using Code-First? Not necessarily asking for the code for this exact diagram but maybe quick example to help me wrap my head around Code-First.
Do my mappings look correct for these relations?
Any help or point in the right direction is greatly appreciated!! Thank you!
Below is an ER diagram that represents the following:
Room (id, number, building, capacity)
TimeSlot (id, startHour, endHour, dayOfWeek)
User (id, firstName, lastName, email)
Available (userId, timeID)
Reserved (roomID, timeID)
Assigned (reservedID, availableID)
Firstly in the ER diagram I would have expected a link directly from Room to TimeSlot (top-right) and User to Timeslot (bottom right), but knowing the likely queries that will be run I would suggest the ERD should be as follows.
Room linked to an entity called RoomAvailability. RoomAvailability contains all the free time slots for rooms, so this will initially be populated with one record per room per day (RoomId, Date, StartTime, EndTime) going to as many days into the future as you think necessary.
Similarly I would have an entity UserAvailability (UserId, Date, StartTime, EndTime) linked to User.
Entity RoomReservation (RoomId, UserId, Date, StartTime, EndTime) linked to both Room and User which contains all room reservations (assumes only 1 user can book a room).
When a room is reserved a RoomReservation records is added and a single RoomAvailability record may be split into 2 separate ones (e.g. room is free for whole day then someone books a slot during the day leaving 2 free periods at the start and end of the day).
When a reservation is cancelled the RoomReservation record is deleted and 2 RoomAvailability records may be merged back into 1 (the reverse of the above).
I believe that splitting and merging of available slots is how similar systems work.

Database design for handling individual and recurring charges

We have a billing system where we process individual charges as well as recurring charges (subscriptions).
There are two SQL tables:
StandardCharges
RecurringCharges
StandardCharges table holds individual items purchased by customers during the month.
RecurringCharges table holds recurring items with a charge by date. When the time comes our system automatically creates a recur request which adds a row to the StandardCharges table and increases the charge by date to next month in RecurringCharges table.
At the end of each month we get the total values for each customer from StandardCharges table and create an invoice.
Is there a kind of design pattern or another way of doing this? Is this the right database design? Ideally I would like to hold all charges in one Charges table and manage recurring charges from there as well?
Thanks
I suspect that your design is indeed correct.
When thinking about the data in real world terms it makes no sense to have "possible" transactions (I.E., transactions which have not yet happened and may not materialize, perhaps because the customer had overrun their credit limit) mixed in with committed and actual transactions.
Merging the data into a single table can also make reporting difficult as you have to apply special filtering criteria and store extra meta data - like TransactionCompleted and TransactionIsFutureCharge.
If I was to make a suggestion it would be renaming the StandardCharges to something closer to the data it holds like CompletedTransactions and the RecurringTransactions something like PendingTransactions.
The current design seems reasonable to me. But if you want to merge the two tables, you could simply add a BIT column called IsRecurring or IsFuture or IsScheduled or whatever you want to use to designate the charges that would have otherwise gone in RecurringCharges. Then when your due date is hit for a recurring charge, you just insert into the same table instead of a different table. As for the invoice, you'd just add a condition to the query to filter out the charges that have the BIT column set.

How to provide Unique ID in Offline mode?

In a client-server accounting application in invoice form when a user saves an invoce it gets An invoice number like 90134 from server and saves the invoice with that number The invoice number is needed for the customer.
So in Offline mode (like when the network dropped) how provide a unique id?
Is it good to use String Id like this pattern: client + incremental number?
I don't want to use GUIDs.
If you know in advance how many invoice numbers you will generate per client during an offline period, would you be able to pre-allocate invoice numbers? e.g. if each client is likely only to generate 4 invoices per offline period, you could allocate a block of 4 numbers to each client. This may involve an extra column in your DB to store a value indicating whether the number is an invoice already created, or a preallocation of a number. Depending on the structure and constraints within your DB, you may also need to store some dummy data to enforce referential integrity.
The downsides would be that your block of numbers may not get used sequentially, or indeed at all, so your invoice numbers would not be in chronological order. Also, you would run into problems if the pool of available numbers is used up.
You can use Guid:
var myUniqueID = Guid.NewID();
In SQL server is corresponding type uniqueidentifier.
In general the Guid is 128-bit number.
More about Guid you can read:
http://en.wikipedia.org/wiki/Globally_unique_identifier
http://msdn.microsoft.com/en-us/library/system.guid.aspx
I suppose the invoice number (integer) is incremental: in this case, since you have no way of knowing the last invoice number, you could save the invoice in a local db/cache/xml without the invoice Number and wait for the network connection to insert the new records in the DB (the invoice number would be generated then)
You could start your numbers for each client at a different range... e.g.:
client 1: 1,000,000
client 2: 2,000,000
client 3: 3,000,000
Update them every now and then when there is a connection to avoid overlaps.
It's not 100% bulletproof, but at least it's better than nothing.
My favorite would still be a GUID for this, since they're always unique.
There is a workaround, but it is merely a "dirty hack", you should seriously reconsider accepting new data entries while offline, especially when dealing with unique IDs to be inserted in many tables.
Say you have an "orders" table and another "orderDetails" table in your local dataset:
1- add a tmpID of type integer in your "orders" table to temporarily identify each unique order.
2- use the tmpID of your newly created order in the rest of the process (say for adding products to the current order in the orderDetails table)
--> once you are connected to the server, in a single transaction do the following
1- insert the first order in the "orders" table
2- get its uniqueID generated on your SQL server
3- search for each line in "orderDetails" that have a tmpID of currentOrder.tmpID and insert them in the "orderDetails" table on your server
4- commit the transaction and continue to the following row.
Keep in mind that this is very bad coding and that it can get real dirty and hard to maintain.
it looks like impossible to create unique numbers with two different systems both offline when it must be chronological and without missing numbers.
imho there is no way if the last number (on the server) was 10, to know if i should return 11 or 12; i would have to know if 11 was already used by another person.
I can only imagine to use a temporary number and later on renumber those numbers, but if the invoices are printed and the number can not be changed, i don't know how you could accomplish such a solution.

Categories

Resources