Compare commits
1 Commits
dev
...
0b6b92876e
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b6b92876e |
99
README.md
99
README.md
@@ -1,99 +1,12 @@
|
|||||||
# COOPGO Fleets
|
# COOPGO Fleets
|
||||||
|
|
||||||
COOPGO Fleets is a vehicle fleet management microservice providing vehicle and booking management capabilities.
|
COOPGO Fleets is a vehicle management and booking service.
|
||||||
|
|
||||||
## Features
|
It provides :
|
||||||
|
|
||||||
- gRPC API for vehicle and booking management
|
- a gRPC API to manage fleets of vehicles and bookings
|
||||||
- Vehicle availability tracking with booking integration
|
- availability information on véhicles
|
||||||
- Flexible data schema for custom vehicle and booking attributes
|
- a flexible data schema to push any information on vehicles or bookings
|
||||||
- Soft delete for bookings with metadata preservation
|
|
||||||
- Multi-namespace support for fleet isolation
|
|
||||||
- Vehicle filtering by type, administrator, and availability
|
|
||||||
|
|
||||||
## Architecture
|
It is not a full featured booking platform but just a microservice intended to be used as part of a bigger platform, like the COOPGO Technical Platform. It doesn't provide any king of booking UI or management interface.
|
||||||
|
|
||||||
This microservice is designed to be part of the COOPGO Technical Platform. It does not provide a UI or management interface.
|
|
||||||
|
|
||||||
```
|
|
||||||
├── grpcapi/ # gRPC server and protocol definitions
|
|
||||||
├── handlers/ # Business logic
|
|
||||||
└── storage/ # Database access layer (MongoDB, PostgreSQL)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Configuration is managed via Viper. Create a `config.yaml` file or use environment variables.
|
|
||||||
|
|
||||||
### Default configuration
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: "COOPGO Fleets"
|
|
||||||
dev_env: false
|
|
||||||
|
|
||||||
storage:
|
|
||||||
db:
|
|
||||||
type: mongodb # or "psql"
|
|
||||||
mongodb:
|
|
||||||
host: localhost
|
|
||||||
port: "27017"
|
|
||||||
db_name: coopgo_platform
|
|
||||||
collections:
|
|
||||||
vehicles: fleet_vehicles
|
|
||||||
bookings: fleet_bookings
|
|
||||||
|
|
||||||
services:
|
|
||||||
grpc:
|
|
||||||
enable: true
|
|
||||||
port: 8093
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment variables
|
|
||||||
|
|
||||||
Use underscore-separated uppercase names: `STORAGE_DB_TYPE`, `SERVICES_GRPC_PORT`, etc.
|
|
||||||
|
|
||||||
## Storage backends
|
|
||||||
|
|
||||||
- **MongoDB** (default)
|
|
||||||
- **PostgreSQL** (with Atlas migrations)
|
|
||||||
|
|
||||||
## Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go build
|
|
||||||
```
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker build \
|
|
||||||
--build-arg ACCESS_TOKEN_USR=<user> \
|
|
||||||
--build-arg ACCESS_TOKEN_PWD=<password> \
|
|
||||||
-t coopgo-fleets .
|
|
||||||
```
|
|
||||||
|
|
||||||
## gRPC API
|
|
||||||
|
|
||||||
### Vehicles
|
|
||||||
|
|
||||||
| Method | Description |
|
|
||||||
|--------|-------------|
|
|
||||||
| `AddVehicle` | Create a new vehicle |
|
|
||||||
| `GetVehicle` | Get a vehicle by ID (includes bookings) |
|
|
||||||
| `GetVehicles` | List vehicles with filters |
|
|
||||||
| `UpdateVehicle` | Update vehicle data |
|
|
||||||
|
|
||||||
### Bookings
|
|
||||||
|
|
||||||
| Method | Description |
|
|
||||||
|--------|-------------|
|
|
||||||
| `CreateBooking` | Create a booking |
|
|
||||||
| `GetBooking` | Get a booking by ID |
|
|
||||||
| `GetBookings` | List all bookings |
|
|
||||||
| `GetDriverBookings` | Get bookings for a driver |
|
|
||||||
| `UpdateBooking` | Update a booking |
|
|
||||||
| `DeleteBooking` | Soft delete a booking |
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
See [LICENSE.md](LICENSE.md)
|
|
||||||
|
|||||||
@@ -11,16 +11,14 @@ func ReadConfig() (*viper.Viper, error) {
|
|||||||
"name": "COOPGO Fleets",
|
"name": "COOPGO Fleets",
|
||||||
"dev_env": false,
|
"dev_env": false,
|
||||||
"storage": map[string]any{
|
"storage": map[string]any{
|
||||||
"db": map[string]any{
|
|
||||||
"type": "mongodb",
|
"type": "mongodb",
|
||||||
"mongodb": map[string]any{
|
"mongodb": map[string]any{
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"port": "27017",
|
"port": "27017",
|
||||||
"db_name": "coopgo_platform",
|
"db_name": "coopgo_platform",
|
||||||
"collections": map[string]any{
|
"collections": map[string]any{
|
||||||
"vehicles": "vehicles",
|
"vehicles": "fleet_vehicles",
|
||||||
"bookings": "bookings",
|
"bookings": "fleet_bookings",
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ func (v Booking) ToStorageType() storage.Booking {
|
|||||||
Unavailableto: v.Unavailableto.AsTime(),
|
Unavailableto: v.Unavailableto.AsTime(),
|
||||||
Data: map[string]any{},
|
Data: map[string]any{},
|
||||||
Deleted: v.Deleted,
|
Deleted: v.Deleted,
|
||||||
ManualStatus: v.ManualStatus,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, d := range v.Data.GetFields() {
|
for k, d := range v.Data.GetFields() {
|
||||||
@@ -39,19 +38,6 @@ func (v Booking) ToStorageType() storage.Booking {
|
|||||||
booking.Vehicle = v.Vehicle.ToStorageType()
|
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
|
return booking
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,20 +63,6 @@ func BookingFromStorageType(booking *storage.Booking) (*Booking, error) {
|
|||||||
Unavailableto: timestamppb.New(booking.Unavailableto),
|
Unavailableto: timestamppb.New(booking.Unavailableto),
|
||||||
Data: data,
|
Data: data,
|
||||||
Deleted: booking.Deleted,
|
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)
|
result.Vehicle, err = VehicleFromStorageType(&booking.Vehicle)
|
||||||
|
|||||||
@@ -119,8 +119,6 @@ type Booking struct {
|
|||||||
Data *structpb.Struct `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"`
|
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"`
|
Vehicle *Vehicle `protobuf:"bytes,9,opt,name=vehicle,proto3" json:"vehicle,omitempty"`
|
||||||
Deleted bool `protobuf:"varint,10,opt,name=deleted,proto3" json:"deleted,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
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -225,120 +223,6 @@ func (x *Booking) GetDeleted() bool {
|
|||||||
return false
|
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
|
var File_vehicles_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_vehicles_proto_rawDesc = "" +
|
const file_vehicles_proto_rawDesc = "" +
|
||||||
@@ -350,7 +234,7 @@ const file_vehicles_proto_rawDesc = "" +
|
|||||||
"\x04type\x18\x03 \x01(\tR\x04type\x12&\n" +
|
"\x04type\x18\x03 \x01(\tR\x04type\x12&\n" +
|
||||||
"\x0eadministrators\x18\x04 \x03(\tR\x0eadministrators\x12+\n" +
|
"\x0eadministrators\x18\x04 \x03(\tR\x0eadministrators\x12+\n" +
|
||||||
"\x04data\x18\x05 \x01(\v2\x17.google.protobuf.StructR\x04data\x12$\n" +
|
"\x04data\x18\x05 \x01(\v2\x17.google.protobuf.StructR\x04data\x12$\n" +
|
||||||
"\bbookings\x18\x06 \x03(\v2\b.BookingR\bbookings\"\x93\x04\n" +
|
"\bbookings\x18\x06 \x03(\v2\b.BookingR\bbookings\"\xb2\x03\n" +
|
||||||
"\aBooking\x12\x0e\n" +
|
"\aBooking\x12\x0e\n" +
|
||||||
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1c\n" +
|
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1c\n" +
|
||||||
"\tvehicleid\x18\x02 \x01(\tR\tvehicleid\x12\x16\n" +
|
"\tvehicleid\x18\x02 \x01(\tR\tvehicleid\x12\x16\n" +
|
||||||
@@ -362,20 +246,7 @@ const file_vehicles_proto_rawDesc = "" +
|
|||||||
"\x04data\x18\b \x01(\v2\x17.google.protobuf.StructR\x04data\x12\"\n" +
|
"\x04data\x18\b \x01(\v2\x17.google.protobuf.StructR\x04data\x12\"\n" +
|
||||||
"\avehicle\x18\t \x01(\v2\b.VehicleR\avehicle\x12\x18\n" +
|
"\avehicle\x18\t \x01(\v2\b.VehicleR\avehicle\x12\x18\n" +
|
||||||
"\adeleted\x18\n" +
|
"\adeleted\x18\n" +
|
||||||
" \x01(\bR\adeleted\x12#\n" +
|
" \x01(\bR\adeletedB.Z,git.coopgo.io/coopgo-platform/fleets/grpcapib\x06proto3"
|
||||||
"\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 (
|
var (
|
||||||
file_vehicles_proto_rawDescOnce sync.Once
|
file_vehicles_proto_rawDescOnce sync.Once
|
||||||
@@ -389,30 +260,27 @@ func file_vehicles_proto_rawDescGZIP() []byte {
|
|||||||
return file_vehicles_proto_rawDescData
|
return file_vehicles_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_vehicles_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
var file_vehicles_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||||
var file_vehicles_proto_goTypes = []any{
|
var file_vehicles_proto_goTypes = []any{
|
||||||
(*Vehicle)(nil), // 0: Vehicle
|
(*Vehicle)(nil), // 0: Vehicle
|
||||||
(*Booking)(nil), // 1: Booking
|
(*Booking)(nil), // 1: Booking
|
||||||
(*StatusHistoryEntry)(nil), // 2: StatusHistoryEntry
|
(*structpb.Struct)(nil), // 2: google.protobuf.Struct
|
||||||
(*structpb.Struct)(nil), // 3: google.protobuf.Struct
|
(*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp
|
||||||
(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
|
|
||||||
}
|
}
|
||||||
var file_vehicles_proto_depIdxs = []int32{
|
var file_vehicles_proto_depIdxs = []int32{
|
||||||
3, // 0: Vehicle.data:type_name -> google.protobuf.Struct
|
2, // 0: Vehicle.data:type_name -> google.protobuf.Struct
|
||||||
1, // 1: Vehicle.bookings:type_name -> Booking
|
1, // 1: Vehicle.bookings:type_name -> Booking
|
||||||
4, // 2: Booking.startdate:type_name -> google.protobuf.Timestamp
|
3, // 2: Booking.startdate:type_name -> google.protobuf.Timestamp
|
||||||
4, // 3: Booking.enddate:type_name -> google.protobuf.Timestamp
|
3, // 3: Booking.enddate:type_name -> google.protobuf.Timestamp
|
||||||
4, // 4: Booking.unavailablefrom:type_name -> google.protobuf.Timestamp
|
3, // 4: Booking.unavailablefrom:type_name -> google.protobuf.Timestamp
|
||||||
4, // 5: Booking.unavailableto:type_name -> google.protobuf.Timestamp
|
3, // 5: Booking.unavailableto:type_name -> google.protobuf.Timestamp
|
||||||
3, // 6: Booking.data:type_name -> google.protobuf.Struct
|
2, // 6: Booking.data:type_name -> google.protobuf.Struct
|
||||||
0, // 7: Booking.vehicle:type_name -> Vehicle
|
0, // 7: Booking.vehicle:type_name -> Vehicle
|
||||||
2, // 8: Booking.status_history:type_name -> StatusHistoryEntry
|
8, // [8:8] is the sub-list for method output_type
|
||||||
4, // 9: StatusHistoryEntry.date:type_name -> google.protobuf.Timestamp
|
8, // [8:8] is the sub-list for method input_type
|
||||||
10, // [10:10] is the sub-list for method output_type
|
8, // [8:8] is the sub-list for extension type_name
|
||||||
10, // [10:10] is the sub-list for method input_type
|
8, // [8:8] is the sub-list for extension extendee
|
||||||
10, // [10:10] is the sub-list for extension type_name
|
0, // [0:8] is the sub-list for field 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() }
|
func init() { file_vehicles_proto_init() }
|
||||||
@@ -426,7 +294,7 @@ func file_vehicles_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_vehicles_proto_rawDesc), len(file_vehicles_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_vehicles_proto_rawDesc), len(file_vehicles_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 3,
|
NumMessages: 2,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -26,18 +26,4 @@ message Booking {
|
|||||||
|
|
||||||
Vehicle vehicle = 9;
|
Vehicle vehicle = 9;
|
||||||
bool deleted = 10;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,17 +8,6 @@ const (
|
|||||||
StatusForthcoming = 1
|
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 {
|
type Booking struct {
|
||||||
ID string `json:"id" bson:"_id"`
|
ID string `json:"id" bson:"_id"`
|
||||||
Vehicleid string `json:"vehicleid"`
|
Vehicleid string `json:"vehicleid"`
|
||||||
@@ -31,9 +20,6 @@ type Booking struct {
|
|||||||
|
|
||||||
Deleted bool `json:"deleted"`
|
Deleted bool `json:"deleted"`
|
||||||
Vehicle Vehicle `json:"vehicle" bson:"-"`
|
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 {
|
func (b Booking) Status() int {
|
||||||
|
|||||||
Reference in New Issue
Block a user