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.
Related
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.
So, not sure how to explain this but here goes. I am trying to translate a table of commissions earned. Some of the records have the same invoice and item meaning multiple people earned commissions on that product. I want to merge those records so I only have one record per product per invoice. Basically, like a pyramid scheme, salespeople make commissions on sales and depending on what level they are at, (1,2,3,4) all salespeople above them get a commission as well. So I need to find records where invoice and item are the same,
pull data from each of those records and then output only one record with that data.
I am pretty sure a script component is the way to go but I am not sure how to pull multiple rows of data in to check for duplicate invoice and item, also keeping some of the data for each row to output together.
Let me know if you have any questions, I know I didn't word that the best.
The source table looks like this
COMMISSION Table
SalespersonID - the person getting the commission
InvoiceID - ID of invoice
ItemID - ID of specific lineitem on invoice
ProductID - ID of product sold
Sales_Amt - total for that lineitem
Salesperson Downlevel ID - ID of salesperson below SalespersonID if exists
Commission Rate - percentage Salesperson receives
Commission Total - amt salesperson receives
There are some other columns but these are the important ones.
I am translating this into a table that looks like this
New COMMISSION Table
CommissionId - Primary key for commission table
CommissionPayable - amt salesperson gets
CommissionPayableUpline1 - amt salespersonUpline1 gets
CommissionPayableUpline2 - amt salespersonUpline2 gets
CommissionPayableUpline3 - amt salespersonUpline3 gets
CommissionRate - percent salesperson gets of amount
CommissionRateUpline1 - percent salesperson upline1 gets
CommissionRateUpline2 - percent salesperson upline2 gets
CommissionRateUpline3 - percent salesperson upline3 gets
SalespersonId - Id of salesperson
SalespersonUpline1 - ID of salesperson upline1
SalespersonUpline2 - ID of salesperson upline2
salespersonUpline3 - ID of salesperson upline3
So you see we can have up to four levels of salespeople. Most of our salespeople are only 1 to 2 levels but we do have a few 3 levels deep and none currently that are four levels deep. The way it is stored in the old database is confusing and not very efficient.
I want to find rows with duplicate invoice and item ids, grab the salespeople, and down level salespeople as well as commission rates and amounts for each, then insert all that into one row in new system.
Well I finally got this figured out by using the ssis script component and then doing some fancy sorting and creating new records on output.
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
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.
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).