diff --git a/dal/dal.go b/dal/dal.go
index 4d0c38d..106e537 100644
--- a/dal/dal.go
+++ b/dal/dal.go
@@ -5,6 +5,8 @@ import (
"database/sql"
_ "embed"
"errors"
+ "fmt"
+ _ "github.com/ClickHouse/clickhouse-go"
_ "github.com/lib/pq"
"github.com/minio/minio-go/v7"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen"
@@ -31,6 +33,7 @@ type DAL struct {
ResultRepo *result.ResultRepository
WorkerRepo *workers.WorkerRepository
StatisticsRepo *statistics.StatisticsRepository
+ WorkerAnsRepo *answer.WorkerAnswerRepository
}
func New(ctx context.Context, cred string, minioClient *minio.Client) (*DAL, error) {
@@ -62,12 +65,17 @@ func New(ctx context.Context, cred string, minioClient *minio.Client) (*DAL, err
}
}
- answerRepo := answer.NewAnswerRepository(answer.Deps{
+ workerAnsRepo := answer.NewWorkerAnswerRepo(answer.Deps{
Queries: queries,
Pool: pool,
AnswerMinio: storerAnswer,
})
+ answerRepo := answer.NewAnswerRepository(answer.Deps{
+ Queries: queries,
+ Pool: pool,
+ })
+
questionRepo := question.NewQuestionRepository(question.Deps{
Queries: queries,
Pool: pool,
@@ -102,6 +110,7 @@ func New(ctx context.Context, cred string, minioClient *minio.Client) (*DAL, err
ResultRepo: resultRepo,
WorkerRepo: workerRepo,
StatisticsRepo: statisticsRepo,
+ WorkerAnsRepo: workerAnsRepo,
}, nil
}
@@ -177,3 +186,38 @@ func (d *AmoDal) Close(ctx context.Context) error {
}
return nil
}
+
+type ClickHouseDAL struct {
+ conn *sql.DB
+ StatisticClickRepo *statistics.StatisticClick
+}
+
+func NewClickHouseDAL(ctx context.Context, cred string) (*ClickHouseDAL, error) {
+ conn, err := sql.Open("clickhouse", cred)
+ if err != nil {
+ return nil, fmt.Errorf("error open database connection: %w", err)
+ }
+
+ timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
+ defer cancel()
+
+ if err := conn.PingContext(timeoutCtx); err != nil {
+ return nil, fmt.Errorf("error ping database: %w", err)
+ }
+
+ statsClickRepo, err := statistics.NewClickStatistic(ctx, statistics.DepsClick{
+ Conn: conn,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &ClickHouseDAL{
+ conn: conn,
+ StatisticClickRepo: statsClickRepo,
+ }, nil
+}
+
+func (d *ClickHouseDAL) Close(ctx context.Context) error {
+ return d.conn.Close()
+}
diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql
index 2413636..e5868b8 100644
--- a/dal/db_query/queries.sql
+++ b/dal/db_query/queries.sql
@@ -20,7 +20,7 @@ INSERT INTO quiz (accountid,
qid
)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19)
- RETURNING id, created_at, updated_at, qid;
+RETURNING id, created_at, updated_at, qid;
-- name: InsertQuestion :one
INSERT INTO question (
@@ -35,7 +35,7 @@ INSERT INTO question (
updated_at
)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
- RETURNING id, created_at, updated_at;
+RETURNING id, created_at, updated_at;
-- name: DeleteQuestion :one
UPDATE question SET deleted=true WHERE id=$1 RETURNING question.*;
@@ -51,7 +51,7 @@ INSERT INTO question(
SELECT $1, title, description, questiontype, required,
page, content, version, parent_ids
FROM question WHERE question.id=$2
- RETURNING question.id, quiz_id, created_at, updated_at;
+RETURNING question.id, quiz_id, created_at, updated_at;
-- name: DuplicateQuestion :one
INSERT INTO question(
@@ -61,7 +61,7 @@ INSERT INTO question(
SELECT quiz_id, title, description, questiontype, required,
page, content, version, parent_ids
FROM question WHERE question.id=$1
- RETURNING question.id, quiz_id, created_at, updated_at;
+RETURNING question.id, quiz_id, created_at, updated_at;
-- name: MoveToHistory :one
INSERT INTO question(
@@ -71,7 +71,7 @@ INSERT INTO question(
SELECT quiz_id, title, description, questiontype, required,
page, content, version, parent_ids, true as deleted
FROM question WHERE question.id=$1
- RETURNING question.id, quiz_id, parent_ids;
+RETURNING question.id, quiz_id, parent_ids;
-- name: MoveToHistoryQuiz :one
INSERT INTO quiz(deleted,
@@ -81,7 +81,7 @@ INSERT INTO quiz(deleted,
SELECT true as deleted, accountid, archived,fingerprinting,repeatable,note_prevented,mail_notifications,unique_answers,name,description,config,
status,limit_answers,due_to,time_of_passing,pausable,version,version_comment,parent_ids,questions_count,answers_count,average_time_passing, super, group_id
FROM quiz WHERE quiz.id=$1 AND quiz.accountid=$2
- RETURNING quiz.id, qid, parent_ids;
+RETURNING quiz.id, qid, parent_ids;
-- name: CopyQuiz :one
INSERT INTO quiz(
@@ -91,7 +91,7 @@ INSERT INTO quiz(
SELECT accountid, archived,fingerprinting,repeatable,note_prevented,mail_notifications,unique_answers,name,description,config,
status,limit_answers,due_to,time_of_passing,pausable,version,version_comment,parent_ids,questions_count, super, group_id
FROM quiz WHERE quiz.id=$1 AND quiz.accountId=$2
- RETURNING id, qid,created_at, updated_at;
+RETURNING id, qid,created_at, updated_at;
-- name: CopyQuizQuestions :exec
INSERT INTO question(
@@ -134,6 +134,7 @@ SELECT
p.amount,
p.created_at,
a.id,
+ a.email,
qz.config
FROM
privileges AS p
@@ -143,7 +144,7 @@ WHERE
qz.id = $1;
-- name: CreateAccount :one
-INSERT INTO account (id, user_id, created_at, deleted) VALUES ($1, $2, $3, $4) RETURNING *;
+INSERT INTO account (id, user_id, email, created_at, deleted) VALUES ($1, $2, $3, $4, $5) RETURNING *;;
-- name: DeletePrivilegeByAccID :exec
DELETE FROM privileges WHERE account_id = $1;
@@ -232,11 +233,11 @@ SET
answers_count = COALESCE(aa.unique_true_answers_count, 0),
average_time_passing = COALESCE(sta.average_session_time, 0),
sessions_count = COALESCE(sta.sess,0)
- FROM
+FROM
(SELECT * FROM quiz WHERE deleted = FALSE AND archived = FALSE) q_sub
-LEFT JOIN answer_aggregates aa ON q_sub.id = aa.quiz_id
- LEFT JOIN question_aggregates qa ON q_sub.id = qa.quiz_id
- LEFT JOIN session_times_aggregates sta ON q_sub.id = sta.quiz_id
+ LEFT JOIN answer_aggregates aa ON q_sub.id = aa.quiz_id
+ LEFT JOIN question_aggregates qa ON q_sub.id = qa.quiz_id
+ LEFT JOIN session_times_aggregates sta ON q_sub.id = sta.quiz_id
WHERE
q.id = q_sub.id;
@@ -247,6 +248,7 @@ UPDATE privileges SET amount = $1 WHERE id = $2;
SELECT
a.id,
a.user_id,
+ a.email,
a.created_at,
COALESCE(p.ID,0),
coalesce(p.privilegeid,''),
@@ -407,13 +409,13 @@ WITH TimeBucket AS (
SELECT
date_trunc('hour', timestamp_bucket)::TIMESTAMP AS time_interval_start,
COALESCE(LEAD(
- date_trunc('hour', timestamp_bucket)::TIMESTAMP
- ) OVER (ORDER BY timestamp_bucket), NOW()) AS time_interval_end
+ date_trunc('hour', timestamp_bucket)::TIMESTAMP
+ ) OVER (ORDER BY timestamp_bucket), NOW()) AS time_interval_end
FROM
- generate_series(TO_TIMESTAMP($1), TO_TIMESTAMP($2), CASE
- WHEN EXTRACT(epoch FROM TO_TIMESTAMP($2)) - EXTRACT(epoch FROM TO_TIMESTAMP($1)) > 172800 THEN '1 day'::interval
- ELSE '1 hour'::interval
- END) AS timestamp_bucket
+ generate_series(TO_TIMESTAMP($1), TO_TIMESTAMP($2), CASE
+ WHEN EXTRACT(epoch FROM TO_TIMESTAMP($2)) - EXTRACT(epoch FROM TO_TIMESTAMP($1)) > 172800 THEN '1 day'::interval
+ ELSE '1 hour'::interval
+ END) AS timestamp_bucket
),
OpenStats AS (
SELECT
@@ -494,7 +496,7 @@ SELECT
CASE
WHEN COALESCE(os.open_count, 0) > 0 THEN COALESCE(rs.true_result_count, 0)::float / COALESCE(os.open_count, 0)::float
ELSE 0
- END::float AS conversion,
+ END::float AS conversion,
COALESCE(at.avg_time, 0) AS avg_time
FROM
TimeBucket tb
@@ -511,10 +513,10 @@ FROM
-- name: QuestionsStatistics :many
WITH Funnel AS (
SELECT
- COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false,
- COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true,
- COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question,
- COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result
+ COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false,
+ COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true,
+ COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question,
+ COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result
FROM
answer a
LEFT JOIN (
@@ -529,23 +531,23 @@ WITH Funnel AS (
AND a.created_at <= TO_TIMESTAMP($3)
),
Results AS (
- SELECT
- COALESCE(q.title, '') AS question_title,
- COUNT(*) AS total_answers,
- CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS FLOAT8) AS percentage
- FROM
- question q
- JOIN answer a ON q.id = a.question_id
- WHERE
- a.quiz_id = $1
- AND a.created_at >= TO_TIMESTAMP($2)
- AND a.created_at <= TO_TIMESTAMP($3)
- AND a.result = TRUE
- GROUP BY
- q.title, a.quiz_id, a.result
- HAVING
- COUNT(*) >= 1
- ),
+ SELECT
+ COALESCE(q.title, '') AS question_title,
+ COUNT(*) AS total_answers,
+ CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS FLOAT8) AS percentage
+ FROM
+ question q
+ JOIN answer a ON q.id = a.question_id
+ WHERE
+ a.quiz_id = $1
+ AND a.created_at >= TO_TIMESTAMP($2)
+ AND a.created_at <= TO_TIMESTAMP($3)
+ AND a.result = TRUE
+ GROUP BY
+ q.title, a.quiz_id, a.result
+ HAVING
+ COUNT(*) >= 1
+ ),
LastContent AS (
SELECT
a.question_id,
@@ -561,35 +563,35 @@ WITH Funnel AS (
answer
WHERE
quiz_id = $1
- AND start != true
+ AND start != true
AND created_at >= TO_TIMESTAMP($2)
AND created_at <= TO_TIMESTAMP($3)
GROUP BY
- question_id, session
+ question_id, session
) AS last_created_at_one_session ON a.session = last_created_at_one_session.session AND a.question_id = last_created_at_one_session.question_id AND a.created_at = last_created_at_one_session.last_created_at
),
Questions AS (
- SELECT
- q.title AS question_title,
- q.page AS question_page,
- lc.last_answer_content AS answer_content,
- CAST(
- COUNT(CASE WHEN a.result = FALSE THEN 1 END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 END)) OVER (PARTITION BY q.id), 0) AS FLOAT8
- ) AS percentage
- FROM
- question q
- JOIN LastContent lc ON q.id = lc.question_id
- JOIN answer a ON q.id = a.question_id
- WHERE
- a.quiz_id = $1
- AND a.start != true
- AND a.created_at >= TO_TIMESTAMP($2)
- AND a.created_at <= TO_TIMESTAMP($3)
- GROUP BY
- q.id, q.title, lc.last_answer_content
- HAVING
- COUNT(*) >= 1
-)
+ SELECT
+ q.title AS question_title,
+ q.page AS question_page,
+ lc.last_answer_content AS answer_content,
+ CAST(
+ COUNT(CASE WHEN a.result = FALSE THEN 1 END) * 100.0 / NULLIF(SUM(COUNT(CASE WHEN a.result = FALSE THEN 1 END)) OVER (PARTITION BY q.id), 0) AS FLOAT8
+ ) AS percentage
+ FROM
+ question q
+ JOIN LastContent lc ON q.id = lc.question_id
+ JOIN answer a ON q.id = a.question_id
+ WHERE
+ a.quiz_id = $1
+ AND a.start != true
+ AND a.created_at >= TO_TIMESTAMP($2)
+ AND a.created_at <= TO_TIMESTAMP($3)
+ GROUP BY
+ q.id, q.title, lc.last_answer_content
+ HAVING
+ COUNT(*) >= 1
+ )
SELECT
Funnel.count_start_false,
Funnel.count_start_true,
@@ -603,34 +605,34 @@ SELECT
COALESCE(Questions.percentage, 0) AS questions_percentage
FROM
Funnel
- LEFT JOIN Results ON true
- LEFT JOIN Questions ON Questions.percentage >= 1;
+ LEFT JOIN Results ON true
+ LEFT JOIN Questions ON Questions.percentage >= 1;
-- name: QuizCopyQid :one
- INSERT INTO quiz (
- accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config,
- status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id
- )
- SELECT
- $2, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config,
- status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id
- FROM
- quiz as q
- WHERE
- q.qid = $1
- RETURNING (select id from quiz where qid = $1),id, qid;
-
+INSERT INTO quiz (
+ accountid, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config,
+ status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id
+)
+SELECT
+ $2, archived, fingerprinting, repeatable, note_prevented, mail_notifications, unique_answers, name, description, config,
+ status, limit_answers, due_to, time_of_passing, pausable, version, version_comment, parent_ids, questions_count, answers_count, average_time_passing, super, group_id
+FROM
+ quiz as q
+WHERE
+ q.qid = $1
+RETURNING (select id from quiz where qid = $1),id, qid;
+
-- name: CopyQuestionQuizID :exec
INSERT INTO question (
quiz_id, title, description, questiontype, required,
page, content, version, parent_ids, created_at, updated_at
)
-SELECT
+SELECT
$2, title, description, questiontype, required,
page, content, version, parent_ids, created_at, updated_at
-FROM
+FROM
question
-WHERE
+WHERE
question.quiz_id = $1 AND deleted = false;
-- name: GetQidOwner :one
@@ -656,7 +658,7 @@ SELECT
(SELECT registration_count FROM Registrations) AS registrations,
(SELECT quiz_count FROM Quizes) AS quizes,
(SELECT result_count FROM Results) AS results;
-
+
-- name: GetListStartQuiz :many
SELECT id FROM quiz WHERE accountid = $1 AND status = 'start';
@@ -684,8 +686,8 @@ RETURNING quiz_id;
-- amo methods:
-- name: CreateAmoAccount :exec
-INSERT INTO users (AccountID, AmoID, Name, Email, Role, "Group", Deleted, CreatedAt, Subdomain, AmoUserID, Country,DriveURL)
-VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12);
+INSERT INTO accountsAmo (AccountID, AmoID,Name, Subdomain, Country,DriveURL)
+VALUES ($1, $2, $3, $4, $5, $6);
-- name: CreateWebHook :exec
INSERT INTO tokens (AccountID, RefreshToken, AccessToken, AuthCode, Expiration, CreatedAt)
@@ -698,61 +700,80 @@ WHERE accountID = $5;
-- name: GetAllTokens :many
SELECT * FROM tokens;
--- name: CheckExpired :many
-SELECT * FROM tokens WHERE Expiration <= TO_TIMESTAMP(EXTRACT(EPOCH FROM NOW()) + (10 * 60));
+-- name: CheckExpiredToken :one
+SELECT * FROM tokens WHERE AccountID = $1 AND Expiration <= NOW();
+
+-- name: UpdateAmoAccount :exec
+UPDATE accountsAmo SET Name = $2, Subdomain = $3, Country = $4, DriveURL = $5 WHERE AccountID = $1 AND Deleted = false;
-- name: WebhookDelete :exec
-WITH userd AS (
- UPDATE users SET Deleted = true WHERE AmoUserID = $1 RETURNING AccountID
-)
-DELETE FROM tokens WHERE AccountID IN (SELECT AccountID FROM userd);
+WITH companyDel AS (
+ UPDATE accountsAmo SET Deleted = true WHERE accountsAmo.AmoID = $1 RETURNING AccountID
+),
+ userDel AS (
+ UPDATE usersAmo SET Deleted = true WHERE AmoID = $1
+ )
+DELETE FROM tokens WHERE AccountID IN (SELECT AccountID FROM companyDel);
-- name: SoftDeleteAccount :exec
-WITH userd AS (
- SELECT AmoUserID FROM users WHERE users.AccountID = $1
+WITH amoCompany AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1
+),usersDel AS (
+ UPDATE usersAmo SET Deleted = true WHERE AmoID = (SELECT AmoID FROM amoCompany)
),
- tokend AS (
- UPDATE users SET Deleted = true WHERE AmoUserID IN (SELECT AmoUserID FROM userd)
+ companyDel AS ( UPDATE accountsAmo SET Deleted = true WHERE AmoID = (SELECT AmoID FROM amoCompany)
)
DELETE FROM tokens WHERE tokens.AccountID = $1;
--- name: GetCurrentAccount :one
-SELECT * FROM users WHERE AccountID = $1 AND Deleted = false;
+-- name: GetCurrentCompany :one
+SELECT * FROM accountsAmo WHERE AccountID = $1 AND Deleted = false;
--- name: CheckMainUser :exec
-UPDATE users SET Name = $1, "Group" = $2, Email = $3, Role = $4 WHERE AmoID = $5;
+-- name: GetAllCompanyUsers :many
+SELECT * FROM usersamo WHERE amoid = $1 AND deleted = false;
-- name: GetUsersWithPagination :many
WITH user_data AS (
- SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
-SELECT u.*, COUNT(*) OVER() as total_count
-FROM users u
-JOIN user_data a ON u.AmoUserID = a.AmoID
+SELECT u.*, COUNT(*) OVER() as total_count
+FROM usersAmo u
+ JOIN user_data a ON u.AmoID = a.AmoID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetTagsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT t.*, COUNT(*) OVER() as total_count
-FROM tags t JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON t.AccountID = u.AmoID
+FROM tags t JOIN user_data u ON t.AccountID = u.AmoID
WHERE t.Deleted = false
ORDER BY t.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetStepsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT s.*, COUNT(*) OVER() as total_count
-FROM steps s JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON s.AccountID = u.AmoID
+FROM steps s JOIN user_data u ON s.AccountID = u.AmoID
WHERE s.Deleted = false AND PipelineID = $4
ORDER BY s.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetPipelinesWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT p.*, COUNT(*) OVER() as total_count
-FROM pipelines p JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON p.AccountID = u.AmoID
+FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID
WHERE p.Deleted = false
ORDER BY p.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetFieldsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT f.*, COUNT(*) OVER() as total_count
-FROM fields f JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON f.AccountID = u.AmoID
+FROM fields f JOIN user_data u ON f.AccountID = u.AmoID
WHERE f.Deleted = false
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3;
@@ -791,12 +812,10 @@ FROM json_array_elements($1::json) AS update_data
WHERE f.amoID = (update_data ->> 'AmoID')::INT
AND f.accountID = (update_data ->> 'AccountID')::INT
AND f.Entity = (update_data ->> 'Entity')::entitytype;
-
+
-- name: CheckTags :many
WITH user_data AS (
- SELECT AmoID
- FROM users
- WHERE users.AccountID = $1
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
), new_tags AS (
SELECT (tag->>'AmoID')::INT AS amoID,
(tag->>'Entity')::entitytype AS Entity,
@@ -818,7 +837,7 @@ WITH user_data AS (
)
SELECT nt.*,ud.AmoID
FROM new_tags nt
- JOIN user_data ud ON true
+ JOIN user_data ud ON true
WHERE NOT EXISTS (
SELECT *
FROM inserted_tags ins
@@ -836,14 +855,14 @@ WITH new_pipelines AS (
FROM json_array_elements($1::json) AS pipeline
), inserted_pipelines AS(
INSERT INTO pipelines (amoID, accountID, name, isArchive, createdAt)
- SELECT np.amoID,
- np.accountID,
- np.name,
- np.isArchive,
- np.createdAt
- FROM new_pipelines np
- ON CONFLICT (amoID, accountID) DO NOTHING
- RETURNING *
+ SELECT np.amoID,
+ np.accountID,
+ np.name,
+ np.isArchive,
+ np.createdAt
+ FROM new_pipelines np
+ ON CONFLICT (amoID, accountID) DO NOTHING
+ RETURNING *
)
SELECT np.*
FROM new_pipelines np
@@ -855,34 +874,32 @@ WHERE NOT EXISTS (
-- name: CheckFields :many
WITH user_data AS (
- SELECT AmoID
- FROM users
- WHERE users.AccountID = $1
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
), new_fields AS (
SELECT (field->>'AmoID')::INT AS amoID,
- COALESCE(field->>'Code', '')::varchar(255) AS code,
- COALESCE(field->>'Name', '')::varchar(512) AS name,
- CAST(field->>'Entity' AS entitytype) AS Entity,
- COALESCE(field->>'Type', '')::fieldtype AS type,
- CURRENT_TIMESTAMP AS createdAt
+ COALESCE(field->>'Code', '')::varchar(255) AS code,
+ COALESCE(field->>'Name', '')::varchar(512) AS name,
+ CAST(field->>'Entity' AS entitytype) AS Entity,
+ COALESCE(field->>'Type', '')::fieldtype AS type,
+ CURRENT_TIMESTAMP AS createdAt
FROM json_array_elements($2::json) AS field
), inserted_fields AS(
INSERT INTO fields (amoID, code, accountID, name, Entity, type, createdAt)
- SELECT nf.amoID,
- nf.code,
- ud.AmoID,
- nf.name,
- nf.Entity,
- nf.type,
- nf.createdAt
- FROM new_fields nf
- JOIN user_data ud ON true
- ON CONFLICT (amoID, accountID, entity) DO NOTHING
- RETURNING *
+ SELECT nf.amoID,
+ nf.code,
+ ud.AmoID,
+ nf.name,
+ nf.Entity,
+ nf.type,
+ nf.createdAt
+ FROM new_fields nf
+ JOIN user_data ud ON true
+ ON CONFLICT (amoID, accountID, entity) DO NOTHING
+ RETURNING *
)
SELECT nf.*,ud.AmoID
FROM new_fields nf
- JOIN user_data ud ON true
+ JOIN user_data ud ON true
WHERE NOT EXISTS (
SELECT *
FROM inserted_fields ins
@@ -901,15 +918,15 @@ WITH new_steps AS (
FROM json_array_elements($1::json) AS step
), inserted_steps AS (
INSERT INTO steps (amoID, pipelineID, accountID, name, color, createdAt)
- SELECT ns.amoID,
- ns.pipelineID,
- ns.accountID,
- ns.name,
- ns.color,
- ns.createdAt
- FROM new_steps ns
- ON CONFLICT (amoID, accountID, PipelineID) DO NOTHING
- RETURNING *
+ SELECT ns.amoID,
+ ns.pipelineID,
+ ns.accountID,
+ ns.name,
+ ns.color,
+ ns.createdAt
+ FROM new_steps ns
+ ON CONFLICT (amoID, accountID, PipelineID) DO NOTHING
+ RETURNING *
)
SELECT ns.*
FROM new_steps ns
@@ -928,13 +945,13 @@ SELECT * FROM rules WHERE QuizID = $1 AND Deleted = false;
-- name: SetQuizSettings :one
INSERT INTO rules (AccountID, QuizID, PerformerID, PipelineID, StepID, FieldsRule,TagsToAdd)
SELECT u.AmoID AS AccountID,$1 AS QuizID,$2 AS PerformerID,$3 AS PipelineID,
- $4 AS StepID,$5 AS FieldsRule,$6 AS TagsToAdd FROM users u WHERE u.AccountID = $7 AND u.Deleted = false
- RETURNING id;
+ $4 AS StepID,$5 AS FieldsRule,$6 AS TagsToAdd FROM accountsamo u WHERE u.AccountID = $7 AND u.Deleted = false
+RETURNING id;
-- name: ChangeQuizSettings :one
UPDATE rules
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5
-WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $6 AND users.Deleted = false) AND QuizID = $7 AND Deleted = false
+WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7 AND Deleted = false
RETURNING id;
-- name: GetQuestionListByIDs :many
@@ -942,62 +959,29 @@ SELECT * FROM question WHERE id = ANY($1::int[]) AND deleted = FALSE;
-- name: UpdateFieldRules :exec
UPDATE rules SET FieldsRule = $1
-WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $2 AND users.Deleted = false) AND QuizID = $3 AND Deleted = false;
+WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $2 AND accountsAmo.Deleted = false) AND QuizID = $3 AND Deleted = false;
--- name: UpdateUsers :exec
-UPDATE users AS u
-SET Name = (update_data ->> 'Name')::varchar(512),
- Email = (update_data ->> 'Email')::varchar(50),
- Role = (update_data ->> 'Role')::INT,
- "Group" = (update_data ->> 'Group')::INT,
- AmoUserID= (update_data ->> 'AmoUserID')::INT
-FROM json_array_elements($1::json) AS update_data
-WHERE u.AmoID = (update_data ->> 'AmocrmID')::INT;
+-- name: UpdateAmoAccountUser :exec
+UPDATE usersAmo SET Name = $3, Email = $4, Role = $5, "Group" = $6
+WHERE AmoID = $1 AND AmoUserID = $2 AND deleted = false;
--- name: CheckUsers :many
-WITH new_users AS (
- SELECT (u->>'AmocrmID')::INT AS AmoID,
- (u->>'Name')::VARCHAR(512) AS Name,
- (u->>'Group')::INT AS "Group",
- (u->>'Role')::INT AS Role,
- (u->>'Email')::VARCHAR(50) AS Email,
- (u->>'AmoUserID')::INT AS AmoUserID,
- CURRENT_TIMESTAMP AS createdAt
- FROM json_array_elements($1::json) AS u
-), inserted_users AS (
- INSERT INTO users (AmoID, Name, "Group", Role, Email, AmoUserID,createdAt)
- SELECT nu.AmoID,
- nu.Name,
- nu."Group",
- nu.Role,
- nu.Email,
- nu.AmoUserID,
- nu.createdAt
- FROM new_users nu
- ON CONFLICT (amoID) DO NOTHING
- RETURNING *
-)
-SELECT nu.*
-FROM new_users nu
-WHERE NOT EXISTS (
- SELECT *
- FROM inserted_users ins
- WHERE ins.amoID = nu.amoID
-);
+-- name: AddAmoAccountUser :exec
+INSERT INTO usersAmo (AmoID, AmoUserID, Name, Email, Role, "Group")
+VALUES ($1, $2, $3, $4, $5, $6);
-- name: GettingAmoUsersTrueResults :many
SELECT a.quiz_id,a.id,a.result,a.question_id,a.content,a.session,
- (SELECT a2.utm
- FROM answer a2
- WHERE a2.start = true AND a2.session = a.session
- LIMIT 1) AS utm
-,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM users u WHERE u.amoid = r.performerid) AS performer_name,u.subdomain,u.accountid,u.driveurl
+ COALESCE((SELECT a2.utm
+ FROM answer a2
+ WHERE a2.start = true AND a2.session = a.session
+ LIMIT 1), '{}'::jsonb) AS utm
+ ,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
FROM answer a
INNER JOIN quiz q ON a.quiz_id = q.id
LEFT JOIN amoCRMStatuses s ON a.id = s.AnswerID
INNER JOIN rules r ON q.id = r.QuizID
INNER JOIN tokens t ON q.accountid = t.AccountID
- INNER JOIN users u ON q.accountid = u.accountid AND u.amoid = r.accountid
+ INNER JOIN accountsAmo u ON q.accountid = u.accountid AND u.amoid = r.accountid
WHERE a.result = true
AND s.id IS NULL
AND a.deleted = false
@@ -1009,12 +993,12 @@ WHERE a.result = true
INSERT INTO amoCRMStatuses (AccountID, DealID, AnswerID, Status)
SELECT u.AmoID, $1, $2, $3
FROM tokens AS t
- JOIN users AS u ON t.AccountID = u.AccountID
+ JOIN accountsAmo AS u ON t.AccountID = u.AccountID
WHERE t.AccessToken = $4 AND u.Deleted = false;
-- name: UpdatingDealAmoStatus :exec
UPDATE amoCRMStatuses SET Status = $1
-WHERE DealID = $2 AND AccountID = (SELECT u.AmoID FROM tokens AS t JOIN users AS u ON t.AccountID = u.AccountID WHERE t.AccessToken = $3 AND u.Deleted = false);
+WHERE DealID = $2 AND AccountID = (SELECT u.AmoID FROM tokens AS t JOIN accountsAmo AS u ON t.AccountID = u.AccountID WHERE t.AccessToken = $3 AND u.Deleted = false);
-- name: DeleteFields :exec
UPDATE fields SET Deleted = true WHERE ID = ANY($1::bigint[]);
@@ -1029,7 +1013,7 @@ UPDATE steps SET Deleted = true WHERE ID = ANY($1::bigint[]);
UPDATE pipelines SET Deleted = true WHERE ID = ANY($1::bigint[]);
-- name: DeleteUsers :exec
-UPDATE users SET Deleted = true WHERE ID = ANY($1::bigint[]);
+UPDATE usersAmo SET Deleted = true WHERE ID = ANY($1::bigint[]);
-- name: GetUserTagsByID :many
SELECT ID,AmoID,AccountID,Name,Entity,Color
@@ -1047,9 +1031,7 @@ FROM pipelines
WHERE AccountID = $1 AND Deleted = false;
-- name: GetUserUsersByID :many
-SELECT ID,AccountID,AmoID,Name,Email,Role,"Group",Subdomain,AmoUserID,Country
-FROM users
-WHERE AmoUserID = $1 AND Deleted = false;
+SELECT * FROM usersAmo WHERE amoid = $1 AND Deleted = false;
-- name: GetFieldByAmoID :one
SELECT * FROM fields WHERE AmoID = $1 AND Deleted = false;
@@ -1062,7 +1044,19 @@ WHERE AccountID = $1 AND Deleted = false;
-- name: DecrementManual :one
UPDATE privileges p SET amount = amount - 1 FROM account a
WHERE p.account_id = a.id AND a.user_id = $1 AND p.privilegeID = $2 AND p.amount > 0
-RETURNING p.id, p.privilegeID, p.account_id, p.privilege_name, p.amount, p.created_at;;
+RETURNING p.id, p.privilegeID, p.account_id, p.privilege_name, p.amount, p.created_at;
+
+-- name: GetExistingContactAmo :many
+WITH getAmoID AS (
+ SELECT AmoID FROM amoContact WHERE amoContact.AccountID = $1 AND amoContact.Field = ANY($2::text[])
+) SELECT * FROM amoContact
+WHERE amoContact.AccountID = $1 AND amoContact.AmoID IN (SELECT AmoID FROM getAmoID);
+
+-- name: InsertContactAmo :one
+INSERT INTO amoContact (AccountID, AmoID, Field) VALUES ($1, $2, $3) RETURNING AmoID;
+
+-- name: UpdateAmoContact :exec
+UPDATE amoContact SET Field = $1,AmoID=$3 WHERE ID = $2;
-- name: CreateLeadTarget :one
INSERT INTO leadtarget (accountID,type,quizID,target) VALUES ($1,$2,$3,$4) RETURNING *;
diff --git a/dal/schema/000014_init.down.sql b/dal/schema/000014_init.down.sql
new file mode 100644
index 0000000..5ddb16f
--- /dev/null
+++ b/dal/schema/000014_init.down.sql
@@ -0,0 +1,20 @@
+DROP TABLE IF EXISTS usersAmo;
+DROP INDEX IF EXISTS idx_unique_accountsAmo;
+DROP TABLE IF EXISTS accountsAmo;
+
+CREATE TABLE IF NOT EXISTS users (
+ ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
+ AccountID VARCHAR(30) NOT NULL DEFAULT '', -- id квизе из токена
+ AmoID INT NOT NULL , -- id в амо
+ Name VARCHAR(512) NOT NULL DEFAULT '', -- имя в амо
+ Email VARCHAR(50) NOT NULL DEFAULT '', -- почта в амо
+ Role INT NOT NULL DEFAULT 0, -- роль в амо
+ "Group" INT NOT NULL DEFAULT 0, -- вложенная структура так как в амо группы хранятся массивом структур
+ Deleted BOOLEAN NOT NULL DEFAULT FALSE,
+ CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ Subdomain VARCHAR(50) NOT NULL DEFAULT '',
+ AmoUserID INT NOT NULL , -- id пользователя который подключал интеграцию
+ Country VARCHAR(50) NOT NULL DEFAULT '' -- страна в амо
+);
+
+CREATE UNIQUE INDEX idx_unique_users ON users (amoID) WHERE Deleted = false;
\ No newline at end of file
diff --git a/dal/schema/000014_init.up.sql b/dal/schema/000014_init.up.sql
new file mode 100644
index 0000000..9542bbb
--- /dev/null
+++ b/dal/schema/000014_init.up.sql
@@ -0,0 +1,28 @@
+DROP TABLE IF EXISTS users;
+DROP INDEX IF EXISTS idx_unique_users;
+
+CREATE TABLE IF NOT EXISTS accountsAmo (
+ ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
+ AccountID VARCHAR(30) NOT NULL DEFAULT '', -- ID аккаунта у нас
+ AmoID INT NOT NULL, -- ID "компании" в амо
+ Name VARCHAR(512) NOT NULL DEFAULT '',
+ Deleted BOOLEAN NOT NULL DEFAULT FALSE,
+ CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ Subdomain VARCHAR(50) NOT NULL DEFAULT '', -- поддомен - пример https://penadigitaltech.amocrm.ru
+ Country VARCHAR(50) NOT NULL DEFAULT '',
+ DriveURL VARCHAR(255) NOT NULL DEFAULT '' -- URL объктного хранилища
+);
+
+CREATE UNIQUE INDEX idx_unique_accountsAmo ON accountsAmo (amoID) WHERE Deleted = false;
+
+CREATE TABLE IF NOT EXISTS usersAmo (
+ ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
+ AmoID INT NOT NULL, -- ID компании в амо (внешний ключ)
+ AmoUserID INT NOT NULL, -- ID пользователя в амо
+ Name VARCHAR(512) NOT NULL DEFAULT '',
+ Email VARCHAR(50) NOT NULL DEFAULT '',
+ Role INT NOT NULL DEFAULT 0,
+ "Group" INT NOT NULL DEFAULT 0,
+ Deleted BOOLEAN NOT NULL DEFAULT FALSE,
+ CreatedAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
\ No newline at end of file
diff --git a/dal/schema/000015_init.down.sql b/dal/schema/000015_init.down.sql
new file mode 100644
index 0000000..e69de29
diff --git a/dal/schema/000015_init.up.sql b/dal/schema/000015_init.up.sql
new file mode 100644
index 0000000..3985517
--- /dev/null
+++ b/dal/schema/000015_init.up.sql
@@ -0,0 +1,19 @@
+UPDATE answer
+SET content =
+ CASE
+ WHEN content ~ '
|' THEN
+ regexp_replace(content, '<\/?tr[^>]*>|<\/?td[^>]*>', '', 'g')
+ WHEN content ~ '[^<]+' THEN
+ regexp_replace(content, '([^<]+)', '\1', 'g')
+ WHEN content ~ ' ]*src="([^"]*)"[^>]*' THEN
+ regexp_replace(content, ' ]*src="\s*"[^>]*', '', 'g')
+ ELSE content
+ END;
+
+UPDATE answer
+SET content =
+ CASE
+ WHEN content ~ ' ]*src=["'']?([^"''>]+)["'']?[^>]*>)', '\1\3', 'g')
+ ELSE content
+ END;
diff --git a/dal/schema/000016_init.down.sql b/dal/schema/000016_init.down.sql
new file mode 100644
index 0000000..28b2333
--- /dev/null
+++ b/dal/schema/000016_init.down.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS amoContact;
\ No newline at end of file
diff --git a/dal/schema/000016_init.up.sql b/dal/schema/000016_init.up.sql
new file mode 100644
index 0000000..a4866d0
--- /dev/null
+++ b/dal/schema/000016_init.up.sql
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS amoContact (
+ ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
+ AccountID INT NOT NULL, -- ID "компании" в амо
+ AmoID INT NOT NULL, -- ID контакта в амо
+ Field text NOT NULL DEFAULT '' -- значение чего то email? phone? etc
+)
\ No newline at end of file
diff --git a/dal/sqlcgen/models.go b/dal/sqlcgen/models.go
index 2bf4670..448fa8a 100644
--- a/dal/sqlcgen/models.go
+++ b/dal/sqlcgen/models.go
@@ -19,6 +19,25 @@ type Account struct {
Deleted sql.NullBool `db:"deleted" json:"deleted"`
}
+type Accountsamo struct {
+ ID int64 `db:"id" json:"id"`
+ Accountid string `db:"accountid" json:"accountid"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Name string `db:"name" json:"name"`
+ Deleted bool `db:"deleted" json:"deleted"`
+ Createdat time.Time `db:"createdat" json:"createdat"`
+ Subdomain string `db:"subdomain" json:"subdomain"`
+ Country string `db:"country" json:"country"`
+ Driveurl string `db:"driveurl" json:"driveurl"`
+}
+
+type Amocontact struct {
+ ID int64 `db:"id" json:"id"`
+ Accountid int32 `db:"accountid" json:"accountid"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Field string `db:"field" json:"field"`
+}
+
type Amocrmstatus struct {
ID int64 `db:"id" json:"id"`
Accountid int32 `db:"accountid" json:"accountid"`
@@ -182,18 +201,14 @@ type Token struct {
Createdat sql.NullTime `db:"createdat" json:"createdat"`
}
-type User struct {
- ID int64 `db:"id" json:"id"`
- Accountid string `db:"accountid" json:"accountid"`
- Amoid int32 `db:"amoid" json:"amoid"`
- Name string `db:"name" json:"name"`
- Email string `db:"email" json:"email"`
- Role int32 `db:"role" json:"role"`
- Group int32 `db:"Group" json:"Group"`
- Deleted bool `db:"deleted" json:"deleted"`
- Createdat sql.NullTime `db:"createdat" json:"createdat"`
- Subdomain string `db:"subdomain" json:"subdomain"`
- Amouserid int32 `db:"amouserid" json:"amouserid"`
- Country string `db:"country" json:"country"`
- Driveurl string `db:"driveurl" json:"driveurl"`
+type Usersamo struct {
+ ID int64 `db:"id" json:"id"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Amouserid int32 `db:"amouserid" json:"amouserid"`
+ Name string `db:"name" json:"name"`
+ Email string `db:"email" json:"email"`
+ Role int32 `db:"role" json:"role"`
+ Group int32 `db:"Group" json:"Group"`
+ Deleted bool `db:"deleted" json:"deleted"`
+ Createdat time.Time `db:"createdat" json:"createdat"`
}
diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go
index c2f2ebc..736febf 100644
--- a/dal/sqlcgen/queries.sql.go
+++ b/dal/sqlcgen/queries.sql.go
@@ -53,6 +53,32 @@ func (q *Queries) AccountPagination(ctx context.Context, arg AccountPaginationPa
return items, nil
}
+const addAmoAccountUser = `-- name: AddAmoAccountUser :exec
+INSERT INTO usersAmo (AmoID, AmoUserID, Name, Email, Role, "Group")
+VALUES ($1, $2, $3, $4, $5, $6)
+`
+
+type AddAmoAccountUserParams struct {
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Amouserid int32 `db:"amouserid" json:"amouserid"`
+ Name string `db:"name" json:"name"`
+ Email string `db:"email" json:"email"`
+ Role int32 `db:"role" json:"role"`
+ Group int32 `db:"Group" json:"Group"`
+}
+
+func (q *Queries) AddAmoAccountUser(ctx context.Context, arg AddAmoAccountUserParams) error {
+ _, err := q.db.ExecContext(ctx, addAmoAccountUser,
+ arg.Amoid,
+ arg.Amouserid,
+ arg.Name,
+ arg.Email,
+ arg.Role,
+ arg.Group,
+ )
+ return err
+}
+
const allServiceStatistics = `-- name: AllServiceStatistics :one
WITH Registrations AS (
SELECT COUNT(*) AS registration_count
@@ -110,7 +136,7 @@ func (q *Queries) ArchiveQuiz(ctx context.Context, arg ArchiveQuizParams) error
const changeQuizSettings = `-- name: ChangeQuizSettings :one
UPDATE rules
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5
-WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $6 AND users.Deleted = false) AND QuizID = $7 AND Deleted = false
+WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7 AND Deleted = false
RETURNING id
`
@@ -157,45 +183,27 @@ func (q *Queries) CheckAndAddDefault(ctx context.Context, arg CheckAndAddDefault
return err
}
-const checkExpired = `-- name: CheckExpired :many
-SELECT accountid, refreshtoken, accesstoken, authcode, expiration, createdat FROM tokens WHERE Expiration <= TO_TIMESTAMP(EXTRACT(EPOCH FROM NOW()) + (10 * 60))
+const checkExpiredToken = `-- name: CheckExpiredToken :one
+SELECT accountid, refreshtoken, accesstoken, authcode, expiration, createdat FROM tokens WHERE AccountID = $1 AND Expiration <= NOW()
`
-func (q *Queries) CheckExpired(ctx context.Context) ([]Token, error) {
- rows, err := q.db.QueryContext(ctx, checkExpired)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- var items []Token
- for rows.Next() {
- var i Token
- if err := rows.Scan(
- &i.Accountid,
- &i.Refreshtoken,
- &i.Accesstoken,
- &i.Authcode,
- &i.Expiration,
- &i.Createdat,
- ); err != nil {
- return nil, err
- }
- items = append(items, i)
- }
- if err := rows.Close(); err != nil {
- return nil, err
- }
- if err := rows.Err(); err != nil {
- return nil, err
- }
- return items, nil
+func (q *Queries) CheckExpiredToken(ctx context.Context, accountid string) (Token, error) {
+ row := q.db.QueryRowContext(ctx, checkExpiredToken, accountid)
+ var i Token
+ err := row.Scan(
+ &i.Accountid,
+ &i.Refreshtoken,
+ &i.Accesstoken,
+ &i.Authcode,
+ &i.Expiration,
+ &i.Createdat,
+ )
+ return i, err
}
const checkFields = `-- name: CheckFields :many
WITH user_data AS (
- SELECT AmoID
- FROM users
- WHERE users.AccountID = $1
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
), new_fields AS (
SELECT (field->>'AmoID')::INT AS amoID,
COALESCE(field->>'Code', '')::varchar(255) AS code,
@@ -275,29 +283,6 @@ func (q *Queries) CheckFields(ctx context.Context, arg CheckFieldsParams) ([]Che
return items, nil
}
-const checkMainUser = `-- name: CheckMainUser :exec
-UPDATE users SET Name = $1, "Group" = $2, Email = $3, Role = $4 WHERE AmoID = $5
-`
-
-type CheckMainUserParams struct {
- Name string `db:"name" json:"name"`
- Group int32 `db:"Group" json:"Group"`
- Email string `db:"email" json:"email"`
- Role int32 `db:"role" json:"role"`
- Amoid int32 `db:"amoid" json:"amoid"`
-}
-
-func (q *Queries) CheckMainUser(ctx context.Context, arg CheckMainUserParams) error {
- _, err := q.db.ExecContext(ctx, checkMainUser,
- arg.Name,
- arg.Group,
- arg.Email,
- arg.Role,
- arg.Amoid,
- )
- return err
-}
-
const checkPipelines = `-- name: CheckPipelines :many
WITH new_pipelines AS (
SELECT (pipeline->>'AmoID')::INT AS amoID,
@@ -480,9 +465,7 @@ func (q *Queries) CheckSteps(ctx context.Context, dollar_1 json.RawMessage) ([]C
const checkTags = `-- name: CheckTags :many
WITH user_data AS (
- SELECT AmoID
- FROM users
- WHERE users.AccountID = $1
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
), new_tags AS (
SELECT (tag->>'AmoID')::INT AS amoID,
(tag->>'Entity')::entitytype AS Entity,
@@ -555,79 +538,6 @@ func (q *Queries) CheckTags(ctx context.Context, arg CheckTagsParams) ([]CheckTa
return items, nil
}
-const checkUsers = `-- name: CheckUsers :many
-WITH new_users AS (
- SELECT (u->>'AmocrmID')::INT AS AmoID,
- (u->>'Name')::VARCHAR(512) AS Name,
- (u->>'Group')::INT AS "Group",
- (u->>'Role')::INT AS Role,
- (u->>'Email')::VARCHAR(50) AS Email,
- (u->>'AmoUserID')::INT AS AmoUserID,
- CURRENT_TIMESTAMP AS createdAt
- FROM json_array_elements($1::json) AS u
-), inserted_users AS (
- INSERT INTO users (AmoID, Name, "Group", Role, Email, AmoUserID,createdAt)
- SELECT nu.AmoID,
- nu.Name,
- nu."Group",
- nu.Role,
- nu.Email,
- nu.AmoUserID,
- nu.createdAt
- FROM new_users nu
- ON CONFLICT (amoID) DO NOTHING
- RETURNING id, accountid, amoid, name, email, role, "Group", deleted, createdat, subdomain, amouserid, country, driveurl
-)
-SELECT nu.amoid, nu.name, nu."Group", nu.role, nu.email, nu.amouserid, nu.createdat
-FROM new_users nu
-WHERE NOT EXISTS (
- SELECT id, accountid, amoid, name, email, role, "Group", deleted, createdat, subdomain, amouserid, country, driveurl
- FROM inserted_users ins
- WHERE ins.amoID = nu.amoID
-)
-`
-
-type CheckUsersRow struct {
- Amoid int32 `db:"amoid" json:"amoid"`
- Name string `db:"name" json:"name"`
- Group int32 `db:"Group" json:"Group"`
- Role int32 `db:"role" json:"role"`
- Email string `db:"email" json:"email"`
- Amouserid int32 `db:"amouserid" json:"amouserid"`
- Createdat interface{} `db:"createdat" json:"createdat"`
-}
-
-func (q *Queries) CheckUsers(ctx context.Context, dollar_1 json.RawMessage) ([]CheckUsersRow, error) {
- rows, err := q.db.QueryContext(ctx, checkUsers, dollar_1)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- var items []CheckUsersRow
- for rows.Next() {
- var i CheckUsersRow
- if err := rows.Scan(
- &i.Amoid,
- &i.Name,
- &i.Group,
- &i.Role,
- &i.Email,
- &i.Amouserid,
- &i.Createdat,
- ); err != nil {
- return nil, err
- }
- items = append(items, i)
- }
- if err := rows.Close(); err != nil {
- return nil, err
- }
- if err := rows.Err(); err != nil {
- return nil, err
- }
- return items, nil
-}
-
const copyQuestion = `-- name: CopyQuestion :one
INSERT INTO question(
quiz_id, title, description, questiontype, required,
@@ -770,23 +680,17 @@ func (q *Queries) CreateAccount(ctx context.Context, arg CreateAccountParams) (A
const createAmoAccount = `-- name: CreateAmoAccount :exec
-INSERT INTO users (AccountID, AmoID, Name, Email, Role, "Group", Deleted, CreatedAt, Subdomain, AmoUserID, Country,DriveURL)
-VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
+INSERT INTO accountsAmo (AccountID, AmoID,Name, Subdomain, Country,DriveURL)
+VALUES ($1, $2, $3, $4, $5, $6)
`
type CreateAmoAccountParams struct {
- Accountid string `db:"accountid" json:"accountid"`
- Amoid int32 `db:"amoid" json:"amoid"`
- Name string `db:"name" json:"name"`
- Email string `db:"email" json:"email"`
- Role int32 `db:"role" json:"role"`
- Group int32 `db:"Group" json:"Group"`
- Deleted bool `db:"deleted" json:"deleted"`
- Createdat sql.NullTime `db:"createdat" json:"createdat"`
- Subdomain string `db:"subdomain" json:"subdomain"`
- Amouserid int32 `db:"amouserid" json:"amouserid"`
- Country string `db:"country" json:"country"`
- Driveurl string `db:"driveurl" json:"driveurl"`
+ Accountid string `db:"accountid" json:"accountid"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Name string `db:"name" json:"name"`
+ Subdomain string `db:"subdomain" json:"subdomain"`
+ Country string `db:"country" json:"country"`
+ Driveurl string `db:"driveurl" json:"driveurl"`
}
// amo methods:
@@ -795,13 +699,7 @@ func (q *Queries) CreateAmoAccount(ctx context.Context, arg CreateAmoAccountPara
arg.Accountid,
arg.Amoid,
arg.Name,
- arg.Email,
- arg.Role,
- arg.Group,
- arg.Deleted,
- arg.Createdat,
arg.Subdomain,
- arg.Amouserid,
arg.Country,
arg.Driveurl,
)
@@ -1034,7 +932,7 @@ func (q *Queries) DeleteTags(ctx context.Context, dollar_1 []int64) error {
}
const deleteUsers = `-- name: DeleteUsers :exec
-UPDATE users SET Deleted = true WHERE ID = ANY($1::bigint[])
+UPDATE usersAmo SET Deleted = true WHERE ID = ANY($1::bigint[])
`
func (q *Queries) DeleteUsers(ctx context.Context, dollar_1 []int64) error {
@@ -1486,6 +1384,43 @@ func (q *Queries) GetAllAnswersByQuizID(ctx context.Context, session sql.NullStr
return items, nil
}
+const getAllCompanyUsers = `-- name: GetAllCompanyUsers :many
+SELECT id, amoid, amouserid, name, email, role, "Group", deleted, createdat FROM usersamo WHERE amoid = $1 AND deleted = false
+`
+
+func (q *Queries) GetAllCompanyUsers(ctx context.Context, amoid int32) ([]Usersamo, error) {
+ rows, err := q.db.QueryContext(ctx, getAllCompanyUsers, amoid)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var items []Usersamo
+ for rows.Next() {
+ var i Usersamo
+ if err := rows.Scan(
+ &i.ID,
+ &i.Amoid,
+ &i.Amouserid,
+ &i.Name,
+ &i.Email,
+ &i.Role,
+ &i.Group,
+ &i.Deleted,
+ &i.Createdat,
+ ); err != nil {
+ return nil, err
+ }
+ items = append(items, i)
+ }
+ if err := rows.Close(); err != nil {
+ return nil, err
+ }
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}
+
const getAllTokens = `-- name: GetAllTokens :many
SELECT accountid, refreshtoken, accesstoken, authcode, expiration, createdat FROM tokens
`
@@ -1520,31 +1455,67 @@ func (q *Queries) GetAllTokens(ctx context.Context) ([]Token, error) {
return items, nil
}
-const getCurrentAccount = `-- name: GetCurrentAccount :one
-SELECT id, accountid, amoid, name, email, role, "Group", deleted, createdat, subdomain, amouserid, country, driveurl FROM users WHERE AccountID = $1 AND Deleted = false
+const getCurrentCompany = `-- name: GetCurrentCompany :one
+SELECT id, accountid, amoid, name, deleted, createdat, subdomain, country, driveurl FROM accountsAmo WHERE AccountID = $1 AND Deleted = false
`
-func (q *Queries) GetCurrentAccount(ctx context.Context, accountid string) (User, error) {
- row := q.db.QueryRowContext(ctx, getCurrentAccount, accountid)
- var i User
+func (q *Queries) GetCurrentCompany(ctx context.Context, accountid string) (Accountsamo, error) {
+ row := q.db.QueryRowContext(ctx, getCurrentCompany, accountid)
+ var i Accountsamo
err := row.Scan(
&i.ID,
&i.Accountid,
&i.Amoid,
&i.Name,
- &i.Email,
- &i.Role,
- &i.Group,
&i.Deleted,
&i.Createdat,
&i.Subdomain,
- &i.Amouserid,
&i.Country,
&i.Driveurl,
)
return i, err
}
+const getExistingContactAmo = `-- name: GetExistingContactAmo :many
+WITH getAmoID AS (
+ SELECT AmoID FROM amoContact WHERE amoContact.AccountID = $1 AND amoContact.Field = ANY($2::text[])
+) SELECT id, accountid, amoid, field FROM amoContact
+WHERE amoContact.AccountID = $1 AND amoContact.AmoID IN (SELECT AmoID FROM getAmoID)
+`
+
+type GetExistingContactAmoParams struct {
+ Accountid int32 `db:"accountid" json:"accountid"`
+ Column2 []string `db:"column_2" json:"column_2"`
+}
+
+func (q *Queries) GetExistingContactAmo(ctx context.Context, arg GetExistingContactAmoParams) ([]Amocontact, error) {
+ rows, err := q.db.QueryContext(ctx, getExistingContactAmo, arg.Accountid, pq.Array(arg.Column2))
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var items []Amocontact
+ for rows.Next() {
+ var i Amocontact
+ if err := rows.Scan(
+ &i.ID,
+ &i.Accountid,
+ &i.Amoid,
+ &i.Field,
+ ); err != nil {
+ return nil, err
+ }
+ items = append(items, i)
+ }
+ if err := rows.Close(); err != nil {
+ return nil, err
+ }
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}
+
const getExpiredCountPrivilege = `-- name: GetExpiredCountPrivilege :many
SELECT p.id, p.privilegeID, p.privilege_name, p.amount, p.created_at, a.user_id
FROM privileges p
@@ -1661,8 +1632,11 @@ func (q *Queries) GetFieldByAmoID(ctx context.Context, amoid int32) (Field, erro
}
const getFieldsWithPagination = `-- name: GetFieldsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT f.id, f.amoid, f.code, f.accountid, f.name, f.entity, f.type, f.deleted, f.createdat, COUNT(*) OVER() as total_count
-FROM fields f JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON f.AccountID = u.AmoID
+FROM fields f JOIN user_data u ON f.AccountID = u.AmoID
WHERE f.Deleted = false
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@@ -1817,8 +1791,11 @@ func (q *Queries) GetListStartQuiz(ctx context.Context, accountid string) ([]int
}
const getPipelinesWithPagination = `-- name: GetPipelinesWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT p.id, p.amoid, p.accountid, p.name, p.isarchive, p.deleted, p.createdat, COUNT(*) OVER() as total_count
-FROM pipelines p JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON p.AccountID = u.AmoID
+FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID
WHERE p.Deleted = false
ORDER BY p.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@@ -2432,8 +2409,11 @@ func (q *Queries) GetResultAnswers(ctx context.Context, id int64) ([]GetResultAn
}
const getStepsWithPagination = `-- name: GetStepsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT s.id, s.amoid, s.pipelineid, s.accountid, s.name, s.color, s.deleted, s.createdat, COUNT(*) OVER() as total_count
-FROM steps s JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON s.AccountID = u.AmoID
+FROM steps s JOIN user_data u ON s.AccountID = u.AmoID
WHERE s.Deleted = false AND PipelineID = $4
ORDER BY s.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@@ -2496,8 +2476,11 @@ func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPa
}
const getTagsWithPagination = `-- name: GetTagsWithPagination :many
+WITH user_data AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
+)
SELECT t.id, t.amoid, t.accountid, t.entity, t.name, t.color, t.deleted, t.createdat, COUNT(*) OVER() as total_count
-FROM tags t JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false) u ON t.AccountID = u.AmoID
+FROM tags t JOIN user_data u ON t.AccountID = u.AmoID
WHERE t.Deleted = false
ORDER BY t.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@@ -2752,44 +2735,28 @@ func (q *Queries) GetUserTagsByID(ctx context.Context, accountid int32) ([]GetUs
}
const getUserUsersByID = `-- name: GetUserUsersByID :many
-SELECT ID,AccountID,AmoID,Name,Email,Role,"Group",Subdomain,AmoUserID,Country
-FROM users
-WHERE AmoUserID = $1 AND Deleted = false
+SELECT id, amoid, amouserid, name, email, role, "Group", deleted, createdat FROM usersAmo WHERE amoid = $1 AND Deleted = false
`
-type GetUserUsersByIDRow struct {
- ID int64 `db:"id" json:"id"`
- Accountid string `db:"accountid" json:"accountid"`
- Amoid int32 `db:"amoid" json:"amoid"`
- Name string `db:"name" json:"name"`
- Email string `db:"email" json:"email"`
- Role int32 `db:"role" json:"role"`
- Group int32 `db:"Group" json:"Group"`
- Subdomain string `db:"subdomain" json:"subdomain"`
- Amouserid int32 `db:"amouserid" json:"amouserid"`
- Country string `db:"country" json:"country"`
-}
-
-func (q *Queries) GetUserUsersByID(ctx context.Context, amouserid int32) ([]GetUserUsersByIDRow, error) {
- rows, err := q.db.QueryContext(ctx, getUserUsersByID, amouserid)
+func (q *Queries) GetUserUsersByID(ctx context.Context, amoid int32) ([]Usersamo, error) {
+ rows, err := q.db.QueryContext(ctx, getUserUsersByID, amoid)
if err != nil {
return nil, err
}
defer rows.Close()
- var items []GetUserUsersByIDRow
+ var items []Usersamo
for rows.Next() {
- var i GetUserUsersByIDRow
+ var i Usersamo
if err := rows.Scan(
&i.ID,
- &i.Accountid,
&i.Amoid,
+ &i.Amouserid,
&i.Name,
&i.Email,
&i.Role,
&i.Group,
- &i.Subdomain,
- &i.Amouserid,
- &i.Country,
+ &i.Deleted,
+ &i.Createdat,
); err != nil {
return nil, err
}
@@ -2806,11 +2773,11 @@ func (q *Queries) GetUserUsersByID(ctx context.Context, amouserid int32) ([]GetU
const getUsersWithPagination = `-- name: GetUsersWithPagination :many
WITH user_data AS (
- SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
-SELECT u.id, u.accountid, u.amoid, u.name, u.email, u.role, u."Group", u.deleted, u.createdat, u.subdomain, u.amouserid, u.country, u.driveurl, COUNT(*) OVER() as total_count
-FROM users u
-JOIN user_data a ON u.AmoUserID = a.AmoID
+SELECT u.id, u.amoid, u.amouserid, u.name, u.email, u.role, u."Group", u.deleted, u.createdat, COUNT(*) OVER() as total_count
+FROM usersAmo u
+ JOIN user_data a ON u.AmoID = a.AmoID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@@ -2822,20 +2789,16 @@ type GetUsersWithPaginationParams struct {
}
type GetUsersWithPaginationRow struct {
- ID int64 `db:"id" json:"id"`
- Accountid string `db:"accountid" json:"accountid"`
- Amoid int32 `db:"amoid" json:"amoid"`
- Name string `db:"name" json:"name"`
- Email string `db:"email" json:"email"`
- Role int32 `db:"role" json:"role"`
- Group int32 `db:"Group" json:"Group"`
- Deleted bool `db:"deleted" json:"deleted"`
- Createdat sql.NullTime `db:"createdat" json:"createdat"`
- Subdomain string `db:"subdomain" json:"subdomain"`
- Amouserid int32 `db:"amouserid" json:"amouserid"`
- Country string `db:"country" json:"country"`
- Driveurl string `db:"driveurl" json:"driveurl"`
- TotalCount int64 `db:"total_count" json:"total_count"`
+ ID int64 `db:"id" json:"id"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Amouserid int32 `db:"amouserid" json:"amouserid"`
+ Name string `db:"name" json:"name"`
+ Email string `db:"email" json:"email"`
+ Role int32 `db:"role" json:"role"`
+ Group int32 `db:"Group" json:"Group"`
+ Deleted bool `db:"deleted" json:"deleted"`
+ Createdat time.Time `db:"createdat" json:"createdat"`
+ TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPaginationParams) ([]GetUsersWithPaginationRow, error) {
@@ -2849,18 +2812,14 @@ func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPa
var i GetUsersWithPaginationRow
if err := rows.Scan(
&i.ID,
- &i.Accountid,
&i.Amoid,
+ &i.Amouserid,
&i.Name,
&i.Email,
&i.Role,
&i.Group,
&i.Deleted,
&i.Createdat,
- &i.Subdomain,
- &i.Amouserid,
- &i.Country,
- &i.Driveurl,
&i.TotalCount,
); err != nil {
return nil, err
@@ -2878,17 +2837,17 @@ func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPa
const gettingAmoUsersTrueResults = `-- name: GettingAmoUsersTrueResults :many
SELECT a.quiz_id,a.id,a.result,a.question_id,a.content,a.session,
- (SELECT a2.utm
+ COALESCE((SELECT a2.utm
FROM answer a2
WHERE a2.start = true AND a2.session = a.session
- LIMIT 1) AS utm
-,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM users u WHERE u.amoid = r.performerid) AS performer_name,u.subdomain,u.accountid,u.driveurl
+ LIMIT 1), '{}'::jsonb) AS utm
+,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
FROM answer a
INNER JOIN quiz q ON a.quiz_id = q.id
LEFT JOIN amoCRMStatuses s ON a.id = s.AnswerID
INNER JOIN rules r ON q.id = r.QuizID
INNER JOIN tokens t ON q.accountid = t.AccountID
- INNER JOIN users u ON q.accountid = u.accountid AND u.amoid = r.accountid
+ INNER JOIN accountsAmo u ON q.accountid = u.accountid AND u.amoid = r.accountid
WHERE a.result = true
AND s.id IS NULL
AND a.deleted = false
@@ -2904,7 +2863,7 @@ type GettingAmoUsersTrueResultsRow struct {
QuestionID int64 `db:"question_id" json:"question_id"`
Content sql.NullString `db:"content" json:"content"`
Session sql.NullString `db:"session" json:"session"`
- Utm json.RawMessage `db:"utm" json:"utm"`
+ Utm interface{} `db:"utm" json:"utm"`
Accesstoken string `db:"accesstoken" json:"accesstoken"`
Accountid int32 `db:"accountid" json:"accountid"`
Fieldsrule json.RawMessage `db:"fieldsrule" json:"fieldsrule"`
@@ -3038,6 +2997,23 @@ func (q *Queries) InsertAnswers(ctx context.Context, arg InsertAnswersParams) (A
return i, err
}
+const insertContactAmo = `-- name: InsertContactAmo :one
+INSERT INTO amoContact (AccountID, AmoID, Field) VALUES ($1, $2, $3) RETURNING AmoID
+`
+
+type InsertContactAmoParams struct {
+ Accountid int32 `db:"accountid" json:"accountid"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Field string `db:"field" json:"field"`
+}
+
+func (q *Queries) InsertContactAmo(ctx context.Context, arg InsertContactAmoParams) (int32, error) {
+ row := q.db.QueryRowContext(ctx, insertContactAmo, arg.Accountid, arg.Amoid, arg.Field)
+ var amoid int32
+ err := row.Scan(&amoid)
+ return amoid, err
+}
+
const insertPrivilege = `-- name: InsertPrivilege :exec
INSERT INTO privileges (privilegeID, account_id, privilege_name, amount, created_at) VALUES ($1, $2, $3, $4, $5)
`
@@ -3439,7 +3415,7 @@ func (q *Queries) QuizCopyQid(ctx context.Context, arg QuizCopyQidParams) (QuizC
const setQuizSettings = `-- name: SetQuizSettings :one
INSERT INTO rules (AccountID, QuizID, PerformerID, PipelineID, StepID, FieldsRule,TagsToAdd)
SELECT u.AmoID AS AccountID,$1 AS QuizID,$2 AS PerformerID,$3 AS PipelineID,
- $4 AS StepID,$5 AS FieldsRule,$6 AS TagsToAdd FROM users u WHERE u.AccountID = $7 AND u.Deleted = false
+ $4 AS StepID,$5 AS FieldsRule,$6 AS TagsToAdd FROM accountsamo u WHERE u.AccountID = $7 AND u.Deleted = false
RETURNING id
`
@@ -3472,7 +3448,7 @@ const settingDealAmoStatus = `-- name: SettingDealAmoStatus :exec
INSERT INTO amoCRMStatuses (AccountID, DealID, AnswerID, Status)
SELECT u.AmoID, $1, $2, $3
FROM tokens AS t
- JOIN users AS u ON t.AccountID = u.AccountID
+ JOIN accountsAmo AS u ON t.AccountID = u.AccountID
WHERE t.AccessToken = $4 AND u.Deleted = false
`
@@ -3494,12 +3470,13 @@ func (q *Queries) SettingDealAmoStatus(ctx context.Context, arg SettingDealAmoSt
}
const softDeleteAccount = `-- name: SoftDeleteAccount :exec
-WITH userd AS (
- SELECT AmoUserID FROM users WHERE users.AccountID = $1
-),
- tokend AS (
- UPDATE users SET Deleted = true WHERE AmoUserID IN (SELECT AmoUserID FROM userd)
- )
+WITH amoCompany AS (
+ SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1
+),usersDel AS (
+ UPDATE usersAmo SET Deleted = true WHERE AmoID = (SELECT AmoID FROM amoCompany)
+ ),
+ companyDel AS ( UPDATE accountsAmo SET Deleted = true WHERE AmoID = (SELECT AmoID FROM amoCompany)
+ )
DELETE FROM tokens WHERE tokens.AccountID = $1
`
@@ -3545,9 +3522,73 @@ func (q *Queries) TemplateCopy(ctx context.Context, arg TemplateCopyParams) (int
return quiz_id, err
}
+const updateAmoAccount = `-- name: UpdateAmoAccount :exec
+UPDATE accountsAmo SET Name = $2, Subdomain = $3, Country = $4, DriveURL = $5 WHERE AccountID = $1 AND Deleted = false
+`
+
+type UpdateAmoAccountParams struct {
+ Accountid string `db:"accountid" json:"accountid"`
+ Name string `db:"name" json:"name"`
+ Subdomain string `db:"subdomain" json:"subdomain"`
+ Country string `db:"country" json:"country"`
+ Driveurl string `db:"driveurl" json:"driveurl"`
+}
+
+func (q *Queries) UpdateAmoAccount(ctx context.Context, arg UpdateAmoAccountParams) error {
+ _, err := q.db.ExecContext(ctx, updateAmoAccount,
+ arg.Accountid,
+ arg.Name,
+ arg.Subdomain,
+ arg.Country,
+ arg.Driveurl,
+ )
+ return err
+}
+
+const updateAmoAccountUser = `-- name: UpdateAmoAccountUser :exec
+UPDATE usersAmo SET Name = $3, Email = $4, Role = $5, "Group" = $6
+WHERE AmoID = $1 AND AmoUserID = $2 AND deleted = false
+`
+
+type UpdateAmoAccountUserParams struct {
+ Amoid int32 `db:"amoid" json:"amoid"`
+ Amouserid int32 `db:"amouserid" json:"amouserid"`
+ Name string `db:"name" json:"name"`
+ Email string `db:"email" json:"email"`
+ Role int32 `db:"role" json:"role"`
+ Group int32 `db:"Group" json:"Group"`
+}
+
+func (q *Queries) UpdateAmoAccountUser(ctx context.Context, arg UpdateAmoAccountUserParams) error {
+ _, err := q.db.ExecContext(ctx, updateAmoAccountUser,
+ arg.Amoid,
+ arg.Amouserid,
+ arg.Name,
+ arg.Email,
+ arg.Role,
+ arg.Group,
+ )
+ return err
+}
+
+const updateAmoContact = `-- name: UpdateAmoContact :exec
+UPDATE amoContact SET Field = $1,AmoID=$3 WHERE ID = $2
+`
+
+type UpdateAmoContactParams struct {
+ Field string `db:"field" json:"field"`
+ ID int64 `db:"id" json:"id"`
+ Amoid int32 `db:"amoid" json:"amoid"`
+}
+
+func (q *Queries) UpdateAmoContact(ctx context.Context, arg UpdateAmoContactParams) error {
+ _, err := q.db.ExecContext(ctx, updateAmoContact, arg.Field, arg.ID, arg.Amoid)
+ return err
+}
+
const updateFieldRules = `-- name: UpdateFieldRules :exec
UPDATE rules SET FieldsRule = $1
-WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $2 AND users.Deleted = false) AND QuizID = $3 AND Deleted = false
+WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $2 AND accountsAmo.Deleted = false) AND QuizID = $3 AND Deleted = false
`
type UpdateFieldRulesParams struct {
@@ -3680,25 +3721,9 @@ func (q *Queries) UpdateTags(ctx context.Context, dollar_1 json.RawMessage) erro
return err
}
-const updateUsers = `-- name: UpdateUsers :exec
-UPDATE users AS u
-SET Name = (update_data ->> 'Name')::varchar(512),
- Email = (update_data ->> 'Email')::varchar(50),
- Role = (update_data ->> 'Role')::INT,
- "Group" = (update_data ->> 'Group')::INT,
- AmoUserID= (update_data ->> 'AmoUserID')::INT
-FROM json_array_elements($1::json) AS update_data
-WHERE u.AmoID = (update_data ->> 'AmocrmID')::INT
-`
-
-func (q *Queries) UpdateUsers(ctx context.Context, dollar_1 json.RawMessage) error {
- _, err := q.db.ExecContext(ctx, updateUsers, dollar_1)
- return err
-}
-
const updatingDealAmoStatus = `-- name: UpdatingDealAmoStatus :exec
UPDATE amoCRMStatuses SET Status = $1
-WHERE DealID = $2 AND AccountID = (SELECT u.AmoID FROM tokens AS t JOIN users AS u ON t.AccountID = u.AccountID WHERE t.AccessToken = $3 AND u.Deleted = false)
+WHERE DealID = $2 AND AccountID = (SELECT u.AmoID FROM tokens AS t JOIN accountsAmo AS u ON t.AccountID = u.AccountID WHERE t.AccessToken = $3 AND u.Deleted = false)
`
type UpdatingDealAmoStatusParams struct {
@@ -3713,14 +3738,17 @@ func (q *Queries) UpdatingDealAmoStatus(ctx context.Context, arg UpdatingDealAmo
}
const webhookDelete = `-- name: WebhookDelete :exec
-WITH userd AS (
- UPDATE users SET Deleted = true WHERE AmoUserID = $1 RETURNING AccountID
+WITH companyDel AS (
+ UPDATE accountsAmo SET Deleted = true WHERE accountsAmo.AmoID = $1 RETURNING AccountID
+),
+userDel AS (
+UPDATE usersAmo SET Deleted = true WHERE AmoID = $1
)
-DELETE FROM tokens WHERE AccountID IN (SELECT AccountID FROM userd)
+DELETE FROM tokens WHERE AccountID IN (SELECT AccountID FROM companyDel)
`
-func (q *Queries) WebhookDelete(ctx context.Context, amouserid int32) error {
- _, err := q.db.ExecContext(ctx, webhookDelete, amouserid)
+func (q *Queries) WebhookDelete(ctx context.Context, amoid int32) error {
+ _, err := q.db.ExecContext(ctx, webhookDelete, amoid)
return err
}
diff --git a/go.mod b/go.mod
index b30afc3..f5c6edf 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module penahub.gitlab.yandexcloud.net/backend/quiz/common.git
go 1.21.4
require (
+ github.com/ClickHouse/clickhouse-go v1.5.4
github.com/gofiber/fiber/v2 v2.52.0
github.com/golang-jwt/jwt/v5 v5.2.0
github.com/golang/protobuf v1.5.3
@@ -19,6 +20,7 @@ require (
require (
github.com/andybalholm/brotli v1.0.5 // indirect
+ github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/go-cmp v0.6.0 // indirect
diff --git a/go.sum b/go.sum
index e82a594..d047566 100644
--- a/go.sum
+++ b/go.sum
@@ -1,12 +1,19 @@
+github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
+github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
+github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
+github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
+github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
@@ -20,6 +27,7 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
@@ -32,6 +40,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -41,6 +50,7 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=
@@ -52,6 +62,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
diff --git a/model/amo.go b/model/amo.go
index b5bf0ea..5a0dae0 100644
--- a/model/amo.go
+++ b/model/amo.go
@@ -1,32 +1,30 @@
package model
-type User struct {
- /* - айдишник в нашей системе Primary Key*/
- ID int64 `json:"ID"`
- /* - id пользователя из токена в нашей системе*/
- Accountid string `json:"AccountID"`
- /* - айдишник пользователя в амо*/
- AmoID int32 `json:"AmocrmID"`
- /* - имя аккаунта в амо*/
- Name string `json:"Name"`
- /* - почта пользователя из амо*/
- Email string `json:"Email"`
- /* - роль пользователя в амо*/
- Role int32 `json:"Role"`
- /* - группы пользователя в амо*/
- Group int32 `json:"Group"`
- /* - флаг мягкого удаления*/
- Deleted bool `json:"Deleted"`
- /* - таймштамп создания аккаунта*/
- Createdat int64 `json:"CreatedAt"`
- /* - поддомен организации в амо*/
- Subdomain string `json:"Subdomain"`
- /* - айдишник пользвателя, который подключал интеграцию*/
- Amouserid int32 `json:"AmoUserID"`
- /* - страна указанная в настройках амо*/
- Country string `json:"Country"`
- // урл объектного хранилища пользователя в амо
- DriveURL string `json:"DriveURL"`
+import "time"
+
+type AmoAccountUser struct {
+ ID int64 `json:"id"` // ID пользователя
+ AmoID int32 `json:"amoID"` // ID компании в амо, к которой пользователь принадлежит
+ AmoUserID int32 `json:"amoUserID"` // ID пользователя в амо
+ Name string `json:"name"` // Имя
+ Email string `json:"email"` // Email
+ Role int32 `json:"role"` // Роль
+ Group int32 `json:"group"` // Группа
+ Deleted bool `json:"deleted"`
+ CreatedAt time.Time `json:"createdAt"`
+}
+
+type AmoAccount struct {
+ ID int64 `json:"id"` // ID компании
+ AccountID string `json:"accountID"` // ID аккаунта нас
+ AmoID int32 `json:"amoID"` // ID компании в амо
+ Name string `json:"name"` // Название
+ Deleted bool `json:"deleted"`
+ CreatedAt time.Time `json:"createdAt"`
+ Subdomain string `json:"subdomain"` // поддомен
+ Country string `json:"country"` // Страна
+ DriveURL string `json:"driveURL"` // URL объктного хранилища
+ Stale bool `json:"stale"` // флаг "не свежести" если с токенами все в порядке - false, если просрочились то true
}
type UserGroups struct {
@@ -290,3 +288,11 @@ type AmoUsersTrueResults struct {
QuizAccountID string
DriveURL string
}
+
+// возможно стоит добавить enum? тип ContactQuizConfig уже есть
+type ContactAmo struct {
+ ID int64
+ AccountID int32 // id аккаунта в амо к которому привязан контакт
+ AmoID int32 // id контакта в амо
+ Field string // значение поля
+}
diff --git a/model/amoResp.go b/model/amoResp.go
index fd49975..1a65002 100644
--- a/model/amoResp.go
+++ b/model/amoResp.go
@@ -55,7 +55,7 @@ type UserListResp struct {
/* - общее количество юзеров, которые у нас закешированы для этого пользователя*/
Count int64 `json:"count"`
/* - список юзеров, которые были закешированы нашим сервисом*/
- Items []User `json:"items"`
+ Items []AmoAccountUser `json:"items"`
}
type UserListStepsResp struct {
diff --git a/repository/amo/amo.go b/repository/amo/amo.go
index 76c0cb6..63e2e3d 100644
--- a/repository/amo/amo.go
+++ b/repository/amo/amo.go
@@ -6,6 +6,7 @@ import (
"encoding/json"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen"
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
+ "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
"time"
)
@@ -39,20 +40,18 @@ func (r *AmoRepository) GettingUserWithPagination(ctx context.Context, req *mode
return nil, err
}
var count int64
- var users []model.User
+ var users []model.AmoAccountUser
for _, row := range rows {
- user := model.User{
+ user := model.AmoAccountUser{
ID: row.ID,
- Accountid: row.Accountid,
AmoID: row.Amoid,
+ AmoUserID: row.Amouserid,
Name: row.Name,
Email: row.Email,
Group: row.Group,
Role: row.Role,
- Createdat: row.Createdat.Time.Unix(),
- Subdomain: row.Subdomain,
- Amouserid: row.Amouserid,
- Country: row.Country,
+ Deleted: row.Deleted,
+ CreatedAt: row.Createdat,
}
count = row.TotalCount
@@ -75,41 +74,58 @@ func (r *AmoRepository) SoftDeleteAccount(ctx context.Context, accountID string)
return nil
}
-func (r *AmoRepository) GetCurrentAccount(ctx context.Context, accountID string) (*model.User, error) {
- row, err := r.queries.GetCurrentAccount(ctx, accountID)
+func (r *AmoRepository) GetCurrentAccount(ctx context.Context, accountID string) (*model.AmoAccount, error) {
+ row, err := r.queries.GetCurrentCompany(ctx, accountID)
if err != nil {
return nil, err
}
- user := model.User{
+ user := model.AmoAccount{
ID: row.ID,
- Accountid: row.Accountid,
+ AccountID: row.Accountid,
AmoID: row.Amoid,
Name: row.Name,
- Email: row.Email,
- Role: row.Role,
- Group: row.Group,
- Createdat: row.Createdat.Time.Unix(),
+ Deleted: row.Deleted,
+ CreatedAt: row.Createdat,
Subdomain: row.Subdomain,
- Amouserid: row.Amouserid,
Country: row.Country,
DriveURL: row.Driveurl,
}
+ _, err = r.queries.CheckExpiredToken(ctx, accountID)
+ if err != nil {
+ if err == sql.ErrNoRows {
+ user.Stale = false
+ return &user, nil
+ }
+ return nil, err
+ }
+
+ user.Stale = true
+
return &user, nil
}
-func (r *AmoRepository) CreateAccount(ctx context.Context, accountID string, userInfo model.User) error {
+func (r *AmoRepository) UpdateCurrentAccount(ctx context.Context, user model.AmoAccount) error {
+ err := r.queries.UpdateAmoAccount(ctx, sqlcgen.UpdateAmoAccountParams{
+ Accountid: user.AccountID,
+ Name: user.Name,
+ Subdomain: user.Subdomain,
+ Country: user.Country,
+ Driveurl: user.DriveURL,
+ })
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (r *AmoRepository) CreateAccount(ctx context.Context, userInfo model.AmoAccount) error {
err := r.queries.CreateAmoAccount(ctx, sqlcgen.CreateAmoAccountParams{
- Accountid: accountID,
+ Accountid: userInfo.AccountID,
Amoid: userInfo.AmoID,
Name: userInfo.Name,
- Email: userInfo.Email,
- Role: userInfo.Role,
- Group: userInfo.Group,
- Createdat: sql.NullTime{Time: time.Now(), Valid: true},
Subdomain: userInfo.Subdomain,
- Amouserid: userInfo.Amouserid,
Country: userInfo.Country,
Driveurl: userInfo.DriveURL,
})
@@ -121,15 +137,17 @@ func (r *AmoRepository) CreateAccount(ctx context.Context, accountID string, use
return nil
}
-func (r *AmoRepository) CheckMainUser(ctx context.Context, user model.User) error {
- err := r.queries.CheckMainUser(ctx, sqlcgen.CheckMainUserParams{
- Name: user.Name,
- Group: user.Group,
- Email: user.Email,
- Role: user.Role,
- Amoid: user.AmoID,
- })
+// todo возможно стоит обновлять еще и компанию пока не знаю
+func (r *AmoRepository) AddAmoAccountUser(ctx context.Context, user model.AmoAccountUser) error {
+ err := r.queries.AddAmoAccountUser(ctx, sqlcgen.AddAmoAccountUserParams{
+ Amoid: user.AmoID,
+ Amouserid: user.AmoUserID,
+ Name: user.Name,
+ Email: user.Email,
+ Role: user.Role,
+ Group: user.Group,
+ })
if err != nil {
return err
}
@@ -137,39 +155,18 @@ func (r *AmoRepository) CheckMainUser(ctx context.Context, user model.User) erro
return nil
}
-func (r *AmoRepository) CheckAndUpdateUsers(ctx context.Context, users []model.User) error {
- dollar1, err := json.Marshal(users)
+func (r *AmoRepository) UpdateAmoAccountUser(ctx context.Context, user model.AmoAccountUser) error {
+ err := r.queries.UpdateAmoAccountUser(ctx, sqlcgen.UpdateAmoAccountUserParams{
+ Amoid: user.AmoID,
+ Amouserid: user.AmoUserID,
+ Name: user.Name,
+ Email: user.Email,
+ Role: user.Role,
+ Group: user.Group,
+ })
if err != nil {
return err
}
- rows, err := r.queries.CheckUsers(ctx, dollar1)
- if err != nil {
- return err
- }
-
- if rows != nil {
- var toUpdate []model.User
- for _, row := range rows {
- to := model.User{
- AmoID: row.Amoid,
- Name: row.Name,
- Group: row.Group,
- Role: row.Role,
- Email: row.Email,
- Amouserid: row.Amouserid,
- }
- toUpdate = append(toUpdate, to)
- }
- dollar1, err := json.Marshal(toUpdate)
- if err != nil {
- return err
- }
-
- err = r.queries.UpdateUsers(ctx, dollar1)
- if err != nil {
- return err
- }
- }
return nil
}
@@ -195,27 +192,25 @@ func (r *AmoRepository) DeleteUsers(ctx context.Context, ids []int64) error {
return nil
}
-func (r *AmoRepository) GetUserUsersByID(ctx context.Context, amoUserID int32) ([]model.User, error) {
+func (r *AmoRepository) GetUserUsersByID(ctx context.Context, amoUserID int32) ([]model.AmoAccountUser, error) {
rows, err := r.queries.GetUserUsersByID(ctx, amoUserID)
if err != nil {
return nil, err
}
- var users []model.User
+ var users []model.AmoAccountUser
for _, row := range rows {
- user := model.User{
+ user := model.AmoAccountUser{
ID: row.ID,
- Accountid: row.Accountid,
AmoID: row.Amoid,
+ AmoUserID: row.Amouserid,
Name: row.Name,
Email: row.Email,
Group: row.Group,
Role: row.Role,
- Subdomain: row.Subdomain,
- Amouserid: row.Amouserid,
- Country: row.Country,
+ Deleted: row.Deleted,
+ CreatedAt: row.Createdat,
}
-
users = append(users, user)
}
@@ -256,31 +251,6 @@ func (r *AmoRepository) WebhookUpdate(ctx context.Context, token model.Token) er
return nil
}
-// воркер запускается каждые 5 минут, поэтомму ищем токены котторые исекают менее чем через 10 минут отдаем их на обноление
-func (r *AmoRepository) CheckExpired(ctx context.Context) ([]model.Token, error) {
- rows, err := r.queries.CheckExpired(ctx)
- if err != nil {
- return nil, err
- }
-
- var tokens []model.Token
-
- for _, row := range rows {
- token := model.Token{
- AccountID: row.Accountid,
- AccessToken: row.Accesstoken,
- RefreshToken: row.Refreshtoken,
- AuthCode: row.Authcode,
- Expiration: row.Expiration.Unix(),
- CreatedAt: row.Createdat.Time.Unix(),
- }
-
- tokens = append(tokens, token)
- }
-
- return tokens, nil
-}
-
func (r *AmoRepository) GetAllTokens(ctx context.Context) ([]model.Token, error) {
rows, err := r.queries.GetAllTokens(ctx)
if err != nil {
@@ -1038,7 +1008,7 @@ func (r *AmoRepository) GettingAmoUsersTrueResults(ctx context.Context) ([]model
}
var utm model.UTMSavingMap
- err = json.Unmarshal(row.Utm, &utm)
+ err = json.Unmarshal(row.Utm.([]byte), &utm)
if err != nil {
return nil, err
}
@@ -1111,3 +1081,60 @@ func (r *AmoRepository) UpdatingDealAmoStatus(ctx context.Context, deps SaveDeal
return nil
}
+
+// методы для contact в амо
+
+func (r *AmoRepository) GetExistingContactAmo(ctx context.Context, accountID int32, fields []string) (map[int32][]model.ContactAmo, error) {
+ rows, err := r.queries.GetExistingContactAmo(ctx, sqlcgen.GetExistingContactAmoParams{
+ Accountid: accountID,
+ Column2: fields,
+ })
+
+ if err != nil {
+ if err == sql.ErrNoRows {
+ return nil, pj_errors.ErrNotFound
+ }
+ return nil, err
+ }
+
+ result := make(map[int32][]model.ContactAmo)
+
+ for _, row := range rows {
+ result[row.Amoid] = append(result[row.Amoid], model.ContactAmo{
+ ID: row.ID,
+ AmoID: row.Amoid,
+ AccountID: row.Accountid,
+ Field: row.Field,
+ })
+ }
+
+ return result, nil
+}
+
+func (r *AmoRepository) InsertContactAmo(ctx context.Context, val model.ContactAmo) (int32, error) {
+ amoID, err := r.queries.InsertContactAmo(ctx, sqlcgen.InsertContactAmoParams{
+ Accountid: val.AccountID,
+ Amoid: val.AmoID,
+ Field: val.Field,
+ })
+
+ if err != nil {
+ return 0, err
+ }
+
+ return amoID, err
+}
+
+func (r *AmoRepository) UpdateAmoContact(ctx context.Context, id int64, field string, newAmoID int32) error {
+ err := r.queries.UpdateAmoContact(ctx, sqlcgen.UpdateAmoContactParams{
+ Field: field,
+ ID: id,
+ Amoid: newAmoID,
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/repository/answer/answer.go b/repository/answer/answer.go
index c473ce0..893dbb9 100644
--- a/repository/answer/answer.go
+++ b/repository/answer/answer.go
@@ -15,16 +15,14 @@ type Deps struct {
}
type AnswerRepository struct {
- queries *sqlcgen.Queries
- pool *sql.DB
- answerMinio *StorerAnswer
+ queries *sqlcgen.Queries
+ pool *sql.DB
}
func NewAnswerRepository(deps Deps) *AnswerRepository {
return &AnswerRepository{
- queries: deps.Queries,
- pool: deps.Pool,
- answerMinio: deps.AnswerMinio,
+ queries: deps.Queries,
+ pool: deps.Pool,
}
}
@@ -111,17 +109,6 @@ func (r *AnswerRepository) GetAllAnswersByQuizID(ctx context.Context, session st
}
for _, row := range rows {
- //todo тут забыл добавить проверку на то что minio !=nil
- /*if row.Questiontype == model.TypeFile {
- fmt.Println("GALL", row.Qid, row.QuestionID, row.Content)
- fileURL, err := r.answerMinio.GetAnswerURL(ctx, row.Qid.UUID.String(), row.QuestionID, row.Content.String)
- if err != nil {
- fmt.Println("GetAnswerURL dal answer minio answer", err)
- return nil, err
- }
- row.Content = sql.NullString{String: fmt.Sprintf("%s|%s", fileURL, row.Content.String), Valid: true}
- }*/
-
resultAnswer := model.ResultAnswer{
Content: row.Content.String,
CreatedAt: row.CreatedAt.Time,
diff --git a/repository/answer/worker_answer.go b/repository/answer/worker_answer.go
new file mode 100644
index 0000000..3bd1995
--- /dev/null
+++ b/repository/answer/worker_answer.go
@@ -0,0 +1,55 @@
+package answer
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen"
+ "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
+)
+
+type WorkerAnswerRepository struct {
+ queries *sqlcgen.Queries
+ pool *sql.DB
+ answerMinio *StorerAnswer
+}
+
+func NewWorkerAnswerRepo(deps Deps) *WorkerAnswerRepository {
+ return &WorkerAnswerRepository{
+ queries: deps.Queries,
+ pool: deps.Pool,
+ answerMinio: deps.AnswerMinio,
+ }
+}
+
+func (r *WorkerAnswerRepository) GetAllAnswersByQuizID(ctx context.Context, session string) ([]model.ResultAnswer, error) {
+ var results []model.ResultAnswer
+
+ rows, err := r.queries.GetAllAnswersByQuizID(ctx, sql.NullString{String: session, Valid: true})
+ if err != nil {
+ return nil, err
+ }
+
+ for _, row := range rows {
+ if row.Questiontype == model.TypeFile && r.answerMinio != nil {
+ fmt.Println("GALL", row.Qid, row.QuestionID, row.Content)
+ fileURL, err := r.answerMinio.GetAnswerURL(ctx, row.Qid.UUID.String(), row.QuestionID, row.Content.String)
+ if err != nil {
+ fmt.Println("GetAnswerURL dal answer minio answer", err)
+ return nil, err
+ }
+ row.Content = sql.NullString{String: fmt.Sprintf("%s|%s", fileURL, row.Content.String), Valid: true}
+ }
+
+ resultAnswer := model.ResultAnswer{
+ Content: row.Content.String,
+ CreatedAt: row.CreatedAt.Time,
+ QuestionID: uint64(row.QuestionID),
+ AnswerID: uint64(row.ID),
+ }
+
+ results = append(results, resultAnswer)
+ }
+
+ return results, nil
+}
diff --git a/repository/statistics/click_statistics.go b/repository/statistics/click_statistics.go
new file mode 100644
index 0000000..91061c2
--- /dev/null
+++ b/repository/statistics/click_statistics.go
@@ -0,0 +1,199 @@
+package statistics
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
+ "sort"
+ "strings"
+)
+
+type DepsClick struct {
+ Conn *sql.DB
+}
+
+type StatisticClick struct {
+ conn *sql.DB
+}
+
+func NewClickStatistic(ctx context.Context, deps DepsClick) (*StatisticClick, error) {
+ s := &StatisticClick{
+ conn: deps.Conn,
+ }
+
+ err := s.checkMW(ctx)
+ if err != nil {
+ fmt.Println("error check material view existing", err)
+ return nil, err
+ }
+
+ return s, nil
+}
+
+func (s *StatisticClick) checkMW(ctx context.Context) error {
+ query := `
+CREATE MATERIALIZED VIEW IF NOT EXISTS mv_last_answers_events
+ENGINE = MergeTree()
+ORDER BY (ctxsession, event_time) POPULATE AS
+SELECT
+ event_time, ctxsession, ctxquizid, ctxquestionid, ctxidint, message,ctxquiz
+FROM statistics
+WHERE message IN ('InfoQuizOpen', 'InfoAnswer', 'InfoResult') AND event_level = 'info';
+`
+ _, err := s.conn.ExecContext(ctx, query)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+type Statistic struct {
+ Count int64
+ QuestionID int64
+}
+
+type PipeLineStatsResp map[int64][]Statistic
+
+// пример:
+//"[0, 116783, 116810]"
+//"[0, 116783, 116798]"
+//"[0, 116783, 116798, 116831]"
+//"[0, 116783, 116810, 116849]"
+//[0]
+//"[0, 116783]"
+//"[0, 116783, 116810, 116843]"
+
+//SELECT DISTINCT last_que, reversed
+//FROM ( SELECT groupArray(ctxquestionid) AS reversed, arraySlice(arrayReverse(groupArray(ctxquestionid)), 1, 1)[1] AS last_que
+//FROM statistics WHERE ctxquizid = 26276 GROUP BY ctxsession ) AS sub;
+
+func (s *StatisticClick) getFunnel(ctx context.Context, quizID int64, from uint64, to uint64) (map[int64][]int64, error) {
+ query := `
+ SELECT DISTINCT last_que, reversed
+ FROM ( SELECT groupUniqArray(ctxquestionid) AS reversed, arraySlice(arrayReverse(groupArray(ctxquestionid)), 1, 1)[1] AS last_que
+ FROM mv_last_answers_events WHERE ctxquizid = ? AND event_time BETWEEN ? AND ? GROUP BY ctxsession ) AS sub;
+ `
+
+ rows, err := s.conn.QueryContext(ctx, query, quizID, from, to)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ funnel := make(map[int64][]int64)
+ for rows.Next() {
+ var lastQue int64
+ var reversed []int64
+ if err := rows.Scan(&lastQue, &reversed); err != nil {
+ return nil, err
+ }
+ funnel[lastQue] = reversed
+ }
+
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+
+ result := make(map[int64][]int64)
+ keys := make([]int64, 0, len(funnel))
+ for key := range funnel {
+ keys = append(keys, key)
+ }
+ sort.Slice(keys, func(i, j int) bool {
+ return keys[i] < keys[j]
+ })
+
+ for _, lastQue := range keys {
+ reversed := funnel[lastQue]
+ found := false
+
+ for _, otherLastQue := range keys {
+ if otherLastQue != lastQue {
+ otherReversed := funnel[otherLastQue]
+ sort.Slice(otherReversed, func(i, j int) bool {
+ return otherReversed[i] < otherReversed[j]
+ })
+ index := utils.BinarySearch(lastQue, otherReversed)
+ if index {
+ found = true
+ break
+ }
+ }
+ }
+
+ if !found {
+ result[lastQue] = reversed
+ }
+ }
+
+ return result, nil
+}
+
+func (s *StatisticClick) GetPipelinesStatistics(ctx context.Context, quizID int64, from uint64, to uint64) (PipeLineStatsResp, error) {
+ pipelines := make(PipeLineStatsResp)
+
+ funnel, err := s.getFunnel(ctx, quizID, from, to)
+ if err != nil {
+ return nil, err
+ }
+ for lastQue, idS := range funnel {
+ sesCount, err := s.countSession(ctx, quizID, from, to, idS)
+ if err != nil {
+ return nil, err
+ }
+ for _, queID := range idS {
+ if sessionCount, ok := sesCount[queID]; ok {
+ pipeline := Statistic{
+ QuestionID: queID,
+ Count: sessionCount,
+ }
+ pipelines[lastQue] = append(pipelines[lastQue], pipeline)
+ }
+ }
+ }
+ return pipelines, nil
+}
+
+func (s *StatisticClick) countSession(ctx context.Context, quizID int64, from uint64, to uint64, questionIDs []int64) (map[int64]int64, error) {
+ placeholders := make([]string, len(questionIDs))
+ args := make([]interface{}, len(questionIDs)+3)
+ args[0] = quizID
+ for i, id := range questionIDs {
+ placeholders[i] = "?"
+ args[i+1] = id
+ }
+ args[len(args)-2] = from
+ args[len(args)-1] = to
+
+ query := fmt.Sprintf(`
+ SELECT ctxquestionid, COUNT(DISTINCT ctxsession) AS session_count
+ FROM statistics
+ WHERE ctxquizid = ? AND ctxquestionid IN (%s) AND event_time BETWEEN ? AND ?
+ GROUP BY ctxquestionid;
+ `, strings.Join(placeholders, ","))
+
+ rows, err := s.conn.QueryContext(ctx, query, args...)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ counts := make(map[int64]int64)
+
+ for rows.Next() {
+ var questionID int64
+ var count int64
+ err := rows.Scan(&questionID, &count)
+ if err != nil {
+ return nil, err
+ }
+ counts[questionID] = count
+ }
+
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+
+ return counts, nil
+}
diff --git a/sqlc.yaml b/sqlc.yaml
index 8aac75c..031ec0e 100644
--- a/sqlc.yaml
+++ b/sqlc.yaml
@@ -30,6 +30,10 @@ packages:
- "./dal/schema/000012_init.down.sql"
- "./dal/schema/000013_init.up.sql"
- "./dal/schema/000013_init.down.sql"
+ - "./dal/schema/000014_init.up.sql"
+ - "./dal/schema/000014_init.down.sql"
+ - "./dal/schema/000016_init.up.sql"
+ - "./dal/schema/000016_init.down.sql"
- "./dal/schema/000017_init.up.sql"
- "./dal/schema/000017_init.down.sql"
engine: "postgresql"
diff --git a/utils/binary_search.go b/utils/binary_search.go
new file mode 100644
index 0000000..8e91039
--- /dev/null
+++ b/utils/binary_search.go
@@ -0,0 +1,20 @@
+package utils
+
+func BinarySearch(target int64, array []int64) bool {
+ left := 0
+ right := len(array) - 1
+
+ for left <= right {
+ mid := (left + right) / 2
+
+ if array[mid] == target {
+ return true
+ } else if array[mid] < target {
+ left = mid + 1
+ } else if array[mid] > target {
+ right = mid - 1
+ }
+ }
+
+ return false
+}
|