@Override
  public List<I_M_HU_Assignment> retrieveIncludedHUAssignments(final I_M_HU_Assignment assignment) {
    final IQueryBL queryBL = Services.get(IQueryBL.class);
    final IQueryBuilder<I_M_HU_Assignment> queryBuilder =
        queryBL.createQueryBuilder(I_M_HU_Assignment.class, assignment);

    queryBuilder
        // references same record..
        .addEqualsFilter(I_M_HU_Assignment.COLUMN_AD_Table_ID, assignment.getAD_Table_ID())
        .addEqualsFilter(I_M_HU_Assignment.COLUMN_Record_ID, assignment.getRecord_ID())
        // ..and same toplevel-HU..
        .addEqualsFilter(I_M_HU_Assignment.COLUMN_M_HU_ID, assignment.getM_HU_ID());

    // ..but additionally references one of the HU's components (TU or LU)
    final ICompositeQueryFilter<I_M_HU_Assignment> subFilter =
        queryBL.createCompositeQueryFilter(I_M_HU_Assignment.class);
    subFilter
        .setJoinOr()
        .addNotEqualsFilter(I_M_HU_Assignment.COLUMN_M_LU_HU_ID, null)
        .addNotEqualsFilter(I_M_HU_Assignment.COLUMN_M_TU_HU_ID, null);

    queryBuilder.filter(subFilter);

    //
    return queryBuilder.create().list(I_M_HU_Assignment.class);
  }
  @Override
  public void cleanup(final IMRPContext mrpContext, final IMRPExecutor executor) {
    // If DRP module is not activated, then skip the cleanup
    if (!mrpContext.isRequireDRP()) {
      return;
    }

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

    //
    // Delete generated distribution orders
    // (i.e. Distribution Order with Draft Status)
    final ICompositeQueryFilter<I_DD_Order> filters =
        queryBL.createCompositeQueryFilter(I_DD_Order.class);
    filters.addEqualsFilter(I_DD_Order.COLUMNNAME_DocStatus, X_DD_Order.DOCSTATUS_Drafted);

    //
    // Only those which were generated by MRP
    filters.addEqualsFilter(I_DD_Order.COLUMN_MRP_Generated, true);
    // Only those which are allowed to be deleted by MRP cleanup
    filters.addEqualsFilter(I_DD_Order.COLUMN_MRP_AllowCleanup, true);

    //
    // Only for our AD_Client_ID
    filters.addEqualsFilter(I_DD_Order.COLUMNNAME_AD_Client_ID, mrpContext.getAD_Client_ID());
    //
    // Only for our AD_Org_ID
    filters.addEqualsFilter(I_DD_Order.COLUMNNAME_AD_Org_ID, mrpContext.getAD_Org().getAD_Org_ID());
    //
    // Only those DD Orders which are from our Plant or does not have a plant at all
    filters.addInArrayFilter(
        I_DD_Order.COLUMNNAME_PP_Plant_ID, null, mrpContext.getPlant().getS_Resource_ID());

    //
    // Only those which have a line with Destination Warehouse same as our warehouse
    final int targetWarehouseId = mrpContext.getM_Warehouse().getM_Warehouse_ID();
    filters.addFilter(
        Services.get(IDDOrderDAO.class)
            .getDDOrdersForTargetWarehouseQueryFilter(targetWarehouseId));

    //
    // If we are running in an constrained MRP Context, filter only those documents
    if (mrpContext.getEnforced_PP_MRP_Demand_ID() > 0) {
      final IQuery<I_PP_MRP> mrpQuery =
          createMRPQueryBuilderForCleanup(mrpContext, executor)
              .createQueryBuilder()
              .addEqualsFilter(I_PP_MRP.COLUMN_TypeMRP, X_PP_MRP.TYPEMRP_Supply)
              .create();

      filters.addInSubQueryFilter(
          I_DD_Order.COLUMN_DD_Order_ID, I_PP_MRP.COLUMN_DD_Order_ID, mrpQuery);
    }

    deletePO(mrpContext, executor, I_DD_Order.class, filters);
  }
  /**
   * Delete MRP Alternative records for given {@link I_DD_OrderLine_Alternative}.
   *
   * @param ddOrderLineAlt
   */
  private void deleteMRPAlternatives(final I_DD_OrderLine_Alternative ddOrderLineAlt) {
    Check.assumeNotNull(ddOrderLineAlt, "ddOrderLineAlt not null");
    final IQueryBL queryBL = Services.get(IQueryBL.class);
    final IQueryBuilder<I_PP_MRP_Alternative> queryBuilder =
        queryBL
            .createQueryBuilder(I_PP_MRP_Alternative.class, ddOrderLineAlt)
            .addEqualsFilter(
                I_PP_MRP_Alternative.COLUMN_DD_OrderLine_Alternative_ID,
                ddOrderLineAlt.getDD_OrderLine_Alternative_ID());

    queryBuilder.create().deleteDirectly();
  }
  @Override
  public IQueryBuilder<I_M_HU_Assignment> retrieveTUHUAssignmentsForModelQuery(final Object model) {
    final int adTableId = InterfaceWrapperHelper.getModelTableId(model);
    final int recordId = InterfaceWrapperHelper.getId(model);

    final IQueryBL queryBL = Services.get(IQueryBL.class);
    return queryBL
        .createQueryBuilder(I_M_HU_Assignment.class, model)
        .addEqualsFilter(I_M_HU_Assignment.COLUMN_AD_Table_ID, adTableId)
        .addEqualsFilter(I_M_HU_Assignment.COLUMN_Record_ID, recordId)
        .addNotEqualsFilter(I_M_HU_Assignment.COLUMN_M_TU_HU_ID, null) // TU is set
        .addOnlyActiveRecordsFilter();
  }
  @Override
  public I_C_DocLine_Sort find() {
    //
    // BPartner query builder
    final IQueryBuilder<I_C_BP_DocLine_Sort> bpQueryBuilder =
        queryBL
            .createQueryBuilder(I_C_BP_DocLine_Sort.class, getCtx(), ITrx.TRXNAME_None)
            .addOnlyActiveRecordsFilter();

    bpQueryBuilder.addEqualsFilter(I_C_BP_DocLine_Sort.COLUMN_C_BPartner_ID, getC_BPartner_ID());

    //
    // Collect header
    final IQueryBuilder<I_C_DocLine_Sort> docLineQueryBuilder =
        bpQueryBuilder
            .andCollect(I_C_BP_DocLine_Sort.COLUMN_C_DocLine_Sort_ID, I_C_DocLine_Sort.class)
            .addOnlyActiveRecordsFilter();

    //
    // IsDefault
    docLineQueryBuilder.addEqualsFilter(I_C_DocLine_Sort.COLUMN_IsDefault, false);

    //
    // DocBaseType
    docLineQueryBuilder.addEqualsFilter(I_C_DocLine_Sort.COLUMN_DocBaseType, getDocBaseType());

    final boolean existsBPDocLineSortConfig = docLineQueryBuilder.create().match();
    if (existsBPDocLineSortConfig) {
      return docLineQueryBuilder.create().firstOnly(I_C_DocLine_Sort.class);
    }

    //
    // Retrieve default if no match was found
    final IQueryBuilder<I_C_DocLine_Sort> docLineDefaultQueryBuilder =
        queryBL
            .createQueryBuilder(I_C_DocLine_Sort.class, getCtx(), ITrx.TRXNAME_None)
            .addOnlyActiveRecordsFilter();

    //
    // IsDefault
    docLineDefaultQueryBuilder.addEqualsFilter(I_C_DocLine_Sort.COLUMN_IsDefault, true);

    //
    // DocBaseType
    docLineDefaultQueryBuilder.addEqualsFilter(
        I_C_DocLine_Sort.COLUMN_DocBaseType, getDocBaseType());

    //
    // Return default (if any)
    return docLineDefaultQueryBuilder.create().firstOnly(I_C_DocLine_Sort.class);
  }
  /**
   * Loads the ASI template to be used.
   *
   * @param fromAttributeSetInstanceId
   * @return
   *     <ul>
   *       <li>ASI template
   *       <li><code>null</code> if this is not a valid settings and we need to dispose the dialog
   *     </ul>
   *
   * @throws AdempiereException if something failed
   */
  private final MAttributeSetInstance loadASITemplate(final int fromAttributeSetInstanceId) {
    final Properties ctx = getCtx();
    final int productId = getM_Product_ID();
    final boolean isPureProductASI = isPureProductASI();

    //
    // If there is not product specified
    // and we need a pure product ASI (i.e. not the ASI that we configure on product level)
    // => this dialog does not make sense and we need to dispose it ASAP
    // TODO: in future we shall do this checking BEFORE we reach this point
    if (productId <= 0 && isPureProductASI) {
      return null;
    }

    final MAttributeSetInstance asiTemplate;

    //
    // Load/Create the ASI
    // Get the M_AttributeSet.
    MAttributeSet as = null;
    if (productId > 0) {
      // Get/Create the ASI
      asiTemplate = MAttributeSetInstance.get(ctx, fromAttributeSetInstanceId, productId);
      if (asiTemplate == null) {
        throw new AdempiereException(
            "@NotFound@ @M_AttributeSetInstance_ID@ (@M_Product_ID@=" + productId + ")");
      }
      Env.setContext(ctx, m_WindowNo, "M_AttributeSet_ID", asiTemplate.getM_AttributeSet_ID());

      // Get Attribute Set
      as = asiTemplate.getMAttributeSet();
    } else {
      final int M_AttributeSet_ID = attributeContext.getM_AttributeSet_ID();
      asiTemplate =
          new MAttributeSetInstance(ctx, 0, M_AttributeSet_ID, ITrx.TRXNAME_None); // new ASI
      as = asiTemplate.getMAttributeSet();
      if (as == null && M_AttributeSet_ID == 0) {
        // FIXME: workaround to deal with M_AttributeSet_ID=0 which is an existing record
        as =
            queryBL
                .createQueryBuilder(I_M_AttributeSet.class)
                .setContext(ctx, ITrx.TRXNAME_None)
                .addEqualsFilter(I_M_AttributeSet.COLUMNNAME_M_AttributeSet_ID, 0)
                .create()
                .firstOnlyNotNull(MAttributeSet.class);
        asiTemplate.setMAttributeSet(as);
      }
    }
    // Product has no Attribute Set
    if (as == null) {
      throw new AdempiereException("@PAttributeNoAttributeSet@");
    }
    // Product has no Instance Attributes
    if (isPureProductASI && !as.isInstanceAttribute()) {
      throw new AdempiereException("@PAttributeNoInstanceAttribute@");
    }

    return asiTemplate;
  }
  @Override
  public IQueryBuilder<I_PP_MRP> createQueryBuilder() {
    final IQueryFilter<I_PP_MRP> filters = createQueryFilter();
    final IQueryBuilder<I_PP_MRP> queryBuilder =
        queryBL.createQueryBuilder(I_PP_MRP.class, getContextProviderToUse()).filter(filters);

    return queryBuilder;
  }
  @Override
  public <T> List<T> retrieveModelsForHU(
      final I_M_HU hu, final Class<T> clazz, final boolean topLevel) {
    final IQueryBL queryBL = Services.get(IQueryBL.class);

    final int tableId = InterfaceWrapperHelper.getTableId(clazz);
    final String keyColumnName = InterfaceWrapperHelper.getKeyColumnName(clazz);

    final IQueryBuilder<I_M_HU_Assignment> huAssigmentQueryBuilder =
        queryBL
            .createQueryBuilder(I_M_HU_Assignment.class, hu)
            .addOnlyContextClientOrSystem()
            .addOnlyActiveRecordsFilter()
            .addEqualsFilter(I_M_HU_Assignment.COLUMN_AD_Table_ID, tableId);
    if (topLevel) {
      huAssigmentQueryBuilder.addEqualsFilter(I_M_HU_Assignment.COLUMN_M_HU_ID, hu.getM_HU_ID());
      applyCommonTopLevelFilters(huAssigmentQueryBuilder, tableId);
    } else {
      final ICompositeQueryFilter<I_M_HU_Assignment> filter =
          queryBL
              .createCompositeQueryFilter(I_M_HU_Assignment.class)
              .setJoinOr()
              .addEqualsFilter(I_M_HU_Assignment.COLUMN_M_LU_HU_ID, hu.getM_HU_ID())
              .addEqualsFilter(I_M_HU_Assignment.COLUMN_M_TU_HU_ID, hu.getM_HU_ID())
              .addEqualsFilter(I_M_HU_Assignment.COLUMN_VHU_ID, hu.getM_HU_ID());
      huAssigmentQueryBuilder.filter(filter);
    }

    final IQuery<I_M_HU_Assignment> huAssigmentQuery = huAssigmentQueryBuilder.create();

    // @formatter:off
    return queryBL
        .createQueryBuilder(clazz, hu)
        .addOnlyContextClientOrSystem()
        .addOnlyActiveRecordsFilter()
        .addInSubQueryFilter(
            keyColumnName, I_M_HU_Assignment.COLUMNNAME_Record_ID, huAssigmentQuery)
        .orderBy()
        .addColumn(InterfaceWrapperHelper.getKeyColumnName(clazz))
        .endOrderBy()
        .create()
        .list(clazz);
    // @formatter:on
  }
Exemple #9
0
  public final IQueryBuilder<I_M_Material_Tracking_Ref>
      createMaterialTrackingRefQueryBuilderForModels(final List<?> models) {
    if (models == null || models.isEmpty()) {
      return null;
    }

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

    //
    // Iterate models and build model filters
    final ICompositeQueryFilter<I_M_Material_Tracking_Ref> modelFilters =
        queryBL.createCompositeQueryFilter(I_M_Material_Tracking_Ref.class).setJoinOr();
    for (final Object model : models) {
      if (model == null) {
        continue;
      }

      final int adTableId = InterfaceWrapperHelper.getModelTableId(model);
      final int recordId = InterfaceWrapperHelper.getId(model);
      final ICompositeQueryFilter<I_M_Material_Tracking_Ref> filter =
          queryBL
              .createCompositeQueryFilter(I_M_Material_Tracking_Ref.class)
              .addEqualsFilter(I_M_Material_Tracking_Ref.COLUMN_AD_Table_ID, adTableId)
              .addEqualsFilter(I_M_Material_Tracking_Ref.COLUMN_Record_ID, recordId);

      modelFilters.addFilter(filter);
    }

    // No models provided
    if (modelFilters.isEmpty()) {
      return null;
    }

    //
    // Create M_Material_Tracking_Ref query
    final IQueryBuilder<I_M_Material_Tracking_Ref> materialTrackingRefQueryBuilder =
        queryBL
            .createQueryBuilder(I_M_Material_Tracking_Ref.class)
            .setContext(getCtx(), getTrxName())
            .filter(modelFilters);

    return materialTrackingRefQueryBuilder;
  }
  @Override
  public List<I_M_HU> retrieveTopLevelHUsForModel(final Object model, final String trxName) {
    final Properties ctx = InterfaceWrapperHelper.getCtx(model);
    final int adTableId = InterfaceWrapperHelper.getModelTableId(model);
    final int recordId = InterfaceWrapperHelper.getId(model);

    final IQueryBL queryBL = Services.get(IQueryBL.class);
    final IQueryBuilder<I_M_HU> queryBuilder =
        queryBL
            .createQueryBuilder(I_M_HU_Assignment.class, ctx, trxName)
            .addEqualsFilter(I_M_HU_Assignment.COLUMN_AD_Table_ID, adTableId)
            .addEqualsFilter(I_M_HU_Assignment.COLUMN_Record_ID, recordId)
            .addOnlyActiveRecordsFilter()
            //
            // Collect top level HUs
            .andCollect(I_M_HU_Assignment.COLUMN_M_HU_ID);

    //
    // 07612: Order by HU ID to preserve allocation order (i.e highest HU quantities / full HUs
    // first)
    queryBuilder.orderBy().addColumn(I_M_HU.COLUMN_M_HU_ID);

    final List<I_M_HU> husTopLevel = queryBuilder.create().list(I_M_HU.class);

    //
    // Guard: make sure all those HUs are really top level
    // Normally, this shall not happen. But we could have the case when the TU was joined to a LU
    // later and the HU assignment was not updated.
    final IHandlingUnitsBL handlingUnitsBL = Services.get(IHandlingUnitsBL.class);
    for (final Iterator<I_M_HU> husTopLevelIterator = husTopLevel.iterator();
        husTopLevelIterator.hasNext(); ) {
      final I_M_HU hu = husTopLevelIterator.next();
      if (!handlingUnitsBL.isTopLevel(hu)) {
        husTopLevelIterator.remove();
        continue;
      }
    }

    // NOTE: this method will NOT exclude destroyed HUs.
    // Before changing this, please carefully check the depending API.

    return husTopLevel;
  }
  @Override
  public int updateMRPRecordsAndMarkAvailable() {
    // Updater
    final IQueryUpdater<I_PP_MRP> setAvailableUpdater =
        queryBL
            .createCompositeQueryUpdater(I_PP_MRP.class)
            .addSetColumnValue(I_PP_MRP.COLUMNNAME_IsAvailable, true);

    return updateMRPRecords(setAvailableUpdater);
  }
  /**
   * Retrieves MRP Alternative record for given {@link I_DD_OrderLine_Alternative}.
   *
   * @param ddOrderLineAlt
   * @param mrp
   * @return MRP Alternative or <code>null</code>
   */
  private I_PP_MRP_Alternative retrieveMRPAlternative(
      final I_DD_OrderLine_Alternative ddOrderLineAlt, final I_PP_MRP mrp) {
    // Optimization: in case the DD_OrderLine was just created, there is no point to query because
    // there won't be any result for sure
    if (InterfaceWrapperHelper.isJustCreated(ddOrderLineAlt)) {
      return null;
    }

    Check.assumeNotNull(ddOrderLineAlt, "ddOrderLineAlt not null");
    Check.assumeNotNull(mrp, "mrp not null");

    final IQueryBL queryBL = Services.get(IQueryBL.class);
    final IQueryBuilder<I_PP_MRP_Alternative> queryBuilder =
        queryBL
            .createQueryBuilder(I_PP_MRP_Alternative.class, ddOrderLineAlt)
            .addEqualsFilter(
                I_PP_MRP_Alternative.COLUMN_DD_OrderLine_Alternative_ID,
                ddOrderLineAlt.getDD_OrderLine_Alternative_ID())
            .addEqualsFilter(I_PP_MRP_Alternative.COLUMN_PP_MRP_ID, mrp.getPP_MRP_ID());

    return queryBuilder.create().firstOnly(I_PP_MRP_Alternative.class);
  }
Exemple #13
0
  public IQueryBuilder<I_M_Material_Tracking> createQueryBuilder(
      final IMaterialTrackingQuery queryVO) {
    Check.assumeNotNull(queryVO, "queryVO not null");

    final IQueryBuilder<I_M_Material_Tracking> queryBuilder =
        queryBL
            .createQueryBuilder(I_M_Material_Tracking.class)
            .setContext(getCtx(), getTrxName())
            .addOnlyContextClient()
            .addOnlyActiveRecordsFilter();

    final IQueryOrderByBuilder<I_M_Material_Tracking> orderBy = queryBuilder.orderBy();

    //
    // M_Product_ID
    final int productId = queryVO.getM_Product_ID();
    Check.assume(productId > 0, "productId > 0");
    queryBuilder.addEqualsFilter(I_M_Material_Tracking.COLUMN_M_Product_ID, productId);

    //
    // C_BPartner_ID
    final int bpartnerId = queryVO.getC_BPartner_ID();
    queryBuilder.addInArrayFilter(I_M_Material_Tracking.COLUMN_C_BPartner_ID, null, bpartnerId);
    orderBy.addColumn(I_M_Material_Tracking.COLUMN_C_BPartner_ID, Direction.Descending, Nulls.Last);

    // TODO: ValidFrom, ValidTo

    //
    // Processed
    final Boolean processed = queryVO.getProcessed();
    if (processed != null) {
      queryBuilder.addEqualsFilter(I_M_Material_Tracking.COLUMN_Processed, processed);
    }

    //
    // Linked documents
    final List<?> linkedModels = queryVO.getWithLinkedDocuments();
    if (linkedModels != null && !linkedModels.isEmpty()) {
      final IQuery<I_M_Material_Tracking_Ref> materialTrackingRefQuery =
          createMaterialTrackingRefQueryForModels(linkedModels);
      if (materialTrackingRefQuery != null) {
        queryBuilder.addInSubQueryFilter(
            I_M_Material_Tracking.COLUMN_M_Material_Tracking_ID,
            I_M_Material_Tracking_Ref.COLUMN_M_Material_Tracking_ID,
            materialTrackingRefQuery);
      }
      // TODO
    }

    return queryBuilder;
  }
  private final Iterator<I_GL_JournalLine> retrieveGLJournalLines() {
    final I_C_TaxDeclaration taxDeclaration = getC_TaxDeclaration();

    final IQuery<I_C_TaxDeclarationLine> existingTaxDeclarationLinesQuery =
        createQueryBuilder(I_C_TaxDeclarationLine.class).create();

    final ICompositeQueryFilter<I_GL_JournalLine> taxAccountableFilter =
        queryBL
            .createCompositeQueryFilter(I_GL_JournalLine.class)
            .setJoinOr()
            .addEqualsFilter(I_GL_JournalLine.COLUMN_DR_AutoTaxAccount, true)
            .addEqualsFilter(I_GL_JournalLine.COLUMN_CR_AutoTaxAccount, true);

    final IQueryBuilder<I_GL_JournalLine> queryBuilder =
        createQueryBuilder(I_GL_JournalLine.class)
            //
            // Only invoices from reporting interval
            .addBetweenFilter(
                I_GL_JournalLine.COLUMN_DateAcct,
                taxDeclaration.getDateFrom(),
                taxDeclaration.getDateTo(),
                DateTruncQueryFilterModifier.DAY)
            //
            // Only those which are processed
            .addEqualsFilter(I_GL_JournalLine.COLUMN_Processed, true)
            //
            // Only those which are about taxes
            .filter(taxAccountableFilter)
            //
            // Only those which were not already included in other tax declaration
            .addNotInSubQueryFilter(
                I_GL_JournalLine.COLUMN_GL_JournalLine_ID,
                I_C_TaxDeclarationLine.COLUMN_GL_JournalLine_ID,
                existingTaxDeclarationLinesQuery)
        //
        ;

    queryBuilder
        .orderBy()
        .addColumn(I_GL_JournalLine.COLUMN_DateAcct)
        .addColumn(I_GL_JournalLine.COLUMN_GL_JournalLine_ID); // to have a predictable order

    return queryBuilder
        .create()
        // guaranteed because we are inserting in C_TaxDeclarationLine and in our query we check to
        // not have the record already there
        .setOption(IQuery.OPTION_GuaranteedIteratorRequired, true)
        //
        .iterate(I_GL_JournalLine.class);
  }
Exemple #15
0
  public final <T>
      IQueryBuilder<I_M_Material_Tracking_Ref> createMaterialTrackingRefQueryBuilderForModels(
          final IQueryBuilder<T> modelsQuery) {
    final IQueryBL queryBL = Services.get(IQueryBL.class);

    final Class<T> modelClass = modelsQuery.getModelClass();
    final int modelTableId = InterfaceWrapperHelper.getTableId(modelClass);
    final String modelKeyColumnName = InterfaceWrapperHelper.getKeyColumnName(modelClass);

    //
    // Create M_Material_Tracking_Ref query
    final IQueryBuilder<I_M_Material_Tracking_Ref> materialTrackingRefQueryBuilder =
        queryBL
            .createQueryBuilder(I_M_Material_Tracking_Ref.class)
            .setContext(getCtx(), getTrxName())
            .addEqualsFilter(I_M_Material_Tracking_Ref.COLUMN_AD_Table_ID, modelTableId)
            .addInSubQueryFilter(
                I_M_Material_Tracking_Ref.COLUMNNAME_Record_ID,
                modelKeyColumnName,
                modelsQuery.create());

    return materialTrackingRefQueryBuilder;
  }
  @Override
  public <T extends I_AD_Archive> T retrievePDFArchiveForModel(
      final Object model, final Class<T> archiveClass) {
    Check.assumeNotNull(model, "model not null");
    Check.assumeNotNull(archiveClass, "archiveClass not null");

    //
    // Services
    final IQueryBL queryBL = Services.get(IQueryBL.class);
    final IDocOutboundDAO archiveDAO = Services.get(IDocOutboundDAO.class);

    final Object contextProvider = model;
    final int adTableId = InterfaceWrapperHelper.getModelTableId(model);
    final int recordId = InterfaceWrapperHelper.getId(model);

    final IQueryBuilder<I_C_Doc_Outbound_Log> docOutboundLogQueryBuilder =
        queryBL
            .createQueryBuilder(I_C_Doc_Outbound_Log.class, contextProvider)
            .addOnlyActiveRecordsFilter()
            .addEqualsFilter(I_C_Doc_Outbound_Log.COLUMN_AD_Table_ID, adTableId)
            .addEqualsFilter(I_C_Doc_Outbound_Log.COLUMN_Record_ID, recordId);

    final IQueryBuilder<I_C_Doc_Outbound_Log_Line> docOutboundLogLineQueryBuilder =
        docOutboundLogQueryBuilder.andCollectChildren(
            I_C_Doc_Outbound_Log_Line.COLUMN_C_Doc_Outbound_Log_ID,
            I_C_Doc_Outbound_Log_Line.class);

    archiveDAO.addPDFArchiveLogLineFilters(docOutboundLogLineQueryBuilder);

    final I_C_Doc_Outbound_Log_Line pdfLine = docOutboundLogLineQueryBuilder.create().first();

    if (pdfLine == null) {
      return null;
    }
    final T archive = InterfaceWrapperHelper.create(pdfLine.getAD_Archive(), archiveClass);
    return archive;
  }
  /**
   * @param documentClass
   * @return completed documents
   */
  public <T> List<T> completeMRPDocuments(final Class<T> documentClass) {
    final List<T> documentModels =
        queryBL
            .createQueryBuilder(documentClass, contextProvider)
            .addOnlyActiveRecordsFilter()
            .addNotEqualsFilter(I_DD_Order.COLUMNNAME_DocStatus, X_DD_Order.DOCSTATUS_Completed)
            .create()
            .list();
    final List<T> documentModelsCompleted = new ArrayList<>(documentModels.size());
    for (final T documentModel : documentModels) {
      final DocAction document = docActionBL.getDocAction(documentModel);
      docActionBL.processEx(document, DocAction.ACTION_Complete, DocAction.STATUS_Completed);

      documentModelsCompleted.add(documentModel);
    }

    return documentModelsCompleted;
  }
  /** Initialize all panel fields and editors based on {@link #asiTemplate}. */
  private final void initAttributes() {
    final Properties ctx = getCtx();
    final boolean isProductWindow = isProductWindow();
    final boolean isProcessParameter = isProcessParameter();
    final boolean isPureProductASI = isPureProductASI();
    final boolean allowSelectExistingASI = isAllowSelectExistingASI();
    final MAttributeSet as = asiTemplate.getMAttributeSet();
    Check.assumeNotNull(as, "attribute set not null");
    final boolean isASITemplateNew = asiTemplate.getM_AttributeSetInstance_ID() <= 0;

    //
    // Show Select existing ASI (if allowed)
    if (allowSelectExistingASI) {
      // New/Edit - Selection
      if (isASITemplateNew) // new ASI
      cbNewEdit.setText(msgBL.getMsg(ctx, "NewRecord"));
      else cbNewEdit.setText(msgBL.getMsg(ctx, "EditRecord"));
      cbNewEdit.addActionListener(this);
      centerPanel.add(cbNewEdit, new ALayoutConstraint(m_row++, 0));
      bSelectExistingASI.setText(msgBL.getMsg(ctx, "SelectExisting"));
      bSelectExistingASI.addActionListener(this);
      centerPanel.add(bSelectExistingASI, null);
    }

    //
    // Fetch M_Attributes
    final List<MAttribute> attributes;
    if (isProductWindow) {
      attributes = Arrays.asList(as.getMAttributes(false)); // non-instance attributes
    } else if (isPureProductASI) {
      // Regular product's attribute set instance attributes
      attributes = Arrays.asList(as.getMAttributes(true)); // all instance attributes
    } else if (isProcessParameter) {
      final IQueryBuilder<MAttribute> attributesQueryBuilder =
          queryBL
              .createQueryBuilder(MAttribute.class)
              .setContext(ctx, ITrx.TRXNAME_None)
              .addOnlyActiveRecordsFilter()
              .addOnlyContextClient();
      attributesQueryBuilder
          .orderBy()
          .addColumn(I_M_Attribute.COLUMNNAME_Name)
          .addColumn(I_M_Attribute.COLUMNNAME_M_Attribute_ID);
      attributes = attributesQueryBuilder.create().list(MAttribute.class);
    } else {
      attributes = Collections.emptyList();
    }

    //
    // Create attributes UI editors
    for (final MAttribute attribute : attributes) {
      if (!attributeExcludeBL.isExcludedAttribute(
          attribute, as, m_AD_Column_ID, attributeContext.isSOTrx())) {
        addAttributeLine(attribute);
      }
    }

    //
    // Lot
    if (isPureProductASI && as.isLot()) {
      CLabel label = new CLabel(msgBL.translate(ctx, "Lot"));
      label.setLabelFor(fieldLotString);
      centerPanel.add(label, new ALayoutConstraint(m_row++, 0));
      centerPanel.add(fieldLotString, null);
      fieldLotString.setText(asiTemplate.getLot());
      // M_Lot_ID
      // int AD_Column_ID = 9771; // M_AttributeSetInstance.M_Lot_ID
      // fieldLot = new VLookup ("M_Lot_ID", false,false, true,
      // MLookupFactory.get(getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.TableDir));
      final String sql =
          "SELECT M_Lot_ID, Name "
              + "FROM M_Lot l "
              + "WHERE EXISTS (SELECT M_Product_ID FROM M_Product p "
              + "WHERE p.M_AttributeSet_ID="
              + asiTemplate.getM_AttributeSet_ID()
              + " AND p.M_Product_ID=l.M_Product_ID)";
      fieldLot = new CComboBox<>(DB.getKeyNamePairs(sql, true));
      label = new CLabel(msgBL.translate(ctx, "M_Lot_ID"));
      label.setLabelFor(fieldLot);
      centerPanel.add(label, new ALayoutConstraint(m_row++, 0));
      centerPanel.add(fieldLot, null);
      if (asiTemplate.getM_Lot_ID() > 0) {
        for (int i = 1; i < fieldLot.getItemCount(); i++) {
          KeyNamePair pp = fieldLot.getItemAt(i);
          if (pp.getKey() == asiTemplate.getM_Lot_ID()) {
            fieldLot.setSelectedIndex(i);
            fieldLotString.setEditable(false);
            break;
          }
        }
      }
      fieldLot.addActionListener(this);
      // New Lot Button
      if (asiTemplate.getMAttributeSet().getM_LotCtl_ID() > 0) {
        if (Env.getUserRolePermissions().isTableAccess(MLot.Table_ID, false)
            && Env.getUserRolePermissions().isTableAccess(MLotCtl.Table_ID, false)
            && !asiTemplate.isExcludeLot(m_AD_Column_ID, attributeContext.isSOTrx())) {
          centerPanel.add(bLot, null);
          bLot.addActionListener(this);
        }
      }
      // Popup
      fieldLot.addMouseListener(new VPAttributeDialog_mouseAdapter(this)); // popup
      mZoom = new CMenuItem(msgBL.getMsg(ctx, "Zoom"), Images.getImageIcon2("Zoom16"));
      mZoom.addActionListener(this);
      popupMenu.add(mZoom);
    } // Lot

    //
    // SerNo
    if (isPureProductASI && as.isSerNo()) {
      CLabel label = new CLabel(msgBL.translate(ctx, "SerNo"));
      label.setLabelFor(fieldSerNo);
      fieldSerNo.setText(asiTemplate.getSerNo());
      centerPanel.add(label, new ALayoutConstraint(m_row++, 0));
      centerPanel.add(fieldSerNo, null);
      // New SerNo Button
      if (asiTemplate.getMAttributeSet().getM_SerNoCtl_ID() != 0) {
        if (Env.getUserRolePermissions().isTableAccess(MSerNoCtl.Table_ID, false)
            && !asiTemplate.isExcludeSerNo(m_AD_Column_ID, attributeContext.isSOTrx())) {
          centerPanel.add(bSerNo, null);
          bSerNo.addActionListener(this);
        }
      }
    } // SerNo

    //
    // GuaranteeDate.
    // We are displaying it if we deal with a pure product ASI (i.e. user is not editing the ASI
    // from product window),
    // and if:
    // * the attribute set requires a GuaranteeDate
    // * or if the ASI has a GuaranteeDate already set
    if (isPureProductASI && (as.isGuaranteeDate() || asiTemplate.getGuaranteeDate() != null)) {
      CLabel label = new CLabel(msgBL.translate(ctx, "GuaranteeDate"));
      label.setLabelFor(fieldGuaranteeDate);
      if (isASITemplateNew) {
        Date guaranteeDate = asiTemplate.getGuaranteeDate();
        if (guaranteeDate == null) {
          guaranteeDate =
              attributesBL.calculateBestBeforeDate(
                  ctx,
                  m_M_Product_ID, // product
                  attributeContext.getC_BPartner_ID(), // vendor bpartner
                  Env.getDate(ctx) // dateReceipt
                  );
        }
        fieldGuaranteeDate.setValue(guaranteeDate);
      } else {
        fieldGuaranteeDate.setValue(asiTemplate.getGuaranteeDate());
      }
      centerPanel.add(label, new ALayoutConstraint(m_row++, 0));
      centerPanel.add(fieldGuaranteeDate, null);
      fieldGuaranteeDateDisplayed = true;
    } // GuaranteeDate

    // Make sure we have at least something to edit or something to select,
    // else there is no point in showing empty this window.
    if (m_row == 0) {
      throw new AdempiereException("@PAttributeNoInfo@");
    }

    //
    // New/Edit Window
    if (allowSelectExistingASI) {
      cbNewEdit.setSelected(isASITemplateNew);
      cmd_newEdit();
    }

    //
    // Attrribute Set Instance Description
    {
      final CLabel labelDescription = new CLabel(msgBL.translate(ctx, "Description"));
      labelDescription.setLabelFor(fieldDescription);
      fieldDescription.setText(asiTemplate.getDescription());
      fieldDescription.setEditable(false);
      centerPanel.add(labelDescription, new ALayoutConstraint(m_row++, 0));
      centerPanel.add(fieldDescription, null);
    }

    // Window usually to wide (??)
    {
      final Dimension dd = centerPanel.getPreferredSize();
      dd.width = Math.min(500, dd.width);
      centerPanel.setPreferredSize(dd);
    }
  } // initAttribute
  private IQueryFilter<I_PP_MRP> createQueryFilter() {
    final IContextAware contextProvider = getContextProviderToUse();
    final ICompositeQueryFilter<I_PP_MRP> filters =
        queryBL.createCompositeQueryFilter(I_PP_MRP.class);

    //
    // Filter only Active records
    final boolean onlyActiveRecords = isOnlyActiveRecords();
    if (onlyActiveRecords) {
      filters.addOnlyActiveRecordsFilter();
    }

    //
    // Filter by AD_Client_ID
    final int adClientId = getAD_Client_ID_ToUse();
    if (adClientId >= 0) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_AD_Client_ID, adClientId);
    }

    //
    // Filter by AD_Org_ID
    final int adOrgId = getAD_Org_ID_ToUse();
    if (adOrgId >= 0) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_AD_Org_ID, adOrgId);
    }

    //
    // Filter by M_Warehouse_ID
    final int warehouseId = getM_Warehouse_ID_ToUse();
    if (warehouseId > 0) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_M_Warehouse_ID, warehouseId);
    }

    //
    // Filter by Plant (only those lines which have our plant ID or don't have the plant ID set at
    // all)
    // AIM: Clear separation on plant level (06594)
    final Set<Integer> plantIds = getPP_Plant_IDs_ToUse();
    if (plantIds != null && !plantIds.isEmpty()) {
      filters.addInArrayFilter(I_PP_MRP.COLUMNNAME_S_Resource_ID, plantIds);
    }

    //
    // Filter by M_Product_ID
    final int productId = getM_Product_ID_ToUse();
    if (productId > 0) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_M_Product_ID, productId);
    }

    //
    // Filter by Product's Low Level Code (LLC)
    final int productLLC = getLowLevelCode();
    if (productLLC >= 0) {
      final IQuery<I_M_Product> productQuery =
          queryBL
              .createQueryBuilder(I_M_Product.class)
              .setContext(contextProvider)
              .filter(
                  new EqualsQueryFilter<I_M_Product>(I_M_Product.COLUMNNAME_LowLevel, productLLC))
              .create();
      filters.addInSubQueryFilter(
          I_PP_MRP.COLUMNNAME_M_Product_ID, I_M_Product.COLUMNNAME_M_Product_ID, productQuery);
    }

    //
    // Filter by TypeMRP
    final String typeMRP = getTypeMRP();
    if (!Check.isEmpty(typeMRP, true)) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_TypeMRP, typeMRP);
    }

    //
    // Filter by MRPFirmType (i.e. DocStatus)
    final MRPFirmType mrpFirmType = getMRPFirmType();
    if (mrpFirmType != null) {
      final List<String> docStatuses = mrpFirmType.getDocStatuses();
      filters.addInArrayFilter(I_PP_MRP.COLUMNNAME_DocStatus, docStatuses);
    }

    //
    // Filter by OrderType (i.e. similar with DocBaseType)
    final Set<String> orderTypes = getOrderTypes();
    if (!Check.isEmpty(orderTypes)) {
      filters.addInArrayFilter(I_PP_MRP.COLUMNNAME_OrderType, orderTypes);
    }

    //
    // Filter by DatePromised
    final Date datePromisedMax = getDatePromisedMax();
    if (datePromisedMax != null) {
      filters.addCompareFilter(
          I_PP_MRP.COLUMNNAME_DatePromised, Operator.LessOrEqual, datePromisedMax);
    }

    //
    // Filter Non Zero Qty
    final boolean qtyNotZero = isQtyNotZero();
    if (qtyNotZero) {
      filters.addNotEqualsFilter(I_PP_MRP.COLUMNNAME_Qty, BigDecimal.ZERO);
    }

    //
    // Filter by IsAvailable flag
    final Boolean mrpAvailable = getMRPAvailable();
    if (mrpAvailable != null) {
      filters.addEqualsFilter(I_PP_MRP.COLUMNNAME_IsAvailable, mrpAvailable);
    }

    //
    // Filter by Referenced Model
    // i.e. Only those MRP records which are referencing our model
    final Object referencedModel = getReferencedModel();
    if (referencedModel != null) {
      final String modelTableName = InterfaceWrapperHelper.getModelTableName(referencedModel);
      final String modelKeyColumnName = modelTableName + "_ID";
      final int modelId = InterfaceWrapperHelper.getId(referencedModel);
      filters.addEqualsFilter(modelKeyColumnName, modelId);
    }

    //
    // Filter only those MRP lines where PP_Product_BOMLine_ID is not set
    if (_ppOrderBOMLine_Null) {
      filters.addEqualsFilter(I_PP_MRP.COLUMN_PP_Order_BOMLine_ID, null);
    }

    //
    // Filter by specific PP_MRP_IDs
    final Set<Integer> mrpIds = getOnlyPP_MRP_IDs();
    if (mrpIds != null && !mrpIds.isEmpty()) {
      filters.addInArrayFilter(I_PP_MRP.COLUMNNAME_PP_MRP_ID, mrpIds);
    }

    //
    // Filter by enforced MRP demand, i.e.
    // * accept only MRP demand records which have the enforced MRP Demand ID
    // * or accept only MRP supply records which are allocated to the enforced MRP Demand ID
    if (_enforced_PP_MRP_Demand_ID > 0) {
      final ICompositeQueryFilter<I_PP_MRP> filterMRPDemands =
          queryBL
              .createCompositeQueryFilter(I_PP_MRP.class)
              .setJoinAnd()
              .addEqualsFilter(I_PP_MRP.COLUMNNAME_TypeMRP, X_PP_MRP.TYPEMRP_Demand)
              .addEqualsFilter(I_PP_MRP.COLUMNNAME_PP_MRP_ID, _enforced_PP_MRP_Demand_ID);

      final IQuery<I_PP_MRP_Alloc> mrpSuppliesSubQuery =
          queryBL
              .createQueryBuilder(I_PP_MRP.class)
              .setContext(contextProvider)
              .filter(filterMRPDemands)
              .andCollectChildren(I_PP_MRP_Alloc.COLUMN_PP_MRP_Demand_ID, I_PP_MRP_Alloc.class)
              .create();
      final ICompositeQueryFilter<I_PP_MRP> filterMRPSupplies =
          queryBL
              .createCompositeQueryFilter(I_PP_MRP.class)
              .setJoinAnd()
              .addEqualsFilter(I_PP_MRP.COLUMNNAME_TypeMRP, X_PP_MRP.TYPEMRP_Supply)
              .addInSubQueryFilter(
                  I_PP_MRP.COLUMN_PP_MRP_ID,
                  I_PP_MRP_Alloc.COLUMN_PP_MRP_Supply_ID,
                  mrpSuppliesSubQuery);

      final ICompositeQueryFilter<I_PP_MRP> filterEnforcedMRPDemand =
          queryBL
              .createCompositeQueryFilter(I_PP_MRP.class)
              .setJoinOr()
              .addFilter(filterMRPDemands)
              .addFilter(filterMRPSupplies);
      filters.addFilter(filterEnforcedMRPDemand);
    }

    //
    // Apply MRP_Exclude filters
    if (_skipIfMRPExcluded) {
      final IQueryFilter<I_PP_MRP> skipIfMRPExcludedFilters = createQueryFilter_MRP_Exclude();
      filters.addFilter(skipIfMRPExcludedFilters);
    }

    //
    // Return built filters
    return filters;
  }
 private final <T> IQueryBuilder<T> createQueryBuilder(final Class<T> modelClass) {
   return queryBL.createQueryBuilder(modelClass).setContext(getC_TaxDeclaration()) // FIXME
   ;
 }
  /**
   * Called by {@link #createQueryFilter()} to create the MRP_Exclude filter.
   *
   * @return MRP_Exclude filter
   */
  private IQueryFilter<I_PP_MRP> createQueryFilter_MRP_Exclude() {
    final IContextAware contextProvider = getContextProviderToUse();
    final ICompositeQueryFilter<I_PP_MRP> filters =
        queryBL.createCompositeQueryFilter(I_PP_MRP.class);

    // Exclude BPartners
    {
      final IQuery<I_C_BP_Group> excludedBPGroupsQuery =
          queryBL
              .createQueryBuilder(I_C_BP_Group.class)
              .setContext(contextProvider)
              .addEqualsFilter(I_C_BP_Group.COLUMN_MRP_Exclude, X_C_BP_Group.MRP_EXCLUDE_Yes)
              .create();

      final IQuery<I_C_BPartner> excludedBPartnersQuery =
          queryBL
              .createQueryBuilder(I_C_BPartner.class)
              .setContext(contextProvider)
              .setJoinOr()
              .addEqualsFilter(I_C_BPartner.COLUMN_MRP_Exclude, X_C_BPartner.MRP_EXCLUDE_Yes)
              .addInSubQueryFilter(
                  I_C_BPartner.COLUMNNAME_C_BP_Group_ID,
                  I_C_BP_Group.COLUMNNAME_C_BP_Group_ID,
                  excludedBPGroupsQuery)
              .create();

      filters.addNotInSubQueryFilter(
          I_PP_MRP.COLUMNNAME_C_BPartner_ID,
          I_C_BPartner.COLUMNNAME_C_BPartner_ID,
          excludedBPartnersQuery);
    }
    // Exclude Products
    {
      final IQuery<I_M_Product_Category> excludedProductCategoriesQuery =
          queryBL
              .createQueryBuilder(I_M_Product_Category.class)
              .setContext(contextProvider)
              .addEqualsFilter(
                  I_M_Product_Category.COLUMN_MRP_Exclude, X_C_BP_Group.MRP_EXCLUDE_Yes)
              .create();

      final IQuery<I_M_Product> excludedProductsQuery =
          queryBL
              .createQueryBuilder(I_M_Product.class)
              .setContext(contextProvider)
              .setJoinOr()
              .addEqualsFilter(I_M_Product.COLUMN_MRP_Exclude, X_M_Product.MRP_EXCLUDE_Yes)
              .addInSubQueryFilter(
                  I_M_Product.COLUMNNAME_M_Product_Category_ID,
                  I_M_Product_Category.COLUMNNAME_M_Product_Category_ID,
                  excludedProductCategoriesQuery)
              .create();
      filters.addNotInSubQueryFilter(
          I_PP_MRP.COLUMNNAME_M_Product_ID,
          I_M_Product.COLUMNNAME_M_Product_ID,
          excludedProductsQuery);
    }
    // Exclude Warehouses
    {
      final IQuery<I_M_Warehouse> excludedWarehousesQuery =
          queryBL
              .createQueryBuilder(I_M_Warehouse.class)
              .setContext(contextProvider)
              .addEqualsFilter(I_M_Warehouse.COLUMN_MRP_Exclude, X_M_Warehouse.MRP_EXCLUDE_Yes)
              .create();
      filters.addNotInSubQueryFilter(
          I_PP_MRP.COLUMNNAME_M_Warehouse_ID,
          I_M_Warehouse.COLUMNNAME_M_Warehouse_ID,
          excludedWarehousesQuery);
    }
    // Exclude Plants
    {
      final IQuery<I_S_Resource> excludedPlantsQuery =
          queryBL
              .createQueryBuilder(I_S_Resource.class)
              .setContext(contextProvider)
              .addEqualsFilter(I_S_Resource.COLUMN_MRP_Exclude, X_S_Resource.MRP_EXCLUDE_Yes)
              .create();
      filters.addNotInSubQueryFilter(
          I_PP_MRP.COLUMNNAME_S_Resource_ID,
          I_S_Resource.COLUMNNAME_S_Resource_ID,
          excludedPlantsQuery);
    }

    return filters;
  }