Compare commits

...

67 Commits

Author SHA1 Message Date
1bc243df2c gen sqlc 2025-11-21 15:29:52 +00:00
97b7fff0eb fixquerybitrix GetUsersBitrixWithPagination 2025-11-21 15:29:52 +00:00
51d9fabbb0 Merge branch 'yclients' 2025-11-17 22:45:11 +03:00
b91f57578e move yclients migration 2025-11-17 22:43:30 +03:00
3c4b860f40 upd 2025-11-14 14:45:40 +03:00
b9efa4544a upd 2025-11-14 14:40:52 +03:00
a6fe7405db upd 2025-11-14 14:39:57 +03:00
51b9acfc84 change types some columns in table YclientsServices 2025-11-14 14:20:40 +03:00
d439003980 added new migrate files 2025-11-14 13:38:09 +03:00
3662219614 - 2025-11-14 13:03:47 +03:00
d191b6524b - 2025-11-14 13:02:54 +03:00
ebca62c890 - 2025-11-14 13:00:27 +03:00
dcbc77ca4f added new db method GetAllYclientsAccounts 2025-11-14 12:11:05 +03:00
6a3f41120c added new db method GetAllYclientsAccounts 2025-11-14 12:08:16 +03:00
9a7a360c23 drop table yclients token 2025-11-14 11:58:35 +03:00
41b9c3d846 fix 28 migration files errors 2025-11-03 12:10:37 +03:00
a2b9462ebf added new method SaveDealYclientsStatus 2025-10-28 18:17:14 +03:00
1d0b0c8b4c added method GetQuestionListByQuizID 2025-10-28 17:36:37 +03:00
809c5e9c74 - 2025-10-28 17:16:31 +03:00
03e80715c0 - 2025-10-28 17:02:12 +03:00
e600a4888a added method GettingYclientsUsersTrueResults 2025-10-28 16:35:42 +03:00
5d4453a673 added method for update fields rule 2025-10-28 15:20:39 +03:00
ea584c78dc change type YclientsFieldRule 2025-10-28 14:54:31 +03:00
ef0b3d81dc - 2025-10-27 18:53:01 +03:00
35a7666a01 - 2025-10-27 18:42:46 +03:00
d8bca9064e added repo methods for custom fields 2025-10-27 18:41:45 +03:00
ada3f3c47f - 2025-10-27 18:06:51 +03:00
704d08ed0c added table YclientsFields 2025-10-27 18:00:39 +03:00
14d08909a7 added new field in table YclientsRules 2025-10-27 17:39:40 +03:00
f1da78811b added new field in table YclientsRules 2025-10-27 17:33:35 +03:00
3af23cc4d3 added types custom yclients fields 2025-10-27 15:45:30 +03:00
cf81806650 add index for exclusive yclients rules 2025-10-27 15:28:33 +03:00
08ce39d8a8 added methods for add and update yclients rules 2025-10-27 15:16:16 +03:00
fcc4921df4 - 2025-10-21 15:42:22 +03:00
2e872e27d2 added new rerpo method - GettingQuizRules 2025-10-21 15:39:36 +03:00
d661c9039a added new table YclientsRules 2025-10-21 14:54:06 +03:00
bed92de45e - 2025-10-08 15:24:24 +03:00
93f823c41a added method SoftDeleteYclientsAccount 2025-10-08 15:23:18 +03:00
8b1df78c8e upd method DeleteYclientsTimeslots 2025-10-08 13:15:56 +03:00
abea1d7874 upd method AddAccountTimeslots 2025-10-08 13:11:21 +03:00
e32835a232 upd method GetTimeslotsByIDYclients 2025-10-08 13:05:36 +03:00
70941476f2 upd method GetTimeslotsByIDYclients 2025-10-08 12:52:53 +03:00
6a6ab469b0 added method GetTimeslotsByIDYclients 2025-10-08 12:50:14 +03:00
b5e8ef404c added methods UpdateYclientsAccountTimeslots, AddYclientsAccountTimeslots, DeleteYclientsTimeslots 2025-10-08 12:48:13 +03:00
19196aa451 added method GetTimeslotsByIDYclients 2025-10-08 12:12:06 +03:00
24fe283ed2 added method DeleteServices 2025-10-07 16:05:32 +03:00
0b8932fc89 added method AddAccountService 2025-10-07 16:01:47 +03:00
d3235a162f upd table YclientsServices 2025-10-07 15:35:40 +03:00
b0f509bded added method UpdateAccountServices 2025-10-07 15:28:52 +03:00
7d1e1c9ba5 upd table YclientsServices and added method GetAccountServicesByID 2025-10-07 15:17:55 +03:00
e557d9e68d added method DeleteUsers 2025-10-07 13:35:57 +03:00
da5dfd7fdb added method AddAccountUser 2025-10-07 13:31:55 +03:00
a31d045fee added method UpdateAccountUser 2025-10-07 13:21:41 +03:00
319f8d7b4a change table YclientsAccountUsers 2025-10-07 12:39:57 +03:00
437e709ac3 added method GetUserUsersByID 2025-10-07 12:26:37 +03:00
43096217dc added method GetAllYclientsUserToken 2025-10-06 17:18:56 +03:00
a2baabf928 update table YclientsAccounts 2025-10-06 15:18:54 +03:00
425ba10ad4 added method CreateAccount and update table YclientsAccounts 2025-10-06 15:15:57 +03:00
c172584b98 update InsertYclientsTokens 2025-10-06 11:49:57 +03:00
86d8476caf update yclients table,queries,repository methods,models 2025-10-06 11:34:19 +03:00
0f50c86b1a added close method to YclientsDal 2025-09-18 14:46:31 +03:00
f89981e3ad added new yclients question types 2025-09-16 13:25:11 +03:00
01a2eb9aa5 added timeslots table and get timeslots with pagination query 2025-09-16 12:21:39 +03:00
08e1ed9d3b added timeslots table and get timeslots with pagination query 2025-09-16 12:21:26 +03:00
ddb75502e5 added services table and get services with pagination query 2025-09-16 11:39:26 +03:00
fb85656d52 added company table and get company with pagination query 2025-09-16 11:02:38 +03:00
bd515ca881 added yclients dal, yclients company/staff tables and some methods 2025-09-15 17:04:35 +03:00
11 changed files with 2597 additions and 22 deletions

@ -6,20 +6,21 @@ import (
_ "embed"
"errors"
"fmt"
_ "github.com/ClickHouse/clickhouse-go"
_ "github.com/lib/pq"
"github.com/minio/minio-go/v7"
"gitea.pena/SQuiz/common/dal/sqlcgen"
"gitea.pena/SQuiz/common/repository/account"
"gitea.pena/SQuiz/common/repository/amo"
"gitea.pena/SQuiz/common/repository/answer"
"gitea.pena/SQuiz/common/repository/question"
"gitea.pena/SQuiz/common/repository/bitrix"
"gitea.pena/SQuiz/common/repository/question"
"gitea.pena/SQuiz/common/repository/quiz"
"gitea.pena/SQuiz/common/repository/result"
"gitea.pena/SQuiz/common/repository/statistics"
"gitea.pena/SQuiz/common/repository/tg"
"gitea.pena/SQuiz/common/repository/workers"
"gitea.pena/SQuiz/common/repository/yclients"
_ "github.com/ClickHouse/clickhouse-go"
_ "github.com/lib/pq"
"github.com/minio/minio-go/v7"
"time"
)
@ -300,3 +301,72 @@ func NewClickHouseDAL(ctx context.Context, cred string) (*ClickHouseDAL, error)
func (d *ClickHouseDAL) Close(ctx context.Context) error {
return d.conn.Close()
}
type YclientsDal struct {
conn *sql.DB
queries *sqlcgen.Queries
YclientsRepo *yclients.YclientsRepository
QuizRepo *quiz.QuizRepository
QuestionRepo *question.QuestionRepository
AccountRepo *account.AccountRepository
AnswerRepo *answer.AnswerRepository
}
func NewYclientsDal(ctx context.Context, cred string) (*YclientsDal, error) {
pool, err := sql.Open("postgres", cred)
if err != nil {
return nil, err
}
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
if err := pool.PingContext(timeoutCtx); err != nil {
return nil, err
}
queries := sqlcgen.New(pool)
yclientsRepo := yclients.NewYclientsRepository(yclients.Deps{
Queries: queries,
Pool: pool,
})
quizRepo := quiz.NewQuizRepository(quiz.Deps{
Queries: queries,
Pool: pool,
})
questionRepo := question.NewQuestionRepository(question.Deps{
Queries: queries,
Pool: pool,
})
accountRepo := account.NewAccountRepository(account.Deps{
Queries: queries,
Pool: pool,
})
answerRepo := answer.NewAnswerRepository(answer.Deps{
Queries: queries,
Pool: pool,
})
return &YclientsDal{
conn: pool,
queries: queries,
YclientsRepo: yclientsRepo,
QuizRepo: quizRepo,
QuestionRepo: questionRepo,
AccountRepo: accountRepo,
AnswerRepo: answerRepo,
}, nil
}
func (d *YclientsDal) Close(ctx context.Context) error {
err := d.conn.Close()
if err != nil {
return err
}
return nil
}

@ -1167,7 +1167,7 @@ WITH user_data AS (
)
SELECT u.*, COUNT(*) OVER() as total_count
FROM BitrixAccountUsers u
JOIN user_data a ON u.BitrixID = a.BitrixID
JOIN user_data a ON u.AccountID = a.BitrixID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
@ -1493,4 +1493,184 @@ WHERE quiz_id = $1 AND privilege_id = $2;
-- name: ResetQuizPrivilegeUsageCount :exec
UPDATE quiz_privilege_usage SET used_count = 0, updated_at = CURRENT_TIMESTAMP
WHERE quiz_id = $1 AND privilege_id = $2;
WHERE quiz_id = $1 AND privilege_id = $2;
-- Yclients
-- name: GetCurrentYclientsCompany :one
SELECT * FROM YclientsAccounts WHERE AccountID = $1 AND Deleted = false;
-- name: GetUsersYclientsWithPagination :many
WITH user_data AS (
SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1 AND YclientsAccounts.Deleted = false
)
SELECT u.*, COUNT(*) OVER() as total_count
FROM YclientsAccountUsers u
JOIN user_data a ON u.SalonID = a.SalonID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetAllYclientsAccounts :many
SELECT * from YclientsAccounts where Deleted = false;
-- -- name: GetCompanyYclientsWithPagination :many
-- WITH user_data AS (
-- SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1 AND YclientsAccounts.Deleted = false
-- )
-- SELECT u.*, COUNT(*) OVER() as total_count
-- FROM YclientsCompany u
-- JOIN user_data a ON u.SalonID = a.SalonID
-- WHERE u.Deleted = false
-- ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetServicesYclientsWithPagination :many
WITH user_data AS (
SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1 AND YclientsAccounts.Deleted = false
)
SELECT u.*, COUNT(*) OVER() as total_count
FROM YclientsServices u
JOIN user_data a ON u.SalonID = a.SalonID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetTimeslotsYclientsWithPagination :many
WITH user_data AS (
SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1 AND YclientsAccounts.Deleted = false
)
SELECT u.*, COUNT(*) OVER() as total_count
FROM YclientsTimeSlots u
JOIN user_data a ON u.SalonID = a.SalonID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: CreateYclientsAccount :one
insert into YclientsAccounts (AccountID,SalonID,Title) values ($1,$2,$3) RETURNING *;
-- name: GetUsersByIDYclients :many
SELECT * FROM YclientsAccountUsers WHERE SalonID = $1 AND Deleted = false;
-- name: UpdateYclientsAccountUser :exec
UPDATE YclientsAccountUsers SET Name = $3, Specialization = $4, IDPosition = $5, TitlePosition= $6, Fired = $7,Status = $8,Hidden=$9
WHERE SalonID = $1 AND YclientsID = $2 AND deleted = false;
-- name: AddYclientsAccountUser :exec
INSERT INTO YclientsAccountUsers (SalonID, YclientsID, Name, Specialization, IDPosition, TitlePosition,Fired,Status,Hidden,YclientsUserID)
VALUES ($1, $2, $3, $4, $5, $6,$7,$8,$9,$10);
-- name: DeleteYclientsUsers :exec
UPDATE YclientsAccountUsers SET Deleted = true WHERE ID = ANY($1::bigint[]);
-- name: GetServicesByIDYclients :many
SELECT * FROM YclientsServices WHERE SalonID = $1 AND Deleted = false;
-- name: UpdateYclientsAccountServices :exec
UPDATE YclientsServices SET SalonServiceID = $3,Title = $4, CategoryID = $5, PriceMin = $6, PriceMax= $7, Discount = $8,Comment = $9,Active=$10,ApiID=$11,Staff=$12
WHERE SalonID = $1 AND ServiceID = $2 AND deleted = false;
-- name: AddYclientsAccountService :exec
INSERT INTO YclientsServices (SalonID, ServiceID, SalonServiceID, Title, CategoryID, PriceMin,PriceMax,Discount,Comment,Active,ApiID,Staff)
VALUES ($1, $2, $3, $4, $5, $6,$7,$8,$9,$10,$11,$12);
-- name: DeleteYclientsServices :exec
UPDATE YclientsServices SET Deleted = true WHERE ID = ANY($1::bigint[]);
-- name: UpdateYclientsAccountTimeslots :exec
UPDATE YclientsTimeSlots SET IsEnabled = $2,WeekdaysSettings = $3, DatesSettings = $4
WHERE SalonID = $1 AND deleted = false;
-- name: AddYclientsAccountTimeslots :one
INSERT INTO YclientsTimeSlots (SalonID, IsEnabled, WeekdaysSettings, DatesSettings)
VALUES ($1, $2, $3, $4) RETURNING *;
-- name: DeleteYclientsTimeslots :exec
UPDATE YclientsTimeSlots SET Deleted = true WHERE NOT (ID = ANY($1::bigint[]));
-- name: GetTimeslotsByIDYclients :one
SELECT * FROM YclientsTimeSlots WHERE SalonID = $1 AND Deleted = false;
-- name: SoftDeleteYclientsAccount :exec
WITH account_data AS (
UPDATE YclientsAccounts SET Deleted = true WHERE YclientsAccounts.AccountID = $1
),
account_users AS (
UPDATE YclientsAccountUsers SET Deleted = true WHERE SalonID IN (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1)
),
account_services AS (
UPDATE YclientsServices SET Deleted = true WHERE SalonID IN (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1)
),
account_timeslots AS (
UPDATE YclientsTimeSlots SET Deleted = true WHERE SalonID IN (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1)
),
account_rules AS (
UPDATE YclientsRules SET Deleted = true WHERE SalonID IN (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1)
),
account_fields AS (
UPDATE YclientsFields SET Deleted = true WHERE SalonID IN (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1)
)
SELECT 1;
-- name: GetYclientsQuizRule :one
SELECT * FROM YclientsRules WHERE QuizID = $1 AND Deleted = false;
-- name: SetYclientsQuizSettings :one
INSERT INTO YclientsRules (SalonID, QuizID, Services,FieldsRule, CustomColor,StaffID)
SELECT ya.SalonID, $1 AS QuizID, $2 AS Services, $3 AS FieldsRule, $4 AS CustomColor,$6 AS StaffID
FROM YclientsAccounts ya WHERE ya.AccountID = $5 AND ya.Deleted = false
RETURNING id;
-- name: ChangeYclientsQuizSettings :one
UPDATE YclientsRules SET Services = $1, CustomColor = $2,FieldsRule = $3,StaffID=$6
WHERE SalonID = (SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $4 AND YclientsAccounts.Deleted = false)
AND QuizID = $5 AND Deleted = false RETURNING id;
-- name: GetYclientsFieldsWithPagination :many
WITH user_data AS (
SELECT SalonID FROM YclientsAccounts WHERE YclientsAccounts.AccountID = $1 AND YclientsAccounts.Deleted = false
)
SELECT f.*, COUNT(*) OVER() as total_count
FROM YclientsFields f JOIN user_data u ON f.SalonID = u.SalonID
WHERE f.Deleted = false
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: UpdateYclientsAccountFields :exec
UPDATE YclientsFields
SET FieldType = $3,Code = $4,Title = $5,ShowInUI = $6, UserCanEdit = $7
WHERE SalonID = $1 AND YclientsID = $2 AND Deleted = false;
-- name: GetUserYclientsFieldsByID :many
SELECT * FROM YclientsFields WHERE SalonID = $1 AND Deleted = false;
-- name: DeleteYclientsFields :exec
UPDATE YclientsFields SET Deleted = true WHERE ID = ANY($1::bigint[]);
-- name: AddYclientsAccountField :exec
INSERT INTO YclientsFields (YclientsID, SalonID, FieldType, Code, Title, ShowInUI, UserCanEdit)
VALUES ($1, $2, $3, $4, $5, $6, $7);
-- name: UpdateYclientsFieldRules :exec
UPDATE YclientsRules SET FieldsRule = $1
WHERE SalonID = $2 AND QuizID = $3 AND Deleted = false;
-- name: GettingYclientsUsersTrueResults :many
SELECT
a.quiz_id, a.id AS answer_id, a.result,
a.question_id, a.content, a.session,
COALESCE((SELECT a2.utm FROM answer a2 WHERE a2.start = true AND a2.session = a.session LIMIT 1), '{}'::jsonb) AS utm,
r.salonid, r.fieldsrule, r.staffid, r.services,
r.customcolor, u.accountid AS quiz_accountid,
a.created_at as datetime -- добавляем время result ответа
FROM answer a
INNER JOIN quiz q ON a.quiz_id = q.id
LEFT JOIN yclientscrmstatuses s ON a.id = s.AnswerID
INNER JOIN yclientsrules r ON q.id = r.QuizID
INNER JOIN yclientsaccounts u ON q.accountid = u.accountid AND r.salonid = u.salonid
WHERE a.result = true AND s.id IS NULL AND a.deleted = false
AND r.deleted = false AND q.deleted = false
AND u.deleted = false;
-- name: GetQuestionListByQuizID :many
SELECT * from question where quiz_id=$1 and deleted = false;
-- name: SaveDealYclientsStatus :exec
INSERT INTO YclientsCRMStatuses (SalonID, RecordID, AnswerID, Status)
values ($4, $1, $2, $3);

@ -0,0 +1,12 @@
DROP TABLE If EXISTS YclientsTokens;
DROP TABLE If EXISTS YclientsAccounts;
DROP TABLE If EXISTS YclientsAccountUsers;
-- DROP TABLE If EXISTS YclientsCompany;
DROP TABLE If EXISTS YclientsServices;
DROP TABLE If EXISTS YclientsTimeSlots;
DROP TABLE If EXISTS YclientsRules;
DROP TABLE If EXISTS YclientsFields;
DROP TABLE If EXISTS YclientsCRMStatuses;
DROP INDEX if EXISTS idx_unique_tokens_yclients;
DROP INDEX if EXISTS idx_unique_yclients_rules;

@ -0,0 +1,157 @@
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'CustomFieldsTypeYclients') THEN
CREATE TYPE CustomFieldsTypeYclients AS ENUM (
'text',
'number',
'select',
'date',
'datetime'
);
END IF;
END $$;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_enum
WHERE enumlabel = 'yclients_staff_id' AND enumtypid = 'question_type'::regtype
) THEN
ALTER TYPE question_type ADD VALUE 'yclients_staff_id';
END IF;
END $$;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_enum
WHERE enumlabel = 'yclients_services' AND enumtypid = 'question_type'::regtype
) THEN
ALTER TYPE question_type ADD VALUE 'yclients_services';
END IF;
END $$;
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_enum
WHERE enumlabel = 'yclients_comment' AND enumtypid = 'question_type'::regtype
) THEN
ALTER TYPE question_type ADD VALUE 'yclients_comment';
END IF;
END $$;
CREATE TABLE IF NOT EXISTS YclientsTokens (
AccountID VARCHAR(30) PRIMARY KEY,
SalonID int not null, -- ID компании
AccessToken TEXT NOT NULL DEFAULT '',
Active BOOLEAN NOT NULL DEFAULT FALSE,
Expiration BOOLEAN NOT NULL DEFAULT FALSE, -- флаг истек ли токен
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
create UNIQUE INDEX idx_unique_tokens_yclients ON YclientsTokens (SalonID, AccountID) WHERE Active = true and Expiration = false;
CREATE TABLE IF NOT EXISTS YclientsAccounts (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
AccountID VARCHAR(30) NOT NULL DEFAULT '', -- ID аккаунта у нас
SalonID INT NOT NULL, -- ID компании
Title text NOT NULL DEFAULT '',
ShortDecription text NOT NULL DEFAULT '',
Country VARCHAR(50) NOT NULL DEFAULT '',
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS YclientsAccountUsers (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
SalonID INT NOT NULL, -- ID компании
YclientsID INT NOT NULL, -- ID пользователя в Yclients
Name VARCHAR(512) NOT NULL DEFAULT '',
Specialization text NOT NULL DEFAULT '',
IDPosition int not null default 0,
TitlePosition text not null default 0,
Fired BOOLEAN not null default false, -- Уволен ли сотрудник
Status BOOLEAN not null default false, -- Удален ли сотрудник
Hidden BOOLEAN not null default false, -- Скрыт ли сотрудник для онлайн-записи
YclientsUserID INT NOT NULL, -- ID пользователя в Yclients2
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- CREATE TABLE IF NOT EXISTS YclientsCompany (
-- ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
-- SalonID INT NOT NULL, -- ID компании
-- Title text NOT NULL,
-- ShortDecription text NOT NULL,
-- Active INT NOT NULL,
-- Country text NOT NULL,
-- GroupPriority INT NOT NULL,
-- Deleted BOOLEAN NOT NULL DEFAULT FALSE,
-- CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
-- );
CREATE TABLE IF NOT EXISTS YclientsServices (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
SalonID INT NOT NULL, -- ID компании
ServiceID INT NOT NULL,
SalonServiceID INT NOT NULL,
Title text NOT NULL,
CategoryID INT NOT NULL,
PriceMin text NOT NULL,
PriceMax text NOT NULL,
Discount text NOT NULL,
Comment text NOT NULL,
Active BOOLEAN not null default false,
ApiID text NOT NULL,
Staff JSONB NOT NULL DEFAULT '{}',
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS YclientsTimeSlots (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
SalonID INT NOT NULL, -- ID компании
IsEnabled BOOLEAN NOT NULL DEFAULT false,
WeekdaysSettings JSONB NOT NULL DEFAULT '[]',
DatesSettings JSONB NOT NULL DEFAULT '{}',
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS YclientsRules (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
SalonID INT NOT NULL, -- ID компании
QuizID INT NOT NULL, -- ID квиза на которое вешается правило
StaffID INT NOT NULL,
Services JSONB NOT NULL DEFAULT '{}',
FieldsRule JSONB NOT NULL DEFAULT '{}',
CustomColor text NOT NULL Default '',
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS YclientsFields (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
YclientsID INT NOT NULL, -- Айдишник field в Yclients
SalonID INT NOT NULL, -- ID компании
FieldType CustomFieldsTypeYclients NOT NULL, -- тип поля
Code text NOT NULL,
Title text NOT NULL,
ShowInUI BOOLEAN NOT NULL DEFAULT FALSE,
UserCanEdit BOOLEAN NOT NULL DEFAULT FALSE,
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS YclientsCRMStatuses (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
AnswerID BIGINT NOT NULL,
SalonID INT NOT NULL,
RecordID INT NOT NULL DEFAULT 0, -- ID созданной записи в YClients
Status TEXT NOT NULL DEFAULT '', -- запись о ошибке, либо успехе
CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX idx_unique_yclients_rules ON YclientsRules (SalonID, QuizID) WHERE Deleted = false;

@ -400,3 +400,90 @@ type Usersamo struct {
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientsaccount struct {
ID int64 `db:"id" json:"id"`
Accountid string `db:"accountid" json:"accountid"`
Salonid int32 `db:"salonid" json:"salonid"`
Title string `db:"title" json:"title"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientsaccountuser struct {
ID int64 `db:"id" json:"id"`
Salonid int32 `db:"salonid" json:"salonid"`
Yclientsid int32 `db:"yclientsid" json:"yclientsid"`
Name string `db:"name" json:"name"`
Specialization string `db:"specialization" json:"specialization"`
Idposition int32 `db:"idposition" json:"idposition"`
Titleposition string `db:"titleposition" json:"titleposition"`
Fired bool `db:"fired" json:"fired"`
Status bool `db:"status" json:"status"`
Hidden bool `db:"hidden" json:"hidden"`
Yclientsuserid int32 `db:"yclientsuserid" json:"yclientsuserid"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientscrmstatus struct {
ID int64 `db:"id" json:"id"`
Answerid int64 `db:"answerid" json:"answerid"`
Salonid int32 `db:"salonid" json:"salonid"`
Recordid int32 `db:"recordid" json:"recordid"`
Status string `db:"status" json:"status"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientsfield struct {
ID int64 `db:"id" json:"id"`
Yclientsid int32 `db:"yclientsid" json:"yclientsid"`
Salonid int32 `db:"salonid" json:"salonid"`
Fieldtype interface{} `db:"fieldtype" json:"fieldtype"`
Code string `db:"code" json:"code"`
Title string `db:"title" json:"title"`
Showinui bool `db:"showinui" json:"showinui"`
Usercanedit bool `db:"usercanedit" json:"usercanedit"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientsrule struct {
ID int64 `db:"id" json:"id"`
Salonid int32 `db:"salonid" json:"salonid"`
Quizid int32 `db:"quizid" json:"quizid"`
Staffid int32 `db:"staffid" json:"staffid"`
Services json.RawMessage `db:"services" json:"services"`
Fieldsrule json.RawMessage `db:"fieldsrule" json:"fieldsrule"`
Customcolor string `db:"customcolor" json:"customcolor"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientsservice struct {
ID int64 `db:"id" json:"id"`
Salonid int32 `db:"salonid" json:"salonid"`
Serviceid int32 `db:"serviceid" json:"serviceid"`
Salonserviceid int32 `db:"salonserviceid" json:"salonserviceid"`
Title string `db:"title" json:"title"`
Categoryid int32 `db:"categoryid" json:"categoryid"`
Pricemin float64 `db:"pricemin" json:"pricemin"`
Pricemax float64 `db:"pricemax" json:"pricemax"`
Discount int32 `db:"discount" json:"discount"`
Comment string `db:"comment" json:"comment"`
Active bool `db:"active" json:"active"`
Apiid string `db:"apiid" json:"apiid"`
Staff json.RawMessage `db:"staff" json:"staff"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}
type Yclientstimeslot struct {
ID int64 `db:"id" json:"id"`
Salonid int32 `db:"salonid" json:"salonid"`
Isenabled bool `db:"isenabled" json:"isenabled"`
Weekdayssettings json.RawMessage `db:"weekdayssettings" json:"weekdayssettings"`
Datessettings json.RawMessage `db:"datessettings" json:"datessettings"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
}

File diff suppressed because it is too large Load Diff

@ -16,18 +16,21 @@ const (
StatusOffLimit = "offlimit"
StatusAI = "ai"
TypeVariant = "variant"
TypeImages = "images"
TypeVarImages = "varimg"
TypeFile = "file"
TypeText = "text"
TypeEmoji = "emoji"
TypeSelect = "select"
TypeDate = "date"
TypeNumber = "number"
TypePage = "page"
TypeRating = "rating"
TypeResult = "result"
TypeVariant = "variant"
TypeImages = "images"
TypeVarImages = "varimg"
TypeFile = "file"
TypeText = "text"
TypeEmoji = "emoji"
TypeSelect = "select"
TypeDate = "date"
TypeNumber = "number"
TypePage = "page"
TypeRating = "rating"
TypeResult = "result"
TypeYclientsStaffID = "yclients_staff_id"
TypeYclientsServices = "yclients_services"
TypeYclientsComment = "yclients_comment"
)
const QuizGigaChatPrivilegeLimitUsage = 30

183
model/yclients.go Normal file

@ -0,0 +1,183 @@
package model
import "time"
type YclientsAccount struct {
ID int64 `json:"id"`
AccountID string `json:"accountID"` // ID аккаунта нас
SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
Title string `json:"title"`
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type YclientsAccountUser struct {
ID int64 `json:"id"`
SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
YclientsID int32 `json:"yclientsID"` // ID пользователя в Yclients
Name string `json:"name"`
Specialization string `json:"specialization"`
IDPosition int32 `json:"idPosition"`
TitlePosition string `json:"titlePosition"`
Fired bool `json:"fired"` // Уволен ли сотрудник
Status bool `json:"status"` //Удален ли сотрудник
Hidden bool `json:"hidden"` // Скрыт ли сотрудник для онлайн-записи
YclientsUserID int32 `json:"yclientsUserID"` // ID пользователя в Yclients2
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type UserListYclientsResp struct {
Count int64 `json:"count"`
Items []YclientsAccountUser `json:"items"`
}
//type YclientsCompany struct {
// ID int64 `json:"id"`
// SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
// Title string `json:"title"`
// ShortDecription string `json:"shortDecription"`
// Active int32 `json:"active"`
// Country string `json:"country"`
// GroupPriority int32 `json:"groupPriority"`
// Deleted bool `json:"deleted"`
// CreatedAt time.Time `json:"createdAt"`
//}
//type CompanyListYclientsResp struct {
// Count int64 `json:"count"`
// Items []YclientsCompany `json:"items"`
//}
type YclientsServices struct {
ID int64 `json:"id"`
SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
ServiceID int32 `json:"serviceID"`
SalonServiceID int32 `json:"salon_service_id"`
Title string `json:"title"`
CategoryID int32 `json:"categoryID"`
PriceMin float64 `json:"priceMin"`
PriceMax float64 `json:"priceMax"`
Discount int32 `json:"discount"`
Comment string `json:"comment"`
Active bool `json:"active"`
ApiID string `json:"apiID"`
Staff []YclientsServiceStaff `json:"staff"`
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type YclientsServiceStaff struct {
ID int `json:"id"`
SeanceLength int `json:"seance_length"`
}
type ServicesListYclientsResp struct {
Count int64 `json:"count"`
Items []YclientsServices `json:"items"`
}
type Timeslots struct {
ID int64 `json:"id"`
SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
// ниже то что используется в запросе
IsEnabled bool `json:"is_enabled"`
WeekdaysSettings []WeekdaySetting `json:"weekdays_settings"`
DatesSettings []DateSetting `json:"dates_settings"`
// выше то что используется в запросе
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type WeekdaySetting struct {
Weekday int `json:"weekday"`
Timeslots []int `json:"timeslots"`
Setting GridSetting `json:"setting"`
}
type DateSetting struct {
Date string `json:"date"`
Timeslots []int `json:"timeslots"`
Setting GridSetting `json:"setting"`
}
type GridSetting struct {
GridFirstTimeslot int `json:"grid_first_timeslot"`
GridLastTimeslot int `json:"grid_last_timeslot"`
GridDisplayStep int `json:"grid_display_step"`
GridNearestTimeslotDelay int `json:"grid_nearest_timeslot_delay"`
GridBaseType string `json:"grid_base_type"`
IsGridFlexible bool `json:"is_grid_flexible"`
}
type TimeslotsListYclientsResp struct {
Count int64 `json:"count"`
Items []Timeslots `json:"items"`
}
type YclientsRule struct {
ID int64 `json:"id"`
SalonID int32 `json:"salon_id"` // ID "аккаунта который ГЛАВНЫЙ"
QuizID int32 `json:"quizID"` // ID квиза на которое вешается правило
StaffID int32 `json:"staffID"`
Services []ServiceYclientsRule `json:"services"`
FieldsRule YclientsFieldRule `json:"fields_rule"`
CustomColor string `json:"custom_color"`
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type YclientsFieldRule struct {
QuestionID map[uint64]int32 `json:"question_id"`
}
type ServiceYclientsRule struct {
ID int `json:"id"`
FirstCost int `json:"first_cost"`
Discount int `json:"discount"`
Cost float64 `json:"cost"`
}
type YclientsCustomFieldsType string
const (
TypeYclientsText YclientsCustomFieldsType = "text" // строка длиной до 255 символов
TypeYclientsNumber YclientsCustomFieldsType = "number" // число
TypeYclientsSelect YclientsCustomFieldsType = "select" // список
TypeYclientsDate YclientsCustomFieldsType = "date" // Дата (Y-m-d)
TypeYclientsDateTime YclientsCustomFieldsType = "datetime" // Дата и время (Y-m-d H:i:s)
)
type YclientsField struct {
ID int64 `json:"id"`
YclientsID int32 `json:"yclientsID"`
SalonID int32 `json:"salonID"`
FieldType YclientsCustomFieldsType `json:"field_type"`
Code string `json:"code"`
Title string `json:"title"`
ShowINUI bool `json:"show_in_ui"`
UserCanEdit bool `json:"user_can_edit"`
Deleted bool `json:"deleted"`
CreatedAt time.Time `json:"createdAt"`
}
type UserListYclientsFieldsResp struct {
Count int64 `json:"count"`
Items []YclientsField `json:"items"`
}
type YclientsUsersTrueResults struct {
QuizID int64
AnswerID int64
Result bool
QuestionID int64
Content string
Session string
SalonID int32
UTMs UTMSavingMap
FieldsRule YclientsFieldRule
StaffID int32
Services []ServiceYclientsRule
CustomColor string
QuizAccountID string
Datetime time.Time // время result ответа
}

@ -5,13 +5,14 @@ import (
"database/sql"
"errors"
"fmt"
"gitea.pena/SQuiz/common/dal/sqlcgen"
"gitea.pena/SQuiz/common/model"
"github.com/lib/pq"
"sort"
"strings"
"sync"
"time"
"gitea.pena/SQuiz/common/dal/sqlcgen"
"gitea.pena/SQuiz/common/model"
"github.com/lib/pq"
)
type Deps struct {
@ -559,3 +560,31 @@ func (r *QuestionRepository) CheckQuestionOwner(ctx context.Context, accountID s
}
return accountID == id, nil
}
func (r *QuestionRepository) GetQuestionListByQuizID(ctx context.Context, quizID int64) ([]model.Question, error) {
rows, err := r.queries.GetQuestionListByQuizID(ctx, quizID)
if err != nil {
return nil, err
}
var questions []model.Question
for _, row := range rows {
questions = append(questions, model.Question{
Id: uint64(row.ID),
QuizId: uint64(row.QuizID),
Title: row.Title,
Description: row.Description.String,
Type: string(row.Questiontype.([]byte)),
Required: row.Required.Bool,
Deleted: row.Deleted.Bool,
Page: int(row.Page.Int16),
Content: row.Content.String,
Version: int(row.Version.Int16),
ParentIds: row.ParentIds,
CreatedAt: row.CreatedAt.Time,
UpdatedAt: row.UpdatedAt.Time,
Auditory: row.Auditory,
Session: row.Session,
})
}
return questions, nil
}

@ -0,0 +1,800 @@
package yclients
import (
"context"
"database/sql"
"encoding/json"
"errors"
"gitea.pena/SQuiz/common/dal/sqlcgen"
"gitea.pena/SQuiz/common/model"
)
type YclientsRepository struct {
queries *sqlcgen.Queries
pool *sql.DB
}
type Deps struct {
Queries *sqlcgen.Queries
Pool *sql.DB
}
func NewYclientsRepository(deps Deps) *YclientsRepository {
return &YclientsRepository{
queries: deps.Queries,
pool: deps.Pool,
}
}
// users
func (r *YclientsRepository) GetCurrentAccount(ctx context.Context, accountID string) (*model.YclientsAccount, error) {
row, err := r.queries.GetCurrentYclientsCompany(ctx, accountID)
if err != nil {
return nil, err
}
user := model.YclientsAccount{
ID: row.ID,
AccountID: row.Accountid,
SalonID: row.Salonid,
Title: row.Title,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
}
return &user, nil
}
func (r *YclientsRepository) GetAllYclientsAccounts(ctx context.Context) ([]model.YclientsAccount, error) {
rows, err := r.queries.GetAllYclientsAccounts(ctx)
if err != nil {
return nil, err
}
var result []model.YclientsAccount
for _, row := range rows {
result = append(result, model.YclientsAccount{
ID: row.ID,
AccountID: row.Accountid,
SalonID: row.Salonid,
Title: row.Title,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
}
return result, nil
}
func (r *YclientsRepository) GettingUserWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListYclientsResp, error) {
rows, err := r.queries.GetUsersYclientsWithPagination(ctx, sqlcgen.GetUsersYclientsWithPaginationParams{
Accountid: accountID,
Column2: req.Page,
Limit: req.Size,
})
if err != nil {
return nil, err
}
var users []model.YclientsAccountUser
var count int64
for _, row := range rows {
users = append(users, model.YclientsAccountUser{
ID: row.ID,
SalonID: row.Salonid,
YclientsID: row.Yclientsid,
Name: row.Name,
IDPosition: row.Idposition,
TitlePosition: row.Titleposition,
Fired: row.Fired,
Status: row.Status,
Hidden: row.Hidden,
YclientsUserID: row.Yclientsuserid,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
count = row.TotalCount
}
resp := model.UserListYclientsResp{
Count: count,
Items: users,
}
return &resp, nil
}
func (r *YclientsRepository) CreateAccount(ctx context.Context, account model.YclientsAccount) (*model.YclientsAccount, error) {
row, err := r.queries.CreateYclientsAccount(ctx, sqlcgen.CreateYclientsAccountParams{
Accountid: account.AccountID,
Salonid: account.SalonID,
Title: account.Title,
})
if err != nil {
return nil, err
}
return &model.YclientsAccount{
ID: row.ID,
AccountID: row.Accountid,
SalonID: row.Salonid,
Title: row.Title,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
}, nil
}
func (r *YclientsRepository) GetUserUsersByID(ctx context.Context, salonID int32) ([]model.YclientsAccountUser, error) {
rows, err := r.queries.GetUsersByIDYclients(ctx, salonID)
if err != nil {
return nil, err
}
var users []model.YclientsAccountUser
for _, row := range rows {
users = append(users, model.YclientsAccountUser{
ID: row.ID,
SalonID: row.Salonid,
YclientsID: row.Yclientsid,
Name: row.Name,
IDPosition: row.Idposition,
TitlePosition: row.Titleposition,
Fired: row.Fired,
Status: row.Status,
Hidden: row.Hidden,
YclientsUserID: row.Yclientsuserid,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
}
return users, nil
}
func (r *YclientsRepository) UpdateAccountUser(ctx context.Context, user model.YclientsAccountUser) error {
err := r.queries.UpdateYclientsAccountUser(ctx, sqlcgen.UpdateYclientsAccountUserParams{
Salonid: user.SalonID,
Yclientsid: user.YclientsID,
Name: user.Name,
Specialization: user.Specialization,
Idposition: user.IDPosition,
Titleposition: user.TitlePosition,
Fired: user.Fired,
Status: user.Status,
Hidden: user.Hidden,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) AddAccountUser(ctx context.Context, user model.YclientsAccountUser) error {
err := r.queries.AddYclientsAccountUser(ctx, sqlcgen.AddYclientsAccountUserParams{
Salonid: user.SalonID,
Yclientsid: user.YclientsID,
Name: user.Name,
Specialization: user.Specialization,
Idposition: user.IDPosition,
Titleposition: user.TitlePosition,
Fired: user.Fired,
Status: user.Status,
Hidden: user.Hidden,
Yclientsuserid: user.YclientsUserID,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) DeleteUsers(ctx context.Context, ids []int64) error {
err := r.queries.DeleteYclientsUsers(ctx, ids)
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) SoftDeleteAccount(ctx context.Context, accountID string) error {
err := r.queries.SoftDeleteYclientsAccount(ctx, accountID)
if err != nil {
return err
}
return nil
}
// company
//func (r *YclientsRepository) GettingCompanyWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.CompanyListYclientsResp, error) {
// rows, err := r.queries.GetCompanyYclientsWithPagination(ctx, sqlcgen.GetCompanyYclientsWithPaginationParams{
// Accountid: accountID,
// Column2: req.Page,
// Limit: req.Size,
// })
// if err != nil {
// return nil, err
// }
// var users []model.YclientsCompany
// var count int64
// for _, row := range rows {
// users = append(users, model.YclientsCompany{
// ID: row.ID,
// SalonID: row.Salonid,
// Title: row.Title,
// ShortDecription: row.Shortdecription,
// Active: row.Active,
// Country: row.Country,
// GroupPriority: row.Grouppriority,
// Deleted: row.Deleted,
// CreatedAt: row.Createdat,
// })
// count = row.TotalCount
// }
//
// resp := model.CompanyListYclientsResp{
// Count: count,
// Items: users,
// }
//
// return &resp, nil
//}
//
//func (r *YclientsRepository) UpdateCompany() {
//
//}
// services
func (r *YclientsRepository) GettingServicesWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.ServicesListYclientsResp, error) {
rows, err := r.queries.GetServicesYclientsWithPagination(ctx, sqlcgen.GetServicesYclientsWithPaginationParams{
Accountid: accountID,
Column2: req.Page,
Limit: req.Size,
})
if err != nil {
return nil, err
}
var services []model.YclientsServices
var count int64
for _, row := range rows {
var staff []model.YclientsServiceStaff
err = json.Unmarshal(row.Staff, &staff)
if err != nil {
return nil, err
}
services = append(services, model.YclientsServices{
ID: row.ID,
SalonID: row.Salonid,
ServiceID: row.Serviceid,
SalonServiceID: row.Salonserviceid,
Title: row.Title,
CategoryID: row.Categoryid,
PriceMin: row.Pricemin,
PriceMax: row.Pricemax,
Discount: row.Discount,
Comment: row.Comment,
Active: row.Active,
ApiID: row.Apiid,
Staff: staff,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
count = row.TotalCount
}
resp := model.ServicesListYclientsResp{
Count: count,
Items: services,
}
return &resp, nil
}
func (r *YclientsRepository) GetAccountServicesByID(ctx context.Context, salonID int32) ([]model.YclientsServices, error) {
rows, err := r.queries.GetServicesByIDYclients(ctx, salonID)
if err != nil {
return nil, err
}
var services []model.YclientsServices
for _, row := range rows {
var staff []model.YclientsServiceStaff
err = json.Unmarshal(row.Staff, &staff)
if err != nil {
return nil, err
}
services = append(services, model.YclientsServices{
ID: row.ID,
SalonID: row.Salonid,
ServiceID: row.Serviceid,
SalonServiceID: row.Salonserviceid,
Title: row.Title,
CategoryID: row.Categoryid,
PriceMin: row.Pricemin,
PriceMax: row.Pricemax,
Discount: row.Discount,
Comment: row.Comment,
Active: row.Active,
ApiID: row.Apiid,
Staff: staff,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
}
return services, nil
}
func (r *YclientsRepository) UpdateAccountServices(ctx context.Context, service model.YclientsServices) error {
staff, err := json.Marshal(service.Staff)
if err != nil {
return err
}
err = r.queries.UpdateYclientsAccountServices(ctx, sqlcgen.UpdateYclientsAccountServicesParams{
Salonid: service.SalonID,
Serviceid: service.ServiceID,
Salonserviceid: service.SalonServiceID,
Title: service.Title,
Categoryid: service.CategoryID,
Pricemin: service.PriceMin,
Pricemax: service.PriceMax,
Discount: service.Discount,
Comment: service.Comment,
Active: service.Active,
Apiid: service.ApiID,
Staff: staff,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) AddAccountService(ctx context.Context, service model.YclientsServices) error {
staff, err := json.Marshal(service.Staff)
if err != nil {
return err
}
err = r.queries.AddYclientsAccountService(ctx, sqlcgen.AddYclientsAccountServiceParams{
Salonid: service.SalonID,
Serviceid: service.ServiceID,
Salonserviceid: service.SalonServiceID,
Title: service.Title,
Categoryid: service.CategoryID,
Pricemin: service.PriceMin,
Pricemax: service.PriceMax,
Discount: service.Discount,
Comment: service.Comment,
Active: service.Active,
Apiid: service.ApiID,
Staff: staff,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) DeleteServices(ctx context.Context, ids []int64) error {
err := r.queries.DeleteYclientsServices(ctx, ids)
if err != nil {
return err
}
return nil
}
// timeslots
func (r *YclientsRepository) GettingTimeslotsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.TimeslotsListYclientsResp, error) {
rows, err := r.queries.GetTimeslotsYclientsWithPagination(ctx, sqlcgen.GetTimeslotsYclientsWithPaginationParams{
Accountid: accountID,
Column2: req.Page,
Limit: req.Size,
})
if err != nil {
return nil, err
}
var timeslots []model.Timeslots
var count int64
for _, row := range rows {
var weekdaysSettings []model.WeekdaySetting
err = json.Unmarshal(row.Weekdayssettings, &weekdaysSettings)
if err != nil {
return nil, err
}
var datesSettings []model.DateSetting
err = json.Unmarshal(row.Datessettings, &datesSettings)
if err != nil {
return nil, err
}
timeslots = append(timeslots, model.Timeslots{
ID: row.ID,
SalonID: row.Salonid,
IsEnabled: row.Isenabled,
WeekdaysSettings: weekdaysSettings,
DatesSettings: datesSettings,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
count = row.TotalCount
}
resp := model.TimeslotsListYclientsResp{
Count: count,
Items: timeslots,
}
return &resp, nil
}
func (r *YclientsRepository) UpdateAccountTimeslots(ctx context.Context, salonID int32, timeslots model.Timeslots) error {
weekdaysSettings, err := json.Marshal(timeslots.WeekdaysSettings)
if err != nil {
return err
}
datesSettings, err := json.Marshal(timeslots.DatesSettings)
if err != nil {
return err
}
err = r.queries.UpdateYclientsAccountTimeslots(ctx, sqlcgen.UpdateYclientsAccountTimeslotsParams{
Salonid: salonID,
Isenabled: timeslots.IsEnabled,
Weekdayssettings: weekdaysSettings,
Datessettings: datesSettings,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) AddAccountTimeslots(ctx context.Context, salonID int32, timeslots model.Timeslots) (int64, error) {
weekdaysSettings, err := json.Marshal(timeslots.WeekdaysSettings)
if err != nil {
return 0, err
}
datesSettings, err := json.Marshal(timeslots.DatesSettings)
if err != nil {
return 0, err
}
row, err := r.queries.AddYclientsAccountTimeslots(ctx, sqlcgen.AddYclientsAccountTimeslotsParams{
Salonid: salonID,
Isenabled: timeslots.IsEnabled,
Weekdayssettings: weekdaysSettings,
Datessettings: datesSettings,
})
if err != nil {
return 0, err
}
return row.ID, nil
}
func (r *YclientsRepository) DeleteTimeslots(ctx context.Context, ids []int64) error {
err := r.queries.DeleteYclientsTimeslots(ctx, ids)
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) GetAccountTimeslotsByID(ctx context.Context, salonID int32) (*model.Timeslots, error) {
row, err := r.queries.GetTimeslotsByIDYclients(ctx, salonID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
return nil, err
}
var weekdaysSettings []model.WeekdaySetting
err = json.Unmarshal(row.Weekdayssettings, &weekdaysSettings)
if err != nil {
return nil, err
}
var datesSettings []model.DateSetting
err = json.Unmarshal(row.Datessettings, &datesSettings)
if err != nil {
return nil, err
}
return &model.Timeslots{
ID: row.ID,
SalonID: row.Salonid,
IsEnabled: row.Isenabled,
WeekdaysSettings: weekdaysSettings,
DatesSettings: datesSettings,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
}, nil
}
// rule
func (r *YclientsRepository) GettingQuizRules(ctx context.Context, quizID int32) (*model.YclientsRule, error) {
row, err := r.queries.GetYclientsQuizRule(ctx, quizID)
if err != nil {
return nil, err
}
var services []model.ServiceYclientsRule
err = json.Unmarshal(row.Services, &services)
if err != nil {
return nil, err
}
var fieldsRule model.YclientsFieldRule
err = json.Unmarshal(row.Fieldsrule, &fieldsRule)
if err != nil {
return nil, err
}
return &model.YclientsRule{
ID: row.ID,
SalonID: row.Salonid,
QuizID: row.Quizid,
Services: services,
FieldsRule: fieldsRule,
CustomColor: row.Customcolor,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
StaffID: row.Staffid,
}, nil
}
func (r *YclientsRepository) SetQuizSettings(ctx context.Context, rule model.YclientsRule, accountID string) error {
jsonServices, err := json.Marshal(rule.Services)
if err != nil {
return err
}
jsonFieldsRule, err := json.Marshal(rule.FieldsRule)
if err != nil {
return err
}
_, err = r.queries.SetYclientsQuizSettings(ctx, sqlcgen.SetYclientsQuizSettingsParams{
Quizid: rule.QuizID,
Staffid: rule.StaffID,
Services: jsonServices,
Fieldsrule: jsonFieldsRule,
Customcolor: rule.CustomColor,
Accountid: accountID,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) ChangeQuizSettings(ctx context.Context, rule model.YclientsRule, accountID string) error {
jsonServices, err := json.Marshal(rule.Services)
if err != nil {
return err
}
jsonFieldsRule, err := json.Marshal(rule.FieldsRule)
if err != nil {
return err
}
_, err = r.queries.ChangeYclientsQuizSettings(ctx, sqlcgen.ChangeYclientsQuizSettingsParams{
Quizid: rule.QuizID,
Staffid: rule.StaffID,
Services: jsonServices,
Fieldsrule: jsonFieldsRule,
Customcolor: rule.CustomColor,
Accountid: accountID,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) UpdateFieldRules(ctx context.Context, fieldRules model.YclientsFieldRule, salonID int32, quizID int32) error {
jsonFieldsRule, err := json.Marshal(fieldRules)
if err != nil {
return err
}
err = r.queries.UpdateYclientsFieldRules(ctx, sqlcgen.UpdateYclientsFieldRulesParams{
Fieldsrule: jsonFieldsRule,
Salonid: salonID,
Quizid: quizID,
})
if err != nil {
return err
}
return nil
}
// fields
func (r *YclientsRepository) GetFieldsWithPagination(ctx context.Context, req *model.PaginationReq, accountID string) (*model.UserListYclientsFieldsResp, error) {
rows, err := r.queries.GetYclientsFieldsWithPagination(ctx, sqlcgen.GetYclientsFieldsWithPaginationParams{
Accountid: accountID,
Column2: req.Page,
Limit: req.Size,
})
if err != nil {
return nil, err
}
var count int64
var fields []model.YclientsField
for _, row := range rows {
count = row.TotalCount
var fieldType model.YclientsCustomFieldsType
f := string(row.Fieldtype.([]byte))
fieldType = model.YclientsCustomFieldsType(f)
fields = append(fields, model.YclientsField{
ID: row.ID,
YclientsID: row.Yclientsid,
SalonID: row.Salonid,
FieldType: fieldType,
Code: row.Code,
Title: row.Title,
ShowINUI: row.Showinui,
UserCanEdit: row.Usercanedit,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
}
resp := model.UserListYclientsFieldsResp{
Count: count,
Items: fields,
}
return &resp, nil
}
func (r *YclientsRepository) AddAccountField(ctx context.Context, field model.YclientsField) error {
err := r.queries.AddYclientsAccountField(ctx, sqlcgen.AddYclientsAccountFieldParams{
Yclientsid: field.YclientsID,
Salonid: field.SalonID,
Fieldtype: field.FieldType,
Code: field.Code,
Title: field.Title,
Showinui: field.ShowINUI,
Usercanedit: field.UserCanEdit,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) UpdateAccountFields(ctx context.Context, salonID int32, field model.YclientsField) error {
err := r.queries.UpdateYclientsAccountFields(ctx, sqlcgen.UpdateYclientsAccountFieldsParams{
Salonid: salonID,
Yclientsid: field.YclientsID,
Fieldtype: field.FieldType,
Code: field.Code,
Title: field.Title,
Showinui: field.ShowINUI,
Usercanedit: field.UserCanEdit,
})
if err != nil {
return err
}
return nil
}
func (r *YclientsRepository) GetUserFieldsByID(ctx context.Context, salonID int32) ([]model.YclientsField, error) {
rows, err := r.queries.GetUserYclientsFieldsByID(ctx, salonID)
if err != nil {
return nil, err
}
var fields []model.YclientsField
for _, row := range rows {
var fieldType model.YclientsCustomFieldsType
f := string(row.Fieldtype.([]byte))
fieldType = model.YclientsCustomFieldsType(f)
fields = append(fields, model.YclientsField{
ID: row.ID,
YclientsID: row.Yclientsid,
SalonID: row.Salonid,
FieldType: fieldType,
Code: row.Code,
Title: row.Title,
ShowINUI: row.Showinui,
UserCanEdit: row.Usercanedit,
Deleted: row.Deleted,
CreatedAt: row.Createdat,
})
}
return fields, nil
}
func (r *YclientsRepository) DeleteFields(ctx context.Context, ids []int64) error {
err := r.queries.DeleteYclientsFields(ctx, ids)
if err != nil {
return err
}
return nil
}
// true results fetch
// todo нужно хорошенько проверить
func (r *YclientsRepository) GettingYclientsUsersTrueResults(ctx context.Context) ([]model.YclientsUsersTrueResults, error) {
rows, err := r.queries.GettingYclientsUsersTrueResults(ctx)
if err != nil {
return nil, err
}
var results []model.YclientsUsersTrueResults
for _, row := range rows {
var fieldsRule model.YclientsFieldRule
err = json.Unmarshal(row.Fieldsrule, &fieldsRule)
if err != nil {
return nil, err
}
var utms model.UTMSavingMap
err = json.Unmarshal(row.Utm.([]byte), &utms)
if err != nil {
return nil, err
}
var services []model.ServiceYclientsRule
err = json.Unmarshal(row.Services, &services)
if err != nil {
return nil, err
}
result := model.YclientsUsersTrueResults{
QuizID: row.QuizID,
AnswerID: row.AnswerID,
Result: row.Result.Bool,
QuestionID: row.QuestionID,
Content: row.Content.String,
Session: row.Session.String,
SalonID: row.Salonid,
UTMs: utms,
FieldsRule: fieldsRule,
StaffID: row.Staffid,
Services: services,
CustomColor: row.Customcolor,
QuizAccountID: row.QuizAccountid,
Datetime: row.Datetime.Time,
}
results = append(results, result)
}
return results, nil
}
type SaveDealYclientsDeps struct {
RecordID int32
AnswerID int64
Status string
SalonID int32
}
func (r *YclientsRepository) SaveDealYclientsStatus(ctx context.Context, deps SaveDealYclientsDeps) error {
err := r.queries.SaveDealYclientsStatus(ctx, sqlcgen.SaveDealYclientsStatusParams{
Recordid: deps.RecordID,
Answerid: deps.AnswerID,
Status: deps.Status,
Salonid: deps.SalonID,
})
if err != nil {
return err
}
return nil
}

@ -58,6 +58,8 @@ packages:
- "./dal/schema/000027_init.down.sql"
- "./dal/schema/000028_init.up.sql"
- "./dal/schema/000028_init.down.sql"
- "./dal/schema/000029_init.up.sql"
- "./dal/schema/000029_init.down.sql"
engine: "postgresql"
emit_json_tags: true
emit_db_tags: true