package handlers import ( "context" "encoding/json" "fmt" "strings" "github.com/fiskerinc/cloud-services/services/attendant/services" "github.com/fiskerinc/cloud-services/pkg/common" "github.com/fiskerinc/cloud-services/pkg/grpc/sms" "github.com/fiskerinc/cloud-services/pkg/logger" "github.com/fiskerinc/cloud-services/pkg/manifestsender" "github.com/fiskerinc/cloud-services/pkg/tmobile" "github.com/fiskerinc/cloud-services/pkg/utils/envtool" ) var ENABLE_ORDERUPDATE_SENDS = envtool.GetEnvBool("ENABLE_ORDERUPDATE_SENDS", false) // Take the feature codes from VehicleOrder message to generate the VOD and CDSs // Create a new common.UpdateManifest with the VOD and CDS and save it as a common.ConfigUpdateType // Create a new common.CarUpdate for the VIN and the manifest in step 2 and save it to the database // Copy the car update id into the UpdateManifest // Send the UpdateManifest to both trex and hmi func OrderUpdated(db *services.DB, smsClient sms.SMSServiceClient, vin string, data []byte) error { logger.Debug().Msgf("Order updated %s", vin) var order common.VehicleOrder err := json.Unmarshal(data, &order) if err != nil { return err } err = setCarSettings(db, vin, order) if err != nil { return err } err = changeRatePlan(db, smsClient, vin, order.VehicleSpecification.DestinationCountry) if err != nil { logger.Error().Msgf("Failed to change rate plan for %s, %s", vin, err) } if !ENABLE_ORDERUPDATE_SENDS { return nil } cs := services.GetVehicleConfig() r := services.RedisClientPool().GetFromPool() defer r.Close() trex := manifestsender.NewTBOXManifestSender(r, cs, services.GetDB(), nil, nil) defer trex.Close() // I don't think this has ever been called on production, or dev ! input := manifestsender.ProcessConfigUpdateStruct{ VIN: vin, Name: "SAP order change update", Username: "unidentified attendant sap user", SendToCar: true, DontCreateDatabaseEntry: false, Forced: false, } _, err = trex.ProcessConfigUpdate(input, services.GetDB().GetCarConfigData()) return err } func setCarSettings(db *services.DB, vin string, order common.VehicleOrder) (err error) { // If the sequence number is missing, go will fill it in as 0, which is the case where the car has no sequence number if order.VehicleSpecification.SequenceNumber != "" { _, err = db.GetCars().SetSetting(&common.CarSetting{ VIN: vin, Name: common.SEQUENCE_NUMBER, Value: fmt.Sprint(order.VehicleSpecification.SequenceNumber), Type: "string", }) if err != nil { return err } } _, err = db.GetCars().SetSetting(&common.CarSetting{ VIN: vin, Name: common.BODY_COLOR, Value: common.FeatureCodeToBodyColor(order.VehicleSpecification.VehicleFeatures), Type: "string", }) if err != nil { return err } // Incase SAP hasn't sent this value yet if order.VehicleSpecification.DestinationCountry != "" { _, err = db.GetCars().SetSetting(&common.CarSetting{ VIN: vin, Name: common.DELIVERY_DESTINATION, Value: order.VehicleSpecification.DestinationCountry, Type: "string", }) if err != nil { return err } } return } func changeRatePlan(db *services.DB, smsClient sms.SMSServiceClient, vin, destinationCountry string) error { car, err := services.GetDB().GetCars().SelectByVIN(vin) if err != nil { return err } if len(car.ICCID) == 0 { return fmt.Errorf("no iccid found for vehicle %s", vin) } iccid := strings.TrimSuffix(strings.ToLower(car.ICCID), "f") customAtributeReq := sms.CustomAtributesRequest{ ICCID: iccid, AccountCustom1: destinationCountry, } _, err = smsClient.HandleCustomAttributes(context.Background(), &customAtributeReq) if err != nil { return err } ratePlan, err := db.GetRatePlan().Select(destinationCountry) if err != nil { return err } changeRatePlanRequest := sms.ChangeRatePlanRequest{ ICCID: iccid, ProductId: ratePlan.ProductID, AccountId: tmobile.FISKER_TMOBILE_ACCOUNT_ID, } _, err = smsClient.HandleChangeRatePlan(context.Background(), &changeRatePlanRequest) if err != nil { return err } go verifyRatePlan(smsClient, iccid, destinationCountry) return nil } func verifyRatePlan(smsClient sms.SMSServiceClient, iccid, destinationCountry string) error { deviceDetailsRequest := sms.DeviceDetailsRequest{ ICCID: iccid, } details, err := smsClient.HandleDeviceDetails(context.Background(), &deviceDetailsRequest) if err != nil { logger.Error().Msgf("failed to check device details for iccid %s", iccid) } logger.Info().Msgf("device details for iccid %s: %+v", iccid, details) return nil }