Files
FamilyHUB/backend/src/repositories/receipts.go
T

391 lines
6.8 KiB
Go

package repositories
import (
"context"
"database/sql"
"errors"
"log"
"FamilyHub/src/domain"
)
type ReceiptsRepository interface {
Create(ctx context.Context, receipt *domain.Receipt) (int64, error)
GetByID(ctx context.Context, id int64) (*domain.Receipt, error)
GetAll(ctx context.Context, limit, offset int) ([]*domain.Receipt, error)
Update(ctx context.Context, receipt *domain.Receipt) error
Delete(ctx context.Context, id int64) error
}
type ReceiptsSQLRepository struct {
db *sql.DB
}
func NewReceiptsSQLRepository(db *sql.DB) *ReceiptsSQLRepository {
return &ReceiptsSQLRepository{db: db}
}
func (r *ReceiptsSQLRepository) Create(ctx context.Context, receipt *domain.Receipt) (int64, error) {
log.Printf("%+v\n", receipt)
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return 0, err
}
defer tx.Rollback()
if receipt.ReceiptNumber != receipt.UI {
receipt.ReceiptNumber = receipt.UI
}
log.Println("First query")
query := `
INSERT INTO receipts (
transaction_id,
receipt_number,
ui,
status,
issued_at,
total_amount,
payment_amount,
cash_amount,
another_amount,
clearing_amount,
margin,
currency,
payment_type,
cashbox_number,
cashier,
name_spd,
name_to,
name_np,
type_np,
street_to,
house_to,
kod_soato,
oblast_soato,
rayon_soato,
selsovet_soato,
doc_num,
skno_number,
unp,
success
)
VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9, $10,
$11, $12, $13, $14, $15,
$16, $17, $18, $19, $20,
$21, $22, $23, $24, $25,
$26, $27, $28, $29
)
RETURNING id;
`
args := []any{
receipt.TransactionID,
receipt.ReceiptNumber,
receipt.UI,
receipt.Status,
receipt.IssuedAt,
receipt.TotalAmount,
receipt.PaymentAmount,
receipt.CashAmount,
receipt.AnotherAmount,
receipt.ClearingAmount,
receipt.Margin,
receipt.Currency,
receipt.PaymentType,
receipt.CashboxNumber,
receipt.Cashier,
receipt.NameSPD,
receipt.NameTO,
receipt.NameNP,
receipt.TypeNP,
receipt.StreetTo,
receipt.HouseTo,
receipt.KodSoato,
receipt.OblastSoato,
receipt.RayonSoato,
receipt.SelsovetSoato,
receipt.DocNum,
receipt.SknoNumber,
receipt.UNP,
receipt.Success,
}
log.Printf("SQL: %s", query)
log.Printf("ARGS: %+v", args)
var receiptID int64
err = tx.QueryRowContext(ctx, query, args...).Scan(&receiptID)
if err != nil {
return 0, err
}
log.Println("Second query")
stmt, err := tx.PrepareContext(ctx, `
INSERT INTO positions (
receipt_id,
section_number,
gtin_code,
product_name,
product_count,
amount,
discount,
surcharge,
tag,
marking_code,
ukz_code
)
VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9, $10, $11
)
`)
if err != nil {
return 0, err
}
defer stmt.Close()
for _, p := range receipt.Positions {
_, err = stmt.ExecContext(
ctx,
receiptID,
p.SectionNumber,
p.GTINCode,
p.ProductName,
p.ProductCount,
p.Amount,
p.Discount,
p.Surcharge,
p.Tag,
p.MarkingCode,
p.UKZCode,
)
if err != nil {
return 0, err
}
}
if err = tx.Commit(); err != nil {
return 0, err
}
return receiptID, nil
}
func (r *ReceiptsSQLRepository) GetByID(ctx context.Context, id int64) (*domain.Receipt, error) {
var receipt domain.Receipt
err := r.db.QueryRowContext(ctx, `
SELECT
id,
transaction_id,
receipt_number, ui, status, issued_at,
total_amount, payment_amount, cash_amount,
another_amount, clearing_amount, margin,
currency, payment_type,
cashbox_number, cashier,
name_spd, name_to, name_np, type_np,
street_to, house_to,
kod_soato, oblast_soato, rayon_soato, selsovet_soato,
doc_num, skno_number, unp,
success
FROM receipts
WHERE id = $1
`, id).Scan(
&receipt.ID,
&receipt.TransactionID,
&receipt.ReceiptNumber,
&receipt.UI,
&receipt.Status,
&receipt.IssuedAt,
&receipt.TotalAmount,
&receipt.PaymentAmount,
&receipt.CashAmount,
&receipt.AnotherAmount,
&receipt.ClearingAmount,
&receipt.Margin,
&receipt.Currency,
&receipt.PaymentType,
&receipt.CashboxNumber,
&receipt.Cashier,
&receipt.NameSPD,
&receipt.NameTO,
&receipt.NameNP,
&receipt.TypeNP,
&receipt.StreetTo,
&receipt.HouseTo,
&receipt.KodSoato,
&receipt.OblastSoato,
&receipt.RayonSoato,
&receipt.SelsovetSoato,
&receipt.DocNum,
&receipt.SknoNumber,
&receipt.UNP,
&receipt.Success,
)
if errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, err
}
rows, err := r.db.QueryContext(ctx, `
SELECT
id, receipt_id,
section_number, gtin_code, product_name,
product_count, amount,
discount, surcharge,
tag, marking_code, ukz_code
FROM positions WHERE receipt_id = $1
`, id)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var p domain.Position
if err := rows.Scan(
&p.ID,
&p.ReceiptID,
&p.SectionNumber,
&p.GTINCode,
&p.ProductName,
&p.ProductCount,
&p.Amount,
&p.Discount,
&p.Surcharge,
&p.Tag,
&p.MarkingCode,
&p.UKZCode,
); err != nil {
return nil, err
}
receipt.Positions = append(receipt.Positions, p)
}
return &receipt, nil
}
func (r *ReceiptsSQLRepository) GetAll(ctx context.Context, limit, offset int) ([]*domain.Receipt, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT
id,
transaction_id,
receipt_number,
issued_at,
total_amount,
currency
FROM receipts
ORDER BY issued_at DESC
LIMIT $1 OFFSET $2
`, limit, offset)
if err != nil {
return nil, err
}
defer rows.Close()
var receipts []*domain.Receipt
for rows.Next() {
var rct domain.Receipt
if err := rows.Scan(
&rct.ID,
&rct.TransactionID,
&rct.ReceiptNumber,
&rct.IssuedAt,
&rct.TotalAmount,
&rct.Currency,
); err != nil {
return nil, err
}
receipts = append(receipts, &rct)
}
if err := rows.Err(); err != nil {
return nil, err
}
return receipts, nil
}
func (r *ReceiptsSQLRepository) Update(ctx context.Context, receipt *domain.Receipt) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
_, err = tx.ExecContext(ctx, `
UPDATE receipts SET
transaction_id = $1,
issued_at = $2,
total_amount = $3,
currency = $4
WHERE id = $5
`,
receipt.TransactionID,
receipt.IssuedAt,
receipt.TotalAmount,
receipt.Currency,
receipt.ID,
)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, `DELETE FROM positions WHERE receipt_id = $1`, receipt.ID)
if err != nil {
return err
}
for _, p := range receipt.Positions {
_, err = tx.ExecContext(ctx, `
INSERT INTO positions (
receipt_id, product_name, product_count, amount
) VALUES ($1, $2, $3, $4)
`, receipt.ID, p.ProductName, p.ProductCount, p.Amount)
if err != nil {
return err
}
}
return tx.Commit()
}
func (r *ReceiptsSQLRepository) Delete(ctx context.Context, id int64) error {
_, err := r.db.ExecContext(ctx,
`DELETE FROM receipts WHERE id = $1`,
id,
)
return err
}