# Simplane API's design
## Swagger:
- http://localhost:8282/simplane-service/swagger-ui/index.html
- /simplane-service/api-docs
## Database:
- mongodb+srv://lhquan:25251325Quan@cluster0.0u1hb.mongodb.net/?retryWrites=true&w=majority
## Mutable tables
### 1. Airport
| code | name | address |
| ---- | ---- | ------- |
| SGN | Tân Sơn Nhất | TP.HCM |
| HAN | Nội Bài | Hà Nội |
| VDH | Đồng Hới | Quảng Bình |
| VII | Vinh | Nghệ An |
| CXR | Cam Ranh | Khánh Hòa |
| VCA | Cần Thơ | Cần Thơ |
| DAD | Đà Nẵng | Đà Nẵng |
## Fixed tables
### 1. Manager account
| id | username | password | fullname |
| -- | -------- | -------- | -------- |
| 0 | admin | admin | Admin |
### 2. Ticket class
| id | enName | viName | canChange | changeFee | canReturn | returnFee |
| --- | --- | --- | --- | --- | ---| --- |
| P | Economy super lite | Phổ thông siêu tiết kiệm | false | 0 | false | 0 |
| L | Economy | Phổ thông | true | 120000.0 | false | 0 |
| C | Business | Thương gia | true | 0 | true | 30000.0 |
## Authenticate
### 1. Login
- Type: **POST**
- Path: `/auth/sign-in`
- Request's params:
```json=
{
"username": "lehongquan",
"password": "123456"
}
```
- Response:
```json=
{
"statusCode": 200,
"message": "Đăng nhập thành công",
"data": {
"isVerified": true,
"fullname": "Lê Hồng Quân",
"isAdmin": true,
"username": "lehongquan",
"token": "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsZWhvbmdxdWFuIiwiaWF0IjoxNjU1MDM3MDY1LCJleHAiOjE2NTU2NDE4NjV9.pOnfcarliOp2K20_Gzej57hNJO4ehSQ-IkASptApYfnXcN4bidAU0xPtLe9dE7octwdk5-GZEtqSUrs-Z9Q2Kg"
}
}
```
```json=
{
"statusCode": 0,
"message": "Mật khẩu không đúng! Vui lòng kiểm tra lại!"
}
```
```json=
{
"statusCode": 0,
"message": "Tài khoản không tồn tại! Vui lòng kiểm tra lại!"
}
```
- Note: `isAdmin` có thể không cần, mặc định là false, khi nào là tài khoản admin thì mới true
### 2. Sign up
- Type: **POST**
- Path: `/auth/sign-up`
- Request's params:
```json=
{
"username": "lehongquan1",
"password": "123456",
"fullname": "Lê Hồng Quân",
"accessToken": "",
"isVerified": true,
"idAdmin": true
}
```
- Response:
```json=
{
"statusCode": 200,
"data": {
"username": "lehongquan2",
"password": "123456",
"fullname": "Lê Hồng Quân",
"accessToken": "string",
"isVerified": true,
"idAdmin": true
}
}
```
```json=
{
"statusCode": 0,
"message": "Tài khoản đã tồn tại! Vui lòng kiểm tra lại!"
}
```
### 3. Logout
- Type: **POST**
- Path: `/auth/sign-out`
- Request's params:
```json=
{
}
```
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Response:
```json=
{
"data": {}
"result": 0,
"code": "Success"
}
```
```json=
{
"data": {}
"result": -1,
"code": "Fail",
"errorMessage": "Tài khoản chưa đăng nhập"
}
```
## Flight
### 1. Get flight
- Type: **GET**
- Path: `$/flight/:id`
- Request's params:
```json=
{
"id": 3423
}
```
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
"data":
{
"id": 3423,
"code": "VN 6010",
"fromAirport":
{
"code": "SGN",
"name": "Tân Sơn Nhất",
"address": "TP.HCM"
},
"toAirport":
{
"code": "HAN",
"name": "Nội Bài",
"address": "Hà Nội"
},
"datetime": "2022-05-27 05:55:00",
"duration": 115,
"ticketClassPrice":
{
"P": 230000.0,
"L": 450000.0,
"C": 1200000.0,
},
"seatAmount":
{
"P": 50,
"L": 70,
"C": 10,
},
"bookedAmount":
{
"P": 32,
"L": 43,
"C": 3,
},
"middleAirports": [
{
"code": "VDH",
"name": "Đồng Hới",
"address": "Quảng Bình"
},
{
"code": "VII",
"name": "Vinh",
"address": "Nghệ An"
},
],
"stopDuration": [
12,
16
]
},
"result": 0,
"code": "Success"
}
```
```json=
{
"data": {}
"result": -1,
"code": "Fail",
"errorMessage": "Không tồn tại chuyến bay có ID này"
}
```
- Note: Định dạng của _datetime_ là tùy ý
### 2. POST flight
- Type: **POST**
- Path: `$/flight`
- Request's params:
```json=
{
"id": "",
"fromAirportCode": "SGN",
"toAirportCode": "HAN",
"dateTime": "2022-06-12T16:24:28.024007Z",
"duration": 0,
"seatAmount": {
"P": 100,
"L": 50,
"C": 20
},
"bookedAmount": {
"P": 0,
"L": 0,
"C": 0
},
"ticketClassPrice": {
"P": 1000000.0,
"L": 2000000.0,
"C": 3000000.0
},
"middleAirportCodes": [
],
"stopDuration": [
]
}
```
- Reponse:
```json=
{
"statusCode": 200,
"data": {
"id": "1015",
"code": "VN-1015",
"fromAirport": {
"code": "SGN",
"name": "Tân Sơn Nhất",
"address": "TP.HCM"
},
"toAirport": {
"code": "HAN",
"name": "Nội Bài",
"address": "Hà Nội"
},
"dateTime": "2022-06-12T16:24:28.119+00:00",
"duration": 0,
"seatAmount": {
"P": 0,
"C": 0,
"L": 0
},
"bookedAmount": null,
"middleAirports": null,
"stopDurations": null
}
}
```
### 3. Get flights
- Type: **GET**
- Path: `$/flight/:id`
- Request's params:
```json=
{
"fromDate": "2022-05-20 00:00:00",
"toDate": "2022-05-29 00:00:00",
}
```
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
"data": [
{
"id": 3423,
"code": "VN 6010",
"fromAirport":
{
"code": "SGN",
"name": "Tân Sơn Nhất",
"address": "TP.HCM"
},
"toAirport":
{
"code": "HAN",
"name": "Nội Bài",
"address": "Hà Nội"
},
"datetime": "2022-05-27 05:55:00",
"duration": 115,
"seatAmount":
{
"P": 50,
"L": 70,
"C": 10,
},
"bookedAmount":
{
"P": 32,
"L": 43,
"C": 3,
},
"middleAirports": [
{
"code": "VDH",
"name": "Đồng Hới",
"address": "Quảng Bình"
},
{
"code": "VII",
"name": "Vinh",
"address": "Nghệ An"
},
],
"stopDuration": [
12,
16
]
},
{
"id": 3425,
"code": "VN 800",
"fromAirport":
{
"code": "VDH",
"name": "Đồng Hới",
"address": "Quảng Bình"
},
"toAirport":
{
"code": "SGN",
"name": "Tân Sơn Nhất",
"address": "TP.HCM"
},
"datetime": "2022-05-28 17:05:00",
"duration": 85,
"seatAmount":
{
"P": 60,
"L": 80,
"C": 15,
},
"bookedAmount":
{
"P": 45,
"L": 32,
"C": 8,
},
"middleAirports": [],
"stopDuration": []
},
],
"result": 0,
"code": "Success"
}
```
## Ticket
### 1. Get ticket
- Type: **GET**
- Path: `/ticket`
- Request's params:
```json=
{
"id": 446
}
```
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
"statusCode": 0,
"message": null,
"data": [
{
"id": "1004",
"flightCode": "VN-1012",
"flightDate": 1655049315776,
"passenger": {
"id": "1005",
"firstName": "Đặng",
"lastName": "Phương Nam",
"identityNumber": "147893652",
"email": "dpnam@gmail.com",
"phoneNumber": "123456789"
},
"ticketClassId": "P",
"price": 10000,
"bookedTime": 1655747656317,
"idUser": "1000"
},
{
"id": "1005",
"flightCode": "VN-1012",
"flightDate": 1655049315776,
"passenger": {
"id": "1006",
"firstName": "Đặng",
"lastName": "Phương Nam",
"identityNumber": "147893652",
"email": "dpnam@gmail.com",
"phoneNumber": "123456789"
},
"ticketClassId": "P",
"price": 10000,
"bookedTime": 1655747656317,
"idUser": "1000"
}
]
}
```
```json=
{
"data": {}
"result": -1,
"code": "Fail",
"errorMessage": "Không tồn tại vé có ID này"
}
```
- Note:
- _passenger_, _bookedTime_, _verifiedTime_ có thể NULL
- Quy tắc:
```java=
boolean isBooked = passenger != null && bookedTime != null;
boolean isPending = passenger != null && bookedTime != null && verifiedTime == null;
boolean isVerified = passenger != null && bookedTime != null && verifiedTime != null;
```
### 2. POST ticket
- Type: **POST**
- Path: `/ticket`
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Body:
```json=
{
"id": "",
"flightCode": "VN-1012",
"flightDate": 1655049315776,
"passenger": {
"id": "",
"firstName": "Đặng",
"lastName": "Phương Nam",
"identityNumber": "147893652",
"email": "dpnam@gmail.com",
"phoneNumber": "123456789"
},
"ticketClassId": "P",
"price": 10000,
"bookedTime": 1655747656317,
"idUser": "1000"
}
```
- Reponse:
```json=
{
"statusCode": 200,
"data": {
"id": "1005",
"flightCode": "VN-1012",
"flightDate": 1655049315776,
"passenger": null,
"ticketClassId": "P",
"price": 10000,
"bookedTime": 1655747656317,
"idUser": "1000"
}
}
```
## Report
### 1. Get report (by staff)
- Type: **GET**
- Path: `$URL/api/report/get`
- Request's params:
```json=
{
"year": 2022,
"staffId": 123,
}
```
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
"data":
{
"year": 2022,
"staffId": 123,
"monthlyReports": [
{
"year": 2022,
"staffId": 123,
"month": 1,
"ticketCount": 35,
"revenue": 52300000.0,
},
{
"year": 2022,
"staffId": 123,
"month": 2,
"ticketCount": 24,
"revenue": 31200000.0,
},
...
{
"year": 2022,
"staffId": 123,
"month": 12,
"ticketCount": 46,
"revenue": 75200000.0,
},
]
}
"result": 0,
"code": "Success"
}
```
### 2. Get report (by manager)
- Type: **GET**
- Path: `$URL/api/report/get`
- Request's params:
```json=
{
"year": 2022,
}
```
- Request's headers:
```json=
{
"accessToken": "jjh24kjh34234jh32jk4kj324jkh234kjh4"
}
```
- Reponse:
```json=
{
"data":
{
"year": 2022,
"monthlyReports": [
{
"year": 2022,
"month": 1,
"flightCount": 60,
"ticketCount": 312,
"revenue": 523000000.0,
},
{
"year": 2022,
"month": 2,
"flightCount": 58,
"ticketCount": 246,
"revenue": 312000000.0,
},
...
{
"year": 2022,
"month": 12,
"flightCount": 75,
"ticketCount": 412,
"revenue": 752000000.0,
},
]
}
"result": 0,
"code": "Success"
}
```
- Note:
- Phân biệt request của staff và manager bằng accessToken
- Manager thì không có staffId, vì manager xem được của báo cáo của tất cả staff
- Manager xem được báo cáo tổng của tất cả các nhân viên, và có thêm số lượng chuyến bay
## Staff (only Manager)
### 1. Get staffs
- Type: **GET**
- Path: `$URL/api/staff`
- Request's headers:
```json=
{
"accessToken": "asdskd2312h3kj12h3jk123gh3g12h3g12"
}
```
- Reponse:
```json=
{
"data": [
{
"id": 123,
"username": "lehongquan2",
"fullname": "Lê Hồng Quân",
"totalTicket": 124.0,
"totalRevenue": 45200000.0,
},
{
"id": 123,
"username": "lehongquan2",
"fullname": "Lê Hồng Quân",
"totalTicket": 124.0,
"totalRevenue": 45200000.0,
},
{
"id": 123,
"username": "lehongquan2",
"fullname": "Lê Hồng Quân",
"totalTicket": 124.0,
"totalRevenue": 45200000.0,
},
],
"result": 200,
"code": "Success"
}
```
### 2. Remove staff
- Type: **DELETE**
- Path: `$URL/api/staff`
- Request's params:
```json=
{
"id": 123,
}
```
- Request's headers:
```json=
{
"accessToken": "jjh24kjh34234jh32jk4kj324jkh234kjh4"
}
```
- Reponse:
```json=
{
"data": { }
"result": 200,
"code": "Success"
}
```
## Ticket Class
### 1. Get list
- Type: **GET**
- Path: `$URL/api/ticket-class/gets`
- Request's params:
```json=
{
}
```
- Request's headers:
```json=
{
}
```
- Reponse:
```json=
{
"data": [
{
"id": "P",
"enName": "Economy super lite",
"viName": "Phổ thông siêu tiết kiệm",
"canChange": false,
"changeFee": 0.0,
"canReturn": false,
"returnFee": 0.0,
},
...
],
"result": 0,
"code": "Success"
}
```
- Note: Xem bảng 2 ở Fixed tables