37794-vm/core/pricing.py
2026-02-01 17:18:59 +00:00

71 lines
2.3 KiB
Python

from decimal import Decimal
import math
from .models import PricingRule, PlatformProfile
def calculate_haversine_distance(lat1, lon1, lat2, lon2):
"""
Calculate the great circle distance in kilometers between two points
on the earth (specified in decimal degrees)
"""
if lat1 is None or lon1 is None or lat2 is None or lon2 is None:
return Decimal('0.00')
# Convert decimal degrees to radians
lat1, lon1, lat2, lon2 = map(math.radians, [float(lat1), float(lon1), float(lat2), float(lon2)])
# Haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = math.sin(dlat/2)**2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon/2)**2
c = 2 * math.asin(math.sqrt(a))
r = 6371 # Radius of earth in kilometers. Use 3956 for miles
return Decimal(c * r)
def get_pricing_breakdown(distance_km, weight_kg):
"""
Returns a dictionary with pricing breakdown:
{
'price': Decimal,
'platform_fee': Decimal,
'platform_fee_percentage': Decimal,
'driver_amount': Decimal,
'error': str (optional)
}
"""
# 1. Find matching rule
# We look for a rule that covers this distance and weight
rule = PricingRule.objects.filter(
min_distance__lte=distance_km,
max_distance__gte=distance_km,
min_weight__lte=weight_kg,
max_weight__gte=weight_kg
).first()
if not rule:
# Fallback or Error
# Try to find a rule just by distance if weight is slightly off? No, strict for now.
return {
'price': Decimal('0.000'),
'platform_fee': Decimal('0.000'),
'platform_fee_percentage': Decimal('0.00'),
'driver_amount': Decimal('0.000'),
'error': 'No pricing rule found for this distance/weight combination.'
}
total_price = rule.price
# 2. Calculate Fees
profile = PlatformProfile.objects.first()
fee_percentage = profile.platform_fee_percentage if profile else Decimal('0.00')
platform_fee = total_price * (fee_percentage / Decimal('100.00'))
driver_amount = total_price - platform_fee
return {
'price': total_price,
'platform_fee': platform_fee,
'platform_fee_percentage': fee_percentage,
'driver_amount': driver_amount
}