go-crm improvements
This commit is contained in:
@@ -5,13 +5,14 @@ import (
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
ClientID int64 `json:"client_id"`
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
ClientID int64 `json:"client_id"`
|
||||
AccountID int64 `json:"account_id"`
|
||||
Name string `json:"name"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
}
|
||||
|
||||
type Customer struct {
|
||||
@@ -59,8 +60,8 @@ type Payment struct {
|
||||
|
||||
func (c *Client) Create(db *sql.DB) error {
|
||||
result, err := db.Exec(
|
||||
"INSERT INTO clients (name, phone, email, address, notes, created_at) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
c.Name, c.Phone, c.Email, c.Address, c.Notes, c.CreatedAt,
|
||||
"INSERT INTO clients (account_id, name, phone, email, address, notes, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
c.AccountID, c.Name, c.Phone, c.Email, c.Address, c.Notes, c.CreatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -75,29 +76,35 @@ func (c *Client) Create(db *sql.DB) error {
|
||||
|
||||
func (c *Client) Read(db *sql.DB, id int64) error {
|
||||
return db.QueryRow(
|
||||
"SELECT client_id, name, phone, email, address, notes, created_at FROM clients WHERE client_id = ?",
|
||||
"SELECT client_id, account_id, name, COALESCE(phone,''), COALESCE(email,''), COALESCE(address,''), COALESCE(notes,''), created_at FROM clients WHERE client_id = ?",
|
||||
id,
|
||||
).Scan(&c.ClientID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt)
|
||||
).Scan(&c.ClientID, &c.AccountID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt)
|
||||
}
|
||||
|
||||
func (c *Client) Update(db *sql.DB) error {
|
||||
_, err := db.Exec(
|
||||
"UPDATE clients SET name = ?, phone = ?, email = ?, address = ?, notes = ? WHERE client_id = ?",
|
||||
c.Name, c.Phone, c.Email, c.Address, c.Notes, c.ClientID,
|
||||
"UPDATE clients SET name = ?, phone = ?, email = ?, address = ?, notes = ? WHERE client_id = ? AND account_id = ?",
|
||||
c.Name, c.Phone, c.Email, c.Address, c.Notes, c.ClientID, c.AccountID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) Delete(db *sql.DB, id int64) error {
|
||||
_, err := db.Exec("DELETE FROM clients WHERE client_id = ?", id)
|
||||
func (c *Client) Delete(db *sql.DB) error {
|
||||
_, err := db.Exec("DELETE FROM clients WHERE client_id = ? AND account_id = ?", c.ClientID, c.AccountID)
|
||||
return err
|
||||
}
|
||||
|
||||
func ListClients(db *sql.DB, limit, offset int) ([]Client, error) {
|
||||
rows, err := db.Query(
|
||||
"SELECT client_id, name, phone, email, address, notes, created_at FROM clients ORDER BY created_at DESC LIMIT ? OFFSET ?",
|
||||
limit, offset,
|
||||
)
|
||||
func ListClients(db *sql.DB, accountID int64, limit, offset int) ([]Client, error) {
|
||||
query := "SELECT client_id, account_id, name, COALESCE(phone,''), COALESCE(email,''), COALESCE(address,''), COALESCE(notes,''), created_at FROM clients"
|
||||
args := []interface{}{}
|
||||
if accountID > 0 {
|
||||
query += " WHERE account_id = ?"
|
||||
args = append(args, accountID)
|
||||
}
|
||||
query += " ORDER BY created_at DESC LIMIT ? OFFSET ?"
|
||||
args = append(args, limit, offset)
|
||||
|
||||
rows, err := db.Query(query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,7 +113,7 @@ func ListClients(db *sql.DB, limit, offset int) ([]Client, error) {
|
||||
var clients []Client
|
||||
for rows.Next() {
|
||||
var c Client
|
||||
if err := rows.Scan(&c.ClientID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt); err != nil {
|
||||
if err := rows.Scan(&c.ClientID, &c.AccountID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clients = append(clients, c)
|
||||
@@ -114,12 +121,12 @@ func ListClients(db *sql.DB, limit, offset int) ([]Client, error) {
|
||||
return clients, rows.Err()
|
||||
}
|
||||
|
||||
func GetClientByID(db *sql.DB, id int64) (*Client, error) {
|
||||
func GetClientByID(db *sql.DB, accountID, id int64) (*Client, error) {
|
||||
var c Client
|
||||
err := db.QueryRow(
|
||||
"SELECT client_id, name, phone, email, address, notes, created_at FROM clients WHERE client_id = ?",
|
||||
id,
|
||||
).Scan(&c.ClientID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt)
|
||||
"SELECT client_id, account_id, name, COALESCE(phone,''), COALESCE(email,''), COALESCE(address,''), COALESCE(notes,''), created_at FROM clients WHERE client_id = ? AND account_id = ?",
|
||||
id, accountID,
|
||||
).Scan(&c.ClientID, &c.AccountID, &c.Name, &c.Phone, &c.Email, &c.Address, &c.Notes, &c.CreatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -142,13 +149,24 @@ func (cu *Customer) Create(db *sql.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListCustomers(db *sql.DB, clientID int64, limit, offset int) ([]Customer, error) {
|
||||
func ListCustomers(db *sql.DB, accountID, clientID int64, limit, offset int) ([]Customer, error) {
|
||||
args := []interface{}{}
|
||||
query := "SELECT customer_id, client_id, name, phone, birth_date, instagram, created_at FROM customers"
|
||||
var args []interface{}
|
||||
cond := ""
|
||||
if clientID > 0 {
|
||||
query += " WHERE client_id = ?"
|
||||
cond = "client_id = ?"
|
||||
args = append(args, clientID)
|
||||
}
|
||||
if accountID > 0 {
|
||||
if cond != "" {
|
||||
cond += " AND "
|
||||
}
|
||||
cond += "client_id IN (SELECT client_id FROM clients WHERE account_id = ?)"
|
||||
args = append(args, accountID)
|
||||
}
|
||||
if cond != "" {
|
||||
query += " WHERE " + cond
|
||||
}
|
||||
query += " ORDER BY created_at DESC LIMIT ? OFFSET ?"
|
||||
args = append(args, limit, offset)
|
||||
|
||||
@@ -185,13 +203,24 @@ func (s *Service) Create(db *sql.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListServices(db *sql.DB, clientID int64, limit, offset int) ([]Service, error) {
|
||||
func ListServices(db *sql.DB, accountID, clientID int64, limit, offset int) ([]Service, error) {
|
||||
args := []interface{}{}
|
||||
query := "SELECT service_id, client_id, name, price, description, duration, created_at FROM services"
|
||||
var args []interface{}
|
||||
cond := ""
|
||||
if clientID > 0 {
|
||||
query += " WHERE client_id = ?"
|
||||
cond = "client_id = ?"
|
||||
args = append(args, clientID)
|
||||
}
|
||||
if accountID > 0 {
|
||||
if cond != "" {
|
||||
cond += " AND "
|
||||
}
|
||||
cond += "client_id IN (SELECT client_id FROM clients WHERE account_id = ?)"
|
||||
args = append(args, accountID)
|
||||
}
|
||||
if cond != "" {
|
||||
query += " WHERE " + cond
|
||||
}
|
||||
query += " ORDER BY created_at DESC LIMIT ? OFFSET ?"
|
||||
args = append(args, limit, offset)
|
||||
|
||||
@@ -430,7 +459,8 @@ type AnswerWithDetails struct {
|
||||
QuestionText string `json:"question_text"`
|
||||
}
|
||||
|
||||
func ListAnswersWithDetails(db *sql.DB, questionID int64, limit, offset int) ([]AnswerWithDetails, error) {
|
||||
func ListAnswersWithDetails(db *sql.DB, accountID, questionID int64, limit, offset int) ([]AnswerWithDetails, error) {
|
||||
args := []interface{}{accountID}
|
||||
query := `
|
||||
SELECT
|
||||
a.answer_id, a.client_id, a.question_id, a.answer, a.timestamp, a.status, a.created_at,
|
||||
@@ -441,8 +471,7 @@ func ListAnswersWithDetails(db *sql.DB, questionID int64, limit, offset int) ([]
|
||||
JOIN questions q ON a.question_id = q.question_id
|
||||
JOIN customers cu ON q.customer_id = cu.customer_id
|
||||
JOIN clients c ON q.client_id = c.client_id
|
||||
WHERE 1=1`
|
||||
var args []interface{}
|
||||
WHERE c.account_id = ?`
|
||||
if questionID > 0 {
|
||||
query += " AND a.question_id = ?"
|
||||
args = append(args, questionID)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
_ "github.com/glebarez/sqlite"
|
||||
)
|
||||
@@ -27,12 +28,14 @@ CREATE TABLE IF NOT EXISTS sessions (
|
||||
|
||||
CREATE TABLE IF NOT EXISTS clients (
|
||||
client_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
account_id INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
address TEXT,
|
||||
notes TEXT,
|
||||
created_at INTEGER NOT NULL
|
||||
created_at INTEGER NOT NULL,
|
||||
FOREIGN KEY (account_id) REFERENCES accounts(account_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS customers (
|
||||
@@ -138,5 +141,20 @@ func Init(path string) (*sql.DB, error) {
|
||||
return nil, fmt.Errorf("failed to create schema: %w", err)
|
||||
}
|
||||
|
||||
if err := migrate(database); err != nil {
|
||||
return nil, fmt.Errorf("failed to migrate: %w", err)
|
||||
}
|
||||
|
||||
return database, nil
|
||||
}
|
||||
|
||||
func migrate(db *sql.DB) error {
|
||||
_, err := db.Exec("ALTER TABLE clients ADD COLUMN account_id INTEGER")
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "duplicate column name") {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user