relynolli-server/external/bitrix/api.go

368 lines
13 KiB
Go

package bitrix
import (
"bytes"
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
"github.com/sirupsen/logrus"
"net/http"
"os"
"strings"
"time"
)
var EP = os.Getenv("BITRIX_API_EP")
type ClientsResource struct {
EntityId string `json:"entityId"`
}
type OrderResource struct {
ID string `json:"id,omitempty"`
Clients []ClientsResource `json:"clients"`
Lid string `json:"lid,omitempty"`
DateInsert time.Time `json:"dateInsert,omitempty"`
DateUpdate time.Time `json:"dateUpdate,omitempty"`
PersonTypeID string `json:"personTypeId,omitempty"`
StatusID string `json:"statusId,omitempty"`
DateStatus time.Time `json:"dateStatus,omitempty"`
EmpStatusID any `json:"empStatusId,omitempty"`
Marked string `json:"marked,omitempty"`
DateMarked any `json:"dateMarked,omitempty"`
EmpMarkedID any `json:"empMarkedId,omitempty"`
ReasonMarked any `json:"reasonMarked,omitempty"`
Price float64 `json:"price,omitempty"`
DiscountValue string `json:"discountValue,omitempty"`
TaxValue string `json:"taxValue,omitempty"`
UserDescription string `json:"userDescription,omitempty"`
AdditionalInfo any `json:"additionalInfo,omitempty"`
Comments string `json:"comments,omitempty"`
CompanyID string `json:"companyId,omitempty"`
ResponsibleID any `json:"responsibleId,omitempty"`
StatGid any `json:"statGid,omitempty"`
DatePayBefore any `json:"datePayBefore,omitempty"`
DateBill any `json:"dateBill,omitempty"`
RecurringID any `json:"recurringId,omitempty"`
LockedBy string `json:"lockedBy,omitempty"`
DateLock time.Time `json:"dateLock,omitempty"`
RecountFlag string `json:"recountFlag,omitempty"`
AffiliateID any `json:"affiliateId,omitempty"`
DeliveryDocNum any `json:"deliveryDocNum,omitempty"`
DeliveryDocDate any `json:"deliveryDocDate,omitempty"`
Updated1C string `json:"updated1c,omitempty"`
OrderTopic any `json:"orderTopic,omitempty"`
XMLID any `json:"xmlId,omitempty"`
ID1C any `json:"id1c,omitempty"`
Version1C any `json:"version1c,omitempty"`
Version string `json:"version,omitempty"`
ExternalOrder string `json:"externalOrder,omitempty"`
StoreID any `json:"storeId,omitempty"`
Canceled string `json:"canceled,omitempty"`
EmpCanceledID any `json:"empCanceledId,omitempty"`
DateCanceled any `json:"dateCanceled,omitempty"`
ReasonCanceled any `json:"reasonCanceled,omitempty"`
BasketItems []BasketResource `json:"basketItems,omitempty"`
Properties []propertyValueResource `json:"properties,omitempty"`
Payments []PaymentResource `json:"payments,omitempty"`
Shipments []any `json:"shipments,omitempty"`
}
type propertyValueResource struct {
Id string `json:"id"`
Name string `json:"name"`
Value []string `json:"value"`
Code string `json:"code"`
OrderPropsId string `json:"orderPropsId"`
}
type PaymentResource struct {
Id string `json:"id"`
OrderId string `json:"orderId"`
Paid string `json:"paid"`
DatePaid interface{} `json:"datePaid"`
EmpPaidId interface{} `json:"empPaidId"`
PaySystemId string `json:"paySystemId"`
PsStatus interface{} `json:"psStatus"`
PsStatusCode interface{} `json:"psStatusCode"`
PsInvoiceId interface{} `json:"psInvoiceId"`
PsStatusDescription interface{} `json:"psStatusDescription"`
PsStatusMessage interface{} `json:"psStatusMessage"`
PsSum interface{} `json:"psSum"`
PsCurrency interface{} `json:"psCurrency"`
PsResponseDate interface{} `json:"psResponseDate"`
PayVoucherNum string `json:"payVoucherNum"`
PayVoucherDate interface{} `json:"payVoucherDate"`
DatePayBefore interface{} `json:"datePayBefore"`
DateBill time.Time `json:"dateBill"`
XmlId interface{} `json:"xmlId"`
Sum string `json:"sum"`
PriceCod string `json:"priceCod"`
Currency string `json:"currency"`
PaySystemName string `json:"paySystemName"`
ResponsibleId interface{} `json:"responsibleId"`
EmpResponsibleId interface{} `json:"empResponsibleId"`
DateResponsibleId interface{} `json:"dateResponsibleId"`
Comments interface{} `json:"comments"`
CompanyId string `json:"companyId"`
PayReturnNum string `json:"payReturnNum"`
PayReturnDate interface{} `json:"payReturnDate"`
EmpReturnId interface{} `json:"empReturnId"`
PayReturnComment string `json:"payReturnComment"`
IsReturn string `json:"isReturn"`
Marked string `json:"marked"`
DateMarked interface{} `json:"dateMarked"`
EmpMarkedId interface{} `json:"empMarkedId"`
ReasonMarked interface{} `json:"reasonMarked"`
Updated1C string `json:"updated1c"`
Id1C interface{} `json:"id1c"`
Version1C interface{} `json:"version1c"`
ExternalPayment string `json:"externalPayment"`
}
type BasketResource struct {
Module string `json:"module"`
ProductId string `json:"productId"`
Id string `json:"id"`
Lid string `json:"lid"`
Quantity string `json:"quantity"`
Weight string `json:"weight"`
Price float64 `json:"price"`
CustomPrice string `json:"customPrice"`
BasePrice string `json:"basePrice"`
ProductPriceId string `json:"productPriceId"`
PriceTypeId string `json:"priceTypeId"`
Currency string `json:"currency"`
BarcodeMulti string `json:"barcodeMulti"`
Name string `json:"name"`
CatalogXmlId string `json:"catalogXmlId"`
VatRate string `json:"vatRate"`
Notes string `json:"notes"`
DiscountPrice string `json:"discountPrice"`
ProductProviderClass string `json:"productProviderClass"`
Dimensions string `json:"dimensions"`
Type interface{} `json:"type"`
SetParentId interface{} `json:"setParentId"`
DetailPageUrl string `json:"detailPageUrl"`
MeasureCode string `json:"measureCode"`
MeasureName string `json:"measureName"`
OrderId string `json:"orderId"`
ProductXmlId string `json:"productXmlId"`
Subscribe string `json:"subscribe"`
Recommendation interface{} `json:"recommendation"`
VatIncluded string `json:"vatIncluded"`
Sort string `json:"sort"`
DiscountName interface{} `json:"discountName"`
DiscountValue interface{} `json:"discountValue"`
DiscountCoupon interface{} `json:"discountCoupon"`
Properties []struct {
Id string `json:"id"`
BasketId string `json:"basketId"`
Name string `json:"name"`
Value string `json:"value"`
Code string `json:"code"`
Sort string `json:"sort"`
} `json:"properties"`
}
type bitrix struct{}
type Bitrix interface {
CreateAnonymousUser() (int, error)
CreateOrder(userId int) (int, error)
ApprovePayment(paymentId int, paySystemId int) error
CancelOrder(orderId int) error
GetOrderInfo(orderId int) (*OrderResource, error)
CreatePayment(orderId int, sum float64) error
AddProductToOrder(orderId int, productId int, price float64, quantity int) error
UpdateContact(contactId int, email string, name string, phone string) error
}
type createAnonymousUserRequest struct {
Email string `json:"EMAIL"`
Name string `json:"NAME"`
Password string `json:"PASSWORD"`
ConfirmPassword string `json:"CONFIRM_PASSWORD"`
UFDepartment []int `json:"UF_DEPARTMENT"`
}
type createAnonymousUserResponse struct {
Result int `json:"result"`
}
func (_ bitrix) CreateAnonymousUser() (int, error) {
uid, _ := uuid.NewUUID()
req := createAnonymousUserRequest{
Email: fmt.Sprintf("anonymous%s@anonym.ru", uid.String()),
Name: "Анонимный пользователь",
Password: uid.String(),
ConfirmPassword: uid.String(),
UFDepartment: []int{0},
}
query, _ := json.Marshal(req)
resp, err := http.Post(EP+"/user.add", "application/json", bytes.NewBuffer(query))
result := createAnonymousUserResponse{}
err = json.NewDecoder(resp.Body).Decode(&result)
return result.Result, err
}
type createOrderRequestWrapper struct {
Fields createOrderRequest `json:"fields"`
}
type createOrderRequest struct {
Lid string `json:"lid"`
PersonTypeId int `json:"personTypeId"`
Currency string `json:"currency"`
UserId int `json:"userId"`
}
type createOrderResponse struct {
Result struct {
Order struct {
Id int `json:"id"`
} `json:"order"`
} `json:"result"`
}
func (_ bitrix) CreateOrder(userId int) (int, error) {
req := createOrderRequestWrapper{createOrderRequest{
Lid: "s2",
PersonTypeId: 5,
Currency: "RUB",
UserId: userId,
}}
query, _ := json.Marshal(req)
resp, _ := http.Post(EP+"/sale.order.add", "application/json", bytes.NewBuffer(query))
result := createOrderResponse{}
err := json.NewDecoder(resp.Body).Decode(&result)
return result.Result.Order.Id, err
}
func (_ bitrix) ApprovePayment(paymentId int, paySystemId int) error {
req := map[string]interface{}{
"id": paymentId,
"fields": map[string]interface{}{"paid": "Y", "paySystemId": paySystemId},
}
query, _ := json.Marshal(req)
_, err := http.Post(EP+"/sale.payment.update", "application/json", bytes.NewBuffer(query))
return err
}
func (_ bitrix) CancelOrder(orderId int) error {
req := map[string]interface{}{
"id": orderId,
"fields": map[string]interface{}{"canceled": "Y"},
}
query, _ := json.Marshal(req)
_, err := http.Post(EP+"/sale.order.update", "application/json", bytes.NewBuffer(query))
return err
}
func (_ bitrix) GetOrderInfo(orderId int) (*OrderResource, error) {
req := map[string]interface{}{
"id": orderId,
}
query, _ := json.Marshal(req)
response, err := http.Post(EP+"/sale.order.get", "application/json", bytes.NewBuffer(query))
result := struct {
Result struct {
Order map[string]interface{} `json:"order"`
} `json:"result"`
}{}
err = json.NewDecoder(response.Body).Decode(&result)
if err != nil {
logrus.Errorf("Error: %s", err.Error())
}
resultParsed := OrderResource{}
mapstructure.Decode(result.Result.Order, &resultParsed)
return &resultParsed, err
}
func (_ bitrix) CreatePayment(orderId int, sum float64) error {
req := map[string]interface{}{
"fields": map[string]interface{}{
"orderId": orderId,
"sum": sum,
"paid": "N",
"paySystemId": 8,
},
}
query, _ := json.Marshal(req)
_, err := http.Post(EP+"/sale.payment.add", "application/json", bytes.NewBuffer(query))
return err
}
func (_ bitrix) AddProductToOrder(orderId int, productId int, price float64, quantity int) error {
req := map[string]interface{}{
"fields": map[string]interface{}{
"orderId": orderId,
"productId": productId,
"quantity": quantity,
"currency": "RUB",
"price": price,
},
}
query, _ := json.Marshal(req)
_, err := http.Post(EP+"/sale.basketitem.addCatalogProduct", "application/json", bytes.NewBuffer(query))
return err
}
func (_ bitrix) UpdateContact(contactId int, email string, name string, phone string) error {
req := map[string]interface{}{
"id": contactId,
"fields": map[string]interface{}{
"EMAIL": append([]map[string]interface{}{}, map[string]interface{}{
"VALUE_TYPE": "other",
"VALUE": email,
"TYPE_ID": "EMAIL",
}),
"NAME": strings.Split(name, " ")[1],
"LAST_NAME": strings.Split(name, " ")[0],
"SECOND_NAME": strings.Split(name, " ")[2],
"PHONE": append([]map[string]interface{}{}, map[string]interface{}{
"VALUE_TYPE": "other",
"VALUE": phone,
"TYPE_ID": "PHONE",
}),
},
}
query, _ := json.Marshal(req)
_, err := http.Post(EP+"/crm.contact.update", "application/json", bytes.NewBuffer(query))
return err
}
func Initialize() Bitrix {
return &bitrix{}
}