package basket import ( "encoding/json" "html" "net/http" "strings" "golang-fave/engine/sqlw" "golang-fave/utils" ) type session struct { listCurrencies map[int]*currency totalSum float64 Products map[int]*product `json:"products"` Currency *currency `json:"currency"` TotalSum string `json:"total_sum"` TotalCount int `json:"total_count"` } func (this *session) makePrice(product_price float64, product_currency_id int) float64 { if this.Currency == nil { return product_price } if this.Currency.Id == product_currency_id { return product_price } if product_currency_id == 1 { return product_price * this.Currency.Coefficient } else { if c, ok := this.listCurrencies[product_currency_id]; ok == true { return product_price / c.Coefficient } else { return product_price } } } func (this *session) updateProducts(db *sqlw.DB) { products_ids := []int{} for _, product := range this.Products { products_ids = append(products_ids, product.Id) } if len(products_ids) > 0 { if rows, err := db.Query( `SELECT shop_products.id, shop_products.name, shop_products.price, shop_products.alias, shop_currencies.id, shop_currencies.name, shop_currencies.coefficient, shop_currencies.code, shop_currencies.symbol, IF(image_this.filename IS NULL, shop_products.parent_id, shop_products.id) as imgid, IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename FROM shop_products LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency LEFT JOIN ( SELECT m.product_id, m.filename FROM shop_product_images as m LEFT JOIN ( SELECT t.product_id, MIN(t.ord) as ordmin FROM shop_product_images as t GROUP BY t.product_id ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord WHERE u.product_id IS NOT NULL ) as image_this ON image_this.product_id = shop_products.id LEFT JOIN ( SELECT m.product_id, m.filename FROM shop_product_images as m LEFT JOIN ( SELECT t.product_id, MIN(t.ord) as ordmin FROM shop_product_images as t GROUP BY t.product_id ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord WHERE u.product_id IS NOT NULL ) as image_parent ON image_parent.product_id = shop_products.parent_id WHERE shop_products.active = 1 AND shop_products.id IN (` + strings.Join(utils.ArrayOfIntToArrayOfString(products_ids), ",") + `) ;`, ); err == nil { defer rows.Close() for rows.Next() { row := &utils.MySql_shop_product{} roc := &utils.MySql_shop_currency{} var img_product_id string var img_filename string if err = rows.Scan( &row.A_id, &row.A_name, &row.A_price, &row.A_alias, &roc.A_id, &roc.A_name, &roc.A_coefficient, &roc.A_code, &roc.A_symbol, &img_product_id, &img_filename, ); err == nil { if p, ok := this.Products[row.A_id]; ok == true { // Load product image here var product_image string if img_filename == "" { // TODO: Placeholder product_image = "" } else { product_image = "/products/images/" + img_product_id + "/thumb-0-" + img_filename } p.Name = html.EscapeString(row.A_name) p.Image = product_image p.Link = "/shop/" + row.A_alias + "/" p.price = row.A_price p.currency.Id = roc.A_id p.currency.Name = html.EscapeString(roc.A_name) p.currency.Coefficient = roc.A_coefficient p.currency.Code = html.EscapeString(roc.A_code) p.currency.Symbol = html.EscapeString(roc.A_symbol) } } } } } } func (this *session) updateTotals() { this.totalSum = 0 this.TotalCount = 0 for _, product := range this.Products { product.Price = utils.Float64ToStrF(this.makePrice(product.price, product.currency.Id), "%.2f") product.Sum = utils.Float64ToStrF(this.makePrice(product.price*float64(product.Quantity), product.currency.Id), "%.2f") this.totalSum += this.makePrice(product.price, product.currency.Id) * float64(product.Quantity) this.TotalCount += product.Quantity } this.TotalSum = utils.Float64ToStrF(this.totalSum, "%.2f") } // Info, Plus, Minus func (this *session) Preload(r *http.Request, db *sqlw.DB) { user_currency := 1 if cookie, err := r.Cookie("currency"); err == nil { user_currency = utils.StrToInt(cookie.Value) } // Clear list of currencies this.listCurrencies = map[int]*currency{} // Load currencies from database if rows, err := db.Query( `SELECT id, name, coefficient, code, symbol FROM shop_currencies ORDER BY id ASC ;`, ); err == nil { defer rows.Close() for rows.Next() { roc := &utils.MySql_shop_currency{} if err = rows.Scan( &roc.A_id, &roc.A_name, &roc.A_coefficient, &roc.A_code, &roc.A_symbol, ); err == nil { this.listCurrencies[roc.A_id] = ¤cy{ Id: roc.A_id, Name: html.EscapeString(roc.A_name), Coefficient: roc.A_coefficient, Code: html.EscapeString(roc.A_code), Symbol: html.EscapeString(roc.A_symbol), } } } } // Check if selected currency is exists if _, ok := this.listCurrencies[user_currency]; ok != true { user_currency = 1 } // Save selected currency if c, ok := this.listCurrencies[user_currency]; ok == true { this.Currency = ¤cy{ Id: c.Id, Name: c.Name, Coefficient: c.Coefficient, Code: c.Code, Symbol: c.Symbol, } } } func (this *session) String(db *sqlw.DB) string { this.updateProducts(db) this.updateTotals() json, err := json.Marshal(this) if err != nil { return `{"msg":"basket_engine_error","message":"` + err.Error() + `"}` } return string(json) } func (this *session) Plus(db *sqlw.DB, product_id int) { if p, ok := this.Products[product_id]; ok == true { p.Quantity++ this.updateProducts(db) this.updateTotals() return } row := &utils.MySql_shop_product{} roc := &utils.MySql_shop_currency{} var img_product_id string var img_filename string if err := db.QueryRow(` SELECT shop_products.id, shop_products.name, shop_products.price, shop_products.alias, shop_currencies.id, shop_currencies.name, shop_currencies.coefficient, shop_currencies.code, shop_currencies.symbol, IF(image_this.filename IS NULL, shop_products.parent_id, shop_products.id) as imgid, IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename FROM shop_products LEFT JOIN shop_currencies ON shop_currencies.id = shop_products.currency LEFT JOIN ( SELECT m.product_id, m.filename FROM shop_product_images as m LEFT JOIN ( SELECT t.product_id, MIN(t.ord) as ordmin FROM shop_product_images as t GROUP BY t.product_id ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord WHERE u.product_id IS NOT NULL ) as image_this ON image_this.product_id = shop_products.id LEFT JOIN ( SELECT m.product_id, m.filename FROM shop_product_images as m LEFT JOIN ( SELECT t.product_id, MIN(t.ord) as ordmin FROM shop_product_images as t GROUP BY t.product_id ) as u ON u.product_id = m.product_id AND u.ordmin = m.ord WHERE u.product_id IS NOT NULL ) as image_parent ON image_parent.product_id = shop_products.parent_id WHERE shop_products.active = 1 AND shop_products.id = ? LIMIT 1;`, product_id, ).Scan( &row.A_id, &row.A_name, &row.A_price, &row.A_alias, &roc.A_id, &roc.A_name, &roc.A_coefficient, &roc.A_code, &roc.A_symbol, &img_product_id, &img_filename, ); err == nil { // Load product image here var product_image string if img_filename == "" { // TODO: Placeholder product_image = "" } else { product_image = "/products/images/" + img_product_id + "/thumb-0-" + img_filename } this.Products[product_id] = &product{ currency: ¤cy{Id: roc.A_id, Name: roc.A_name, Coefficient: roc.A_coefficient, Code: roc.A_code, Symbol: roc.A_symbol}, Id: row.A_id, Name: html.EscapeString(row.A_name), Image: product_image, Link: "/shop/" + row.A_alias + "/", price: row.A_price, Quantity: 1, } this.updateProducts(db) this.updateTotals() } } func (this *session) Minus(db *sqlw.DB, product_id int) { if p, ok := this.Products[product_id]; ok == true { if p.Quantity > 1 { p.Quantity-- } else { delete(this.Products, product_id) } this.updateProducts(db) this.updateTotals() } } func (this *session) Remove(db *sqlw.DB, product_id int) { if _, ok := this.Products[product_id]; ok == true { delete(this.Products, product_id) this.updateProducts(db) this.updateTotals() } } func (this *session) ProductsCount() int { return this.TotalCount }