87 lines
2.2 KiB
Go
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
|
|
}
|