endpoint shipment/{cargo_id}/cost

This commit is contained in:
Dmitriy Bondarenko 2025-03-27 22:50:42 +00:00
parent 5cf8dd1bb1
commit 40780ae405
5 changed files with 87 additions and 4 deletions

View File

@ -1,14 +1,32 @@
# track-company
# Truck-Company
# В ПРОЦЕССЕ РАЗРАБОТКИ
# Задание
[Задание](Task15.md)
## Файл .env
- `POSTGRES_USER`=
- `POSTGRES_PASSWORD`=
- `POSTGRES_DB`=
- `DB_HOST`=postgres
- `DB_PORT`=5432
- `DB_SSLMODE`=disable
## Запуск
`podman-compose build && podman-compose up`
## Рабочие Endpoints:
- `/routes` - Получить список маршрутов;
- `/routes/{route_id}/transport` - Список транспорта, занятого на данном маршруте;
- `/shipment/{cargo_id}/cost` - Рассчет стоимости услуг, оказанных по перевозке данного груза с учётом скидки постоянного клиента ;
## Схема БД
![Схема БД](docs/Diagram.png)

View File

@ -23,8 +23,8 @@ func (h *TruckCompanyHandler) RegisterRoutes(r *mux.Router) {
r.HandleFunc("/routes", h.GetRoutes).Methods("GET")
r.HandleFunc("/routes/{route_id}/transport", h.GetTransportByRoute).Methods("GET")
r.HandleFunc("/shipment/{cargo_id}/cost", h.GetShipmentCost).Methods("GET")
// r.HandleFunc("/routes/{route_id}/transport-types", h.GetTransportTypesByRoute).Methods("GET")
// r.HandleFunc("/shipments/cost", h.GetShipmentCost).Methods("GET")
// r.HandleFunc("/routes/{route_id}/cargo-turnover", h.GetCargoTurnoverByRoute).Methods("GET")
//404 для всех остальных
@ -64,3 +64,29 @@ func (h *TruckCompanyHandler) GetTransportByRoute(w http.ResponseWriter, r *http
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(transport)
}
func (h *TruckCompanyHandler) GetShipmentCost(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
cargo_id, err := strconv.ParseInt(vars["cargo_id"], 10, 64)
if err != nil {
sendErrorResponse(w, http.StatusBadRequest, "Invalid cargo ID", err.Error())
return
}
final_cost, err := h.uc.GetCargoCost(cargo_id)
if err != nil {
sendErrorResponse(w, http.StatusInternalServerError, "", err.Error())
return
}
response := struct {
CargoCost float64 `json:"cargo_cost_count"`
}{
CargoCost: final_cost,
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}

View File

@ -8,4 +8,5 @@ type RepositoryInterface interface {
GetAllRoutes() ([]domain.Route, error)
GetTransportByRoute(routeID int64) ([]domain.Transport, error)
GetShipmentCosts() ([]domain.Shipment, error)
GetCargoCost(cargoID int64) (float64, error)
}

View File

@ -3,6 +3,7 @@ package repository
import (
"database/sql"
"errors"
"log"
domain "truck-company/internal/domain"
)
@ -38,8 +39,12 @@ func (r *AppRepo) GetAllRoutes() ([]domain.Route, error) {
return routes, nil
}
func (t *AppRepo) GetTransportByRoute(routeID int64) ([]domain.Transport, error) {
rows, err := t.db.Query(`
func (r *AppRepo) GetTransportByRoute(routeID int64) ([]domain.Transport, error) {
if r.db == nil {
return nil, errors.New("Ошибка подключения к бд. *db == nil")
}
rows, err := r.db.Query(`
SELECT t.id, t.model, t.capacity, tt.name
FROM transport t
JOIN shipment s ON t.id = s.transport_id
@ -60,3 +65,32 @@ func (t *AppRepo) GetTransportByRoute(routeID int64) ([]domain.Transport, error)
}
return transports, nil
}
func (r *AppRepo) GetCargoCost(cargoID int64) (float64, error) {
if r.db == nil {
return 0, errors.New("Ошибка подключения к бд. *db == nil")
}
var finalCost float64
query := `
SELECT
SUM( CASE
WHEN cl.is_regular THEN s.cost * 0.95 -- 5% скидка постоянным клиентам
ELSE s.cost
END) AS final_cost
FROM shipment s
JOIN client cl ON s.client_id = cl.id
JOIN route r ON s.route_id = r.id
JOIN cargo c ON s.cargo_id = c.id
WHERE c.id = $1
GROUP BY c.id;
`
err := r.db.QueryRow(query, cargoID).Scan(&finalCost)
if err != nil {
log.Println("Ошибка при получении стоимости перевозки:", err)
return 0, err
}
return finalCost, nil
}

View File

@ -22,3 +22,7 @@ func (u *UseCase) GetAllRoutes() ([]domain.Route, error) {
func (u *UseCase) GetTransportByRoute(routeID int64) ([]domain.Transport, error) {
return u.AppRepo.GetTransportByRoute(routeID)
}
func (u *UseCase) GetCargoCost(cargoID int64) (float64, error) {
return u.AppRepo.GetCargoCost(cargoID)
}