session.go 9.7 KB

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