Init commit

This commit is contained in:
2026-01-27 15:31:58 +03:00
commit e6dc59c266
37 changed files with 1707 additions and 0 deletions
@@ -0,0 +1,151 @@
package receiptService
import (
"GoFinanceManager/src/domain/models"
"GoFinanceManager/src/repositories"
"GoFinanceManager/src/utils"
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"log"
"mime/multipart"
"net/http"
"time"
)
type ReceiptService struct {
client *http.Client
repo repositories.ReceiptRepository
}
func NewReceiptService(repo repositories.ReceiptRepository) *ReceiptService {
return &ReceiptService{
client: &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
},
repo: repo,
}
}
func (s *ReceiptService) GetReceipt(
ctx context.Context,
date string,
number string,
) (*models.Receipt, error) {
url := "https://ch.info-center.by/ajax/check1.php"
var receipt models.Receipt
body, contentType := buildMultipartBody(date, number)
req, err := http.NewRequestWithContext(
ctx,
http.MethodPost,
url,
body,
)
if err != nil {
log.Println(err.Error())
return nil, err
}
req.Header.Set("Content-Type", contentType)
resp, err := s.client.Do(req)
if err != nil {
log.Println(err.Error())
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Printf("external service returned %d\n", resp.StatusCode)
return nil, fmt.Errorf("external service returned %d", resp.StatusCode)
}
var raw struct {
Message map[string]interface{} `json:"message"`
}
log.Println(raw.Message)
if err := json.NewDecoder(resp.Body).Decode(&raw); err != nil {
log.Printf("external service returned %s\n", err.Error())
return nil, err
}
raw.Message["receipt_number"] = number
bytes_, _ := json.Marshal(raw.Message)
if err := json.Unmarshal(bytes_, &receipt); err != nil {
return nil, err
}
log.Println(receipt)
positions, err := parsePositions(receipt.PositionsRaw)
if err != nil {
log.Printf("failed to parse positions: %s", err.Error())
return nil, err
}
log.Println(receipt.IssuedAtRaw)
receipt.IssuedAt, err = utils.ParseIssuedAt(receipt.IssuedAtRaw)
if err != nil {
log.Printf("failed to parse issued at: %s", err.Error())
return nil, err
}
receipt.Positions = positions
for i := range receipt.Positions {
p := &receipt.Positions[i]
p.ProductCount, err = utils.ParseFloat(p.ProductCountRaw)
if err != nil {
log.Printf("failed to parse product count: %s", err.Error())
return nil, err
}
p.Amount, err = utils.ParseFloat(p.AmountRaw)
if err != nil {
log.Printf("failed to parse amount: %s", err.Error())
return nil, err
}
p.Discount, _ = utils.ParseFloat(p.DiscountRaw)
p.Surcharge, _ = utils.ParseFloat(p.SurchargeRaw)
}
if _, err := s.repo.Create(ctx, &receipt); err != nil {
return nil, err
}
return &receipt, nil
}
func buildMultipartBody(date, number string) (*bytes.Buffer, string) {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
_ = writer.WriteField("orig_date", date)
_ = writer.WriteField("orig_ui", number)
_ = writer.Close()
return body, writer.FormDataContentType()
}
func parsePositions(raw string) ([]models.Position, error) {
var positions []models.Position
if raw == "" {
return positions, nil
}
if err := json.Unmarshal([]byte(raw), &positions); err != nil {
return nil, err
}
return positions, nil
}