package drafts import ( "fmt" "rmser/internal/domain/drafts" "github.com/google/uuid" "gorm.io/gorm" ) type pgRepository struct { db *gorm.DB } func NewRepository(db *gorm.DB) drafts.Repository { return &pgRepository{db: db} } func (r *pgRepository) Create(draft *drafts.DraftInvoice) error { return r.db.Create(draft).Error } func (r *pgRepository) GetByID(id uuid.UUID) (*drafts.DraftInvoice, error) { var draft drafts.DraftInvoice err := r.db. Preload("Items", func(db *gorm.DB) *gorm.DB { return db.Order("draft_invoice_items.order ASC") }). Preload("Items.Product"). Preload("Items.Product.MainUnit"). Preload("Items.Container"). Where("id = ?", id). First(&draft).Error if err != nil { return nil, err } return &draft, nil } func (r *pgRepository) GetByRMSInvoiceID(rmsInvoiceID uuid.UUID) (*drafts.DraftInvoice, error) { var draft drafts.DraftInvoice err := r.db. Where("rms_invoice_id = ?", rmsInvoiceID). First(&draft).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, nil } return nil, err } return &draft, nil } func (r *pgRepository) Update(draft *drafts.DraftInvoice) error { return r.db.Model(draft).Updates(map[string]interface{}{ "status": draft.Status, "document_number": draft.DocumentNumber, "incoming_document_number": draft.IncomingDocumentNumber, "date_incoming": draft.DateIncoming, "supplier_id": draft.SupplierID, "store_id": draft.StoreID, "comment": draft.Comment, "rms_invoice_id": draft.RMSInvoiceID, "rms_server_id": draft.RMSServerID, "updated_at": gorm.Expr("NOW()"), }).Error } func (r *pgRepository) CreateItems(items []drafts.DraftInvoiceItem) error { if len(items) == 0 { return nil } return r.db.CreateInBatches(items, 100).Error } func (r *pgRepository) CreateItem(item *drafts.DraftInvoiceItem) error { return r.db.Create(item).Error } func (r *pgRepository) DeleteItem(itemID uuid.UUID) error { return r.db.Delete(&drafts.DraftInvoiceItem{}, itemID).Error } // GetItemByID - новый метод func (r *pgRepository) GetItemByID(itemID uuid.UUID) (*drafts.DraftInvoiceItem, error) { var item drafts.DraftInvoiceItem err := r.db.Where("id = ?", itemID).First(&item).Error if err != nil { return nil, err } return &item, nil } // UpdateItem - обновленный метод, принимает map func (r *pgRepository) UpdateItem(itemID uuid.UUID, updates map[string]interface{}) error { return r.db.Model(&drafts.DraftInvoiceItem{}). Where("id = ?", itemID). Updates(updates).Error } // UpdateItemOrder обновляет порядок позиции func (r *pgRepository) UpdateItemOrder(itemID uuid.UUID, newOrder int) error { return r.db.Model(&drafts.DraftInvoiceItem{}). Where("id = ?", itemID). Update("order", newOrder).Error } // ReorderItems обновляет порядок нескольких элементов в одной транзакции func (r *pgRepository) ReorderItems(draftID uuid.UUID, items []struct { ID uuid.UUID Order int }) error { return r.db.Transaction(func(tx *gorm.DB) error { for _, item := range items { // Проверяем, что элемент принадлежит указанному черновику var count int64 if err := tx.Model(&drafts.DraftInvoiceItem{}). Where("id = ? AND draft_id = ?", item.ID, draftID). Count(&count).Error; err != nil { return err } if count == 0 { return fmt.Errorf("элемент с id %s не принадлежит черновику %s", item.ID.String(), draftID.String()) } // Обновляем только колонку order if err := tx.Model(&drafts.DraftInvoiceItem{}). Where("id = ?", item.ID). Update("order", item.Order).Error; err != nil { return err } } return nil }) } func (r *pgRepository) Delete(id uuid.UUID) error { return r.db.Delete(&drafts.DraftInvoice{}, id).Error } func (r *pgRepository) GetActive(serverID uuid.UUID) ([]drafts.DraftInvoice, error) { var list []drafts.DraftInvoice activeStatuses := []string{ drafts.StatusProcessing, drafts.StatusReadyToVerify, drafts.StatusError, drafts.StatusCanceled, } err := r.db. Preload("Items"). Preload("Store"). Where("rms_server_id = ? AND status IN ?", serverID, activeStatuses). Order("created_at DESC"). Find(&list).Error return list, err } func (r *pgRepository) GetLinkedDraftsMap(serverID uuid.UUID) (map[uuid.UUID]drafts.LinkedDraftInfo, error) { var draftsList []drafts.DraftInvoice err := r.db. Select("id", "rms_invoice_id", "sender_photo_url"). Where("rms_server_id = ? AND rms_invoice_id IS NOT NULL", serverID). Find(&draftsList).Error if err != nil { return nil, err } result := make(map[uuid.UUID]drafts.LinkedDraftInfo) for _, d := range draftsList { if d.RMSInvoiceID != nil { result[*d.RMSInvoiceID] = drafts.LinkedDraftInfo{ DraftID: d.ID, PhotoURL: d.SenderPhotoURL, } } } return result, nil }