/**
   * Update Tax & Header
   *
   * @return true if header updated
   */
  private boolean updateHeaderTax() {
    // Recalculate Tax for this Tax
    if (!getParent().isProcessed()) {
      if (!updateOrderTax(false)) {
        return false;
      }
    }

    // task 08999:
    // Avoid a possible deadlock by updating the C_Order *after* the current transaction, because at
    // this point we might already hold a lot of locks to different objects.
    // The updates in updateHeader0 will try aggregate and obtain any number of additional shared
    // locks.
    // Concrete, we observed a deadlock between this code and
    // M_ReceiptSchedule.propagateQtysToOrderLine()
    final ITrxManager trxManager = Services.get(ITrxManager.class);
    trxManager
        .getTrxListenerManager(get_TrxName())
        .registerListener(
            new TrxListenerAdapter() {
              @Override
              public void afterCommit(final ITrx trx) {
                trxManager.run(
                    new TrxRunnableAdapter() {
                      @Override
                      public void run(final String localTrxName) throws Exception {
                        updateHeader0(getC_Order_ID());
                      }
                    });
              }
            });
    return true;
  } // updateHeaderTax
  private void assertThreadInheritedTrxSet() {
    final String trxName = trxManager.getThreadInheritedTrxName();
    Assert.assertTrue(
        "Thread inherited transaction shall be set at this point", !trxManager.isNull(trxName));

    Assert.assertEquals(
        "Thread inherited transaction shall match context transaction",
        processorCtx.getTrxName(),
        trxName);

    if (expectTrxSavepoints != null) {
      final PlainTrx trx = (PlainTrx) processorCtx.getTrx();
      Assert.assertEquals(
          "Active savepoints for " + trx, expectTrxSavepoints, trx.hasActiveSavepoints());
    }
  }
Exemple #3
0
  @Test
  public void test_GuaranteedPOBufferedIterator_changingData() throws Exception {
    final ITrxManager trxManager = Services.get(ITrxManager.class);
    final String trxName = trxManager.createTrxName("Test");
    trxManager.run(
        trxName,
        new TrxRunnable() {

          @Override
          public void run(final String localTrxName) throws Exception {
            test_GuaranteedPOBufferedIterator_changingData(localTrxName);
          }
        });

    DB.rollback(true, trxName);
  }
  /** Asserts dialog is opened out of transaction. */
  public static final void assertUIOutOfTransaction() {
    final ITrxManager trxManager = Services.get(ITrxManager.class);
    final String trxName = trxManager.getThreadInheritedTrxName(OnTrxMissingPolicy.ReturnTrxNone);
    if (!trxManager.isNull(trxName)) {
      final AdempiereException ex =
          new AdempiereException(
              "Opening a dialog while running in a trasaction it's always a bad idea"
                  + " because the database will be kept locked until the user will answer.");

      // NOTE: this issue is so critical that it's better to throw exception instead to just advice
      if (Services.get(IDeveloperModeBL.class).isEnabled()) {
        throw ex;
      } else {
        // In case we run in production, we won't fail because that would be a show stopper, but we
        // will log the exception.
        log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
      }
    }
  }
  /**
   * Save Selection
   *
   * @return asi which was saved or null
   * @return true if saved
   */
  private MAttributeSetInstance saveSelection() {
    final IMutable<MAttributeSetInstance> asiRef = new Mutable<>();
    trxManager.run(
        new TrxRunnableAdapter() {
          @Override
          public void run(String localTrxName) throws Exception {
            final MAttributeSetInstance asi = saveSelection0();
            asiRef.setValue(asi);
          }
        });

    return asiRef.getValue();
  }
  private boolean addGLJournalLine(final I_GL_JournalLine glJournalLine) {
    final AtomicBoolean addedRef = new AtomicBoolean(false);
    trxManager.run(
        getTrxNameInitial(),
        new TrxRunnable() {

          @Override
          public void run(final String localTrxName) throws Exception {
            final boolean added = addGLJournalLine0(glJournalLine);
            addedRef.set(added);
          }
        });

    return addedRef.get();
  }
  @Override
  public I_M_HU_LUTU_Configuration createLUTUConfiguration(
      final I_M_HU_PI_Item_Product tuPIItemProduct,
      final I_M_Product cuProduct,
      final I_C_UOM cuUOM,
      final org.compiere.model.I_C_BPartner bpartner) {
    Check.assumeNotNull(tuPIItemProduct, "tuPIItemProduct not null");
    Check.assumeNotNull(cuProduct, "cuProduct not null");
    Check.assumeNotNull(cuUOM, "cuUOM not null");

    // Services used:
    final ITrxManager trxManager = Services.get(ITrxManager.class);
    final IHandlingUnitsDAO handlingUnitsDAO = Services.get(IHandlingUnitsDAO.class);
    final IHUCapacityBL huCapacityBL = Services.get(IHUCapacityBL.class);

    //
    // Context
    final Properties ctx = InterfaceWrapperHelper.getCtx(tuPIItemProduct);
    final IContextAware contextProvider;
    final String threadTrxName = trxManager.getThreadInheritedTrxName();
    if (trxManager.isNull(threadTrxName)) {
      contextProvider = new PlainContextAware(ctx, ITrx.TRXNAME_None);
    } else {
      contextProvider = trxManager.createThreadContextAware(ctx);
    }

    //
    // LU/TU configuration (draft)
    final I_M_HU_LUTU_Configuration lutuConfiguration =
        InterfaceWrapperHelper.newInstance(I_M_HU_LUTU_Configuration.class, contextProvider);
    lutuConfiguration.setC_BPartner(bpartner);
    lutuConfiguration.setIsActive(true);

    //
    // TU Configuration
    final I_M_HU_PI tuPI = tuPIItemProduct.getM_HU_PI_Item().getM_HU_PI_Version().getM_HU_PI();
    final IHUCapacityDefinition tuCapacity =
        huCapacityBL.getCapacity(tuPIItemProduct, cuProduct, cuUOM);
    //
    lutuConfiguration.setM_HU_PI_Item_Product(tuPIItemProduct);
    lutuConfiguration.setM_TU_HU_PI(tuPI);
    lutuConfiguration.setM_Product(cuProduct);
    lutuConfiguration.setC_UOM(cuUOM);
    if (tuCapacity.isInfiniteCapacity()) {
      lutuConfiguration.setIsInfiniteQtyCU(true);
      lutuConfiguration.setQtyCU(BigDecimal.ZERO);
    } else {
      lutuConfiguration.setIsInfiniteQtyCU(false);
      lutuConfiguration.setQtyCU(tuCapacity.getCapacity());
    }

    //
    // LU Configuration
    final I_M_HU_PI_Item luPIItem =
        handlingUnitsDAO.retrieveDefaultParentPIItem(
            tuPI, X_M_HU_PI_Version.HU_UNITTYPE_LoadLogistiqueUnit, bpartner);
    if (luPIItem != null) {
      final I_M_HU_PI luPI = luPIItem.getM_HU_PI_Version().getM_HU_PI();
      lutuConfiguration.setM_LU_HU_PI(luPI);
      lutuConfiguration.setM_LU_HU_PI_Item(luPIItem);

      lutuConfiguration.setIsInfiniteQtyLU(true); // we produce as many as needed
      lutuConfiguration.setQtyLU(BigDecimal.ZERO);

      final int qtyTU = luPIItem.getQty().intValueExact();
      lutuConfiguration.setIsInfiniteQtyTU(false);
      lutuConfiguration.setQtyTU(BigDecimal.valueOf(qtyTU));
    } else {
      lutuConfiguration.setM_LU_HU_PI(null);
      lutuConfiguration.setM_LU_HU_PI_Item(null);

      lutuConfiguration.setIsInfiniteQtyLU(false);
      lutuConfiguration.setQtyLU(BigDecimal.ZERO);

      lutuConfiguration.setIsInfiniteQtyTU(true); // as many as needed
      lutuConfiguration.setQtyTU(BigDecimal.ZERO);
    }

    return lutuConfiguration;
  }
  /**
   * If the bpartner's <code>DocumentCopies</code> changes, then this method updates all unprocessed
   * C_Printing_Queues which reference the bpartner. The update is performed in a dedicated
   * transaction, after the MV's current trx is committed.
   *
   * @task
   *     http://dewiki908/mediawiki/index.php/08958_Druck_Warteschlange_Sortierung_Massendruck_%28103271838939%29
   */
  @ModelChange(
      timings = {ModelValidator.TYPE_AFTER_CHANGE},
      ifColumnsChanged = I_C_BPartner.COLUMNNAME_DocumentCopies)
  public void setCopiesFromBPartner(final I_C_BPartner bPartner) {
    final int documentCopies =
        bPartner.getDocumentCopies() > 0 ? bPartner.getDocumentCopies() : 1; // default

    final ITrxManager trxManager = Services.get(ITrxManager.class);
    trxManager
        .getTrxListenerManager(InterfaceWrapperHelper.getTrxName(bPartner))
        .registerListener(
            new TrxListenerAdapter() {
              @Override
              public void afterCommit(final ITrx trx) {
                trxManager.run(
                    new TrxRunnable() {
                      @Override
                      public void run(final String localTrxName) throws Exception {
                        final Properties ctx = InterfaceWrapperHelper.getCtx(bPartner);

                        final IQueryBL queryBL = Services.get(IQueryBL.class);

                        // 08958: for the starts, we only update queue items that reference invoices
                        final IQuery<I_C_DocType> invoicedocTypeQuery =
                            queryBL
                                .createQueryBuilder(
                                    I_C_DocType.class, ctx, ITrx.TRXNAME_ThreadInherited)
                                .addOnlyActiveRecordsFilter()
                                .addInArrayFilter(
                                    I_C_DocType.COLUMNNAME_DocBaseType,
                                    X_C_DocType.DOCBASETYPE_APCreditMemo,
                                    X_C_DocType.DOCBASETYPE_APInvoice,
                                    X_C_DocType.DOCBASETYPE_ARCreditMemo,
                                    X_C_DocType.DOCBASETYPE_ARInvoice,
                                    X_C_DocType.DOCBASETYPE_ARProFormaInvoice)
                                .create();

                        final int updatedCount =
                            queryBL
                                .createQueryBuilder(
                                    I_C_Printing_Queue.class, ctx, ITrx.TRXNAME_ThreadInherited)
                                .addOnlyActiveRecordsFilter()
                                .addEqualsFilter(
                                    I_C_Printing_Queue.COLUMN_C_BPartner_ID,
                                    bPartner.getC_BPartner_ID())
                                .addEqualsFilter(I_C_Printing_Queue.COLUMN_Processed, false)
                                .addInSubQueryFilter(
                                    I_C_Printing_Queue.COLUMN_C_DocType_ID,
                                    I_C_DocType.COLUMN_C_DocType_ID,
                                    invoicedocTypeQuery)
                                .addNotEqualsFilter(
                                    I_C_Printing_Queue.COLUMN_Copies, documentCopies)
                                .create()
                                .updateDirectly()
                                .addSetColumnValue(
                                    I_C_Printing_Queue.COLUMNNAME_Copies, documentCopies)
                                .setExecuteDirectly(true) // just to be sure
                                .execute();

                        logger.debug(
                            "C_BPartner={}: set C_Printing_Queue.Copies={} for {} C_Printing_Queue records",
                            new Object[] {bPartner, documentCopies, updatedCount});
                      }
                    });
              }
            });
  }