Files
bssapp/svc/queries/last10_avg_purchase_price_cache.go
2026-05-22 14:57:56 +03:00

87 lines
2.2 KiB
Go

package queries
import (
"context"
"database/sql"
"fmt"
"strings"
)
type Last10AvgPurchasePriceRow struct {
ItemCode string
CurrencyCode string
SampleCount int
AvgDocPrice float64
MinInvoiceDate sql.NullString
MaxInvoiceDate sql.NullString
}
// LookupLast10AvgPurchasePriceByItemCodes reads from dbo.cache_last10_avg_purchase_price (Nebim/V3 MSSQL).
// It is designed to be used in hot paths (save) where live invoice scans are too slow.
func LookupLast10AvgPurchasePriceByItemCodes(ctx context.Context, mssqlDB *sql.DB, itemCodes []string) ([]Last10AvgPurchasePriceRow, error) {
if mssqlDB == nil {
return nil, fmt.Errorf("mssql db is nil")
}
codes := make([]string, 0, len(itemCodes))
seen := map[string]struct{}{}
for _, c := range itemCodes {
c = strings.TrimSpace(c)
if c == "" {
continue
}
if _, ok := seen[c]; ok {
continue
}
seen[c] = struct{}{}
codes = append(codes, c)
}
if len(codes) == 0 {
return []Last10AvgPurchasePriceRow{}, nil
}
valParts := make([]string, 0, len(codes))
args := make([]any, 0, len(codes))
for i, code := range codes {
valParts = append(valParts, fmt.Sprintf("(@p%d)", i+1))
args = append(args, code)
}
sqlText := fmt.Sprintf(`
WITH C AS (
SELECT LTRIM(RTRIM(V.code)) AS ItemCode
FROM (VALUES %s) AS V(code)
)
SELECT
T.ItemCode,
T.Doc_CurrencyCode,
T.sample_count,
T.avg_doc_price,
CONVERT(varchar(10), T.min_invoice_date, 23) AS min_invoice_date,
CONVERT(varchar(10), T.max_invoice_date, 23) AS max_invoice_date
FROM dbo.cache_last10_avg_purchase_price T WITH (NOLOCK)
INNER JOIN C
ON C.ItemCode = T.ItemCode
`, strings.Join(valParts, ","))
rows, err := mssqlDB.QueryContext(ctx, sqlText, args...)
if err != nil {
return nil, err
}
defer rows.Close()
out := make([]Last10AvgPurchasePriceRow, 0, len(codes))
for rows.Next() {
var r Last10AvgPurchasePriceRow
if err := rows.Scan(&r.ItemCode, &r.CurrencyCode, &r.SampleCount, &r.AvgDocPrice, &r.MinInvoiceDate, &r.MaxInvoiceDate); err != nil {
return nil, err
}
r.ItemCode = strings.TrimSpace(r.ItemCode)
r.CurrencyCode = strings.TrimSpace(strings.ToUpper(r.CurrencyCode))
out = append(out, r)
}
if err := rows.Err(); err != nil {
return nil, err
}
return out, nil
}