2026-03-12 22:03:51 +03:00
|
|
|
package merch
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"database/sql"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Labels interface {
|
|
|
|
|
createLabel(ctx context.Context, userId int64, label *Label) error
|
2026-03-13 16:52:39 +03:00
|
|
|
getLabels(ctx context.Context, userId int64) ([]LabelsList, error)
|
2026-03-12 22:03:51 +03:00
|
|
|
updateLabel(ctx context.Context, userId int64, label *Label) error
|
|
|
|
|
deleteLabel(ctx context.Context, userId int64, labelUuid string, now sql.NullTime) error
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
attachLabel(ctx context.Context, userId int64, label *LabelLink) error
|
|
|
|
|
detachLabel(ctx context.Context, userId int64, label *LabelLink) error
|
2026-03-12 22:03:51 +03:00
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
getManyAttachedLabelsByList(ctx context.Context, userId int64, list []int64) (map[int64][]string, error)
|
2026-03-12 22:03:51 +03:00
|
|
|
getAttachedLabelsByUuid(ctx context.Context, userId int64, merchUuid string) ([]string, error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *repo) createLabel(ctx context.Context, userId int64, l *Label) error {
|
|
|
|
|
q := `
|
|
|
|
|
INSERT INTO labels (created_at, updated_at, deleted_at, user_id, uuid, name, color, bg_color)
|
|
|
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
|
|
|
`
|
|
|
|
|
_, err := r.db.Exec(ctx, q, l.CreatedAt, l.UpdatedAt, l.DeletedAt, userId, l.Uuid, l.Name, l.Color, l.BgColor)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
func (r *repo) getLabels(ctx context.Context, userId int64) ([]LabelsList, error) {
|
2026-03-12 22:03:51 +03:00
|
|
|
q := `
|
|
|
|
|
SELECT uuid, name, color, bg_color
|
|
|
|
|
FROM labels
|
|
|
|
|
WHERE user_id = $1
|
|
|
|
|
AND deleted_at IS NULL
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
rows, err := r.db.Query(ctx, q, userId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
var labels []LabelsList
|
2026-03-12 22:03:51 +03:00
|
|
|
for rows.Next() {
|
2026-03-13 16:52:39 +03:00
|
|
|
var l LabelsList
|
|
|
|
|
if err = rows.Scan(&l.LabelUuid, &l.Name, &l.Color, &l.BgColor); err != nil {
|
2026-03-12 22:03:51 +03:00
|
|
|
rows.Close()
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
labels = append(labels, l)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows.Close()
|
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return labels, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *repo) updateLabel(ctx context.Context, userId int64, l *Label) error {
|
|
|
|
|
q := `
|
2026-03-13 16:52:39 +03:00
|
|
|
UPDATE labels
|
|
|
|
|
SET
|
|
|
|
|
updated_at = $1,
|
|
|
|
|
name = COALESCE(NULLIF($2, ''), labels.name),
|
|
|
|
|
color = COALESCE(NULLIF($3, ''), labels.color),
|
|
|
|
|
bg_color = COALESCE(NULLIF($4, ''), labels.bg_color)
|
|
|
|
|
WHERE uuid = $5
|
|
|
|
|
AND user_id = $6;
|
|
|
|
|
`
|
2026-03-12 22:03:51 +03:00
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
_, err := r.db.Exec(ctx, q, l.UpdatedAt, l.Name, l.Color, l.BgColor, l.Uuid, userId)
|
2026-03-12 22:03:51 +03:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *repo) deleteLabel(ctx context.Context, userId int64, labelUuid string, now sql.NullTime) error {
|
|
|
|
|
q := `UPDATE labels SET deleted_at = &1 WHERE user_id = $2 AND uuid = $3`
|
|
|
|
|
_, err := r.db.Exec(ctx, q, now, userId, labelUuid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
func (r *repo) attachLabel(ctx context.Context, userId int64, label *LabelLink) error {
|
2026-03-12 22:03:51 +03:00
|
|
|
q := `
|
|
|
|
|
INSERT INTO card_labels (user_id, label_id, merch_id)
|
|
|
|
|
VALUES ($1, (SELECT id FROM labels WHERE uuid = $2), (SELECT id FROM merch WHERE merch_uuid = $3 AND user_id = $1))
|
|
|
|
|
`
|
|
|
|
|
_, err := r.db.Exec(ctx, q, userId, label.LabelUuid, label.MerchUuid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
func (r *repo) detachLabel(ctx context.Context, userId int64, label *LabelLink) error {
|
2026-03-12 22:03:51 +03:00
|
|
|
q := `
|
|
|
|
|
DELETE FROM card_labels
|
|
|
|
|
WHERE user_id = $1
|
|
|
|
|
AND label_id = (SELECT id FROM labels WHERE uuid = $2)
|
|
|
|
|
AND merch_id = (SELECT id FROM merch WHERE merch_uuid = $3 AND user_id = $1)
|
|
|
|
|
`
|
|
|
|
|
_, err := r.db.Exec(ctx, q, userId, label.LabelUuid, label.MerchUuid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
func (r *repo) getManyAttachedLabelsByList(ctx context.Context, userId int64, list []int64) (map[int64][]string, error) {
|
2026-03-12 22:03:51 +03:00
|
|
|
q := `
|
|
|
|
|
SELECT l.uuid, cl.merch_id
|
|
|
|
|
FROM card_labels AS cl
|
|
|
|
|
JOIN labels AS l ON cl.label_id = l.id
|
|
|
|
|
WHERE cl.user_id = $1
|
|
|
|
|
AND cl.merch_id = ANY($2)
|
|
|
|
|
AND l.deleted_at IS NULL
|
|
|
|
|
`
|
|
|
|
|
rows, err := r.db.Query(ctx, q, userId, list)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-13 16:52:39 +03:00
|
|
|
cardLabelsMap := make(map[int64][]string)
|
2026-03-12 22:03:51 +03:00
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
|
var (
|
|
|
|
|
merchId int64
|
|
|
|
|
labelUuid string
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if err = rows.Scan(&labelUuid, &merchId); err != nil {
|
|
|
|
|
rows.Close()
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2026-03-13 16:52:39 +03:00
|
|
|
cardLabelsMap[merchId] = append(cardLabelsMap[merchId], labelUuid)
|
2026-03-12 22:03:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rows.Close()
|
|
|
|
|
if err = rows.Err(); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cardLabelsMap, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (r *repo) getAttachedLabelsByUuid(ctx context.Context, userId int64, merchUuid string) ([]string, error) {
|
|
|
|
|
q := `
|
|
|
|
|
SELECT l.uuid
|
|
|
|
|
FROM card_labels AS cl
|
|
|
|
|
JOIN labels AS l ON cl.label_id = l.id
|
|
|
|
|
WHERE cl.merch_id = (SELECT id FROM merch WHERE merch_uuid = $2 AND user_id = $1 AND deleted_at IS NULL)
|
|
|
|
|
AND cl.user_id = $1
|
|
|
|
|
AND l.deleted_at IS NULL
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
rows, err := r.db.Query(ctx, q, userId, merchUuid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var labels []string
|
|
|
|
|
for rows.Next() {
|
|
|
|
|
var label string
|
|
|
|
|
if err = rows.Scan(&label); err != nil {
|
|
|
|
|
rows.Close()
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
labels = append(labels, label)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return labels, nil
|
|
|
|
|
}
|