MySQL storing VAT rates and amounts for each invoice - mysql

I have the tables invoice_header, invoice_rows and vat_codes from the billing software based on a MySQL database. I need to add my own table invoice_vat.
For each new invoice (or updated invoice) I need to store (or update) VAT rates, net amounts and VAT amounts into the table invoice_vat, groupped by the vat code.
I have several vate codes and rates. For example I have:
ABC tax rate 5%
DEF tax rate 10%
GHI tax rate 22% etc.
For each invoice I can sell together some products with ABC vat, some products with DEF vat and some other products with GHI vat. Usually we do not use more than 5 different vat rates in one invoice.
For example one of my invoice looks like:
product1, quantity 2pcs, unit_net_price 100.00, row_net_amount 200.00, vat ABC.
product2, quantity 3pcs, unit_net_price 50.00, row_net_amount 150.00, vat ABC.
product3, quantity 1pcs, unit_net_price 90.00, row_net_amount 90.00, vat DEF.
product4, quantity 4pcs, unit_net_price 25.00, row_net_amount 100.00, vat GHI.
For this invoice I need to store the values into the tables invoice_vat:
vat1_code ABC, vat1_rate 5, vat1_net_total_amount 350.00
vat2_code DEF, vat2_rate 10, vat2_net_total_amount 90.00
vat3_code GHI, vat3_rate 22, vat3_net_total_amount 100.00
vat4_code NIL, vat4_rate 0, vat4_net_total_amount 0.00
vat5_code NIL, vat5_rate 0, vat5_net_total_amount 0.00
I can do the following query:
SELECT invoice_rows.vat, sum(invoice_rows.row_net_amount) AS mysum
WHERE invoice_rows.id=655
group by invoice_rows.vat;
Now I need to store the values I get from the query, every time I make a new invoice or I revise/update an old invoice.
Should I use a trigger? How should look the trigger?
Giuseppe

Have table(s) that itemize the components of an invoice. Have another table that shows the invoice amounts as sent to the customer. For accounting and business and maybe legal reasons, this table should be "write once". That is, you should never change it, once it is finalized. At this point you are recording what you sent to the customer; it is not some scratch pad where things can be added/changed/deleted.
Note, in particular, if a item's price changes, or a VAT amount changes, then new computations would lead to an invoice that disagrees with what you sent the customer. Not good.

Related

Applying row over row conditional logic in aggregate functions in SQL

I have two tables stored in a MySQL database. The first contains pricing information about SKUs I want to sell tomorrow. The second contains historical sales and visitation data for SKUs. What I want to do is calculate the conversion rate (orders divided by visits) for each SKU at the price specified in the tomorrow's pricing table based on prior sales data at tomorrow's specified price, conditioned that the SKU at that price has at least 100 visits OR 50 visits and 1 order, and if not then I want it to add the visits and orders from the next highest price point.
I've created a table containing example data in an SQL fiddle
http://www.sqlfiddle.com/#!9/bf4273
Using the example data in the sqlfiddle, what I want to return then would be
ABC1, 100.0, 100, 0
ABC2, 75.0, 24, 0
ABC3, 35.0, 1312, 57
ABC4, 190, 55, 1
ABC5, 250, 72, 1
ABC6, 250.0, 80, 1
If you examine the data in the sql fiddle, you can see that ABC1 doesn't meet the count requirements at the specified $100 price point, so it rolls up the visits from the next higher price point, in that case 110, but keeps the reported price at 100.
ABC2 doesn't have enough visits at the specified price, but there aren't any visits at any other price point higher than the specified one, so it just returns the 24 and 0 visits.
ABC3 meets the requirements, so it just returns the specified value
ABC4 meets the > 50 visits and > 1 sale, so it's returned
ABC5 doesn't have enough visits and orders at the specified price, so it sums up the visits and orders to include the next highest price point. This logic is re-applied again if rolling up to the next highest price point still doesn't meet the requirements for 100 visits or 50 visits and 1 order.
ABC6 is similar to ABC5 except that now the orders at the specified price point for ABC6 for tomorrow is zero, but we still take the orders count from the next highest price point too (e.g. we sum up visits and orders from the next highest price point until we meet the necessary visits and/or orders requirements).
At the moment I've applied this logic inside Python, but it's a bit cumbersome and if possible I'd like to have it all in SQL. Can anyone help? Even telling me it's not possible to do this in MySQL would be valued.
Thanks,
Brad

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.

ssis duplicate rows and script componenet

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.

without losing old fees payment in 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

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.