dana-medical-site/internal/api/clinics.go
2026-10-14 13:33:13 +00:00

119 lines
4.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"net/http"
"regexp"
"strings"
"dana/internal/megafon"
"dana/internal/storage"
)
// Клиники, для которых считаются «Отчёт по каналам», дашборд и звонки АТС. DANA — основная:
// все данные, загруженные до разделения, относятся к ней. «Очевидно» — вторая компания в том же
// Битрикс24 со своей АТС МегаФон, своими номерами и своими кабинетами площадок.
const clinicDANA = "dana"
type clinicDef struct {
Key string `json:"key"`
Title string `json:"title"`
// ПроДокторов: в строке 1 выгрузки — название клиники; файл чужого кабинета отклоняется.
prodoctorovRE *regexp.Regexp
prodoctorovName string
// Битрикс24: источник лида (SOURCE_ID) → канал отчёта; белый список для каждой клиники.
bitrixSources map[string]string
bitrixGeneral map[string]bool // общая линия без рекламного канала — в «все номера»
// Контакты Битрикса без источника идут в «все номера». Портал общий, контакты не делятся
// по клиникам, поэтому так считает только DANA (как и до разделения).
bitrixContacts bool
// Автовыгрузка ПроДокторова и СберЗдоровья с сервера настроена на кабинеты DANA.
partnerCabinets bool
}
// bitrixOchevidnoSources — источники лидов «Очевидно» в общем Битрикс24 (crm.status.list, SOURCE).
var bitrixOchevidnoSources = map[string]string{
"145|FBINSTAGRAMDIRECT": "инстаграмм",
"151": "инстаграмм", // WhatsApp 530-00-77: заявки приходят из инстаграма (как у DANA 047-00-55)
"174": "max",
"167": "сайт", "111|PACT_WHATSAPP_CONNECTOR_104167": "сайт", "173": "сайт",
"172": "баннера и маршрутки",
"165": "2гис", "169": "2гис",
"164": "яндекс", "168": "яндекс",
"170": "продокторов", "175": "продокторов",
"153": "напоправку",
"171": "сберздоровье",
"152": "zoon",
}
var clinicList = []*clinicDef{
{
Key: clinicDANA, Title: "DANA",
prodoctorovRE: regexp.MustCompile(`(?i)дана|dana`), prodoctorovName: "Дана Медикал",
bitrixSources: bitrixChannelBySource, bitrixGeneral: bitrixGeneralSources,
bitrixContacts: true, partnerCabinets: true,
},
{
Key: "ochevidno", Title: "Очевидно",
prodoctorovRE: regexp.MustCompile(`(?i)очевидно`), prodoctorovName: "Очевидно",
bitrixSources: bitrixOchevidnoSources,
// звонки на основной номер 530-00-77 — колл-центр без рекламного канала (как у DANA 047-00-55)
bitrixGeneral: map[string]bool{"150": true},
},
}
var clinicByKey = func() map[string]*clinicDef {
m := make(map[string]*clinicDef, len(clinicList))
for _, c := range clinicList {
m[c.Key] = c
}
return m
}()
// clinicFrom — клиника из параметра запроса; пусто — DANA, как было до разделения.
func clinicFrom(v string) (*clinicDef, bool) {
v = strings.ToLower(strings.TrimSpace(v))
if v == "" {
return clinicByKey[clinicDANA], true
}
c, ok := clinicByKey[v]
return c, ok
}
// requestClinic читает ?clinic= (или поле формы) и отвечает 400 на неизвестную клинику.
func requestClinic(w http.ResponseWriter, r *http.Request) (*clinicDef, bool) {
c, ok := clinicFrom(r.FormValue("clinic"))
if !ok {
fail(w, http.StatusBadRequest, "bad_request", "Неизвестная клиника")
}
return c, ok
}
// WithClinicPBX подключает АТС второй клиники. АТС DANA — WithPBX.
func (a *API) WithClinicPBX(clinic string, c *megafon.Client) {
if clinic == clinicDANA {
a.pbx = c
return
}
if a.pbxClinics == nil {
a.pbxClinics = map[string]*megafon.Client{}
}
a.pbxClinics[clinic] = c
}
// pbxFor — АТС клиники; nil, если не подключена (Configured() у nil — false).
func (a *API) pbxFor(clinic string) *megafon.Client {
if clinic == clinicDANA || clinic == "" {
return a.pbx
}
return a.pbxClinics[clinic]
}
func (a *API) adminClinics(w http.ResponseWriter, r *http.Request, u *storage.AdminUser) {
out := make([]map[string]any, 0, len(clinicList))
for _, c := range clinicList {
out = append(out, map[string]any{"key": c.Key, "title": c.Title, "pbx": a.pbxFor(c.Key).Configured()})
}
ok(w, out, nil)
}