package modules import ( "context" "time" "golang-fave/engine/utils" "golang-fave/engine/wrapper" ) func (this *Modules) RegisterAction_ShopDuplicate() *Action { return this.newAction(AInfo{ Mount: "shop-duplicate", WantAdmin: true, }, func(wrap *wrapper.Wrapper) { pf_id := utils.Trim(wrap.R.FormValue("id")) pf_attach := utils.Trim(wrap.R.FormValue("attach")) if !utils.IsNumeric(pf_id) { wrap.MsgError(`Inner system error`) return } var lastID int64 = 0 if err := wrap.DB.Transaction(wrap.R.Context(), func(ctx context.Context, tx *wrapper.Tx) error { // Block rows if _, err := tx.Exec(ctx, "SELECT id FROM fave_shop_products WHERE id = ? FOR UPDATE;", utils.StrToInt(pf_id)); err != nil { return err } if _, err := tx.Exec(ctx, "SELECT product_id FROM fave_shop_cat_product_rel WHERE product_id = ? FOR UPDATE;", utils.StrToInt(pf_id)); err != nil { return err } if _, err := tx.Exec(ctx, "SELECT product_id FROM fave_shop_filter_product_values WHERE product_id = ? FOR UPDATE;", utils.StrToInt(pf_id)); err != nil { return err } parent_id := "parent_id" if pf_attach == "1" { parent_id = pf_id } // Duplicate product res, err := tx.Exec( ctx, `INSERT INTO fave_shop_products ( parent_id, user, currency, price, gname, name, alias, vendor, quantity, category, briefly, content, datetime, active ) SELECT `+parent_id+`, user, currency, price, '', CONCAT(name, ' (Copy)'), CONCAT(REGEXP_REPLACE(alias, '-c[0-9]+$', ''), '-c', '`+utils.Int64ToStr(time.Now().Unix())+`'), vendor, quantity, category, briefly, content, '`+utils.UnixTimestampToMySqlDateTime(utils.GetCurrentUnixTimestamp())+`', 0 FROM fave_shop_products WHERE id = ? ;`, utils.StrToInt(pf_id), ) if err != nil { return err } // Get inserted product id lastID, err = res.LastInsertId() if err != nil { return err } // Block new product row if _, err := tx.Exec(ctx, "SELECT id FROM fave_shop_products WHERE id = ? FOR UPDATE;", lastID); err != nil { return err } // Duplicate categories cat_sqls := []string{} if cat_rows, err := tx.Query( ctx, `SELECT product_id, category_id FROM fave_shop_cat_product_rel WHERE product_id = ? ;`, utils.StrToInt(pf_id), ); err == nil { defer cat_rows.Close() for cat_rows.Next() { var product_id int var category_id int if err := cat_rows.Scan(&product_id, &category_id); *wrap.LogCpError(&err) == nil { cat_sqls = append(cat_sqls, ` INSERT INTO fave_shop_cat_product_rel SET product_id = `+utils.Int64ToStr(lastID)+`, category_id = `+utils.IntToStr(category_id)+` ; `) } } } for _, sql_query := range cat_sqls { tx.Exec(ctx, sql_query) } // Duplicate attributes attributes_sqls := []string{} if attributes_rows, err := tx.Query( ctx, `SELECT product_id, filter_value_id FROM fave_shop_filter_product_values WHERE product_id = ? ;`, utils.StrToInt(pf_id), ); err == nil { defer attributes_rows.Close() for attributes_rows.Next() { var product_id int var filter_value_id int if err := attributes_rows.Scan(&product_id, &filter_value_id); *wrap.LogCpError(&err) == nil { attributes_sqls = append(attributes_sqls, ` INSERT INTO fave_shop_filter_product_values SET product_id = `+utils.Int64ToStr(lastID)+`, filter_value_id = `+utils.IntToStr(filter_value_id)+` ; `) } } } for _, sql_query := range attributes_sqls { tx.Exec(ctx, sql_query) } return nil }); err != nil { wrap.MsgError(err.Error()) return } // Navigate to new product page wrap.Write(`window.location='/cp/shop/modify/` + utils.Int64ToStr(lastID) + `/';`) }) }