From d6ce717c7583795ac3951c115dd7b76ab443f9f4 Mon Sep 17 00:00:00 2001 From: Arnaud Delcasse Date: Thu, 26 Feb 2026 17:54:02 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20ajout=20manual=5Fstatus=20et=20status?= =?UTF-8?q?=5Fhistory=20aux=20r=C3=A9servations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.go | 18 +++-- grpcapi/bookings.go | 28 +++++++ grpcapi/vehicles.pb.go | 170 ++++++++++++++++++++++++++++++++++++----- grpcapi/vehicles.proto | 14 ++++ storage/bookings.go | 14 ++++ 5 files changed, 217 insertions(+), 27 deletions(-) diff --git a/config.go b/config.go index 9618595..0ffd229 100644 --- a/config.go +++ b/config.go @@ -11,14 +11,16 @@ func ReadConfig() (*viper.Viper, error) { "name": "COOPGO Fleets", "dev_env": false, "storage": map[string]any{ - "type": "mongodb", - "mongodb": map[string]any{ - "host": "localhost", - "port": "27017", - "db_name": "coopgo_platform", - "collections": map[string]any{ - "vehicles": "fleet_vehicles", - "bookings": "fleet_bookings", + "db": map[string]any{ + "type": "mongodb", + "mongodb": map[string]any{ + "host": "localhost", + "port": "27017", + "db_name": "coopgo_platform", + "collections": map[string]any{ + "vehicles": "vehicles", + "bookings": "bookings", + }, }, }, }, diff --git a/grpcapi/bookings.go b/grpcapi/bookings.go index 879b912..76431e1 100644 --- a/grpcapi/bookings.go +++ b/grpcapi/bookings.go @@ -21,6 +21,7 @@ func (v Booking) ToStorageType() storage.Booking { Unavailableto: v.Unavailableto.AsTime(), Data: map[string]any{}, Deleted: v.Deleted, + ManualStatus: v.ManualStatus, } for k, d := range v.Data.GetFields() { @@ -38,6 +39,19 @@ func (v Booking) ToStorageType() storage.Booking { booking.Vehicle = v.Vehicle.ToStorageType() } + for _, entry := range v.StatusHistory { + booking.StatusHistory = append(booking.StatusHistory, storage.StatusHistoryEntry{ + FromStatus: entry.FromStatus, + ToStatus: entry.ToStatus, + UserID: entry.UserId, + UserName: entry.UserName, + GroupID: entry.GroupId, + GroupName: entry.GroupName, + Date: entry.Date.AsTime(), + Comment: entry.Comment, + }) + } + return booking } @@ -63,6 +77,20 @@ func BookingFromStorageType(booking *storage.Booking) (*Booking, error) { Unavailableto: timestamppb.New(booking.Unavailableto), Data: data, Deleted: booking.Deleted, + ManualStatus: booking.ManualStatus, + } + + for _, entry := range booking.StatusHistory { + result.StatusHistory = append(result.StatusHistory, &StatusHistoryEntry{ + FromStatus: entry.FromStatus, + ToStatus: entry.ToStatus, + UserId: entry.UserID, + UserName: entry.UserName, + GroupId: entry.GroupID, + GroupName: entry.GroupName, + Date: timestamppb.New(entry.Date), + Comment: entry.Comment, + }) } result.Vehicle, err = VehicleFromStorageType(&booking.Vehicle) diff --git a/grpcapi/vehicles.pb.go b/grpcapi/vehicles.pb.go index 03d3de7..007da9e 100644 --- a/grpcapi/vehicles.pb.go +++ b/grpcapi/vehicles.pb.go @@ -119,6 +119,8 @@ type Booking struct { Data *structpb.Struct `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"` Vehicle *Vehicle `protobuf:"bytes,9,opt,name=vehicle,proto3" json:"vehicle,omitempty"` Deleted bool `protobuf:"varint,10,opt,name=deleted,proto3" json:"deleted,omitempty"` + ManualStatus string `protobuf:"bytes,11,opt,name=manual_status,json=manualStatus,proto3" json:"manual_status,omitempty"` + StatusHistory []*StatusHistoryEntry `protobuf:"bytes,12,rep,name=status_history,json=statusHistory,proto3" json:"status_history,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -223,6 +225,120 @@ func (x *Booking) GetDeleted() bool { return false } +func (x *Booking) GetManualStatus() string { + if x != nil { + return x.ManualStatus + } + return "" +} + +func (x *Booking) GetStatusHistory() []*StatusHistoryEntry { + if x != nil { + return x.StatusHistory + } + return nil +} + +type StatusHistoryEntry struct { + state protoimpl.MessageState `protogen:"open.v1"` + FromStatus string `protobuf:"bytes,1,opt,name=from_status,json=fromStatus,proto3" json:"from_status,omitempty"` + ToStatus string `protobuf:"bytes,2,opt,name=to_status,json=toStatus,proto3" json:"to_status,omitempty"` + UserId string `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"` + GroupId string `protobuf:"bytes,5,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + GroupName string `protobuf:"bytes,6,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty"` + Date *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=date,proto3" json:"date,omitempty"` + Comment string `protobuf:"bytes,8,opt,name=comment,proto3" json:"comment,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusHistoryEntry) Reset() { + *x = StatusHistoryEntry{} + mi := &file_vehicles_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StatusHistoryEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusHistoryEntry) ProtoMessage() {} + +func (x *StatusHistoryEntry) ProtoReflect() protoreflect.Message { + mi := &file_vehicles_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusHistoryEntry.ProtoReflect.Descriptor instead. +func (*StatusHistoryEntry) Descriptor() ([]byte, []int) { + return file_vehicles_proto_rawDescGZIP(), []int{2} +} + +func (x *StatusHistoryEntry) GetFromStatus() string { + if x != nil { + return x.FromStatus + } + return "" +} + +func (x *StatusHistoryEntry) GetToStatus() string { + if x != nil { + return x.ToStatus + } + return "" +} + +func (x *StatusHistoryEntry) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *StatusHistoryEntry) GetUserName() string { + if x != nil { + return x.UserName + } + return "" +} + +func (x *StatusHistoryEntry) GetGroupId() string { + if x != nil { + return x.GroupId + } + return "" +} + +func (x *StatusHistoryEntry) GetGroupName() string { + if x != nil { + return x.GroupName + } + return "" +} + +func (x *StatusHistoryEntry) GetDate() *timestamppb.Timestamp { + if x != nil { + return x.Date + } + return nil +} + +func (x *StatusHistoryEntry) GetComment() string { + if x != nil { + return x.Comment + } + return "" +} + var File_vehicles_proto protoreflect.FileDescriptor const file_vehicles_proto_rawDesc = "" + @@ -234,7 +350,7 @@ const file_vehicles_proto_rawDesc = "" + "\x04type\x18\x03 \x01(\tR\x04type\x12&\n" + "\x0eadministrators\x18\x04 \x03(\tR\x0eadministrators\x12+\n" + "\x04data\x18\x05 \x01(\v2\x17.google.protobuf.StructR\x04data\x12$\n" + - "\bbookings\x18\x06 \x03(\v2\b.BookingR\bbookings\"\xb2\x03\n" + + "\bbookings\x18\x06 \x03(\v2\b.BookingR\bbookings\"\x93\x04\n" + "\aBooking\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1c\n" + "\tvehicleid\x18\x02 \x01(\tR\tvehicleid\x12\x16\n" + @@ -246,7 +362,20 @@ const file_vehicles_proto_rawDesc = "" + "\x04data\x18\b \x01(\v2\x17.google.protobuf.StructR\x04data\x12\"\n" + "\avehicle\x18\t \x01(\v2\b.VehicleR\avehicle\x12\x18\n" + "\adeleted\x18\n" + - " \x01(\bR\adeletedB.Z,git.coopgo.io/coopgo-platform/fleets/grpcapib\x06proto3" + " \x01(\bR\adeleted\x12#\n" + + "\rmanual_status\x18\v \x01(\tR\fmanualStatus\x12:\n" + + "\x0estatus_history\x18\f \x03(\v2\x13.StatusHistoryEntryR\rstatusHistory\"\x8c\x02\n" + + "\x12StatusHistoryEntry\x12\x1f\n" + + "\vfrom_status\x18\x01 \x01(\tR\n" + + "fromStatus\x12\x1b\n" + + "\tto_status\x18\x02 \x01(\tR\btoStatus\x12\x17\n" + + "\auser_id\x18\x03 \x01(\tR\x06userId\x12\x1b\n" + + "\tuser_name\x18\x04 \x01(\tR\buserName\x12\x19\n" + + "\bgroup_id\x18\x05 \x01(\tR\agroupId\x12\x1d\n" + + "\n" + + "group_name\x18\x06 \x01(\tR\tgroupName\x12.\n" + + "\x04date\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\x04date\x12\x18\n" + + "\acomment\x18\b \x01(\tR\acommentB.Z,git.coopgo.io/coopgo-platform/fleets/grpcapib\x06proto3" var ( file_vehicles_proto_rawDescOnce sync.Once @@ -260,27 +389,30 @@ func file_vehicles_proto_rawDescGZIP() []byte { return file_vehicles_proto_rawDescData } -var file_vehicles_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_vehicles_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_vehicles_proto_goTypes = []any{ (*Vehicle)(nil), // 0: Vehicle (*Booking)(nil), // 1: Booking - (*structpb.Struct)(nil), // 2: google.protobuf.Struct - (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp + (*StatusHistoryEntry)(nil), // 2: StatusHistoryEntry + (*structpb.Struct)(nil), // 3: google.protobuf.Struct + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp } var file_vehicles_proto_depIdxs = []int32{ - 2, // 0: Vehicle.data:type_name -> google.protobuf.Struct - 1, // 1: Vehicle.bookings:type_name -> Booking - 3, // 2: Booking.startdate:type_name -> google.protobuf.Timestamp - 3, // 3: Booking.enddate:type_name -> google.protobuf.Timestamp - 3, // 4: Booking.unavailablefrom:type_name -> google.protobuf.Timestamp - 3, // 5: Booking.unavailableto:type_name -> google.protobuf.Timestamp - 2, // 6: Booking.data:type_name -> google.protobuf.Struct - 0, // 7: Booking.vehicle:type_name -> Vehicle - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 3, // 0: Vehicle.data:type_name -> google.protobuf.Struct + 1, // 1: Vehicle.bookings:type_name -> Booking + 4, // 2: Booking.startdate:type_name -> google.protobuf.Timestamp + 4, // 3: Booking.enddate:type_name -> google.protobuf.Timestamp + 4, // 4: Booking.unavailablefrom:type_name -> google.protobuf.Timestamp + 4, // 5: Booking.unavailableto:type_name -> google.protobuf.Timestamp + 3, // 6: Booking.data:type_name -> google.protobuf.Struct + 0, // 7: Booking.vehicle:type_name -> Vehicle + 2, // 8: Booking.status_history:type_name -> StatusHistoryEntry + 4, // 9: StatusHistoryEntry.date:type_name -> google.protobuf.Timestamp + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_vehicles_proto_init() } @@ -294,7 +426,7 @@ func file_vehicles_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_vehicles_proto_rawDesc), len(file_vehicles_proto_rawDesc)), NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/grpcapi/vehicles.proto b/grpcapi/vehicles.proto index ba5c1e0..9dfe5e0 100644 --- a/grpcapi/vehicles.proto +++ b/grpcapi/vehicles.proto @@ -26,4 +26,18 @@ message Booking { Vehicle vehicle = 9; bool deleted = 10; + + string manual_status = 11; + repeated StatusHistoryEntry status_history = 12; +} + +message StatusHistoryEntry { + string from_status = 1; + string to_status = 2; + string user_id = 3; + string user_name = 4; + string group_id = 5; + string group_name = 6; + google.protobuf.Timestamp date = 7; + string comment = 8; } diff --git a/storage/bookings.go b/storage/bookings.go index 93ab853..7fd2d6e 100644 --- a/storage/bookings.go +++ b/storage/bookings.go @@ -8,6 +8,17 @@ const ( StatusForthcoming = 1 ) +type StatusHistoryEntry struct { + FromStatus string `json:"from_status" bson:"from_status"` + ToStatus string `json:"to_status" bson:"to_status"` + UserID string `json:"user_id" bson:"user_id"` + UserName string `json:"user_name" bson:"user_name"` + GroupID string `json:"group_id" bson:"group_id"` + GroupName string `json:"group_name" bson:"group_name"` + Date time.Time `json:"date" bson:"date"` + Comment string `json:"comment" bson:"comment"` +} + type Booking struct { ID string `json:"id" bson:"_id"` Vehicleid string `json:"vehicleid"` @@ -20,6 +31,9 @@ type Booking struct { Deleted bool `json:"deleted"` Vehicle Vehicle `json:"vehicle" bson:"-"` + + ManualStatus string `json:"manual_status" bson:"manual_status"` + StatusHistory []StatusHistoryEntry `json:"status_history" bson:"status_history"` } func (b Booking) Status() int {