fix MMS43 pricing
This commit is contained in:
		
							parent
							
								
									e36cd6e557
								
							
						
					
					
						commit
						75d0288d2d
					
				| 
						 | 
				
			
			@ -7,6 +7,17 @@ func NewMMS43PricingService() (*MMS43PricingService, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (s *MMS43PricingService) Prices(params PricingParams) (map[string]Price, error) {
 | 
			
		||||
	// Determine which distance to use based on mobility type
 | 
			
		||||
	// For solidarity transport: use driver distance
 | 
			
		||||
	// For organized carpool: use passenger distance
 | 
			
		||||
	var distanceForPricing int64
 | 
			
		||||
	if params.MobilityType == "solidarity_transport" {
 | 
			
		||||
		distanceForPricing = params.SharedMobility.DriverDistance
 | 
			
		||||
	} else {
 | 
			
		||||
		// organized_carpool or default
 | 
			
		||||
		distanceForPricing = params.SharedMobility.PassengerDistance
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Calculate passenger price
 | 
			
		||||
	var passengerAmount float64
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,12 +27,12 @@ func (s *MMS43PricingService) Prices(params PricingParams) (map[string]Price, er
 | 
			
		|||
		// Trip is free
 | 
			
		||||
		passengerAmount = 0.0
 | 
			
		||||
	} else {
 | 
			
		||||
		// Price is 0.15€/km for passenger distance
 | 
			
		||||
		passengerAmount = 0.15 * float64(params.SharedMobility.PassengerDistance)
 | 
			
		||||
		// Price is 0.15€/km based on mobility type distance
 | 
			
		||||
		passengerAmount = 0.15 * float64(distanceForPricing)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Driver indemnification is always 0.30€/km for driver distance
 | 
			
		||||
	driverAmount := 0.30 * float64(params.SharedMobility.DriverDistance)
 | 
			
		||||
	// Driver indemnification is always 0.30€/km based on mobility type distance
 | 
			
		||||
	driverAmount := 0.30 * float64(distanceForPricing)
 | 
			
		||||
 | 
			
		||||
	return map[string]Price{
 | 
			
		||||
		"passenger": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,9 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
		expectedError  bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "First trip - should be free for passenger",
 | 
			
		||||
			name: "Solidarity transport - First trip - should be free for passenger",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  0, // First trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,13 +28,33 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for first trip
 | 
			
		||||
				"driver":    {Amount: 4.5, Currency: "EUR"}, // 15km * 0.30€/km
 | 
			
		||||
				"driver":    {Amount: 4.5, Currency: "EUR"}, // 15km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Second trip - should be free for passenger",
 | 
			
		||||
			name: "Organized carpool - First trip - should be free for passenger",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "organized_carpool",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  0, // First trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 10, // 10km in meters
 | 
			
		||||
					DriverDistance:    15, // 15km in meters
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for first trip
 | 
			
		||||
				"driver":    {Amount: 3.0, Currency: "EUR"}, // 10km * 0.30€/km (passenger distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Solidarity transport - Second trip - should be free for passenger",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  1, // Second trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -45,31 +66,71 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for second trip
 | 
			
		||||
				"driver":    {Amount: 7.5, Currency: "EUR"}, // 25km * 0.30€/km
 | 
			
		||||
				"driver":    {Amount: 7.5, Currency: "EUR"}, // 25km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Third trip - passenger should pay",
 | 
			
		||||
			name: "Organized carpool - Second trip - should be free for passenger",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "organized_carpool",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  1, // Second trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 20, // 20km in meters
 | 
			
		||||
					DriverDistance:    25, // 25km in meters
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 0.0, Currency: "EUR"}, // Free for second trip
 | 
			
		||||
				"driver":    {Amount: 6.0, Currency: "EUR"}, // 20km * 0.30€/km (passenger distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Solidarity transport - Third trip - passenger should pay",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  2, // Third trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 10, // 10km in meters
 | 
			
		||||
					DriverDistance:    10, // 10km in meters
 | 
			
		||||
					DriverDistance:    12, // 12km 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
 | 
			
		||||
				"passenger": {Amount: 1.8, Currency: "EUR"}, // 12km * 0.15€/km (driver distance)
 | 
			
		||||
				"driver":    {Amount: 3.6, Currency: "EUR"}, // 12km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Multiple trips - passenger pays normal rate",
 | 
			
		||||
			name: "Organized carpool - Third trip - passenger should pay",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "organized_carpool",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  2, // Third trip
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 10, // 10km in meters
 | 
			
		||||
					DriverDistance:    12, // 12km in meters
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 1.5, Currency: "EUR"}, // 10km * 0.15€/km (passenger distance)
 | 
			
		||||
				"driver":    {Amount: 3.0, Currency: "EUR"}, // 10km * 0.30€/km (passenger distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Solidarity transport - Multiple trips - passenger pays normal rate",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  5, // Multiple trips
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -80,14 +141,34 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 4.5, Currency: "EUR"},  // 30km * 0.15€/km
 | 
			
		||||
				"driver":    {Amount: 10.5, Currency: "EUR"}, // 35km * 0.30€/km
 | 
			
		||||
				"passenger": {Amount: 5.25, Currency: "EUR"}, // 35km * 0.15€/km (driver distance)
 | 
			
		||||
				"driver":    {Amount: 10.5, Currency: "EUR"}, // 35km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Zero distance - should return zero amounts",
 | 
			
		||||
			name: "Organized carpool - Multiple trips - passenger pays normal rate",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "organized_carpool",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  5, // Multiple trips
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 30, // 30km in meters
 | 
			
		||||
					DriverDistance:    35, // 35km in meters
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 4.5, Currency: "EUR"}, // 30km * 0.15€/km (passenger distance)
 | 
			
		||||
				"driver":    {Amount: 9.0, Currency: "EUR"}, // 30km * 0.30€/km (passenger distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Solidarity transport - Zero distance - should return zero amounts",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  3,
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -104,8 +185,9 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Large distances - check calculation accuracy",
 | 
			
		||||
			name: "Solidarity transport - Large distances - check calculation accuracy",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  10,
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -116,14 +198,34 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 15.0, Currency: "EUR"}, // 100km * 0.15€/km
 | 
			
		||||
				"driver":    {Amount: 36.0, Currency: "EUR"}, // 120km * 0.30€/km
 | 
			
		||||
				"passenger": {Amount: 18.0, Currency: "EUR"}, // 120km * 0.15€/km (driver distance)
 | 
			
		||||
				"driver":    {Amount: 36.0, Currency: "EUR"}, // 120km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Edge case - exactly 2 trips history (3rd trip)",
 | 
			
		||||
			name: "Organized carpool - Large distances - check calculation accuracy",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "organized_carpool",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  10,
 | 
			
		||||
					Priority: false,
 | 
			
		||||
				},
 | 
			
		||||
				SharedMobility: SharedMobilityParams{
 | 
			
		||||
					PassengerDistance: 100, // 100km in meters
 | 
			
		||||
					DriverDistance:    120, // 120km in meters
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 15.0, Currency: "EUR"}, // 100km * 0.15€/km (passenger distance)
 | 
			
		||||
				"driver":    {Amount: 30.0, Currency: "EUR"}, // 100km * 0.30€/km (passenger distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Solidarity transport - Edge case - exactly 2 trips history (3rd trip)",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  2, // Exactly at the limit
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -134,14 +236,15 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
				},
 | 
			
		||||
			},
 | 
			
		||||
			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
 | 
			
		||||
				"passenger": {Amount: 0.75, Currency: "EUR"}, // 5km * 0.15€/km (first paid trip, driver distance)
 | 
			
		||||
				"driver":    {Amount: 1.5, Currency: "EUR"},  // 5km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Small distances with fractions",
 | 
			
		||||
			name: "Solidarity transport - Small distances with fractions",
 | 
			
		||||
			params: PricingParams{
 | 
			
		||||
				MobilityType: "solidarity_transport",
 | 
			
		||||
				Beneficiary: BeneficiaryParams{
 | 
			
		||||
					History:  3,
 | 
			
		||||
					Priority: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -152,8 +255,8 @@ func TestMMS43Prices(t *testing.T) {
 | 
			
		|||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expectedPrices: map[string]Price{
 | 
			
		||||
				"passenger": {Amount: 0.3, Currency: "EUR"}, // 2km * 0.15€/km
 | 
			
		||||
				"driver":    {Amount: 0.9, Currency: "EUR"}, // 3km * 0.30€/km
 | 
			
		||||
				"passenger": {Amount: 0.45, Currency: "EUR"}, // 3km * 0.15€/km (driver distance)
 | 
			
		||||
				"driver":    {Amount: 0.9, Currency: "EUR"},  // 3km * 0.30€/km (driver distance)
 | 
			
		||||
			},
 | 
			
		||||
			expectedError: false,
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -183,8 +286,9 @@ func TestMMS43PricingEdgeCases(t *testing.T) {
 | 
			
		|||
	pricingService, err := NewMMS43PricingService()
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
	t.Run("Negative history should still work", func(t *testing.T) {
 | 
			
		||||
	t.Run("Solidarity transport - Negative history should still work", func(t *testing.T) {
 | 
			
		||||
		params := PricingParams{
 | 
			
		||||
			MobilityType: "solidarity_transport",
 | 
			
		||||
			Beneficiary: BeneficiaryParams{
 | 
			
		||||
				History: -1, // Edge case: negative history
 | 
			
		||||
			},
 | 
			
		||||
| 
						 | 
				
			
			@ -201,8 +305,28 @@ func TestMMS43PricingEdgeCases(t *testing.T) {
 | 
			
		|||
		assert.InDelta(t, 3.0, prices["driver"].Amount, 0.001)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Very high history", func(t *testing.T) {
 | 
			
		||||
	t.Run("Organized carpool - Negative history should still work", func(t *testing.T) {
 | 
			
		||||
		params := PricingParams{
 | 
			
		||||
			MobilityType: "organized_carpool",
 | 
			
		||||
			Beneficiary: BeneficiaryParams{
 | 
			
		||||
				History: -1, // Edge case: negative history
 | 
			
		||||
			},
 | 
			
		||||
			SharedMobility: SharedMobilityParams{
 | 
			
		||||
				PassengerDistance: 10,
 | 
			
		||||
				DriverDistance:    12,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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) // Uses passenger distance
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Solidarity transport - Very high history", func(t *testing.T) {
 | 
			
		||||
		params := PricingParams{
 | 
			
		||||
			MobilityType: "solidarity_transport",
 | 
			
		||||
			Beneficiary: BeneficiaryParams{
 | 
			
		||||
				History: 100,
 | 
			
		||||
			},
 | 
			
		||||
| 
						 | 
				
			
			@ -218,5 +342,24 @@ func TestMMS43PricingEdgeCases(t *testing.T) {
 | 
			
		|||
		assert.InDelta(t, 1.5, prices["passenger"].Amount, 0.001)
 | 
			
		||||
		assert.InDelta(t, 3.0, prices["driver"].Amount, 0.001)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	t.Run("Organized carpool - Very high history", func(t *testing.T) {
 | 
			
		||||
		params := PricingParams{
 | 
			
		||||
			MobilityType: "organized_carpool",
 | 
			
		||||
			Beneficiary: BeneficiaryParams{
 | 
			
		||||
				History: 100,
 | 
			
		||||
			},
 | 
			
		||||
			SharedMobility: SharedMobilityParams{
 | 
			
		||||
				PassengerDistance: 10,
 | 
			
		||||
				DriverDistance:    12,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		prices, err := pricingService.Prices(params)
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
		// Should charge normal rate based on passenger distance
 | 
			
		||||
		assert.InDelta(t, 1.5, prices["passenger"].Amount, 0.001) // 10km * 0.15
 | 
			
		||||
		assert.InDelta(t, 3.0, prices["driver"].Amount, 0.001)    // 10km * 0.30
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue