1187 lines
40 KiB
Go
1187 lines
40 KiB
Go
package queries
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"bssapp-backend/models"
|
|
)
|
|
|
|
// ========================================================
|
|
// 📌 GetOrderProductionItems — OrderHeaderID için U ürünleri
|
|
// ========================================================
|
|
func GetOrderProductionItems(mssql *sql.DB, orderHeaderID string) (*sql.Rows, error) {
|
|
return mssql.Query(`
|
|
SELECT
|
|
CAST(l.OrderHeaderID AS NVARCHAR(50)) AS OrderHeaderID,
|
|
CAST(l.OrderLineID AS NVARCHAR(50)) AS OrderLineID,
|
|
l.ItemTypeCode AS ItemTypeCode,
|
|
ISNULL(l.ItemDim1Code,'') AS OldDim1,
|
|
ISNULL(l.ItemDim3Code,'') AS OldDim3,
|
|
|
|
ISNULL(l.ItemCode,'') AS OldItemCode,
|
|
ISNULL(l.ColorCode,'') AS OldColor,
|
|
ISNULL((
|
|
SELECT TOP 1 LTRIM(RTRIM(cd.ColorDescription))
|
|
FROM dbo.cdColorDesc cd WITH (NOLOCK)
|
|
WHERE cd.ColorCode = l.ColorCode
|
|
AND cd.LangCode = N'TR'
|
|
), '') AS OldColorDescription,
|
|
ISNULL(l.ItemDim2Code,'') AS OldDim2,
|
|
ISNULL(l.LineDescription,'') AS OldDesc,
|
|
CAST(ISNULL(l.Qty1, 0) AS FLOAT) AS OldQty,
|
|
|
|
CAST('' AS NVARCHAR(60)) AS NewItemCode,
|
|
CAST('' AS NVARCHAR(30)) AS NewColor,
|
|
CAST('' AS NVARCHAR(30)) AS NewDim2,
|
|
CAST('' AS NVARCHAR(250)) AS NewDesc,
|
|
|
|
CONVERT(NVARCHAR(10), l.DeliveryDate, 126) AS OldDueDate,
|
|
CONVERT(NVARCHAR(10), l.DeliveryDate, 126) AS NewDueDate,
|
|
|
|
CAST(0 AS bit) AS IsVariantMissing
|
|
FROM dbo.trOrderLine l
|
|
WHERE l.OrderHeaderID = @p1
|
|
AND ISNULL(l.ItemCode,'') LIKE 'U%'
|
|
ORDER BY l.SortOrder, l.OrderLineID
|
|
`, orderHeaderID)
|
|
}
|
|
|
|
// ========================================================
|
|
// 📌 InsertMissingProductionVariants — eksik prItemVariant ekler
|
|
// ========================================================
|
|
func InsertMissingProductionVariants(mssql *sql.DB, orderHeaderID string, username string) (int64, error) {
|
|
query := `
|
|
;WITH Missing AS (
|
|
SELECT DISTINCT
|
|
l.ItemTypeCode,
|
|
l.ItemCode,
|
|
l.ColorCode,
|
|
l.ItemDim1Code,
|
|
l.ItemDim2Code,
|
|
l.ItemDim3Code
|
|
FROM dbo.trOrderLine l
|
|
LEFT JOIN dbo.prItemVariant pv
|
|
ON pv.ItemTypeCode = l.ItemTypeCode
|
|
AND ISNULL(LTRIM(RTRIM(pv.ItemCode)),'') = ISNULL(LTRIM(RTRIM(l.ItemCode)),'')
|
|
AND ISNULL(LTRIM(RTRIM(pv.ColorCode)),'') = ISNULL(LTRIM(RTRIM(l.ColorCode)),'')
|
|
AND ISNULL(LTRIM(RTRIM(pv.ItemDim1Code)),'') = ISNULL(LTRIM(RTRIM(l.ItemDim1Code)),'')
|
|
AND ISNULL(LTRIM(RTRIM(pv.ItemDim2Code)),'') = ISNULL(LTRIM(RTRIM(l.ItemDim2Code)),'')
|
|
AND ISNULL(LTRIM(RTRIM(pv.ItemDim3Code)),'') = ISNULL(LTRIM(RTRIM(l.ItemDim3Code)),'')
|
|
WHERE l.OrderHeaderID = @p1
|
|
AND ISNULL(l.ItemCode,'') LIKE 'U%'
|
|
AND pv.ItemCode IS NULL
|
|
)
|
|
INSERT INTO dbo.prItemVariant (
|
|
ItemTypeCode,
|
|
ItemCode,
|
|
ColorCode,
|
|
ItemDim1Code,
|
|
ItemDim2Code,
|
|
ItemDim3Code,
|
|
IsSalesOrderClosed,
|
|
IsPurchaseOrderClosed,
|
|
IsLocked,
|
|
IsBlocked,
|
|
CreatedUserName,
|
|
CreatedDate,
|
|
LastUpdatedUserName,
|
|
LastUpdatedDate,
|
|
RowGuid,
|
|
UseInternet,
|
|
IsStoreOrderClosed
|
|
)
|
|
SELECT
|
|
m.ItemTypeCode,
|
|
m.ItemCode,
|
|
m.ColorCode,
|
|
m.ItemDim1Code,
|
|
m.ItemDim2Code,
|
|
m.ItemDim3Code,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
@p2,
|
|
GETDATE(),
|
|
@p2,
|
|
GETDATE(),
|
|
NEWID(),
|
|
0,
|
|
0
|
|
FROM Missing m;
|
|
`
|
|
|
|
res, err := mssql.Exec(query, orderHeaderID, username)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return res.RowsAffected()
|
|
}
|
|
|
|
// ========================================================
|
|
// OrderProductionUpdate - variant kontrolu ve guncelleme
|
|
// ========================================================
|
|
func GetOrderLineDims(mssql *sql.DB, orderHeaderID string, orderLineID string) (int16, string, string, string, error) {
|
|
var itemTypeCode int16
|
|
var dim1 string
|
|
var dim2 string
|
|
var dim3 string
|
|
err := mssql.QueryRow(`
|
|
SELECT
|
|
ItemTypeCode,
|
|
ISNULL(ItemDim1Code,'') AS ItemDim1Code,
|
|
ISNULL(ItemDim2Code,'') AS ItemDim2Code,
|
|
ISNULL(ItemDim3Code,'') AS ItemDim3Code
|
|
FROM dbo.trOrderLine
|
|
WHERE OrderHeaderID = @p1 AND OrderLineID = @p2
|
|
`, orderHeaderID, orderLineID).Scan(&itemTypeCode, &dim1, &dim2, &dim3)
|
|
return itemTypeCode, dim1, dim2, dim3, err
|
|
}
|
|
|
|
type OrderLineDims struct {
|
|
ItemTypeCode int16
|
|
ItemDim1Code string
|
|
ItemDim2Code string
|
|
ItemDim3Code string
|
|
}
|
|
|
|
func GetOrderLineDimsMap(mssql *sql.DB, orderHeaderID string) (map[string]OrderLineDims, error) {
|
|
rows, err := mssql.Query(`
|
|
SELECT
|
|
CAST(OrderLineID AS NVARCHAR(50)) AS OrderLineID,
|
|
ItemTypeCode,
|
|
ISNULL(ItemDim1Code,'') AS ItemDim1Code,
|
|
ISNULL(ItemDim2Code,'') AS ItemDim2Code,
|
|
ISNULL(ItemDim3Code,'') AS ItemDim3Code
|
|
FROM dbo.trOrderLine WITH(NOLOCK)
|
|
WHERE OrderHeaderID = @p1
|
|
`, orderHeaderID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
out := make(map[string]OrderLineDims, 128)
|
|
for rows.Next() {
|
|
var lineID string
|
|
var d OrderLineDims
|
|
if err := rows.Scan(&lineID, &d.ItemTypeCode, &d.ItemDim1Code, &d.ItemDim2Code, &d.ItemDim3Code); err != nil {
|
|
return nil, err
|
|
}
|
|
out[strings.TrimSpace(lineID)] = d
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func VariantExists(mssql *sql.DB, itemTypeCode int16, itemCode string, colorCode string, dim1 string, dim2 string, dim3 string) (bool, error) {
|
|
var exists int
|
|
err := mssql.QueryRow(`
|
|
SELECT TOP 1 1
|
|
FROM dbo.prItemVariant
|
|
WHERE ItemTypeCode = @p1
|
|
AND ItemCode = @p2
|
|
AND (
|
|
ColorCode = @p3
|
|
OR (@p3 = '' AND (ColorCode IS NULL OR ColorCode = ''))
|
|
)
|
|
AND (
|
|
ItemDim1Code = @p4
|
|
OR (@p4 = '' AND (ItemDim1Code IS NULL OR ItemDim1Code = ''))
|
|
)
|
|
AND (
|
|
ItemDim2Code = @p5
|
|
OR (@p5 = '' AND (ItemDim2Code IS NULL OR ItemDim2Code = ''))
|
|
)
|
|
AND (
|
|
ItemDim3Code = @p6
|
|
OR (@p6 = '' AND (ItemDim3Code IS NULL OR ItemDim3Code = ''))
|
|
)
|
|
`, itemTypeCode, itemCode, colorCode, dim1, dim2, dim3).Scan(&exists)
|
|
if err == sql.ErrNoRows {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func InsertMissingVariantsTx(
|
|
tx *sql.Tx,
|
|
missing []models.OrderProductionMissingVariant,
|
|
username string,
|
|
cdItemByCode map[string]models.OrderProductionCdItemDraft,
|
|
) (int64, error) {
|
|
start := time.Now()
|
|
if len(missing) == 0 {
|
|
log.Printf("[InsertMissingVariantsTx] missing=0 inserted=0 duration_ms=0")
|
|
return 0, nil
|
|
}
|
|
|
|
var inserted int64
|
|
ensuredItems := make(map[string]struct{}, len(missing))
|
|
uniqueVariants := make([]models.OrderProductionMissingVariant, 0, len(missing))
|
|
seenVariants := make(map[string]struct{}, len(missing))
|
|
|
|
for _, v := range missing {
|
|
variantKey := strconv.FormatInt(int64(v.ItemTypeCode), 10) + "|" +
|
|
strings.ToUpper(strings.TrimSpace(v.ItemCode)) + "|" +
|
|
strings.ToUpper(strings.TrimSpace(v.ColorCode)) + "|" +
|
|
strings.ToUpper(strings.TrimSpace(v.ItemDim1Code)) + "|" +
|
|
strings.ToUpper(strings.TrimSpace(v.ItemDim2Code)) + "|" +
|
|
strings.ToUpper(strings.TrimSpace(v.ItemDim3Code))
|
|
if _, ok := seenVariants[variantKey]; ok {
|
|
continue
|
|
}
|
|
seenVariants[variantKey] = struct{}{}
|
|
uniqueVariants = append(uniqueVariants, v)
|
|
|
|
itemKey := strconv.FormatInt(int64(v.ItemTypeCode), 10) + "|" + v.ItemCode
|
|
if _, ok := ensuredItems[itemKey]; !ok {
|
|
draft, hasDraft := cdItemByCode[itemKey]
|
|
if !hasDraft {
|
|
draft, hasDraft = cdItemByCode[NormalizeCdItemMapKey(v.ItemTypeCode, v.ItemCode)]
|
|
}
|
|
var draftPtr *models.OrderProductionCdItemDraft
|
|
if hasDraft {
|
|
tmp := draft
|
|
draftPtr = &tmp
|
|
}
|
|
if err := ensureCdItemTx(tx, v.ItemTypeCode, v.ItemCode, username, draftPtr); err != nil {
|
|
return inserted, err
|
|
}
|
|
ensuredItems[itemKey] = struct{}{}
|
|
}
|
|
}
|
|
|
|
if len(uniqueVariants) == 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
args := make([]any, 0, len(uniqueVariants)*6+1)
|
|
valueRows := make([]string, 0, len(uniqueVariants))
|
|
paramPos := 1
|
|
for _, v := range uniqueVariants {
|
|
valueRows = append(valueRows, fmt.Sprintf("(@p%d,@p%d,@p%d,@p%d,@p%d,@p%d)", paramPos, paramPos+1, paramPos+2, paramPos+3, paramPos+4, paramPos+5))
|
|
args = append(args, v.ItemTypeCode, v.ItemCode, v.ColorCode, v.ItemDim1Code, v.ItemDim2Code, v.ItemDim3Code)
|
|
paramPos += 6
|
|
}
|
|
usernameParam := paramPos
|
|
args = append(args, username)
|
|
|
|
query := fmt.Sprintf(`
|
|
SET NOCOUNT ON;
|
|
;WITH Missing(ItemTypeCode, ItemCode, ColorCode, ItemDim1Code, ItemDim2Code, ItemDim3Code) AS (
|
|
SELECT *
|
|
FROM (VALUES %s) AS v(ItemTypeCode, ItemCode, ColorCode, ItemDim1Code, ItemDim2Code, ItemDim3Code)
|
|
)
|
|
INSERT INTO dbo.prItemVariant (
|
|
ItemTypeCode,
|
|
ItemCode,
|
|
ColorCode,
|
|
ItemDim1Code,
|
|
ItemDim2Code,
|
|
ItemDim3Code,
|
|
IsSalesOrderClosed,
|
|
IsPurchaseOrderClosed,
|
|
IsLocked,
|
|
IsBlocked,
|
|
CreatedUserName,
|
|
CreatedDate,
|
|
LastUpdatedUserName,
|
|
LastUpdatedDate,
|
|
RowGuid,
|
|
UseInternet,
|
|
IsStoreOrderClosed
|
|
)
|
|
SELECT
|
|
m.ItemTypeCode,
|
|
m.ItemCode,
|
|
m.ColorCode,
|
|
m.ItemDim1Code,
|
|
m.ItemDim2Code,
|
|
m.ItemDim3Code,
|
|
0, 0, 0, 0,
|
|
@p%d, GETDATE(), @p%d, GETDATE(),
|
|
NEWID(),
|
|
0,
|
|
0
|
|
FROM Missing m
|
|
LEFT JOIN dbo.prItemVariant pv
|
|
ON pv.ItemTypeCode = m.ItemTypeCode
|
|
AND pv.ItemCode = m.ItemCode
|
|
AND (
|
|
pv.ColorCode = m.ColorCode
|
|
OR (m.ColorCode = '' AND (pv.ColorCode IS NULL OR pv.ColorCode = ''))
|
|
)
|
|
AND (
|
|
pv.ItemDim1Code = m.ItemDim1Code
|
|
OR (m.ItemDim1Code = '' AND (pv.ItemDim1Code IS NULL OR pv.ItemDim1Code = ''))
|
|
)
|
|
AND (
|
|
pv.ItemDim2Code = m.ItemDim2Code
|
|
OR (m.ItemDim2Code = '' AND (pv.ItemDim2Code IS NULL OR pv.ItemDim2Code = ''))
|
|
)
|
|
AND (
|
|
pv.ItemDim3Code = m.ItemDim3Code
|
|
OR (m.ItemDim3Code = '' AND (pv.ItemDim3Code IS NULL OR pv.ItemDim3Code = ''))
|
|
)
|
|
WHERE pv.ItemCode IS NULL;
|
|
`, strings.Join(valueRows, ","), usernameParam, usernameParam)
|
|
|
|
res, err := tx.Exec(query, args...)
|
|
if err != nil {
|
|
return inserted, err
|
|
}
|
|
if rows, rowsErr := res.RowsAffected(); rowsErr == nil {
|
|
inserted += rows
|
|
}
|
|
log.Printf("[InsertMissingVariantsTx] missing=%d unique=%d ensuredItems=%d inserted=%d duration_ms=%d",
|
|
len(missing), len(uniqueVariants), len(ensuredItems), inserted, time.Since(start).Milliseconds())
|
|
return inserted, nil
|
|
}
|
|
|
|
func NormalizeCdItemMapKey(itemTypeCode int16, itemCode string) string {
|
|
return strconv.FormatInt(int64(itemTypeCode), 10) + "|" + strings.ToUpper(strings.TrimSpace(itemCode))
|
|
}
|
|
|
|
func ensureCdItemTx(
|
|
tx *sql.Tx,
|
|
itemTypeCode int16,
|
|
itemCode string,
|
|
username string,
|
|
draft *models.OrderProductionCdItemDraft,
|
|
) error {
|
|
_, err := tx.Exec(`
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM dbo.cdItem
|
|
WHERE ItemTypeCode = @p1
|
|
AND ItemCode = @p2
|
|
)
|
|
BEGIN
|
|
;WITH Template AS (
|
|
SELECT TOP 1
|
|
ItemDimTypeCode, ProductTypeCode, ProductHierarchyID,
|
|
UnitOfMeasureCode1, UnitOfMeasureCode2, UnitConvertRate, UnitConvertRateNotFixed,
|
|
UseInternet, UsePOS, UseStore, EnablePartnerCompanies, UseManufacturing, UseSerialNumber,
|
|
GenerateOpticalDataMatrixCode, ByWeight, SupplyPeriod, GuaranteePeriod, ShelfLife, OrderLeadTime,
|
|
ItemAccountGrCode, ItemTaxGrCode, ItemPaymentPlanGrCode, ItemDiscountGrCode, ItemVendorGrCode,
|
|
PromotionGroupCode, PromotionGroupCode2, ProductCollectionGrCode, StorePriceLevelCode, PerceptionOfFashionCode,
|
|
CommercialRoleCode, StoreCapacityLevelCode, CustomsTariffNumberCode, IsFixedExpense, BOMEntityCode, CompanyCode,
|
|
IsBlocked, IsLocked, LockedDate, IsSalesOrderClosed, IsPurchaseOrderClosed, UseRoll, UseBatch,
|
|
MaxCreditCardInstallmentCount, GenerateSerialNumber, IsSubsequentDeliveryForR, IsSubsequentDeliveryForRI,
|
|
IGACommissionGroup, UniFreeCommissionGroup, CustomsProductGroupCode, IsUTSDeclaratedItem, IsStoreOrderClosed
|
|
FROM dbo.cdItem WITH (UPDLOCK, HOLDLOCK)
|
|
WHERE ItemTypeCode = @p1
|
|
AND ItemCode LIKE 'U%'
|
|
ORDER BY CreatedDate DESC
|
|
)
|
|
INSERT INTO dbo.cdItem (
|
|
ItemTypeCode, ItemCode,
|
|
ItemDimTypeCode, ProductTypeCode, ProductHierarchyID,
|
|
UnitOfMeasureCode1, UnitOfMeasureCode2, UnitConvertRate, UnitConvertRateNotFixed,
|
|
UseInternet, UsePOS, UseStore, EnablePartnerCompanies, UseManufacturing, UseSerialNumber,
|
|
GenerateOpticalDataMatrixCode, ByWeight, SupplyPeriod, GuaranteePeriod, ShelfLife, OrderLeadTime,
|
|
ItemAccountGrCode, ItemTaxGrCode, ItemPaymentPlanGrCode, ItemDiscountGrCode, ItemVendorGrCode,
|
|
PromotionGroupCode, PromotionGroupCode2, ProductCollectionGrCode, StorePriceLevelCode, PerceptionOfFashionCode,
|
|
CommercialRoleCode, StoreCapacityLevelCode, CustomsTariffNumberCode, IsFixedExpense, BOMEntityCode, CompanyCode,
|
|
IsBlocked, IsLocked, LockedDate, IsSalesOrderClosed, IsPurchaseOrderClosed,
|
|
CreatedUserName, CreatedDate, LastUpdatedUserName, LastUpdatedDate, RowGuid,
|
|
UseRoll, UseBatch, MaxCreditCardInstallmentCount, GenerateSerialNumber,
|
|
IsSubsequentDeliveryForR, IsSubsequentDeliveryForRI,
|
|
IGACommissionGroup, UniFreeCommissionGroup, CustomsProductGroupCode, IsUTSDeclaratedItem, IsStoreOrderClosed
|
|
)
|
|
SELECT
|
|
@p1, @p2,
|
|
t.ItemDimTypeCode, t.ProductTypeCode, t.ProductHierarchyID,
|
|
t.UnitOfMeasureCode1, t.UnitOfMeasureCode2, t.UnitConvertRate, t.UnitConvertRateNotFixed,
|
|
t.UseInternet, t.UsePOS, t.UseStore, t.EnablePartnerCompanies, t.UseManufacturing, t.UseSerialNumber,
|
|
t.GenerateOpticalDataMatrixCode, t.ByWeight, t.SupplyPeriod, t.GuaranteePeriod, t.ShelfLife, t.OrderLeadTime,
|
|
t.ItemAccountGrCode, t.ItemTaxGrCode, t.ItemPaymentPlanGrCode, t.ItemDiscountGrCode, t.ItemVendorGrCode,
|
|
t.PromotionGroupCode, t.PromotionGroupCode2, t.ProductCollectionGrCode, t.StorePriceLevelCode, t.PerceptionOfFashionCode,
|
|
t.CommercialRoleCode, t.StoreCapacityLevelCode, t.CustomsTariffNumberCode, t.IsFixedExpense, t.BOMEntityCode, t.CompanyCode,
|
|
t.IsBlocked, t.IsLocked, t.LockedDate, t.IsSalesOrderClosed, t.IsPurchaseOrderClosed,
|
|
@p3, GETDATE(), @p3, GETDATE(), NEWID(),
|
|
t.UseRoll, t.UseBatch, t.MaxCreditCardInstallmentCount, t.GenerateSerialNumber,
|
|
t.IsSubsequentDeliveryForR, t.IsSubsequentDeliveryForRI,
|
|
t.IGACommissionGroup, t.UniFreeCommissionGroup, t.CustomsProductGroupCode, t.IsUTSDeclaratedItem, t.IsStoreOrderClosed
|
|
FROM Template t;
|
|
|
|
IF @@ROWCOUNT = 0
|
|
BEGIN
|
|
INSERT INTO dbo.cdItem (
|
|
ItemTypeCode, ItemCode,
|
|
ItemDimTypeCode, ProductTypeCode, ProductHierarchyID,
|
|
UnitOfMeasureCode1, UnitOfMeasureCode2, UnitConvertRate, UnitConvertRateNotFixed,
|
|
UseInternet, UsePOS, UseStore, EnablePartnerCompanies, UseManufacturing, UseSerialNumber,
|
|
GenerateOpticalDataMatrixCode, ByWeight, SupplyPeriod, GuaranteePeriod, ShelfLife, OrderLeadTime,
|
|
ItemAccountGrCode, ItemTaxGrCode, ItemPaymentPlanGrCode, ItemDiscountGrCode, ItemVendorGrCode,
|
|
PromotionGroupCode, PromotionGroupCode2, ProductCollectionGrCode, StorePriceLevelCode, PerceptionOfFashionCode,
|
|
CommercialRoleCode, StoreCapacityLevelCode, CustomsTariffNumberCode, IsFixedExpense, BOMEntityCode, CompanyCode,
|
|
IsBlocked, IsLocked, LockedDate, IsSalesOrderClosed, IsPurchaseOrderClosed,
|
|
CreatedUserName, CreatedDate, LastUpdatedUserName, LastUpdatedDate, RowGuid,
|
|
UseRoll, UseBatch, MaxCreditCardInstallmentCount, GenerateSerialNumber,
|
|
IsSubsequentDeliveryForR, IsSubsequentDeliveryForRI,
|
|
IGACommissionGroup, UniFreeCommissionGroup, CustomsProductGroupCode, IsUTSDeclaratedItem, IsStoreOrderClosed
|
|
)
|
|
VALUES (
|
|
@p1, @p2,
|
|
2, 1, 2,
|
|
'AD', '', 0, 0,
|
|
1, 1, 1, 0, 1, 0,
|
|
0, 0, 0, 0, 0, 0,
|
|
'', '%10', '', '', '',
|
|
'', '', '0', '0', '0',
|
|
'0', '', '', 0, '', '1',
|
|
0, 0, '1900-01-01', 0, 0,
|
|
@p3, GETDATE(), @p3, GETDATE(), NEWID(),
|
|
0, 0, 12, 0,
|
|
0, 0,
|
|
'', '', '0', 0, 0
|
|
);
|
|
END
|
|
END
|
|
`, itemTypeCode, itemCode, username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if draft == nil {
|
|
return nil
|
|
}
|
|
|
|
_, err = tx.Exec(`
|
|
UPDATE dbo.cdItem
|
|
SET
|
|
ItemDimTypeCode = COALESCE(@p3, ItemDimTypeCode),
|
|
ProductTypeCode = COALESCE(@p4, ProductTypeCode),
|
|
ProductHierarchyID = COALESCE(@p5, ProductHierarchyID),
|
|
UnitOfMeasureCode1 = COALESCE(NULLIF(@p6,''), UnitOfMeasureCode1),
|
|
ItemAccountGrCode = COALESCE(NULLIF(@p7,''), ItemAccountGrCode),
|
|
ItemTaxGrCode = CASE
|
|
WHEN NULLIF(@p8,'') IS NULL THEN ItemTaxGrCode
|
|
WHEN EXISTS (
|
|
SELECT 1
|
|
FROM dbo.cdItemTaxGr g WITH(NOLOCK)
|
|
WHERE LTRIM(RTRIM(g.ItemTaxGrCode)) = LTRIM(RTRIM(@p8))
|
|
) THEN @p8
|
|
ELSE ItemTaxGrCode
|
|
END,
|
|
ItemPaymentPlanGrCode = COALESCE(NULLIF(@p9,''), ItemPaymentPlanGrCode),
|
|
ItemDiscountGrCode = COALESCE(NULLIF(@p10,''), ItemDiscountGrCode),
|
|
ItemVendorGrCode = COALESCE(NULLIF(@p11,''), ItemVendorGrCode),
|
|
PromotionGroupCode = COALESCE(NULLIF(@p12,''), PromotionGroupCode),
|
|
ProductCollectionGrCode = COALESCE(NULLIF(@p13,''), ProductCollectionGrCode),
|
|
StorePriceLevelCode = COALESCE(NULLIF(@p14,''), StorePriceLevelCode),
|
|
PerceptionOfFashionCode = COALESCE(NULLIF(@p15,''), PerceptionOfFashionCode),
|
|
CommercialRoleCode = COALESCE(NULLIF(@p16,''), CommercialRoleCode),
|
|
StoreCapacityLevelCode = COALESCE(NULLIF(@p17,''), StoreCapacityLevelCode),
|
|
CustomsTariffNumberCode = COALESCE(NULLIF(@p18,''), CustomsTariffNumberCode),
|
|
CompanyCode = COALESCE(NULLIF(@p19,''), CompanyCode),
|
|
LastUpdatedUserName = @p20,
|
|
LastUpdatedDate = GETDATE()
|
|
WHERE ItemTypeCode = @p1
|
|
AND ItemCode = @p2;
|
|
`,
|
|
itemTypeCode,
|
|
itemCode,
|
|
draft.ItemDimTypeCode,
|
|
draft.ProductTypeCode,
|
|
draft.ProductHierarchyID,
|
|
draft.UnitOfMeasureCode1,
|
|
draft.ItemAccountGrCode,
|
|
draft.ItemTaxGrCode,
|
|
draft.ItemPaymentPlanGrCode,
|
|
draft.ItemDiscountGrCode,
|
|
draft.ItemVendorGrCode,
|
|
draft.PromotionGroupCode,
|
|
draft.ProductCollectionGrCode,
|
|
draft.StorePriceLevelCode,
|
|
draft.PerceptionOfFashionCode,
|
|
draft.CommercialRoleCode,
|
|
draft.StoreCapacityLevelCode,
|
|
draft.CustomsTariffNumberCode,
|
|
draft.CompanyCode,
|
|
username,
|
|
)
|
|
return err
|
|
}
|
|
|
|
func UpdateOrderLinesTx(tx *sql.Tx, orderHeaderID string, lines []models.OrderProductionUpdateLine, username string) (int64, error) {
|
|
if len(lines) == 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
const chunkSize = 300
|
|
var updated int64
|
|
|
|
for i := 0; i < len(lines); i += chunkSize {
|
|
end := i + chunkSize
|
|
if end > len(lines) {
|
|
end = len(lines)
|
|
}
|
|
chunk := lines[i:end]
|
|
|
|
values := make([]string, 0, len(chunk))
|
|
args := make([]any, 0, len(chunk)*8+2)
|
|
paramPos := 1
|
|
for _, line := range chunk {
|
|
var itemDim1 any
|
|
if line.ItemDim1Code != nil {
|
|
itemDim1 = strings.TrimSpace(*line.ItemDim1Code)
|
|
}
|
|
values = append(values, fmt.Sprintf("(@p%d,@p%d,@p%d,@p%d,@p%d,@p%d,@p%d,@p%d)", paramPos, paramPos+1, paramPos+2, paramPos+3, paramPos+4, paramPos+5, paramPos+6, paramPos+7))
|
|
args = append(args,
|
|
strings.TrimSpace(line.OrderLineID),
|
|
line.NewItemCode,
|
|
line.NewColor,
|
|
itemDim1,
|
|
line.NewDim2,
|
|
line.NewDesc,
|
|
line.OldDueDate,
|
|
line.NewDueDate,
|
|
)
|
|
paramPos += 8
|
|
}
|
|
|
|
orderHeaderParam := paramPos
|
|
usernameParam := paramPos + 1
|
|
args = append(args, orderHeaderID, username)
|
|
|
|
query := fmt.Sprintf(`
|
|
SET NOCOUNT ON;
|
|
;WITH src (OrderLineID, NewItemCode, NewColor, ItemDim1Code, NewDim2, NewDesc, OldDueDate, NewDueDate) AS (
|
|
SELECT *
|
|
FROM (VALUES %s) AS v (OrderLineID, NewItemCode, NewColor, ItemDim1Code, NewDim2, NewDesc, OldDueDate, NewDueDate)
|
|
)
|
|
UPDATE l
|
|
SET
|
|
l.ItemCode = s.NewItemCode,
|
|
l.ColorCode = s.NewColor,
|
|
l.ItemDim1Code = COALESCE(s.ItemDim1Code, l.ItemDim1Code),
|
|
l.ItemDim2Code = s.NewDim2,
|
|
l.LineDescription = COALESCE(NULLIF(s.NewDesc,''), l.LineDescription),
|
|
l.DeliveryDate = CASE WHEN ISDATE(s.NewDueDate) = 1 THEN CAST(s.NewDueDate AS DATETIME) ELSE l.DeliveryDate END,
|
|
l.LastUpdatedUserName = @p%d,
|
|
l.LastUpdatedDate = GETDATE()
|
|
FROM dbo.trOrderLine l
|
|
JOIN src s
|
|
ON CAST(l.OrderLineID AS NVARCHAR(50)) = s.OrderLineID
|
|
WHERE l.OrderHeaderID = @p%d;
|
|
`, strings.Join(values, ","), usernameParam, orderHeaderParam)
|
|
|
|
chunkStart := time.Now()
|
|
res, execErr := tx.Exec(query, args...)
|
|
if execErr != nil {
|
|
log.Printf("[UpdateOrderLinesTx] ERROR orderHeaderID=%s chunk=%d-%d err=%v", orderHeaderID, i, end, execErr)
|
|
return updated, fmt.Errorf("update lines chunk failed chunkStart=%d chunkEnd=%d duration_ms=%d: %w", i, end, time.Since(chunkStart).Milliseconds(), execErr)
|
|
}
|
|
log.Printf("[UpdateOrderLinesTx] orderHeaderID=%s chunk=%d-%d duration_ms=%d", orderHeaderID, i, end, time.Since(chunkStart).Milliseconds())
|
|
|
|
if rows, rowsErr := res.RowsAffected(); rowsErr == nil {
|
|
updated += rows
|
|
}
|
|
}
|
|
return updated, nil
|
|
}
|
|
|
|
func UpdateOrderHeaderAverageDueDateTx(tx *sql.Tx, orderHeaderID string, averageDueDate *string, username string) error {
|
|
if averageDueDate == nil {
|
|
return nil
|
|
}
|
|
|
|
dueDate := strings.TrimSpace(*averageDueDate)
|
|
if dueDate != "" {
|
|
if _, err := time.Parse("2006-01-02", dueDate); err != nil {
|
|
return fmt.Errorf("invalid header average due date %q: %w", dueDate, err)
|
|
}
|
|
}
|
|
|
|
_, err := tx.Exec(`
|
|
UPDATE dbo.trOrderHeader
|
|
SET
|
|
AverageDueDate = CASE WHEN @p1 = '' THEN NULL ELSE CAST(@p1 AS DATETIME) END,
|
|
LastUpdatedUserName = @p2,
|
|
LastUpdatedDate = GETDATE()
|
|
WHERE OrderHeaderID = @p3;
|
|
`, dueDate, username, orderHeaderID)
|
|
return err
|
|
}
|
|
|
|
type sqlQueryRower interface {
|
|
QueryRow(query string, args ...any) *sql.Row
|
|
}
|
|
|
|
type plannedProductionBarcode struct {
|
|
Barcode string
|
|
BarcodeTypeCode string
|
|
ItemTypeCode int16
|
|
ItemCode string
|
|
ColorCode string
|
|
ItemDim1Code string
|
|
ItemDim2Code string
|
|
ItemDim3Code string
|
|
}
|
|
|
|
func barcodeTypeExists(q sqlQueryRower, barcodeTypeCode string) (bool, error) {
|
|
var exists int
|
|
err := q.QueryRow(`
|
|
SELECT TOP 1 1
|
|
FROM dbo.cdBarcodeType
|
|
WHERE BarcodeTypeCode = @p1
|
|
`, strings.TrimSpace(barcodeTypeCode)).Scan(&exists)
|
|
if err == sql.ErrNoRows {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func barcodeExists(q sqlQueryRower, barcode string) (bool, error) {
|
|
var exists int
|
|
err := q.QueryRow(`
|
|
SELECT TOP 1 1
|
|
FROM dbo.prItemBarcode WITH (UPDLOCK, HOLDLOCK)
|
|
WHERE Barcode = @p1
|
|
`, strings.TrimSpace(barcode)).Scan(&exists)
|
|
if err == sql.ErrNoRows {
|
|
return false, nil
|
|
}
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func existingVariantBarcode(
|
|
q sqlQueryRower,
|
|
barcodeTypeCode string,
|
|
itemTypeCode int16,
|
|
itemCode string,
|
|
colorCode string,
|
|
dim1 string,
|
|
dim2 string,
|
|
dim3 string,
|
|
) (string, bool, error) {
|
|
|
|
var barcode string
|
|
|
|
err := q.QueryRow(`
|
|
SELECT TOP 1 LTRIM(RTRIM(ISNULL(Barcode, '')))
|
|
FROM dbo.prItemBarcode WITH (UPDLOCK, HOLDLOCK)
|
|
WHERE BarcodeTypeCode = @p1
|
|
AND ItemTypeCode = @p2
|
|
AND ISNULL(LTRIM(RTRIM(ItemCode)), '') = @p3
|
|
AND ISNULL(LTRIM(RTRIM(ColorCode)), '') = @p4
|
|
AND ISNULL(LTRIM(RTRIM(ItemDim1Code)), '') = @p5
|
|
AND ISNULL(LTRIM(RTRIM(ItemDim2Code)), '') = @p6
|
|
AND ISNULL(LTRIM(RTRIM(ItemDim3Code)), '') = @p7
|
|
AND ISNULL(LTRIM(RTRIM(UnitOfMeasureCode)), '') = 'AD'
|
|
ORDER BY
|
|
CASE
|
|
WHEN ISNUMERIC(Barcode) = 1
|
|
THEN CAST(Barcode AS BIGINT)
|
|
ELSE 0
|
|
END DESC,
|
|
Barcode DESC
|
|
`,
|
|
strings.TrimSpace(barcodeTypeCode),
|
|
itemTypeCode,
|
|
strings.TrimSpace(itemCode),
|
|
strings.TrimSpace(colorCode),
|
|
strings.TrimSpace(dim1),
|
|
strings.TrimSpace(dim2),
|
|
strings.TrimSpace(dim3),
|
|
).Scan(&barcode)
|
|
|
|
if err == sql.ErrNoRows {
|
|
return "", false, nil
|
|
}
|
|
|
|
if err != nil {
|
|
return "", false, err
|
|
}
|
|
|
|
return strings.TrimSpace(barcode), true, nil
|
|
}
|
|
func maxNumericBarcode(q sqlQueryRower) (int64, error) {
|
|
|
|
var maxBarcode int64
|
|
|
|
err := q.QueryRow(`
|
|
SELECT ISNULL(MAX(
|
|
CASE
|
|
WHEN ISNUMERIC(Barcode) = 1
|
|
THEN CAST(Barcode AS BIGINT)
|
|
ELSE NULL
|
|
END
|
|
), 0)
|
|
FROM dbo.prItemBarcode WITH (UPDLOCK, HOLDLOCK)
|
|
`).Scan(&maxBarcode)
|
|
|
|
return maxBarcode, err
|
|
}
|
|
|
|
func ValidateProductionBarcodePlan(q sqlQueryRower, variants []models.OrderProductionMissingVariant, barcodeTypeCode string) ([]models.OrderProductionBarcodeValidation, error) {
|
|
typeCode := strings.ToUpper(strings.TrimSpace(barcodeTypeCode))
|
|
if len(variants) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
validations := make([]models.OrderProductionBarcodeValidation, 0)
|
|
typeExists, err := barcodeTypeExists(q, typeCode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !typeExists {
|
|
validations = append(validations, models.OrderProductionBarcodeValidation{
|
|
Code: "invalid_barcode_type",
|
|
Message: fmt.Sprintf("Barkod tipi bulunamadi: %s", typeCode),
|
|
BarcodeTypeCode: typeCode,
|
|
})
|
|
return validations, nil
|
|
}
|
|
|
|
sorted := append([]models.OrderProductionMissingVariant(nil), variants...)
|
|
sort.Slice(sorted, func(i, j int) bool {
|
|
left := sorted[i]
|
|
right := sorted[j]
|
|
leftKey := fmt.Sprintf("%05d|%s|%s|%s|%s|%s", left.ItemTypeCode, left.ItemCode, left.ColorCode, left.ItemDim1Code, left.ItemDim2Code, left.ItemDim3Code)
|
|
rightKey := fmt.Sprintf("%05d|%s|%s|%s|%s|%s", right.ItemTypeCode, right.ItemCode, right.ColorCode, right.ItemDim1Code, right.ItemDim2Code, right.ItemDim3Code)
|
|
return leftKey < rightKey
|
|
})
|
|
|
|
maxBarcode, err := maxNumericBarcode(q)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
nextOffset := int64(0)
|
|
planned := make(map[string]struct{}, len(sorted))
|
|
for _, variant := range sorted {
|
|
existingBarcode, exists, err := existingVariantBarcode(q, typeCode, variant.ItemTypeCode, variant.ItemCode, variant.ColorCode, variant.ItemDim1Code, variant.ItemDim2Code, variant.ItemDim3Code)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if exists && existingBarcode != "" {
|
|
continue
|
|
}
|
|
|
|
nextOffset++
|
|
barcode := strconv.FormatInt(maxBarcode+nextOffset, 10)
|
|
if _, duplicated := planned[barcode]; duplicated {
|
|
validations = append(validations, models.OrderProductionBarcodeValidation{
|
|
Code: "barcode_duplicate_in_plan",
|
|
Message: fmt.Sprintf("Planlanan barkod ayni istekte birden fazla kez olusuyor: %s", barcode),
|
|
Barcode: barcode,
|
|
BarcodeTypeCode: typeCode,
|
|
ItemTypeCode: variant.ItemTypeCode,
|
|
ItemCode: strings.TrimSpace(variant.ItemCode),
|
|
ColorCode: strings.TrimSpace(variant.ColorCode),
|
|
ItemDim1Code: strings.TrimSpace(variant.ItemDim1Code),
|
|
ItemDim2Code: strings.TrimSpace(variant.ItemDim2Code),
|
|
ItemDim3Code: strings.TrimSpace(variant.ItemDim3Code),
|
|
})
|
|
continue
|
|
}
|
|
planned[barcode] = struct{}{}
|
|
|
|
inUse, err := barcodeExists(q, barcode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if inUse {
|
|
validations = append(validations, models.OrderProductionBarcodeValidation{
|
|
Code: "barcode_in_use",
|
|
Message: fmt.Sprintf("Barkod daha once kullanilmis: %s (%s / %s / %s / %s)", barcode, strings.TrimSpace(variant.ItemCode), strings.TrimSpace(variant.ColorCode), strings.TrimSpace(variant.ItemDim1Code), strings.TrimSpace(variant.ItemDim2Code)),
|
|
Barcode: barcode,
|
|
BarcodeTypeCode: typeCode,
|
|
ItemTypeCode: variant.ItemTypeCode,
|
|
ItemCode: strings.TrimSpace(variant.ItemCode),
|
|
ColorCode: strings.TrimSpace(variant.ColorCode),
|
|
ItemDim1Code: strings.TrimSpace(variant.ItemDim1Code),
|
|
ItemDim2Code: strings.TrimSpace(variant.ItemDim2Code),
|
|
ItemDim3Code: strings.TrimSpace(variant.ItemDim3Code),
|
|
})
|
|
}
|
|
}
|
|
|
|
return validations, nil
|
|
}
|
|
|
|
func InsertItemBarcodesTx(tx *sql.Tx, orderHeaderID string, lines []models.OrderProductionUpdateLine, username string) (int64, error) {
|
|
start := time.Now()
|
|
|
|
if len(lines) == 0 {
|
|
log.Printf("[InsertItemBarcodesTx] lines=0 inserted=0 duration_ms=0")
|
|
return 0, nil
|
|
}
|
|
|
|
lineIDs := make([]string, 0, len(lines))
|
|
seen := make(map[string]struct{}, len(lines))
|
|
|
|
for _, line := range lines {
|
|
lineID := strings.TrimSpace(line.OrderLineID)
|
|
if lineID == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[lineID]; ok {
|
|
continue
|
|
}
|
|
seen[lineID] = struct{}{}
|
|
lineIDs = append(lineIDs, lineID)
|
|
}
|
|
|
|
if len(lineIDs) == 0 {
|
|
log.Printf("[InsertItemBarcodesTx] uniqueLineIDs=0 inserted=0")
|
|
return 0, nil
|
|
}
|
|
|
|
const chunkSize = 900
|
|
var inserted int64
|
|
|
|
for i := 0; i < len(lineIDs); i += chunkSize {
|
|
|
|
end := i + chunkSize
|
|
if end > len(lineIDs) {
|
|
end = len(lineIDs)
|
|
}
|
|
|
|
chunk := lineIDs[i:end]
|
|
|
|
values := make([]string, 0, len(chunk))
|
|
args := make([]any, 0, len(chunk)+2)
|
|
|
|
paramPos := 1
|
|
|
|
for _, lineID := range chunk {
|
|
values = append(values, fmt.Sprintf("(@p%d)", paramPos))
|
|
args = append(args, lineID)
|
|
paramPos++
|
|
}
|
|
|
|
orderHeaderParam := paramPos
|
|
usernameParam := paramPos + 1
|
|
|
|
args = append(args, orderHeaderID, username)
|
|
|
|
query := fmt.Sprintf(`
|
|
SET NOCOUNT ON
|
|
;
|
|
|
|
WITH srcLine (OrderLineID) AS (
|
|
SELECT *
|
|
FROM (VALUES %s) v(OrderLineID)
|
|
),
|
|
|
|
src AS (
|
|
SELECT DISTINCT
|
|
l.ItemTypeCode,
|
|
UPPER(LTRIM(RTRIM(ISNULL(l.ItemCode,'')))) ItemCode,
|
|
UPPER(LTRIM(RTRIM(ISNULL(l.ColorCode,'')))) ColorCode,
|
|
UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim1Code,'')))) ItemDim1Code,
|
|
UPPER(LTRIM(RTRIM(ISNULL(l.ItemDim2Code,'')))) ItemDim2Code,
|
|
CAST('' AS NVARCHAR(50)) ItemDim3Code
|
|
FROM dbo.trOrderLine l
|
|
JOIN srcLine s
|
|
ON CAST(l.OrderLineID AS NVARCHAR(50)) = s.OrderLineID
|
|
WHERE l.OrderHeaderID = @p%d
|
|
AND NULLIF(LTRIM(RTRIM(ISNULL(l.ItemCode,''))), '') IS NOT NULL
|
|
),
|
|
|
|
missing AS (
|
|
SELECT
|
|
s.*,
|
|
ROW_NUMBER() OVER (
|
|
ORDER BY
|
|
s.ItemCode,
|
|
s.ColorCode,
|
|
s.ItemDim1Code,
|
|
s.ItemDim2Code,
|
|
s.ItemDim3Code
|
|
) RowNo
|
|
FROM src s
|
|
WHERE NOT EXISTS (
|
|
SELECT 1
|
|
FROM dbo.prItemBarcode b
|
|
WHERE b.BarcodeTypeCode = 'BAGGI3'
|
|
AND b.UnitOfMeasureCode = 'AD'
|
|
AND b.ItemTypeCode = s.ItemTypeCode
|
|
AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemCode,'')))) = s.ItemCode
|
|
AND UPPER(LTRIM(RTRIM(ISNULL(b.ColorCode,'')))) = s.ColorCode
|
|
AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim1Code,'')))) = s.ItemDim1Code
|
|
AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim2Code,'')))) = s.ItemDim2Code
|
|
AND UPPER(LTRIM(RTRIM(ISNULL(b.ItemDim3Code,'')))) = s.ItemDim3Code
|
|
)
|
|
)
|
|
|
|
INSERT INTO dbo.prItemBarcode
|
|
(
|
|
Barcode,
|
|
BarcodeTypeCode,
|
|
ItemTypeCode,
|
|
ItemCode,
|
|
ColorCode,
|
|
ItemDim1Code,
|
|
ItemDim2Code,
|
|
ItemDim3Code,
|
|
UnitOfMeasureCode,
|
|
Qty,
|
|
CreatedUserName,
|
|
CreatedDate,
|
|
LastUpdatedUserName,
|
|
LastUpdatedDate,
|
|
RowGuid
|
|
)
|
|
|
|
SELECT
|
|
CAST(seed.MaxBarcode + m.RowNo AS NVARCHAR(50)),
|
|
'BAGGI3',
|
|
m.ItemTypeCode,
|
|
m.ItemCode,
|
|
m.ColorCode,
|
|
m.ItemDim1Code,
|
|
m.ItemDim2Code,
|
|
m.ItemDim3Code,
|
|
'AD',
|
|
1,
|
|
@p%d,
|
|
GETDATE(),
|
|
@p%d,
|
|
GETDATE(),
|
|
NEWID()
|
|
|
|
FROM missing m
|
|
|
|
CROSS JOIN (
|
|
SELECT ISNULL(MAX(
|
|
CASE
|
|
WHEN ISNUMERIC(Barcode)=1
|
|
THEN CAST(Barcode AS BIGINT)
|
|
ELSE NULL
|
|
END
|
|
),0) AS MaxBarcode
|
|
FROM dbo.prItemBarcode
|
|
) seed
|
|
`, strings.Join(values, ","), orderHeaderParam, usernameParam, usernameParam)
|
|
|
|
chunkStart := time.Now()
|
|
|
|
res, err := tx.Exec(query, args...)
|
|
|
|
if err != nil {
|
|
log.Printf("[InsertItemBarcodesTx] ERROR chunk=%d-%d err=%v", i, end, err)
|
|
return inserted, err
|
|
}
|
|
|
|
rows, _ := res.RowsAffected()
|
|
|
|
inserted += rows
|
|
|
|
log.Printf(
|
|
"[InsertItemBarcodesTx] chunk=%d-%d inserted=%d cumulative=%d duration_ms=%d",
|
|
i,
|
|
end,
|
|
rows,
|
|
inserted,
|
|
time.Since(chunkStart).Milliseconds(),
|
|
)
|
|
}
|
|
|
|
log.Printf(
|
|
"[InsertItemBarcodesTx] lines=%d unique=%d inserted=%d duration_ms=%d",
|
|
len(lines),
|
|
len(lineIDs),
|
|
inserted,
|
|
time.Since(start).Milliseconds(),
|
|
)
|
|
|
|
return inserted, nil
|
|
}
|
|
|
|
func UpsertItemAttributesTx(tx *sql.Tx, attrs []models.OrderProductionItemAttributeRow, username string) (int64, error) {
|
|
start := time.Now()
|
|
if len(attrs) == 0 {
|
|
log.Printf("[UpsertItemAttributesTx] attrs=0 affected=0 duration_ms=0")
|
|
return 0, nil
|
|
}
|
|
|
|
// SQL Server parameter limiti (2100) nedeniyle batch'li set-based upsert kullanilir.
|
|
const chunkSize = 400 // 400 * 4 param + 1 username = 1601
|
|
var affected int64
|
|
for i := 0; i < len(attrs); i += chunkSize {
|
|
end := i + chunkSize
|
|
if end > len(attrs) {
|
|
end = len(attrs)
|
|
}
|
|
chunk := attrs[i:end]
|
|
|
|
values := make([]string, 0, len(chunk))
|
|
args := make([]any, 0, len(chunk)*4+1)
|
|
paramPos := 1
|
|
for _, a := range chunk {
|
|
values = append(values, fmt.Sprintf("(@p%d,@p%d,@p%d,@p%d)", paramPos, paramPos+1, paramPos+2, paramPos+3))
|
|
args = append(args, a.ItemTypeCode, a.ItemCode, a.AttributeTypeCode, a.AttributeCode)
|
|
paramPos += 4
|
|
}
|
|
usernameParam := paramPos
|
|
args = append(args, username)
|
|
|
|
query := fmt.Sprintf(`
|
|
WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS (
|
|
SELECT *
|
|
FROM (VALUES %s) AS v (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode)
|
|
)
|
|
UPDATE tgt
|
|
SET
|
|
tgt.AttributeCode = src.AttributeCode,
|
|
tgt.LastUpdatedUserName = @p%d,
|
|
tgt.LastUpdatedDate = GETDATE()
|
|
FROM dbo.prItemAttribute tgt
|
|
JOIN src
|
|
ON src.ItemTypeCode = tgt.ItemTypeCode
|
|
AND src.ItemCode = tgt.ItemCode
|
|
AND src.AttributeTypeCode = tgt.AttributeTypeCode;
|
|
|
|
WITH src (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode) AS (
|
|
SELECT *
|
|
FROM (VALUES %s) AS v (ItemTypeCode, ItemCode, AttributeTypeCode, AttributeCode)
|
|
)
|
|
INSERT INTO dbo.prItemAttribute (
|
|
ItemTypeCode,
|
|
ItemCode,
|
|
AttributeTypeCode,
|
|
AttributeCode,
|
|
CreatedUserName,
|
|
CreatedDate,
|
|
LastUpdatedUserName,
|
|
LastUpdatedDate,
|
|
RowGuid
|
|
)
|
|
SELECT
|
|
src.ItemTypeCode,
|
|
src.ItemCode,
|
|
src.AttributeTypeCode,
|
|
src.AttributeCode,
|
|
@p%d,
|
|
GETDATE(),
|
|
@p%d,
|
|
GETDATE(),
|
|
NEWID()
|
|
FROM src
|
|
LEFT JOIN dbo.prItemAttribute tgt
|
|
ON src.ItemTypeCode = tgt.ItemTypeCode
|
|
AND src.ItemCode = tgt.ItemCode
|
|
AND src.AttributeTypeCode = tgt.AttributeTypeCode
|
|
WHERE tgt.ItemCode IS NULL;
|
|
`, strings.Join(values, ","), usernameParam, strings.Join(values, ","), usernameParam, usernameParam)
|
|
|
|
chunkStart := time.Now()
|
|
res, err := tx.Exec(query, args...)
|
|
if err != nil {
|
|
log.Printf("[UpsertItemAttributesTx] ERROR chunk=%d-%d err=%v", i, end, err)
|
|
return affected, fmt.Errorf("upsert item attributes chunk failed chunkStart=%d chunkEnd=%d duration_ms=%d: %w", i, end, time.Since(chunkStart).Milliseconds(), err)
|
|
}
|
|
chunkAffected, _ := res.RowsAffected()
|
|
affected += chunkAffected
|
|
log.Printf("[UpsertItemAttributesTx] chunk=%d-%d chunkAffected=%d cumulative=%d duration_ms=%d",
|
|
i, end, chunkAffected, affected, time.Since(chunkStart).Milliseconds())
|
|
}
|
|
log.Printf("[UpsertItemAttributesTx] attrs=%d affected=%d duration_ms=%d",
|
|
len(attrs), affected, time.Since(start).Milliseconds())
|
|
return affected, nil
|
|
}
|
|
|
|
func GetOrderProductionLookupOptions(mssql *sql.DB) (models.OrderProductionCdItemLookups, error) {
|
|
out := models.OrderProductionCdItemLookups{}
|
|
|
|
queryPairs := []struct {
|
|
Name string
|
|
Query string
|
|
Target *[]models.OrderProductionLookupOption
|
|
}{
|
|
{"ItemDimTypeCodes", `SELECT
|
|
CAST(t.ItemDimTypeCode AS NVARCHAR(50)) AS Code,
|
|
ISNULL(d.ItemDimTypeDescription, CAST(t.ItemDimTypeCode AS NVARCHAR(50))) AS [Description]
|
|
FROM dbo.bsItemDimType t WITH(NOLOCK)
|
|
LEFT JOIN dbo.bsItemDimTypeDesc d WITH(NOLOCK)
|
|
ON d.ItemDimTypeCode = t.ItemDimTypeCode
|
|
AND d.LangCode = 'TR'
|
|
WHERE ISNULL(t.IsBlocked, 0) = 0
|
|
ORDER BY t.ItemDimTypeCode`, &out.ItemDimTypeCodes},
|
|
{"ProductTypeCodes", `SELECT DISTINCT CAST(ProductTypeCode AS NVARCHAR(50)) AS Code, CAST(ProductTypeCode AS NVARCHAR(50)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE ProductTypeCode IS NOT NULL ORDER BY Code`, &out.ProductTypeCodes},
|
|
{"ProductHierarchyIDs", `SELECT
|
|
CAST(h.ProductHierarchyID AS NVARCHAR(50)) AS Code,
|
|
LTRIM(RTRIM(
|
|
CONCAT(
|
|
CAST(ISNULL(h.ProductHierarchyLevelCode01, 0) AS NVARCHAR(50)),
|
|
CASE
|
|
WHEN ISNULL(d.ProductHierarchyLevelDescription, '') <> '' THEN CONCAT(' - ', d.ProductHierarchyLevelDescription)
|
|
ELSE ''
|
|
END
|
|
)
|
|
)) AS [Description]
|
|
FROM dbo.dfProductHierarchy h WITH(NOLOCK)
|
|
LEFT JOIN dbo.cdProductHierarchyLevelDesc d WITH(NOLOCK)
|
|
ON d.ProductHierarchyLevelCode = h.ProductHierarchyLevelCode01
|
|
AND d.LangCode = 'TR'
|
|
ORDER BY h.ProductHierarchyID`, &out.ProductHierarchyIDs},
|
|
{"UnitOfMeasureCode1List", `SELECT DISTINCT CAST(UnitOfMeasureCode1 AS NVARCHAR(50)) AS Code, CAST(UnitOfMeasureCode1 AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(UnitOfMeasureCode1 AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.UnitOfMeasureCode1List},
|
|
{"ItemAccountGrCodes", `SELECT DISTINCT CAST(ItemAccountGrCode AS NVARCHAR(50)) AS Code, CAST(ItemAccountGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ItemAccountGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ItemAccountGrCodes},
|
|
{"ItemTaxGrCodes", `SELECT DISTINCT CAST(ItemTaxGrCode AS NVARCHAR(50)) AS Code, CAST(ItemTaxGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ItemTaxGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ItemTaxGrCodes},
|
|
{"ItemPaymentPlanGrCodes", `SELECT DISTINCT CAST(ItemPaymentPlanGrCode AS NVARCHAR(50)) AS Code, CAST(ItemPaymentPlanGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ItemPaymentPlanGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ItemPaymentPlanGrCodes},
|
|
{"ItemDiscountGrCodes", `SELECT DISTINCT CAST(ItemDiscountGrCode AS NVARCHAR(50)) AS Code, CAST(ItemDiscountGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ItemDiscountGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ItemDiscountGrCodes},
|
|
{"ItemVendorGrCodes", `SELECT DISTINCT CAST(ItemVendorGrCode AS NVARCHAR(50)) AS Code, CAST(ItemVendorGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ItemVendorGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ItemVendorGrCodes},
|
|
{"PromotionGroupCodes", `SELECT DISTINCT CAST(PromotionGroupCode AS NVARCHAR(50)) AS Code, CAST(PromotionGroupCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(PromotionGroupCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.PromotionGroupCodes},
|
|
{"ProductCollectionGrCodes", `SELECT DISTINCT CAST(ProductCollectionGrCode AS NVARCHAR(50)) AS Code, CAST(ProductCollectionGrCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(ProductCollectionGrCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.ProductCollectionGrCodes},
|
|
{"StorePriceLevelCodes", `SELECT DISTINCT CAST(StorePriceLevelCode AS NVARCHAR(50)) AS Code, CAST(StorePriceLevelCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(StorePriceLevelCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.StorePriceLevelCodes},
|
|
{"PerceptionOfFashionCodes", `SELECT DISTINCT CAST(PerceptionOfFashionCode AS NVARCHAR(50)) AS Code, CAST(PerceptionOfFashionCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(PerceptionOfFashionCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.PerceptionOfFashionCodes},
|
|
{"CommercialRoleCodes", `SELECT DISTINCT CAST(CommercialRoleCode AS NVARCHAR(50)) AS Code, CAST(CommercialRoleCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(CommercialRoleCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.CommercialRoleCodes},
|
|
{"StoreCapacityLevelCodes", `SELECT DISTINCT CAST(StoreCapacityLevelCode AS NVARCHAR(50)) AS Code, CAST(StoreCapacityLevelCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(StoreCapacityLevelCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.StoreCapacityLevelCodes},
|
|
{"CustomsTariffNumbers", `SELECT DISTINCT CAST(CustomsTariffNumberCode AS NVARCHAR(50)) AS Code, CAST(CustomsTariffNumberCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(CustomsTariffNumberCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.CustomsTariffNumbers},
|
|
{"CompanyCodes", `SELECT DISTINCT CAST(CompanyCode AS NVARCHAR(50)) AS Code, CAST(CompanyCode AS NVARCHAR(200)) AS [Description] FROM dbo.cdItem WITH(NOLOCK) WHERE NULLIF(LTRIM(RTRIM(CAST(CompanyCode AS NVARCHAR(200)))), '') IS NOT NULL ORDER BY Code`, &out.CompanyCodes},
|
|
}
|
|
|
|
for _, pair := range queryPairs {
|
|
start := time.Now()
|
|
log.Printf("[GetOrderProductionLookupOptions] executing [%s]", pair.Name)
|
|
rows, err := mssql.Query(pair.Query)
|
|
if err != nil {
|
|
return out, fmt.Errorf("lookup query failed [%s]: %w", pair.Name, err)
|
|
}
|
|
|
|
list := make([]models.OrderProductionLookupOption, 0, 64)
|
|
for rows.Next() {
|
|
var item models.OrderProductionLookupOption
|
|
if err := rows.Scan(&item.Code, &item.Description); err != nil {
|
|
rows.Close()
|
|
return out, fmt.Errorf("lookup scan failed [%s]: %w", pair.Name, err)
|
|
}
|
|
item.Code = strings.TrimSpace(item.Code)
|
|
item.Description = strings.TrimSpace(item.Description)
|
|
list = append(list, item)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
rows.Close()
|
|
return out, fmt.Errorf("lookup rows failed [%s]: %w", pair.Name, err)
|
|
}
|
|
rows.Close()
|
|
log.Printf("[GetOrderProductionLookupOptions] ok [%s] count=%d duration=%s", pair.Name, len(list), time.Since(start))
|
|
*pair.Target = list
|
|
}
|
|
|
|
return out, nil
|
|
}
|