/**
   * Parent Constructor
   *
   * @param invoice invoice
   * @param paySchedule payment schedule
   */
  public MInvoicePaySchedule(MInvoice invoice, MPaySchedule paySchedule) {
    super(invoice.getCtx(), 0, invoice.get_TrxName());
    m_parent = invoice;
    setClientOrg(invoice);
    setC_Invoice_ID(invoice.getC_Invoice_ID());
    setC_PaySchedule_ID(paySchedule.getC_PaySchedule_ID());

    //	Amounts
    int scale = MCurrency.getStdPrecision(getCtx(), invoice.getC_Currency_ID());
    BigDecimal due = invoice.getGrandTotal();
    if (due.compareTo(Env.ZERO) == 0) {
      setDueAmt(Env.ZERO);
      setDiscountAmt(Env.ZERO);
      setIsValid(false);
    } else {
      due =
          due.multiply(paySchedule.getPercentage())
              .divide(HUNDRED, scale, BigDecimal.ROUND_HALF_UP);
      setDueAmt(due);
      BigDecimal discount =
          due.multiply(paySchedule.getDiscount()).divide(HUNDRED, scale, BigDecimal.ROUND_HALF_UP);
      setDiscountAmt(discount);
      setIsValid(true);
    }

    //	Dates
    Timestamp dueDate = TimeUtil.addDays(invoice.getDateInvoiced(), paySchedule.getNetDays());
    setDueDate(dueDate);
    Timestamp discountDate =
        TimeUtil.addDays(invoice.getDateInvoiced(), paySchedule.getDiscountDays());
    setDiscountDate(discountDate);
  } //	MInvoicePaySchedule
예제 #2
0
 /**
  * Date In Period
  *
  * @param date date
  * @return true if in period
  */
 public boolean isInPeriod(Timestamp date) {
   if (date == null) return false;
   Timestamp dateOnly = TimeUtil.getDay(date);
   Timestamp from = TimeUtil.getDay(getStartDate());
   if (dateOnly.before(from)) return false;
   Timestamp to = TimeUtil.getDay(getEndDate());
   if (dateOnly.after(to)) return false;
   return true;
 } //	isInPeriod
예제 #3
0
  @Override
  protected String doIt() throws Exception {
    final long startTime = System.currentTimeMillis();

    // note: delete the scheds via API to make sure that the appropriate relations are also removed
    final List<MMPurchaseSchedule> schedsToDelete =
        new Query(getCtx(), I_M_PurchaseSchedule.Table_Name, "", get_TrxName())
            .setClient_ID()
            .list();
    for (final MMPurchaseSchedule sched : schedsToDelete) {
      // addLog("Deleting " + sched);
      sched.deleteEx(false);
    }

    final long afterDeleteTime = System.currentTimeMillis();
    addLog(
        "Deleted "
            + schedsToDelete.size()
            + " @M_PurchaseSchedule_ID@ records in "
            + TimeUtil.formatElapsed(afterDeleteTime - startTime));

    final IOrderPA orderPA = Services.get(IOrderPA.class);
    final IPurchaseScheduleBL purchaseScheduleBL = Services.get(IPurchaseScheduleBL.class);

    int createCounter = 0;
    for (final I_C_Order order :
        orderPA.retrieveOpenOrders(DocAction.STATUS_Completed, get_TrxName())) {
      if (!order.isSOTrx()) {
        continue;
      }

      final Collection<MMPurchaseSchedule> purchaseScheds =
          purchaseScheduleBL.retrieveOrCreateForSO(getCtx(), order, get_TrxName());
      for (final MMPurchaseSchedule ps : purchaseScheds) {
        purchaseScheduleBL.updateStorageData(getCtx(), ps, get_TrxName());
        purchaseScheduleBL.updateQtyToOrder(ps);
        ps.saveEx();
      }

      addLog(
          "Created "
              + purchaseScheds.size()
              + " @M_PurchaseSchedule_ID@ records for @C_Order_ID@ "
              + order.getDocumentNo());
      createCounter += purchaseScheds.size();
    }

    addLog(
        "Created "
            + createCounter
            + " purchase schedule records in "
            + TimeUtil.formatElapsed(System.currentTimeMillis() - afterDeleteTime));
    return "@Success@";
  }
예제 #4
0
  @Override
  @Cached(cacheName = I_C_ConversionType_Default.Table_Name + "#by#Dimension")
  public I_C_ConversionType retrieveDefaultConversionType(
      @CacheCtx final Properties ctx, final int adClientId, final int adOrgId, final Date date) {
    // NOTE to developer: keep in sync with: getDefaultConversionType_ID database function

    Check.assumeNotNull(date, "date not null");
    final Date dateDay = TimeUtil.trunc(date, TimeUtil.TRUNC_DAY);

    return Services.get(IQueryBL.class)
        .createQueryBuilder(I_C_ConversionType_Default.class, ctx, ITrx.TRXNAME_None)
        .addOnlyActiveRecordsFilter()
        .addInArrayFilter(
            I_C_ConversionType_Default.COLUMN_AD_Client_ID,
            adClientId,
            Env.CTXVALUE_AD_Client_ID_System)
        .addInArrayFilter(
            I_C_ConversionType_Default.COLUMN_AD_Org_ID, adClientId, Env.CTXVALUE_AD_Org_ID_System)
        .addCompareFilter(
            I_C_ConversionType_Default.COLUMN_ValidFrom, Operator.LESS_OR_EQUAL, dateDay)
        //
        .orderBy()
        .addColumn(I_C_ConversionType_Default.COLUMN_ValidFrom, Direction.Descending, Nulls.Last)
        .addColumn(I_C_ConversionType_Default.COLUMN_AD_Client_ID, Direction.Descending, Nulls.Last)
        .addColumn(I_C_ConversionType_Default.COLUMN_AD_Org_ID, Direction.Descending, Nulls.Last)
        .endOrderBy()
        //
        .setLimit(1) // only the first one
        //
        .andCollect(I_C_ConversionType_Default.COLUMN_C_ConversionType_ID)
        .create()
        .firstOnlyNotNull(I_C_ConversionType.class);
  }
예제 #5
0
  /**
   * Creates a dummy MRP firm demand.
   *
   * <p>NOTE:
   *
   * <ul>
   *   <li>DocStatus will be Completed
   *   <li>OrderType will be SalesOrder
   * </ul>
   *
   * @param product
   * @param qty
   * @param date
   * @param plant
   * @param warehouse
   * @return demand MRP record
   */
  public I_PP_MRP createMRPDemand(
      final I_M_Product product,
      final BigDecimal qty,
      final Date date,
      final I_S_Resource plant,
      final I_M_Warehouse warehouse,
      final I_C_BPartner bpartner) {
    final I_PP_MRP mrp = InterfaceWrapperHelper.newInstance(I_PP_MRP.class, contextProvider);
    mrp.setAD_Org_ID(warehouse.getAD_Org_ID());
    mrp.setS_Resource(plant);
    mrp.setM_Warehouse(warehouse);
    mrp.setC_BPartner(bpartner);
    //
    final Timestamp dateTS = TimeUtil.asTimestamp(date);
    mrp.setDatePromised(dateTS);
    mrp.setDateStartSchedule(dateTS);
    mrp.setDateFinishSchedule(dateTS);
    //
    mrp.setTypeMRP(X_PP_MRP.TYPEMRP_Demand);
    mrp.setDocStatus(X_PP_MRP.DOCSTATUS_Completed); // Firm Demand
    mrp.setOrderType(X_PP_MRP.ORDERTYPE_SalesOrder); // Sales Order
    mrp.setIsAvailable(true);
    //
    mrp.setM_Product(product);
    Services.get(IMRPBL.class).setQty(mrp, qty, qty, product.getC_UOM());
    //
    // mrp.setC_BPartner(C_BPartner);

    InterfaceWrapperHelper.save(mrp);

    return mrp;
  }
예제 #6
0
 /** Work */
 protected void doWork() {
   m_summary = new StringBuffer();
   m_errors = new StringBuffer();
   //
   int count = 0;
   int countError = 0;
   MAlert[] alerts = m_model.getAlerts(false);
   for (int i = 0; i < alerts.length; i++) {
     if (!processAlert(alerts[i])) countError++;
     count++;
   }
   //
   String summary = "Total=" + count;
   if (countError > 0) summary += ", Not processed=" + countError;
   summary += " - ";
   m_summary.insert(0, summary);
   //
   int no = m_model.deleteLog();
   m_summary.append("Logs deleted=").append(no);
   //
   MAlertProcessorLog pLog = new MAlertProcessorLog(m_model, m_summary.toString());
   pLog.setReference(
       "#"
           + String.valueOf(p_runCount)
           + " - "
           + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
   pLog.setTextMsg(m_errors.toString());
   pLog.save();
 } //	doWork
예제 #7
0
  /**
   * Sets DeliveryDateTimeMax = DeliveryDate + BufferHours.
   *
   * @param deliveryDay
   */
  @Override
  public void setDeliveryDateTimeMax(final I_M_DeliveryDay deliveryDay) {
    final Timestamp deliveryDate = deliveryDay.getDeliveryDate();
    final int bufferHours = deliveryDay.getBufferHours();
    final Timestamp deliveryDateTimeMax = TimeUtil.addHours(deliveryDate, bufferHours);

    deliveryDay.setDeliveryDateTimeMax(deliveryDateTimeMax);
  }
예제 #8
0
  private IDunnableDoc createDunnableDoc(
      final IDunningContext context, final I_C_Dunning_Candidate_Invoice_v1 candidate) {
    final int invoiceId = candidate.getC_Invoice_ID();
    final int invoicePayScheduleId = candidate.getC_InvoicePaySchedule_ID();
    final int adClientId = candidate.getAD_Client_ID();
    final int adOrgId = candidate.getAD_Org_ID();
    final int bpartnerId = candidate.getC_BPartner_ID();
    final int bpartnerLocationId = candidate.getC_BPartner_Location_ID();
    final int contactId = candidate.getAD_User_ID();
    final int currencyId = candidate.getC_Currency_ID();
    final BigDecimal grandTotal = candidate.getGrandTotal();
    final BigDecimal openAmt = candidate.getOpenAmt();
    final Date dateInvoiced = candidate.getDateInvoiced();
    final Date dueDate = candidate.getDueDate();
    final Date dunningGrace = candidate.getDunningGrace();
    final int paymentTermId = candidate.getC_PaymentTerm_ID();
    final boolean isInDispute = candidate.isInDispute();

    final String tableName;
    final int recordId;
    if (invoicePayScheduleId > 0) {
      tableName = I_C_InvoicePaySchedule.Table_Name;
      recordId = invoicePayScheduleId;
    } else
    // if (C_Invoice_ID > 0)
    {
      tableName = I_C_Invoice.Table_Name;
      recordId = invoiceId;
    }

    final int daysDue;
    if (invoicePayScheduleId > 0) {
      daysDue = TimeUtil.getDaysBetween(dueDate, context.getDunningDate());
    } else {
      daysDue =
          Services.get(IInvoiceSourceDAO.class)
              .retrieveDueDays(paymentTermId, dateInvoiced, context.getDunningDate());
    }

    final IDunnableDoc dunnableDoc =
        new DunnableDoc(
            tableName,
            recordId,
            adClientId,
            adOrgId,
            bpartnerId,
            bpartnerLocationId,
            contactId,
            currencyId,
            grandTotal,
            openAmt,
            dueDate,
            dunningGrace,
            daysDue,
            isInDispute);

    return dunnableDoc;
  }
예제 #9
0
 /**
  * ************************************************************************ Update/save Goals for
  * the same measure
  *
  * @param force force to update goal (default once per day)
  * @return true if updated
  */
 public boolean updateGoal(boolean force) {
   log.config("Force=" + force);
   MMeasure measure = MMeasure.get(getCtx(), getPA_Measure_ID());
   if (force || getDateLastRun() == null || !TimeUtil.isSameHour(getDateLastRun(), null)) {
     if (measure.updateGoals()) // 	saves
     {
       load(get_ID(), get_Trx());
       return true;
     }
   }
   return false;
 } //	updateGoal
예제 #10
0
  /**
   * Find standard Period of DateAcct based on Client Calendar
   *
   * @param ctx context
   * @param C_Calendar_ID calendar
   * @param DateAcct date
   * @return active Period or null
   */
  public static MPeriod getOfCalendar(Ctx ctx, int C_Calendar_ID, Timestamp DateAcct) {
    if (DateAcct == null) {
      s_log.warning("No DateAcct");
      return null;
    }
    if (C_Calendar_ID == 0) {
      s_log.warning("No Calendar");
      return null;
    }
    //	Search in Cache first
    Iterator<MPeriod> it = s_cache.values().iterator();
    while (it.hasNext()) {
      MPeriod period = it.next();
      if (period.getC_Calendar_ID() == C_Calendar_ID
          && period.isStandardPeriod()
          && period.isInPeriod(DateAcct)) return period;
    }

    //	Get it from DB
    MPeriod retValue = null;
    String sql =
        "SELECT * FROM C_Period "
            + "WHERE C_Year_ID IN "
            + "(SELECT C_Year_ID FROM C_Year WHERE C_Calendar_ID=?)"
            + " AND ? BETWEEN TRUNC(StartDate,'DD') AND TRUNC(EndDate,'DD')"
            + " AND IsActive='Y' AND PeriodType='S'";
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      pstmt = DB.prepareStatement(sql, (Trx) null);
      pstmt.setInt(1, C_Calendar_ID);
      pstmt.setTimestamp(2, TimeUtil.getDay(DateAcct));
      rs = pstmt.executeQuery();
      while (rs.next()) {
        MPeriod period = new MPeriod(ctx, rs, null);
        Integer key = Integer.valueOf(period.getC_Period_ID());
        s_cache.put(key, period);
        if (period.isStandardPeriod()) retValue = period;
      }
    } catch (SQLException e) {
      s_log.log(Level.SEVERE, "DateAcct=" + DateAcct, e);
    } finally {
      DB.closeStatement(pstmt);
      DB.closeResultSet(rs);
    }
    if (retValue == null)
      s_log.warning(
          "No Standard Period for " + DateAcct + " (C_Calendar_ID=" + C_Calendar_ID + ")");
    return retValue;
  } //	get
예제 #11
0
 /**
  * ************************************************************************ Standard Constructor
  *
  * @param ctx context
  * @param C_Tax_ID id
  * @param trxName transaction
  */
 public MTax(Properties ctx, int C_Tax_ID, String trxName) {
   super(ctx, C_Tax_ID, trxName);
   if (C_Tax_ID == 0) {
     //	setC_Tax_ID (0);		PK
     setIsDefault(false);
     setIsDocumentLevel(true);
     setIsSummary(false);
     setIsTaxExempt(false);
     //	setName (null);
     setRate(Env.ZERO);
     setRequiresTaxCertificate(false);
     //	setC_TaxCategory_ID (0);	//	FK
     setSOPOType(SOPOTYPE_Both);
     setValidFrom(TimeUtil.getDay(1990, 1, 1));
     setIsSalesTax(false);
   }
 } //	MTax
  @Override
  public void setParameterValue(
      final I_C_Queue_WorkPackage_Param workpackageParam, final Object parameterValue) {
    // NOTE to developer: when changing this, make sure you are also changing the counterpart method
    // createProcessInfoParameter()

    if (parameterValue == null) {
      workpackageParam.setAD_Reference_ID(DisplayType.String);
      resetParameterValue(workpackageParam);
    } else if (parameterValue instanceof String) {
      workpackageParam.setAD_Reference_ID(DisplayType.String);
      resetParameterValue(workpackageParam);
      workpackageParam.setP_String(parameterValue.toString());
    } else if (parameterValue instanceof Date) {
      final Date date = (Date) parameterValue;
      workpackageParam.setAD_Reference_ID(DisplayType.DateTime);
      resetParameterValue(workpackageParam);
      workpackageParam.setP_Date(TimeUtil.asTimestamp(date));
    } else if (parameterValue instanceof BigDecimal) {
      final BigDecimal valueBD = (BigDecimal) parameterValue;
      workpackageParam.setAD_Reference_ID(DisplayType.Number);
      resetParameterValue(workpackageParam);
      workpackageParam.setP_Number(valueBD);
    } else if (parameterValue instanceof Number) {
      final int valueInt = ((Number) parameterValue).intValue();
      workpackageParam.setAD_Reference_ID(DisplayType.Integer);
      resetParameterValue(workpackageParam);
      workpackageParam.setP_Number(BigDecimal.valueOf(valueInt));
    } else if (parameterValue instanceof Boolean) {
      final boolean valueBoolean = (boolean) parameterValue;
      workpackageParam.setAD_Reference_ID(DisplayType.YesNo);
      resetParameterValue(workpackageParam);
      workpackageParam.setP_String(DisplayType.toBooleanString(valueBoolean));
    } else {
      throw new IllegalArgumentException(
          "Unsupported parameter value: "
              + parameterValue
              + " ("
              + parameterValue.getClass()
              + ")");
    }
  }
예제 #13
0
  /** Do Work */
  @Override
  protected void doWork() {
    //	Close Socket
    if (m_serverSocket != null) {
      try {
        m_serverSocket.close();
      } catch (Exception e) {
      }
    }
    m_counter = 0;
    //
    m_summary = new StringBuffer(m_model.toString()).append(" - ");
    //

    try {
      m_serverSocket = new ServerSocket(m_model.getLdapPort());
      log.log(Level.INFO, "Opened Port=" + m_model.getLdapPort());
      while (!isInterrupted()) {
        Socket socket = m_serverSocket.accept(); // 	waits for connection
        log.log(Level.FINE, "Connection on Port=" + m_model.getLdapPort());
        LdapConnectionHandler handler = new LdapConnectionHandler(socket, m_model);
        handler.start();
        m_counter++;
      }
    } catch (Exception e) {
      log.log(Level.WARNING, "Port=" + m_model.getLdapPort(), e);
      m_summary.append(e.toString());
    }

    m_summary.append("; ").append(m_model.getInfo());

    int no = m_model.deleteLog();
    m_summary.append("; Logs deleted=").append(no);
    //
    MLdapProcessorLog pLog = new MLdapProcessorLog(m_model, m_summary.toString());
    pLog.setReference(
        "#"
            + String.valueOf(p_runCount)
            + " - "
            + TimeUtil.formatElapsed(new Timestamp(p_startWork)));
    pLog.save();
  } //	doWork
 /**
  * Check availability and insert record
  *
  * @return true if saved/updated
  */
 private boolean cmd_save() {
   log.config("");
   //	Set AssignDateTo
   Calendar date = new GregorianCalendar();
   getDateAndTimeFrom(date);
   Timestamp assignDateFrom = new Timestamp(date.getTimeInMillis());
   BigDecimal qty = fQty.getValue();
   ListItem listItem = fResource.getSelectedItem();
   KeyNamePair resource =
       listItem != null
           ? new KeyNamePair((Integer) listItem.getValue(), listItem.getLabel())
           : null;
   KeyNamePair uom = (KeyNamePair) m_lookup.get(resource);
   int minutes = MUOMConversion.convertToMinutes(Env.getCtx(), uom.getKey(), qty);
   Timestamp assignDateTo = TimeUtil.addMinutess(assignDateFrom, minutes);
   m_mAssignment.setAssignDateTo(assignDateTo);
   //
   //	m_mAssignment.dump();
   return m_mAssignment.save();
 } //	cmdSave
예제 #15
0
  /**
   * Find Period of Date based on Client Calendar, it need not be a standard period (used in MRP)
   *
   * @param ctx context
   * @param C_Calendar_ID calendar
   * @param Date date
   * @param trx trx
   * @return active Period or null
   */
  public static MPeriod getPeriod(Ctx ctx, int C_Calendar_ID, Timestamp Date, Trx trx) {
    if (Date == null) {
      s_log.warning("No Date");
      return null;
    }
    if (C_Calendar_ID == 0) {
      s_log.warning("No Calendar");
      return null;
    }

    //	Get it from DB
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    MPeriod retValue = null;
    String sql =
        "SELECT * FROM C_Period "
            + "WHERE C_Year_ID IN "
            + "(SELECT C_Year_ID FROM C_Year WHERE C_Calendar_ID=?)"
            + " AND ? BETWEEN TRUNC(StartDate,'DD') AND TRUNC(EndDate,'DD')"
            + " AND IsActive='Y' ";
    try {
      pstmt = DB.prepareStatement(sql, trx);
      pstmt.setInt(1, C_Calendar_ID);
      pstmt.setTimestamp(2, TimeUtil.getDay(Date));
      rs = pstmt.executeQuery();
      if (rs.next()) {
        retValue = new MPeriod(ctx, rs, trx);
      }
    } catch (SQLException e) {
      s_log.log(Level.SEVERE, "DateAcct=" + Date, e);
    } finally {
      DB.closeResultSet(rs);
      DB.closeStatement(pstmt);
    }
    if (retValue == null)
      s_log.warning("No Period for " + Date + " (C_Calendar_ID=" + C_Calendar_ID + ")");
    return retValue;
  } //	getPeriod
예제 #16
0
 public void setToday(int year, int month, int day) {
   this._today = TimeUtil.getDay(year, month, day);
 }
예제 #17
0
 /** @return the <code>model</code>'s date promised value, truncated to "day". */
 public Timestamp getDatePromised() {
   return TimeUtil.trunc(model.getDatePromised(), TimeUtil.TRUNC_DAY);
 }
  @Override
  public void createSupply(final IMRPCreateSupplyRequest request) {
    final IMRPContext mrpContext = request.getMRPContext();
    final IMRPExecutor executor = request.getMRPExecutor();

    final Properties ctx = mrpContext.getCtx();
    final I_PP_Product_Planning productPlanningData = mrpContext.getProductPlanning();
    final I_AD_Org org = mrpContext.getAD_Org();
    final I_S_Resource plant = mrpContext.getPlant();
    final Timestamp supplyDateFinishSchedule = TimeUtil.asTimestamp(request.getDemandDate());

    // QtyToSupply: qty for which we need to produce the supply
    final BigDecimal qtyToSupply = request.getQtyToSupply();

    // TODO vpj-cd I need to create logic for DRP-040 Shipment Due Action Notice
    // Indicates that a shipment for a Order Distribution is due.
    // Action should be taken at the source warehouse to ensure that the order is received on time.

    // TODO vpj-cd I need to create logic for DRP-050 Shipment Pas Due Action Notice
    // Indicates that a shipment for a Order Distribution is past due. You should either delay the
    // orders created the requirement for the product
    // or expedite them when the product does arrive.

    if (productPlanningData.getDD_NetworkDistribution_ID() <= 0) {
      // Indicates that the Product Planning Data for this product does not specify a valid network
      // distribution.
      executor.newMRPNote(mrpContext, ERR_DRP_060_NoSourceOfSupply).collect();
      //
      return;
    }

    final I_DD_NetworkDistribution network = productPlanningData.getDD_NetworkDistribution();
    final List<I_DD_NetworkDistributionLine> networkLines =
        Services.get(IDistributionNetworkDAO.class)
            .retrieveNetworkLinesByTargetWarehouse(
                network, productPlanningData.getM_Warehouse_ID());
    if (networkLines.isEmpty()) {
      // No network lines were found for our target warehouse
      final I_M_Warehouse warehouseTo = productPlanningData.getM_Warehouse();
      executor
          .newMRPNote(mrpContext, ERR_DRP_060_NoSourceOfSupply)
          .setComment("@NotFound@ @DD_NetworkDistributionLine_ID@")
          .addParameter(
              I_DD_NetworkDistribution.COLUMNNAME_DD_NetworkDistribution_ID,
              network == null ? "?" : network.getName())
          .addParameter("M_Warehouse_Dest_ID", warehouseTo == null ? "?" : warehouseTo.getName())
          .collect();
      //
      return;
    }

    int M_Shipper_ID = -1;
    I_DD_Order order = null;

    BigDecimal qtyToSupplyRemaining = qtyToSupply;
    for (final I_DD_NetworkDistributionLine networkLine : networkLines) {
      //
      // Check: if we created DD Orders for all qty that needed to be supplied, stop here
      if (qtyToSupplyRemaining.signum() <= 0) {
        break;
      }

      // get supply source warehouse and locator
      final I_M_Warehouse warehouseFrom = networkLine.getM_WarehouseSource();
      final I_M_Locator locatorFrom =
          Services.get(IWarehouseBL.class).getDefaultLocator(warehouseFrom);

      // get supply target warehouse and locator
      final I_M_Warehouse warehouseTo = networkLine.getM_Warehouse();
      final I_M_Locator locatorTo = Services.get(IWarehouseBL.class).getDefaultLocator(warehouseTo);

      if (locatorFrom == null || locatorTo == null) {
        executor
            .newMRPNote(mrpContext, "DRP-001") // FIXME: DRP-001 error code does not exist
            .addParameter(
                I_DD_NetworkDistribution.COLUMNNAME_DD_NetworkDistribution_ID,
                network == null ? "?" : network.getName())
            .addParameter(
                I_DD_NetworkDistributionLine.COLUMNNAME_M_WarehouseSource_ID,
                warehouseFrom.getName())
            .addParameter(
                I_DD_NetworkDistributionLine.COLUMNNAME_M_Warehouse_ID, warehouseTo.getName())
            .setComment("No locators found for source or target warehouse")
            .collect();
        //
        continue;
      }

      //
      // Get the warehouse in transit
      final I_M_Warehouse warehouseInTrasit =
          retrieveInTransitWarehouse(ctx, warehouseFrom.getAD_Org_ID());
      if (warehouseInTrasit == null) {
        // DRP-010: Do not exist Transit Warehouse to this Organization
        executor
            .newMRPNote(mrpContext, ERR_DRP_010_InTransitWarehouseNotFound)
            .addParameter(I_AD_Org.COLUMNNAME_AD_Org_ID, org.getName())
            .collect();
        //
        continue;
      }

      //
      // DRP-030: Do not exist Shipper for Create Distribution Order
      if (networkLine.getM_Shipper_ID() <= 0) {
        executor
            .newMRPNote(mrpContext, "DRP-030")
            .addParameter(
                I_DD_NetworkDistribution.COLUMNNAME_DD_NetworkDistribution_ID,
                network == null ? "?" : network.getName())
            .addParameter(
                I_DD_NetworkDistributionLine.COLUMNNAME_DD_NetworkDistributionLine_ID, networkLine)
            .collect();
        //
        continue;
      }

      if (M_Shipper_ID != networkLine.getM_Shipper_ID()) {
        // Org Must be linked to BPartner
        final I_AD_Org locatorToOrg = locatorTo.getAD_Org();
        final IBPartnerOrgBL bpartnerOrgBL = Services.get(IBPartnerOrgBL.class);
        final I_C_BPartner orgBPartner = bpartnerOrgBL.retrieveLinkedBPartner(locatorToOrg);
        if (orgBPartner == null) {
          // DRP-020: Target Org has no BP linked to it
          executor
              .newMRPNote(mrpContext, "DRP-020")
              .addParameter(I_AD_Org.COLUMNNAME_AD_Org_ID, locatorToOrg.getName())
              .collect();
          //
          continue;
        }

        final I_C_BPartner_Location orgBPLocation =
            bpartnerOrgBL.retrieveOrgBPLocation(
                mrpContext.getCtx(), locatorToOrg.getAD_Org_ID(), ITrx.TRXNAME_None);

        //
        // Try found some DD_Order with Shipper , Business Partner and Doc Status = Draft
        // Consolidate the demand in a single order for each Shipper , Business Partner ,
        // DemandDateStartSchedule
        order =
            getDDOrderFromCache(
                org,
                plant,
                warehouseInTrasit,
                networkLine.getM_Shipper_ID(),
                orgBPartner.getC_BPartner_ID(),
                supplyDateFinishSchedule);
        if (order == null) {
          order = InterfaceWrapperHelper.newInstance(I_DD_Order.class, mrpContext);
          order.setMRP_Generated(true);
          order.setMRP_AllowCleanup(true);
          order.setAD_Org_ID(warehouseTo.getAD_Org_ID());
          order.setPP_Plant(plant);
          order.setC_BPartner(orgBPartner);
          order.setC_BPartner_Location(orgBPLocation);
          // order.setAD_User_ID(productPlanningData.getPlanner_ID()); // FIXME: improve
          // performances/cache and retrive Primary BP's User
          order.setSalesRep_ID(productPlanningData.getPlanner_ID());

          final int docTypeDO_ID =
              getC_DocType_ID(mrpContext, X_C_DocType.DOCBASETYPE_DistributionOrder);
          order.setC_DocType_ID(docTypeDO_ID);
          order.setM_Warehouse(warehouseInTrasit);
          order.setDocStatus(X_DD_Order.DOCSTATUS_Drafted);
          order.setDocAction(X_DD_Order.DOCACTION_Complete);
          order.setDateOrdered(mrpContext.getDateAsTimestamp());
          order.setDatePromised(supplyDateFinishSchedule);
          order.setM_Shipper_ID(networkLine.getM_Shipper_ID());
          order.setIsInDispute(false);
          order.setIsInTransit(false);

          InterfaceWrapperHelper.save(order);

          executor.addGeneratedSupplyDocument(order);
          addToCache(order);
        }
        M_Shipper_ID = networkLine.getM_Shipper_ID();
      }

      //
      // Crate DD order line
      final BigDecimal qtyToMove =
          calculateQtyToMove(qtyToSupplyRemaining, networkLine.getPercent());
      createDD_OrderLine(
          mrpContext,
          order,
          networkLine,
          locatorFrom,
          locatorTo,
          qtyToMove,
          supplyDateFinishSchedule,
          request);

      qtyToSupplyRemaining = qtyToSupplyRemaining.subtract(qtyToMove);
    }

    //
    // Check: remaining qtyToSupply shall be ZERO
    if (qtyToSupplyRemaining.signum() != 0) {
      // TODO: introduce DRP-XXX notice
      throw new LiberoException(
          "Cannot create DD Order for required Qty To Supply."
              + "\nQtyToSupply: "
              + qtyToSupply
              + "\nQtyToSupply (remaining): "
              + qtyToSupplyRemaining
              + "\n@DD_NetworkDistribution_ID@: "
              + network
              + "\n@DD_NetworkDistributionLine_ID@: "
              + networkLines
              + "\nMRPContext: "
              + mrpContext);
    }
  }
예제 #19
0
  /**
   * Before Save. Truncate Dates
   *
   * @param newRecord new
   * @return true
   */
  @Override
  protected boolean beforeSave(boolean newRecord) {
    Timestamp startdate = getStartDate();
    Timestamp enddate = getEndDate();

    if (enddate != null && startdate.after(enddate)) {

      s_log.saveError("Error", Msg.getMsg(getCtx(), "CalPeriodInvalidDate"));
      return false;
    }
    //	Truncate Dates
    startdate = TimeUtil.getDay(startdate);
    setStartDate(startdate);

    if (enddate != null) enddate = TimeUtil.getDay(enddate);
    else enddate = TimeUtil.getMonthLastDay(getStartDate());

    //		Adding the time component of 23:59:59 to the end date
    enddate = new Timestamp(enddate.getTime() + 86399000);
    setEndDate(enddate);

    MPeriod[] periods = getAllPeriodsInYear(getC_Year_ID(), "S", getCtx(), get_Trx());
    MPeriod[] allperiods = getAllPeriodsInCalendar(getC_Calendar_ID(), "S", getCtx(), get_Trx());
    //		Check for non-negative period number
    if (getPeriodNo() < 0) {
      s_log.saveError("Error", Msg.getMsg(getCtx(), "CalNegPeriodNo"));
      return false;
    }

    //		Check for standard period
    if (isStandardPeriod() == true) {
      // Check Period number is in ascending order

      Timestamp nextPeriodStartDate = null;
      Timestamp prevPeriodStartDate = null;

      // Get the next standard period number Start Date in this year
      String sql =
          "SELECT StartDate FROM C_Period WHERE "
              + "C_Period.IsActive='Y' AND PeriodType='S' "
              + "AND C_Period.C_Year_ID =? "
              + "AND C_Period.C_Period_ID <> ?"
              + "AND  C_Period.PeriodNo "
              + " >  ?  ORDER BY  C_Period.PeriodNo ASC";
      Object[][] result = null;
      result =
          QueryUtil.executeQuery(get_Trx(), sql, getC_Year_ID(), getC_Period_ID(), getPeriodNo());

      if (result.length != 0) nextPeriodStartDate = (Timestamp) result[0][0];

      // Get the previous standard period number Start Date in this year
      sql =
          "SELECT StartDate FROM C_Period WHERE "
              + "C_Period.IsActive='Y' AND PeriodType='S'  "
              + "AND C_Period.C_Year_ID =? "
              + "AND C_Period.C_Period_ID <> ?"
              + "AND C_Period.PeriodNo "
              + "< ?  ORDER BY  C_Period.PeriodNo DESC";

      result =
          QueryUtil.executeQuery(get_Trx(), sql, getC_Year_ID(), getC_Period_ID(), getPeriodNo());
      if (result.length != 0) prevPeriodStartDate = (Timestamp) result[0][0];

      if ((prevPeriodStartDate != null
          && TimeUtil.max(prevPeriodStartDate, startdate) == prevPeriodStartDate)) {
        s_log.saveError("Error", Msg.getMsg(getCtx(), "CalPeriodAsc"));
        return false;
      }

      if ((nextPeriodStartDate != null
          && TimeUtil.max(nextPeriodStartDate, startdate) == startdate)) {
        s_log.saveError("Error", Msg.getMsg(getCtx(), "CalPeriodAsc"));
        return false;
      }

      //  Check if the Standard Period is overlapping other periods.

      for (MPeriod period : allperiods) {
        if ((TimeUtil.isValid(period.getStartDate(), period.getEndDate(), startdate) == true
                || TimeUtil.isValid(period.getStartDate(), period.getEndDate(), enddate) == true)
            && period.getC_Period_ID() != getC_Period_ID()) {
          s_log.saveError("Error", Msg.getMsg(getCtx(), "CalPeriodOverlap"));
          return false;
        }
      }

    }
    //		Check for adjusting period
    else {
      boolean startflag = false;
      boolean endflag = false;
      for (MPeriod period : periods) {
        if (TimeUtil.isValid(period.getStartDate(), period.getEndDate(), startdate) == true)
          startflag = true;
        if (TimeUtil.isValid(period.getStartDate(), period.getEndDate(), enddate) == true)
          endflag = true;
        if (startflag == true && endflag == true) break;
      }
      if (startflag == false || endflag == false) {
        s_log.saveError("Error", Msg.getMsg(getCtx(), "CalAdjPeriod"));
        return false;
      }
    }
    return true;
  } //	beforeSave
  private I_DD_OrderLine createDD_OrderLine(
      final IMRPContext mrpContext,
      final I_DD_Order order,
      final I_DD_NetworkDistributionLine networkLine,
      final I_M_Locator locatorFrom,
      final I_M_Locator locatorTo,
      final BigDecimal qtyToMove,
      final Timestamp supplyDateFinishSchedule,
      final IMRPCreateSupplyRequest request) {
    final I_M_Product product = mrpContext.getM_Product();
    final int bpartnerId = request.getMRPDemandBPartnerId();
    final int orderLineSOId = request.getMRPDemandOrderLineSOId();

    //
    // Create DD Order Line
    final I_DD_OrderLine ddOrderline =
        InterfaceWrapperHelper.newInstance(I_DD_OrderLine.class, order);
    ddOrderline.setAD_Org_ID(order.getAD_Org_ID());
    ddOrderline.setDD_Order(order);
    ddOrderline.setC_BPartner_ID(bpartnerId);
    ddOrderline.setC_OrderLineSO_ID(orderLineSOId);

    //
    // Locator From/To
    ddOrderline.setM_Locator(locatorFrom);
    ddOrderline.setM_LocatorTo(locatorTo);

    //
    // Product, UOM, Qty
    // NOTE: we assume qtyToMove is in "mrpContext.getC_UOM()" which shall be the Product's stocking
    // UOM
    ddOrderline.setM_Product(product);
    ddOrderline.setC_UOM(mrpContext.getC_UOM());
    ddOrderline.setQtyEntered(qtyToMove);
    ddOrderline.setQtyOrdered(qtyToMove);
    ddOrderline.setTargetQty(qtyToMove);

    //
    // Dates
    ddOrderline.setDateOrdered(order.getDateOrdered());
    ddOrderline.setDatePromised(order.getDatePromised());

    //
    // Other flags
    ddOrderline.setIsInvoiced(false);
    ddOrderline.setDD_AllowPush(networkLine.isDD_AllowPush());
    ddOrderline.setIsKeepTargetPlant(networkLine.isKeepTargetPlant());

    //
    // Save DD Order Line
    InterfaceWrapperHelper.save(ddOrderline);

    //
    // Create DD_OrderLine_Alternatives
    // NOTE: demand MRP line is available only in lot-for-lot order policy
    // TODO: i think we shall get all MRP demands, retrieve their alternatives, aggregate them and
    // create DD_OrderLine_Alternatives
    final I_PP_MRP parentMRPDemand = request.getMRPDemandRecordOrNull();
    if (parentMRPDemand != null) {
      final List<I_PP_MRP_Alternative> mrpAlternatives =
          mrpDAO.retrieveMRPAlternativesQuery(parentMRPDemand).create().list();
      for (final I_PP_MRP_Alternative mrpAlternative : mrpAlternatives) {
        createDD_OrderLine_Alternative(mrpContext, ddOrderline, mrpAlternative);
      }
    }

    //
    // Set Correct Planning Dates
    final int durationDays = calculateDurationDays(mrpContext, networkLine);
    final Timestamp supplyDateStartSchedule =
        TimeUtil.addDays(supplyDateFinishSchedule, 0 - durationDays);
    final List<I_PP_MRP> mrpList = mrpDAO.retrieveMRPRecords(ddOrderline);
    for (final I_PP_MRP mrp : mrpList) {
      mrp.setDateStartSchedule(supplyDateStartSchedule);
      mrp.setDateFinishSchedule(supplyDateFinishSchedule);
      InterfaceWrapperHelper.save(mrp);
    }

    return ddOrderline;
  }