123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- package basket
- import (
- "context"
- "encoding/json"
- "html"
- "strings"
- "golang-fave/engine/sqlw"
- "golang-fave/engine/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(ctx context.Context, 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(
- ctx,
- `SELECT
- fave_shop_products.id,
- fave_shop_products.name,
- fave_shop_products.price,
- fave_shop_products.alias,
- fave_shop_products.quantity,
- fave_shop_currencies.id,
- fave_shop_currencies.name,
- fave_shop_currencies.coefficient,
- fave_shop_currencies.code,
- fave_shop_currencies.symbol,
- IF(image_this.filename IS NULL, IFNULL(fave_shop_products.parent_id, fave_shop_products.id), fave_shop_products.id) as imgid,
- IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename
- FROM
- fave_shop_products
- LEFT JOIN fave_shop_currencies ON fave_shop_currencies.id = fave_shop_products.currency
- LEFT JOIN (
- SELECT
- m.product_id,
- m.filename
- FROM
- fave_shop_product_images as m
- LEFT JOIN (
- SELECT
- t.product_id,
- MIN(t.ord) as ordmin
- FROM
- fave_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 = fave_shop_products.id
- LEFT JOIN (
- SELECT
- m.product_id,
- m.filename
- FROM
- fave_shop_product_images as m
- LEFT JOIN (
- SELECT
- t.product_id,
- MIN(t.ord) as ordmin
- FROM
- fave_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 = fave_shop_products.parent_id
- WHERE
- fave_shop_products.active = 1 AND
- fave_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,
- &row.A_quantity,
- &roc.A_id,
- &roc.A_name,
- &roc.A_coefficient,
- &roc.A_code,
- &roc.A_symbol,
- &img_product_id,
- &img_filename,
- ); err == nil {
- removeProductId := 0
- if p, ok := this.Products[row.A_id]; ok == true {
- if row.A_quantity > 0 {
- var product_image string
- if img_filename == "" {
- product_image = utils.GetImagePlaceholderSrc()
- } 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)
- } else {
- removeProductId = row.A_id
- }
- }
- if removeProductId != 0 {
- delete(this.Products, removeProductId)
- }
- }
- }
- }
- }
- }
- func (this *session) updateTotals(p *SBParam) {
- this.totalSum = 0
- this.TotalCount = 0
- for _, product := range this.Products {
- product.Price = utils.FormatProductPrice(this.makePrice(product.price, product.currency.Id), (*p.Config).Shop.Price.Format, (*p.Config).Shop.Price.Round)
- product.Sum = utils.FormatProductPrice(this.makePrice(product.price*float64(product.Quantity), product.currency.Id), (*p.Config).Shop.Price.Format, (*p.Config).Shop.Price.Round)
- this.totalSum += this.makePrice(product.price, product.currency.Id) * float64(product.Quantity)
- this.TotalCount += product.Quantity
- }
- this.TotalSum = utils.FormatProductPrice(this.totalSum, (*p.Config).Shop.Price.Format, (*p.Config).Shop.Price.Round)
- }
- func (this *session) Preload(p *SBParam) {
- user_currency := 1
- if cookie, err := p.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 := p.DB.Query(
- p.R.Context(),
- `SELECT
- id,
- name,
- coefficient,
- code,
- symbol
- FROM
- fave_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
- }
- // Remember 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(p *SBParam) string {
- this.updateProducts(p.R.Context(), p.DB)
- this.updateTotals(p)
- json, err := json.Marshal(this)
- if err != nil {
- return `{"msg":"basket_engine_error","message":"` + err.Error() + `"}`
- }
- return string(json)
- }
- func (this *session) Plus(p *SBParam, product_id int) {
- if prod, ok := this.Products[product_id]; ok == true {
- prod.Quantity++
- this.updateProducts(p.R.Context(), p.DB)
- this.updateTotals(p)
- return
- }
- row := &utils.MySql_shop_product{}
- roc := &utils.MySql_shop_currency{}
- var img_product_id string
- var img_filename string
- if err := p.DB.QueryRow(
- p.R.Context(),
- `
- SELECT
- fave_shop_products.id,
- fave_shop_products.name,
- fave_shop_products.price,
- fave_shop_products.alias,
- fave_shop_currencies.id,
- fave_shop_currencies.name,
- fave_shop_currencies.coefficient,
- fave_shop_currencies.code,
- fave_shop_currencies.symbol,
- IF(image_this.filename IS NULL, IFNULL(fave_shop_products.parent_id, fave_shop_products.id), fave_shop_products.id) as imgid,
- IFNULL(IFNULL(image_this.filename, image_parent.filename), '') as filename
- FROM
- fave_shop_products
- LEFT JOIN fave_shop_currencies ON fave_shop_currencies.id = fave_shop_products.currency
- LEFT JOIN (
- SELECT
- m.product_id,
- m.filename
- FROM
- fave_shop_product_images as m
- LEFT JOIN (
- SELECT
- t.product_id,
- MIN(t.ord) as ordmin
- FROM
- fave_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 = fave_shop_products.id
- LEFT JOIN (
- SELECT
- m.product_id,
- m.filename
- FROM
- fave_shop_product_images as m
- LEFT JOIN (
- SELECT
- t.product_id,
- MIN(t.ord) as ordmin
- FROM
- fave_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 = fave_shop_products.parent_id
- WHERE
- fave_shop_products.active = 1 AND
- fave_shop_products.quantity > 0 AND
- fave_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 {
- var product_image string
- if img_filename == "" {
- product_image = utils.GetImagePlaceholderSrc()
- } 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(p.R.Context(), p.DB)
- this.updateTotals(p)
- }
- }
- func (this *session) Minus(p *SBParam, product_id int) {
- if prod, ok := this.Products[product_id]; ok == true {
- if prod.Quantity > 1 {
- prod.Quantity--
- } else {
- delete(this.Products, product_id)
- }
- this.updateProducts(p.R.Context(), p.DB)
- this.updateTotals(p)
- }
- }
- func (this *session) Remove(p *SBParam, product_id int) {
- if _, ok := this.Products[product_id]; ok == true {
- delete(this.Products, product_id)
- this.updateProducts(p.R.Context(), p.DB)
- this.updateTotals(p)
- }
- }
- func (this *session) ClearBasket(p *SBParam) {
- this.Products = map[int]*product{}
- this.updateProducts(p.R.Context(), p.DB)
- this.updateTotals(p)
- }
- func (this *session) ProductsCount() int {
- return this.TotalCount
- }
- func (this *session) GetAll(p *SBParam) *utils.MySql_basket {
- products := []utils.MySql_basket_product{}
- for _, product := range this.Products {
- products = append(products, utils.MySql_basket_product{
- A_product_id: product.Id,
- A_price: this.makePrice(product.price, product.currency.Id),
- A_quantity: product.Quantity,
- RenderName: product.Name,
- RenderLink: product.Link,
- RenderPrice: product.Price,
- RenderQuantity: product.Quantity,
- RenderSum: product.Sum,
- })
- }
- currency := utils.MySql_basket_currency{
- Id: this.Currency.Id,
- Name: this.Currency.Name,
- Coefficient: this.Currency.Coefficient,
- Code: this.Currency.Code,
- Symbol: this.Currency.Symbol,
- }
- all := utils.MySql_basket{
- Products: &products,
- Currency: ¤cy,
- TotalSum: this.totalSum,
- TotalCount: this.TotalCount,
- RenderTotalSum: this.TotalSum,
- }
- return &all
- }
|