235 lines
6.1 KiB
Go
235 lines
6.1 KiB
Go
package queries
|
|
|
|
import (
|
|
"bssapp-backend/db"
|
|
"bssapp-backend/models"
|
|
"context"
|
|
"database/sql"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func GetProductPricingList(ctx context.Context) ([]models.ProductPricing, error) {
|
|
const query = `
|
|
WITH base_products AS (
|
|
SELECT
|
|
LTRIM(RTRIM(ProductCode)) AS ProductCode,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt45Desc)), '') AS AskiliYan,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt44Desc)), '') AS Kategori,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt42Desc)), '') AS UrunIlkGrubu,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt01Desc)), '') AS UrunAnaGrubu,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt02Desc)), '') AS UrunAltGrubu,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt41Desc)), '') AS Icerik,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt29Desc)), '') AS Karisim,
|
|
COALESCE(LTRIM(RTRIM(ProductAtt10Desc)), '') AS Marka
|
|
FROM ProductFilterWithDescription('TR')
|
|
WHERE ProductAtt42 IN ('SERI', 'AKSESUAR')
|
|
AND IsBlocked = 0
|
|
AND LEN(LTRIM(RTRIM(ProductCode))) = 13
|
|
),
|
|
latest_base_price AS (
|
|
SELECT
|
|
LTRIM(RTRIM(b.ItemCode)) AS ItemCode,
|
|
CAST(b.Price AS DECIMAL(18, 2)) AS CostPrice,
|
|
CONVERT(VARCHAR(10), b.PriceDate, 23) AS LastPricingDate,
|
|
ROW_NUMBER() OVER (
|
|
PARTITION BY LTRIM(RTRIM(b.ItemCode))
|
|
ORDER BY b.PriceDate DESC, b.LastUpdatedDate DESC
|
|
) AS rn
|
|
FROM prItemBasePrice b
|
|
WHERE b.ItemTypeCode = 1
|
|
AND b.BasePriceCode = 1
|
|
AND LTRIM(RTRIM(b.CurrencyCode)) = 'USD'
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(b.ItemCode))
|
|
)
|
|
),
|
|
stock_entry_dates AS (
|
|
SELECT
|
|
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
|
CONVERT(VARCHAR(10), MAX(s.OperationDate), 23) AS StockEntryDate
|
|
FROM trStock s WITH(NOLOCK)
|
|
WHERE s.ItemTypeCode = 1
|
|
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
|
AND s.In_Qty1 > 0
|
|
AND LTRIM(RTRIM(s.WarehouseCode)) IN (
|
|
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
|
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
|
'1-0-33','101','1-014','1-0-49','1-0-36'
|
|
)
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
|
)
|
|
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
|
),
|
|
stock_base AS (
|
|
SELECT
|
|
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
|
SUM(s.In_Qty1 - s.Out_Qty1) AS InventoryQty1
|
|
FROM trStock s WITH(NOLOCK)
|
|
WHERE s.ItemTypeCode = 1
|
|
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
|
)
|
|
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
|
),
|
|
pick_base AS (
|
|
SELECT
|
|
LTRIM(RTRIM(p.ItemCode)) AS ItemCode,
|
|
SUM(p.Qty1) AS PickingQty1
|
|
FROM PickingStates p
|
|
WHERE p.ItemTypeCode = 1
|
|
AND LEN(LTRIM(RTRIM(p.ItemCode))) = 13
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(p.ItemCode))
|
|
)
|
|
GROUP BY LTRIM(RTRIM(p.ItemCode))
|
|
),
|
|
reserve_base AS (
|
|
SELECT
|
|
LTRIM(RTRIM(r.ItemCode)) AS ItemCode,
|
|
SUM(r.Qty1) AS ReserveQty1
|
|
FROM ReserveStates r
|
|
WHERE r.ItemTypeCode = 1
|
|
AND LEN(LTRIM(RTRIM(r.ItemCode))) = 13
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(r.ItemCode))
|
|
)
|
|
GROUP BY LTRIM(RTRIM(r.ItemCode))
|
|
),
|
|
disp_base AS (
|
|
SELECT
|
|
LTRIM(RTRIM(d.ItemCode)) AS ItemCode,
|
|
SUM(d.Qty1) AS DispOrderQty1
|
|
FROM DispOrderStates d
|
|
WHERE d.ItemTypeCode = 1
|
|
AND LEN(LTRIM(RTRIM(d.ItemCode))) = 13
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM base_products bp
|
|
WHERE bp.ProductCode = LTRIM(RTRIM(d.ItemCode))
|
|
)
|
|
GROUP BY LTRIM(RTRIM(d.ItemCode))
|
|
),
|
|
stock_totals AS (
|
|
SELECT
|
|
bp.ProductCode AS ItemCode,
|
|
CAST(ROUND(
|
|
ISNULL(sb.InventoryQty1, 0)
|
|
- ISNULL(pb.PickingQty1, 0)
|
|
- ISNULL(rb.ReserveQty1, 0)
|
|
- ISNULL(db.DispOrderQty1, 0)
|
|
, 2) AS DECIMAL(18, 2)) AS StockQty
|
|
FROM base_products bp
|
|
LEFT JOIN stock_base sb
|
|
ON sb.ItemCode = bp.ProductCode
|
|
LEFT JOIN pick_base pb
|
|
ON pb.ItemCode = bp.ProductCode
|
|
LEFT JOIN reserve_base rb
|
|
ON rb.ItemCode = bp.ProductCode
|
|
LEFT JOIN disp_base db
|
|
ON db.ItemCode = bp.ProductCode
|
|
)
|
|
SELECT
|
|
bp.ProductCode AS ProductCode,
|
|
COALESCE(lp.CostPrice, 0) AS CostPrice,
|
|
COALESCE(st.StockQty, 0) AS StockQty,
|
|
COALESCE(se.StockEntryDate, '') AS StockEntryDate,
|
|
COALESCE(lp.LastPricingDate, '') AS LastPricingDate,
|
|
bp.AskiliYan,
|
|
bp.Kategori,
|
|
bp.UrunIlkGrubu,
|
|
bp.UrunAnaGrubu,
|
|
bp.UrunAltGrubu,
|
|
bp.Icerik,
|
|
bp.Karisim,
|
|
bp.Marka
|
|
FROM base_products bp
|
|
LEFT JOIN latest_base_price lp
|
|
ON lp.ItemCode = bp.ProductCode
|
|
AND lp.rn = 1
|
|
LEFT JOIN stock_entry_dates se
|
|
ON se.ItemCode = bp.ProductCode
|
|
LEFT JOIN stock_totals st
|
|
ON st.ItemCode = bp.ProductCode
|
|
ORDER BY bp.ProductCode;
|
|
`
|
|
|
|
var (
|
|
rows *sql.Rows
|
|
rowsErr error
|
|
)
|
|
for attempt := 1; attempt <= 3; attempt++ {
|
|
var err error
|
|
rows, err = db.MssqlDB.QueryContext(ctx, query)
|
|
if err == nil {
|
|
rowsErr = nil
|
|
break
|
|
}
|
|
rowsErr = err
|
|
if ctx.Err() != nil || !isTransientMSSQLNetworkError(err) || attempt == 3 {
|
|
break
|
|
}
|
|
wait := time.Duration(attempt*300) * time.Millisecond
|
|
select {
|
|
case <-ctx.Done():
|
|
break
|
|
case <-time.After(wait):
|
|
}
|
|
}
|
|
if rowsErr != nil {
|
|
return nil, rowsErr
|
|
}
|
|
defer rows.Close()
|
|
|
|
var out []models.ProductPricing
|
|
for rows.Next() {
|
|
var item models.ProductPricing
|
|
if err := rows.Scan(
|
|
&item.ProductCode,
|
|
&item.CostPrice,
|
|
&item.StockQty,
|
|
&item.StockEntryDate,
|
|
&item.LastPricingDate,
|
|
&item.AskiliYan,
|
|
&item.Kategori,
|
|
&item.UrunIlkGrubu,
|
|
&item.UrunAnaGrubu,
|
|
&item.UrunAltGrubu,
|
|
&item.Icerik,
|
|
&item.Karisim,
|
|
&item.Marka,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, item)
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func isTransientMSSQLNetworkError(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
e := strings.ToLower(err.Error())
|
|
return strings.Contains(e, "i/o timeout") ||
|
|
strings.Contains(e, "timeout") ||
|
|
strings.Contains(e, "wsarecv") ||
|
|
strings.Contains(e, "connection attempt failed") ||
|
|
strings.Contains(e, "no connection could be made") ||
|
|
strings.Contains(e, "broken pipe") ||
|
|
strings.Contains(e, "connection reset")
|
|
}
|