150 lines
6.5 KiB
Go
150 lines
6.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
beforeflightinspection "wucher/internal/domain/before_flight_inspection"
|
|
"wucher/internal/shared/pkg/appctx"
|
|
)
|
|
|
|
type BeforeFlightInspectionService struct {
|
|
repo beforeflightinspection.Repository
|
|
}
|
|
|
|
func NewBeforeFlightInspectionService(repo beforeflightinspection.Repository) *BeforeFlightInspectionService {
|
|
return &BeforeFlightInspectionService{repo: repo}
|
|
}
|
|
|
|
func (s *BeforeFlightInspectionService) Upsert(ctx context.Context, flightInspectionID []byte, req *beforeflightinspection.UpsertRequest) (*beforeflightinspection.BeforeFlightInspection, error) {
|
|
if len(flightInspectionID) != 16 {
|
|
return nil, &beforeflightinspection.ValidationError{Status: 400, Title: "Invalid flight_inspection_id", Detail: "flight_inspection_id must be a valid UUID"}
|
|
}
|
|
|
|
exists, err := s.repo.FlightInspectionExists(ctx, flightInspectionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to check flight inspection: %w", err)
|
|
}
|
|
if !exists {
|
|
return nil, &beforeflightinspection.ValidationError{Status: 404, Title: "Flight inspection not found", Detail: "The specified flight inspection does not exist"}
|
|
}
|
|
|
|
caps, err := s.repo.GetHelicopterCapabilities(ctx, flightInspectionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get helicopter capabilities: %w", err)
|
|
}
|
|
|
|
if err := s.validateRequest(req, caps); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
row := &beforeflightinspection.BeforeFlightInspection{
|
|
FlightInspectionID: flightInspectionID,
|
|
OilEngineNR1Checked: req.OilEngineNR1Checked,
|
|
OilEngineNR2Checked: req.OilEngineNR2Checked,
|
|
HydraulicLHChecked: req.HydraulicLHChecked,
|
|
HydraulicRHChecked: req.HydraulicRHChecked,
|
|
OilTransmissionMGBChecked: req.OilTransmissionMGBChecked,
|
|
OilTransmissionIGBChecked: req.OilTransmissionIGBChecked,
|
|
OilTransmissionTGBChecked: req.OilTransmissionTGBChecked,
|
|
FuelAmount: req.FuelAmount,
|
|
FuelUnit: s.normalizeFuelUnit(req.FuelUnit),
|
|
FuelAddedAmount: req.FuelAddedAmount,
|
|
}
|
|
|
|
// Keep update idempotent on unique flight_inspection_id.
|
|
// If a row already exists, update it instead of inserting a new one.
|
|
existing, err := s.repo.GetByFlightInspectionID(ctx, flightInspectionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get before flight inspection: %w", err)
|
|
}
|
|
if existing != nil {
|
|
row.ID = append([]byte(nil), existing.ID...)
|
|
row.CreatedBy = append([]byte(nil), existing.CreatedBy...)
|
|
row.CreatedAt = existing.CreatedAt
|
|
}
|
|
|
|
userID := appctx.GetUserID(ctx)
|
|
if userID != nil {
|
|
if existing == nil {
|
|
row.CreatedBy = userID
|
|
}
|
|
row.UpdatedBy = userID
|
|
}
|
|
|
|
if err := s.repo.Upsert(ctx, row); err != nil {
|
|
return nil, fmt.Errorf("failed to upsert before flight inspection: %w", err)
|
|
}
|
|
|
|
return row, nil
|
|
}
|
|
|
|
func (s *BeforeFlightInspectionService) GetByFlightInspectionID(ctx context.Context, flightInspectionID []byte) (*beforeflightinspection.BeforeFlightInspection, error) {
|
|
if len(flightInspectionID) != 16 {
|
|
return nil, &beforeflightinspection.ValidationError{Status: 400, Title: "Invalid flight_inspection_id", Detail: "flight_inspection_id must be a valid UUID"}
|
|
}
|
|
|
|
exists, err := s.repo.FlightInspectionExists(ctx, flightInspectionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to check flight inspection: %w", err)
|
|
}
|
|
if !exists {
|
|
return nil, &beforeflightinspection.ValidationError{Status: 404, Title: "Flight inspection not found", Detail: "The specified flight inspection does not exist"}
|
|
}
|
|
|
|
row, err := s.repo.GetByFlightInspectionID(ctx, flightInspectionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get before flight inspection: %w", err)
|
|
}
|
|
|
|
return row, nil
|
|
}
|
|
|
|
func (s *BeforeFlightInspectionService) validateRequest(req *beforeflightinspection.UpsertRequest, caps *beforeflightinspection.HelicopterCapabilities) error {
|
|
if req.FuelAmount != nil && *req.FuelAmount < 0 {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid fuel_amount", Detail: "fuel_amount cannot be negative"}
|
|
}
|
|
if req.FuelAddedAmount != nil && *req.FuelAddedAmount < 0 {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid fuel_added_amount", Detail: "fuel_added_amount cannot be negative"}
|
|
}
|
|
|
|
if req.FuelUnit != nil {
|
|
if _, valid := beforeflightinspection.NormalizeFuelUnit(*req.FuelUnit); !valid {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid fuel_unit", Detail: "fuel_unit must be one of: LT, KG, POUND"}
|
|
}
|
|
}
|
|
|
|
// Capability=true means corresponding check must be explicitly true.
|
|
if caps.NR1 && (req.OilEngineNR1Checked == nil || !*req.OilEngineNR1Checked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid oil_engine_nr1_checked", Detail: "oil_engine_nr1_checked must be true for this helicopter"}
|
|
}
|
|
if caps.NR2 && (req.OilEngineNR2Checked == nil || !*req.OilEngineNR2Checked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid oil_engine_nr2_checked", Detail: "oil_engine_nr2_checked must be true for this helicopter"}
|
|
}
|
|
if caps.LH && (req.HydraulicLHChecked == nil || !*req.HydraulicLHChecked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid hydraulic_lh_checked", Detail: "hydraulic_lh_checked must be true for this helicopter"}
|
|
}
|
|
if caps.RH && (req.HydraulicRHChecked == nil || !*req.HydraulicRHChecked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid hydraulic_rh_checked", Detail: "hydraulic_rh_checked must be true for this helicopter"}
|
|
}
|
|
if caps.MGB && (req.OilTransmissionMGBChecked == nil || !*req.OilTransmissionMGBChecked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid oil_transmission_mgb_checked", Detail: "oil_transmission_mgb_checked must be true for this helicopter"}
|
|
}
|
|
if caps.IGB && (req.OilTransmissionIGBChecked == nil || !*req.OilTransmissionIGBChecked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid oil_transmission_igb_checked", Detail: "oil_transmission_igb_checked must be true for this helicopter"}
|
|
}
|
|
if caps.TGB && (req.OilTransmissionTGBChecked == nil || !*req.OilTransmissionTGBChecked) {
|
|
return &beforeflightinspection.ValidationError{Status: 422, Title: "Invalid oil_transmission_tgb_checked", Detail: "oil_transmission_tgb_checked must be true for this helicopter"}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *BeforeFlightInspectionService) normalizeFuelUnit(unit *string) string {
|
|
if unit == nil {
|
|
return ""
|
|
}
|
|
normalized, _ := beforeflightinspection.NormalizeFuelUnit(*unit)
|
|
return normalized
|
|
}
|