Example #1
0
  @Override
  public String modelChange(final PO po, final int type) throws Exception {
    if (type == TYPE_BEFORE_CHANGE) {
      final I_C_Order order = InterfaceWrapperHelper.create(po, I_C_Order.class);

      if (po.is_ValueChanged(I_C_Invoice_Candidate.COLUMNNAME_DateOrdered)) {
        final IOrderPA orderPA = Services.get(IOrderPA.class);
        final IInvoiceCandDAO invoiceCandDB = Services.get(IInvoiceCandDAO.class);

        for (final I_C_OrderLine ol : orderPA.retrieveOrderLines(order, I_C_OrderLine.class)) {
          for (final I_C_Invoice_Candidate icOfOl : invoiceCandDB.retrieveReferencing(ol)) {
            if (icOfOl.isToClear()) {
              // If the column was updatable, we would have to
              // *check if new and old term are the same
              // *check if ICAs need update, creation or deletion and do it;
              // *check which dataEntries' ActualQty needs update and make sure that they are not
              // yet
              // completed
              // *check is isToClear needs update;
              throw new AdempiereException(
                  Env.getAD_Language(po.getCtx()),
                  MSG_ORDER_DATE_ORDERED_CHANGE_FORBIDDEN_1P,
                  new Object[] {ol.getLine()});
            }
          }
        }
      }
    }
    return null;
  }
  private void reactivateAndComplete(
      final GridWindowHelper dataEntryHelper, final I_C_Flatrate_DataEntry dataEntry) {
    assertThat(
        dataEntry + " has wrong DocStatus",
        dataEntry.getDocStatus(),
        is(X_C_Flatrate_DataEntry.DOCSTATUS_Completed));

    final I_C_Invoice_Candidate icBeforeReactivation = dataEntry.getC_Invoice_Candidate();
    final I_C_Invoice_Candidate icCorrBeforeReactivation = dataEntry.getC_Invoice_Candidate_Corr();

    helper.reactivateEntry(dataEntryHelper);

    assertThat(
        dataEntry + " has wrong C_Invoice_Candidate_ID",
        dataEntry.getC_Invoice_Candidate_ID(),
        is(0));
    assertThat(
        dataEntry + " has wrong C_Invoice_Candidate_Corr_ID",
        dataEntry.getC_Invoice_Candidate_Corr_ID(),
        is(0));

    // invoice cand(s) should have been deleted
    final I_C_Invoice_Candidate icAfterReactivation =
        InterfaceWrapperHelper.create(
            driver.getCtx(),
            icBeforeReactivation.getC_Invoice_Candidate_ID(),
            I_C_Invoice_Candidate.class,
            driver.getTrxName());
    assertThat(icAfterReactivation, nullValue());
    final I_C_Invoice_Candidate icCorrAfterReactivation =
        InterfaceWrapperHelper.create(
            driver.getCtx(),
            icCorrBeforeReactivation.getC_Invoice_Candidate_ID(),
            I_C_Invoice_Candidate.class,
            driver.getTrxName());
    assertThat(icCorrAfterReactivation, nullValue());

    //
    // completing again
    //

    // expecting completion to fail, because depending invoice candidates have no been updated yet
    helper.completeEntry(dataEntryHelper, X_C_Flatrate_DataEntry.DOCSTATUS_Invalid);

    // running UpdateInvoiceCands and expecting the completIt to succeed
    invoiceCandHelper.runProcess_UpdateInvoiceCands();
    try {
      Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    helper.completeEntry(dataEntryHelper, X_C_Flatrate_DataEntry.DOCSTATUS_Completed);

    invoiceCandHelper.runProcess_UpdateInvoiceCands();
    dataEntryHelper.refresh();
  }
  /**
   * Makes an invoice run with the given <code>cands</code>.
   *
   * @param invoiceCandHelper
   * @param cands
   */
  private void processCands(
      final InvoiceCandHelper invoiceCandHelper, final I_C_Invoice_Candidate... cands) {
    invoiceCandHelper.runProcess_UpdateInvoiceCands();
    invoiceCandHelper.runProcess_InvoiceGenerateFromCands(cands);
    invoiceCandHelper.runProcess_UpdateInvoiceCands();

    for (final I_C_Invoice_Candidate cand : cands) {
      InterfaceWrapperHelper.refresh(cand);
      assertThat(cand + " has wrong 'Processed' status", cand.isProcessed(), is(true));
    }
  }
  private void checkInvoicingDataEntry(
      final I_C_Order order, final I_C_Flatrate_DataEntry dataEntry, final I_C_Flatrate_Term term) {
    assertThat(dataEntry.isSimulation(), equalTo(term.isSimulation()));
    assertThat(term.getC_Flatrate_Term_ID(), equalTo(dataEntry.getC_Flatrate_Term_ID()));

    final TestConfig testConfig = helper.getConfig();
    final boolean paramIsSimulation =
        testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_SIMULATION);

    final IFlatrateDAO flatrateDB = Services.get(IFlatrateDAO.class);

    BigDecimal sum = BigDecimal.ZERO;

    final boolean dataEntryCompleted =
        dataEntry.getDocStatus().equals(X_C_Flatrate_DataEntry.DOCSTATUS_Completed);

    final List<I_C_Invoice_Clearing_Alloc> clearingAllocs =
        flatrateDB.retrieveClearingAllocs(dataEntry);

    if (paramIsSimulation) {
      assertThat(
          "Expected *no* C_Invoice_Clearing_Allocs for " + dataEntry,
          clearingAllocs.size(),
          equalTo(0));
    } else {
      // note that we expect the C_Invoice_Clearing_Allocs no matter whether 'dataEntry' has already
      // been
      // completed
      assertThat(
          "Expected C_Invoice_Clearing_Allocs for " + dataEntry,
          clearingAllocs.size(),
          greaterThan(0));
    }

    for (final MOrderLine ol :
        driver.getHelper().mkOrderHelper().getOrderPO(order).getLines(true, null)) {
      for (final I_C_Invoice_Clearing_Alloc ica : clearingAllocs) {
        assertThat(ica.getC_Invoice_Cand_ToClear_ID(), greaterThan(0));

        assertThat(ica.getC_Flatrate_Term_ID(), equalTo(term.getC_Flatrate_Term_ID()));
        assertThat(
            ica.getC_Flatrate_DataEntry_ID(), equalTo(dataEntry.getC_Flatrate_DataEntry_ID()));

        final I_C_Invoice_Candidate icToClear = ica.getC_Invoice_Cand_ToClear();

        assertThat(
            icToClear + " has wrong C_OrderLine_ID",
            ol.getC_OrderLine_ID(),
            equalTo(icToClear.getC_OrderLine_ID()));

        assertThat(
            "Sales test driver should have called the update process",
            icToClear.isToRecompute(),
            is(false));
        assertThat(icToClear.isToClear(), is(true));

        if (dataEntryCompleted) {
          assertThat(ica.getC_Invoice_Candidate_ID(), greaterThan(0));
          assertThat(
              ica.getC_Invoice_Candidate_ID(), equalTo(dataEntry.getC_Invoice_Candidate_ID()));

          final I_C_Invoice_Candidate newCand = ica.getC_Invoice_Candidate();
          assertThat(
              "Sales test driver should have called the update process",
              newCand.isToRecompute(),
              is(false));

          assertThat(newCand.isToClear(), is(false));
          assertThat(newCand.isProcessed(), is(false));
          assertThat(icToClear + " has been marked a processed", icToClear.isProcessed(), is(true));
          assertThat(icToClear.getQtyInvoiced(), not(comparesEqualTo(BigDecimal.ZERO)));
          assertThat(icToClear.getQtyToInvoice(), comparesEqualTo(BigDecimal.ZERO));

          sum = sum.add(icToClear.getQtyInvoiced());
        } else {
          assertThat(ica.getC_Invoice_Candidate_ID(), equalTo(0));

          assertThat(icToClear + " has wrong 'Processed'", icToClear.isProcessed(), is(false));
          assertThat(
              icToClear + " has wrong 'QtyInvoiced'",
              icToClear.getQtyInvoiced(),
              comparesEqualTo(BigDecimal.ZERO));
          assertThat(
              icToClear + " has wrong 'QtyToInvoice'",
              icToClear.getQtyToInvoice(),
              not(comparesEqualTo(BigDecimal.ZERO)));

          sum = sum.add(icToClear.getQtyToInvoice());
        }
      }
    }

    if (!paramIsSimulation) {
      assertThat(
          "Expecting test config param 'PARAM_ACTUAL_QTY' to match C_FlatRate_DataEntry.ActualQty of "
              + dataEntry,
          testConfig.getCustomParamBD(PARAM_BD_ACTUAL_QTY),
          comparesEqualTo(dataEntry.getActualQty()));
      assertThat(
          "Expecting sum of invoice candidates to match C_FlatRate_DataEntry.ActualQty of "
              + dataEntry,
          sum,
          comparesEqualTo(dataEntry.getActualQty()));
    }
  }
  public void finishTerm(final TermAndOrder termAndOrder) {
    final TestConfig testConfig = helper.getConfig();

    final I_C_Flatrate_Term term = termAndOrder.term;
    final I_C_Order order = termAndOrder.order;
    final I_C_Flatrate_Conditions fc = term.getC_Flatrate_Conditions();

    final GridWindowHelper dataEntryHelper = helper.retrieveMainInvoicingEntry(fc, order);
    final I_C_Flatrate_DataEntry dataEntry =
        dataEntryHelper.getGridTabInterface(I_C_Flatrate_DataEntry.class);

    final boolean paramIsSimulation =
        testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_SIMULATION);

    if (!paramIsSimulation) {
      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_AMOUNT + " for " + dataEntry,
          dataEntry.getFlatrateAmt(),
          comparesEqualTo(testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_AMOUNT)));
      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_QTY_PER_UNIT + " for " + dataEntry,
          dataEntry.getActualQtyPerUnit(),
          comparesEqualTo(
              testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_QTY_PER_UNIT)));
      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PER_UNIT + " for " + dataEntry,
          dataEntry.getActualQtyDiffPerUOM(),
          comparesEqualTo(
              testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PER_UNIT)));

      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_EFF_PERCENT + " for " + dataEntry,
          dataEntry.getActualQtyDiffPercentEff(),
          comparesEqualTo(
              testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_EFF_PERCENT)));
      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PERCENT + " for " + dataEntry,
          dataEntry.getActualQtyDiffPercent(),
          comparesEqualTo(
              testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PERCENT)));
      assertThat(
          FlatFeeScenario.PARAM_BD_EXP_ACTUAL_CORR_AMOUNT + " for " + dataEntry,
          dataEntry.getFlatrateAmtCorr(),
          comparesEqualTo(
              testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_CORR_AMOUNT)));

      final I_C_Invoice_Candidate invoiceCand = dataEntry.getC_Invoice_Candidate();

      assertThat(invoiceCand.getM_Product_ID(), is(fc.getM_Product_Flatrate_ID()));

      if (fc.getM_Product_Actual_ID() == fc.getM_Product_Flatrate_ID()
          && !fc.isCorrectionAmtAtClosing()) {
        assertThat(dataEntry.getC_Invoice_Candidate_Corr_ID(), is(0));

        assertThat(
            invoiceCand.getNetAmtToInvoice(),
            comparesEqualTo(dataEntry.getFlatrateAmt().add(dataEntry.getFlatrateAmtCorr())));

        processCands(invoiceCandHelper, invoiceCand);

        assertThat(
            invoiceCand.getNetAmtInvoiced(),
            comparesEqualTo(dataEntry.getFlatrateAmt().add(dataEntry.getFlatrateAmtCorr())));
      } else {
        assertThat(invoiceCand.getNetAmtToInvoice(), comparesEqualTo(dataEntry.getFlatrateAmt()));

        if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) {
          assertThat(fc.isCorrectionAmtAtClosing(), is(true)); // just a little guard
          assertThat(
              dataEntry + " has wrong C_Invoice_Candidate_Corr_ID",
              dataEntry.getC_Invoice_Candidate_Corr_ID(),
              is(0));
          processCands(invoiceCandHelper, invoiceCand);
        } else {
          assertThat(fc.isCorrectionAmtAtClosing(), is(false)); // just a little guard
          assertThat(dataEntry.getC_Invoice_Candidate_Corr_ID(), greaterThan(0));
          final I_C_Invoice_Candidate invoiceCandCorr = dataEntry.getC_Invoice_Candidate_Corr();

          assertThat(invoiceCandCorr.getM_Product_ID(), is(fc.getM_Product_Actual_ID()));
          assertThat(
              invoiceCandCorr.getNetAmtToInvoice(),
              comparesEqualTo(dataEntry.getFlatrateAmtCorr()));

          processCands(invoiceCandHelper, invoiceCand, invoiceCandCorr);

          assertThat(
              invoiceCandCorr.getNetAmtInvoiced(), comparesEqualTo(dataEntry.getFlatrateAmtCorr()));
        }

        assertThat(invoiceCand.getNetAmtInvoiced(), comparesEqualTo(dataEntry.getFlatrateAmt()));
      }
    }

    // now complete all dataEntries with a Qty_reported of 1 each
    final List<I_C_Invoice_Candidate> allCandidates =
        helper.completeAllInvoicingEntries(term, BigDecimal.ONE);
    if (!paramIsSimulation) {
      assertThat(allCandidates.size(), greaterThan(0));
    }
    processCands(
        invoiceCandHelper, allCandidates.toArray(new I_C_Invoice_Candidate[allCandidates.size()]));

    if (!term.isClosingWithCorrectionSum()) {
      // we are done
      return;
    }

    final MPeriod closingPeriod =
        MPeriod.findByCalendar(
            driver.getCtx(),
            term.getEndDate(),
            fc.getC_Flatrate_Transition().getC_Calendar_Contract_ID(),
            driver.getTrxName());

    helper
        .mkProcessHelper()
        .setProcessClass(C_Flatrate_Term_Prepare_Closing.class)
        .setPO(term)
        .setParameter(I_C_Period.COLUMNNAME_C_Period_ID, closingPeriod.getC_Period_ID())
        .run();

    final GridWindowHelper entryGridWindowHelper = helper.retrieveMainCorrectionEntry(fc, term);
    final I_C_Flatrate_DataEntry correctionEntry =
        entryGridWindowHelper.getGridTabInterface(I_C_Flatrate_DataEntry.class);

    // expecting <PARAM_TRANSITION_TERM_DURATION> times 1 plus <PARAM_BD_UNITS_REPORTED>
    assertThat(
        correctionEntry + " has wrong Qty_Planned",
        correctionEntry.getQty_Planned(),
        comparesEqualTo(
            new BigDecimal(
                    testConfig.getCustomParamInt(ContractsHelper.PARAM_TRANSITION_TERM_DURATION))
                .add(testConfig.getCustomParamBD(PARAM_BD_UNITS_REPORTED))));

    final BigDecimal correctionQty =
        testConfig.getCustomParamBD(PARAM_BD_UNITS_REPORTED).add(new BigDecimal("2"));
    correctionEntry.setQty_Reported(correctionQty);

    helper.completeEntry(entryGridWindowHelper, X_C_Flatrate_DataEntry.DOCSTATUS_Completed);
    invoiceCandHelper.runProcess_UpdateInvoiceCands();

    assertThat(
        correctionEntry + " wrong FlatrateAmtPerUOM",
        correctionEntry.getFlatrateAmtPerUOM(),
        comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_PRICE_PER_UNIT_CLOSING)));
    assertThat(
        correctionEntry + " wrong FlatrateAmt",
        correctionEntry.getFlatrateAmt(),
        comparesEqualTo(
            correctionQty
                .subtract(correctionEntry.getQty_Planned())
                .multiply(correctionEntry.getFlatrateAmtPerUOM())));

    if (testConfig.getCustomParamBool(PARAM_BOOL_IS_SIMULATION)) {
      assertThat(correctionEntry.getC_Invoice_Candidate_ID(), is(0));
      assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), is(0));

      if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) {
        assertThat(
            correctionEntry + " has wrong ActualQty",
            correctionEntry.getActualQty(),
            comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_ACTUAL_QTY)));
        assertThat(
            correctionEntry + " has wrong FlatrateAmtCorr.signum()",
            correctionEntry.getFlatrateAmtCorr().signum(),
            not(is(0)));
      }
    } else {
      assertThat(correctionEntry.getC_Invoice_Candidate_ID(), greaterThan(0));
      final I_C_Invoice_Candidate correctionEntryCand = correctionEntry.getC_Invoice_Candidate();

      assertThat(
          correctionEntryCand + " wrong M_Product_ID",
          correctionEntryCand.getM_Product_ID(),
          is(fc.getM_Product_Correction_ID()));
      assertThat(
          correctionEntryCand + " wrong NetAmtToInvoice",
          correctionEntryCand.getNetAmtToInvoice(),
          comparesEqualTo(correctionEntry.getFlatrateAmt()));

      if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) {
        assertThat(
            correctionEntry + " has wrong ActualQty",
            correctionEntry.getActualQty(),
            comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_ACTUAL_QTY)));

        // note: the actual numbers are checked in a unit test
        assertThat(
            correctionEntry + " has wrong FlatrateAmtCorr().signum()",
            correctionEntry.getFlatrateAmtCorr().signum(),
            greaterThan(0));
        assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), greaterThan(0));

        final I_C_Invoice_Candidate correctionEntryCorrCand =
            correctionEntry.getC_Invoice_Candidate_Corr();
        assertThat(correctionEntryCorrCand.getM_Product_ID(), is(fc.getM_Product_Actual_ID()));
        assertThat(
            correctionEntryCorrCand.getNetAmtToInvoice(),
            comparesEqualTo(correctionEntry.getFlatrateAmtCorr()));
      } else {
        assertThat(correctionEntry.getFlatrateAmtCorr().signum(), equalTo(0));
        assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), equalTo(0));
      }
    }
  }