Files
fm_be/internal/repository/mysql/mcf_repo.go
2026-07-16 22:16:45 +07:00

117 lines
4.1 KiB
Go

package mysql
import (
"context"
"errors"
"gorm.io/gorm"
"wucher/internal/domain/mcf"
)
type MCFRepository struct{ db *gorm.DB }
func NewMCFRepository(db *gorm.DB) *MCFRepository { return &MCFRepository{db: db} }
func (r *MCFRepository) Create(ctx context.Context, row *mcf.MaintenanceCheckFlight) error {
return r.db.WithContext(ctx).Create(row).Error
}
func (r *MCFRepository) Update(ctx context.Context, row *mcf.MaintenanceCheckFlight) error {
return r.db.WithContext(ctx).Save(row).Error
}
func (r *MCFRepository) Delete(ctx context.Context, id []byte, deletedBy []byte) error {
return r.db.WithContext(ctx).Model(&mcf.MaintenanceCheckFlight{}).
Where("id = ? AND deleted_at IS NULL", id).
Updates(map[string]any{"deleted_at": gorm.Expr("NOW(3)"), "deleted_by": deletedBy, "updated_by": deletedBy}).Error
}
func (r *MCFRepository) GetByID(ctx context.Context, id []byte) (*mcf.MaintenanceCheckFlight, error) {
var row mcf.MaintenanceCheckFlight
err := r.db.WithContext(ctx).
Where("id = ? AND deleted_at IS NULL", id).
First(&row).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return &row, err
}
func (r *MCFRepository) GetLatestByHelicopter(ctx context.Context, helicopterID []byte) (*mcf.MaintenanceCheckFlight, error) {
var row mcf.MaintenanceCheckFlight
err := r.db.WithContext(ctx).
Where("helicopter_id = ? AND deleted_at IS NULL", helicopterID).
Order("created_at DESC").
First(&row).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return &row, err
}
func (r *MCFRepository) ListByHelicopter(ctx context.Context, helicopterID []byte) ([]mcf.MaintenanceCheckFlight, error) {
rows := make([]mcf.MaintenanceCheckFlight, 0)
err := r.db.WithContext(ctx).
Where("helicopter_id = ? AND deleted_at IS NULL", helicopterID).
Order("created_at DESC").
Find(&rows).Error
return rows, err
}
// LatestByHelicopterIDs returns the latest (non-deleted) MCF per helicopter, keyed by
// helicopter id (raw bytes as string). Helicopters without an MCF are simply absent.
func (r *MCFRepository) LatestByHelicopterIDs(ctx context.Context, helicopterIDs [][]byte) (map[string]*mcf.MaintenanceCheckFlight, error) {
out := make(map[string]*mcf.MaintenanceCheckFlight, len(helicopterIDs))
if len(helicopterIDs) == 0 {
return out, nil
}
rows := make([]mcf.MaintenanceCheckFlight, 0)
err := r.db.WithContext(ctx).
Where("helicopter_id IN ? AND deleted_at IS NULL AND id = (SELECT m2.id FROM maintenance_check_flights m2 WHERE m2.helicopter_id = maintenance_check_flights.helicopter_id AND m2.deleted_at IS NULL ORDER BY m2.created_at DESC, m2.id DESC LIMIT 1)", helicopterIDs).
Find(&rows).Error
if err != nil {
return out, err
}
for i := range rows {
out[string(rows[i].HelicopterID)] = &rows[i]
}
return out, nil
}
// HelicopterHasOpenMCF reports whether the helicopter has a draft MCF (created but not
// yet completed/signed). Enforces one open MCF per helicopter.
func (r *MCFRepository) HelicopterHasOpenMCF(ctx context.Context, helicopterID []byte) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&mcf.MaintenanceCheckFlight{}).
Where("helicopter_id = ? AND deleted_at IS NULL AND completed_at IS NULL AND cancelled_at IS NULL", helicopterID).
Count(&count).Error
if err != nil {
return false, err
}
return count > 0, nil
}
func (r *MCFRepository) PendingHelicopterIDs(ctx context.Context, helicopterIDs [][]byte) (map[string]bool, error) {
out := make(map[string]bool)
if len(helicopterIDs) == 0 {
return out, nil
}
type rowT struct {
HelicopterID []byte `gorm:"column:helicopter_id"`
}
rows := make([]rowT, 0)
err := r.db.WithContext(ctx).
Table("maintenance_check_flights m").
Select("m.helicopter_id").
Where("m.deleted_at IS NULL AND m.cancelled_at IS NULL AND m.helicopter_id IN ? AND m.id = (SELECT m2.id FROM maintenance_check_flights m2 WHERE m2.helicopter_id = m.helicopter_id AND m2.deleted_at IS NULL AND m2.cancelled_at IS NULL ORDER BY m2.created_at DESC, m2.id DESC LIMIT 1) AND m.completed_at IS NULL", helicopterIDs).
Scan(&rows).Error
if err != nil {
return out, err
}
for i := range rows {
out[string(rows[i].HelicopterID)] = true
}
return out, nil
}