Bug in conversion of net/gross prices - mysql

In my project the user input for prices can be net or gross, depending on a configuration value. In database we save the net price as decimal(9,2), the VAT and a flag for the price to know if is deductible or not.
For example conversion from gross to net (that most users use):
VAT = 19%
Gross Price (user input)
Net Price (saved in Database)
1500
1260.50
But revert conversion to user input is not the same:
Net Price (saved in Database)
Gross Price (user input)
1260.50
1499.99
Saving the cents in database, will not solve the problem.
Saving the gross price in database is a bad practice and will imply a big data migration when the VAT changes.
Rounding the gross price for user will also not help, because it will generate calculation errors for the total price.
Please help...
Edit:
Another example (database price column is double):
Gross Price (user input)
Net Price (saved in Database)
19500
16386.554621848
Reverted conversion:
Net Price (saved in Database)
Gross Price (user input)
16386.554621848
19499.999999999

Revised answer:
It is not a bug but a roundoff error. You seem to be performing a division operation 1500 / (119 / 100) and storing the result in a fixed point datatype. Unfortunately, like in the above example, the result will contain infinite many digits after decimal (enter the above example on wolframalpha.com to see what I mean). When you use the truncated value to reproduce the original value, it will not match.
Unfortunately, the only thing you can do is to increase the scale of the net column. This will not eliminate the error, but it will decrease its magnitude. Then use the ROUND function for accounting purpose and for recreating the original value.
DB<>Fiddle

Related

Mysql datatype for money

i was trying to create a money related app in which users can choose their currency. Mysql datatype i tried is decimal(19,4). Now the problem is few currencies need three precisions and some need two
Eg:
oman rial needs three precisions. ie 1000 baisa = 1 omani rial. Hence my customers may enter 6.783 omani rial.
Where as my US customers will need only 2 precisions as 100 cents = 1 dollar and they may enter 5.50.
When i insert these two entries to my database using decimal(19,4), it is saved as 6.7830 and 5.5000 respectively.
Now the real pain is when i need to display their entrys as i dont want to display that extra 0 in omani rial entry and that 00 in US dollar. I also tried float but last digit gets rounded off at times.
Is there any mysql data type in which i can save exact entry as it is without any rounding off or extra zeros? If there is no such entry, how can i make it ppssible?
You can use VARCHAR to store exact representations, but I don't recommend that because it takes more bytes to store a number as a string. And any arithmetic you do on the value will convert it to a number anyway.
I recommend you use DECIMAL(19,4), and then format the value in application code, to display it with the appropriate digits. Every programming language has some function like printf() that allows you to control the output formatting, regardless of the value stored.

Find the exact phrase in a string (SQL Server 2008)

I receive the file from third party, which I upload to a table. It has a Description column in which I have to find an "Account NO" (9 characters in length).
A few sample descriptions:
FROM AMH-061060-POK UNSECURED OVER 40 DAYS
MAINTENANCE FEE A/C A4G123456
ADJUST BALANCE VS 6PK-123123
REIMBURSEMENT OF CHECK RE-ORDER FEE A4G111111 p11
Asset Mgmt acct gold annual fee MPL NFL234234.
Description column is a free text and doesn't know where the account no appears.
As you see above, it may appear at the end of the description or in the middle somewhere or at the start.
For this AMH-061060-POK, we truncate POK and remove '-' to get 9 length account number.
Any help is appreciated in finding the account number using SQL functions?
Anupama - in the first example, how do you know that the account number is "AMH-061060" and not "UNSECURED"? Both are nine characters.
What is logic in determining which string is the account number? First define it, then you can code it.

What datatype should I use for my Tickets table?

I'm creating a table which is set to list out the prices of tickets for specific venues of a tour in my database.
The price needs to be in UK currency (£0.00) as the tours are based in the UK. However when it comes to setting the datatypes for the price columns I was unsure what datatype would allow the format of UK currency to fit. So I used DOUBLE PRECISION but when trying to input these values:
INSERT INTO `tbl_Tickets` (`Student_Price`, `Adult_Price`, `OAP_Price`, `Tourdate_id`)
VALUES ('£15.00', '£22.00' ,'£13.50', 1);
I get a 0, each of the price columns.
What datatype should I set my price columns to, to allow UK currency to properly fit?
You should probably use a fixed-point numeric type to store currency of any nationality, eg. DECIMAL(5, 2) which would store values up to 999.99.
As spencer7593 points out below, there's no need to be stingy with the number of digits, as the DECIMAL type's storage format is quite compact.
You must never, never, never use a floating-point datatype for money. You must always use a decimal radix, in this case DECIMAL(N, 2), where N is some reasonably high upper bound on values, their sums, etc, such as ten, or much more if you're running a bank. The 2 is because you have 100 pence to the pound, but again there are cases where you might want a bit more.

Using running totals in MS access report cumulatively

I am developing a db (MS access 2010) to support a school with a well-defined model for tuition quotation. The list of products is assembled for each quote, then various discounts are applied. The discounts may be a percentage or an absolute dollar amount. So far, so easy. The problem is that their business logic requires:
No limit on number of discounts.
Specific discounts to be applied in a defined sequence (implemented in my case with a "discount ordinal" column, values 1 (first applied) to 100 (last applied).
Each sequential application of a discount is to the running total of the quote. Eg: Total products $1000. Discount: 50%. Value: $500. Subtotal $500.
Subtotal: $500. Discount: $25. Value: $25. Subtotal: $475.
Subtotal: $475. Discount: $10%. Value: $47.50. Subtotal: $427.50.
This appears to be a variation of the "get the value of the field in the previous row" problem, but with the added twist that the "value of the field" is actually a cumulative calculation. It has the flavor of recursion: while discounts remain, subtotal(previous subtotal).
I have no clear idea how to implement this in a report, because the calculation as noted above is self-referential. I'm not looking for code here, just guidance on the general approach to the problem (ie, some kind of global variable, using VBA - in which case, I'm not sure what the "glue" between the query in VBA and the report would be - or some trick with a calculated field although I've spent a lot of time trying to figure one out). Any thoughts?
In that kind of situations, I always create a new table, that will get filled up when the report opens, and base the report in that table, not the original one. That way I can do all the calculations I need, even making several passes. The report then is simply a "dump" of the table. Complex totals can be additional columns, that will be shown only in the totals section.
You could have table for purchase history using an integer to link each purchase since an autonumber by itself will not link each discount stage.
So in excel I would use something like this:
v = Starting Value
i = 1
Do Until i = Last Discount
d = ws.Cells(i, 9).Value
v = v * (1 - d)
ws.Range("B2").Value = v
i = i + 1
Loop
At each stage you could write to the table (using docmd.runsql) the discount applied (d) and the value (v) but it could be quite slow. You could then order the table by purchase identifier then descending by value since sequential discounts will inherently order correctly.

Mysql temporary database in codeigniter?

i have a deployment to do within 2 days time and for the last three days i have been busy trying to understand this one thing am stuck in. It probably might be very silly of me but please take me as a newbie.
I am using an opensource software php opensource pos and it is made on CI. Now the issue is that the reports in the application are different than what my client wants. I want to change that to the way they want it but i cant.
this is the code:
$this->db->select('sale_date, sum(total) as total, sum(profit) as profit');
$this->db->from('sales_items_temp');
if ($inputs['sale_type'] == 'sales')
{
$this->db->where('quantity_purchased > 0');
}
elseif ($inputs['sale_type'] == 'returns')
{
$this->db->where('quantity_purchased < 0');
}
$this->db->group_by('sale_date');
$this->db->having('sale_date BETWEEN "'. $inputs['start_date']. '" and "'. $inputs['end_date'].'"');
$this->db->order_by('sale_date');
return $this->db->get()->result_array();
every thing is working fine and as expected. Now i need to make some changes but the issue is i cannot find the temp database to see which fields it has. This database table (the temp one) is being used in all the reports functions, same database.
Can some one be so helpful and explain me the way it works, or how is that i can make a change to it!?
The scenario is that it is giving a summary of all the sales in the selected date range as total. I want a break down in terms of cash, credit, credit card, debit card etc.
I have another report which shows that, but not in date wise as in not saying how much in which day but in total of the date range. This one gives the total as in total sales in a day but not the break up of it as in what was what.
You can login here first:
https://demo.phppointofsale.com/index.php/login (id and password is saved on the page)
Then you can paste this link on the address bar and see the report.
https://demo.phppointofsale.com/index.php/reports/summary_sales/1969-12-31/2012-03-13/all/0
I need it to be a breakdown of the total and remove the tax, profit and subtotal columns and change that with the kind of payment as in cash | credit | cheque etc and then a total for that day.
PS: I am sorry for such a big writing but i am really stuck, please help me out. Thank you in advance.
The table name is sales_items_temp.
To see the actual database config (for database name, host, etc), look in either /system/application/config/database.php or /application/config/database.php depending on the version of Codeigniter.
To see about changing the query, check out http://codeigniter.com/user_guide/database/active_record.html.