session.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. package basket
  2. import (
  3. "encoding/json"
  4. "html"
  5. "net/http"
  6. "strings"
  7. "golang-fave/engine/sqlw"
  8. "golang-fave/utils"
  9. )
  10. type session struct {
  11. listCurrencies map[int]*currency
  12. totalSum float64
  13. Products map[int]*product `json:"products"`
  14. Currency *currency `json:"currency"`
  15. TotalSum string `json:"total_sum"`
  16. TotalCount int `json:"total_count"`
  17. }
  18. func (this *session) makePrice(product_price float64, product_currency_id int) float64 {
  19. if this.Currency == nil {
  20. return product_price
  21. }
  22. if this.Currency.Id == product_currency_id {
  23. return product_price
  24. }
  25. if product_currency_id == 1 {
  26. return product_price * this.Currency.Coefficient
  27. } else {
  28. if c, ok := this.listCurrencies[product_currency_id]; ok == true {
  29. return product_price / c.Coefficient
  30. } else {
  31. return product_price
  32. }
  33. }
  34. }
  35. func (this *session) updateProducts(db *sqlw.DB) {
  36. products_ids := []int{}
  37. for _, product := range this.Products {
  38. products_ids = append(products_ids, product.Id)
  39. }
  40. if len(products_ids) > 0 {
  41. if rows, err := db.Query(
  42. `SELECT
  43. shop_products.id,
  44. shop_products.name,
  45. shop_products.price,
  46. shop_products.alias,
  47. shop_currencies.id,
  48. shop_currencies.name,
  49. shop_currencies.coefficient,
  50. shop_currencies.code,
  51. shop_currencies.symbol,
  52. IF(image_this.filename IS NULL, shop_products.parent_id, shop_products.id) as imgid,
  53. IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename
  54. FROM
  55. shop_products
  56. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  57. LEFT JOIN (
  58. SELECT
  59. m.product_id,
  60. m.filename
  61. FROM
  62. shop_product_images as m
  63. LEFT JOIN (
  64. SELECT
  65. t.product_id,
  66. MIN(t.ord) as ordmin
  67. FROM
  68. shop_product_images as t
  69. GROUP BY
  70. t.product_id
  71. ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord
  72. WHERE
  73. u.product_id IS NOT NULL
  74. ) as image_this ON image_this.product_id = shop_products.id
  75. LEFT JOIN (
  76. SELECT
  77. m.product_id,
  78. m.filename
  79. FROM
  80. shop_product_images as m
  81. LEFT JOIN (
  82. SELECT
  83. t.product_id,
  84. MIN(t.ord) as ordmin
  85. FROM
  86. shop_product_images as t
  87. GROUP BY
  88. t.product_id
  89. ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord
  90. WHERE
  91. u.product_id IS NOT NULL
  92. ) as image_parent ON image_parent.product_id = shop_products.parent_id
  93. WHERE
  94. shop_products.active = 1 AND
  95. shop_products.id IN (` + strings.Join(utils.ArrayOfIntToArrayOfString(products_ids), ",") + `)
  96. ;`,
  97. ); err == nil {
  98. defer rows.Close()
  99. for rows.Next() {
  100. row := &utils.MySql_shop_product{}
  101. roc := &utils.MySql_shop_currency{}
  102. var img_product_id string
  103. var img_filename string
  104. if err = rows.Scan(
  105. &row.A_id,
  106. &row.A_name,
  107. &row.A_price,
  108. &row.A_alias,
  109. &roc.A_id,
  110. &roc.A_name,
  111. &roc.A_coefficient,
  112. &roc.A_code,
  113. &roc.A_symbol,
  114. &img_product_id,
  115. &img_filename,
  116. ); err == nil {
  117. if p, ok := this.Products[row.A_id]; ok == true {
  118. // Load product image here
  119. var product_image string
  120. if img_filename == "" {
  121. // TODO: Placeholder
  122. product_image = ""
  123. } else {
  124. product_image = "/products/images/" + img_product_id + "/thumb-0-" + img_filename
  125. }
  126. p.Name = html.EscapeString(row.A_name)
  127. p.Image = product_image
  128. p.Link = "/shop/" + row.A_alias + "/"
  129. p.price = row.A_price
  130. p.currency.Id = roc.A_id
  131. p.currency.Name = html.EscapeString(roc.A_name)
  132. p.currency.Coefficient = roc.A_coefficient
  133. p.currency.Code = html.EscapeString(roc.A_code)
  134. p.currency.Symbol = html.EscapeString(roc.A_symbol)
  135. }
  136. }
  137. }
  138. }
  139. }
  140. }
  141. func (this *session) updateTotals() {
  142. this.totalSum = 0
  143. this.TotalCount = 0
  144. for _, product := range this.Products {
  145. product.Price = utils.Float64ToStrF(this.makePrice(product.price, product.currency.Id), "%.2f")
  146. product.Sum = utils.Float64ToStrF(this.makePrice(product.price*float64(product.Quantity), product.currency.Id), "%.2f")
  147. this.totalSum += this.makePrice(product.price, product.currency.Id) * float64(product.Quantity)
  148. this.TotalCount += product.Quantity
  149. }
  150. this.TotalSum = utils.Float64ToStrF(this.totalSum, "%.2f")
  151. }
  152. // Info, Plus, Minus
  153. func (this *session) Preload(r *http.Request, db *sqlw.DB) {
  154. user_currency := 1
  155. if cookie, err := r.Cookie("currency"); err == nil {
  156. user_currency = utils.StrToInt(cookie.Value)
  157. }
  158. // Clear list of currencies
  159. this.listCurrencies = map[int]*currency{}
  160. // Load currencies from database
  161. if rows, err := db.Query(
  162. `SELECT
  163. id,
  164. name,
  165. coefficient,
  166. code,
  167. symbol
  168. FROM
  169. shop_currencies
  170. ORDER BY
  171. id ASC
  172. ;`,
  173. ); err == nil {
  174. defer rows.Close()
  175. for rows.Next() {
  176. roc := &utils.MySql_shop_currency{}
  177. if err = rows.Scan(
  178. &roc.A_id,
  179. &roc.A_name,
  180. &roc.A_coefficient,
  181. &roc.A_code,
  182. &roc.A_symbol,
  183. ); err == nil {
  184. this.listCurrencies[roc.A_id] = &currency{
  185. Id: roc.A_id,
  186. Name: html.EscapeString(roc.A_name),
  187. Coefficient: roc.A_coefficient,
  188. Code: html.EscapeString(roc.A_code),
  189. Symbol: html.EscapeString(roc.A_symbol),
  190. }
  191. }
  192. }
  193. }
  194. // Check if selected currency is exists
  195. if _, ok := this.listCurrencies[user_currency]; ok != true {
  196. user_currency = 1
  197. }
  198. // Save selected currency
  199. if c, ok := this.listCurrencies[user_currency]; ok == true {
  200. this.Currency = &currency{
  201. Id: c.Id,
  202. Name: c.Name,
  203. Coefficient: c.Coefficient,
  204. Code: c.Code,
  205. Symbol: c.Symbol,
  206. }
  207. }
  208. }
  209. func (this *session) String(db *sqlw.DB) string {
  210. this.updateProducts(db)
  211. this.updateTotals()
  212. json, err := json.Marshal(this)
  213. if err != nil {
  214. return `{"msg":"basket_engine_error","message":"` + err.Error() + `"}`
  215. }
  216. return string(json)
  217. }
  218. func (this *session) Plus(db *sqlw.DB, product_id int) {
  219. if p, ok := this.Products[product_id]; ok == true {
  220. p.Quantity++
  221. this.updateProducts(db)
  222. this.updateTotals()
  223. return
  224. }
  225. row := &utils.MySql_shop_product{}
  226. roc := &utils.MySql_shop_currency{}
  227. var img_product_id string
  228. var img_filename string
  229. if err := db.QueryRow(`
  230. SELECT
  231. shop_products.id,
  232. shop_products.name,
  233. shop_products.price,
  234. shop_products.alias,
  235. shop_currencies.id,
  236. shop_currencies.name,
  237. shop_currencies.coefficient,
  238. shop_currencies.code,
  239. shop_currencies.symbol,
  240. IF(image_this.filename IS NULL, shop_products.parent_id, shop_products.id) as imgid,
  241. IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename
  242. FROM
  243. shop_products
  244. LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency
  245. LEFT JOIN (
  246. SELECT
  247. m.product_id,
  248. m.filename
  249. FROM
  250. shop_product_images as m
  251. LEFT JOIN (
  252. SELECT
  253. t.product_id,
  254. MIN(t.ord) as ordmin
  255. FROM
  256. shop_product_images as t
  257. GROUP BY
  258. t.product_id
  259. ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord
  260. WHERE
  261. u.product_id IS NOT NULL
  262. ) as image_this ON image_this.product_id = shop_products.id
  263. LEFT JOIN (
  264. SELECT
  265. m.product_id,
  266. m.filename
  267. FROM
  268. shop_product_images as m
  269. LEFT JOIN (
  270. SELECT
  271. t.product_id,
  272. MIN(t.ord) as ordmin
  273. FROM
  274. shop_product_images as t
  275. GROUP BY
  276. t.product_id
  277. ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord
  278. WHERE
  279. u.product_id IS NOT NULL
  280. ) as image_parent ON image_parent.product_id = shop_products.parent_id
  281. WHERE
  282. shop_products.active = 1 AND
  283. shop_products.id = ?
  284. LIMIT 1;`,
  285. product_id,
  286. ).Scan(
  287. &row.A_id,
  288. &row.A_name,
  289. &row.A_price,
  290. &row.A_alias,
  291. &roc.A_id,
  292. &roc.A_name,
  293. &roc.A_coefficient,
  294. &roc.A_code,
  295. &roc.A_symbol,
  296. &img_product_id,
  297. &img_filename,
  298. ); err == nil {
  299. // Load product image here
  300. var product_image string
  301. if img_filename == "" {
  302. // TODO: Placeholder
  303. product_image = ""
  304. } else {
  305. product_image = "/products/images/" + img_product_id + "/thumb-0-" + img_filename
  306. }
  307. this.Products[product_id] = &product{
  308. currency: &currency{Id: roc.A_id, Name: roc.A_name, Coefficient: roc.A_coefficient, Code: roc.A_code, Symbol: roc.A_symbol},
  309. Id: row.A_id,
  310. Name: html.EscapeString(row.A_name),
  311. Image: product_image,
  312. Link: "/shop/" + row.A_alias + "/",
  313. price: row.A_price,
  314. Quantity: 1,
  315. }
  316. this.updateProducts(db)
  317. this.updateTotals()
  318. }
  319. }
  320. func (this *session) Minus(db *sqlw.DB, product_id int) {
  321. if p, ok := this.Products[product_id]; ok == true {
  322. if p.Quantity > 1 {
  323. p.Quantity--
  324. } else {
  325. delete(this.Products, product_id)
  326. }
  327. this.updateProducts(db)
  328. this.updateTotals()
  329. }
  330. }
  331. func (this *session) Remove(db *sqlw.DB, product_id int) {
  332. if _, ok := this.Products[product_id]; ok == true {
  333. delete(this.Products, product_id)
  334. this.updateProducts(db)
  335. this.updateTotals()
  336. }
  337. }
  338. func (this *session) ProductsCount() int {
  339. return this.TotalCount
  340. }