Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-05-14 02:19:59 +03:00
parent 43f965a3cf
commit 7d1304b75a
8 changed files with 726 additions and 109 deletions

View File

@@ -37,6 +37,34 @@ ORDER BY ProductCode;
return urunAnaGrubu, urunAltGrubu, nil
}
func GetProductIlkAnaAltGrupByUrunKodu(ctx context.Context, mssqlDB *sql.DB, urunKodu string) (urunIlkGrubu string, urunAnaGrubu string, urunAltGrubu string, err error) {
urunKodu = strings.TrimSpace(urunKodu)
if mssqlDB == nil || urunKodu == "" {
return "", "", "", nil
}
// Nebim V3: ProductFilterWithDescription exposes ProductAtt42Desc (ilk grup), ProductAtt01Desc (ana), ProductAtt02Desc (alt).
sqlText := `
SELECT TOP 1
ISNULL(ProductAtt42Desc, '') AS UrunIlkGrubu,
ISNULL(ProductAtt01Desc, '') AS UrunAnaGrubu,
ISNULL(ProductAtt02Desc, '') AS UrunAltGrubu
FROM ProductFilterWithDescription('TR')
WHERE IsBlocked = 0
AND LTRIM(RTRIM(ProductCode)) = @p1
ORDER BY ProductCode;
`
row := mssqlDB.QueryRowContext(ctx, sqlText, urunKodu)
if err := row.Scan(&urunIlkGrubu, &urunAnaGrubu, &urunAltGrubu); err != nil {
if err == sql.ErrNoRows {
return "", "", "", nil
}
return "", "", "", err
}
return urunIlkGrubu, urunAnaGrubu, urunAltGrubu, nil
}
func GetProductionProductCostingAnaGrupOptions(ctx context.Context, mssqlDB *sql.DB, search string, limit int) (*sql.Rows, error) {
search = strings.TrimSpace(search)
if limit <= 0 {
@@ -131,6 +159,7 @@ SELECT TOP (@p2)
ISNULL(B.sAdi, '') AS sAdi
FROM dbo.spUrtMTBolum B WITH (NOLOCK)
WHERE ISNULL(B.bAktif, 0) = 1
AND ISNULL(B.nUrtTipiID, 0) = 1
AND (@p1 = '' OR ISNULL(B.sAdi, '') LIKE @p3 OR CONVERT(VARCHAR(32), ISNULL(B.nUrtMTBolumID, 0)) LIKE @p3)
ORDER BY B.nUrtMTBolumID
`
@@ -160,6 +189,7 @@ SELECT
FROM dbo.mk_MaliyetParcaEslestirme M WITH (NOLOCK)
LEFT JOIN dbo.spUrtMTBolum B WITH (NOLOCK)
ON B.nUrtMTBolumID = M.nUrtMTBolumID
AND ISNULL(B.nUrtTipiID, 0) = 1
OUTER APPLY (
SELECT
STUFF((
@@ -268,6 +298,97 @@ DECLARE @id INT;
return mappingID, nil
}
type ProductionProductCostingInvalidHammaddeForPart struct {
NHammaddeTuruNo int
Aciklama string
MTBolumID int
}
// FilterHammaddeTurleriForPart enforces spUrtOnMLHammaddeTuru.MTnUrtMTBolumID rules:
// - If MTnUrtMTBolumID > 0, the hammadde type is allowed only for that part (nUrtMTBolumID).
// - If MTnUrtMTBolumID is 0/NULL, it is considered global/unknown and allowed.
func FilterHammaddeTurleriForPart(
ctx context.Context,
uretimDB *sql.DB,
nUrtMTBolumID int,
nHammaddeTurleri []int,
) (allowed []int, invalid []ProductionProductCostingInvalidHammaddeForPart, err error) {
seen := make(map[int]bool, len(nHammaddeTurleri))
unique := make([]int, 0, len(nHammaddeTurleri))
for _, n := range nHammaddeTurleri {
if n <= 0 || seen[n] {
continue
}
seen[n] = true
unique = append(unique, n)
}
if len(unique) == 0 {
return []int{}, []ProductionProductCostingInvalidHammaddeForPart{}, nil
}
// Build IN list safely.
ph := make([]string, 0, len(unique))
args := make([]any, 0, len(unique))
for i, n := range unique {
ph = append(ph, fmt.Sprintf("@p%d", i+1))
args = append(args, n)
}
sqlText := fmt.Sprintf(`
SELECT
ISNULL(H.nHammaddeTuruNo, 0) AS nHammaddeTuruNo,
ISNULL(H.sAciklama, '') AS sAciklama,
ISNULL(H.MTnUrtMTBolumID, 0) AS MTnUrtMTBolumID
FROM dbo.spUrtOnMLHammaddeTuru H WITH (NOLOCK)
WHERE H.nHammaddeTuruNo IN (%s)
`, strings.Join(ph, ","))
rows, qerr := uretimDB.QueryContext(ctx, sqlText, args...)
if qerr != nil {
return nil, nil, qerr
}
defer rows.Close()
type meta struct {
aciklama string
mtBolumID int
}
metaByNo := map[int]meta{}
for rows.Next() {
var no int
var aciklama string
var mtBolum int
if scanErr := rows.Scan(&no, &aciklama, &mtBolum); scanErr != nil {
return nil, nil, scanErr
}
metaByNo[no] = meta{aciklama: strings.TrimSpace(aciklama), mtBolumID: mtBolum}
}
if rowsErr := rows.Err(); rowsErr != nil {
return nil, nil, rowsErr
}
allowed = make([]int, 0, len(unique))
invalid = make([]ProductionProductCostingInvalidHammaddeForPart, 0)
for _, n := range unique {
m, ok := metaByNo[n]
if !ok {
// Unknown in lookup; allow (we can't validate).
allowed = append(allowed, n)
continue
}
if m.mtBolumID > 0 && nUrtMTBolumID > 0 && m.mtBolumID != nUrtMTBolumID {
invalid = append(invalid, ProductionProductCostingInvalidHammaddeForPart{
NHammaddeTuruNo: n,
Aciklama: m.aciklama,
MTBolumID: m.mtBolumID,
})
continue
}
allowed = append(allowed, n)
}
return allowed, invalid, nil
}
func SetProductionProductCostingParcaMappingActive(ctx context.Context, uretimDB *sql.DB, id int, bAktif bool, user string) error {
user = strings.TrimSpace(user)
activeVal := 0
@@ -699,7 +820,8 @@ WITH RecipeMatch AS (
),
HammaddeTekil AS (
SELECT
ISNULL(NULLIF(LTRIM(RTRIM(HT.sAciklama3)), ''), ISNULL(NULLIF(LTRIM(RTRIM(HT.sAciklama)), ''), N'TANIMSIZ')) AS sAciklama3,
-- Group label: DT/TP/CM2/FABRIC... Prefer sAciklama3, then sAciklama2. Never fall back to sAciklama (name).
COALESCE(NULLIF(LTRIM(RTRIM(HT.sAciklama3)), ''), NULLIF(LTRIM(RTRIM(HT.sAciklama2)), ''), N'TANIMSIZ') AS sAciklama3,
ISNULL(HT.nHammaddeTuruNo, 0) AS nHammaddeTuruNoSort,
RTRIM(CONVERT(VARCHAR(32), ISNULL(HT.nHammaddeTuruNo, 0))) AS nHammaddeTuruNo,
-- Match URETIM's sp_pUrtOnMaliyetRecetedenKop behavior: use model code + color code instead of variant stock code.
@@ -709,6 +831,8 @@ HammaddeTekil AS (
ISNULL(HT.sAciklama, '') AS sHammaddeTuruAdi,
ISNULL(S.sBirimCinsi1, '') AS sBirim,
ISNULL(RMik.lHMiktar, 0) AS lMiktar,
ISNULL(HT.MTnUrtMTBolumID, 0) AS MTnUrtMTBolumID,
ISNULL(B.sAdi, '') AS sParcaAdi,
ROW_NUMBER() OVER (
PARTITION BY HT.nHammaddeTuruNo
ORDER BY ISNULL(S.sModel, ISNULL(S.sKodu, ''))
@@ -725,13 +849,20 @@ HammaddeTekil AS (
SELECT TOP 1
H.nHammaddeTuruNo,
H.sAciklama,
H.sAciklama3
H.sAciklama2,
H.sAciklama3,
H.MTnUrtMTBolumID
FROM dbo.spUrtOnMLHammaddeTuru H
WHERE H.nUrtMBolumID = RMik.nUrtMBolumID
-- In our data, RMik.nUrtMBolumID carries the required hammadde type number (e.g. 900/901/3300),
-- not a "bolum id". So match by hammadde type number.
WHERE H.nHammaddeTuruNo = RMik.nUrtMBolumID
ORDER BY
CASE WHEN H.nUrtMTBolumID = RMik.nUrtMTBolumID THEN 0 ELSE 1 END,
CASE WHEN H.MTnUrtMTBolumID = RMik.nUrtMTBolumID THEN 0 ELSE 1 END,
H.nHammaddeTuruNo
) HT
LEFT JOIN dbo.spUrtMTBolum B WITH (NOLOCK)
ON B.nUrtMTBolumID = HT.MTnUrtMTBolumID
AND ISNULL(B.nUrtTipiID, 0) = 1
WHERE HT.nHammaddeTuruNo IS NOT NULL
)
SELECT
@@ -762,7 +893,7 @@ SELECT
0.0 AS gbpTutar,
HT.sBirim,
HT.sHammaddeTuruAdi,
HT.sHammaddeTuruAdi AS sParcaAdi
HT.sParcaAdi AS sParcaAdi
FROM HammaddeTekil HT
WHERE HT.rn = 1
ORDER BY
@@ -800,15 +931,22 @@ func GetProductionHasCostDetailHammaddeTypeOptions(
SELECT TOP (@p2)
RTRIM(CONVERT(VARCHAR(32), ISNULL(T.nHammaddeTuruNo, 0))) AS nHammaddeTuruNo,
ISNULL(T.sAciklama, '') AS sHammaddeTuruAdi,
ISNULL(NULLIF(LTRIM(RTRIM(T.sAciklama3)), ''), N'TANIMSIZ') AS sAciklama3
FROM dbo.spUrtOnMLHammaddeTuru T
WHERE
ISNULL(T.bAktif, 0) = 1
AND (
COALESCE(NULLIF(LTRIM(RTRIM(T.sAciklama3)), ''), NULLIF(LTRIM(RTRIM(T.sAciklama2)), ''), N'TANIMSIZ') AS sAciklama3,
ISNULL(T.MTnUrtMTBolumID, 0) AS mtUrtMTBolumID,
ISNULL(B.sAdi, '') AS sParcaAdi
FROM dbo.spUrtOnMLHammaddeTuru T WITH (NOLOCK)
LEFT JOIN dbo.spUrtMTBolum B WITH (NOLOCK)
ON B.nUrtMTBolumID = T.MTnUrtMTBolumID
AND ISNULL(B.nUrtTipiID, 0) = 1
WHERE
ISNULL(T.bAktif, 0) = 1
AND (
@p1 = ''
OR RTRIM(CONVERT(VARCHAR(32), ISNULL(T.nHammaddeTuruNo, 0))) LIKE @p3
OR ISNULL(T.sAciklama, '') LIKE @p3
OR ISNULL(T.sAciklama2, '') LIKE @p3
OR ISNULL(T.sAciklama3, '') LIKE @p3
OR ISNULL(B.sAdi, '') LIKE @p3
)
ORDER BY
CASE