client.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package repo
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "saura/src/common"
  6. )
  7. const (
  8. ClientTypePhysical string = "Физ"
  9. ClientTypeLegal string = "Юр"
  10. ClientTypeSupplier string = "Поставщик"
  11. ClientTypeEmployee string = "Сотрудник"
  12. ClientTypeCounterparty string = "Контрагент"
  13. ClientTypeCustomer string = "Покупатель"
  14. )
  15. type ClientInfo struct {
  16. Id string `db:"id" json:"id" form:"id"`
  17. Id2 string `db:"id2" json:"id2" form:"id2"`
  18. Mark string `db:"mark" json:"mark" form:"mark"`
  19. Contractor bool `db:"contractor" json:"contractor" form:"contractor"`
  20. FullName string `db:"full_name" json:"full_name" form:"full_name"`
  21. Type string `db:"type" json:"type" form:"type"`
  22. Phones []string `json:"phones" form:"phones"`
  23. Email string `db:"email" json:"email" form:"email"`
  24. LegalAddress string `db:"legal_address" json:"legal_address" form:"legal_address"`
  25. PhysicalAddress string `db:"physical_address" json:"physical_address" form:"physical_address"`
  26. RegistrationDate string `db:"registration_date" json:"registration_date" form:"registration_date"`
  27. AdChannel string `db:"ad_channel" json:"ad_channel" form:"ad_channel"`
  28. RegData1 string `db:"reg_data_1" json:"reg_data_1" form:"reg_data_1"`
  29. RegData2 string `db:"reg_data_2" json:"reg_data_2" form:"reg_data_2"`
  30. Note string `db:"note" json:"note" form:"note"`
  31. RequestCount int `db:"request_count" json:"request_count" form:"request_count"`
  32. Birthday string `db:"birthday" json:"birthday" form:"birthday"`
  33. Income common.Money `db:"income" json:"income" form:"income"`
  34. }
  35. type ClientRepo struct {
  36. db *sql.DB
  37. dbUrl string
  38. }
  39. func NewClientRepo(db *sql.DB, dbUrl string) *ClientRepo {
  40. return &ClientRepo{db: db, dbUrl: dbUrl}
  41. }
  42. func (r *ClientRepo) InsertClient(client ClientInfo) error {
  43. var err error
  44. var exists bool
  45. err = r.db.QueryRow("SELECT EXISTS(SELECT 1 FROM clients WHERE id = ? OR id2 = ?)", client.Id, client.Id2).Scan(&exists)
  46. if err != nil {
  47. return fmt.Errorf("failed to check if client exists: %w", err)
  48. }
  49. if exists {
  50. return fmt.Errorf("client with id %s already exists", client.Id)
  51. }
  52. _, err = r.db.Exec(
  53. `
  54. INSERT INTO clients (
  55. id, id2, mark, contractor, full_name, type, email,
  56. legal_address, physical_address, registration_date, ad_channel,
  57. reg_data_1, reg_data_2, note, request_count, birthday, income
  58. ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  59. `,
  60. client.Id, client.Id2, client.Mark, client.Contractor, client.FullName,
  61. client.Type, client.Email, client.LegalAddress,
  62. client.PhysicalAddress, client.RegistrationDate, client.AdChannel,
  63. client.RegData1, client.RegData2, client.Note, client.RequestCount,
  64. client.Birthday, client.Income,
  65. )
  66. if err != nil {
  67. return fmt.Errorf("failed to insert client: %w", err)
  68. }
  69. return nil
  70. }
  71. func (r *ClientRepo) FetchClientByID(id string) (*ClientInfo, error) {
  72. var err error
  73. row := r.db.QueryRow(`
  74. SELECT
  75. id, id2, mark, contractor, full_name, type, email,
  76. legal_address, physical_address, registration_date, ad_channel,
  77. reg_data_1, reg_data_2, note, request_count, birthday, income
  78. FROM clients
  79. WHERE id = ?
  80. `, id)
  81. var client ClientInfo
  82. err = row.Scan(
  83. &client.Id, &client.Id2, &client.Mark, &client.Contractor, &client.FullName,
  84. &client.Type, &client.Email, &client.LegalAddress,
  85. &client.PhysicalAddress, &client.RegistrationDate, &client.AdChannel,
  86. &client.RegData1, &client.RegData2, &client.Note, &client.RequestCount,
  87. &client.Birthday, &client.Income,
  88. )
  89. if err == sql.ErrNoRows {
  90. return nil, fmt.Errorf("client with id %s not found", id)
  91. } else if err != nil {
  92. return nil, fmt.Errorf("failed to scan row: %w", err)
  93. }
  94. phones, err := r.FetchClientPhones(client.Id)
  95. if err != nil {
  96. return nil, fmt.Errorf("error: %w", err)
  97. }
  98. client.Phones = phones
  99. return &client, nil
  100. }
  101. func (r *ClientRepo) InsertClientPhones(client_id string, phones []string) error {
  102. for _, phone := range phones {
  103. _, err := r.db.Exec("INSERT INTO client_phones VALUES(?, ?)", client_id, phone)
  104. if err != nil {
  105. return err
  106. }
  107. }
  108. return nil
  109. }
  110. func (r *ClientRepo) FetchClientPhones(client_id string) ([]string, error) {
  111. rows, err := r.db.Query("SELECT phone FROM client_phones WHERE client_id = ?", client_id)
  112. if err != nil {
  113. return nil, err
  114. }
  115. defer rows.Close()
  116. var tags []string
  117. for rows.Next() {
  118. var tag string
  119. rows.Scan(&tag)
  120. tags = append(tags, tag)
  121. }
  122. return tags, nil
  123. }
  124. func (r *ClientRepo) FetchClients(count int, offset int) ([]ClientInfo, error) {
  125. rows, err := r.db.Query(`
  126. SELECT
  127. id, id2, mark, contractor, full_name, type, email,
  128. legal_address, physical_address, registration_date, ad_channel,
  129. reg_data_1, reg_data_2, note, request_count, birthday, income
  130. FROM clients
  131. LIMIT ? OFFSET ?
  132. `, count, offset)
  133. if err != nil {
  134. return nil, fmt.Errorf("failed to execute query: %w", err)
  135. }
  136. defer rows.Close()
  137. var clients []ClientInfo
  138. for rows.Next() {
  139. var client ClientInfo
  140. err := rows.Scan(
  141. &client.Id,
  142. &client.Id2,
  143. &client.Mark,
  144. &client.Contractor,
  145. &client.FullName,
  146. &client.Type,
  147. &client.Email,
  148. &client.LegalAddress,
  149. &client.PhysicalAddress,
  150. &client.RegistrationDate, // time.Time или sql.NullTime
  151. &client.AdChannel,
  152. &client.RegData1,
  153. &client.RegData2,
  154. &client.Note, // sql.NullString
  155. &client.RequestCount, // int или sql.NullInt32
  156. &client.Birthday, // time.Time или sql.NullTime
  157. &client.Income, // float64 или sql.NullFloat64
  158. )
  159. if err != nil {
  160. return nil, fmt.Errorf("failed to scan row: %w", err)
  161. }
  162. phones, err := r.FetchClientPhones(client.Id)
  163. if err != nil {
  164. return nil, fmt.Errorf("rows error: %w", err)
  165. }
  166. client.Phones = phones
  167. clients = append(clients, client)
  168. }
  169. // Проверка ошибок после итерации
  170. if err := rows.Err(); err != nil {
  171. return nil, fmt.Errorf("rows error: %w", err)
  172. }
  173. return clients, nil
  174. }
  175. func (r *ClientRepo) FetchClientsCount() (int, error) {
  176. var count int
  177. query := "SELECT COUNT(*) FROM clients"
  178. err := r.db.QueryRow(query).Scan(&count)
  179. if err != nil {
  180. return 0, fmt.Errorf("failed to fetch count: %w", err)
  181. }
  182. return count, nil
  183. }
  184. func (r *ClientRepo) DeleteClient(id string) error {
  185. query := "DELETE FROM clients WHERE id = ?"
  186. result, err := r.db.Exec(query, id)
  187. if err != nil {
  188. return fmt.Errorf("failed to delete client: %w", err)
  189. }
  190. rowsAffected, err := result.RowsAffected()
  191. if err != nil {
  192. return fmt.Errorf("failed to get rows affected: %w", err)
  193. }
  194. if rowsAffected == 0 {
  195. return fmt.Errorf("client with id %s not found", id)
  196. }
  197. return nil
  198. }
  199. func (r *ClientRepo) UpdateClient(id string, client ClientInfo) error {
  200. // Проверим, существует ли клиент
  201. var exists string
  202. err := r.db.QueryRow("SELECT id FROM clients WHERE id = ?", id).Scan(&exists)
  203. if err == sql.ErrNoRows {
  204. return fmt.Errorf("client with id %s not found", id)
  205. } else if err != nil {
  206. return fmt.Errorf("failed to check client existence: %w", err)
  207. }
  208. query := `
  209. UPDATE clients SET
  210. id = ?,
  211. id2 = ?,
  212. mark = ?,
  213. contractor = ?,
  214. full_name = ?,
  215. type = ?,
  216. email = ?,
  217. legal_address = ?,
  218. physical_address = ?,
  219. registration_date = ?,
  220. ad_channel = ?,
  221. reg_data_1 = ?,
  222. reg_data_2 = ?,
  223. note = ?,
  224. request_count = ?,
  225. birthday = ?,
  226. income = ?
  227. WHERE id = ?
  228. `
  229. contractorInt := 0
  230. if client.Contractor {
  231. contractorInt = 1
  232. }
  233. _, err = r.db.Exec(query,
  234. id,
  235. client.Id2,
  236. client.Mark,
  237. contractorInt,
  238. client.FullName,
  239. client.Type,
  240. client.Email,
  241. client.LegalAddress,
  242. client.PhysicalAddress,
  243. client.RegistrationDate,
  244. client.AdChannel,
  245. client.RegData1,
  246. client.RegData2,
  247. client.Note,
  248. client.RequestCount,
  249. client.Birthday,
  250. client.Income,
  251. id,
  252. )
  253. if err != nil {
  254. return fmt.Errorf("failed to update client: %w", err)
  255. }
  256. return nil
  257. }