session.go 9.6 KB

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