farmstar-survey-backend/internal/router/transaction.go

147 lines
4.5 KiB
Go

package router
import (
"fmt"
"log"
"time"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/forms"
"github.com/pocketbase/pocketbase/models"
)
const timezone = "Europe/Moscow"
func (r *RouterContainer) bootstrapTransactionRoute() {
r.PB.OnBeforeServe().Add(func(e *core.ServeEvent) error {
e.Router.POST("/transaction", func(c echo.Context) error {
requestData := struct {
Phone string `json:"phone"`
Tx string `json:"tx" `
TxBuyType string `json:"buy"`
TxSellType string `json:"sell"`
TxBuyDate string `json:"buy_date"`
TxSellDate string `json:"sell_date"`
Feedback string `json:"feedback"`
EvergrowQuantityPurchase string `json:"evergrow_quantity_purchase"`
EvergrowQuantitySale string `json:"evergrow_quantity_sale"`
DistributorName string `json:"distributor_name"`
}{}
if err := c.Bind(&requestData); err != nil {
return apis.NewBadRequestError("Failed to read request data", err)
}
initiatorRecord, err := r.PB.Dao().FindFirstRecordByData("users", "phone", requestData.Phone)
if err != nil {
return apis.NewNotFoundError("Initiator not registered", err)
}
txCollection, err := r.PB.Dao().FindCollectionByNameOrId("transactions")
if err != nil {
return err
}
txRecord := models.NewRecord(txCollection)
txForm := forms.NewRecordUpsert(r.PB, txRecord)
txData := map[string]any{
"initiator": initiatorRecord.Id,
"tx_type": requestData.Tx,
"feedback": requestData.Feedback,
"completed": false,
}
if requestData.Tx == "buy" {
counterpartyRecord, err := r.PB.Dao().FindFirstRecordByData("users", "phone", requestData.TxBuyType)
if err != nil {
return apis.NewNotFoundError("Counterparty not registered", err)
}
if counterpartyRecord.GetString("participant_type") != "distributor" {
return apis.NewNotFoundError("Counterparty is not registered as a distributor", err)
}
distributorRecord, err := r.PB.Dao().FindFirstRecordByData("distributor_base", "user", counterpartyRecord.Id)
if err != nil {
return apis.NewNotFoundError("Counterparty not found in distributors record", err)
}
if distributorRecord.GetString("distributor_name") != requestData.DistributorName {
return apis.NewNotFoundError(fmt.Sprintf("Counterparty is not registered to %s", requestData.DistributorName), err)
}
incorrectDate, err := isFutureDate(requestData.TxBuyDate)
if err != nil {
return apis.NewBadRequestError("Incorrect date format", err)
}
if incorrectDate {
return apis.NewBadRequestError("Date cannot be in the future", err)
}
txData["evergrow_quantity"] = requestData.EvergrowQuantityPurchase
txData["distributor_name"] = requestData.DistributorName
txData["counterparty"] = counterpartyRecord.Id
txData["tx_date"] = requestData.TxBuyDate
}
if requestData.Tx == "sell" {
counterpartyRecord, err := r.PB.Dao().FindFirstRecordByData("users", "phone", requestData.TxSellType)
if err != nil {
return apis.NewNotFoundError("", err)
}
if counterpartyRecord.GetString("participant_type") != "farmer" {
return apis.NewNotFoundError("Counterparty is not registered as a farmer", err)
}
incorrectDate, err := isFutureDate(requestData.TxSellDate)
if err != nil {
return apis.NewBadRequestError("Incorrect date format", err)
}
if incorrectDate {
return apis.NewBadRequestError("Date cannot be in the future", err)
}
txData["evergrow_quantity"] = requestData.EvergrowQuantitySale
txData["counterparty"] = counterpartyRecord.Id
txData["tx_date"] = requestData.TxSellDate
}
txForm.LoadData(txData)
log.Println("pre_submit")
if err := txForm.Submit(); err != nil {
log.Println(err)
return apis.NewBadRequestError("Failed to submit tx details", err)
}
c.JSON(200, map[string]any{"ok": "true"})
return nil
})
return nil
})
}
func isFutureDate(inputDate string) (bool, error) {
parsedDate, err := time.Parse("2006-01-02", inputDate)
if err != nil {
return false, err
}
location, err := time.LoadLocation(timezone)
if err != nil {
return false, err
}
parsedDate = parsedDate.In(location)
currentDate := time.Now().In(location)
fmt.Println(currentDate)
return parsedDate.After(currentDate), nil
}