391 lines
6.8 KiB
Go
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
|
|
}
|