add get card method
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-05-24 01:10:31 +07:00
parent 4bd82a34a1
commit 8fbeae6fc1
12 changed files with 685 additions and 137 deletions
+30 -77
View File
@@ -2,33 +2,27 @@ package app
import (
"bytes"
"cake_crm/internal/models/messenger"
"cake_crm/internal/models/storage"
"cake_crm/internal/modules/messenger"
"cake_crm/internal/modules/storage"
"cake_crm/internal/services/card"
proto "cake_crm/proto"
"context"
"errors"
"fmt"
"strconv"
)
type orderItem struct {
product *proto.Product
count int64
}
type Server struct {
proto.UnsafeCRMServer
storage storage.IStorage
messenger messenger.IMessenger
storage storage.IStorage
messenger messenger.IMessenger
cardService *card.Service
}
func NewServer(
storage storage.IStorage,
messenger messenger.IMessenger,
) proto.CRMServer {
func NewServer(storage storage.IStorage, messenger messenger.IMessenger, cardService *card.Service) proto.CRMServer {
return &Server{
storage: storage,
messenger: messenger,
storage: storage,
messenger: messenger,
cardService: cardService,
}
}
@@ -65,88 +59,39 @@ func (s *Server) GetBreadcrumbs(ctx context.Context, req *proto.GetBreadcrumbsRe
}
func (s *Server) Order(ctx context.Context, req *proto.OrderReq) (*proto.OrderRsp, error) {
items := make([]*orderItem, 0, len(req.Order.Items))
for _, item := range req.Order.Items {
product, err := s.storage.GetProduct(ctx, item.ProductId)
if err != nil {
return nil, err
}
items = append(
items,
&orderItem{
product: product,
count: item.Count,
},
)
enrichItems, err := s.cardService.GetCard(ctx, req.Order.Items)
if err != nil {
return nil, err
}
text, err := createOrderText(req, items)
text, err := createOrderText(req, enrichItems)
if err != nil {
return nil, err
}
return &proto.OrderRsp{}, s.messenger.SendMessage(text)
}
func createOrderText(req *proto.OrderReq, items []*orderItem) (string, error) {
func createOrderText(req *proto.OrderReq, items []*proto.CardItem) (string, error) {
buffer := bytes.Buffer{}
orderAmount := 0.0
var orderAmount int64
buffer.WriteString(fmt.Sprintf("Заказ от:\n%s\n%s\n", req.Name, req.Phone))
buffer.WriteString("\n")
for _, item := range items {
buffer.WriteString(item.product.Name)
buffer.WriteString(item.Name)
buffer.WriteString("\n")
unit, err := unitToText(item.product.Unit)
unit, err := unitToText(item.Unit)
if err != nil {
return "", err
}
buffer.WriteString(fmt.Sprintf("Количество: %d%s\n", item.count, unit))
amount, err := calcItemAmount(item)
if err != nil {
return "", err
}
orderAmount += amount
buffer.WriteString(fmt.Sprintf("Сумма: %.00fр\n", amount))
buffer.WriteString(fmt.Sprintf("Количество: %d%s\n", item.Count, unit))
orderAmount += item.Amount
buffer.WriteString(fmt.Sprintf("Сумма: %.00fр\n", float64(item.Amount)/100))
buffer.WriteString("\n")
}
buffer.WriteString("\n")
buffer.WriteString(fmt.Sprintf("ИТОГО: %.00fр\n", orderAmount))
buffer.WriteString(fmt.Sprintf("ИТОГО: %.00fр\n", float64(orderAmount)/100))
return buffer.String(), nil
}
func calcItemAmount(item *orderItem) (float64, error) {
var variant *proto.Variant
for _, v := range item.product.Variants {
check := true
for _, property := range v.Properties {
if property.Name == "min" {
minBorder, err := strconv.ParseInt(property.Value, 10, 64)
if err != nil {
return 0, err
}
if item.count < minBorder {
check = false
}
}
if property.Name == "max" {
maxBorder, err := strconv.ParseInt(property.Value, 10, 64)
if err != nil {
return 0, err
}
if item.count > maxBorder {
check = false
}
}
if check {
variant = v
break
}
}
}
if variant == nil {
return 0, errors.New("variant not found")
}
return float64(variant.Price) * float64(item.count) / 100, nil
}
func unitToText(unit string) (string, error) {
switch unit {
case "kg":
@@ -156,3 +101,11 @@ func unitToText(unit string) (string, error) {
}
return "", errors.New("unit not found")
}
func (s *Server) GetCard(ctx context.Context, req *proto.CardReq) (*proto.CardRsp, error) {
enrichItems, err := s.cardService.GetCard(ctx, req.Items)
if err != nil {
return nil, err
}
return &proto.CardRsp{Items: enrichItems}, nil
}
@@ -1,7 +1,7 @@
package telegram
import (
"cake_crm/internal/models/messenger"
"cake_crm/internal/modules/messenger"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
@@ -1,7 +1,7 @@
package storage_file
import (
"cake_crm/internal/models/storage"
"cake_crm/internal/modules/storage"
crm "cake_crm/proto"
"context"
"encoding/json"
+93
View File
@@ -0,0 +1,93 @@
package card
import (
"cake_crm/internal/modules/storage"
"cake_crm/proto"
"context"
"errors"
"strconv"
)
type ProductAndCount struct {
product *proto.Product
count int64
}
type Service struct {
storage storage.IStorage
}
func NewService(storage storage.IStorage) *Service {
return &Service{
storage: storage,
}
}
func (s *Service) GetCard(ctx context.Context, items []*proto.OrderItem) ([]*proto.CardItem, error) {
res := make([]*proto.CardItem, 0, len(items))
for _, item := range items {
product, err := s.storage.GetProduct(ctx, item.ProductId)
if err != nil {
return nil, err
}
amount, err := calcItemAmount(
&ProductAndCount{
product: product,
count: item.Count,
},
)
if err != nil {
return nil, err
}
res = append(
res,
&proto.CardItem{
Id: product.Id,
Article: product.Article,
Name: product.Name,
Uri: product.Uri,
Images: product.Images,
Unit: product.Unit,
Inventory: product.Inventory,
Count: item.Count,
Amount: amount,
},
)
}
return res, nil
}
func calcItemAmount(item *ProductAndCount) (int64, error) {
var variant *proto.Variant
for _, v := range item.product.Variants {
check := true
for _, property := range v.Properties {
if property.Name == "min" {
minBorder, err := strconv.ParseInt(property.Value, 10, 64)
if err != nil {
return 0, err
}
if item.count < minBorder {
check = false
}
}
if property.Name == "max" {
maxBorder, err := strconv.ParseInt(property.Value, 10, 64)
if err != nil {
return 0, err
}
if item.count > maxBorder {
check = false
}
}
if check {
variant = v
break
}
}
}
if variant == nil {
return 0, errors.New("variant not found")
}
return variant.Price * item.count, nil
}