87 lines
2.5 KiB
Go
Raw Normal View History

package repository
import (
"context"
"database/sql"
"fmt"
"github.com/muyuqingfeng/iloom/purchaser-service/internal/model"
)
type APRepo struct {
db *sql.DB
}
func NewAPRepo(db *sql.DB) *APRepo {
return &APRepo{db: db}
}
func (r *APRepo) List(ctx context.Context, companyID string) ([]model.AccountsPayable, error) {
query := `SELECT ap.id, ap.plan_id, ap.purchaser_id, ap.textile_factory_id,
ap.price_per_meter, ap.total_quantity, ap.total_amount,
ap.paid_quantity, ap.paid_amount, ap.unpaid_quantity, ap.unpaid_amount,
ap.status, ap.created_at, ap.updated_at,
COALESCE(pp.plan_code, '') as plan_code,
COALESCE(c.name, '') as factory_name
FROM ilm_accounts_payable ap
LEFT JOIN ilm_production_plan pp ON pp.id = ap.plan_id
LEFT JOIN ilm_company c ON c.id = ap.textile_factory_id
WHERE ap.purchaser_id = ?
ORDER BY ap.created_at DESC`
rows, err := r.db.QueryContext(ctx, query, companyID)
if err != nil {
return nil, fmt.Errorf("list accounts payable: %w", err)
}
defer rows.Close()
var list []model.AccountsPayable
for rows.Next() {
var ap model.AccountsPayable
if err := rows.Scan(
&ap.ID, &ap.PlanID, &ap.PurchaserID, &ap.TextileFactoryID,
&ap.PricePerMeter, &ap.TotalQuantity, &ap.TotalAmount,
&ap.PaidQuantity, &ap.PaidAmount, &ap.UnpaidQuantity, &ap.UnpaidAmount,
&ap.Status, &ap.CreatedAt, &ap.UpdatedAt,
&ap.PlanCode, &ap.FactoryName,
); err != nil {
return nil, fmt.Errorf("scan accounts payable: %w", err)
}
list = append(list, ap)
}
return list, nil
}
func (r *APRepo) Pay(ctx context.Context, tx *sql.Tx, apID string, amount float64) error {
query := `UPDATE ilm_accounts_payable SET
paid_amount = paid_amount + ?,
unpaid_amount = unpaid_amount - ?,
status = CASE WHEN unpaid_amount - ? <= 0 THEN 'completed' ELSE status END,
updated_at = NOW()
WHERE id = ? AND unpaid_amount >= ?`
result, err := tx.ExecContext(ctx, query, amount, amount, amount, apID, amount)
if err != nil {
return fmt.Errorf("pay: %w", err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("check rows affected: %w", err)
}
if rowsAffected == 0 {
return fmt.Errorf("payment failed: insufficient unpaid amount or record not found")
}
return nil
}
func (r *APRepo) TotalUnpaid(ctx context.Context, companyID string) (float64, error) {
var total float64
err := r.db.QueryRowContext(ctx,
`SELECT COALESCE(SUM(unpaid_amount), 0) FROM ilm_accounts_payable WHERE purchaser_id = ?`,
companyID,
).Scan(&total)
if err != nil {
return 0, fmt.Errorf("total unpaid: %w", err)
}
return total, nil
}