diff --git a/go.mod b/go.mod index 5c1b544..9b56eb2 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,18 @@ module git.coopgo.io/coopgo-platform/payments go 1.24.2 require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/manterfield/go-mapreader v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/paulmach/orb v0.11.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect + github.com/stretchr/testify v1.10.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 + go.mongodb.org/mongo-driver v1.11.4 // indirect + golang.org/x/sys v0.12.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 874e470..7c3b827 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,97 @@ +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/manterfield/go-mapreader v0.2.0 h1:ZDJbja6bZCatRG725SDchdudqYnULyk04wSH58gvyqM= github.com/manterfield/go-mapreader v0.2.0/go.mod h1:dYr8DHvSqfhrwTHBO1h8dLa9nUUnushqBYuWBns1Z0s= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= +github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= +github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizXas= +go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pricing/pricing.go b/pricing/pricing.go index 52254b9..3641d98 100644 --- a/pricing/pricing.go +++ b/pricing/pricing.go @@ -1,9 +1,13 @@ package pricing -import "fmt" +import ( + "fmt" + + "github.com/paulmach/orb/geojson" +) type PricingService interface { - Prices(vars map[string]any) (map[string]Price, error) + Prices(params PricingParams) (map[string]Price, error) } func NewPricingService(implementation string) (PricingService, error) { @@ -17,3 +21,32 @@ func NewPricingService(implementation string) (PricingService, error) { } } + +type PricingParams struct { + MobilityType string + SharedMobility SharedMobilityParams + Beneficiary BeneficiaryParams + Data map[string]any // other data (specific) +} + +type SharedMobilityParams struct { + DriverDistance int64 + PassengerDistance int64 + Departure GeographyParams + Destination GeographyParams + OutwardOnly bool +} + +type BeneficiaryParams struct { + Address GeographyParams + Priority bool + History int +} + +type GeographyParams struct { + Location *geojson.Feature + CityCode string // INSEE code + IntercommunalityCode string // SIRENnumber + RegionCode string + DepartmentCode string +} diff --git a/pricing/pricing_mms43.go b/pricing/pricing_mms43.go index e4503be..fd9e67b 100644 --- a/pricing/pricing_mms43.go +++ b/pricing/pricing_mms43.go @@ -1,34 +1,19 @@ 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) - } - +func (s *MMS43PricingService) Prices(params PricingParams) (map[string]Price, error) { return map[string]Price{ "passenger": { - Amount: 0.32 * float64(passenger_distance), + Amount: 0.32 * float64(params.SharedMobility.PassengerDistance), Currency: "EUR/2", }, "driver": { - Amount: 0.32 * float64(driver_distance), + Amount: 0.32 * float64(params.SharedMobility.DriverDistance), Currency: "EUR/2", }, }, nil diff --git a/pricing/pricing_pfm63.go b/pricing/pricing_pfm63.go index 3f8edf2..3369245 100644 --- a/pricing/pricing_pfm63.go +++ b/pricing/pricing_pfm63.go @@ -1,66 +1,54 @@ package pricing import ( - "fmt" "slices" - "github.com/manterfield/go-mapreader" "github.com/rs/zerolog/log" ) +const ( + PFM63_CC_CHAVAILLON_COMBAILLES_VOLCANS = "200071215" + PFM63_CC_DOMES_SANCY_ARTENSE = "200069169" + PFM63_CC_AMBERT_LIVRADOIS_FOREZ = "200070761" + PFM63_COM_CLERMONT = "63113" + PFM63_COM_USSEL = "19275" + PFM63_COM_AUBUSSON = "23008" + PFM63_COM_RIOM = "63300" +) + 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, "journey_type") - if err != nil { - return nil, fmt.Errorf("journey_type parameter not found : %v", err) - } - fmt.Println(journey_type) - passenger_priority, err := mapreader.BoolErr(vars, "passenger.priority") - if err != nil { - return nil, fmt.Errorf("passenger_priority parameter not found : %v", err) - } - ret, err := mapreader.BoolErr(vars, "return") - if err != nil { - return nil, fmt.Errorf("passenger_priority parameter not found : %v", err) - } - passenger_history, err := mapreader.IntErr(vars, "passenger.history") - if err != nil { - return nil, fmt.Errorf("passenger_history parameter not found : %v", err) - } - destination_locality, err := mapreader.StrErr(vars, "journey.passenger_drop.properties.locality") - if err != nil { - return nil, fmt.Errorf("destination_locality parameter not found : %v", err) - } - // passenger_locality, err := mapreader.StrErr(vars, "passenger.locality") - // if err != nil { - // return nil, fmt.Errorf("destination_locality parameter not found : %v", err) - // } - driver_distance, err := mapreader.IntErr(vars, "journey.driver_distance") - if err != nil { - return nil, fmt.Errorf("driver_distance parameter not found : %v", err) - } - passenger_distance, err := mapreader.IntErr(vars, "journey.passenger_distance") - if err != nil { - return nil, fmt.Errorf("passenger_distance parameter not found : %v", err) +func (s *PFM63PricingService) Prices(params PricingParams) (map[string]Price, error) { + log.Debug().Any("params", params).Msg("get price") + free_trips := 0 + fixedCityPrices := []string{} + + switch params.Beneficiary.Address.IntercommunalityCode { + case PFM63_CC_CHAVAILLON_COMBAILLES_VOLCANS: + fixedCityPrices = []string{PFM63_COM_CLERMONT, PFM63_COM_AUBUSSON, PFM63_COM_RIOM, PFM63_COM_USSEL} + case PFM63_CC_DOMES_SANCY_ARTENSE: + fixedCityPrices = []string{PFM63_COM_CLERMONT, PFM63_COM_USSEL} + case PFM63_CC_AMBERT_LIVRADOIS_FOREZ: + free_trips = 1 } + passenger_distance := params.SharedMobility.PassengerDistance + pricing := 0.0 - log.Debug().Str("destination loc", destination_locality).Msg("debuf pricing") - if passenger_history == 0 { + if params.Beneficiary.History < free_trips { pricing = 0 - } else if passenger_priority && passenger_distance <= 5 { + } else if params.Beneficiary.Priority && params.Beneficiary.History <= 5 { pricing = 0 - } else if slices.Contains([]string{"Clermont-Ferrand", "Ussel", "Aubusson", "Riom"}, destination_locality) { - if ret { - pricing = 10 - } else { + } else if slices.Contains(fixedCityPrices, params.SharedMobility.Destination.CityCode) { + if params.SharedMobility.OutwardOnly { pricing = 5 + } else { + pricing = 10 } } else if passenger_distance < 15 { pricing = 2 @@ -80,12 +68,13 @@ func (s *PFM63PricingService) Prices(vars map[string]any) (map[string]Price, err pricing = 15 } else if passenger_distance < 140 { pricing = 17 + } else { + pricing = 17 + log.Error().Msg("no pricing case found") } - fmt.Println(pricing) - - kmCompensation := 0.2 - if journey_type == "carpool" { + kmCompensation := 0.22 + if params.MobilityType == "carpool" { kmCompensation = 0.09 } @@ -95,7 +84,7 @@ func (s *PFM63PricingService) Prices(vars map[string]any) (map[string]Price, err Currency: "EUR/2", }, "driver": { - Amount: kmCompensation * float64(driver_distance), + Amount: kmCompensation * float64(params.SharedMobility.DriverDistance), Currency: "EUR/2", }, }, nil diff --git a/pricing/pricing_pfm63_test.go b/pricing/pricing_pfm63_test.go new file mode 100644 index 0000000..d3ef3c3 --- /dev/null +++ b/pricing/pricing_pfm63_test.go @@ -0,0 +1,248 @@ +package pricing + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPrices(t *testing.T) { + testCases := []struct { + name string + params PricingParams + expectedPrices map[string]Price + expectedError bool + }{ + { + name: "Chavallon Combailes Volcans, Clermont destination, outward only", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: PFM63_CC_CHAVAILLON_COMBAILLES_VOLCANS, + }, + History: 0, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: PFM63_COM_CLERMONT}, + OutwardOnly: true, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 5, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Chavallon Combailes Volcans, Aubusson destination, outward only", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: PFM63_CC_CHAVAILLON_COMBAILLES_VOLCANS, + }, + History: 0, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: PFM63_COM_AUBUSSON}, + OutwardOnly: true, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 5, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Domes Sancy Artense, Ussel destination, round trip", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: PFM63_CC_DOMES_SANCY_ARTENSE, + }, + History: 0, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: PFM63_COM_USSEL}, + OutwardOnly: false, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 10, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Ambert Livradois Artense, Clermont destination, round trip", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: PFM63_CC_AMBERT_LIVRADOIS_FOREZ, + }, + History: 10, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 150, + Destination: GeographyParams{CityCode: PFM63_COM_CLERMONT}, + OutwardOnly: true, + DriverDistance: 200, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 17, Currency: "EUR/2"}, + "driver": {Amount: 44, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Ambert Livradois Forez, free trip", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: PFM63_CC_AMBERT_LIVRADOIS_FOREZ, + }, + History: 0, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: "63113"}, + OutwardOnly: true, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 0, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Priority beneficiary, history <= 5", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: "unknown", + }, + History: 3, + Priority: true, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: "63113"}, + OutwardOnly: true, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 0, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Passenger distance < 15", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: "unknown", + }, + History: 6, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 10, + Destination: GeographyParams{CityCode: "63113"}, + OutwardOnly: true, + DriverDistance: 10, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 2, Currency: "EUR/2"}, + "driver": {Amount: 2.2, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Passenger distance < 30", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: "unknown", + }, + History: 6, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 20, + Destination: GeographyParams{CityCode: "63113"}, + OutwardOnly: true, + DriverDistance: 20, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 4, Currency: "EUR/2"}, + "driver": {Amount: 4.4, Currency: "EUR/2"}, + }, + expectedError: false, + }, + { + name: "Passenger distance > 140", + params: PricingParams{ + Beneficiary: BeneficiaryParams{ + Address: GeographyParams{ + IntercommunalityCode: "unknown", + }, + History: 6, + Priority: false, + }, + SharedMobility: SharedMobilityParams{ + PassengerDistance: 150, + Destination: GeographyParams{CityCode: "63113"}, + OutwardOnly: true, + DriverDistance: 200, + }, + MobilityType: "solidarity_transport", + }, + expectedPrices: map[string]Price{ + "passenger": {Amount: 17, Currency: "EUR/2"}, + "driver": {Amount: 44.0, Currency: "EUR/2"}, + }, + expectedError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + pricingService, err := NewPFM63PricingService() + assert.NoError(t, err) + + prices, err := pricingService.Prices(tc.params) + if tc.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expectedPrices, prices) + } + }) + } +}