commit 90abfe05b2140d7d5094706d68d93504ba93e3ef Author: Arnaud Delcasse Date: Fri May 23 09:44:40 2025 +0200 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..578e9e0 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# COOPGO Payments + +COOPGO Payments is the payments microservice for the COOPGO Technical Platform + + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5c1b544 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module git.coopgo.io/coopgo-platform/payments + +go 1.24.2 + +require ( + github.com/manterfield/go-mapreader v0.2.0 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..874e470 --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/manterfield/go-mapreader v0.2.0 h1:ZDJbja6bZCatRG725SDchdudqYnULyk04wSH58gvyqM= +github.com/manterfield/go-mapreader v0.2.0/go.mod h1:dYr8DHvSqfhrwTHBO1h8dLa9nUUnushqBYuWBns1Z0s= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= diff --git a/pricing/price.go b/pricing/price.go new file mode 100644 index 0000000..baa9816 --- /dev/null +++ b/pricing/price.go @@ -0,0 +1,6 @@ +package pricing + +type Price struct { + Amount float64 + Currency string +} diff --git a/pricing/pricing.go b/pricing/pricing.go new file mode 100644 index 0000000..52254b9 --- /dev/null +++ b/pricing/pricing.go @@ -0,0 +1,19 @@ +package pricing + +import "fmt" + +type PricingService interface { + Prices(vars map[string]any) (map[string]Price, error) +} + +func NewPricingService(implementation string) (PricingService, error) { + switch implementation { + case "mms43": + return NewMMS43PricingService() + case "pfm63": + return NewPFM63PricingService() + default: + return nil, fmt.Errorf("pricing implementation %v is not supported", implementation) + + } +} diff --git a/pricing/pricing_mms43.go b/pricing/pricing_mms43.go new file mode 100644 index 0000000..e4503be --- /dev/null +++ b/pricing/pricing_mms43.go @@ -0,0 +1,35 @@ +package pricing + +import ( + "fmt" + + "github.com/manterfield/go-mapreader" +) + +type MMS43PricingService struct{} + +func NewMMS43PricingService() (*MMS43PricingService, error) { + return &MMS43PricingService{}, nil +} + +func (s *MMS43PricingService) Prices(vars map[string]any) (map[string]Price, error) { + driver_distance, err := mapreader.IntErr(vars, "journey.driver_distance") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + passenger_distance, err := mapreader.IntErr(vars, "journey.passenger_distance") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + + return map[string]Price{ + "passenger": { + Amount: 0.32 * float64(passenger_distance), + Currency: "EUR/2", + }, + "driver": { + Amount: 0.32 * float64(driver_distance), + Currency: "EUR/2", + }, + }, nil +} diff --git a/pricing/pricing_pfm63.go b/pricing/pricing_pfm63.go new file mode 100644 index 0000000..99b4d44 --- /dev/null +++ b/pricing/pricing_pfm63.go @@ -0,0 +1,85 @@ +package pricing + +import ( + "fmt" + "slices" + + "github.com/manterfield/go-mapreader" +) + +type PFM63PricingService struct{} + +func NewPFM63PricingService() (*PFM63PricingService, error) { + return &PFM63PricingService{}, nil +} + +func (s *PFM63PricingService) Prices(vars map[string]any) (map[string]Price, error) { + journey_type, err := mapreader.StrErr(vars, "journet_type") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + passenger_priority, err := mapreader.BoolErr(vars, "passenger.priority") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + passenger_history, err := mapreader.IntErr(vars, "passenger.history") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + destination_postcode, err := mapreader.StrErr(vars, "journey.passenger_drop.properties.postcode") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + driver_distance, err := mapreader.IntErr(vars, "journey.driver_distance") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + passenger_distance, err := mapreader.IntErr(vars, "journey.passenger_distance") + if err != nil { + return nil, fmt.Errorf("parameter not found : %v", err) + } + + pricing := 0.0 + + if passenger_history == 0 { + pricing = 0 + } else if passenger_priority && passenger_distance <= 5 { + pricing = 0 + } else if slices.Contains([]string{"15300", "63000", "63100", "63200", "63015"}, destination_postcode) { + pricing = 5 + } else if passenger_distance < 15 { + pricing = 2 + } else if passenger_distance < 30 { + pricing = 4 + } else if passenger_distance < 45 { + pricing = 6 + } else if passenger_distance < 60 { + pricing = 7 + } else if passenger_distance < 75 { + pricing = 9 + } else if passenger_distance < 90 { + pricing = 10 + } else if passenger_distance < 105 { + pricing = 12 + } else if passenger_distance < 120 { + pricing = 15 + } else if passenger_distance < 140 { + pricing = 17 + } + + kmCompensation := 0.2 + if journey_type == "carpool" { + kmCompensation = 0.09 + } + + return map[string]Price{ + "passenger": { + Amount: pricing, + Currency: "EUR/2", + }, + "driver": { + Amount: kmCompensation * float64(driver_distance), + Currency: "EUR/2", + }, + }, nil +}