/** * Is standard Period closed for all Document Base Types * * @param ctx context for AD_Client * @param DateAcct accounting date * @return true if closed */ public static boolean isClosed(Ctx ctx, Timestamp DateAcct) { if (DateAcct == null) return false; MAcctSchema as = MClient.get(ctx, ctx.getAD_Client_ID()).getAcctSchema(); if (as.isAutoPeriodControl()) return !as.isAutoPeriodControlOpen(DateAcct); // Get all Calendars in line with Organizations MClientInfo cInfo = MClientInfo.get(ctx, ctx.getAD_Client_ID(), null); ArrayList<Integer> calendars = new ArrayList<Integer>(); MOrg[] orgs = MOrg.getOfClient(cInfo); for (MOrg org : orgs) { MOrgInfo info = MOrgInfo.get(ctx, org.getAD_Org_ID(), null); int C_Calendar_ID = info.getC_Calendar_ID(); if (C_Calendar_ID == 0) C_Calendar_ID = cInfo.getC_Calendar_ID(); if (!calendars.contains(C_Calendar_ID)) calendars.add(C_Calendar_ID); } // Should not happen if (calendars.size() == 0) throw new IllegalArgumentException("@NotFound@ @C_Calendar_ID@"); // For all Calendars get Periods for (int i = 0; i < calendars.size(); i++) { int C_Calendar_ID = calendars.get(i); MPeriod period = MPeriod.getOfCalendar(ctx, C_Calendar_ID, DateAcct); // Period not found if (period == null) return false; if (!period.isClosed()) return false; } return true; // closed } // isClosed
/** * Returns the previous period * * @param period MPeriod * @param periodCount Count * @param trx trx * @param ctx Ctx * @return MPeriod */ public static MPeriod getPreviousPeriod(MPeriod period, Ctx ctx, Trx trx) { MPeriod newPeriod = null; String sql = "SELECT * FROM C_Period WHERE " + "C_Period.IsActive='Y' AND PeriodType='S' " + "AND C_Period.C_Year_ID IN " + "(SELECT C_Year_ID FROM C_Year WHERE C_Year.C_Calendar_ID = ? ) " + "AND ((C_Period.C_Year_ID * 1000) + C_Period.PeriodNo) " + " < ((? * 1000) + ?) ORDER BY C_Period.C_Year_ID DESC, C_Period.PeriodNo DESC"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, trx); pstmt.setInt(1, period.getC_Calendar_ID()); pstmt.setInt(2, period.getC_Year_ID()); pstmt.setInt(3, period.getPeriodNo()); rs = pstmt.executeQuery(); if (rs.next()) newPeriod = new MPeriod(ctx, rs, trx); } catch (Exception e) { s_log.log(Level.SEVERE, sql, e); } finally { DB.closeResultSet(rs); DB.closeStatement(pstmt); } return newPeriod; }
/** * Get Period from Cache * * @param ctx context * @param C_Period_ID id * @return MPeriod */ public static MPeriod get(Ctx ctx, int C_Period_ID) { Integer key = Integer.valueOf(C_Period_ID); MPeriod retValue = s_cache.get(ctx, key); if (retValue != null) return retValue; // retValue = new MPeriod(ctx, C_Period_ID, null); if (retValue.get_ID() != 0) s_cache.put(key, retValue); return retValue; } // get
/** * Create 12 Standard Periods from the specified start date. Creates also Period Control from * DocType. * * @see DocumentTypeVerify#createPeriodControls(Properties, int, SvrProcess, String) * @param locale locale * @param startDate first day of the calendar year * @param dateFormat SimpleDateFormat pattern for generating the period names. * @return true if created */ public boolean createStdPeriods(Locale locale, Timestamp startDate, String dateFormat) { if (locale == null) { MClient client = MClient.get(getCtx()); locale = client.getLocale(); } if (locale == null && Language.getLoginLanguage() != null) locale = Language.getLoginLanguage().getLocale(); if (locale == null) locale = Env.getLanguage(getCtx()).getLocale(); // SimpleDateFormat formatter; if (dateFormat == null || dateFormat.equals("")) dateFormat = "MMM-yy"; formatter = new SimpleDateFormat(dateFormat, locale); // int year = getYearAsInt(); GregorianCalendar cal = new GregorianCalendar(locale); if (startDate != null) { cal.setTime(startDate); if (cal.get(Calendar.YEAR) != year) // specified start date takes precedence in setting year year = cal.get(Calendar.YEAR); } else { cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, 0); cal.set(Calendar.DAY_OF_MONTH, 1); } cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); // for (int month = 0; month < 12; month++) { Timestamp start = new Timestamp(cal.getTimeInMillis()); String name = formatter.format(start); // get last day of same month cal.add(Calendar.MONTH, 1); cal.add(Calendar.DAY_OF_YEAR, -1); Timestamp end = new Timestamp(cal.getTimeInMillis()); // MPeriod period = MPeriod.findByCalendar(getCtx(), start, getC_Calendar_ID(), get_TrxName()); if (period == null) { period = new MPeriod(this, month + 1, name, start, end); } else { period.setC_Year_ID(this.getC_Year_ID()); period.setPeriodNo(month + 1); period.setName(name); period.setStartDate(start); period.setEndDate(end); } period.saveEx(get_TrxName()); // Creates Period Control // get first day of next month cal.add(Calendar.DAY_OF_YEAR, 1); } return true; } // createStdPeriods
/** * Import Forecast Record using X_I_ProductPlanning table * * @param ipp X_I_ProductPlanning */ private void importForecast(X_I_ProductPlanning ipp) { if (ipp.getForecastValue() == null && ipp.getM_Forecast_ID() == 0) { ipp.setI_ErrorMsg(Msg.getMsg(getCtx(), "@M_Forecast_ID@ @NotFound@")); ipp.saveEx(); isImported = false; return; } MForecast forecast = new MForecast(getCtx(), ipp.getM_Forecast_ID(), get_TrxName()); final StringBuffer whereClause = new StringBuffer(); whereClause .append(X_M_ForecastLine.COLUMNNAME_M_Forecast_ID) .append("=? AND ") .append(X_M_ForecastLine.COLUMNNAME_M_Product_ID) .append("=? AND ") .append(X_M_ForecastLine.COLUMNNAME_M_Warehouse_ID) .append("=? AND ") .append(X_M_ForecastLine.COLUMNNAME_DatePromised) .append("=? AND ") .append(X_M_ForecastLine.COLUMNNAME_SalesRep_ID) .append("=?"); X_M_ForecastLine forecastLine = null; if (ipp.getM_ForecastLine_ID() > 0) { forecastLine = new X_M_ForecastLine(getCtx(), ipp.getM_ForecastLine_ID(), get_TrxName()); } else { forecastLine = new Query(getCtx(), X_M_ForecastLine.Table_Name, whereClause.toString(), get_TrxName()) .setClient_ID() .setParameters( new Object[] { ipp.getM_Forecast_ID(), ipp.getM_Product_ID(), ipp.getM_Warehouse_ID(), ipp.getDatePromised(), ipp.getSalesRep_ID() }) .first(); } if (forecastLine == null) { forecastLine = new X_M_ForecastLine(getCtx(), 0, get_TrxName()); } forecastLine.setM_Forecast_ID(ipp.getM_Forecast_ID()); forecastLine.setAD_Org_ID(ipp.getAD_Org_ID()); forecastLine.setM_Product_ID(ipp.getM_Product_ID()); forecastLine.setM_Warehouse_ID(ipp.getM_Warehouse_ID()); forecastLine.setC_Period_ID( MPeriod.getC_Period_ID(getCtx(), ipp.getDatePromised(), ipp.getAD_Org_ID())); forecastLine.setDatePromised(ipp.getDatePromised()); forecastLine.setSalesRep_ID(ipp.getSalesRep_ID()); forecastLine.setQty(ipp.getQty()); forecastLine.saveEx(); ipp.setM_ForecastLine_ID(forecastLine.getM_ForecastLine_ID()); ipp.saveEx(); isImported = true; }
// metas: tsa: 2181: changed method name to reflect what is doing private boolean voidIt0() { if (!isActive()) throw new IllegalStateException("Allocation already reversed (not active)"); // Can we delete posting MPeriod.testPeriodOpen( getCtx(), getDateTrx(), X_C_DocType.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); // Set Inactive setIsActive(false); setDocumentNo(getDocumentNo() + "^"); setDocStatus(DOCSTATUS_Reversed); // for direct calls if (!save() || isActive()) throw new IllegalStateException("Cannot de-activate allocation"); // Delete Posting Services.get(IFactAcctDAO.class).deleteForDocument(this); // Unlink Invoices getLines(true); final Set<Integer> bpartnerIds = new HashSet<Integer>(); for (int i = 0; i < m_lines.length; i++) { MAllocationLine line = m_lines[i]; line.setIsActive(false); line.save(); final int bpartnerId = line.processIt(true); // reverse bpartnerIds.add(bpartnerId); } updateBP(bpartnerIds); return true; } // reverse
/** * Is standard Period Open for Document Base Type - does not check Orgs * * @param ctx context * @param DateAcct date * @param DocBaseType base type * @return true if open * @deprecated use new isOpen */ @Deprecated public static boolean isOpenOld(Ctx ctx, Timestamp DateAcct, String DocBaseType) { if (DateAcct == null) { s_log.warning("No DateAcct"); return false; } if (DocBaseType == null) { s_log.warning("No DocBaseType"); return false; } MPeriod period = MPeriod.getOfOrg(ctx, 0, DateAcct); if (period == null) { s_log.warning("No Period for " + DateAcct + " (" + DocBaseType + ")"); return false; } String error = period.isOpen(DocBaseType, DateAcct); if (error != null) s_log.warning(error + " - " + period.getName()); return error == null; } // isOpen
/** * Load Invoice Line. * * @param bs bank statement 4 amounts AMTTYPE_Payment AMTTYPE_Statement2 AMTTYPE_Charge * AMTTYPE_Interest * @return DocLine Array */ private DocLine[] loadLines(final MBankStatement bs) { ArrayList<DocLine> list = new ArrayList<DocLine>(); MBankStatementLine[] lines = bs.getLines(false); for (int i = 0; i < lines.length; i++) { MBankStatementLine line = lines[i]; DocLine_BankStatement docLine = new DocLine_BankStatement(line, this); // Set Date Acct if (i == 0) setDateAcct(line.getDateAcct()); MPeriod period = MPeriod.get(getCtx(), line.getDateAcct(), line.getAD_Org_ID()); if (period != null && period.isOpen(DOCTYPE_BankStatement, line.getDateAcct(), bs.getAD_Org_ID())) { docLine.setC_Period_ID(period.getC_Period_ID()); } // list.add(docLine); } // Return Array DocLine[] dls = new DocLine[list.size()]; list.toArray(dls); return dls; } // loadLines
/** * 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
/** * Before Delete. * * @return true if acct was deleted */ @Override protected boolean beforeDelete() { String trxName = get_TrxName(); if (trxName == null || trxName.length() == 0) log.warning("No transaction"); if (isPosted()) { MPeriod.testPeriodOpen( getCtx(), getDateTrx(), MDocType.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); setPosted(false); Services.get(IFactAcctDAO.class).deleteForDocument(this); } // Unlink getLines(true); HashSet<Integer> bps = new HashSet<Integer>(); for (int i = 0; i < m_lines.length; i++) { MAllocationLine line = m_lines[i]; bps.add(line.getC_BPartner_ID()); line.deleteEx(true, trxName); } updateBP(bps); return true; } // beforeDelete
/** * gets all Periods in the Range * * @param startPeriod * @param endPeriod * @param calendar_ID * @return MPeriod[] */ public static MPeriod[] getAllPeriodsInRange( MPeriod startPeriod, MPeriod endPeriod, int calendar_ID, Ctx ctx, Trx trx) { if ((startPeriod.getC_Calendar_ID() != calendar_ID) || (endPeriod.getC_Calendar_ID() != calendar_ID)) { log.saveError("Error", "Periods do not belong to the calendar"); return null; } ArrayList<MPeriod> periods = new ArrayList<MPeriod>(); String sql = "SELECT * FROM C_Period WHERE " + "C_Period.IsActive='Y' AND PeriodType='S' " + "AND C_Period.C_Year_ID IN " + "(SELECT C_Year_ID FROM C_Year WHERE C_Year.C_Calendar_ID = ? ) " + // calendar_ID "AND ((C_Period.C_Year_ID * 1000) + C_Period.PeriodNo) BETWEEN" + " (? * 1000 + ?) AND (? * 1000 + ? )" + // start Period year ID, Period Number , End Period Year ID, Period Number " ORDER BY C_Period.C_Year_ID ASC, C_Period.PeriodNo ASC"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, trx); pstmt.setInt(1, calendar_ID); pstmt.setInt(2, startPeriod.getC_Year_ID()); pstmt.setInt(3, startPeriod.getPeriodNo()); pstmt.setInt(4, endPeriod.getC_Year_ID()); pstmt.setInt(5, endPeriod.getPeriodNo()); rs = pstmt.executeQuery(); while (rs.next()) periods.add(new MPeriod(ctx, rs, trx)); } catch (Exception e) { s_log.log(Level.SEVERE, sql, e); } finally { DB.closeResultSet(rs); DB.closeStatement(pstmt); } MPeriod[] retValue = new MPeriod[periods.size()]; periods.toArray(retValue); return retValue; }
/** * 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
/** * Is standard Period Open for specified orgs for the client. For best performance, ensure that * the list of orgs does not contain duplicates. * * @param ctx * @param AD_Client_ID * @param orgs * @param DateAcct accounting date * @param DocBaseType document base type * @return error message or null */ public static String isOpen( Ctx ctx, int AD_Client_ID, ArrayList<Integer> orgs, Timestamp DateAcct, String DocBaseType) { if (DateAcct == null) return "@NotFound@ @DateAcct@"; if (DocBaseType == null) return "@NotFound@ @DocBaseType@"; MAcctSchema as = MClient.get(ctx, AD_Client_ID).getAcctSchema(); if (as == null) return "@NotFound@ @C_AcctSchema_ID@ for AD_Client_ID=" + AD_Client_ID; if (as.isAutoPeriodControl()) { if (as.isAutoPeriodControlOpen(DateAcct)) return null; else return "@PeriodClosed@ - @AutoPeriodControl@"; } // Get all Calendars in line with Organizations MClientInfo clientInfo = MClientInfo.get(ctx, AD_Client_ID, null); ArrayList<Integer> orgCalendars = new ArrayList<Integer>(); ArrayList<Integer> calendars = new ArrayList<Integer>(); for (int org : orgs) { MOrgInfo orgInfo = MOrgInfo.get(ctx, org, null); int C_Calendar_ID = orgInfo.getC_Calendar_ID(); if (C_Calendar_ID == 0) C_Calendar_ID = clientInfo.getC_Calendar_ID(); orgCalendars.add(C_Calendar_ID); if (!calendars.contains(C_Calendar_ID)) calendars.add(C_Calendar_ID); } // Should not happen if (calendars.size() == 0) return "@NotFound@ @C_Calendar_ID@"; // For all Calendars get Periods for (int i = 0; i < calendars.size(); i++) { int C_Calendar_ID = calendars.get(i); MPeriod period = MPeriod.getOfCalendar(ctx, C_Calendar_ID, DateAcct); // First Org for Calendar int AD_Org_ID = 0; for (int j = 0; j < orgCalendars.size(); j++) { if (orgCalendars.get(j) == C_Calendar_ID) { AD_Org_ID = orgs.get(j); break; } } if (period == null) { MCalendar cal = MCalendar.get(ctx, C_Calendar_ID); String date = DisplayType.getDateFormat(DisplayTypeConstants.Date).format(DateAcct); if (cal != null) return "@NotFound@ @C_Period_ID@: " + date + " - " + MOrg.get(ctx, AD_Org_ID).getName() + " -> " + cal.getName(); else return "@NotFound@ @C_Period_ID@: " + date + " - " + MOrg.get(ctx, AD_Org_ID).getName() + " -> C_Calendar_ID=" + C_Calendar_ID; } String error = period.isOpen(DocBaseType, DateAcct); if (error != null) return error + " - " + MOrg.get(ctx, AD_Org_ID).getName() + " -> " + MCalendar.get(ctx, C_Calendar_ID).getName(); } return null; // open } // isOpen
/** * Find valid standard Period of DateAcct based on Client Calendar * * @param ctx context * @param DateAcct date * @return C_Period_ID or 0 */ public static int getC_Period_ID(Ctx ctx, int AD_Org_ID, Timestamp DateAcct) { MPeriod period = getOfOrg(ctx, AD_Org_ID, DateAcct); if (period == null) return 0; return period.getC_Period_ID(); } // getC_Period_ID
public void finishTerm(final TermAndOrder termAndOrder) { final TestConfig testConfig = helper.getConfig(); final I_C_Flatrate_Term term = termAndOrder.term; final I_C_Order order = termAndOrder.order; final I_C_Flatrate_Conditions fc = term.getC_Flatrate_Conditions(); final GridWindowHelper dataEntryHelper = helper.retrieveMainInvoicingEntry(fc, order); final I_C_Flatrate_DataEntry dataEntry = dataEntryHelper.getGridTabInterface(I_C_Flatrate_DataEntry.class); final boolean paramIsSimulation = testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_SIMULATION); if (!paramIsSimulation) { assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_AMOUNT + " for " + dataEntry, dataEntry.getFlatrateAmt(), comparesEqualTo(testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_AMOUNT))); assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_QTY_PER_UNIT + " for " + dataEntry, dataEntry.getActualQtyPerUnit(), comparesEqualTo( testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_QTY_PER_UNIT))); assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PER_UNIT + " for " + dataEntry, dataEntry.getActualQtyDiffPerUOM(), comparesEqualTo( testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PER_UNIT))); assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_EFF_PERCENT + " for " + dataEntry, dataEntry.getActualQtyDiffPercentEff(), comparesEqualTo( testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_EFF_PERCENT))); assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PERCENT + " for " + dataEntry, dataEntry.getActualQtyDiffPercent(), comparesEqualTo( testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_DIFF_PERCENT))); assertThat( FlatFeeScenario.PARAM_BD_EXP_ACTUAL_CORR_AMOUNT + " for " + dataEntry, dataEntry.getFlatrateAmtCorr(), comparesEqualTo( testConfig.getCustomParamBD(FlatFeeScenario.PARAM_BD_EXP_ACTUAL_CORR_AMOUNT))); final I_C_Invoice_Candidate invoiceCand = dataEntry.getC_Invoice_Candidate(); assertThat(invoiceCand.getM_Product_ID(), is(fc.getM_Product_Flatrate_ID())); if (fc.getM_Product_Actual_ID() == fc.getM_Product_Flatrate_ID() && !fc.isCorrectionAmtAtClosing()) { assertThat(dataEntry.getC_Invoice_Candidate_Corr_ID(), is(0)); assertThat( invoiceCand.getNetAmtToInvoice(), comparesEqualTo(dataEntry.getFlatrateAmt().add(dataEntry.getFlatrateAmtCorr()))); processCands(invoiceCandHelper, invoiceCand); assertThat( invoiceCand.getNetAmtInvoiced(), comparesEqualTo(dataEntry.getFlatrateAmt().add(dataEntry.getFlatrateAmtCorr()))); } else { assertThat(invoiceCand.getNetAmtToInvoice(), comparesEqualTo(dataEntry.getFlatrateAmt())); if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) { assertThat(fc.isCorrectionAmtAtClosing(), is(true)); // just a little guard assertThat( dataEntry + " has wrong C_Invoice_Candidate_Corr_ID", dataEntry.getC_Invoice_Candidate_Corr_ID(), is(0)); processCands(invoiceCandHelper, invoiceCand); } else { assertThat(fc.isCorrectionAmtAtClosing(), is(false)); // just a little guard assertThat(dataEntry.getC_Invoice_Candidate_Corr_ID(), greaterThan(0)); final I_C_Invoice_Candidate invoiceCandCorr = dataEntry.getC_Invoice_Candidate_Corr(); assertThat(invoiceCandCorr.getM_Product_ID(), is(fc.getM_Product_Actual_ID())); assertThat( invoiceCandCorr.getNetAmtToInvoice(), comparesEqualTo(dataEntry.getFlatrateAmtCorr())); processCands(invoiceCandHelper, invoiceCand, invoiceCandCorr); assertThat( invoiceCandCorr.getNetAmtInvoiced(), comparesEqualTo(dataEntry.getFlatrateAmtCorr())); } assertThat(invoiceCand.getNetAmtInvoiced(), comparesEqualTo(dataEntry.getFlatrateAmt())); } } // now complete all dataEntries with a Qty_reported of 1 each final List<I_C_Invoice_Candidate> allCandidates = helper.completeAllInvoicingEntries(term, BigDecimal.ONE); if (!paramIsSimulation) { assertThat(allCandidates.size(), greaterThan(0)); } processCands( invoiceCandHelper, allCandidates.toArray(new I_C_Invoice_Candidate[allCandidates.size()])); if (!term.isClosingWithCorrectionSum()) { // we are done return; } final MPeriod closingPeriod = MPeriod.findByCalendar( driver.getCtx(), term.getEndDate(), fc.getC_Flatrate_Transition().getC_Calendar_Contract_ID(), driver.getTrxName()); helper .mkProcessHelper() .setProcessClass(C_Flatrate_Term_Prepare_Closing.class) .setPO(term) .setParameter(I_C_Period.COLUMNNAME_C_Period_ID, closingPeriod.getC_Period_ID()) .run(); final GridWindowHelper entryGridWindowHelper = helper.retrieveMainCorrectionEntry(fc, term); final I_C_Flatrate_DataEntry correctionEntry = entryGridWindowHelper.getGridTabInterface(I_C_Flatrate_DataEntry.class); // expecting <PARAM_TRANSITION_TERM_DURATION> times 1 plus <PARAM_BD_UNITS_REPORTED> assertThat( correctionEntry + " has wrong Qty_Planned", correctionEntry.getQty_Planned(), comparesEqualTo( new BigDecimal( testConfig.getCustomParamInt(ContractsHelper.PARAM_TRANSITION_TERM_DURATION)) .add(testConfig.getCustomParamBD(PARAM_BD_UNITS_REPORTED)))); final BigDecimal correctionQty = testConfig.getCustomParamBD(PARAM_BD_UNITS_REPORTED).add(new BigDecimal("2")); correctionEntry.setQty_Reported(correctionQty); helper.completeEntry(entryGridWindowHelper, X_C_Flatrate_DataEntry.DOCSTATUS_Completed); invoiceCandHelper.runProcess_UpdateInvoiceCands(); assertThat( correctionEntry + " wrong FlatrateAmtPerUOM", correctionEntry.getFlatrateAmtPerUOM(), comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_PRICE_PER_UNIT_CLOSING))); assertThat( correctionEntry + " wrong FlatrateAmt", correctionEntry.getFlatrateAmt(), comparesEqualTo( correctionQty .subtract(correctionEntry.getQty_Planned()) .multiply(correctionEntry.getFlatrateAmtPerUOM()))); if (testConfig.getCustomParamBool(PARAM_BOOL_IS_SIMULATION)) { assertThat(correctionEntry.getC_Invoice_Candidate_ID(), is(0)); assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), is(0)); if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) { assertThat( correctionEntry + " has wrong ActualQty", correctionEntry.getActualQty(), comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_ACTUAL_QTY))); assertThat( correctionEntry + " has wrong FlatrateAmtCorr.signum()", correctionEntry.getFlatrateAmtCorr().signum(), not(is(0))); } } else { assertThat(correctionEntry.getC_Invoice_Candidate_ID(), greaterThan(0)); final I_C_Invoice_Candidate correctionEntryCand = correctionEntry.getC_Invoice_Candidate(); assertThat( correctionEntryCand + " wrong M_Product_ID", correctionEntryCand.getM_Product_ID(), is(fc.getM_Product_Correction_ID())); assertThat( correctionEntryCand + " wrong NetAmtToInvoice", correctionEntryCand.getNetAmtToInvoice(), comparesEqualTo(correctionEntry.getFlatrateAmt())); if (testConfig.getCustomParamBool(FlatFeeScenario.PARAM_BOOL_IS_CORR_AFTER_CLOSING)) { assertThat( correctionEntry + " has wrong ActualQty", correctionEntry.getActualQty(), comparesEqualTo(testConfig.getCustomParamBD(PARAM_BD_ACTUAL_QTY))); // note: the actual numbers are checked in a unit test assertThat( correctionEntry + " has wrong FlatrateAmtCorr().signum()", correctionEntry.getFlatrateAmtCorr().signum(), greaterThan(0)); assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), greaterThan(0)); final I_C_Invoice_Candidate correctionEntryCorrCand = correctionEntry.getC_Invoice_Candidate_Corr(); assertThat(correctionEntryCorrCand.getM_Product_ID(), is(fc.getM_Product_Actual_ID())); assertThat( correctionEntryCorrCand.getNetAmtToInvoice(), comparesEqualTo(correctionEntry.getFlatrateAmtCorr())); } else { assertThat(correctionEntry.getFlatrateAmtCorr().signum(), equalTo(0)); assertThat(correctionEntry.getC_Invoice_Candidate_Corr_ID(), equalTo(0)); } } }
/** * Prepare Document * * @return new status (In Progress or Invalid) */ @Override public String prepareIt() { log.log(Level.INFO, "{0}", this); m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); if (m_processMsg != null) return DocAction.STATUS_Invalid; // Std Period open? MPeriod.testPeriodOpen( getCtx(), getDateAcct(), MDocType.DOCBASETYPE_PaymentAllocation, getAD_Org_ID()); getLines(false); if (m_lines.length == 0) { m_processMsg = "@NoLines@"; return DocAction.STATUS_Invalid; } // Stop the Document Workflow if invoice to allocate is as paid // @formatter:off // 04627: metas.ts: commenting out, because: // we want to allocate, even if the invoice is paid (in that case with amout=0), because a // customer might // inadvertedly overpay an invoice, but still this shall also be documented in the allocation // if (this.getReversal_ID() <= 0) { // metas: tsa: 02181: check only if is not a reversal // for (MAllocationLine line :m_lines) // { // if (line.getC_Invoice_ID() != 0) // { // final String whereClause = I_C_Invoice.COLUMNNAME_C_Invoice_ID + "=? AND " // + I_C_Invoice.COLUMNNAME_IsPaid + "=? AND " // + I_C_Invoice.COLUMNNAME_DocStatus + " NOT IN (?,?)"; // boolean InvoiceIsPaid = new Query(getCtx(), I_C_Invoice.Table_Name, whereClause, // get_TrxName()) // .setClient_ID() // .setParameters(new Object[]{line.getC_Invoice_ID(), "Y", MInvoice.DOCSTATUS_Voided, // MInvoice.DOCSTATUS_Reversed}) // .match(); // if(InvoiceIsPaid) // throw new AdempiereException("@ValidationError@ @C_Invoice_ID@ @IsPaid@"); // } // } // } // metas: tsa: 02181: check only if is not a reversal // @formatter:on // Add up Amounts & validate BigDecimal approval = Env.ZERO; for (int i = 0; i < m_lines.length; i++) { MAllocationLine line = m_lines[i]; approval = approval.add(line.getWriteOffAmt()).add(line.getDiscountAmt()); // Make sure there is BP if (line.getC_BPartner_ID() <= 0) { m_processMsg = "No Business Partner"; return DocAction.STATUS_Invalid; } } setApprovalAmt(approval); // m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE); if (m_processMsg != null) return DocAction.STATUS_Invalid; m_justPrepared = true; if (!DOCACTION_Complete.equals(getDocAction())) setDocAction(DOCACTION_Complete); return DocAction.STATUS_InProgress; } // prepareIt