Update MMS43 pricing
This commit is contained in:
parent
77f7b00b8f
commit
9b091bc041
|
@ -7,14 +7,30 @@ func NewMMS43PricingService() (*MMS43PricingService, error) {
|
|||
}
|
||||
|
||||
func (s *MMS43PricingService) Prices(params PricingParams) (map[string]Price, error) {
|
||||
// Calculate passenger price
|
||||
var passengerAmount float64
|
||||
|
||||
// First 2 trips are free (1 return trip or 2 outward trips)
|
||||
freeTripsRemaining := 2 - params.Beneficiary.History
|
||||
if freeTripsRemaining > 0 {
|
||||
// Trip is free
|
||||
passengerAmount = 0.0
|
||||
} else {
|
||||
// Price is 0.15€/km for passenger distance (convert meters to km)
|
||||
passengerAmount = 0.15 * (float64(params.SharedMobility.PassengerDistance) / 1000.0)
|
||||
}
|
||||
|
||||
// Driver indemnification is always 0.30€/km for driver distance (convert meters to km)
|
||||
driverAmount := 0.30 * (float64(params.SharedMobility.DriverDistance) / 1000.0)
|
||||
|
||||
return map[string]Price{
|
||||
"passenger": {
|
||||
Amount: 0.32 * float64(params.SharedMobility.PassengerDistance),
|
||||
Currency: "EUR/2",
|
||||
Amount: passengerAmount,
|
||||
Currency: "EUR",
|
||||
},
|
||||
"driver": {
|
||||
Amount: 0.32 * float64(params.SharedMobility.DriverDistance),
|
||||
Currency: "EUR/2",
|
||||
Amount: driverAmount,
|
||||
Currency: "EUR",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
package pricing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMMS43Prices(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
params PricingParams
|
||||
expectedPrices map[string]Price
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "First trip - should be free for passenger",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 0, // First trip
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 10000, // 10km in meters
|
||||
DriverDistance: 15000, // 15km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for first trip
|
||||
"driver": {Amount: 4.5, Currency: "EUR"}, // 15km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Second trip - should be free for passenger",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 1, // Second trip
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 20000, // 20km in meters
|
||||
DriverDistance: 25000, // 25km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for second trip
|
||||
"driver": {Amount: 7.5, Currency: "EUR"}, // 25km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Third trip - passenger should pay",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 2, // Third trip
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 10000, // 10km in meters
|
||||
DriverDistance: 10000, // 10km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 1.5, Currency: "EUR"}, // 10km * 0.15€/km
|
||||
"driver": {Amount: 3.0, Currency: "EUR"}, // 10km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Multiple trips - passenger pays normal rate",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 5, // Multiple trips
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 30000, // 30km in meters
|
||||
DriverDistance: 35000, // 35km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 4.5, Currency: "EUR"}, // 30km * 0.15€/km
|
||||
"driver": {Amount: 10.5, Currency: "EUR"}, // 35km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Zero distance - should return zero amounts",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 3,
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 0,
|
||||
DriverDistance: 0,
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 0.0, Currency: "EUR"},
|
||||
"driver": {Amount: 0.0, Currency: "EUR"},
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Large distances - check calculation accuracy",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 10,
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 100000, // 100km in meters
|
||||
DriverDistance: 120000, // 120km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 15.0, Currency: "EUR"}, // 100km * 0.15€/km
|
||||
"driver": {Amount: 36.0, Currency: "EUR"}, // 120km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Edge case - exactly 2 trips history (3rd trip)",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 2, // Exactly at the limit
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 4000, // 4km in meters
|
||||
DriverDistance: 5000, // 5km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 0.6, Currency: "EUR"}, // 4km * 0.15€/km (first paid trip)
|
||||
"driver": {Amount: 1.5, Currency: "EUR"}, // 5km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "Small distances with fractions",
|
||||
params: PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 3,
|
||||
Priority: false,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 2000, // 2km in meters
|
||||
DriverDistance: 3000, // 3km in meters
|
||||
},
|
||||
},
|
||||
expectedPrices: map[string]Price{
|
||||
"passenger": {Amount: 0.3, Currency: "EUR"}, // 2km * 0.15€/km
|
||||
"driver": {Amount: 0.9, Currency: "EUR"}, // 3km * 0.30€/km
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
pricingService, err := NewMMS43PricingService()
|
||||
assert.NoError(t, err)
|
||||
|
||||
prices, err := pricingService.Prices(tc.params)
|
||||
if tc.expectedError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
// Use InDelta for floating-point comparisons to handle precision issues
|
||||
assert.InDelta(t, tc.expectedPrices["passenger"].Amount, prices["passenger"].Amount, 0.001)
|
||||
assert.Equal(t, tc.expectedPrices["passenger"].Currency, prices["passenger"].Currency)
|
||||
assert.InDelta(t, tc.expectedPrices["driver"].Amount, prices["driver"].Amount, 0.001)
|
||||
assert.Equal(t, tc.expectedPrices["driver"].Currency, prices["driver"].Currency)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMMS43PricingEdgeCases(t *testing.T) {
|
||||
pricingService, err := NewMMS43PricingService()
|
||||
assert.NoError(t, err)
|
||||
|
||||
t.Run("Negative history should still work", func(t *testing.T) {
|
||||
params := PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: -1, // Edge case: negative history
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 10000,
|
||||
DriverDistance: 10000,
|
||||
},
|
||||
}
|
||||
|
||||
prices, err := pricingService.Prices(params)
|
||||
assert.NoError(t, err)
|
||||
// Should still be free (2 - (-1) = 3 > 0)
|
||||
assert.InDelta(t, 0.0, prices["passenger"].Amount, 0.001)
|
||||
assert.InDelta(t, 3.0, prices["driver"].Amount, 0.001)
|
||||
})
|
||||
|
||||
t.Run("Very high history", func(t *testing.T) {
|
||||
params := PricingParams{
|
||||
Beneficiary: BeneficiaryParams{
|
||||
History: 100,
|
||||
},
|
||||
SharedMobility: SharedMobilityParams{
|
||||
PassengerDistance: 10000,
|
||||
DriverDistance: 10000,
|
||||
},
|
||||
}
|
||||
|
||||
prices, err := pricingService.Prices(params)
|
||||
assert.NoError(t, err)
|
||||
// Should charge normal rate
|
||||
assert.InDelta(t, 1.5, prices["passenger"].Amount, 0.001)
|
||||
assert.InDelta(t, 3.0, prices["driver"].Amount, 0.001)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue