An Example Data Migration
Analysis of MFI and their source data
MFI has ~100 offices (~70 are branchs) and wishes to migrate 5 of these branchs to mifos.
MFI has x amount of personnel, y of which are loan officers, z of which are other staff, such as data-entry, manager etc
MFI has 1 Loan Product (a individual loan applicable to clients, 1-24 installments, weekly installments)
No Centers as such.
Number of groups per branch?
Number of clients per group?
Group with many clients
Clients with individual loans and savings accounts
Custom Fields for client information
Decision is taken to manually enter Personnel, Offices, Reference Data (Loan Purposes),
Decision is taken to use an 'opening balance' approach. Basically for a specific branch and field-officer, if that field-officer is meeting with a praticular group on say Monday. Once the day is over, a spreadsheet with all the details of the loan for each client member of group is captured and the following details are tracked:
Original Loan Amount
no of installments
Disbursement Date
First Installment Date
Current Installment Date
Amount Paid to Date (Principla + Interest)
Loan Cycle
Loan Purpose
extraction, transformation and loading of data
This information is then extracted from template spreadsheet and (possibly transformed in some way) and loaded into mifos.
At this point this group is considered to be on mifos and from now on they should be using mifos application
Pros
Consolidation? ask ryan again?
Cons
Past history of loans is not captured.
Steps to getting setup
Create latest schema with lastest data
From a blank mifos schema:
- apply latest-schema.sql
- apply latest-data.sql
- update 'admin' users password to 'testmifos'
update personnel set password=0x22648ca42330a561964dbe32f54e6a04a49d03f203ca64b2515338d9 where personnel_id=1;
Use custom configuration files
After doing analysis on the mfi, it may be possible to put together application configuration files:
- edit applicationConfiguration.custom.properties and place in configuration directory e.g. MIFOS_CONF
- create mifosBeanConfig.custom.xml (think this must go in application server classpath (lib folder for instance))
- create mifosChartOfAccounts.custom.xml and place in configuration directory e.g. MIFOS_CONF
Launch Application
At this point you should be able to start mifos application against mifos schema. As a result the database at present has the following information:
- Latest database structure (tables, relationships, constrainst etc)
- Reference Data that comes out of box and must exist for mifos to startup
- Persistence of some configuration from applicationConfiguration.custom.properties which now cannot be changed.
Reference Data
Executing the following query will show you the existing reference data
SELECT l.lookup_id, le.entity_name, l.lookup_name, le.description FROM lookup_value l INNER JOIN lookup_entity le ON l.entity_id=le.entity_id order by l.entity_id, l.lookup_id;
Seed Reference Data
Reference data populated by applying latest-data.sql and which must exist for application to work.
Data Type |
entity_id |
Options |
---|---|---|
ClientStatus |
1 |
Pending Approval, active, on hold, cancelled, closed |
GroupStatus |
2 |
Partial, Pending, active, on hold, cancelled, closed |
AccountStates |
5 |
partial, pending, approved, disbursed to LO, active-good-standing, active-bad-standing, closed-obligations-met, closed-written-off, closed-rescheduled, cancelled |
PovertyStatus |
10 |
poor, very poor, non poor |
Gender |
16 |
male, female |
PersonnelLevels |
30 |
loan officer, non loan officer |
SpouseFather |
52 |
spouse, father, mother, child |
CustomerStatus |
53 |
active, inactive |
PersonnelStatus |
56 |
active, inactive |
Language |
74 |
English, Spanish, French, etc |
LivingStatus |
92 |
Together, Not Together |
Custom Reference Data
Reference data that is optional and typically different on a customer by customer basis
Data Type |
entity_id |
Options |
---|---|---|
Salutation |
15 |
Mr., Mrs. |
MaritalStatus |
17 |
single, married, seperated, widow |
Citizenship |
18 |
Roman Catholic,Protestant Baptist Pentecostal,Born Again Christian,Seventh Day Adventist,Iglesia Ni Kristo,Jehovahs Witness,Latter Day Saints,Islam,Others |
Ethinicity |
19 |
Yes, No |
EducationLevel |
20 |
Elementary, High School, College, Vocational, None |
BusinessActivities |
21 |
BuyAndSell, Vending, SariSariStore, Retailing, Dressmaking, Garments, Handicrafts, FoodProcessing, SoapMaking, PerfumeMaking, DishwashingDetergentMaking, BeadsAccessoriesMaking, Tailoring, Upholstery, Vulcanizing, DoormatMaking, TricycleOperator |
PersonnelTitles |
29 |
Program Officer, Program Unit Supervisor, Branch Accountant, Branch Accountant Assistant, Branch Manager |
NOTE: Citizenship is used to track religon
NOTE: Ethinicity is used to track ?
You should restart the application after inserting in custom reference data as lookup values are cached on start up.
SQL Script for inserting in customer specific reference data
-- Entity: Salutation insert into lookup_value(lookup_id,entity_id,lookup_name) values (2000, 15, 'Salutation-Mr'), (2001, 15, 'Salutation-Mrs'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2000,1, 2000,'Mr'), (2001,1, 2001,'Mrs'); -- Entity: MaritalStatus insert into lookup_value(lookup_id,entity_id,lookup_name) values (2002, 17, 'MaritalStatus-Single'), (2003, 17, 'MaritalStatus-Married'), (2004, 17, 'MaritalStatus-Seperated'), (2005, 17, 'MaritalStatus-Widow'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2002, 1, 2002, 'Single'), (2003, 1, 2003, 'Married'), (2004, 1, 2004, 'Seperated'), (2005, 1, 2005, 'Widow'); -- Entity: Citizenship insert into lookup_value(lookup_id,entity_id,lookup_name) values (2006, 18, 'Citizenship-RomanCatholic'), (2007, 18, 'Citizenship-ProtestantBaptistPentecostal'), (2008, 18, 'Citizenship-BornAgainChristian'), (2009, 18, 'Citizenship-SeventhDayAdventist'), (2010, 18, 'Citizenship-IglesiaNiKristo'), (2011, 18, 'Citizenship-JehovahsWitness'), (2012, 18, 'Citizenship-LatterDaySaints'), (2013, 18, 'Citizenship-Islam'), (2014, 18, 'Citizenship-Others'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2006, 1, 2006, 'Roman Catholic'), (2007, 1, 2007, 'Protestant Baptist Pentecostal'), (2008, 1, 2008, 'Born Again Christian'), (2009, 1, 2009, 'Seventh Day Adventist'), (2010, 1, 2010, 'Iglesia Ni Kristo'), (2011, 1, 2011, 'Jehovahs Witness'), (2012, 1, 2012, 'Latter Day Saints'), (2013, 1, 2013, 'Islam'), (2014, 1, 2014, 'Others'); -- Entity: Ethinicity insert into lookup_value(lookup_id,entity_id,lookup_name) values (2015, 19, 'Ethinicity-Yes'), (2016, 19, 'Ethinicity-No'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2015, 1, 2015, 'Yes'), (2016, 1, 2016, 'No'); -- Entity: EducationLevel insert into lookup_value(lookup_id,entity_id,lookup_name) values (2017, 20, 'EducationLevel-Elementary'), (2018, 20, 'EducationLevel-High School'), (2019, 20, 'EducationLevel-College'), (2020, 20, 'EducationLevel-Vocational'), (2021, 20, 'EducationLevel-None'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2017, 1, 2017, 'Elementary'), (2018, 1, 2018, 'High School'), (2019, 1, 2019, 'College'), (2020, 1, 2020, 'Vocational'), (2021, 1, 2021, 'None'); -- Entity: PersonnelTitles insert into lookup_value(lookup_id,entity_id,lookup_name) values (2022, 29, 'PersonnelTitles-ProgramOfficer'), (2023, 29, 'PersonnelTitles-ProgramUnitSupervisor'), (2024, 29, 'PersonnelTitles-BranchAccountant'), (2025, 29, 'PersonnelTitles-BranchAccountantAssistant'), (2026, 29, 'PersonnelTitles-BranchManager'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2022, 1, 2022, 'Program Officer'), (2023, 1, 2023, 'Program Unit Supervisor'), (2024, 1, 2024, 'Branch Accountant'), (2025, 1, 2025, 'Branch Accountant Assistant'), (2026, 1, 2026, 'Branch Manager'); -- Entity: BusinessActivities insert into lookup_value(lookup_id,entity_id,lookup_name) values (2027, 21, 'BusinessActivities-BuyAndSell'), (2028, 21, 'BusinessActivities-Vending'), (2029, 21, 'BusinessActivities-SariSariStore'), (2030, 21, 'BusinessActivities-Retailing'), (2031, 21, 'BusinessActivities-Dressmaking'), (2032, 21, 'BusinessActivities-Garments'), (2033, 21, 'BusinessActivities-Handicrafts'), (2034, 21, 'BusinessActivities-FoodProcessing'), (2035, 21, 'BusinessActivities-SoapMaking'), (2036, 21, 'BusinessActivities-PerfumeMaking'), (2037, 21, 'BusinessActivities-DishwashingDetergentMaking'), (2038, 21, 'BusinessActivities-BeadsAccessoriesMaking'), (2039, 21, 'BusinessActivities-Tailoring'), (2040, 21, 'BusinessActivities-Upholstery'), (2041, 21, 'BusinessActivities-Vulcanizing'), (2042, 21, 'BusinessActivities-DoormatMaking'), (2043, 21, 'BusinessActivities-TricycleOperator'); insert into lookup_value_locale(lookup_value_id,locale_id,lookup_id,lookup_value) values (2027, 1, 2027, 'Buy And Sell'), (2028, 1, 2028, 'Vending'), (2029, 1, 2029, 'Sari Sari Store'), (2030, 1, 2030, 'Retailing'), (2031, 1, 2031, 'Dressmaking'), (2032, 1, 2032, 'Garments'), (2033, 1, 2033, 'Handicrafts'), (2034, 1, 2034, 'Food Processing'), (2035, 1, 2035, 'Soap Making'), (2036, 1, 2036, 'Perfume Making'), (2037, 1, 2037, 'Dishwashing Detergent Making'), (2038, 1, 2038, 'Beads Accessories Making'), (2039, 1, 2039, 'Tailoring'), (2040, 1, 2040, 'Upholstery'), (2041, 1, 2041, 'Vulcanizing'), (2042, 1, 2042, 'Doormat Making'), (2043, 1, 2043, 'Tricycle Operator');
Roles and Permissions
- Relaunched application with all the reference data as shown above.
- Manually created five roles (Branch Accountant, Branch Accountant Assistant, Branch Manager, Program Officer, Program Unit Supervisor)
Model Organisation
After ensuring configuration, reference data is setup correctly for application, its time to add organizational items that are central to how mifos application works.
Model Office Hierarchy and offices
- There are ~100 offices of which ~70 are branches so there are other types of offices. An office hierarchy of Head Office -> Regional Office -> Area Office -> Branch Office is used (dropped divisional office)
- Manually created the first 11 offices: Customer Head Office, Luzon, North Luzon, Central Luzon, Capas, NCR, NCR North, Tandang Sora, Bulacan, Meycauayan, Valenzuela of which 4 were branch offices Capas, Tandang Sora, Meycauayan, Valenzuela.
NOTE: Only created first 11 up as far as Valenzuela as I want to migrate data for this branch into mifos.
Model Personnel/Staff/Application Users
- The first data to be migrated is for a specific branch-loan-officer-group so I manually create a Personnel as a loan officer and associate with Valenzuela branch.
Model Financial Products
- There is one general loan product available so manually created loan product.
- Didn't have much info on savings product so manually created volunatry savings product.
Migrate group information
Be Careful
Manually migrating group data cannot be done correctly without modifying the system date where the application is running or by somehow modifying the data directly on the database after the group has being created and activated.
Support Creation of Groups whoose activation date is in the past
Build flexibility into mifos services and API to allow groups to be created and activated with an activation date in the past.
Example code for using API to migrate Group (taking into account activiation/mfiJoining date in past)
package demo.migration; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.mifos.application.admin.servicefacade.AdminServiceFacade; import org.mifos.application.admin.servicefacade.OfficeServiceFacade; import org.mifos.application.admin.servicefacade.PersonnelServiceFacade; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.meeting.util.helpers.MeetingType; import org.mifos.application.meeting.util.helpers.RecurrenceType; import org.mifos.application.servicefacade.GroupServiceFacade; import org.mifos.application.servicefacade.SavingsServiceFacade; import org.mifos.calendar.DayOfWeek; import org.mifos.customers.util.helpers.CustomerStatus; import org.mifos.dto.domain.AddressDto; import org.mifos.dto.domain.ApplicableAccountFeeDto; import org.mifos.dto.domain.GroupCreationDetail; import org.mifos.dto.domain.MeetingDetailsDto; import org.mifos.dto.domain.MeetingDto; import org.mifos.dto.domain.MeetingRecurrenceDto; import org.mifos.dto.domain.MeetingTypeDto; import org.mifos.dto.screen.ProductDisplayDto; import org.mifos.framework.hibernate.helper.StaticHibernateUtil; import org.mifos.framework.util.helpers.Money; import org.mifos.security.AuthenticationAuthorizationServiceFacade; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class KMBIMigrationDemo { public static void main(String[] args) { System.setProperty("mifos.mode", "main"); String[] configLocations = new String[2]; configLocations[0] = "classpath:/org/mifos/config/resources/applicationContext.xml"; configLocations[1] = "classpath:META-INF/spring/QuestionnaireContext.xml"; // NOTE: Questionaire is coupled with applicationContext due to // QuestionaireMigration effort. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations); // NOTE: need to ensure hibernateUtil is initialised StaticHibernateUtil.initialize(); // NOTE: need to set default currency final MifosCurrency RUPEE = new MifosCurrency((short) 2, "RUPEE", BigDecimal.valueOf(1.0), "INR"); Money.setDefaultCurrency(RUPEE); System.out.println("fetching service"); GroupServiceFacade groupServiceFacade = applicationContext.getBean(GroupServiceFacade.class); AuthenticationAuthorizationServiceFacade authenticationAuthorizationServiceFacade = applicationContext.getBean(AuthenticationAuthorizationServiceFacade.class); System.out.println("found"); // authenticate first of all authenticationAuthorizationServiceFacade.reloadUserDetailsForSecurityContext("mifos"); String displayName = "VAL B-211"; Short loanOfficerId = Short.valueOf("2"); // hardcoded id of ALDRIN HONDANTE Short officeId = Short.valueOf("11"); // hardcoded office id of Valenzuela Short customerStatus = CustomerStatus.GROUP_ACTIVE.getValue(); boolean trained = true; DateTime trainedOn = new DateTime().withDate(2010, 11, 30); DateTime mfiJoiningDate = new DateTime().withDate(2010, 12, 06); DateTime activationDate = new DateTime().withDate(2010, 12, 06); GroupCreationDetail groupCreationDetail = createGroupDto(displayName, loanOfficerId, officeId, customerStatus, trained, trainedOn, mfiJoiningDate, activationDate); LocalDate meetingStartDate = new LocalDate(new DateTime().withDate(2010, 12, 06)); Integer dayOfWeek = DayOfWeek.monday(); Integer recurrenceTypeId = RecurrenceType.WEEKLY.getValue().intValue(); Integer every = Integer.valueOf(1); MeetingDto meeting = createMeetingDto(meetingStartDate, dayOfWeek, recurrenceTypeId, every); // create group ( groupServiceFacade.createNewGroup(groupCreationDetail, meeting); } private static MeetingDto createMeetingDto(LocalDate meetingStartDate, Integer dayOfWeek, Integer recurrenceTypeId, Integer every) { String meetingPlace = "SANTULAN MALABON CITY"; MeetingTypeDto meetingType = new MeetingTypeDto(MeetingType.CUSTOMER_MEETING.getValue().intValue(), "group meeting", "some description of meeting"); String recurrenceName = "weekly"; Integer dayNumber = Integer.valueOf(0); Integer weekOfMonth = null; MeetingRecurrenceDto recurrenceDetails = new MeetingRecurrenceDto(dayNumber, weekOfMonth, dayOfWeek); MeetingDetailsDto meetingDetailsDto = new MeetingDetailsDto(recurrenceTypeId, recurrenceName, every, recurrenceDetails); MeetingDto meeting = new MeetingDto(meetingStartDate, meetingPlace, meetingType, meetingDetailsDto); return meeting; } private static GroupCreationDetail createGroupDto(String displayName, Short loanOfficerId, Short officeId, Short customerStatus, boolean trained, DateTime trainedOn, DateTime mfiJoiningDate, DateTime activationDate) { String externalId = null; AddressDto addressDto = null; List<ApplicableAccountFeeDto> feesToApply = new ArrayList<ApplicableAccountFeeDto>(); String parentSystemId = null; GroupCreationDetail groupCreationDetail = new GroupCreationDetail(displayName, externalId, addressDto, loanOfficerId, feesToApply, customerStatus, trained, trainedOn, parentSystemId, officeId, mfiJoiningDate, activationDate); return groupCreationDetail; } }
Results of migrating group using API (taking into account activiation/mfiJoining date in past)
Meeting is created for every monday, weekly.
In customer table, entry for group has the following details of interest:
display name |
trained |
trained_date |
created_date |
created_by |
mfijoining_date |
customer_activation_date |
---|---|---|---|---|---|---|
VAL B-211 |
YES |
30-11-2010 |
19-01-2011 |
1 |
06-Dec-2010 |
06-Dec-2010 |
In the customer schedule table, ten customer schedules are created starting from 06-Dec-2010 ending 14-Feb-2011.
Be Careful
At present, only ten customer schedules are created when customer is activated and each night a batch job checks to see if more should be added. If the activation date is further than 10 of meeting periods away from today then there won't be a customer schedule existing for a meeting that should occur today or in the future until a batch job runs after midnight. So we should also check to see if customer activation date is in past and if so, create customer schedules from that date up to todays date, and then also create the 10 extra customer schedules for future meeting dates.
Migrate client members of group information
Be Careful
Manually migrating client data cannot be done correctly without modifying the system date where the application is running or by somehow modifying the data directly on the database after the group has being created and activated.
Support Creation of Clients whoose activation date is in the past
Build flexibility into mifos services and API to allow groups to be created and activated with an activation date in the past.
Example of migrating client information
package demo.migration; import java.io.InputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.mifos.application.admin.servicefacade.AdminServiceFacade; import org.mifos.application.admin.servicefacade.OfficeServiceFacade; import org.mifos.application.admin.servicefacade.PersonnelServiceFacade; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.meeting.util.helpers.MeetingType; import org.mifos.application.meeting.util.helpers.RecurrenceType; import org.mifos.application.servicefacade.ClientServiceFacade; import org.mifos.application.servicefacade.GroupServiceFacade; import org.mifos.application.servicefacade.SavingsServiceFacade; import org.mifos.application.util.helpers.YesNoFlag; import org.mifos.calendar.DayOfWeek; import org.mifos.customers.client.business.NameType; import org.mifos.customers.util.helpers.CustomerStatus; import org.mifos.dto.domain.AddressDto; import org.mifos.dto.domain.ApplicableAccountFeeDto; import org.mifos.dto.domain.ClientCreationDetail; import org.mifos.dto.domain.GroupCreationDetail; import org.mifos.dto.domain.MeetingDetailsDto; import org.mifos.dto.domain.MeetingDto; import org.mifos.dto.domain.MeetingRecurrenceDto; import org.mifos.dto.domain.MeetingTypeDto; import org.mifos.dto.domain.SavingsDetailDto; import org.mifos.dto.screen.ClientFamilyDetailDto; import org.mifos.dto.screen.ClientNameDetailDto; import org.mifos.dto.screen.ClientPersonalDetailDto; import org.mifos.dto.screen.ProductDisplayDto; import org.mifos.framework.hibernate.helper.StaticHibernateUtil; import org.mifos.framework.util.helpers.Money; import org.mifos.security.AuthenticationAuthorizationServiceFacade; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class KMBIMigrationDemo { public static void main(String[] args) { System.setProperty("mifos.mode", "main"); String[] configLocations = new String[2]; configLocations[0] = "classpath:/org/mifos/config/resources/applicationContext.xml"; configLocations[1] = "classpath:META-INF/spring/QuestionnaireContext.xml"; // NOTE: Questionaire is coupled with applicationContext due to // QuestionaireMigration effort. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configLocations); // NOTE: need to ensure hibernateUtil is initialised StaticHibernateUtil.initialize(); // NOTE: need to set default currency final MifosCurrency RUPEE = new MifosCurrency((short) 2, "RUPEE", BigDecimal.valueOf(1.0), "INR"); Money.setDefaultCurrency(RUPEE); System.out.println("fetching service"); ClientServiceFacade clientServiceFacade = applicationContext.getBean(ClientServiceFacade.class); AuthenticationAuthorizationServiceFacade authenticationAuthorizationServiceFacade = applicationContext.getBean(AuthenticationAuthorizationServiceFacade.class); System.out.println("found"); // authenticate first of all authenticationAuthorizationServiceFacade.reloadUserDetailsForSecurityContext("mifos"); List<Short> selectedSavingProducts = new ArrayList<Short>(); String clientName = "CARMELITA DAGALLA ALCARAZ"; Short clientStatus = CustomerStatus.CLIENT_ACTIVE.getValue(); boolean trained = true; Date trainedOn = new DateTime().withDate(2010, 11, 30).toDate(); Date mfiJoiningDate = new DateTime().withDate(2010, 12, 06).toDate(); LocalDate activationDate = new LocalDate(mfiJoiningDate); String externalId = null; AddressDto address = new AddressDto("48M. SANTOS ST. SANTULAN", null, null, "MALABON CITY", null, "PHILIPPINES", "1470", null); Short formedBy = null; Date dateOfBirth = new DateTime().withDate(1954, 5, 14).toDate(); String governmentId = null; Short groupFlag = YesNoFlag.YES.getValue(); Integer salutation = Integer.valueOf(2001); //Mrs. see custom reference-data for salutations String firstName = "CARMELITA"; String middleName = "DAGALLA"; String lastName = "ALCARAZ"; String secondLastName = null; ClientNameDetailDto clientNameDetailDto = new ClientNameDetailDto(NameType.CLIENT.getValue(), salutation, firstName, middleName, lastName, secondLastName); Integer ethinicity = Integer.valueOf(19); // no Integer citizenship = Integer.valueOf(2006); // roman catholic Integer handicapped = null; Integer businessActivities = Integer.valueOf(2029); // sari sari Integer maritalStatus = Integer.valueOf(2005); // widow Integer educationLevel = Integer.valueOf(2018); // high school Short numChildren = Short.valueOf("1"); Short gender = Short.valueOf("50"); // female Short povertyStatus = null; ClientPersonalDetailDto clientPersonalDetailDto = new ClientPersonalDetailDto(ethinicity, citizenship, handicapped, businessActivities, maritalStatus, educationLevel, numChildren, gender, povertyStatus); ClientNameDetailDto spouseFatherName = null; InputStream picture = null; List<ApplicableAccountFeeDto> feesToApply = new ArrayList<ApplicableAccountFeeDto>(); String parentGroupId = "5"; List<ClientNameDetailDto> familyNames = new ArrayList<ClientNameDetailDto>(); List<ClientFamilyDetailDto> familyDetails = new ArrayList<ClientFamilyDetailDto>(); Short loanOfficerId = null; // 2 inherit from parent Short officeId = null; // 11 inherit from parent ClientCreationDetail client = new ClientCreationDetail(selectedSavingProducts, clientName, clientStatus, mfiJoiningDate, externalId, address, formedBy, dateOfBirth, governmentId, trained, trainedOn, groupFlag, clientNameDetailDto, clientPersonalDetailDto, spouseFatherName, picture, feesToApply, parentGroupId, familyNames, familyDetails, loanOfficerId, officeId, activationDate); MeetingDto meeting = null; // will inherit meeting of parent group. List<SavingsDetailDto> savings = new ArrayList<SavingsDetailDto>(); clientServiceFacade.createNewClient(client, meeting, savings); } }
Results of migrating client using API (taking into account activiation/mfiJoining date in past)
Meeting is created for every monday, weekly.
In customer table, entry for client has the following details of interest:
display name |
trained |
trained_date |
created_date |
created_by |
mfijoining_date |
customer_activation_date |
---|---|---|---|---|---|---|
CARMELITA DAGALLA ALCARAZ |
YES |
30-11-2010 |
19-01-2011 |
1 |
06-Dec-2010 |
06-Dec-2010 |
In the customer schedule table, ten customer schedules are created starting from 06-Dec-2010 ending 14-Feb-2011.
Be Careful
At present, only ten customer schedules are created when customer is activated and each night a batch job checks to see if more should be added. If the activation date is further than 10 of meeting periods away from today then there won't be a customer schedule existing for a meeting that should occur today or in the future until a batch job runs after midnight. So we should also check to see if customer activation date is in past and if so, create customer schedules from that date up to todays date, and then also create the 10 extra customer schedules for future meeting dates.