Files
fm_be/internal/service/after_flight_inspection_service.go
2026-07-16 22:16:45 +07:00

169 lines
5.5 KiB
Go

package service
import (
"context"
"fmt"
"strings"
afterflightinspection "wucher/internal/domain/after_flight_inspection"
"wucher/internal/shared/pkg/appctx"
)
type AfterFlightInspectionService struct {
repo afterflightinspection.Repository
}
func NewAfterFlightInspectionService(repo afterflightinspection.Repository) *AfterFlightInspectionService {
return &AfterFlightInspectionService{repo: repo}
}
func (s *AfterFlightInspectionService) Upsert(ctx context.Context, flightInspectionID []byte, req *afterflightinspection.UpsertRequest) (*afterflightinspection.AfterFlightInspection, error) {
if err := s.ensureFlightInspection(ctx, flightInspectionID); err != nil {
return nil, err
}
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 := &afterflightinspection.AfterFlightInspection{
FlightInspectionID: flightInspectionID,
OilEngineNR1Checked: req.OilEngineNR1Checked,
OilEngineNR2Checked: req.OilEngineNR2Checked,
HydraulicLHChecked: req.HydraulicLHChecked,
HydraulicRHChecked: req.HydraulicRHChecked,
OilTransmissionMGBChecked: req.OilTransmissionMGBChecked,
OilTransmissionIGBChecked: req.OilTransmissionIGBChecked,
OilTransmissionTGBChecked: req.OilTransmissionTGBChecked,
Note: req.Note,
}
existing, err := s.repo.GetByFlightInspectionID(ctx, flightInspectionID)
if err != nil {
return nil, fmt.Errorf("failed to load after flight inspection: %w", err)
}
userID := appctx.GetUserID(ctx)
if existing != nil {
row.ID = existing.ID
row.CreatedAt = existing.CreatedAt
row.CreatedBy = existing.CreatedBy
if userID != nil {
row.UpdatedBy = userID
} else {
row.UpdatedBy = existing.UpdatedBy
}
} else if userID != nil {
row.CreatedBy = userID
row.UpdatedBy = userID
}
if err := s.repo.Upsert(ctx, row); err != nil {
return nil, fmt.Errorf("failed to upsert after flight inspection: %w", err)
}
return row, nil
}
func (s *AfterFlightInspectionService) GetByFlightInspectionID(ctx context.Context, flightInspectionID []byte) (*afterflightinspection.AfterFlightInspection, error) {
if err := s.ensureFlightInspection(ctx, flightInspectionID); err != nil {
return nil, err
}
row, err := s.repo.GetByFlightInspectionID(ctx, flightInspectionID)
if err != nil {
return nil, fmt.Errorf("failed to get after flight inspection: %w", err)
}
return row, nil
}
func (s *AfterFlightInspectionService) DeleteByFlightInspectionID(ctx context.Context, flightInspectionID []byte) error {
if err := s.ensureFlightInspection(ctx, flightInspectionID); err != nil {
return err
}
if err := s.repo.DeleteByFlightInspectionID(ctx, flightInspectionID); err != nil {
return fmt.Errorf("failed to delete after flight inspection: %w", err)
}
return nil
}
// ensureFlightInspection validates the identifier and confirms the referenced
// flight inspection exists. It returns domain sentinel errors so the transport
// layer can map them to apperrorsx definitions.
func (s *AfterFlightInspectionService) ensureFlightInspection(ctx context.Context, flightInspectionID []byte) error {
if len(flightInspectionID) != 16 {
return afterflightinspection.ErrInvalidFlightInspectionID
}
exists, err := s.repo.FlightInspectionExists(ctx, flightInspectionID)
if err != nil {
return fmt.Errorf("failed to check flight inspection: %w", err)
}
if !exists {
return afterflightinspection.ErrFlightInspectionNotFound
}
return nil
}
func (s *AfterFlightInspectionService) validateRequest(req *afterflightinspection.UpsertRequest, caps *afterflightinspection.HelicopterCapabilities) error {
if caps == nil {
return afterflightinspection.ErrCapabilitiesUnavailable
}
if caps.NR1 && !hasNonEmptyString(req.OilEngineNR1Checked) {
return afterflightinspection.ErrNR1Required
}
if hasNonEmptyString(req.OilEngineNR1Checked) && !caps.NR1 {
return afterflightinspection.ErrNR1NotAvailable
}
if caps.NR2 && !hasNonEmptyString(req.OilEngineNR2Checked) {
return afterflightinspection.ErrNR2Required
}
if hasNonEmptyString(req.OilEngineNR2Checked) && !caps.NR2 {
return afterflightinspection.ErrNR2NotAvailable
}
if caps.LH && !hasNonEmptyString(req.HydraulicLHChecked) {
return afterflightinspection.ErrLHRequired
}
if hasNonEmptyString(req.HydraulicLHChecked) && !caps.LH {
return afterflightinspection.ErrLHNotAvailable
}
if caps.RH && !hasNonEmptyString(req.HydraulicRHChecked) {
return afterflightinspection.ErrRHRequired
}
if hasNonEmptyString(req.HydraulicRHChecked) && !caps.RH {
return afterflightinspection.ErrRHNotAvailable
}
if caps.MGB && !hasNonEmptyString(req.OilTransmissionMGBChecked) {
return afterflightinspection.ErrMGBRequired
}
if hasNonEmptyString(req.OilTransmissionMGBChecked) && !caps.MGB {
return afterflightinspection.ErrMGBNotAvailable
}
if caps.IGB && !hasNonEmptyString(req.OilTransmissionIGBChecked) {
return afterflightinspection.ErrIGBRequired
}
if hasNonEmptyString(req.OilTransmissionIGBChecked) && !caps.IGB {
return afterflightinspection.ErrIGBNotAvailable
}
if caps.TGB && !hasNonEmptyString(req.OilTransmissionTGBChecked) {
return afterflightinspection.ErrTGBRequired
}
if hasNonEmptyString(req.OilTransmissionTGBChecked) && !caps.TGB {
return afterflightinspection.ErrTGBNotAvailable
}
return nil
}
func hasNonEmptyString(v *string) bool {
return v != nil && strings.TrimSpace(*v) != ""
}