Example #1
0
func (c *Controller) EMyHistory() (string, error) {

	var err error

	if c.SessUserId == 0 {
		return `<script language="javascript"> window.location.href = "` + c.EURL + `"</script>If you are not redirected automatically, follow the <a href="` + c.EURL + `">` + c.EURL + `</a>`, nil
	}

	currencyList, err := utils.EGetCurrencyList()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	//fmt.Println("currencyList", currencyList)
	var myHistory []*EmyHistory

	rows, err := c.Query(c.FormatQuery(`
			SELECT id, time, amount, sell_rate, sell_currency_id, buy_currency_id
			FROM e_trade
			WHERE user_id = ?
			ORDER BY time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		myHist := new(EmyHistory)
		err = rows.Scan(&myHist.Id, &myHist.Time, &myHist.Amount, &myHist.SellRate, &myHist.SellCurrencyId, &myHist.BuyCurrencyId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}

		// определим тип ордера и пару
		if myHist.SellCurrencyId < 1000 {
			myHist.OrderType = "sell"
			myHist.SellRate = 1 / myHist.SellRate
			myHist.Total = myHist.Amount * myHist.SellRate
			myHist.Amount = myHist.Amount
			myHist.Pair = currencyList[myHist.SellCurrencyId] + "/" + currencyList[myHist.BuyCurrencyId]
		} else {
			myHist.OrderType = "buy"
			myHist.Total = myHist.Amount
			myHist.Amount = myHist.Amount * (1 / myHist.SellRate)
			myHist.Pair = currencyList[myHist.BuyCurrencyId] + "/" + currencyList[myHist.SellCurrencyId]
		}

		myHistory = append(myHistory, myHist)
	}

	TemplateStr, err := makeTemplate("e_my_history", "eMyHistory", &eMyHistoryPage{
		Lang:         c.Lang,
		UserId:       c.SessUserId,
		MyHistory:    myHistory,
		CurrencyList: currencyList})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
Example #2
0
func Exchange(chBreaker chan bool, chAnswer chan string) {

	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "Exchange"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if utils.Mobile() {
		d.sleepTime = 3600
	} else {
		d.sleepTime = 60
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		blockId, err := d.GetConfirmedBlockId()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		var myPrefix string
		community, err := d.GetCommunityUsers()
		if len(community) > 0 {
			adminUserId, err := d.GetPoolAdminUserId()
			if err != nil {
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			myPrefix = utils.Int64ToStr(adminUserId) + "_"
		} else {
			myPrefix = ""
		}

		eConfig, err := d.GetMap(`SELECT * FROM e_config`, "name", "value")
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		confirmations := utils.StrToInt64(eConfig["confirmations"])
		mainDcAccount := utils.StrToInt64(eConfig["main_dc_account"])

		// все валюты, с которыми работаем
		currencyList, err := utils.EGetCurrencyList()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		// ++++++++++++ reduction ++++++++++++

		// максимальный номер блока для процентов. Чтобы брать только новые
		maxReductionBlock, err := d.Single(`SELECT max(block_id) FROM e_reduction`).Int64()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		// если есть свежая reduction, то нужно остановить торги
		reduction, err := d.Single(`SELECT block_id FROM reduction WHERE block_id > ? and pct > 0`, maxReductionBlock).Int64()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		if reduction > 0 {
			err = d.ExecSql(`INSERT INTO e_reduction_lock (time) VALUES (?)`, utils.Time())
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
			}
		}

		// если уже прошло 10 блоков с момента обнаружения reduction, то производим сокращение объема монет
		rows, err := d.Query(d.FormatQuery(`SELECT pct, currency_id, time, block_id FROM reduction WHERE block_id > ? AND
	block_id < ?`), maxReductionBlock, blockId-confirmations)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		for rows.Next() {
			var pct float64
			var currencyId, rTime, blockId int64
			err = rows.Scan(&pct, &currencyId, &rTime, &blockId)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			//	$k = (100-$row['pct'])/100;
			k := (100 - pct) / 100
			// уменьшаем все средства на счетах
			err = d.ExecSql(`UPDATE e_wallets SET amount = amount * ? WHERE currency_id = ?`, k, currencyId)

			// уменьшаем все средства на вывод
			err = d.ExecSql(`UPDATE e_withdraw SET amount = amount * ? WHERE currency_id = ? AND close_time = 0`, k, currencyId)

			// уменьшаем все ордеры на продажу
			err = d.ExecSql(`UPDATE e_orders SET amount = amount * ?, begin_amount = begin_amount * ? WHERE sell_currency_id = ?`, k, k, currencyId)

			err = d.ExecSql(`INSERT INTO e_reduction (
					time,
					block_id,
					currency_id,
					pct
				)
				VALUES (
					?,
					?,
					?,
					?
				)`, rTime, blockId, currencyId, pct)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}
		rows.Close()

		// ++++++++++++ DC ++++++++++++
		/*
		 * Важно! отключать в кроне при обнулении данных в БД
		 *
		 * 1. Получаем инфу о входящих переводах и начисляем их на счета юзеров
		 * 2. Обновляем проценты
		 * 3. Чистим кол-во отправленных смс-ок
		 * */
		nodePrivateKey, err := d.GetNodePrivateKey(myPrefix)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		/*
		 * Получаем инфу о входящих переводах и начисляем их на счета юзеров
		 * */

		// если всё остановлено из-за найденного блока с reduction, то входящие переводы не обрабатываем
		reductionLock, err := utils.EGetReductionLock()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		if reductionLock > 0 {
			if d.dPrintSleep(utils.ErrInfo("reductionLock"), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		rows, err = d.Query(d.FormatQuery(`
				SELECT amount, id, block_id, type_id, currency_id, to_user_id, time, comment, comment_status
				FROM my_dc_transactions
				WHERE type = 'from_user' AND
					  block_id < ? AND
					  exchange_checked = 0 AND
					  status = 'approved' AND
					  to_user_id = ?
				ORDER BY id DESC`), blockId-confirmations, mainDcAccount)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		for rows.Next() {
			var amount float64
			var id, blockId, typeId, currencyId, toUserId, txTime int64
			var comment, commentStatus string
			err = rows.Scan(&amount, &id, &blockId, &typeId, &currencyId, &toUserId, &txTime, &comment, &commentStatus)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			// отметим exchange_checked=1, чтобы больше не брать эту тр-ию
			err = d.ExecSql(`UPDATE my_dc_transactions SET exchange_checked = 1 WHERE id = ?`, id)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			// вначале нужно проверить, точно ли есть такой перевод в блоке
			binaryData, err := d.Single(`SELECT data FROM block_chain WHERE id = ?`, blockId).Bytes()
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			p := new(dcparser.Parser)
			p.DCDB = d.DCDB
			p.BinaryData = binaryData
			p.ParseDataLite()
			for _, txMap := range p.TxMapArr {
				// пропускаем все ненужные тр-ии
				if utils.BytesToInt64(txMap["type"]) != utils.TypeInt("SendDc") {
					continue
				}
				log.Debug("md5hash %s", txMap["md5hash"])

				// если что-то случится с таблой my_dc_transactions, то все ввода на биржу будут зачислены по новой
				// поэтому нужно проверять e_adding_funds
				exists, err := d.Single(`SELECT id FROM e_adding_funds WHERE hex(tx_hash) = ?`, string(txMap["md5hash"])).Int64()
				if err != nil {
					rows.Close()
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				log.Debug("exists %d", exists)
				if exists != 0 {
					continue
				}

				log.Debug("user_id = %d / typeId = %d / currency_id = %d / currencyId = %d / amount = %f / amount = %f / comment = %s / comment = %s / to_user_id = %d / toUserId = %d ", utils.BytesToInt64(txMap["user_id"]), typeId, utils.BytesToInt64(txMap["currency_id"]), currencyId, utils.BytesToFloat64(txMap["amount"]), amount, string(utils.BinToHex(txMap["comment"])), comment, utils.BytesToInt64(txMap["to_user_id"]), toUserId)
				// сравнение данных из таблы my_dc_transactions с тем, что в блоке
				if utils.BytesToInt64(txMap["user_id"]) == typeId && utils.BytesToInt64(txMap["currency_id"]) == currencyId && utils.BytesToFloat64(txMap["amount"]) == amount && string(utils.BinToHex(txMap["comment"])) == comment && utils.BytesToInt64(txMap["to_user_id"]) == toUserId {

					decryptedComment := comment
					if commentStatus == "encrypted" {
						// расшифруем коммент
						block, _ := pem.Decode([]byte(nodePrivateKey))
						if block == nil || block.Type != "RSA PRIVATE KEY" {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						private_key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						decryptedComment_, err := rsa.DecryptPKCS1v15(rand.Reader, private_key, utils.HexToBin(comment))
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						decryptedComment = string(decryptedComment_)
						// запишем расшифрованный коммент, чтобы потом можно было найти перевод в ручном режиме
						err = d.ExecSql("UPDATE "+myPrefix+"my_dc_transactions SET comment = ?, comment_status = 'decrypted' WHERE id = ?", decryptedComment, id)
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
					}

					// возможно юзер сделал перевод в той валюте, которая у нас на бирже еще не торгуется
					if len(currencyList[currencyId]) == 0 {
						log.Error("currencyId %d not trading", currencyId)
						continue
					}

					// возможно, что чуть раньше было reduction, а это значит, что все тр-ии,
					// которые мы ещё не обработали и которые были До блока с reduction нужно принимать с учетом reduction
					// т.к. средства на нашем счете уже урезались, а  вот те, что после reduction - остались в том виде, в котором пришли
					lastReduction, err := d.OneRow("SELECT block_id, pct FROM reduction WHERE currency_id  = ? ORDER BY block_id", currencyId).Int64()
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					if blockId <= lastReduction["block_id"] {
						// сумму с учетом reduction
						k0 := (100 - lastReduction["pct"]) / 100
						amount = amount * float64(k0)
					}

					// начисляем средства на счет того, чей id указан в комменте
					r, _ := regexp.Compile(`(?i)\s*#\s*([0-9]+)\s*`)
					user := r.FindStringSubmatch(decryptedComment)
					if len(user) == 0 {
						log.Error("len(user) == 0")
						continue
					}
					log.Debug("user %s", user[1])
					// user_id с биржевой таблы
					uid := utils.StrToInt64(user[1])
					userAmountAndProfit := utils.EUserAmountAndProfit(uid, currencyId)
					newAmount_ := userAmountAndProfit + amount

					utils.UpdEWallet(uid, currencyId, utils.Time(), newAmount_, true)

					// для отчетности запишем в историю
					err = d.ExecSql(`
						INSERT INTO e_adding_funds (
							user_id,
							currency_id,
							time,
							amount,
							tx_hash
						)
						VALUES (
							?,
							?,
							?,
							?,
							?
						)`, uid, currencyId, txTime, amount, string(txMap["md5hash"]))
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
				}
			}
		}
		rows.Close()

		/*
		 * Обновляем проценты
		 * */
		// максимальный номер блока для процентов. Чтобы брать только новые
		maxPctBlock, err := d.Single(`SELECT max(block_id) FROM e_user_pct`).Int64()

		log.Debug(`SELECT time, block_id, currency_id, user FROM pct WHERE  block_id < ` + utils.Int64ToStr(blockId-confirmations) + ` AND block_id > ` + utils.Int64ToStr(maxPctBlock))
		rows, err = d.Query(d.FormatQuery(`SELECT time, block_id, currency_id, user FROM pct WHERE  block_id < ? AND block_id > ?`), blockId-confirmations, maxPctBlock)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		for rows.Next() {
			var pct float64
			var pTime, blockId, currencyId int64
			err = rows.Scan(&pTime, &blockId, &currencyId, &pct)
			if err != nil {
				rows.Close()
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			d.ExecSql(`
				INSERT INTO e_user_pct (
					time,
					block_id,
					currency_id,
					pct
				)
				VALUES (
					?,
					?,
					?,
					?
				)`, pTime, blockId, currencyId, pct)
		}
		rows.Close()

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}
Example #3
0
func (c *Controller) EMain() (string, error) {

	var err error

	dcCurrencyId := utils.StrToInt64(c.Parameters["dc_currency_id"])
	currencyId := utils.StrToInt64(c.Parameters["currency_id"])
	if dcCurrencyId == 0 {
		dcCurrencyId = 72
	}
	if currencyId == 0 {
		currencyId = 1001
	}

	// все валюты, с которыми работаем
	currencyList, err := utils.EGetCurrencyList()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	log.Debug("%v", currencyList)

	// работаем только с теми валютами, которые есть у нас в списке
	if len(currencyList[dcCurrencyId]) == 0 || len(currencyList[currencyId]) == 0 {
		return "", utils.ErrInfo("incorrect currency")
	}

	// пары валют для меню
	currencyListPair, err := eGetCurrencyPair()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	dcCurrency := currencyList[dcCurrencyId]
	currency := currencyList[currencyId]

	// история сделок
	var tradeHistory []map[string]string

	rows, err := c.Query(c.FormatQuery(`
			SELECT sell_currency_id, sell_rate, amount, time
			FROM e_trade
			WHERE ((sell_currency_id = ? AND buy_currency_id = ?) OR (sell_currency_id = ? AND buy_currency_id = ?)) AND main = 1
			ORDER BY time DESC
			LIMIT 40
			`), dcCurrencyId, currencyId, currencyId, dcCurrencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		var sellCurrencyId, eTime int64
		var sellRate, amount float64
		err = rows.Scan(&sellCurrencyId, &sellRate, &amount, &eTime)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		var eType string
		var eAmount float64
		var eTotal float64
		if sellCurrencyId == dcCurrencyId {
			eType = "sell"
			sellRate = 1 / sellRate
			eAmount = amount
			eTotal = amount * sellRate
		} else {
			eType = "buy"
			eAmount = amount * (1 / sellRate)
			eTotal = amount
		}
		t := time.Unix(eTime, 0)
		tradeHistory = append(tradeHistory, map[string]string{"Time": t.Format(c.TimeFormat), "Type": eType, "SellRate": utils.ClearNull(utils.Float64ToStr(sellRate), 4), "Amount": utils.ClearNull(utils.Float64ToStr(eAmount), 4), "Total": utils.ClearNull(utils.Float64ToStr(eTotal), 4)})
	}

	// активные ордеры на продажу
	var orders eOrders
	rows, err = c.Query(c.FormatQuery(`
			SELECT sell_rate, amount
			FROM e_orders
			WHERE (sell_currency_id = ? AND buy_currency_id = ?) AND
						empty_time = 0 AND
						del_time = 0 AND
						amount > 0
			ORDER BY sell_rate DESC
			LIMIT 100
			`), dcCurrencyId, currencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	// мин. цена покупки
	var buyMin float64
	for rows.Next() {
		var sellRate, amount float64
		err = rows.Scan(&sellRate, &amount)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if orders.Sell == nil {
			orders.Sell = make(map[float64]float64)
		}
		sellRate = utils.ClearNullFloat64(1/sellRate, 6)
		orders.Sell[sellRate] = utils.ClearNullFloat64(orders.Sell[sellRate]+amount, 6)
		if buyMin == 0 {
			buyMin = sellRate
		} else if sellRate < buyMin {
			buyMin = sellRate
		}
	}

	keys := []float64{}
	for k := range orders.Sell {
		keys = append(keys, k)
	}
	sort.Float64s(keys)
	var eOrdersSell []map[string]float64
	for _, k := range keys {
		eOrdersSell = append(eOrdersSell, map[string]float64{"sell_rate": k, "amount": orders.Sell[k]})
	}

	// активные ордеры на покупку
	rows, err = c.Query(c.FormatQuery(`
			SELECT sell_rate, amount
			FROM e_orders
			WHERE (sell_currency_id = ? AND buy_currency_id = ?) AND
					empty_time = 0 AND
					del_time = 0 AND
					amount > 0
			ORDER BY sell_rate ASC
			LIMIT 100
			`), currencyId, dcCurrencyId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	// мин. цена продажи
	var sellMax float64
	for rows.Next() {
		var sellRate, amount float64
		err = rows.Scan(&sellRate, &amount)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if orders.Buy == nil {
			orders.Buy = make(map[float64]float64)
		}
		sellRate = utils.ClearNullFloat64(sellRate, 6)
		orders.Buy[sellRate] = utils.ClearNullFloat64(orders.Buy[sellRate]+amount*(1/sellRate), 6)
		if sellMax == 0 {
			sellMax = sellRate
		} else if sellRate < sellMax {
			sellMax = sellRate
		}
	}
	var keysR sort.Float64Slice
	for k := range orders.Buy {
		keysR = append(keysR, k)
	}
	sort.Sort(sort.Reverse(keysR))
	var eOrdersBuy []map[string]float64
	for _, k := range keysR {
		eOrdersBuy = append(eOrdersBuy, map[string]float64{"sell_rate": k, "amount": orders.Buy[k]})
	}

	// комиссия
	commission := c.EConfig["commission"]
	commissionText := strings.Replace(c.Lang["commission_text"], "[commission]", commission, -1)

	// кол-во юзеров
	members, err := c.Single(`SELECT count(*) FROM e_users`).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}

	TemplateStr, err := makeTemplate("e_main", "eMain", &eMainPage{
		Lang:             c.Lang,
		Commission:       commission,
		Members:          members,
		SellMax:          sellMax,
		BuyMin:           buyMin,
		EOrdersSell:      eOrdersSell,
		EOrdersBuy:       eOrdersBuy,
		DcCurrency:       dcCurrency,
		Currency:         currency,
		DcCurrencyId:     dcCurrencyId,
		UserId:           c.SessUserId,
		TradeHistory:     tradeHistory,
		CurrencyId:       currencyId,
		CommissionText:   commissionText,
		CurrencyListPair: currencyListPair,
		CurrencyList:     currencyList})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
Example #4
0
func (c *Controller) EMyFinance() (string, error) {

	var err error

	if c.SessUserId == 0 {
		return `<script language="javascript"> window.location.href = "` + c.EURL + `"</script>If you are not redirected automatically, follow the <a href="` + c.EURL + `">` + c.EURL + `</a>`, nil
	}

	confirmations := c.EConfig["confirmations"]

	currencyList, err := utils.EGetCurrencyList()

	// счет, куда юзеры должны слать DC
	mainDcAccount := c.EConfig["main_dc_account"]

	currency := make(map[string]map[string]string)

	// валюты, по которым идут торги на бирже
	//var myWallets []map[string]string
	eCurrency, err := c.GetAll(`SELECT name, id FROM e_currency ORDER BY sort_id ASC`, -1)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	for _, data := range eCurrency {
		wallet, err := c.OneRow("SELECT * FROM e_wallets WHERE user_id  =  ? AND currency_id  =  ?", c.SessUserId, data["id"]).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if len(wallet) > 0 {
			amount := utils.StrToFloat64(wallet["amount"])
			profit, err := utils.DB.CalcProfitGen(utils.StrToInt64(wallet["currency_id"]), amount, 0, utils.StrToInt64(wallet["last_update"]), utils.Time(), "wallet")
			if err != nil {
				return "", utils.ErrInfo(err)
			}
			wallet["amount"] = utils.Float64ToStr(amount + profit)
		} else {
			wallet["amount"] = "0"
		}

		currency[data["id"]] = make(map[string]string)
		currency[data["id"]]["amount"] = wallet["amount"]
		currency[data["id"]]["name"] = data["name"]
		if utils.StrToInt64(data["id"]) < 1000 { //DC
			currency[data["id"]]["input"] = strings.Replace(c.Lang["dc_deposit_text"], "[dc_currency]", data["name"], -1)
			currency[data["id"]]["input"] = strings.Replace(currency[data["id"]]["input"], "[account]", mainDcAccount, -1)
			currency[data["id"]]["input"] = strings.Replace(currency[data["id"]]["input"], "[user_id]", utils.Int64ToStr(c.SessUserId), -1)
			currency[data["id"]]["input"] = strings.Replace(currency[data["id"]]["input"], "[confirmations]", confirmations, -1)
		}

		currency[data["id"]]["output"] = `<div class="pull-left"><h4>` + c.Lang["withdraw0"] + ` ` + data["name"] + `</h4>
			<table class="table_out">
			<tbody>
			<tr>
			<td>` + c.Lang["your_dcoin_account"] + `:</td>
			<td class="form-inline"><input id="account-` + data["id"] + `" class="form-control col-xs-3" type="text"></td>
			</tr>
			<tr>
			<td>` + c.Lang["amount_to_withdrawal"] + `:</td>
			<td class="form-inline" style="line-height: 35px"><input id="amount-` + data["id"] + `" class="form-control col-xs-3" maxlength="15" type="text"  onkeyup="calc_withdraw_amount(` + data["id"] + `, '0.1')" onchange="calc_withdraw_amount(` + data["id"] + `, '0.1')" style="margin-right:5px"> ` + data["name"] + `</td>
			</tr>
			<tr>
			<td>` + c.Lang["you_will_receive"] + `:</td>
			<td class="form-inline" style="line-height: 35px"><input  disabled="" id="withdraw_amount-` + data["id"] + `" class="form-control col-xs-3" maxlength="15" type="text" style="margin-right:5px"> ` + data["name"] + `</td>
			</tr>
			</tbody></table><div id="alerts-` + data["id"] + `"></div><button class="btn btn-outline btn-primary" onclick="withdraw(` + data["id"] + `, 'Dcoin')">` + c.Lang["withdrawal"] + `</button>
			</div><div class="pull-left" style="margin-left:30px; margin-top:43px; border-left: 4px solid #ccc; padding:7px 7px; width:400px">`
		dcWithdrawText := strings.Replace(c.Lang["dc_withdraw_text"], "[min_amount]", "5", -1)
		dcWithdrawText = strings.Replace(dcWithdrawText, "[currency]", data["name"], -1)
		currency[data["id"]]["output"] += dcWithdrawText + `</div>`
	}

	if currency["1001"] == nil {
		currency["1001"] = make(map[string]string)
	}

	currency["1001"]["name"] = "USD"
	currency["1001"]["input"] = `<div class="pull-left"><h4>` + c.Lang["deposit0"] + ` USD</h4>
		<select id="ps_select" class="form-control">
		  <option value="pm">Perfect Money</option>
		  <option value="ik">Mobile, Yandex</option>
		  <option value="payeer">BTC</option>
		</select>
			<div style="display:block" id="pm_form">
				<form action="https://perfectmoney.is/api/step1.asp" method="POST">
					<input type="hidden" name="PAYEE_ACCOUNT" value="` + c.EConfig["pm_id"] + `">
					<input type="hidden" name="PAYEE_NAME" value="Dcoin">
					<input type="hidden" name="PAYMENT_ID" value="` + utils.Int64ToStr(c.SessUserId) + `">
					<input type="hidden" name="PAYMENT_UNITS" value="USD">
					<input type="hidden" name="STATUS_URL" value="` + c.EURL + `ajax?controllerName=EGatePm">
					<input type="hidden" name="PAYMENT_URL" value="` + c.EURL + `ajax?controllerName=ESuccess">
					<input type="hidden" name="PAYMENT_URL_METHOD" value="LINK">
					<input type="hidden" name="NOPAYMENT_URL" value="` + c.EURL + `ajax?controllerName=EFailure">
					<input type="hidden" name="NOPAYMENT_URL_METHOD" value="LINK">
					<input type="hidden" name="SUGGESTED_MEMO" value="Dcoins">
					<input type="hidden" name="BAGGAGE_FIELDS" value="">
					<table class="table_out">
					<tbody>
						<tr>
						<td>` + c.Lang["amount_to_pay"] + `</td>
						<td class="form-inline" style="line-height: 35px;"><input name="PAYMENT_AMOUNT" class="form-control" type="text" style="margin-right:5px; width:120px"><input type="submit" value="` + c.Lang["deposit"] + `" class="btn btn-outline btn-success" name="PAYMENT_METHOD"></td>
						</tr>
						<tr>
					 </tbody>
					 </table>
				</form>
			</div>
			<div style="display:none" id="ik_form">
				<form id="payment" name="payment" method="post" action="https://sci.interkassa.com/" enctype="utf-8">
				    <input type="hidden" name="ik_co_id" value="` + c.EConfig["ik_id"] + `" />
					<input type="hidden" name="ik_pm_no" value="ik_pm_no" />
					<input type="hidden" name="ik_cur" value="USD" />
					<input type="hidden" name="ik_ia_u" value="` + c.EURL + `ajax?controllerName=EGateIk" />
					<input type="hidden" name="ik_suc_u" value=""` + c.EURL + `ajax?controllerName=ESuccess" />
					<input type="hidden" name="ik_fal_u" value="` + c.EURL + `ajax?controllerName=EFailure" />
					<input type="hidden" name="ik_desc" value="` + utils.Int64ToStr(c.SessUserId) + `" />
				<table class="table_out">
				<tbody>
					<tr>
					<td>` + c.Lang["amount_to_pay"] + `</td>
					<td class="form-inline" style="line-height: 35px;"><input name="ik_am" class="form-control" type="text" style="margin-right:5px; width:120px"><input type="submit" value="` + c.Lang["deposit"] + `" class="btn btn-outline btn-success"></td>
					</tr>
					<tr>
				 </tbody>
				 </table>
				</form>
			</div>
			<script>
			$('#payeer_sign').bind('click', function () {
				$.post( 'ajax?controllerName=EPayeerSign', {
					m_orderid: $('input[name=m_orderid]').val(),
					m_desc: $('input[name=m_desc]').val(),
					m_amount: $('input[name=m_amount]').val()
				},
				function (data) {
					console.log("data", data)
					$('input[name=m_sign]').val(data);
					$("#payeer_form_data").submit();
				});
			});
			</script>
			<div style="display:none" id="payeer_form">
				<form id="payeer_form_data" name="payment" method="post" action="https://payeer.com/merchant/" enctype="utf-8">
				   	<input type="hidden" id="m_shop" name="m_shop" value="` + c.EConfig["payeer_id"] + `">
					<input type="hidden" id="m_orderid" name="m_orderid" value="1234">
					<input type="hidden" id="m_curr" name="m_curr" value="USD">
					<input type="hidden" id="m_desc" name="m_desc" value="` + base64.StdEncoding.EncodeToString(utils.Int64ToByte(c.SessUserId)) + `">
					<input type="hidden" id="m_sign" name="m_sign" value="">
				<table class="table_out">
				<tbody>
					<tr>
					<td>` + c.Lang["amount_to_pay"] + `</td>
					<td class="form-inline" style="line-height: 35px;"><input id="m_amount" name="m_amount" class="form-control" type="text" style="margin-right:5px; width:120px"><input id="payeer_sign" type="button" value="` + c.Lang["deposit"] + `" class="btn btn-outline btn-success"></td>
					</tr>
					<tr>
				 </tbody>
				 </table>
				</form>
			</div>

			</div>`

	currency["1001"]["output"] = `<div class="pull-left"><h4>` + c.Lang["withdraw0"] + ` USD</h4>
		<table class="table_out">
			<tbody>
			<tr>
			<td>` + c.Lang["withdrawal_on_the_purse"] + `:</td>
			<td class="form-inline"><div class="form-group"><select class="form-control" style="width:300px"><option>Perfect Money [1.5%] [min 10 USD]</option></select></div></td>
			</tr>
			<tr>
			<td>` + c.Lang["purse"] + `:</td>
			<td class="form-inline" style="line-height: 35px;"><input id="account-1001" class="form-control" type="text" style="margin-right:5px; width:300px"></td>
			</tr>
			<tr>
			<td>` + c.Lang["amount_to_withdrawal"] + `:</td>
			<td class="form-inline" style="line-height: 35px;"><input id="amount-1001" class="form-control" type="text"  onkeyup="calc_withdraw_amount(1001, '1.5')" onchange="calc_withdraw_amount(1001, '1.5')" style="margin-right:5px; width:300px"></td>
			</tr>
			<tr>
			<td>` + c.Lang["you_will_receive"] + `:</td>
			<td class="form-inline" style="line-height: 35px"><input  disabled="" id="withdraw_amount-1001" class="form-control" type="text" style="margin-right:5px; width:300px"> </td>
			</tr>
			</tbody></table><div id="alerts-1001"></div><button class="btn btn-outline btn-primary" onclick="withdraw(1001, 'Perfect-money')">` + c.Lang["withdrawal"] + `</button>
			</div><div class="pull-left" style="margin-left:30px; margin-top:43px; border-left: 4px solid #ccc; padding:7px 7px; width:350px">` + c.Lang["withdrawal_within_hours"] + `</div>`

	types := map[string]string{"withdraw": c.Lang["withdraw0"], "adding_funds": c.Lang["deposit0"]}

	// история вывода средств
	myFinanceHistory_ := make(map[int64][]*EmyFinanceType)
	rows, err := c.Query(c.FormatQuery(`
			SELECT id, amount, wd_amount, close_time, currency_id, method, open_time
			FROM e_withdraw
			WHERE user_id = ?
			ORDER BY open_time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		Finance := new(EmyFinanceType)
		err = rows.Scan(&Finance.Id, &Finance.Amount, &Finance.WdAmount, &Finance.CloseTime, &Finance.CurrencyId, &Finance.Method, &Finance.OpenTime)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		Finance.Ftype = types["withdraw"]
		Finance.Amount = Finance.WdAmount
		Finance.AddTime = Finance.OpenTime
		if Finance.CloseTime == 0 {
			Finance.Status = c.Lang["in_process"]
		} else {
			t := time.Unix(Finance.CloseTime, 0)
			timeFormated := t.Format(c.TimeFormat)
			Finance.Status = `<span class="text-success"><strong>` + c.Lang["ready"] + `</strong></span> (` + timeFormated + `)`
		}
		Finance.Method = Finance.Method + ` (` + currencyList[Finance.CurrencyId] + `)`
		myFinanceHistory_[Finance.OpenTime] = append(myFinanceHistory_[Finance.OpenTime], Finance)
	}

	// история ввода средств
	rows, err = c.Query(c.FormatQuery(`
			SELECT id, amount, time, currency_id
			FROM e_adding_funds
			WHERE user_id = ?
			ORDER BY time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		Finance := new(EmyFinanceType)
		err = rows.Scan(&Finance.Id, &Finance.Amount, &Finance.AddTime, &Finance.CurrencyId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		Finance.Ftype = types["adding_funds"]
		Finance.Status = `<span class="text-success"><strong>` + c.Lang["ready"] + `</strong></span>`
		Finance.Method = `Dcoin (` + currencyList[Finance.CurrencyId] + `)`
		myFinanceHistory_[Finance.AddTime] = append(myFinanceHistory_[Finance.AddTime], Finance)
	}

	// история ввода средств IK
	rows, err = c.Query(c.FormatQuery(`
			SELECT id, amount, time, currency_id
			FROM e_adding_funds_ik
			WHERE user_id = ?
			ORDER BY time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		Finance := new(EmyFinanceType)
		err = rows.Scan(&Finance.Id, &Finance.Amount, &Finance.AddTime, &Finance.CurrencyId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		Finance.Ftype = types["adding_funds"]
		Finance.Status = `<span class="text-success"><strong>` + c.Lang["ready"] + `</strong></span>`
		Finance.Method = `Interkassa (` + currencyList[Finance.CurrencyId] + `)`
		myFinanceHistory_[Finance.AddTime] = append(myFinanceHistory_[Finance.AddTime], Finance)
	}

	// история ввода средств PM
	rows, err = c.Query(c.FormatQuery(`
			SELECT id, amount, time, currency_id
			FROM e_adding_funds_pm
			WHERE user_id = ?
			ORDER BY time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		Finance := new(EmyFinanceType)
		err = rows.Scan(&Finance.Id, &Finance.Amount, &Finance.AddTime, &Finance.CurrencyId)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		Finance.Ftype = types["adding_funds"]
		Finance.Status = `<span class="text-success"><strong>` + c.Lang["ready"] + `</strong></span>`
		Finance.Method = `PerfectMoney (` + currencyList[Finance.CurrencyId] + `)`
		myFinanceHistory_[Finance.AddTime] = append(myFinanceHistory_[Finance.AddTime], Finance)
	}

	//map[int64][]*EmyFinanceType
	var keys []int
	for k := range myFinanceHistory_ {
		keys = append(keys, int(k))
	}
	sort.Ints(keys)

	var my_finance_history []*EmyFinanceType
	for _, k := range keys {
		for _, data := range myFinanceHistory_[int64(k)] {
			my_finance_history = append(my_finance_history, data)
		}
	}
	///home/z/go-projects/src/github.com/c-darwin/dcoin-go/packages/controllers/e_my_finance.go:275: cannot use myFinanceHistory_[k] (type []*EmyFinanceType) as type *EmyFinanceType in append

	collapse := c.Parameters["collapse"]

	TemplateStr, err := makeTemplate("e_my_finance", "eMyFinance", &eMyFinancePage{
		Lang:             c.Lang,
		UserId:           c.SessUserId,
		MyFinanceHistory: my_finance_history,
		Collapse:         collapse,
		Currency:         currency,
		CurrencyList:     currencyList})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}
Example #5
0
func (c *Controller) EMyOrders() (string, error) {

	var err error

	if c.SessUserId == 0 {
		return `<script language="javascript"> window.location.href = "` + c.EURL + `"</script>If you are not redirected automatically, follow the <a href="` + c.EURL + `">` + c.EURL + `</a>`, nil
	}

	currencyList, err := utils.EGetCurrencyList()

	var myOrders []*EmyOrders

	rows, err := c.Query(c.FormatQuery(`
			SELECT id, time, empty_time, amount, begin_amount, sell_currency_id, buy_currency_id, sell_rate, begin_amount, del_time
			FROM e_orders
			WHERE user_id = ? AND
						 del_time = 0
			ORDER BY time DESC
			LIMIT 40
			`), c.SessUserId)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	defer rows.Close()
	for rows.Next() {
		myOrder := new(EmyOrders)
		err = rows.Scan(&myOrder.Id, &myOrder.Time, &myOrder.EmptyTime, &myOrder.Amount, &myOrder.BeginAmount, &myOrder.SellCurrencyId, &myOrder.BuyCurrencyId, &myOrder.SellRate, &myOrder.BeginAmount, &myOrder.DelTime)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if myOrder.EmptyTime == 0 {
			myOrder.Status = c.Lang["active"]
		} else {
			myOrder.Status = c.Lang["executed"]
		}

		// на сколько % выполнен ордер
		myOrder.OrderComplete = utils.Round(100-(myOrder.Amount/myOrder.BeginAmount)*100, 1)

		// определим тип ордера и пару
		if myOrder.SellCurrencyId < 1000 {
			myOrder.OrderType = "sell"
			myOrder.SellRate = 1 / myOrder.SellRate
			myOrder.Total = myOrder.BeginAmount * myOrder.SellRate
			myOrder.BeginAmount = myOrder.BeginAmount
			myOrder.Pair = currencyList[myOrder.SellCurrencyId] + "/" + currencyList[myOrder.BuyCurrencyId]
		} else {
			myOrder.OrderType = "buy"
			myOrder.Total = myOrder.BeginAmount
			myOrder.Amount = myOrder.BeginAmount * (1 / myOrder.SellRate)
			myOrder.Pair = currencyList[myOrder.BuyCurrencyId] + "/" + currencyList[myOrder.SellCurrencyId]
		}

		myOrders = append(myOrders, myOrder)
	}

	TemplateStr, err := makeTemplate("e_my_orders", "eMyOrders", &eMyOrdersPage{
		Lang:         c.Lang,
		UserId:       c.SessUserId,
		MyOrders:     myOrders,
		CurrencyList: currencyList})
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	return TemplateStr, nil
}