Dynamic Allocation Of Bank Accounts To the Agents/Tellecaller

Rajnilari2015
Posted by in C# category on for Beginner level | Points: 250 | Views : 1740 red flag

This article will demonstrate a way of dynamically allocating Bank Accounts To the Agents/Tellecaller. This probem will fit perfectly in the allocation module of BFSI domain.


 Download source code for Dynamic Allocation Of Bank Accounts To the Agents/Tellecaller

Recommendation
Read Difference between Var and Object before this article.

Introduction

This is a real time situation.

Context

Let us consider that we have a Financial Institution (FI) which provides loan to various customers. So the FI will have a list of customer bank accounts. Now the FI's will have multiple Agencies under them for the EMI collection purpose.Say suppose there are 1000 bank accounts list of customers for a FI. And 10 Agencies are working under them.Say the FI has given 100 Customer Bank Accounts to each Agencies and the Agencies has to collect the EMI's from the respective customers.For that to happen,each Agencies will employ multiple Agents/Telecaller under them.And then the Agents will assign various customers under each Field Agent and the later's responsibility is to collect the pending amount/EMI's from the customers. Kindly note at this juncture that these customers have delinquent accounts.

Problem Statement

In the current system, the Agencies are allocating the customers(or customer bank accounts) manually to the Agents.But the proposed system needs to happen the allocation dynamically.

Let's say under Agency (say "AGENCY1" ), there are 9 customer bank accounts and 4 Agents (say Agent1,Agent2,Agent3,Agent4). The system should be intelligent enough to allocate the customer bank accounts to the Agents in such a way that -

Constraint

  1. It has to be as evenly distributed as possible.
  2. The allocation has to be in a sequential order.

What it means is that, if we try to distribute evenly those 9 customer bank accounts (say Account1,Account2...,Account9) to the 4 Agents, then the allocation will happen as

Agent1Account1,Account5,Account9
Agent2Account2,Account6
Agent3Account3,Account7
Agent4Account4,Account8

Algorithm

Let us first write the algorithm

	Step 1: Start
	Step 2: Get the Customer Bank Accounts list.
	Step 3: Get the Agents list.
	Step 4: Count of Step 2
	Step 5: Count of Step 3

	Step 6: 
		Case 1 : If Count(Step 4) < Count(Step 5) Then Go To Step 7.
		Case 2 : If Count(Step 4) = Count(Step 5) Then Go To Step 7.
		Case 3 : If Count(Step 4) > Count(Step 5) Then Go To Step 7.				 

	Step 7:
		a) Divide Count(Step 4) / Count(Step 5) + 1				 
		b) Number of Agents generated = Repeat of Agents in a Round Robin way till it exhausts Count(Step 5) * (a)

	Step 8: Map in a sequential way Step 6 and Step 2 until the smaller of them exhausts.
	Step 9: Group Customer Bank Accounts obtained in Step 7 by their Agents.
	Step 10: Display.
	Step 11: Stop.

Using the code

Let us now write the program satisfying the algorithm.We have intentionally left the Customer Bank Accounts list and Agents list as unpopulated collection because it will be filled on a case by case basis.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //step 1 - program starts            

	    //Data to be filled on a Case By Case Basis
            List<string> lstCustomerBankAccounts = new List<string>(); //Step 2
                                                   
	    //Data to be filled on a Case By Case Basis
            List<string> lstAgents = new List<string>(); //Step 3

            var countCustomerBankAccounts = lstCustomerBankAccounts.Count; //Step 4

            var countAgents = lstAgents.Count; //Step 5

            var repeatCount = countCustomerBankAccounts / countAgents + 1; //Step 6  
        
            var numberOfAgentsGenerated = Enumerable.Repeat(lstAgents, repeatCount).SelectMany(m => m); //Step 7 

            var customerBankAccountToAgentMapping =
                            numberOfAgentsGenerated
                            .Zip(lstCustomerBankAccounts,
                                    (agent, account) => new { Agent = agent, CustomerBankAccounts = account }
                                ); //Step 8

            var groupcustomerBankAccountByAgent = customerBankAccountToAgentMapping.GroupBy(a => a.Agent); //Step 9

            var result = groupcustomerBankAccountByAgent
                    .Select(g => new
                    {
                        Agent = g.Key
                        ,
                        Accounts = g.Select(x => x.CustomerBankAccounts).ToList()
                    }); 
            foreach (var r in result)
            {
                Console.WriteLine("Agent Name: " + r.Agent);
                foreach (var cba in r.Accounts)
                {
                    Console.WriteLine("     Is holding " + cba);
                }
                Console.WriteLine(Environment.NewLine);
            }//Step 10
            
            Console.ReadKey();//Step 11
        }        
    }
}

Now, it's time to check all the three cases.

Case 1: If Customer Bank Accounts list < Agents list

List<string> lstCustomerBankAccounts = new List<string>(){ "Account1", "Account2", "Account3"}; //Step 2

List<string> lstAgents = new List<string>(){ "Agent1", "Agent2", "Agent3", "Agent4" }; //Step 3

The output is as under

Case 2: If Customer Bank Accounts list = Agents list

List<string> lstCustomerBankAccounts = new List<string>(){ "Account1", "Account2", "Account3","Account4"}; //Step 2

List<string> lstAgents = new List<string>(){ "Agent1", "Agent2", "Agent3", "Agent4" }; //Step 3

The output is as under

Case 3: If Customer Bank Accounts list > Agents list

List<string> lstCustomerBankAccounts = new List<string>()
                                                    { "Account1", "Account2", "Account3",
                                                      "Account4", "Account5", "Account6",
                                                      "Account7","Account8","Account9"
                                                    }; //Step 2

List<string> lstAgents = new List<string>(){ "Agent1", "Agent2", "Agent3", "Agent4" }; //Step 3

The output is as under

As can be figure out that, our algorithm worked in all the three situations and hence the proof for the algorithm that solves the Dynamic Allocation Of Bank Accounts To the Agents/TelleCaller problem

The above program can be written in a more compact way as under

Enumerable
        .Repeat(lstAgents, lstCustomerBankAccounts.Count / lstAgents.Count + 1)
        .SelectMany(x => x)
        .Zip(lstCustomerBankAccounts, (agent, account) => new { Agent = agent, Account = account })
        .GroupBy(x => x.Agent)
        .Select(g => new { Agent = g.Key, Accounts = g.Select(x => x.Account).ToList() })
        .ToList()
        .ForEach(ag =>
        {
            Console.WriteLine("Agent Name: " + ag.Agent);
            ag.Accounts
            .ToList()
            .ForEach(cba =>
                        {
                            Console.WriteLine("     Is holding " + cba);
                        }

                    ); Console.WriteLine(Environment.NewLine);
        });
    Console.ReadKey();

Conclusion

In this article we have demonstrated the Dynamic Allocation Of Bank Accounts To the Agents/Tellecaller problem which is a very common use case for BFSI domain when the allocation module is consider and has come out with an algorithm that solves it as being proved by implementing the same using C# language.Hope this may come into help to some others who are working in a similar kind of domain or will serve as a reference to similar kind of problem.Thanks for reading. Zipped file attached.

Page copy protected against web site content infringement by Copyscape

About the Author

Rajnilari2015
Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,Microsoft_MVP,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team


Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)