| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.fineract.cn.accounting.importer; |
| |
| import org.apache.fineract.cn.accounting.api.v1.client.AccountAlreadyExistsException; |
| import org.apache.fineract.cn.accounting.api.v1.client.LedgerManager; |
| import org.apache.fineract.cn.accounting.api.v1.domain.Account; |
| import org.apache.fineract.cn.accounting.api.v1.domain.Ledger; |
| import org.apache.commons.csv.CSVFormat; |
| import org.apache.commons.csv.CSVParser; |
| import org.apache.commons.csv.CSVRecord; |
| import org.slf4j.Logger; |
| |
| import java.io.IOException; |
| import java.net.URL; |
| import java.nio.charset.StandardCharsets; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Objects; |
| import java.util.Set; |
| import java.util.stream.Collectors; |
| import java.util.stream.StreamSupport; |
| |
| /** |
| * @author Myrle Krantz |
| */ |
| @SuppressWarnings("unused") |
| public class AccountImporter { |
| private static final String TYPE_COLUMN = "type"; |
| private static final String IDENTIFIER_COLUMN = "identifier"; |
| private static final String NAME_COLUMN = "name"; |
| private static final String PARENT_IDENTIFIER_COLUMN = "parentIdentifier"; |
| private static final String HOLDERS_COLUMN = "holders"; |
| private static final String AUTHORITIES_COLUMN = "authorities"; |
| private static final String BALANCE_COLUMN = "balance"; |
| |
| private final LedgerManager ledgerManager; |
| private final Logger logger; |
| |
| public AccountImporter(final LedgerManager ledgerManager, final Logger logger) { |
| this.ledgerManager = ledgerManager; |
| this.logger = logger; |
| } |
| |
| public void importCSV(final URL toImport) throws IOException { |
| final CSVParser parser = CSVParser.parse(toImport, StandardCharsets.UTF_8, CSVFormat.RFC4180.withHeader()); |
| final List<RecordFromLineNumber<Account>> ledgerList = StreamSupport.stream(parser.spliterator(), false) |
| .map(this::toAccount) |
| .collect(Collectors.toList()); //File should fully parse, correctly, before we begin creating ledgers/accounts. |
| |
| ledgerList.forEach(this::createAccount); |
| } |
| |
| private void createAccount(final RecordFromLineNumber<Account> toCreate) { |
| try { |
| ledgerManager.createAccount(toCreate.getRecord()); |
| } |
| catch (final AccountAlreadyExistsException ignored) { |
| final Account account = ledgerManager.findAccount(toCreate.getRecord().getIdentifier()); |
| if ((!Objects.equals(account.getBalance(), toCreate.getRecord().getBalance())) || |
| (!Objects.equals(account.getIdentifier(), toCreate.getRecord().getIdentifier())) || |
| (!Objects.equals(account.getHolders(), toCreate.getRecord().getHolders())) || |
| (!Objects.equals(account.getLedger(), toCreate.getRecord().getLedger())) || |
| (!Objects.equals(account.getName(), toCreate.getRecord().getName())) || |
| (!Objects.equals(account.getSignatureAuthorities(), toCreate.getRecord().getSignatureAuthorities())) || |
| (!Objects.equals(account.getType(), toCreate.getRecord().getType()))) |
| { |
| logger.error("Creation of account {} failed, because an account with the same identifier but different properties already exists {}", toCreate.getRecord(), account); |
| } |
| } |
| } |
| |
| private RecordFromLineNumber<Account> toAccount(final CSVRecord csvRecord) { |
| try { |
| final String ledgerIdentifier = csvRecord.get(PARENT_IDENTIFIER_COLUMN); |
| String type; |
| try { |
| type = csvRecord.get(TYPE_COLUMN); |
| } |
| catch (final IllegalArgumentException e) { |
| final Ledger ledger = ledgerManager.findLedger(ledgerIdentifier); |
| type = ledger.getType(); |
| } |
| final String identifier = csvRecord.get(IDENTIFIER_COLUMN); |
| String name; |
| try { |
| name = csvRecord.get(NAME_COLUMN); |
| } |
| catch (final IllegalArgumentException e) { |
| name = identifier; |
| } |
| Set<String> holders; |
| try { |
| holders = new HashSet<>(Arrays.asList(csvRecord.get(HOLDERS_COLUMN).split("/"))); |
| } |
| catch (final IllegalArgumentException e) { |
| holders = Collections.emptySet(); |
| } |
| Set<String> authorities; |
| try { |
| authorities = new HashSet<>(Arrays.asList(csvRecord.get(AUTHORITIES_COLUMN).split("/"))); |
| } |
| catch (final IllegalArgumentException e) { |
| authorities = Collections.emptySet(); |
| } |
| Double balance; |
| try { |
| balance = Double.valueOf(csvRecord.get(BALANCE_COLUMN)); |
| } |
| catch (final IllegalArgumentException e) { |
| balance = 0.0; |
| } |
| |
| final Account account = new Account(); |
| |
| account.setType(type); |
| account.setIdentifier(identifier); |
| account.setName(name); |
| account.setHolders(holders); |
| account.setSignatureAuthorities(authorities); |
| account.setLedger(ledgerIdentifier); |
| account.setBalance(balance); |
| |
| return new RecordFromLineNumber<>(csvRecord.getRecordNumber(), account); |
| } |
| catch (final NumberFormatException e) { |
| logger.warn("Number parsing failed on record {}", csvRecord.getRecordNumber()); |
| throw e; |
| } |
| catch (final IllegalArgumentException e) { |
| logger.warn("Parsing failed on record {}", csvRecord.getRecordNumber()); |
| throw e; |
| } |
| } |
| } |