fix: регистронезависимый поиск lot_name и удаление мёртвого кода
- SQLite-запросы по lot_name теперь используют UPPER(lot_name) IN/= для совместимости с легаси-данными, синхронизированными до нормализации регистра - Удалена таблица local_components и весь связанный код синхронизации; источник данных для компонентов — local_pricelist_items - Удалена функция getCategoryFromLotName из JS: категория берётся только из прайслиста, без инференса из имени лота - Регистронезависимые сравнения lot_name в JS (warehouse stock set, addedLots, cartLots, allComponents.find, _bomLotValid) - В support bundle добавлены: latest_pricelist_items.json, local.db, autocomplete_lots.json для диагностики Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -404,6 +404,7 @@ func (s *Service) syncPricelists() (int, error) {
|
||||
CreatedAt: pl.CreatedAt,
|
||||
SyncedAt: time.Now(),
|
||||
IsUsed: false,
|
||||
IsActive: true,
|
||||
}
|
||||
|
||||
itemCount, err := s.syncNewPricelistSnapshot(localPL)
|
||||
@@ -426,6 +427,12 @@ func (s *Service) syncPricelists() (int, error) {
|
||||
slog.Info("deleted stale local pricelists", "deleted", removed)
|
||||
}
|
||||
|
||||
// Mirror server-side deactivations: any local pricelist not in the current active set
|
||||
// is marked is_active=false so offline lookups skip it.
|
||||
if err := s.localDB.DeactivateLocalPricelistsNotIn(serverPricelistIDs); err != nil {
|
||||
slog.Warn("failed to deactivate stale local pricelists", "error", err)
|
||||
}
|
||||
|
||||
// Backfill lot_category for used pricelists (older local caches may miss the column values).
|
||||
s.backfillUsedPricelistItemCategories(pricelistRepo, serverPricelistIDs)
|
||||
|
||||
@@ -1638,24 +1645,3 @@ func (s *Service) getConnectionStatus() db.ConnectionStatus {
|
||||
return s.connMgr.GetStatus()
|
||||
}
|
||||
|
||||
// SyncComponentsIfEmpty syncs components from MariaDB when local_components is empty.
|
||||
// Used by the background worker on first run to populate the catalog for new users.
|
||||
func (s *Service) SyncComponentsIfEmpty() error {
|
||||
if s.localDB.CountComponents() > 0 {
|
||||
return nil
|
||||
}
|
||||
mariaDB, err := s.getDB()
|
||||
if err != nil {
|
||||
_ = s.localDB.SetComponentSyncResult("error", err.Error(), time.Now())
|
||||
return err
|
||||
}
|
||||
result, err := s.localDB.SyncComponents(mariaDB)
|
||||
now := time.Now()
|
||||
if err != nil {
|
||||
_ = s.localDB.SetComponentSyncResult("error", err.Error(), now)
|
||||
return err
|
||||
}
|
||||
_ = s.localDB.SetComponentSyncResult("ok", "", now)
|
||||
slog.Info("background sync: initial component sync completed", "synced", result.TotalSynced)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -80,11 +80,6 @@ func (w *Worker) runSync() {
|
||||
return
|
||||
}
|
||||
|
||||
// Populate component catalog on first run (empty local_components)
|
||||
if err := w.service.SyncComponentsIfEmpty(); err != nil {
|
||||
w.logger.Warn("background sync: initial component sync failed", "error", err)
|
||||
}
|
||||
|
||||
// Push pending changes first
|
||||
pushed, err := w.service.PushPendingChanges()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user