Spaces:
Sleeping
Sleeping
File size: 4,526 Bytes
e69be74 75a9c52 eba303d 75a9c52 e69be74 4a10a29 e69be74 4a10a29 e69be74 4a10a29 e69be74 4a10a29 e69be74 75a9c52 4a10a29 e69be74 eba303d e69be74 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
import math
import copy
from algorithm.product import Product
def calculate_dish_price_with_taxes(_products, taxes, grand_total):
payment_total = round(grand_total - taxes, 2)
grand_total = round(payment_total, 2) + round(taxes, 2)
_product_with_taxes = copy.deepcopy(_products)
for _product in _product_with_taxes:
_product.price = round(((_product.price / payment_total) * grand_total), 5)
return _product_with_taxes, grand_total
def round_up_two_decimals(_products_total):
_product_with_taxes_rounded = copy.deepcopy(_products_total)
for _product in _product_with_taxes_rounded:
_product.price = math.ceil(_product.price * 100) / 100
return _product_with_taxes_rounded
def first_algorithm(_products_total_rounded, receipt_subtotal):
current_total = 0
for _product in _products_total_rounded:
current_total += _product.price
current_total = round(current_total, 2)
difference = current_total - receipt_subtotal
corrections = copy.deepcopy(_products_total_rounded)
for _product in corrections:
_product.price = round((_product.price / current_total) * difference, 2)
for i in range(len(_products_total_rounded)):
_products_total_rounded[i].price = round(_products_total_rounded[i].price - corrections[i].price, 2)
_final_total = 0
for _product in _products_total_rounded:
_final_total += _product.price
return _products_total_rounded, _final_total
def fractional_part_rest(value):
fraction_str = f"{value:.10f}".split('.')[1]
rest_of_digits = fraction_str[2:]
return float(rest_of_digits)
def second_algorithm(_products_total, receipt_total):
_products_total_rounded = round_up_two_decimals(_products_total)
current_total = 0
for _product in _products_total_rounded:
current_total += _product.price
if current_total == receipt_total:
return _products_total_rounded, receipt_total
difference = current_total - receipt_total
difference = round(difference, 2)
fractional_parts = copy.deepcopy(_products_total)
for _product in fractional_parts:
_product.price = fractional_part_rest(_product.price) - math.ceil(_product.price)
fractional_parts = sorted(fractional_parts, key=lambda p: p.price, reverse=False)
for i in range(len(fractional_parts)):
if difference <= 0:
break
_products_total_rounded[i].price -= 0.01
difference -= 0.01
_final_total = 0
for _product in _products_total_rounded:
_final_total += _product.price
for _product in _products_total_rounded:
_product.price = round(_product.price, 2)
return _products_total_rounded, _final_total
def clean_and_convert_to_float(price):
if price == "": return 0.0
clean_price = ''.join(c for c in str(price) if c.isdigit() or c in ",.")
return float(clean_price.replace(",", "."))
def calculate_tips_and_taxes(items_table, total_amount, tax, tips):
products = []
if items_table[0][0] == "No items":
return products, 0
if total_amount == "Not specified" or total_amount == "unknown" or total_amount is None:
total_amount = "0.0"
if tax == "Not specified" or tax == "unknown" or tax is None:
tax = "0.0"
if tips == "Not specified" or tips == "unknown" or tips is None:
tips = "0.0"
for item in items_table:
price = item[5]
if price == "Not specified" or price == "unknown":
price = "0.0"
item_value = clean_and_convert_to_float(price) if item[5] is not None else 0.0
products.append(Product(item[0], item_value))
sum_of_product_prices = 0
for _product in products:
sum_of_product_prices += _product.price
sum_of_product_prices = round(float(sum_of_product_prices), 2)
total_amount = round(clean_and_convert_to_float(total_amount), 2)
tips = round(clean_and_convert_to_float(tips), 2)
tax = round(tips + round(clean_and_convert_to_float(tax), 2), 2)
if round(float(total_amount), 2) != round(float(sum_of_product_prices) + float(tax), 2):
return products, sum_of_product_prices
products_total, subtotal = calculate_dish_price_with_taxes(products, taxes=float(tax),
grand_total=float(total_amount))
final_prices, final_total = second_algorithm(products_total, subtotal)
final_total = round(final_total, 2)
return final_prices, final_total
|