without losing old fees payment in MySQL - mysql

i am creating a student management system, i have 3 tables, student, fees, student_fee, the fee table contains the amount of fees and the student_fee contains reference to student.studentid and fee.feeid, so that whenever a student paid their fees, the studentid, feeid and paid_date will be insert into the student_fee table. Fees can increase the next year, how can i still keep the old records of fees payment without losing and causing any problem to the account

Instead of doing an entire history table separately, just add a column into the student_fee_paid table for the amount of the payment... so you can still query from it directly for the entire history of a student and it will have the historical values all in one... ex:
Student Fee_ID DatePaid FeeAmount
X 1 1/1/2009 $25
X 1 1/1/2010 $25
X 1 1/1/2011 $30
X 1 1/1/2012 $35
Otherwise it will just grow to a larger task... If you have 30 different fees, and the fee schedule amount changes for some but not all, what then... You can keep your "Fee" table to reflect whatever the "Current" fee amount is, but as soon as its paid, stamp that amount immediately.... if rates change mid-year, yet another trouble / history consideration... don't worry about the otherwise minimal amount of data storage this will increase.

Create a history of fee payment table. StudentID, FeeID, DatePaid, AmountPaid
or Effectively Date your Fee table.

Copy the table fees and student_fee for archive purpose.
You can use the SELECT INTO command.
http://www.w3schools.com/sql/sql_select_into.asp

Related

multiple currencies in a single table

How to make a MySQL table that could contain multiple type of currencies ($, Euros, ...) ? And if I want to make a final report is their a way to make a sum of those currencies other than adding multiple if statements to the sum ?
There may be several aspects involved. So here is some brainstorming:
You offer the same product in different currencies, e.g. a toy for 10 EUR or 11 USD. So you'd probably have an item table plus an item_price table, where the latter has product number, currency and price. (An alternative would be to have just one price, e.g. in USD and a currency table with conversion rates and you'd calculate the foreign price. But then you'd get "ugly" prices, e.g. 10.57, rather than typical prices like 10.50, 10.90 or 10.99. But well, you could have a price adjustment funtion for that, too. And you'd have to keep your conversion tables up-to-date or live with possible losses.)
A customer buys products and pays the bill. The bill is in one currency (store price and currency in the bill), but you also get your money in your currency, as PayPal or the bank convert it at a daily rate. Do you need to store this real amount, too? Then that would be another column in your bill.
I don't know how it is about taxes. Different currencies sounds like different countries. Maybe you'd have to deal with these in your database, too. I just don't know. The prices you show and store are usually gross prices (the price a customer actually pays) and the taxes (could be different VAT percentages with different products in one single bill) would have to be calculated.
As to getting sums: with all the information stored you'd get them with joins from the tables. No if-then-else in my opinion.
As per my opinion you can create a Country Table which contains
CountryID, CountryName, CurrencyCode, ExchangeRate. Now In that
country table you have to add all countries which you want to add but
you have to keep one thing in mind that you have to decide 1 currency
as base currency and put exchangeRate as 1 for that currency and
convert all other currencies exchangeRate based on the base currency
and insert into that table. i.e. Keep base currency as USD so insert
1 record with USD and exchangeRate must be 1 for that currency.
Suppose I am adding India as country than exchangeRate for that
country is based on USD as 66.40 Rs. insert all other countries
according to this entries.
Now when you want to add any transaction related to money in any
table then keep exchangeRate column with that amount column. ind
insert the exchangeRate and amount same as user's currency. i.e. If
my user is in India country, so it's currency is INR. Now that user
wants to add 1000 Rs. then you have to enter that 1000 Rs amount in
transaction table as it is without any conversion with exchange Rate
of 66.40 (fetch from country table). Same way If user currency is USD
and he wants to add a transaction of 100$ than store 100 as Amount
and exchangeRate as 1.
Now when you want to create any reports then just divide exchangeRate
with Amount, so you will get report in your base currency and after
conversion in base currency you can generate each report in any
currency as per your requirement.

Client Management DB Design - Track credit based purchases

My reservation system allows us to purchase credits for clients in terms of pre defined packages. I'm struggling with how I record and calculate available credits.
Let's say we're talking about a car wash service. A client can have multiple cars and can purchase the following services, 'Wash and Wax' and 'Detailing'.
Client 1 has two cars, Car A and Car B. He brings them both in and purchases:
Car A - 1 Wash and Wax
Car A - 1 Detailing
Car B - 10 Wash and Wax
Car B - 1 Detailing
This generates 4 rows in my Purchases table, one for each service purchased.
In my DB I have two related tables tracking purchases and reservations. Table 1 Purchases, Table 2 Reservations.
In Purchases I have the following fields of note:
id
client_id
car_id
service_id
credits_purchased
credits_scheduled
credits_used
cart_id
Then in my Reservation table I have the following fields of note:
id
client_id
car_id
service_id
reservation_date
completed_datetime
car_in_datetime
car_out_datetime
purchase_id
I track the credits available by updating the Purchases table fields credits_used and credits_on_schedule as events happen.
For example, when the client makes a reservation the system adds a new record in the Reservations table, once this happens the system also runs an update query and adds +1 to the related Purchases table credits_on_schedule. When the Reservation is updated to complete the system also updates the Purchases table and adds -1 to credits_on_schedule and +1 to credits used. Simple math between credits_purchased, credits_used, and credits_on_schedule derive what credits are available for a client to use.
I feel like this isn't a good way to track the credits. My question is what is a better implementation? Should I just track credits_purchased then use count queries on the Reservation table to calculate credits_used and credits_on_schedule? Should I be using a pivot table to track? I can't seem to wrap my head around what is the cleanest design.
It looks to me that the design is ok in general.
A reservation can only have one purchased related to it so purchase_id field is a foreign key in Reservation table.
Nevertheless, my advise to you is to create a log system of all these record updates.
As you mentioned, as events are fired the system updates the calculated fields.
What if for some reason the system fails at a certain point? You should be able to track these events.
One way to avoid this is, as you mentioned, calculate credit_used by a count query on all completed reservations.

Invoice table design

I am creating an invoice table for the customers. Sometime they will have to send me the commission fees or sometime I send them fees (account balance). How to design a invoice table in this situation?
I have came up with this solution, im not sure if this is correct or what is the alternative way?
tbl_invoice
- invoice_id (PK)
- order_id (FK)
- invoice_date
- amount (copy the price from tbl_order.total table)
- status (Invoice Sent, Cancelled, Amount Received, Amount Sent)
tbl_Payments
- invoice_id (FK)
- amount_received (recieved commission fees from customer)
- amount_sent (sent fees to customer)
- date_received
- date_sent
if the tbl_invoice.amount is -30.00 that mean customer will send me the fees.
if the tbl_invoice.amount is 30.00 then I will send the customer the fees.
Do I need tbl_invoice.amount field?
If you could redesign my tables how it should be that be great.
A few things:
Normalize invoice status to be its own lookup table, then put a Status ID in the invoice table rather than 'Sent', 'Cancelled', etc.
Definitely keep invoice amount. This might have to be different from the price value in tbl_order.total if you ever need to take into account discounts. In any case, numerical data is cheap to store and will be faster to query if you dont have to do any joins.
Give the Payments table its own ID column and make it the PK.
The rest looks ok. There is a case for having two tables, one for payments outgoing, and another for payments incoming. If you really only need to keep the amount and date information, then I dont think you need to make it any more complicated.
Thanks,
Chris.
You should be tracking:
amount_due
amount_sent
amount_received
All three are important. And in the payments, also track the fee_paid.
Lastly, it's usually better to use T-ledger accounting (i.e. debit/credit) for this kind of stuff. It makes things much cleaner if you ever need to worry about discounts, coupons, refunds, chargebacks, etc.

Invoice table: Send fees and Receive Fees [duplicate]

I am creating an invoice table for the customers. Sometime they will have to send me the commission fees or sometime I send them fees (account balance). How to design a invoice table in this situation?
I have came up with this solution, im not sure if this is correct or what is the alternative way?
tbl_invoice
- invoice_id (PK)
- order_id (FK)
- invoice_date
- amount (copy the price from tbl_order.total table)
- status (Invoice Sent, Cancelled, Amount Received, Amount Sent)
tbl_Payments
- invoice_id (FK)
- amount_received (recieved commission fees from customer)
- amount_sent (sent fees to customer)
- date_received
- date_sent
if the tbl_invoice.amount is -30.00 that mean customer will send me the fees.
if the tbl_invoice.amount is 30.00 then I will send the customer the fees.
Do I need tbl_invoice.amount field?
If you could redesign my tables how it should be that be great.
A few things:
Normalize invoice status to be its own lookup table, then put a Status ID in the invoice table rather than 'Sent', 'Cancelled', etc.
Definitely keep invoice amount. This might have to be different from the price value in tbl_order.total if you ever need to take into account discounts. In any case, numerical data is cheap to store and will be faster to query if you dont have to do any joins.
Give the Payments table its own ID column and make it the PK.
The rest looks ok. There is a case for having two tables, one for payments outgoing, and another for payments incoming. If you really only need to keep the amount and date information, then I dont think you need to make it any more complicated.
Thanks,
Chris.
You should be tracking:
amount_due
amount_sent
amount_received
All three are important. And in the payments, also track the fee_paid.
Lastly, it's usually better to use T-ledger accounting (i.e. debit/credit) for this kind of stuff. It makes things much cleaner if you ever need to worry about discounts, coupons, refunds, chargebacks, etc.

Database design: credit top-ups and transactions

We're in the business of lead generation. Customers receive leads from us. They view basic information about the lead and decide whether to accept the lead or reject. If they accept the lead, they are deducted 1 credit (for each lead) and they can view the detail info of the lead.
So each lead costs 1 credit (which is tied to some monetary value).
We have different type of customers: insurance agents, real estate agents, credit card companies, clubs, etc. They pay different price for 1 credit.
Customers can be prepaid or postpaid.
I have the following tables for all of the above:
Customers (id, name, address, is_postpaid, customer_type_id)
CustomerTypes (id, name, credit_price) // name: insurance agent, real estate agent, etc
TransactionTypes (id, name) // add to or deduct from credit balance
CustomerTransactions (id, customer_id, quantity, transaction_type_id, credit_balance, credit_unit_price, date_created)
Questions:
What do you think about the overall approach?
This design is OK for prepaid customers. But what about postpaid?
Any feedback and criticism is appreciated.
Update:: I've updated above tables to include the FK in Customers table.
If the grain of the transaction table is truly one transaction (no cumulative fields), than there is no difference between pre-paid and post-paid customers. You may enter payments as positive and debits as negative numbers in a same column, or (as some people prefer) use two columns for "positive and negative" customer transactions.
Customer balance can always be obtained by:
select
CustomerName
, sum(Credits) - sum(Debits) as AccountBalance
from Transactions as t
join Customer as c on c.CustomerId = t.CustomerId
group by CustomerName
order by CustomerName ;
I would change the database to the following:
Customers (id, name,customerType_id, address, is_postpaid)
CustomerTypes (id, name, credit_price)
CustomerTransactions (id, customer_id, quantity, transaction_type, credit_balance, credit_unit_price, date_created)
What I am not so sure is about the prepaid or postpaid concept. If you can please clarify it for me.
i would also suggest that there is no difference between pre and post pay - you just have transactions.
to accomodate the pre-post differences, you could introduce a new table that describes it:
customer_type
--------------
id
pre_or_post
begin_date
end_date
One thing about credits is that from an accounting standpoint, they are a liability on the books if prepaid. They are sort of like gift cards, you can't recognize the revenue until the credits are used. With that in mind, you want to have credits expire after a certain length of time, like 1 year. Since credits expire, you then need to deduct credits in order, from oldest to newest.
You should have one table to record credit usage (i.e. CustomerCreditUsage), and another table for credit purchases (CustomerTransactions). Upon purchase, you check for negative credit balance and close out the record(s) from the credit usage table. If prepaid, when you record a credit usage transaction, you deduct from the credit balance of the oldest credit purchase.
Keep in mind that there is a loose relation between credit purchases and credit usage. You can have one without the other. Although you don't want to have a credit usage without a matching credit purchase for too long (post paid).