<commit_before>package org.estatio.module.capex.app.paymentbatch;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
import javax.inject.Inject;

import com.google.common.collect.Lists;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.MemberOrder;
import org.apache.isis.applib.annotation.Nature;
import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.Publishing;
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
import org.apache.isis.applib.services.registry.ServiceRegistry2;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.applib.value.Blob;
import org.apache.isis.applib.value.Clob;

import org.isisaddons.module.excel.dom.ExcelService;

import org.estatio.module.base.dom.VisibilityEvaluator;
import org.estatio.module.capex.app.DebtorBankAccountService;
import org.estatio.module.capex.app.paymentline.PaymentLineForExcelExportV1;
import org.estatio.module.capex.dom.invoice.IncomingInvoice;
import org.estatio.module.capex.dom.invoice.IncomingInvoiceRepository;
import org.estatio.module.capex.dom.invoice.approval.IncomingInvoiceApprovalState;
import org.estatio.module.capex.dom.payment.CreditTransfer;
import org.estatio.module.capex.dom.payment.PaymentBatch;
import org.estatio.module.capex.dom.payment.PaymentBatchRepository;
import org.estatio.module.capex.dom.payment.PaymentLine;
import org.estatio.module.capex.dom.payment.approval.triggers.PaymentBatch_complete;
import org.estatio.module.capex.dom.util.InvoicePageRange;
import org.estatio.module.financial.dom.BankAccount;
import org.estatio.module.financial.dom.BankAccountRepository;
import org.estatio.module.invoice.dom.PaymentMethod;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@DomainObject(
        objectType = "org.estatio.capex.dom.payment.PaymentBatchManager"
        ,nature = Nature.VIEW_MODEL
)
public class PaymentBatchFraManager {

    public PaymentBatchFraManager() {
        this(null);
    }

    public PaymentBatchFraManager(final Integer selectedBatchIdx) {
        this.selectedBatchIdx = selectedBatchIdx;
    }

    public String title() {
        return "Payment Batch Manager";
    }


    @Getter @Setter
    private Integer selectedBatchIdx;


    public PaymentBatch getSelectedBatch() {
        final Integer selectedBatchIdx = getSelectedBatchIdx();
        if(selectedBatchIdx == null) {
            return null;
        }
        final List<PaymentBatch> newBatches = getNewBatches();
        if (newBatches.size() == 0) {
            return null;
        }

        return newBatches.get(selectedBatchIdx);
    }


    public List<CreditTransfer> getSelectedBatchTransfers(){
        final PaymentBatch selectedBatch = getSelectedBatch();
        if (selectedBatch == null) {
            return Collections.emptyList();
        }
        return Lists.newArrayList(selectedBatch.getTransfers());
    }

    public List<PaymentLine> getSelectedBatchPaymentLines(){
        final PaymentBatch selectedBatch = getSelectedBatch();
        if (selectedBatch == null) {
            return Collections.emptyList();
        }
        return Lists.newArrayList(selectedBatch.getLines());
    }


    public List<PaymentBatch> getNewBatches() {
        return paymentBatchRepository.findNewBatches().stream().filter(pb->!pb.getAtPath().startsWith("/ITA")).collect(Collectors.toList());
    }


    public List<PaymentBatch> getCompletedBatches() {
        return paymentBatchRepository.findCompletedBatches();
    }


    public List<IncomingInvoice> getPayableInvoicesNotInAnyBatch() {
        return incomingInvoiceRepository.findNotInAnyPaymentBatchByAtPathPrefixesAndApprovalStateAndPaymentMethod(
                IncomingInvoiceRepository.AT_PATHS_FRA_OFFICE,
                IncomingInvoiceApprovalState.PAYABLE,
                PaymentMethod.BANK_TRANSFER);
    }


    @Action(
            semantics = SemanticsOf.IDEMPOTENT,
            publishing = Publishing.DISABLED
    )
    public PaymentBatchFraManager autoCreateBatches(
            @Nullable final List<IncomingInvoice> payableInvoices) {

        for (final IncomingInvoice payableInvoice : payableInvoices) {
            final BankAccount uniqueBankAccountIfAny = debtorBankAccountService.uniqueDebtorAccountToPay(payableInvoice);
            if (uniqueBankAccountIfAny != null && uniqueBankAccountIfAny.getBic() != null) {
                // should be true, because those that don't pass this are filtered out in choicesXxx anyway.
                PaymentBatch paymentBatch = paymentBatchRepository.findOrCreateNewByDebtorBankAccount(uniqueBankAccountIfAny);
                paymentBatch.addLineIfRequired(payableInvoice);
            }
        }

        final List<PaymentBatch> newBatches = getNewBatches();
        for (final PaymentBatch paymentBatch : newBatches) {
            removeNegativeTransfers(paymentBatch);
        }

        return new PaymentBatchFraManager(newBatches.isEmpty()? null: 0);
    }

    /**
     * Removes (deletes) all {@link PaymentLine line}s that correspond to a transfer which is a net negative.
     */
    private void removeNegativeTransfers(PaymentBatch paymentBatch) {

        final List<PaymentLine> paymentLines = paymentBatch.getTransfers()
                .stream()
                .filter(x -> x.getAmount().compareTo(BigDecimal.ZERO) <= 0)
                .map(CreditTransfer::getLines)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        // seems to be necessary to flush everything through both before and after, presumably to deal with the
        // dependent collection (else get DN error about having added a deleted object to the batch's lines collection)
        flushTransaction();

        // this is sufficient, because PaymentBatch#lines is a dependent collection
        for (PaymentLine paymentLine : paymentLines){
            paymentBatch.getLines().remove(paymentLine);
        }

        // see discussion above.
        flushTransaction();

        if(paymentBatch.getLines().isEmpty()) {
            paymentBatch.remove();
        }
    }


    public List<IncomingInvoice> default0AutoCreateBatches() {
        return getPayableInvoicesNotInAnyBatchWithBankAccountAndBic();
    }

    public List<IncomingInvoice> choices0AutoCreateBatches() {
        List<IncomingInvoice> choices = Lists.newArrayList();

        final List<IncomingInvoice> invoices = getPayableInvoicesNotInAnyBatchWithBankAccountAndBic();
        for (final IncomingInvoice payableInvoice : invoices) {
            final BankAccount uniqueBankAccountIfAny = debtorBankAccountService.uniqueDebtorAccountToPay(payableInvoice);
            if (uniqueBankAccountIfAny != null && uniqueBankAccountIfAny.getBic() != null) {
                choices.add(payableInvoice);
            }
        }

        return choices;
    }

    private List<IncomingInvoice> getPayableInvoicesNotInAnyBatchWithBankAccountAndBic() {
        return getPayableInvoicesNotInAnyBatch().stream()
                .filter(pi -> pi.getBankAccount() != null && pi.getBankAccount().getBic() != null)
                .filter(visibilityEvaluator::visibleToMe)
                .collect(Collectors.toList());
    }


    @MemberOrder(name = "newBatches", sequence = "1")
    public PaymentBatchFraManager removeAll() {
        for (PaymentBatch paymentBatch : getNewBatches()) {
            paymentBatch.clearLines();
            paymentBatch.remove();
        }
        return new PaymentBatchFraManager();
    }




    @Action(
            semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE,
            publishing = Publishing.DISABLED
    )
    public PaymentBatchFraManager reset() {
<commit_msg>ECP-1137: removes choices from auto create batches on manager because unused<commit_after>package org.estatio.module.capex.app.paymentbatch;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Nullable;
import javax.inject.Inject;

import com.google.common.collect.Lists;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.CommandPersistence;
import org.apache.isis.applib.annotation.DomainObject;
import org.apache.isis.applib.annotation.MemberOrder;
import org.apache.isis.applib.annotation.Nature;
import org.apache.isis.applib.annotation.ParameterLayout;
import org.apache.isis.applib.annotation.Publishing;
import org.apache.isis.applib.annotation.SemanticsOf;
import org.apache.isis.applib.services.factory.FactoryService;
import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
import org.apache.isis.applib.services.registry.ServiceRegistry2;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.applib.value.Blob;
import org.apache.isis.applib.value.Clob;

import org.isisaddons.module.excel.dom.ExcelService;

import org.estatio.module.base.dom.VisibilityEvaluator;
import org.estatio.module.capex.app.DebtorBankAccountService;
import org.estatio.module.capex.app.paymentline.PaymentLineForExcelExportV1;
import org.estatio.module.capex.dom.invoice.IncomingInvoice;
import org.estatio.module.capex.dom.invoice.IncomingInvoiceRepository;
import org.estatio.module.capex.dom.invoice.approval.IncomingInvoiceApprovalState;
import org.estatio.module.capex.dom.payment.CreditTransfer;
import org.estatio.module.capex.dom.payment.PaymentBatch;
import org.estatio.module.capex.dom.payment.PaymentBatchRepository;
import org.estatio.module.capex.dom.payment.PaymentLine;
import org.estatio.module.capex.dom.payment.approval.triggers.PaymentBatch_complete;
import org.estatio.module.capex.dom.util.InvoicePageRange;
import org.estatio.module.financial.dom.BankAccount;
import org.estatio.module.financial.dom.BankAccountRepository;
import org.estatio.module.invoice.dom.PaymentMethod;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

@DomainObject(
        objectType = "org.estatio.capex.dom.payment.PaymentBatchManager"
        ,nature = Nature.VIEW_MODEL
)
public class PaymentBatchFraManager {

    public PaymentBatchFraManager() {
        this(null);
    }

    public PaymentBatchFraManager(final Integer selectedBatchIdx) {
        this.selectedBatchIdx = selectedBatchIdx;
    }

    public String title() {
        return "Payment Batch Manager";
    }


    @Getter @Setter
    private Integer selectedBatchIdx;


    public PaymentBatch getSelectedBatch() {
        final Integer selectedBatchIdx = getSelectedBatchIdx();
        if(selectedBatchIdx == null) {
            return null;
        }
        final List<PaymentBatch> newBatches = getNewBatches();
        if (newBatches.size() == 0) {
            return null;
        }

        return newBatches.get(selectedBatchIdx);
    }


    public List<CreditTransfer> getSelectedBatchTransfers(){
        final PaymentBatch selectedBatch = getSelectedBatch();
        if (selectedBatch == null) {
            return Collections.emptyList();
        }
        return Lists.newArrayList(selectedBatch.getTransfers());
    }

    public List<PaymentLine> getSelectedBatchPaymentLines(){
        final PaymentBatch selectedBatch = getSelectedBatch();
        if (selectedBatch == null) {
            return Collections.emptyList();
        }
        return Lists.newArrayList(selectedBatch.getLines());
    }


    public List<PaymentBatch> getNewBatches() {
        return paymentBatchRepository.findNewBatches().stream().filter(pb->!pb.getAtPath().startsWith("/ITA")).collect(Collectors.toList());
    }


    public List<PaymentBatch> getCompletedBatches() {
        return paymentBatchRepository.findCompletedBatches();
    }


    public List<IncomingInvoice> getPayableInvoicesNotInAnyBatch() {
        return incomingInvoiceRepository.findNotInAnyPaymentBatchByAtPathPrefixesAndApprovalStateAndPaymentMethod(
                IncomingInvoiceRepository.AT_PATHS_FRA_OFFICE,
                IncomingInvoiceApprovalState.PAYABLE,
                PaymentMethod.BANK_TRANSFER);
    }


    @Action(
            semantics = SemanticsOf.IDEMPOTENT,
            publishing = Publishing.DISABLED
    )
    public PaymentBatchFraManager autoCreateBatches() {

        for (final IncomingInvoice payableInvoice : getPayableInvoicesNotInAnyBatchWithBankAccountAndBic()) {
            final BankAccount uniqueBankAccountIfAny = debtorBankAccountService.uniqueDebtorAccountToPay(payableInvoice);
            if (uniqueBankAccountIfAny != null && uniqueBankAccountIfAny.getBic() != null) {
                PaymentBatch paymentBatch = paymentBatchRepository.findOrCreateNewByDebtorBankAccount(uniqueBankAccountIfAny);
                paymentBatch.addLineIfRequired(payableInvoice);
            }
        }

        final List<PaymentBatch> newBatches = getNewBatches();
        for (final PaymentBatch paymentBatch : newBatches) {
            removeNegativeTransfers(paymentBatch);
        }

        return new PaymentBatchFraManager(newBatches.isEmpty()? null: 0);
    }

    /**
     * Removes (deletes) all {@link PaymentLine line}s that correspond to a transfer which is a net negative.
     */
    private void removeNegativeTransfers(PaymentBatch paymentBatch) {

        final List<PaymentLine> paymentLines = paymentBatch.getTransfers()
                .stream()
                .filter(x -> x.getAmount().compareTo(BigDecimal.ZERO) <= 0)
                .map(CreditTransfer::getLines)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        // seems to be necessary to flush everything through both before and after, presumably to deal with the
        // dependent collection (else get DN error about having added a deleted object to the batch's lines collection)
        flushTransaction();

        // this is sufficient, because PaymentBatch#lines is a dependent collection
        for (PaymentLine paymentLine : paymentLines){
            paymentBatch.getLines().remove(paymentLine);
        }

        // see discussion above.
        flushTransaction();

        if(paymentBatch.getLines().isEmpty()) {
            paymentBatch.remove();
        }
    }

    private List<IncomingInvoice> getPayableInvoicesNotInAnyBatchWithBankAccountAndBic() {
        return getPayableInvoicesNotInAnyBatch().stream()
                .filter(pi -> pi.getBankAccount() != null && pi.getBankAccount().getBic() != null)
                .filter(visibilityEvaluator::visibleToMe)
                .collect(Collectors.toList());
    }


    @MemberOrder(name = "newBatches", sequence = "1")
    public PaymentBatchFraManager removeAll() {
        for (PaymentBatch paymentBatch : getNewBatches()) {
            paymentBatch.clearLines();
            paymentBatch.remove();
        }
        return new PaymentBatchFraManager();
    }




    @Action(
            semantics = SemanticsOf.IDEMPOTENT_ARE_YOU_SURE,
            publishing = Publishing.DISABLED
    )
    public PaymentBatchFraManager reset() {

{'fraction_non_alphanumeric': 0.0928589452435024, 'fraction_numerical': 0.0011355034065102195, 'mean_word_length': 3.419570671870644, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1571312', 'n_tokens_mistral': 4575, 'n_tokens_neox': 4386, 'n_words': 769}