Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -22,6 +22,8 @@ type mkCariBakiyeLine struct {
|
||||
PislemTipi string
|
||||
YerelBakiye float64
|
||||
Bakiye float64
|
||||
VadeGun float64
|
||||
VadeBelgeGun float64
|
||||
}
|
||||
|
||||
type cariMeta struct {
|
||||
@@ -320,7 +322,9 @@ func loadBalanceLines(ctx context.Context, selectedDate, cariSearch string) ([]m
|
||||
SirketKodu,
|
||||
PislemTipi,
|
||||
YerelBakiye,
|
||||
Bakiye
|
||||
Bakiye,
|
||||
CAST(0 AS DECIMAL(18,4)) AS Vade_Gun,
|
||||
CAST(0 AS DECIMAL(18,4)) AS Vade_BelgeTarihi_Gun
|
||||
FROM dbo.MK_CARI_BAKIYE_LIST(@SonTarih)
|
||||
WHERE (@CariSearch = '' OR CariKodu LIKE '%' + @CariSearch + '%')
|
||||
`
|
||||
@@ -345,6 +349,8 @@ func loadBalanceLines(ctx context.Context, selectedDate, cariSearch string) ([]m
|
||||
&r.PislemTipi,
|
||||
&r.YerelBakiye,
|
||||
&r.Bakiye,
|
||||
&r.VadeGun,
|
||||
&r.VadeBelgeGun,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -15,30 +15,59 @@ import (
|
||||
|
||||
func GetStatementAging(params models.StatementAgingParams) ([]map[string]interface{}, error) {
|
||||
accountCode := normalizeMasterAccountCode(params.AccountCode)
|
||||
if strings.TrimSpace(accountCode) == "" {
|
||||
return nil, fmt.Errorf("accountcode is required")
|
||||
}
|
||||
if strings.TrimSpace(params.EndDate) == "" {
|
||||
return nil, fmt.Errorf("enddate is required")
|
||||
}
|
||||
|
||||
useType2, useType3 := resolveUseTypes(params.Parislemler)
|
||||
endDate, _ := time.Parse("2006-01-02", strings.TrimSpace(params.EndDate))
|
||||
endDateText := strings.TrimSpace(params.EndDate)
|
||||
if endDateText == "" {
|
||||
endDateText = time.Now().Format("2006-01-02")
|
||||
}
|
||||
endDate, _ := time.Parse("2006-01-02", endDateText)
|
||||
|
||||
cariFilter := ""
|
||||
if strings.TrimSpace(accountCode) != "" {
|
||||
cariFilter = strings.TrimSpace(accountCode)
|
||||
}
|
||||
|
||||
rows, err := db.MssqlDB.Query(`
|
||||
EXEC dbo.SP_FIFO_MATCH_FINAL
|
||||
@Cari8 = @Cari8,
|
||||
@SonTarih = @SonTarih,
|
||||
@UseType2 = @UseType2,
|
||||
@UseType3 = @UseType3;
|
||||
SELECT TOP (100)
|
||||
Cari8 = LEFT(LTRIM(RTRIM(CariKodu)), 8),
|
||||
CariDetay = LTRIM(RTRIM(CariKodu)),
|
||||
FaturaCari = LTRIM(RTRIM(CariKodu)),
|
||||
OdemeCari = LTRIM(RTRIM(CariKodu)),
|
||||
FaturaRef = CAST(NULL AS NVARCHAR(50)),
|
||||
OdemeRef = CAST(NULL AS NVARCHAR(50)),
|
||||
FaturaTarihi = CAST(NULL AS DATE),
|
||||
OdemeTarihi = CAST(NULL AS DATE),
|
||||
OdemeDocDate = CAST(NULL AS DATE),
|
||||
EslesenTutar = CAST(Bakiye AS DECIMAL(18,2)),
|
||||
GunSayisi = CAST(Vade_Gun AS DECIMAL(18,2)),
|
||||
GunSayisi_DocDate = CAST(Vade_BelgeTarihi_Gun AS DECIMAL(18,2)),
|
||||
Aciklama = CAST('AcikKalem' AS NVARCHAR(30)),
|
||||
DocCurrencyCode = LTRIM(RTRIM(CariDoviz)),
|
||||
PislemTipi,
|
||||
SirketKodu,
|
||||
CurrAccTypeCode,
|
||||
Bakiye,
|
||||
Vade_Gun,
|
||||
Vade_BelgeTarihi_Gun,
|
||||
SonTarih,
|
||||
HesaplamaTarihi
|
||||
FROM dbo.CARI_BAKIYE_GUN_CACHE
|
||||
WHERE
|
||||
(
|
||||
(@UseType2 = 1 AND PislemTipi = '1_2')
|
||||
OR
|
||||
(@UseType3 = 1 AND PislemTipi = '1_3')
|
||||
)
|
||||
AND (@CariFilter = '' OR LTRIM(RTRIM(CariKodu)) LIKE @CariFilter + '%')
|
||||
ORDER BY CariKodu, CariDoviz, PislemTipi;
|
||||
`,
|
||||
sql.Named("Cari8", accountCode),
|
||||
sql.Named("SonTarih", params.EndDate),
|
||||
sql.Named("UseType2", useType2),
|
||||
sql.Named("UseType3", useType3),
|
||||
sql.Named("CariFilter", cariFilter),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("SP_FIFO_MATCH_FINAL query error: %w", err)
|
||||
return nil, fmt.Errorf("CARI_BAKIYE_GUN_CACHE query error: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
|
||||
244
svc/queries/statement_aging_balance_list.go
Normal file
244
svc/queries/statement_aging_balance_list.go
Normal file
@@ -0,0 +1,244 @@
|
||||
package queries
|
||||
|
||||
import (
|
||||
"bssapp-backend/models"
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"bssapp-backend/db"
|
||||
)
|
||||
|
||||
func GetStatementAgingBalanceList(ctx context.Context, params models.CustomerBalanceListParams) ([]models.CustomerBalanceListRow, error) {
|
||||
selectedDate := strings.TrimSpace(params.SelectedDate)
|
||||
if selectedDate == "" {
|
||||
selectedDate = time.Now().Format("2006-01-02")
|
||||
}
|
||||
|
||||
lines, err := loadAgingBalanceLines(ctx, strings.TrimSpace(params.CariSearch))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metaMap, err := loadCariMetaMap(ctx, lines)
|
||||
if err != nil {
|
||||
log.Printf("statement_aging_balance: cari meta query failed, fallback without meta: %v", err)
|
||||
metaMap = map[string]cariMeta{}
|
||||
}
|
||||
|
||||
masterMetaMap, err := loadMasterCariMetaMap(ctx, lines)
|
||||
if err != nil {
|
||||
log.Printf("statement_aging_balance: master cari meta query failed, fallback without master meta: %v", err)
|
||||
masterMetaMap = map[string]masterCariMeta{}
|
||||
}
|
||||
|
||||
companyMap, err := loadCompanyMap(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
glMap, err := loadGLAccountMap(ctx, lines)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rateMap, err := loadNearestTryRates(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
usdTry := rateMap["USD"]
|
||||
if usdTry <= 0 {
|
||||
usdTry = 1
|
||||
}
|
||||
|
||||
filters := buildFilters(params)
|
||||
agg := make(map[string]*models.CustomerBalanceListRow, len(lines))
|
||||
weightMap := make(map[string]float64, len(lines))
|
||||
vadeSumMap := make(map[string]float64, len(lines))
|
||||
vadeBelgeSumMap := make(map[string]float64, len(lines))
|
||||
|
||||
for _, ln := range lines {
|
||||
cari := strings.TrimSpace(ln.CariKodu)
|
||||
if cari == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
curr := strings.ToUpper(strings.TrimSpace(ln.CariDoviz))
|
||||
if curr == "" {
|
||||
curr = "TRY"
|
||||
}
|
||||
|
||||
meta := metaMap[metaKey(ln.CurrAccTypeCode, cari)]
|
||||
meta.MuhasebeKodu = glMap[glKey(ln.CurrAccTypeCode, cari, ln.SirketKodu)]
|
||||
meta.SirketDetay = companyMap[ln.SirketKodu]
|
||||
master := deriveMasterCari(cari)
|
||||
mm := masterMetaMap[master]
|
||||
|
||||
if strings.TrimSpace(mm.Kanal1) != "" {
|
||||
meta.Kanal1 = mm.Kanal1
|
||||
}
|
||||
if strings.TrimSpace(mm.Piyasa) != "" {
|
||||
meta.Piyasa = mm.Piyasa
|
||||
}
|
||||
if strings.TrimSpace(mm.Temsilci) != "" {
|
||||
meta.Temsilci = mm.Temsilci
|
||||
}
|
||||
if strings.TrimSpace(mm.Ulke) != "" {
|
||||
meta.Ulke = mm.Ulke
|
||||
}
|
||||
if strings.TrimSpace(mm.Il) != "" {
|
||||
meta.Il = mm.Il
|
||||
}
|
||||
if strings.TrimSpace(mm.Ilce) != "" {
|
||||
meta.Ilce = mm.Ilce
|
||||
}
|
||||
if strings.TrimSpace(mm.RiskDurumu) != "" {
|
||||
meta.RiskDurumu = mm.RiskDurumu
|
||||
}
|
||||
|
||||
if !filters.matchLine(ln.PislemTipi, meta) {
|
||||
continue
|
||||
}
|
||||
|
||||
key := strconv.Itoa(ln.CurrAccTypeCode) + "|" + cari + "|" + curr + "|" + strconv.Itoa(ln.SirketKodu)
|
||||
row, ok := agg[key]
|
||||
if !ok {
|
||||
row = &models.CustomerBalanceListRow{
|
||||
CariIlkGrup: meta.Kanal1,
|
||||
Piyasa: meta.Piyasa,
|
||||
Temsilci: meta.Temsilci,
|
||||
Sirket: strconv.Itoa(ln.SirketKodu),
|
||||
AnaCariKodu: master,
|
||||
AnaCariAdi: firstNonEmpty(mm.CariDetay, meta.CariDetay),
|
||||
CariKodu: cari,
|
||||
CariDetay: meta.CariDetay,
|
||||
CariTip: meta.CariTip,
|
||||
Kanal1: meta.Kanal1,
|
||||
Ozellik03: meta.RiskDurumu,
|
||||
Ozellik05: meta.Ulke,
|
||||
Ozellik06: meta.Il,
|
||||
Ozellik07: meta.Ilce,
|
||||
Il: meta.Il,
|
||||
Ilce: meta.Ilce,
|
||||
MuhasebeKodu: meta.MuhasebeKodu,
|
||||
TC: meta.TC,
|
||||
RiskDurumu: meta.RiskDurumu,
|
||||
SirketDetay: meta.SirketDetay,
|
||||
CariDoviz: curr,
|
||||
}
|
||||
agg[key] = row
|
||||
}
|
||||
|
||||
usd := toUSD(ln.Bakiye, curr, usdTry, rateMap)
|
||||
tl := toTRY(ln.Bakiye, curr, rateMap)
|
||||
|
||||
switch strings.TrimSpace(ln.PislemTipi) {
|
||||
case "1_2":
|
||||
row.Bakiye12 += ln.Bakiye
|
||||
row.TLBakiye12 += tl
|
||||
row.USDBakiye12 += usd
|
||||
case "1_3":
|
||||
row.Bakiye13 += ln.Bakiye
|
||||
row.TLBakiye13 += tl
|
||||
row.USDBakiye13 += usd
|
||||
}
|
||||
|
||||
w := math.Abs(ln.Bakiye)
|
||||
if w > 0 {
|
||||
weightMap[key] += w
|
||||
vadeSumMap[key] += (ln.VadeGun * w)
|
||||
vadeBelgeSumMap[key] += (ln.VadeBelgeGun * w)
|
||||
}
|
||||
}
|
||||
|
||||
out := make([]models.CustomerBalanceListRow, 0, len(agg))
|
||||
for k, v := range agg {
|
||||
base := weightMap[k]
|
||||
if base > 0 {
|
||||
v.VadeGun = vadeSumMap[k] / base
|
||||
v.VadeBelgeGun = vadeBelgeSumMap[k] / base
|
||||
}
|
||||
out = append(out, *v)
|
||||
}
|
||||
|
||||
sort.Slice(out, func(i, j int) bool {
|
||||
if out[i].AnaCariKodu == out[j].AnaCariKodu {
|
||||
if out[i].CariKodu == out[j].CariKodu {
|
||||
return out[i].CariDoviz < out[j].CariDoviz
|
||||
}
|
||||
return out[i].CariKodu < out[j].CariKodu
|
||||
}
|
||||
return out[i].AnaCariKodu < out[j].AnaCariKodu
|
||||
})
|
||||
|
||||
_ = selectedDate
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func loadAgingBalanceLines(ctx context.Context, cariSearch string) ([]mkCariBakiyeLine, error) {
|
||||
query := `
|
||||
SELECT
|
||||
CurrAccTypeCode,
|
||||
CariKodu = LTRIM(RTRIM(CariKodu)),
|
||||
CariDoviz = LTRIM(RTRIM(CariDoviz)),
|
||||
SirketKodu,
|
||||
PislemTipi,
|
||||
YerelBakiye = CAST(0 AS DECIMAL(18,2)),
|
||||
Bakiye,
|
||||
Vade_Gun,
|
||||
Vade_BelgeTarihi_Gun
|
||||
FROM dbo.CARI_BAKIYE_GUN_CACHE
|
||||
WHERE (@CariSearch = '' OR LTRIM(RTRIM(CariKodu)) LIKE '%' + @CariSearch + '%')
|
||||
ORDER BY CariKodu, CariDoviz, PislemTipi
|
||||
`
|
||||
|
||||
rows, err := db.MssqlDB.QueryContext(ctx, query, sql.Named("CariSearch", strings.TrimSpace(cariSearch)))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("CARI_BAKIYE_GUN_CACHE query error: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]mkCariBakiyeLine, 0, 4096)
|
||||
for rows.Next() {
|
||||
var r mkCariBakiyeLine
|
||||
if err := rows.Scan(
|
||||
&r.CurrAccTypeCode,
|
||||
&r.CariKodu,
|
||||
&r.CariDoviz,
|
||||
&r.SirketKodu,
|
||||
&r.PislemTipi,
|
||||
&r.YerelBakiye,
|
||||
&r.Bakiye,
|
||||
&r.VadeGun,
|
||||
&r.VadeBelgeGun,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, r)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func toTRY(amount float64, currency string, rateMap map[string]float64) float64 {
|
||||
switch currency {
|
||||
case "TRY":
|
||||
return amount
|
||||
case "":
|
||||
return amount
|
||||
default:
|
||||
currTry := rateMap[currency]
|
||||
if currTry <= 0 {
|
||||
return 0
|
||||
}
|
||||
return amount * currTry
|
||||
}
|
||||
}
|
||||
20
svc/queries/statement_aging_cache.go
Normal file
20
svc/queries/statement_aging_cache.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package queries
|
||||
|
||||
import (
|
||||
"bssapp-backend/db"
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// RebuildStatementAgingCache runs only step 2 + step 3.
|
||||
func RebuildStatementAgingCache(ctx context.Context) error {
|
||||
if _, err := db.MssqlDB.ExecContext(ctx, `EXEC dbo.SP_BUILD_CARI_VADE_GUN_STAGING;`); err != nil {
|
||||
return fmt.Errorf("SP_BUILD_CARI_VADE_GUN_STAGING error: %w", err)
|
||||
}
|
||||
|
||||
if _, err := db.MssqlDB.ExecContext(ctx, `EXEC dbo.SP_BUILD_CARI_BAKIYE_CACHE;`); err != nil {
|
||||
return fmt.Errorf("SP_BUILD_CARI_BAKIYE_CACHE error: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user