|
| 1 | +package queries |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + "github.com/DIMO-Network/device-definitions-api/internal/core/mediator" |
| 8 | + "github.com/DIMO-Network/device-definitions-api/internal/infrastructure/db/models" |
| 9 | + "github.com/DIMO-Network/device-definitions-api/internal/infrastructure/exceptions" |
| 10 | + "github.com/DIMO-Network/device-definitions-api/internal/infrastructure/gateways" |
| 11 | + "github.com/DIMO-Network/shared/pkg/db" |
| 12 | + "github.com/DIMO-Network/shared/pkg/logfields" |
| 13 | + vinutils "github.com/DIMO-Network/shared/pkg/vin" |
| 14 | + "github.com/pkg/errors" |
| 15 | + "github.com/rs/zerolog" |
| 16 | + "github.com/volatiletech/null/v8" |
| 17 | + "github.com/volatiletech/sqlboiler/v4/boil" |
| 18 | +) |
| 19 | + |
| 20 | +type UpsertDecodingQueryHandler struct { |
| 21 | + dbs func() *db.ReaderWriter |
| 22 | + logger *zerolog.Logger |
| 23 | + deviceDefinitionOnChainService gateways.DeviceDefinitionOnChainService |
| 24 | +} |
| 25 | + |
| 26 | +type UpsertDecodingQuery struct { |
| 27 | + VIN string `json:"vin"` |
| 28 | + DefinitionID string `json:"definitionId"` |
| 29 | +} |
| 30 | + |
| 31 | +func (*UpsertDecodingQuery) Key() string { return "UpsertDecodingQuery" } |
| 32 | + |
| 33 | +func NewUpsertDecodingQueryHandler(dbs func() *db.ReaderWriter, |
| 34 | + logger *zerolog.Logger, |
| 35 | + deviceDefinitionOnChainService gateways.DeviceDefinitionOnChainService) UpsertDecodingQueryHandler { |
| 36 | + return UpsertDecodingQueryHandler{ |
| 37 | + dbs: dbs, |
| 38 | + logger: logger, |
| 39 | + deviceDefinitionOnChainService: deviceDefinitionOnChainService, |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +func (dc UpsertDecodingQueryHandler) Handle(ctx context.Context, query mediator.Message) (interface{}, error) { |
| 44 | + qry := query.(*UpsertDecodingQuery) |
| 45 | + if len(qry.VIN) < 10 || len(qry.VIN) > 17 { |
| 46 | + return nil, &exceptions.ValidationError{Err: fmt.Errorf("invalid vin %s", qry.VIN)} |
| 47 | + } |
| 48 | + vin := vinutils.VIN(qry.VIN) |
| 49 | + wmi := vin.Wmi() |
| 50 | + |
| 51 | + localLog := dc.logger.With(). |
| 52 | + Str("vin", vin.String()). |
| 53 | + Str("handler", query.Key()). |
| 54 | + Logger() |
| 55 | + |
| 56 | + // check if the definition id exists on chain |
| 57 | + dd, manuf, err := dc.deviceDefinitionOnChainService.GetDefinitionByID(ctx, qry.DefinitionID) |
| 58 | + if err != nil { |
| 59 | + return nil, errors.Wrapf(err, "failed to find device definition by id %s when upserting vin decoding", qry.DefinitionID) |
| 60 | + } |
| 61 | + manufacturerName, err := dc.deviceDefinitionOnChainService.GetManufacturerNameByID(ctx, manuf) |
| 62 | + if err != nil { |
| 63 | + return nil, errors.Wrapf(err, "failed to find manufacturer name by id %s when upserting vin decoding", manuf) |
| 64 | + } |
| 65 | + //upsert the vin |
| 66 | + vinNumber := &models.VinNumber{ |
| 67 | + Vin: qry.VIN, |
| 68 | + Wmi: null.StringFrom(wmi), |
| 69 | + VDS: null.StringFrom(vin.VDS()), |
| 70 | + CheckDigit: null.StringFrom(vin.CheckDigit()), |
| 71 | + SerialNumber: vin.SerialNumber(), |
| 72 | + Vis: null.StringFrom(vin.VIS()), |
| 73 | + DecodeProvider: null.StringFrom("manual entry"), |
| 74 | + Year: dd.Year, |
| 75 | + DefinitionID: dd.ID, |
| 76 | + ManufacturerName: manufacturerName, |
| 77 | + } |
| 78 | + err = vinNumber.Upsert(ctx, dc.dbs().Writer, true, []string{"vin"}, boil.Infer(), boil.Infer()) |
| 79 | + if err != nil { |
| 80 | + return nil, errors.Wrapf(err, "failed to upsert vin number %s for manual update", qry.VIN) |
| 81 | + } |
| 82 | + localLog.Info().Str(logfields.VIN, qry.VIN).Str(logfields.FunctionName, qry.Key()).Msg("manually upserted new vin number") |
| 83 | + return nil, nil |
| 84 | +} |
0 commit comments