MySQL Database Schema for role based system - mysql

We are developing a platform for NGOs (N) to get their work done via Individual Volunteers (V) or Volunteers via a Company (C)
NGO
An NGO can come signup for an account and create a profile.
It creates Activities (jobs it needs help from volunteers) to which Individual Volunteers or a Company (Sub set of their Employees who are registered as Volunteers in the system) can apply.
An NGO can check the Applicants Profile and previous Work History
and accept the application. On Acceptance they become members of an
Activity.
Here While they work after regular intervals say 2weeks they need to
enter the amount of hours they have contributed towards that
particular activity.
NGO has to validate this time so that it can reflect in a Volunteers profile as credit
Company
A Company signup for a profile.
It uploads the list of all its employees in a particular formatted CSV file to add Volunteers against itself or send an invite link to to ask their employees to signup. If an Employees already exists in the system we send an email asking him to validate the company's claims
Company can search for a particular Task and apply to it by selecting all its employes or a subset of it.
While Validating time for the work done it can be done it two ways. 1 Company can centrally say V1 V2 V3 have completed 2hrs 3hrs and 2hrs and submit for validation from the NGO or allow each of its Employees handle this manually and allow them to submit it.
Where i need help?
I have created the NGO and single Volunteer relationships. I am confused as to how use the same tables but allow a new entity like Company come in between the NGO and Volunteer and manage the time validation and activity management.
The Time Validated is very important as it will be used to be shown that in the Social Equity Balance of the NGO, Company as well as Volunteers (Individual Work and also Worked for a cause through a company)
I have created the ER diagram below for the NGO and Volunteer and need to create the Company part of it.
Link: http://i.stack.imgur.com/OMY21.png

I'm not sure you need to change your schema much, or even at all. Your schema requires an application to go with it to make it do anything - you can't implement all the logic here - some/most of it will be in your application.
As I understand it, your spec says that all actual volunteer work is performed by individuals, some of whom may be associated with a Company and some aren't. Your schema captures this already.
That's pretty much all you need, I think. When you say:
While Validating time for the work done it can be done it two ways. 1 Company can centrally say V1 V2 V3 have completed 2hrs 3hrs and 2hrs and submit for validation from the NGO or allow each of its Employees handle this manually and allow them to submit it.
This is already covered - either each individual inputs their own work records or the application allows the company to do it for them - and then the NGO validates these records in the same way, regardless of who entered them.
I have created the NGO and single Volunteer relationships. I am confused as to how use the same tables but allow a new entity like Company come in between the NGO and Volunteer and manage the time validation and activity management.
Lets go through a worked example to illustrate both use cases, to make sure we've got everything covered:
Worked Examples
Individual, no company
An individual signs up, creating a row in the volunteers table. They sign-up for an activity, creating a row in the ngo_activity_applications table.
The NGO approves them, creating a row in the ngo_activity_members table - and either removing the row in the ngo_activity_applications table, or changing it's status - the spec. is unclear.
The individual does some work and logs the time in the app, creating rows in the ngo_activity_time_validations table.
The NGO validates the work done somehow, then tells the app this. This presumably changes the status of the rows in the ngo_activity_time_validations table and creates either one summary row or matching rows in the volunteer_validated_times table. Spec unclear where cost_per_hour comes from?
Company
A company signs up and uploads a CSV file with 3 volunteers in. This creates a row in the companies table, plus three rows in the volunteers table, and 3 rows in the company_volunteers linking table.
Company Volunteer 1 signs up to an activity individually and everything proceeds as above.
The Company signs up for a different activity and volunteers all 3 of it's people to work on it. This creates 3 rows in the ngo_activity_applications table.
The NGO approves all three, creating three new rows in the ngo_activity_members table - and either removing the rows in the ngo_activity_applications table, or changing their status - the spec. is unclear.
The volunteers do some work and the company logs time in the app on behalf of Company Volunteers 1 and 2 - and Company Volunteer 3 logs her own time:
Company Volunteers 1 and 2
The company uses the application to log the time on their behalf - creating 2 rows in the ngo_activity_time_validations table.
Company Volunteer 3
Company Volunteer 3 uses the application to log their own time - creating a row in the ngo_activity_time_validations table.
The NGO validates the work done somehow, then tells the app this. This presumably changes the status of the rows in the ngo_activity_time_validations table and creates either one summary row or matching rows in the volunteer_validated_times table. Spec unclear where cost_per_hour comes from?
Summary
You can see how much validated time any individual has logged by querying the volunteer_validated_times table JOINed to the volunteers table. You can also see how much validated time any Company has logged, by doing the same query but also joining on the company_volunteers table.
Possible changes & Questions:
You might want to add a company_entered flag to the ngp_activity_time_validations table, so that you can distinguish between records entered by individuals and ones entered by the company on an individuals behalf. You might also want to add the ID of the person who makes the entry in this table, if logging that is relevant to your application.
Might want to add an hourly_rate column to the volunteers table, to use as a default cost_per_hour when creating rows in the volunteer_validated_times table.

Related

Database design for weekly time tracking

I am planning on creating a database to track user's time in/time out M-F. Every week should begin on monday and run through sunday.
I have a table filled with my entire user population, so I know which users I need to create entries for and where they belong to. I have proposed so far, a table consisting of the following fields to track the entries (along with example data to fill the fields):
Field Name in table (Example of possible data)
---------------------
Employee (John Smith) 'String
Unit (Quality Assurance) 'String
WeekOf (9/9/13) 'date
InMonday (6:30) 'string, validate either a time in/out or N/A if holiday/vacation
OutMonday (3:15) '^^
HoursWorkedMonday (8.00) 'total hours worked
VacationMonday (0.00) 'if N/A for time, should have hours here
OvertimeMonday (0.00) 'any additional work hours should go here
For this instance, I would have to create In/Out for each day of the week (and perhaps track the date that each day is for). Is this extraneous or is there a seemingly better organization to tracking weekly time measurements? Should I use one table with a unit indicator or multiple tables for each unit?
Usually it's one table with a Date field, an In field and an Out field. That's pretty much standard timesheet data. Take a look at how this guy has it set up.
Make sure you're using an Employee ID in the timesheet, and then you would have a corresponding Employee table with all relevant info (ID, Name, Address, whatever else you store on him/her).
While this project is technically feasible, I have to question the value of making it yourself in Access.
The main issue is with security:
As a desktop program, this can be very easy to hack without precautions. Keep in mind that with Access, the user interface and the designer interface are by default the same thing.
If this is going to be a simple, straightforward db, a motivated user just needs to open the navigation panel and they can add/edit/delete all the timesheets.
If you hide the navigation panel, the user can just do a quick google search and learn to hit F11 (or find it by accident, either way)
You can try regularly (daily? hourly?) transferring the data from the publicly accessible back-end to an archive db that is not accessible to the general users. This can work, but still gives them a window to edit records. And if you don't do the transfer right, they can still add old records.
As a webform on a SharePoint, this can be fairly secure. I'd recommend this if you have Sharepoint.
You should also consider your development time. This is a very common business task across many industries, from restaurants to factories to schools. As such, there's a huge number of cheap web-based options already out there that you can start using today. I'll even assume some of these include summary reviews breaking out numbers by departments as well.
I've never researched these myself, but a quick google search found this interesting page: http://en.wikipedia.org/wiki/Comparison_of_time_tracking_software

Access: Entering multiple subform values with one entry in the form

I've been using Access to create simple databases for a while with great success, but have run into a problem I can't find an answer to.
We ship individualized serialized units to various end-users, and occasionally to resellers that stock them for end-users. I must keep track of which serial numbers end up with each end-users.
The first database I created to handle this recorded company information in one table using their account number as primary key, order information in a second table using the order number as the primary key and linked via the company name, and unit information in a third table with the serial number as the primary key and linked via the order number.
This worked very well until I had to account for these stock orders with a reseller. As it was structured, every unit was linked to one company via the sales order. The issue is that I may ship 20 units on one order to Company A, who then sells 5 to Company B and 3 to Company C.
I realized I needed to link the company name directly to the units, not the orders and have fixed that.
My issue now is simplicity in entering information in the form. My previous database involved the employee in our shipping department merely entering the sales order, selecting the customer name from a drop down menu, then scanning the serial numbers in a subform. This was to ensure simplicity and try to eliminate human error. He had only three things to input, and most of the input was done by scanning barcodes.
As it is currently structured now, the employees out in shipping would have to populate the company name for every record in the subform with the serial number and that complicates things in a way that is unacceptable. At the point of shipping, the company name will always be the same for every unit in the subform.
So.
How would I go about creating a form where the company name is entered once in the form, and automatically populates itself for every record in the subform? The caveat here is that I must also be able to go back occasionally and change the company name of individual units in an order without necessarily affecting the rest of the order. I suppose it starts out as a one-to-many relationship that then must be able to change.
I hope that makes sense.
I have looked for answers using various approaches with auto-fill and relationships and not preserving data integrity, but I feel the answer is just beyond my reach.
The only solution I can think of is to create another field in the unit table for the end-user, and perhaps write a formula that sets this default value as the company name from the order that shipped it. This seems unnecessarily complicated and redundant, there has to be a better way.

Proper way to model user groups

So I have this application that I'm drawing up and I start to think about my users. Well, My initial thought was to create a table for each group type. I've been thinking this over though and I'm not sure that this is the best way.
Example:
// Users
Users [id, name, email, age, etc]
// User Groups
Player [id, years playing, etc]
Ref [id, certified, etc]
Manufacturer Rep [id, years employed, etc]
So everyone would be making an account, but each user would have a different group. They can also be in multiple different groups. Each group has it's own list of different columns. So what is the best way to do this? Lets say I have 5 groups. Do I need 8 tables + a relational table connecting each one to the user table?
I just want to be sure that this is the best way to organize it before I build it.
Edit:
A player would have columns regarding the gear that they use to play, the teams they've played with, events they've gone to.
A ref would have info regarding the certifications they have and the events they've reffed.
Manufacturer reps would have info regarding their position within the company they rep.
A parent would have information regarding how long they've been involved with the sport, perhaps relations with the users they are parent of.
Just as an example.
Edit 2:
**Player Table
id
user id
started date
stopped date
rank
**Ref Table
id
user id
started date
stopped date
is certified
certified by
verified
**Photographer / Videographer / News Reporter Table
id
user id
started date
stopped date
worked under name
website / channel link
about
verified
**Tournament / Big Game Rep Table
id
user id
started date
stopped date
position
tourney id
verified
**Store / Field / Manufacturer Rep Table
id
user id
started date
stopped date
position
store / field / man. id
verified
This is what I planned out so far. I'm still new to this so I could be doing it completely wrong. And it's only five groups. It was more until I condensed it some.
Although I find it weird having so many entities which are different from each other, but I will ignore this and get to the question.
It depends on the group criteria you need, in the case you described where each group has its own columns and information I guess your design is a good one, especially if you need the information in a readable form in the database. If you need all groups in a single table you will have to save the group relevant information in a kind of object, either a blob, XML string or any other form, but then you will lose the ability to filter on these criteria using the database.
In a relational Database I would do it using the design you described.
The design of your tables greatly depends on the requirements of your software.
E.g. your description of users led me in a wrong direction, I was at first thinking about a "normal" user of a software. Basically name, login-information and stuff like that. This I would never split over different tables as it really makes tasks like login, session handling, ... really complicated.
Another point which surprised me, was that you want to store the equipment in columns of those user's tables. Usually the relationship between a person and his equipment is not 1 to 1 and in most cases the amount of different equipment varies. Thus you usually have a relationship between users and their equipment (1:n). Thus you would design an equipment table and there refer to the owner's user id.
But after you have an idea of which data you have in your application and which relationships exist between your data, the design of the tables and so on is rather straitforward.
The good news is, that your data model and database design will develop over time. Try to start with a basic model, covering the majority of your use cases. Then slowly add more use cases / aspects.
As long as you are in the stage of planning and early implementation phasis, it is rather easy to change your database design.

MS Access tracking effective dates of employees

I currently have an MS Access application that stores information about the employees who have responsibility for a certain task.
My form goes like this. You enter the task in a textbox. You pick the employee from a combo box which is bound to the staff table. And finally we save this information to the Task table. As simple as that I thought...
But here is the problem. No employee works forever in a company. A new/another employee maybe assigned the task which was previously carried out by an employee who is no longer working there. In the form once I update the new employee the old employee information is replaced and we wouldn't even know that that employee existed.
I came across the concept of adding effective dates to the employee which may be used to track the history of employees.
Now I would like to know how I would be able to preserve the data of the previous employee when I update the Task form with the information of the new employee.
What should I do?
Thank you for your assistance.
BR,
Paul
I have uploaded links to three forms that I am working on.
In the outside company officer form we don't have the date fields mentioned.
In our companies proposal form we might need to add additional officers but don't want to repeat the proposal information just the officer, division, alternate officer & division.
In the outside company detail form we might need to apply the same concept to the director of the company without applying to other institute information.
I was also researching on this topic where I found a document which explains the concept of effective dates. I need to know how to apply this and also without making a lot of changes to the application.
www.gsa.gov/graphics/staffoffices/DatedInformationandDateTracking.pdf
I hope this helps you understand my problem.
It would seem you are keeping very simple information, you want to know who is currently assigned to any given task. Add a "assignedDate" field to your table. Then you can change any reports or forms where you need to display the current assignee to a query whereby you group by "task" and select only the latest record.
Do not include the assignee as a field in the task table. You would need an additional table, say "TaskAssignees" comprised of TaskID, ContactID, entry date, assigned date, unassigned date. Now in reporting you can pull the correct assignee given any date or list a history of the assignees from start to finish.
I would say that you are making the issue too complicated.
Surely there's an administrative policy on what happens to tasks when an employee leaves -- their replacement takes them over or they are assigned to the departing employee's supervisor or a co-worker.
Thus, your application should encode that business practice. The form where you edit the employees should be set up so that when an employee leaves, their tasks are moved to the appropriate employee. This means you don't have to store effective dates and then write the complex SQL to filter by those dates. Instead, you'll use the same structure as you already have.
Now, of course, I'm not stupid -- I know that many companies SHOULD have such policies, but very often, these things fall through the cracks. When I'm in this position (as an outside contractor) I tell them their two options and price the two options. Implementing a policy for what happens with the assigned tasks when the employee leaves is cheap. Implementing an effective date is EXPENSIVE. So, if they want to save money, they'll come up with a policy that can be implemented in the database application.
If the solutions already suggested don't work for you then you could look at creating an audit table which effectively logs every change that is made to a record (This would have the advantage of allowing you to track ALL changes, even in areas of your system you have not yet developed).
Here are a couple of links that show how you could go about doing this:
a simple solution for tracking changes to access data
Allen Browne - creating an audit log.

Website Transactions in MySQL Database

Good Day,
I'm currently designing database structure for a website of mine. I need community assistance in one aspect only as I never did something similar.
Website will include three types of the payments:
Internal payments (Escrow kind payments). User can send payment to another user.
Deposits. Users add fund to their accounts.
Withdrawal. User can request a withdrawal. Money will be sent to their bank/PayPal account.
Basically, I need some tips to get the best design possible.
Here's what I'm thinking about:
deposits - this table will store info about deposits
deposits_data - this table will store info about deposit transaction (ex. data returned by PayPal IPN)
payments - table to store internal payments
withdrawals - table to store info about withdrawal request
transactions - table to store info about ALL transactions (with ENUM() field called type with following values possible: internal, deposit, withdrawal)
Please note that I have already a table logs to store every user action.
Unfortunately, I feel that my design approch is not the best possible in this aspect. Can you share some ideas/tips?
PS. Can I use a name "escrow" for internal payments or should I choose different name?
Edit
DEPOSITS, PAYMENTS and WITHDRAWALS tables store specific transaction details. TRANSACTIONS table stores only limited info - it's a kind of logs table - with a details field (which contains a text to display in user log section, ex: "User 1 sent you a payment for something")/
Of course I have users tables, etc.
Can I use a name "escrow" for internal
payments or should I choose different
name?
Escrow has a specfic financial/legal meaning, which is different from how you seem to mean it: "a written agreement (or property or money) delivered to a third party or put in trust by one party to a contract to be returned after fulfillment of some condition" (source)
So choosing a different name seems like a good idea.
As for design, what data will DEPOSITS, PAYMENTS and WITHDRAWALS store which TRANSACTIONS won't? Also, you need an ACCOUNTS table. Or are you planning to just use your existing USERS table (I presume you have such a thing)? You probably ought to have something for external parties, even if you only intend to support PayPal for the time being.