using PayRollDAL.DTO.SAP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace PayRollBLL.SAP.Builders
{
///
/// SAP Infotype 581 — HRA / Rent Paid.
/// Service: ZPY_ITDEC_HRA_SRV / ITDecHRA_HeaderSet
/// Source: TDECLARATIONDETAIL rows where DeclarationDetailType == 2 (Rent).
/// One SAP item per rent detail record; dates formatted as dd-MMM-yyyy per SAP spec.
///
public class SAP581Builder : ISapInfotypeBuilder
{
private const byte RentType = 2;
public int Infotype => 581;
public string DisplayName => "HRA / Rent Paid";
public string EndpointPath => "/sap/opu/odata/sap/ZPY_ITDEC_HRA_SRV/ITDecHRA_HeaderSet";
public string MsgNavProperty => "Nav2IT_Dec_HRA_Msg";
public string Build(IEnumerable rows, string date, string remarks)
{
var items = rows
.Where(r => r.DeclarationDetailId.HasValue
&& r.DeclarationDetailType == RentType
&& r.DeclaredAmount != 0)
.Select(r => new Sap581Item
{
EmployeeID = r.EmployeeCode,
FiscalYear = r.FiscalYear,
Particulars = r.Particulars,
From = r.FromPeriod.HasValue
? r.FromPeriod.Value.ToString("dd-MMM-yyyy")
: string.Empty,
To = r.ToPeriod.HasValue
? r.ToPeriod.Value.ToString("dd-MMM-yyyy")
: string.Empty,
// IsMetro: 0 = Metro city, 1 = Non-Metro (per ITDeclarationSapDTO)
Type = r.IsMetro == 0 ? "Metro" : "Non-Metro",
// SAP expects monthly rent; the DB stores the annual declared/approved total.
Declared = SapFmt.Amount(Math.Round(r.DeclaredAmount / 12, 2)),
Approved = SapFmt.Amount(Math.Round(r.ApprovedAmount / 12, 2)),
Remarks = r.DetailRemarks,
LandLordName = r.ContactName,
LandLordPAN = r.ContactPAN,
LandLordTAN = r.ContactTAN,
LandLordAddressLine1 = r.ContactAddress1,
LandLordAddressLine2 = r.ContactAddress2,
LandLordAddressLine3 = r.ContactAddress3,
LandLordAddressLine4 = r.ContactAddress4,
LandLordAddressLine5 = r.ContactAddress5,
})
.ToList();
if (items.Count == 0) return string.Empty;
var payload = new Sap581Payload
{
Date = date,
Remarks = remarks,
Nav2IT_Dec_HRA_Item = items,
};
return JsonSerializer.Serialize(payload, SapJsonOptions.Plain);
}
}
}