Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 34

Budget House notes for creating year wise total result table and giving 2024 column as input

column and based on


selected percentage and year the values will be entered in 2024 column and after clicking on save button it will get
saved on SQL server database table. Code and explanation for this. This code save entire table again and again.

• budget.component.html
<form [formGroup]="myForm">

<div class="top-menu fixed-top">

<div class="newrow">

<div class="product-logo">

<img src="../assets/images/IV.png" alt="AiVie" />

</div>

<div style="display: inline-block; margin-top: 10px; align-items: center;position: absolute; margin-left:


100px;" >

<ng-multiselect-dropdown

[settings]="dropdownSettingsYear"

class="yearDropdown"

[placeholder]="'Select Number of Years'"

[data]="numberOfYearsOptions"

(ngModelChange)="onNumberOfYearsChange($event)"

[singleSelection]="true"

formControlName="numberOfYears"

(onDeSelect)="onItemDeSelect($event)"

>

</ng-multiselect-dropdown>

</div>

<div style="display: inline-block; margin-top: 10px; align-items: center;position: absolute; margin-left:


340px;" >

<ng-multiselect-dropdown

[settings]="dropdownSettingsSelectYear"

[placeholder]="'Select Year'"

[data]="selectYearOptions"

[singleSelection]="true"
formControlName="selectYear"

(onSelect)="onYearSelect($event)"

>

</ng-multiselect-dropdown>

</div>

<div style="display: inline-block; margin-top: 10px; align-items: center;position: absolute; margin-left:


490px;" >

<ng-multiselect-dropdown

[settings]="dropdownSettingsPercentage"

[placeholder]="'Select Percentage'"

[data]="percentageOption"

[singleSelection]="true"

formControlName="percentage"

(onSelect)="onPercentageSelect($event)"

>

</ng-multiselect-dropdown>

</div>

<button class="buttonload"

style="position:absolute;margin-left: 690px;

margin-top: 5px; padding: 15px;

cursor: pointer; font-size: 16px;

border: 2px solid #acbcc7;

border-radius: 5px;

background-color: #23527a;

transition: all 0.3s ease;

color: #ffffff;"

type="submit"

[loading]="loading" (click)="onButtonClick()">

Go</button>

<button class="buttonload"
style="position:absolute;

margin-top: 5px; padding: 15px;

cursor: pointer; font-size: 16px;

border: 2px solid #acbcc7;

border-radius: 5px;

background-color: #23527a;

margin-left: 760px;

transition: all 0.3s ease;

color: #ffffff;"

type="submit"

[loading]="loading" (click)="convertToJson2()">

Save</button>

<div style="text-align: right-end;margin-top: 10px;">

<div class="welcome" style="position: absolute; margin-left: 1285px; margin-top: 8px;">

Welcome<br />

Yadnya

</div>

</div>

<div style="text-align: right; margin-top: 10px;">

<div style="margin-left: 850px;" >

<span class="dot">Y</span>

</div>

</div>

</div>

</div>
<div *ngIf="loading" class="d-flex align-items-center">

<strong>Loading...</strong>

<div class="spinner-border ml-auto" role="status" aria-hidden="true"></div>

</div>

<br>

<div class="row">

<div class="col-xs-12 col-sm-12">

<div id="tableId" class="card mb-3">

<table *ngIf="selectedNumberOfYears" class="custom-table">

<thead class="custom-table1">

<tr>

<th colspan="2">Description</th>

<th [attr.colspan]="selectedNumberOfYears+1">Years</th>

</tr>

<tr>

<td>acc_cat</td>

<td >acc_grp</td>

<td *ngFor="let year of getPreviousYears(); let i = index">{{ year }} </td>

<td>2024</td>

</tr>

</thead>

<tbody>

<ng-container *ngFor="let data of pnl_dataset; let i = index">

<tr *ngIf="i === 0 || data.dsAccountDesc !== pnl_dataset[i - 1].dsAccountDesc">

<td>{{ data.dsAccountDesc }}</td>

<td></td>

<td *ngFor="let year of getPreviousYears(); let j = index">

{{ data.totalResultAcWise[year] || '0.00' }}
</td>

<td><input class="custom-input" type="text" [value]="modifiedValues[i]"


formControlName="inputValueTotalAc" /></td>

</tr>

<tr>

<td></td>

<td *ngIf="i === 0 || data.dsAccGrpDesc !== pnl_dataset[i - 1].dsAccGrpDesc">

{{ data.dsAccGrpDesc }}

</td>

<td *ngFor="let year of getPreviousYears(); let j = index">

{{ data.totalResult[year] || '0.00' }}

</td>

<td><input class="custom-input" type="text" [value]="modifiedValuesGrp[i]"


formControlName="inputValue" /></td>

</tr>

</ng-container>

</tbody>

</table>

</div>

</div>

</div>

</form>

<!-- <table *ngIf="selectedNumberOfYears" class="custom-table">

<thead class="custom-table1">

<tr>

<th colspan="2">Description</th>

<th [attr.colspan]="selectedNumberOfYears+1">Years</th>

</tr>
<tr>

<td>acc_cat</td>

<td >acc_grp</td>

<td *ngFor="let year of getPreviousYears(); let i = index">{{ year }} </td>

<td>2024</td>

</tr>

</thead>

<tbody>

<ng-container *ngFor="let data of budget_house_dataset; let i = index">

<tr *ngIf="i === 0 || data.dsAccountDesc !== budget_house_dataset[i - 1].dsAccountDesc">

<td>{{ data.dsAccountDesc }}</td>

<td></td>

<td *ngFor="let year of getPreviousYears(); let j = index">

{{ data.totalResultAcWise[year] || '0.00' }}

</td>

<td><input class="custom-input" type="text" [value]="modifiedValues[i]"


formControlName="inputValueTotalAc" /></td>

</tr>

<tr>

<td></td>

<td *ngIf="i === 0 || data.dsAccGrpDesc !== budget_house_dataset[i - 1].dsAccGrpDesc">

{{ data.dsAccGrpDesc }}

</td>

<td *ngFor="let year of getPreviousYears(); let j = index">

{{ data.totalResult[year] || '0.00' }}

</td>

<td><input class="custom-input" type="text" [value]="modifiedValuesGrp[i]"


formControlName="inputValue" /></td>

</tr>

</ng-container>
</tbody>

</table> -->

• dropdown.services.ts
import { HttpClient, HttpHeaders, } from '@angular/common/http';

import { Injectable, EventEmitter } from '@angular/core';

import { environment } from '../../environments/environment';

import { catchError } from 'rxjs/internal/operators/catchError';

@Injectable({ providedIn: 'root' })

export class DropdownService {

constructor(private http: HttpClient) {}

getApprover(idCustomer: string) {

return this.http.get<any>(`${environment.apiUrl}/api/usermaster/${idCustomer}`);

getCustomer() {

return this.http.get<any>(`${environment.apiUrl}/api/customermaster`);

getKPI1(idCustomer:string){

var url = "http:localhost:9998/api/customermaster?idcustomer=$idCustomer";

return this.http.get<any>(url);

getKPI(idCustomer:string){

return this.http.get<any>(`${environment.apiUrl}/api/customermaster/${idCustomer}`);

getKPICategoryMaster(idUser:string, idCustomer:string){

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/kpicategorymaster/${idUser}/$
{idCustomer}`);

getKPIMaster(idUser:string, idCustomer:string, idCategory:string){

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/kpimaster/${idUser}/${idCustomer}/$
{idCategory}`);

getDashboardKPI(idCustomer:string, idCategory:string, idKPI:string){

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/kpimaster/${idCustomer}/${idCategory}/$
{idKPI}`);

getKPIFilterMaster(idUser:string, idCustomer:string, idKPI:string){

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/kpifiltermaster/${idUser}/${idCustomer}/$
{idKPI}`);

getJobRole4Combo(idUser: string, idCustomer: string) {

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/authjobrole/${idUser}/${idCustomer}`);

getUser(idUser: string, idCustomer: string) {

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/user/${idUser}/${idCustomer}`);

getRole(idUser: string, idCustomer: any, idRoleType: any) {

return this.http.get<any>(`${environment.apiUrl}/api/dropdown/role/${idUser}/${idCustomer}/$
{idRoleType}`);

getAcDescofAccCat(idUser: string, idCustomer: any, accountCat: any, accountGrp:any) {

return this.http.get<any>(`${environment.apiUrl}/api/BudgetHouse/AccDescByAccCat/${idUser}/$
{idCustomer}/${accountCat}/${accountGrp}`);

getAllDesc(idUser: string, idCustomer: any) {

return this.http.get<any>(`${environment.apiUrl}/api/BudgetHouse/AllDesc/${idUser}/${idCustomer}`);

// PostAccTotalResult(id: string, customer: any,requestBody: any){

// return this.http.post<any>(`${environment.apiUrl}/api/BudgetHouse/AccTotalResult/${id}/${customer}`,
requestBody);

// }

PostAccTotalResult(id: string, customer: any, requestBody: any) {


return this.http.post<any>(

`${environment.apiUrl}/api/BudgetHouse/AccTotalResult/${id}/${customer}`,

requestBody,

{ headers: { 'Content-Type': 'application/json' } }

);

• budget.component.ts
import { Component } from '@angular/core';

import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

import { IDropdownSettings, } from 'ng-multiselect-dropdown';

import { OdataService } from '../_services/odata.service';

import { CommonService } from '../_services/common.service';

import { DropdownService } from '../_services/dropdown.service';

import { debug } from 'node:console';

import { json } from 'stream/consumers';

@Component({

selector: 'app-budget',

templateUrl: './budget.component.html',

styleUrl: './budget.component.css',

providers: [OdataService]

})

export class BudgetComponent {

myForm: FormGroup = this.fb.group({

numberOfYears: [1, [Validators.required, Validators.min(1), Validators.max(5)]],

idCompany: new FormControl(),

percentage: new FormControl(),


selectYear: new FormControl(),

inputValue:new FormControl(),

inputValueTotalAc:new FormControl()

});

selectedNumberOfYears: any;

currentYear: number = new Date().getFullYear();

numberOfYearsOptions :{ item_id: number; item_text: any }[] = [];

selectYearOptions:any[] = [];

percentageOption :{ item_id: number; item_text: string }[] = [];

dropdownSettingsYear:IDropdownSettings={};

dropdownSettingsPercentage:any;

dropdownSettingsSelectYear:any;

dataSet:any;

FormBuilder:any;

CompanyData: any[] = [];

pnl_dataset: any[]=[];

dspnl_dataset: any[] = [];

budget_house_dataset: any[] = [];

dsbudget_house_dataset: any[] = [];

loading: boolean = false;

selectedYear:any;

selectedPercentage:any;

modifiedValues: any[]=[];

modifiedValuesGrp: any[]=[];

table:any;

jsonString: any;

constructor(private fb: FormBuilder,

private odataService: OdataService,


private common: CommonService,

private dropdownService: DropdownService,

){}

ngOnInit() {

this.dropdownSettingsYear = {

singleSelection: true,

idField: 'item_id',

textField: 'item_text',

enableCheckAll: false,

closeDropDownOnSelection: true,

};

this.dropdownSettingsSelectYear = {

singleSelection: true,

idField: 'item_id',

textField: 'item_text',

};

this.dropdownSettingsPercentage = {

singleSelection: true,

idField: 'item_id',

textField: 'item_text',

};

this.numberOfYearsOptions = [

{ item_id: 1, item_text: 'Last 1 year' },

{ item_id: 2, item_text: 'Last 2 years'},

{ item_id: 3, item_text: 'Last 3 years'},

{ item_id: 4, item_text: 'Last 4 years'},

{ item_id: 5, item_text: 'Last 5 years'}


];

this.percentageOption = [

{ item_id: 10, item_text: '10%' },

{ item_id: 20, item_text: '20%'},

{ item_id: 30, item_text: '30%'},

{ item_id: 40, item_text: '40%'},

{ item_id: 50, item_text: '50%'}

];

onYearSelect(item: any) {

this.selectedYear = item.item_text;

onPercentageSelect(item: any) {

this.selectedPercentage = item.item_id;

onButtonClick(){

this.updateTableDataAcc();

this.updateTableDataGrp();

onNumberOfYearsChange(selectedItems:any) {

// this.selectedNumberOfYears = this.myForm.get('numberOfYears')!.value;

this.selectedNumberOfYears = selectedItems[0].item_id;

var previousYear=this.getPreviousYears();

let ODataFilters = {

"PreviousYearsArr":previousYear

};

sessionStorage.setItem("ODataFilters", JSON.stringify(ODataFilters));

this.call_OData_ACC_BAL();

this.updateSelectYearDropdownData();
}

getPreviousYears(): number[] {

const previousYears: number[] = [];

for (let i = 0; i < this.selectedNumberOfYears; i++) {

previousYears.push((this.currentYear-1) - i);

return previousYears.reverse();

updateSelectYearDropdownData() {

const currentYear = new Date().getFullYear();

const selectYearOptions = [];

for (let i = 0; i < this.selectedNumberOfYears; i++) {

selectYearOptions.push({ item_id: i, item_text: (currentYear - 1) - i });

// Enable the form control and update its value

const selectYearControl = this.myForm.get('selectYear');

if (selectYearControl) {

selectYearControl.enable();

selectYearControl.patchValue(selectYearOptions[0]); // Select the first year by default

// Update the data for the dropdown

this.selectYearOptions = selectYearOptions;

updateTableDataAcc() {

this.modifiedValues = [];

if (this.selectedYear !== null && this.selectedPercentage !== null) {

const percentageFactor = 1 + (this.selectedPercentage / 100);

this.pnl_dataset.forEach(data => {

const yearValueString = data.totalResultAcWise[this.selectedYear] || '0';


const yearValue = parseFloat(yearValueString.replace(/,/g, ''));

if (!isNaN(yearValue)) {

const modifiedValue = yearValue * percentageFactor;

let formatValueAcc = modifiedValue ? modifiedValue.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

this.modifiedValues.push(formatValueAcc);

//this.myForm.get('inputValueTotalAc')!.setValue(modifiedValue.toFixed(2));

} else {

console.log('Invalid numeric value for selected year');

});

updateTableDataGrp() {

this.modifiedValuesGrp = [];

if (this.selectedYear !== null && this.selectedPercentage !== null) {

const percentageFactor = 1 + (this.selectedPercentage / 100);

this.pnl_dataset.forEach(data => {

const yearValueString = data.totalResult[this.selectedYear] || '0';

const yearValueGrp = parseFloat(yearValueString.replace(/,/g, ''));

if (!isNaN(yearValueGrp)) {

const modifiedValue = yearValueGrp * percentageFactor;

let formatValueGrp = modifiedValue ? modifiedValue.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

this.modifiedValuesGrp.push(formatValueGrp);

//this.myForm.get('inputValueTotalAc')!.setValue(modifiedValue.toFixed(2));

} else {
console.log('Invalid numeric value for selected year');

});

onSubmit(){

// var previousYear=this.getPreviousYears();

// let ODataFilters = {

// "PreviousYearsArr":previousYear

// };

// sessionStorage.setItem("ODataFilters", JSON.stringify(ODataFilters));

// this.call_OData_ACC_BAL();

call_OData_ACC_BAL(){

let q:any;

const storedData = sessionStorage.getItem("ODataFilters");

if (storedData) {

try {

q = JSON.parse(storedData);

if (typeof q !== 'object' || Array.isArray(q)) {

throw new Error('Invalid JSON format'); // If parsed data is not an object

} catch (error) {

console.error('Error parsing JSON from session storage:', error);

q = {};
}

this.loading = true;

var aFilterFromYear = "";

aFilterFromYear += "gjahr ge '" + q.PreviousYearsArr[0]+ "'";

let selectedYear = q.PreviousYearsArr[0];

var oDataUrl = "/xSOLVIExACplanact?$format=json&$filter=" + aFilterFromYear;

this.odataService.oData_ACC_BAL(oDataUrl).subscribe((x:any)=>{

this.loading = false;

this.dataSet = []

this.dataSet = x.d.results;

// sessionStorage.setItem('dsPreviousYearsindex0', JSON.stringify(this.pnlDataSet ));

this.monthWisePNLDataset(this.dataSet,selectedYear);

})

monthWisePNLDataset(ds: any, selectedYear: number) {

this.pnl_dataset = [];

this.dspnl_dataset = [];

this.budget_house_dataset = [];

var CategoryGroupedWiseData = this.common.groupAndSum(ds, ["ac_cat", "ac_grp", "bal_sh_ind"],


["actual_amount"]);

CategoryGroupedWiseData.forEach((x: any) => {

if (x["bal_sh_ind"] == false) {
let ac_cat = x["ac_cat"];

let ac_grp = x["ac_grp"];

let actual_amount = x["actual_amount"];

let formatClBal = actual_amount ? actual_amount.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

var filter = { ac_cat: [ac_cat] };

let filtered = this.common.getFilterBy(ds, filter);

var groupAndSumWiseYearlyData = this.common.getSelectedColumnsWithGrouping(filtered, ["gjahr",


"actual_amount"], ["gjahr"], ["actual_amount"], "gjahr");

let totalResultAcWise: { [key: number]: any } = {};

// let totalResultAcWiseInput: { [key: number]: any } = {};

groupAndSumWiseYearlyData.forEach((y: any) => {

let gjahr = y["gjahr"];

let actual_amount = y["actual_amount"];

let formaClBal = actual_amount ? actual_amount.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

totalResultAcWise[gjahr] = formaClBal;

});

var filterBy = { ac_grp: [ac_grp], ac_cat: [ac_cat] };

let ds_filtered = this.common.getFilterBy(ds, filterBy);

var groupAndSumWiseYearlyData = this.common.getSelectedColumnsWithGrouping(ds_filtered, ["gjahr",


"actual_amount"], ["gjahr"], ["actual_amount"], "gjahr");

let totalResult: { [key: number]: any } = {};


groupAndSumWiseYearlyData.forEach((y: any) => {

let gjahr = y["gjahr"];

let actual_amount = y["actual_amount"];

let formaClBal = actual_amount ? actual_amount.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

totalResult[gjahr] = formaClBal;

});

let account_desc = "";

let account_grp_desc = "";

this.dropdownService.getAcDescofAccCat("1", "1", ac_cat, ac_grp).subscribe(data => {

if (data && typeof data === 'object') {

account_desc = data["description"];

account_grp_desc = data["groupDescription"];

} else {

console.error("Data is not an object:", data);

this.pnl_dataset.push({

"dsAccoutCat": ac_cat,

"dsAccountgrp": ac_grp,

"dsAccountDesc": account_desc,

"dsAccGrpDesc": account_grp_desc,

"totalResultAcWise": totalResultAcWise,

"totalResult": totalResult,

"actual_amount": formatClBal

});

this.dspnl_dataset.push(this.common.sortData(this.pnl_dataset, "dsAccountgrp"));
});

});

convertToJson2() {

const tablePNL = document.getElementById('tableId');

if (tablePNL) {

const jsonData: { acc_cat: string; acc_grp: string; year:any;value: string}[] = [];

const headerCells = tablePNL.querySelectorAll('thead th');

const yearHeaders = Array.from(headerCells).slice(2).map(cell => cell.textContent || '');

const rows = tablePNL.querySelectorAll('tbody tr');

// let currentAccCat = ''; // Keep track of the current acc_cat value

let acc_cat = '';

rows.forEach((row) => {

const cells = row.querySelectorAll('td');

const acc_catTemp = cells[0].textContent || '';

if(acc_catTemp == ""){

}else{

acc_cat = cells[0].textContent || '';

const acc_grp = cells.length > 1 ? cells[1].textContent || '' : '';

//const curryear = cells[cells.length-2].textContent || '' ;


const curryear = '2024';

cells.forEach((cell, i) => {

if (i >= 2) {

const year = yearHeaders[i - 2];

let value = '';

// Check if the cell contains an input element

const inputElement = cell.querySelector('input');

if (inputElement) {

// Use the input value if it exists

value = inputElement.value;

const rowData: { acc_cat: string; acc_grp: string;year:any;value: string } = {

acc_cat: acc_cat,

acc_grp: acc_grp, // Reset acc_grp when acc_cat changes

year:curryear,

value: value

};

jsonData.push(rowData);

});

});

// Convert the array to JSON string and log it

this.jsonString = JSON.stringify(jsonData, null, 2);

console.log(this.jsonString);

} else {
console.error('Table with ID "tableId" not found.');

this.dropdownService.PostAccTotalResult("1", "1", this.jsonString).subscribe(data => {

console.log(data);

// if (data && typeof data === 'object') {

// // account_desc = data["description"];

// // account_grp_desc = data["groupDescription"];

// } else {

// console.error("Data is not an object:", data);

// }

});

monthWiseBalanceSheetDataSet(ds: any, selectedYear: number) {

this.budget_house_dataset = [];

this.pnl_dataset = [];

var CategoryGroupedWiseData = this.common.groupAndSum(ds, ["ac_cat", "ac_grp", "bal_sh_ind"], ["cl_bal"]);

CategoryGroupedWiseData.forEach((x: any) => {

if (x["bal_sh_ind"] == true) {

let ac_cat = x["ac_cat"];

let ac_grp = x["ac_grp"];

let clbal = x["cl_bal"];

let formatClBal = clbal ? clbal.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits:


2 }) : '0.00';

var filter = { ac_cat: [ac_cat] };

let filtered = this.common.getFilterBy(ds, filter);


var groupAndSumWiseYearlyData = this.common.getSelectedColumnsWithGrouping(filtered, ["gjahr",
"cl_bal"], ["gjahr"], ["cl_bal"], "gjahr");

let totalResultAcWise: { [key: number]: any } = {};

// let totalResultAcWiseInput: { [key: number]: any } = {};

groupAndSumWiseYearlyData.forEach((y: any) => {

let gjahr = y["gjahr"];

let bal = y["cl_bal"];

let formaClBal = bal ? bal.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })


: '0.00';

totalResultAcWise[gjahr] = formaClBal;

});

var filterBy = { ac_grp: [ac_grp], ac_cat: [ac_cat] };

let ds_filtered = this.common.getFilterBy(ds, filterBy);

var groupAndSumWiseYearlyData = this.common.getSelectedColumnsWithGrouping(ds_filtered, ["gjahr",


"cl_bal"], ["gjahr"], ["cl_bal"], "gjahr");

let totalResult: { [key: number]: any } = {};

groupAndSumWiseYearlyData.forEach((y: any) => {

let gjahr = y["gjahr"];

let cl_bal = y["cl_bal"];

let formaClBal = cl_bal ? cl_bal.toLocaleString('en-US', { minimumFractionDigits: 2,


maximumFractionDigits: 2 }) : '0.00';

totalResult[gjahr] = formaClBal;

});
let account_desc = "";

let account_grp_desc = "";

this.dropdownService.getAcDescofAccCat("1", "1", ac_cat, ac_grp).subscribe(data => {

if (data && typeof data === 'object') {

account_desc = data["description"];

account_grp_desc = data["groupDescription"];

} else {

console.error("Data is not an object:", data);

this.budget_house_dataset.push({

"dsAccoutCat": ac_cat,

"dsAccountgrp": ac_grp,

"dsAccountDesc": account_desc,

"dsAccGrpDesc": account_grp_desc,

"totalResultAcWise": totalResultAcWise,

"totalResult": totalResult,

"cl_bal":formatClBal

});

this.dsbudget_house_dataset.push(this.common.sortData(this.budget_house_dataset, "dsAccountgrp"));

});

});

onItemDeSelect(item: any) {

console.log('Deselected Item:', item);

}
}

• Steps to store data from html table to SQL server:


1. Write method to store URL in dropdown.services.ts in PostAccTotalResult(id: string, customer: any,
requestBody: any) {} this method.

2. Write method which is called in dropdown.services.ts in BudgetHouseController.cs


[HttpPost("AccTotalResult/{id}/{customer}")]

public Models.Msg PostAccTotalResult(string id, string customer,[FromBody] JsonElement jsonObject){}

3. Write method logic in BudgetHoueManager.cs public static Msg PostAccTotalResult(string id, string
customer,JsonElement jsonObject){}

4. Create Table in SQL server : Open SQL server -> Database->BudgetHouse-> Tables-> right click on it-> new-
>table-> give column names and data types.

5. Create Table Type:

Click on new query->

CREATE TYPE dbo.AccTotalResultType AS TABLE

AccountCategory NVARCHAR(255),

AccountGroup NVARCHAR(255),

Year NVARCHAR(4),

TotalResult DECIMAL(18, 2)

);

7. To open Table type go to programmability ->Types -> User-defined Table types -> check new table type is listed
or not.

8.Create Stored Procedure:

Programmability -> Stored Procedure -> Right click-> new-> stored procedure.

CREATE PROCEDURE dbo.InsertAccTotalResult

@idUser NVARCHAR(255),

@idCustomer NVARCHAR(255),

@AccTotalResult dbo.AccTotalResultType READONLY

AS

BEGIN

INSERT INTO YourTargetTable (idUser, idCustomer, AccountCategory, AccountGroup, Year, TotalResult)

SELECT @idUser, @idCustomer, t.AccountCategory, t.AccountGroup, t.Year, t.TotalResult


FROM @AccTotalResult t;

END;

• BudgetHouseController.cs
using BudgetHouseApi.Models;

using Microsoft.AspNetCore.Mvc;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using System.Text;

using System.Text.Json;

using System.Data;

using Newtonsoft.Json;

namespace BudgetHouseApi.Controllers

[ApiController]

[Route("api/[controller]")]

public class BudgetHouseController : ControllerBase

[HttpGet("AllDesc/{id}/{customer}")]

public List<BudgetHouse> getAllDesc(string idUser, string idCustomer)

List<BudgetHouse> lst = BudgetHouseManager.getAllDesc(idUser, idCustomer);

return lst;

[HttpGet("AccDescByAccCat/{id}/{customer}/{accountCat}/{accountGroup}")]
public Models.BudgetHouse getAccDescByAccCat(string id, string customer, string accountCat, string
accountGroup)

return Models.BudgetHouseManager.getAccDescByAccCat(id, customer, accountCat, accountGroup);

[HttpPost("AccTotalResult/{id}/{customer}")]

public Models.Msg PostAccTotalResult(string id, string customer,[FromBody] JsonElement jsonObject)

return Models.BudgetHouseManager.PostAccTotalResult(id, customer, jsonObject);

• BudgetHouseManager.cs
public static Msg PostAccTotalResult(string id, string customer,JsonElement jsonObject)

Msg objMsg = new Msg();

try

{ DataAccess da = new DataAccess();

// Create a DataTable to hold the data

DataTable dt = new DataTable();

dt.Columns.Add("AccountCategory", typeof(string));

dt.Columns.Add("AccountGroup", typeof(string));

dt.Columns.Add("Year", typeof(string));

dt.Columns.Add("TotalResult", typeof(string));

// Populate DataTable from JSON array

foreach (JsonElement element in jsonObject.EnumerateArray())

{
string accCat = element.GetProperty("acc_cat").GetString();

string accGrp = element.GetProperty("acc_grp").GetString();

string year = element.GetProperty("year").GetString();

string totalResult = element.GetProperty("value").GetString();

dt.Rows.Add(accCat, accGrp, year, totalResult);

// Execute stored procedure with TVP parameter

SqlParameter[] sqlparam = new SqlParameter[3];

sqlparam[0] = new SqlParameter("@idUser", id);

sqlparam[1] = new SqlParameter("@idCustomer", customer);

sqlparam[2] = new SqlParameter

ParameterName = "@AccTotalResult",

SqlDbType = SqlDbType.Structured,

Value = dt,

TypeName = "dbo.AccTotalResultType"

};

objMsg.Text = da.ExecuteSP("InsertAccTotalResult", sqlparam);

if (!string.IsNullOrEmpty(objMsg.Text))

objMsg.Type = Msg.danger;

else

objMsg.Type = Msg.success;
objMsg.Data = "Bulk data inserted successfully.";

catch (Exception ex)

objMsg.Type = Msg.danger;

objMsg.Text = ex.Message;

return objMsg;

Explanation of above method :


# public static Msg PostAccTotalResult(string id, string customer,JsonElement jsonObject)

• Access Modifier: public static indicates that this method is accessible from outside the class and doesn't
require an instance of the class to be called.

• Return Type: The method returns an object of type Msg.

• Method Name: PostAccTotalResult

• Parameters:-

• string id: Represents an identifier related to a user.

• string customer: Represents a customer identifier.

• JsonElement jsonObject: Represents a JSON object that seems to contain accounting information.

#Msg objMsg = new Msg();

Creates an instance of the Msg class, presumably for storing messages related to the success or failure of the
method.

# DataAccess da = new DataAccess();

• This line creates an instance of the DataAccess class and assigns it to the variable da. DataAccess seems to
be a class or object responsible for handling data access operations, likely interacting with a database.

// Create a DataTable to hold the data

# DataTable dt = new DataTable();

• This line creates a new instance of the DataTable class and assigns it to the variable dt. A DataTable is an
in-memory representation of a table, and it can hold rows and columns of data, similar to a table in a
database.

#dt.Columns.Add("AccountCategory", typeof(string));

dt.Columns.Add("AccountGroup", typeof(string));

dt.Columns.Add("Year", typeof(string));

dt.Columns.Add("TotalResult", typeof(string));

• These lines add columns to the DataTable. Each Add method call adds a new column to the table. The
parameters for Add are the column name and the data type of the column. In this case, it adds four columns:

"AccountCategory" of type string

"AccountGroup" of type string

"Year" of type string

"TotalResult" of type string

# foreach (JsonElement element in jsonObject.EnumerateArray())

string accCat = element.GetProperty("acc_cat").GetString();

string accGrp = element.GetProperty("acc_grp").GetString();

string year = element.GetProperty("year").GetString();

string totalResult = element.GetProperty("value").GetString();

dt.Rows.Add(accCat, accGrp, year, totalResult);

• This loop iterates over each element in the jsonObject, assuming it is an array. Let's go through each part in
detail:

foreach (JsonElement element in jsonObject.EnumerateArray()):

This line starts a loop that iterates over each element in the jsonObject. EnumerateArray() is a method that returns an
enumerator for the elements in a JSON array.

Inside the Loop:

For each iteration of the loop, a JsonElement named element represents the current element in the JSON array.
string accCat = element.GetProperty("acc_cat").GetString();:

This line extracts the value of the "acc_cat" property from the current JSON element and converts it to a string. It
assumes that the "acc_cat" property is present and has a string value.

string accGrp = element.GetProperty("acc_grp").GetString();:

Similarly, this line extracts the value of the "acc_grp" property from the current JSON element and converts it to a
string.

string year = element.GetProperty("year").GetString();:

Extracts the value of the "year" property and converts it to a string.

string totalResult = element.GetProperty("value").GetString();:

Extracts the value of the "value" property and converts it to a string. It assumes that the property is named "value."

dt.Rows.Add(accCat, accGrp, year, totalResult);:

Adds a new row to the DataTable (dt) with values from the current JSON element. The order of values corresponds
to the order of columns in the DataTable created earlier ("AccountCategory," "AccountGroup," "Year,"
"TotalResult"). Each property from the JSON element is mapped to a corresponding column in the DataTable.

# // Execute stored procedure with TVP parameter

SqlParameter[] sqlparam = new SqlParameter[3];

sqlparam[0] = new SqlParameter("@idUser", id);

sqlparam[1] = new SqlParameter("@idCustomer", customer);

sqlparam[2] = new SqlParameter{

ParameterName = "@AccTotalResult",

SqlDbType = SqlDbType.Structured,

Value = dt,

TypeName = "dbo.AccTotalResultType"

};

• The line SqlParameter[] sqlparam = new SqlParameter[3]; is used to create an array of SqlParameter
objects in C#. Each element in this array will represent a parameter that can be passed to a SQL query or
stored procedure.
sqlparam[0] = new SqlParameter("@idUser", id);

sqlparam[1] = new SqlParameter("@idCustomer", customer);

• This line creates a new SqlParameter and assigns it to the first slot (sqlparam[0]) in the array. It is used to
pass a parameter named @idUser with the value of the variable id. This is typically used in a SQL query or
stored procedure.Similar to the previous line, this sets up another SqlParameter in the second slot
(sqlparam[1]). It's used to pass a parameter named @idCustomer with the value of the variable customer.

sqlparam[2] = new SqlParameter

ParameterName = "@AccTotalResult",

SqlDbType = SqlDbType.Structured,

Value = dt,

TypeName = "dbo.AccTotalResultType"

};

• This line creates a more complex SqlParameter in the third slot (sqlparam[2]). It is used to pass a table-
valued parameter (TVP) named @AccTotalResult.

- ParameterName = "@AccTotalResult": This specifies the name of the parameter in the SQL query or stored
procedure.

- SqlDbType = SqlDbType.Structured: Indicates that the parameter is of type structured. In this case, it's used for
passing a structured data type, likely a table.

- Value = dt: Assigns the value of the DataTable named dt to this parameter. This means the data from the DataTable
will be passed to the SQL query or stored procedure through this parameter.

- TypeName = "dbo.AccTotalResultType": Specifies the type name of the structured parameter. In this context, it's
indicating the type of the table-valued parameter, which is probably a user-defined table type named
"AccTotalResultType" in the database.

#objMsg.Text = da.ExecuteSP("InsertAccTotalResult", sqlparam); da.ExecuteSP("InsertAccTotalResult", sqlparam):

• This line is calling a method named ExecuteSP on an instance of the DataAccess class (da). The method
seems to execute a stored procedure named "InsertAccTotalResult" and takes an array of SqlParameter
objects (sqlparam) as parameters.

#objMsg.Text = ...:

• The result of the ExecuteSP method is assigned to the Text property of the objMsg object. The Text
property is likely used to store messages or information related to the execution of the stored procedure.

#if (!string.IsNullOrEmpty(objMsg.Text))

objMsg.Type = Msg.danger;

}
else

objMsg.Type = Msg.success;

objMsg.Data = "Bulk data inserted successfully.";

• Handling the Result:

After executing the stored procedure, the code checks if the Text property of the objMsg object is not null or empty.

if (!string.IsNullOrEmpty(objMsg.Text)):

If the Text property is not empty, it means there was some issue or error during the execution of the stored
procedure.

In this case, it sets the Type property of objMsg to Msg.danger, which might be a predefined constant indicating an
error or danger message.

else:

If the Text property is empty, it means the stored procedure executed successfully without any errors.

In this case, it sets the Type property of objMsg to Msg.success, indicating a successful operation.

Additionally, it sets the Data property of objMsg to the string "Bulk data inserted successfully," which might be a
success message.

* To show updated values in column of SQL server table just change the code in SQL server Stored procedure :

USE [BudgetHouse]

GO

/****** Object: StoredProcedure [dbo].[InsertAccTotalResult] Script Date: 29-01-2024 15:32:23 ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

ALTER PROCEDURE [dbo].[InsertAccTotalResult]

@idUser NVARCHAR(255),

@idCustomer NVARCHAR(255),

@AccTotalResult dbo.AccTotalResultType READONLY

AS
BEGIN

SET NOCOUNT ON;

-- Update existing records

MERGE INTO [dbo].[BudgetPlanPNL] AS target

USING @AccTotalResult AS source

ON target.AccountCategory = source.AccountCategory

AND target.AccountGroup = source.AccountGroup

AND target.Year = source.Year

WHEN MATCHED THEN

UPDATE SET target.TotalResult = source.TotalResult

-- Insert new records

WHEN NOT MATCHED BY TARGET THEN

INSERT (AccountCategory, AccountGroup, Year, TotalResult)

VALUES (source.AccountCategory, source.AccountGroup, source.Year, source.TotalResult);

-- Additional logic if needed

/* -- Update existing records

UPDATE target

SET target.TotalResult = source.TotalResult

FROM [dbo].[BudgetPlanPNL] target

INNER JOIN @AccTotalResult source

ON target.AccountCategory = source.AccountCategory

AND target.AccountGroup = source.AccountGroup

AND target.Year = source.Year;

-- Insert new records

INSERT INTO [dbo].[BudgetPlanPNL] (AccountCategory, AccountGroup, Year, TotalResult)


SELECT t.AccountCategory, t.AccountGroup, t.Year, t.TotalResult

FROM @AccTotalResult t

WHERE NOT EXISTS (

SELECT 1

FROM [dbo].[BudgetPlanPNL] target

WHERE target.AccountCategory = t.AccountCategory

AND target.AccountGroup = t.AccountGroup

AND target.Year = t.Year

);

*/

END;

Note: We can also do this using the commented code i.e by writing update and insert command.

You might also like