0202-финиш перед десктопом

пересчет поправил
редактирование с перепроведением
галка автопроведения работает
рекомендации починил
This commit is contained in:
2026-02-02 13:53:38 +03:00
parent 10882f55c8
commit 88620f3fb6
37 changed files with 1905 additions and 11162 deletions

View File

@@ -4,6 +4,7 @@ import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// Роли пользователей
@@ -75,6 +76,14 @@ type RMSServer struct {
// Stats
InvoiceCount int `gorm:"default:0" json:"invoice_count"`
// Sync settings
SyncInterval int `gorm:"default:360" json:"sync_interval"` // Интервал синхронизации в минутах (default: 6 часов)
LastSyncAt *time.Time `json:"last_sync_at"` // Время последней успешной синхронизации
LastActivityAt *time.Time `json:"last_activity_at"` // Время последнего действия пользователя
// Soft delete
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
@@ -134,4 +143,12 @@ type Repository interface {
// SetMuteDraftNotifications включает/выключает уведомления для пользователя
SetMuteDraftNotifications(userID, serverID uuid.UUID, mute bool) error
// === Синхронизация и активность ===
// UpdateLastActivity обновляет время последней активности пользователя на сервере
UpdateLastActivity(serverID uuid.UUID) error
// UpdateLastSync обновляет время последней успешной синхронизации
UpdateLastSync(serverID uuid.UUID) error
// GetServersForSync возвращает серверы, готовые для синхронизации
GetServersForSync(idleThreshold time.Duration) ([]RMSServer, error)
}

View File

@@ -82,6 +82,12 @@ type DraftInvoiceItem struct {
IsMatched bool `gorm:"default:false" json:"is_matched"`
}
// LinkedDraftInfo содержит информацию о связанном черновике
type LinkedDraftInfo struct {
DraftID uuid.UUID
PhotoURL string
}
type Repository interface {
Create(draft *DraftInvoice) error
GetByID(id uuid.UUID) (*DraftInvoice, error)
@@ -102,6 +108,6 @@ type Repository interface {
// GetActive возвращает активные черновики для СЕРВЕРА (а не юзера)
GetActive(serverID uuid.UUID) ([]DraftInvoice, error)
// GetRMSInvoiceIDToPhotoURLMap возвращает мапу rms_invoice_id -> sender_photo_url для сервера, где rms_invoice_id не NULL
GetRMSInvoiceIDToPhotoURLMap(serverID uuid.UUID) (map[uuid.UUID]string, error)
// GetLinkedDraftsMap возвращает мапу rms_invoice_id -> LinkedDraftInfo для сервера, где rms_invoice_id не NULL
GetLinkedDraftsMap(serverID uuid.UUID) (map[uuid.UUID]LinkedDraftInfo, error)
}

View File

@@ -47,4 +47,5 @@ type Repository interface {
GetByPeriod(serverID uuid.UUID, from, to time.Time) ([]Invoice, error)
SaveInvoices(invoices []Invoice) error
CountRecent(serverID uuid.UUID, days int) (int64, error)
GetStats(serverID uuid.UUID) (total int64, lastMonth int64, last24h int64, err error)
}

View File

@@ -19,6 +19,7 @@ const (
// Recommendation - Результат анализа
type Recommendation struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
RMSServerID uuid.UUID `gorm:"type:uuid;not null;index"`
Type string `gorm:"type:varchar(50);index"`
ProductID uuid.UUID `gorm:"type:uuid;index"`
ProductName string `gorm:"type:varchar(255)"`
@@ -29,15 +30,15 @@ type Recommendation struct {
// Repository отвечает за аналитические выборки и хранение результатов
type Repository interface {
// Методы анализа (возвращают список структур, но не пишут в БД)
FindUnusedGoods() ([]Recommendation, error)
FindNoIncomingIngredients(days int) ([]Recommendation, error)
FindStaleGoods(days int) ([]Recommendation, error)
FindDishesInRecipes() ([]Recommendation, error)
FindPurchasedButUnused(days int) ([]Recommendation, error)
FindUsageWithoutPurchase(days int) ([]Recommendation, error)
// Методы анализа — добавить serverID
FindUnusedGoods(serverID uuid.UUID) ([]Recommendation, error)
FindNoIncomingIngredients(serverID uuid.UUID, days int) ([]Recommendation, error)
FindStaleGoods(serverID uuid.UUID, days int) ([]Recommendation, error)
FindDishesInRecipes(serverID uuid.UUID) ([]Recommendation, error)
FindPurchasedButUnused(serverID uuid.UUID, days int) ([]Recommendation, error)
FindUsageWithoutPurchase(serverID uuid.UUID, days int) ([]Recommendation, error)
// Методы "Кэша" в БД
SaveAll(items []Recommendation) error // Удаляет старые и пишет новые
GetAll() ([]Recommendation, error)
// Методы хранения — добавить serverID
SaveAll(serverID uuid.UUID, items []Recommendation) error
GetAll(serverID uuid.UUID) ([]Recommendation, error)
}