Первичная настройка, часть 1: префикс торгового счёта DEPO — настройка с подсказкой по учёту (был зашит «ВТНКЦ» в 7 запросах); шаг 8 — адрес ИШ вместо ONYX, профили prod-gost/prod-rsa (пункт prod уводил bj в имитацию), без неиспользуемого контейнера, перезапуск bj после смены контура; реквизиты НРД на шаге 4; точная проверка процедур bj2depo и таблиц Fancy M2M; QUIK — объекты M2M и справочник получателей, без зашитого IP; сертификаты из справочника ИШ (FindCertificates — заглушка), уведомления о сроке за 30/14/7/3/1 день; тексты мастера, нумерация, режим разработки; уникальные id оповещений с русскими заголовками

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-05 16:04:43 +03:00
parent 9360543589
commit fdf0ddd498
37 changed files with 807 additions and 129 deletions
+41 -3
View File
@@ -218,7 +218,7 @@ func depoUpsertOrder(rc *RuntimeConfig, guid, direction, cpCode, deponentName, d
// ранний (то же правило, что при зачислении в QUIK); джоба по номеру находит OD_CLIENTS.ID (DEPO).
var clientAcc sql.NullString
if serN != "" && strings.TrimSpace(num) != "" {
_ = db.QueryRowContext(ctx, fsql.Ev03,
_ = db.QueryRowContext(ctx, accSQL(fsql.Ev03),
sql.Named("s", serN), sql.Named("n", strings.TrimSpace(num))).Scan(&clientAcc)
}
hasDepoNumber := depoHasColumn(ctx, db, "FTV_M2M_LINES", "DEPO_NUMBER")
@@ -958,6 +958,9 @@ func depoProcCheck(ctx context.Context, rc *RuntimeConfig) (string, bool) {
if !depoTableExists(ctx, db, "FTV_M2M_EVENTS") {
return "в базе " + f.DepoDB() + " нет таблиц FTV_M2M*", false
}
if msg := depoObjectsMissing(ctx, db, f); msg != "" {
return msg, false
}
if ok, msg := depoRunAsCheck(ctx, db, f); !ok {
return msg, false
}
@@ -1215,7 +1218,7 @@ func depoSimulateIncoming(ctx context.Context, rc *RuntimeConfig, it *IncomingTr
serN := strings.ReplaceAll(strings.TrimSpace(ser), " ", "")
numN := strings.TrimSpace(num)
var name string
if err := db.QueryRowContext(ctx, fsql.Ev11, sql.Named("s", serN), sql.Named("n", numN)).Scan(&name); err != nil {
if err := db.QueryRowContext(ctx, accSQL(fsql.Ev11), sql.Named("s", serN), sql.Named("n", numN)).Scan(&name); err != nil {
return "", fmt.Errorf("клиент с паспортом %s %s и открытым торговым счётом в DEPO не найден", ser, num)
}
guid := strings.ToUpper(fmt.Sprintf("%08x-%04x-4000-8000-%012x", time.Now().Unix()&0xFFFFFFFF, time.Now().UnixNano()&0xFFFF, time.Now().UnixNano()&0xFFFFFFFFFFFF))
@@ -1284,7 +1287,7 @@ func depoSimulateOutgoing(ctx context.Context, rc *RuntimeConfig, svc *Service,
serN := strings.ReplaceAll(strings.TrimSpace(ser), " ", "")
numN := strings.TrimSpace(num)
var name string
if err := db.QueryRowContext(ctx, fsql.Ev11, sql.Named("s", serN), sql.Named("n", numN)).Scan(&name); err != nil {
if err := db.QueryRowContext(ctx, accSQL(fsql.Ev11), sql.Named("s", serN), sql.Named("n", numN)).Scan(&name); err != nil {
return "", fmt.Errorf("клиент с паспортом %s %s и открытым торговым счётом в DEPO не найден", ser, num)
}
req := d.Request
@@ -1400,3 +1403,38 @@ func mapInt(m map[string]any, k string) int64 {
}
return 0
}
// Объекты в базе DEPO, без которых обработка событий не работает: таблицы Fancy с поддержкой M2M и
// процедуры расширения bj2depo (deploy/depo/fancy-m2m). Проверяются по имени сразу — без 40-секундного
// ожидания BJ_PING и без общего «не обработано».
var (
depoFancyM2MTables = []string{"D_CLISER_M2M", "D_CLISER_M2M_DOL", "OD_M2M_ACCS", "OD_ONLINE_M2M_DEPO"}
depoBj2depoProcs = []string{"FTV_M2M_JOB", "FTV_M2M_PROCESS_CREATE", "FTV_M2M_PROCESS_EVENTS", "FTV_M2M_PROCESS_OPERATION", "FTV_M2M_PROCESS_WIRING"}
)
func depoObjectsMissing(ctx context.Context, db *sql.DB, f FancyMSSQLSettings) string {
if f.IsPostgres() {
return ""
}
missing := func(names []string, typ string) []string {
var out []string
for _, n := range names {
var ok int
if err := db.QueryRowContext(ctx, "SELECT CASE WHEN OBJECT_ID(@n, @t) IS NULL THEN 0 ELSE 1 END", sql.Named("n", "dbo."+n), sql.Named("t", typ)).Scan(&ok); err == nil && ok == 0 {
out = append(out, n)
}
}
return out
}
if m := missing(depoFancyM2MTables, "U"); len(m) > 0 {
return "в базе " + f.DepoDB() + " нет таблиц Fancy DEPO с поддержкой M2M (" + strings.Join(m, ", ") + "): нужна версия Fancy DEPO с M2M — обратитесь к разработчику Fancy"
}
procs := depoBj2depoProcs
if p := strings.TrimSpace(f.DepoJobProc); p != "" && !strings.EqualFold(strings.TrimPrefix(p, "dbo."), "FTV_M2M_JOB") {
procs = []string{strings.TrimPrefix(p, "dbo.")} // своя процедура обработки — проверяем только её
}
if m := missing(procs, "P"); len(m) > 0 {
return "в базе " + f.DepoDB() + " нет процедур обработки bj2depo: " + strings.Join(m, ", ") + ". Их нужно установить в базу DEPO (порядок: WIRING → OPERATION → EVENTS → CREATE → JOB), затем — «Перепроверить всё»"
}
return ""
}