diff --git a/README.md b/README.md index 0401961..43b49bb 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 40b2b62..8ba234d 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -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) +} diff --git a/internal/repository/interface.go b/internal/repository/interface.go index 1ba2a3b..1a78d01 100644 --- a/internal/repository/interface.go +++ b/internal/repository/interface.go @@ -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) } diff --git a/internal/repository/postgres.go b/internal/repository/postgres.go index aeb5d5f..d3e55c2 100644 --- a/internal/repository/postgres.go +++ b/internal/repository/postgres.go @@ -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 +} diff --git a/internal/usecase/usecase.go b/internal/usecase/usecase.go index 1b0e034..a0a8393 100644 --- a/internal/usecase/usecase.go +++ b/internal/usecase/usecase.go @@ -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) +}