/** * 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
/** * 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
@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@"; }
@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); }
/** * 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; }
/** 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
/** * 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); }
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; }
/** * ************************************************************************ 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
/** * 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
/** * ************************************************************************ 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() + ")"); } }
/** 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
/** * 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
public void setToday(int year, int month, int day) { this._today = TimeUtil.getDay(year, month, day); }
/** @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); } }
/** * 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; }