fix make order

hotfix/hotfix-mysql-error
Ernest Litvinenko 2024-03-28 21:02:18 +03:00
parent 54b7fedcdb
commit 802b70a601
9 changed files with 214 additions and 201 deletions

View File

@ -3,11 +3,11 @@ package AgentType
type AgentType string type AgentType string
const ( const (
BANKING_PAYMENT_AGENT = "banking_payment_agent" // Банковский платежный агент BANKING_PAYMENT_AGENT AgentType = "banking_payment_agent" // Банковский платежный агент
BANKING_PAYMENT_SUBAGENT = "banking_payment_subagent" // Банковский платежный субагент BANKING_PAYMENT_SUBAGENT AgentType = "banking_payment_subagent" // Банковский платежный субагент
PAYMENT_AGENT = "payment_agent" // Платежный агент PAYMENT_AGENT AgentType = "payment_agent" // Платежный агент
PAYMENT_SUBAGENT = "payment_subagent" // Платежный субагент PAYMENT_SUBAGENT AgentType = "payment_subagent" // Платежный субагент
ATTORNEY = "attorney" // Поверенный ATTORNEY AgentType = "attorney" // Поверенный
COMMISSIONER = "commissioner" // Комиссионер COMMISSIONER AgentType = "commissioner" // Комиссионер
AGENT = "agent" // Агент AGENT AgentType = "agent" // Агент
) )

View File

@ -3,28 +3,28 @@ package Measure
type Measure string type Measure string
const ( const (
PIECE = "piece" // Штука, единица товара PIECE Measure = "piece" // Штука, единица товара
GRAM = "gram" // Грамм GRAM Measure = "gram" // Грамм
KILOGRAM = "kilogram" // Килограмм KILOGRAM Measure = "kilogram" // Килограмм
TON = "ton" // Тонна TON Measure = "ton" // Тонна
CENTIMETER = "centimeter" // Сантиметр CENTIMETER Measure = "centimeter" // Сантиметр
DECIMETER = "decimeter" // Дециметр DECIMETER Measure = "decimeter" // Дециметр
METER = "meter" // Метр METER Measure = "meter" // Метр
SQUARE_CENTIMETER = "square_centimeter" // Квадратный сантиметр SQUARE_CENTIMETER Measure = "square_centimeter" // Квадратный сантиметр
SQUARE_DECIMETER = "square_decimeter" // Квадратный дециметр SQUARE_DECIMETER Measure = "square_decimeter" // Квадратный дециметр
SQUARE_METER = "square_meter" // Квадратный метр SQUARE_METER Measure = "square_meter" // Квадратный метр
MILLILITER = "milliliter" // Миллилитр MILLILITER Measure = "milliliter" // Миллилитр
LITER = "liter" // Литр LITER Measure = "liter" // Литр
CUBIC_METER = "cubic_meter" // Кубический метр CUBIC_METER Measure = "cubic_meter" // Кубический метр
KILOWATT_HOUR = "kilowatt_hour" // Килловат-час KILOWATT_HOUR Measure = "kilowatt_hour" // Килловат-час
GIGACALORIE = "gigacalorie" // Гигакалория GIGACALORIE Measure = "gigacalorie" // Гигакалория
DAY = "day" // Сутки DAY Measure = "day" // Сутки
HOUR = "hour" // Час HOUR Measure = "hour" // Час
MINUTE = "minute" // Минута MINUTE Measure = "minute" // Минута
SECOND = "second" // Секунда SECOND Measure = "second" // Секунда
KILOBYTE = "kilobyte" // Килобайт KILOBYTE Measure = "kilobyte" // Килобайт
MEGABYTE = "megabyte" // Мегабайт MEGABYTE Measure = "megabyte" // Мегабайт
GIGABYTE = "gigabyte" // Гигабайт GIGABYTE Measure = "gigabyte" // Гигабайт
TERABYTE = "terabyte" // Терабайт TERABYTE Measure = "terabyte" // Терабайт
ANOTHER = "another" // Другое ANOTHER Measure = "another" // Другое
) )

View File

@ -3,11 +3,11 @@ package PaymentMode
type PaymentMode string type PaymentMode string
const ( const (
FULL_PREPAYMENT = "full_prepayment" // Полная предоплата FULL_PREPAYMENT PaymentMode = "full_prepayment" // Полная предоплата
PARTIAL_PREPAYMENT = "partial_prepayment" // Частичная предоплата PARTIAL_PREPAYMENT PaymentMode = "partial_prepayment" // Частичная предоплата
ADVANCE = "advance" // Аванс ADVANCE PaymentMode = "advance" // Аванс
FULL_PAYMENT = "full_payment" // Полный расчет FULL_PAYMENT PaymentMode = "full_payment" // Полный расчет
PARTIAL_PAYMENT = "partial_payment" // Частичный расчет и кредит PARTIAL_PAYMENT PaymentMode = "partial_payment" // Частичный расчет и кредит
CREDIT = "credit" // Кредит CREDIT PaymentMode = "credit" // Кредит
CREDIT_PAYMENT = "credit_payment" // Выплата по кредиту CREDIT_PAYMENT PaymentMode = "credit_payment" // Выплата по кредиту
) )

View File

@ -3,23 +3,23 @@ package PaymentSubject
type PaymentSubject string type PaymentSubject string
const ( const (
COMMODITY = "commodity" //Товар Товар COMMODITY PaymentSubject = "commodity" //Товар Товар
EXCISE = "excise" //Подакцизный товар EXCISE PaymentSubject = "excise" //Подакцизный товар
JOB = "job" //Работа JOB PaymentSubject = "job" //Работа
SERVICE = "service" //Услуга Услуга SERVICE PaymentSubject = "service" //Услуга Услуга
PAYMENT = "payment" //Платеж Платеж PAYMENT PaymentSubject = "payment" //Платеж Платеж
CASINO = "casino" // Платеж казино CASINO PaymentSubject = "casino" // Платеж казино
GAMBLING_BET = "gambling_bet" //Ставка в азартной игре GAMBLING_BET PaymentSubject = "gambling_bet" //Ставка в азартной игре
GAMBLING_PRIZE = "gambling_prize" // Выигрыш азартной игры GAMBLING_PRIZE PaymentSubject = "gambling_prize" // Выигрыш азартной игры
LOTTERY = "lottery" // Лотерейный билет LOTTERY PaymentSubject = "lottery" // Лотерейный билет
LOTTERY_PRIZE = "lottery_prize" // Выигрыш в лотерею LOTTERY_PRIZE PaymentSubject = "lottery_prize" // Выигрыш в лотерею
INTELLECTUAL_ACTIVITY = "intellectual_activity" //Результаты интеллектуальной деятельности INTELLECTUAL_ACTIVITY PaymentSubject = "intellectual_activity" //Результаты интеллектуальной деятельности
AGENT_COMMISSION = "agent_commission" //Агентское вознаграждение AGENT_COMMISSION PaymentSubject = "agent_commission" //Агентское вознаграждение
PROPERTY_RIGHT = "property_right" //Имущественное право PROPERTY_RIGHT PaymentSubject = "property_right" //Имущественное право
NON_OPERATING_GAIN = "non_operating_gain" //Внереализационный доход NON_OPERATING_GAIN PaymentSubject = "non_operating_gain" //Внереализационный доход
INSURANCE_PREMIUM = "insurance_premium" //Страховой сбор INSURANCE_PREMIUM PaymentSubject = "insurance_premium" //Страховой сбор
SALES_TAX = "sales_tax" //Торговый сбор SALES_TAX PaymentSubject = "sales_tax" //Торговый сбор
RESORT_FEE = "resort_fee" // Курортный сбор RESORT_FEE PaymentSubject = "resort_fee" // Курортный сбор
COMPOSITE = "composite" // Несколько вариантов COMPOSITE PaymentSubject = "composite" // Несколько вариантов
ANOTHER = "another" // Другое ANOTHER PaymentSubject = "another" // Другое
) )

View File

@ -3,8 +3,8 @@ package Settlements
type Settlements string type Settlements string
const ( const (
CASHLESS = "cashless" // Безналичный расчет CASHLESS Settlements = "cashless" // Безналичный расчет
PREPAYMENT = "prepayment" // Предоплата (аванс) PREPAYMENT Settlements = "prepayment" // Предоплата (аванс)
POSTPAYMENT = "postpayment" // Постоплата (кредит) POSTPAYMENT Settlements = "postpayment" // Постоплата (кредит)
CONSIDERATION = "consideration" // Встречное предоставление CONSIDERATION Settlements = "consideration" // Встречное предоставление
) )

View File

@ -3,7 +3,7 @@ package TaxSystemCode
type TaxSystemCode int type TaxSystemCode int
const ( const (
GENERAL = iota + 1 GENERAL TaxSystemCode = iota + 1
USN_INCOME USN_INCOME
USN_INCOME_MINUS_EXPENCES USN_INCOME_MINUS_EXPENCES
ENVD ENVD

View File

@ -80,7 +80,7 @@ func basicAuth(username, password string) string {
return base64.StdEncoding.EncodeToString([]byte(auth)) return base64.StdEncoding.EncodeToString([]byte(auth))
} }
func CreatePayment(orderId int, sum float64, fullName string, email string, phone string, items []KassaReceiptItems) (map[string]interface{}, error) { func CreatePayment(orderId int, sum float64, fullName string, email string, phone string, items []KassaReceiptItems) (*KassaResult, error) {
req := KassaPaymentReq{ req := KassaPaymentReq{
Amount: KassaAmount{Value: fmt.Sprintf("%f", sum), Currency: "RUB"}, Amount: KassaAmount{Value: fmt.Sprintf("%f", sum), Currency: "RUB"},
Description: fmt.Sprintf("Заказ №%d", orderId), Description: fmt.Sprintf("Заказ №%d", orderId),
@ -111,7 +111,7 @@ func CreatePayment(orderId int, sum float64, fullName string, email string, phon
response, err := client.Do(request) response, err := client.Do(request)
result := map[string]interface{}{} result := new(KassaResult)
json.NewDecoder(response.Body).Decode(&result) json.NewDecoder(response.Body).Decode(&result)
if err != nil { if err != nil {

View File

@ -3,7 +3,9 @@ package endpoints
import ( import (
"context" "context"
"fmt" "fmt"
"net/http"
"relynolli-server/models" "relynolli-server/models"
"relynolli-server/services"
"relynolli-server/status" "relynolli-server/status"
"relynolli-server/storage" "relynolli-server/storage"
"time" "time"
@ -58,31 +60,51 @@ func (h handlers) GetTotal(c *gin.Context) {
} }
func (h handlers) MakeOrder(c *gin.Context) { func (h handlers) MakeOrder(c *gin.Context) {
ctx := context.Background()
// VALIDATION // VALIDATION
validate := validator.New(validator.WithRequiredStructEnabled()) validate := validator.New(validator.WithRequiredStructEnabled())
req := makeOrderRequest{} req := makeOrderRequest{}
err := c.ShouldBindJSON(&req) err := c.ShouldBindJSON(&req)
meta := models.Meta{
RequestStarted: time.Now().Unix(),
}
resp := models.Response{
Status: status.STATUS_OK,
Meta: &meta,
}
if err != nil { if err != nil {
//c.JSON(400, models.Response{Status: http.StatusBadRequest, Info: fmt.Sprintf("ERROR: %s", err.Error())}) meta.RequestFinished = time.Now().Unix()
resp.Info = fmt.Sprintf("ERROR: %s", err.Error())
resp.Status = status.STATUS_BAD_REQUEST
c.JSON(400, resp)
return return
} }
validationErr := validate.Struct(req) validationErr := validate.Struct(req)
if validationErr != nil { if validationErr != nil {
//responseErr := validationErr.(validator.ValidationErrors)[0] responseErr := validationErr.(validator.ValidationErrors)[0]
//c.JSON(http.StatusBadRequest, models.Response{Status: http.StatusBadRequest, Info: fmt.Sprintf("Validation Error: Field %s should be %s", responseErr.Field(), responseErr.Tag())}) meta.RequestFinished = time.Now().Unix()
resp.Info = fmt.Sprintf("Error: %s", responseErr.Error())
resp.Status = status.STATUS_BAD_REQUEST
c.JSON(http.StatusBadRequest, resp)
return return
} }
//kassaResult, serviceErr := services.MakeOrder(req.FuserId, req.Email, req.FullName, req.PhoneNumber) kassaResult, serviceErr := services.MakeOrder(ctx, req.FuserId, req.Email, req.FullName, req.PhoneNumber)
//if serviceErr != nil { if serviceErr != nil {
// c.JSON(http.StatusInternalServerError, models.Response{Status: http.StatusInternalServerError, Info: fmt.Sprintf("Error: %s", serviceErr.Error())}) meta.RequestFinished = time.Now().Unix()
// return resp.Info = fmt.Sprintf("Error: %s", serviceErr.Error())
//} resp.Status = status.STATUS_SERVER_ERROR
c.JSON(http.StatusInternalServerError, resp)
return
}
//c.JSON(http.StatusOK, kassaResult) resp.Data = kassaResult
meta.RequestFinished = time.Now().Unix()
c.JSON(http.StatusOK, resp)
} }
type Handlers interface { type Handlers interface {

View File

@ -1,131 +1,122 @@
package services package services
//func GetTotal(fuserId int) float64 { import (
// rdb := internal.InitRedis() "context"
// keys, _ := rdb.Keys(context.Background(), fmt.Sprintf("api.api_cart.%d.*", fuserId)).Result() "fmt"
// "relynolli-server/external/bitrix"
// result := []models.CatalogWithQuantityWeb{} "relynolli-server/external/kassa"
// "relynolli-server/external/kassa/Measure"
// for _, key := range keys { "relynolli-server/external/kassa/PaymentMode"
// str, _ := rdb.Get(context.Background(), key).Result() "relynolli-server/external/kassa/PaymentSubject"
// item := models.CatalogWithQuantityWeb{} "relynolli-server/external/kassa/VatCodes"
// "relynolli-server/internal"
// json.Unmarshal([]byte(str), &item) "relynolli-server/storage"
// result = append(result, item) "strconv"
// } "strings"
// )
// sum := float64(0)
// func addProductsToOrder(ctx context.Context, storage storage.StorageCart, api bitrix.Bitrix, fuserId, orderId int) error {
// for _, catalogItem := range result {
// sum = sum + catalogItem.Price["BASE"].(float64)*float64(catalogItem.Quantity)
// }
//
// return sum
//}
//
//type addProductsToOrderReq struct {
// ProductId int `db:"product_id"`
// PriceTypeId int `db:"price_type_id"`
// Quantity int `db:"quantity"`
// Price float64 `db:"price"`
//}
//
//func addProductsToOrder(api bitrix.Bitrix, fuserId int, orderId int) error {
// //Получаем данные из корзины // //Получаем данные из корзины
// //
// cartItems := GetCartItems(fuserId) items, err := storage.GetCartItems(ctx, int64(fuserId))
if err != nil {
return err
}
for _, product := range *items {
err = api.AddProductToOrder(orderId, int(product.ProductId), product.Product.Price.BASE, int(product.Quantity))
if err != nil {
return err
}
}
return nil
}
// //
// rdb := internal.InitRedis()
// rdb.Keys(context.Background(), "") func MakeOrder(ctx context.Context, fuserId int, email string, fullName string, phone string) (*kassa.KassaResult, error) {
// //
// for _, product := range cartItems { // Инициализируем api
// err := api.AddProductToOrder(orderId, product.Id, product.Price["BASE"].(float64), product.Quantity) s := storage.NewStorageCart()
// if err != nil {
// return err api := bitrix.Initialize()
// }
// } // 1. Создаем анонимного пользователя
// return nil
// userId, _ := api.CreateAnonymousUser()
//}
// // 2. Создаем заказ
//func MakeOrder(fuserId int, email string, fullName string, phone string) (map[string]interface{}, error) { orderId, _ := api.CreateOrder(userId)
//
// // Инициализируем api // --- обновляем контакт пользователя
// order, orderErr := api.GetOrderInfo(orderId)
// api := bitrix.Initialize()
// if orderErr != nil {
// // 1. Создаем анонимного пользователя return nil, orderErr
// }
// userId, _ := api.CreateAnonymousUser()
// clientId, _ := strconv.Atoi(order.Clients[0].EntityId)
// // 2. Создаем заказ err := api.UpdateContact(clientId, email, fullName, phone)
// orderId, _ := api.CreateOrder(userId) if err != nil {
// return nil, err
// // --- обновляем контакт пользователя }
// order, orderErr := api.GetOrderInfo(orderId)
// if orderErr != nil { // 3. Добавляем элементы в корзину
// return nil, orderErr addProductErr := addProductsToOrder(ctx, s, api, fuserId, orderId)
// } if addProductErr != nil {
// clientId, _ := strconv.Atoi(order.Clients[0].EntityId) return nil, addProductErr
// api.UpdateContact(clientId, email, fullName, phone) }
//
// // 3. Добавляем элементы в корзину // 4. Получаем обновленный ресурс заказа
// addProductErr := addProductsToOrder(api, fuserId, orderId) order, _ = api.GetOrderInfo(orderId)
// if addProductErr != nil {
// return nil, addProductErr // 5. Добавляем способ оплаты товара
// } createPaymentError := api.CreatePayment(orderId, order.Price)
//
// // 4. Получаем обновленный ресурс заказа if createPaymentError != nil {
// order, _ = api.GetOrderInfo(orderId) return nil, createPaymentError
// }
// // 5. Добавляем способ оплаты товара
// createPaymentError := api.CreatePayment(orderId, order.Price) // 6. Получаем ресурс оплаты и url для нее
// paymentData, _ := kassa.CreatePayment(orderId, order.Price, fullName, email, phone, getItemsForPayment(order))
// if createPaymentError != nil {
// return nil, createPaymentError db := internal.InitDatabase().GetInstance()
// }
// db.NewRaw(`
// // 6. Получаем ресурс оплаты и url для нее insert into api_youkassa_payment (payment_id, order_id, link, status)
// paymentData, _ := kassa.CreatePayment(orderId, order.Price, fullName, email, phone, getItemsForPayment(order)) values (?, ?, ?,? );`,
// paymentData.Id,
// insPaymentDataStmt := fmt.Sprintf(` orderId,
// insert into api_youkassa_payment (payment_id, order_id, link, status) paymentData.Confirmation.ConfirmationUrl,
// values ('%s', paymentData.Status).Exec(ctx)
// '%s',
// '%s', if err != nil {
// '%s'); return nil, err
// `, paymentData["id"].(string), }
// orderId,
// paymentData["confirmation"].(map[string]interface{})["confirmation_url"].(string), return paymentData, nil
// paymentData["status"].(string), }
// )
// func getItemsForPayment(order *bitrix.OrderResource) []kassa.KassaReceiptItems {
// db := internal.InitDatabase() result := []kassa.KassaReceiptItems{}
//
// db.Execute(insPaymentDataStmt) for _, basketItem := range order.BasketItems {
// quantity, _ := strconv.Atoi(strings.Split(basketItem.Quantity, ".")[0])
// return paymentData, nil item := kassa.KassaReceiptItems{
//} Description: basketItem.Name,
// Amount: kassa.KassaAmount{
//func getItemsForPayment(order *bitrix.OrderResource) []kassa.KassaReceiptItems { Value: fmt.Sprintf("%f", basketItem.Price),
// result := []kassa.KassaReceiptItems{} Currency: "RUB",
// },
// for _, basketItem := range order.BasketItems { VatCode: VatCodes.NDS_20,
// quantity, _ := strconv.Atoi(strings.Split(basketItem.Quantity, ".")[0]) Quantity: fmt.Sprintf("%d", quantity),
// item := kassa.KassaReceiptItems{ Measure: Measure.PIECE,
// Description: basketItem.Name, PaymentSubject: PaymentSubject.COMMODITY,
// Amount: kassa.KassaAmount{ PaymentMode: PaymentMode.FULL_PAYMENT,
// Value: fmt.Sprintf("%f", basketItem.Price), }
// Currency: "RUB", result = append(result, item)
// }, }
// VatCode: VatCodes.NDS_20,
// Quantity: fmt.Sprintf("%d", quantity), return result
// Measure: Measure.PIECE, }
// PaymentSubject: PaymentSubject.COMMODITY,
// PaymentMode: PaymentMode.FULL_PAYMENT,
// }
// result = append(result, item)
// }
//
// return result
//}