/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.model; import java.io.File; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.List; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; import org.compiere.process.DocAction; import org.compiere.process.DocumentEngine; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.TimeUtil; import org.compiere.util.Util; /** * Requisition Model * * @author Jorg Janke * * @author victor.perez@e-evolution.com, e-Evolution http://www.e-evolution.com *
  • FR [ 2520591 ] Support multiples calendar for Org * @see https://sourceforge.net/p/adempiere/feature-requests/631/ * @version $Id: MRequisition.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ * @author red1 *
  • FR [ 2214883 ] Remove SQL code and Replace for Query * @author Teo Sarca, www.arhipac.ro *
  • FR [ 2744682 ] Requisition: improve error reporting */ public class MRequisition extends X_M_Requisition implements DocAction { /** * generated serial id */ private static final long serialVersionUID = 898606565778668659L; /** * UUID based Constructor * @param ctx Context * @param M_Requisition_UU UUID key * @param trxName Transaction */ public MRequisition(Properties ctx, String M_Requisition_UU, String trxName) { super(ctx, M_Requisition_UU, trxName); if (Util.isEmpty(M_Requisition_UU)) setInitialDefaults(); } /** * Standard Constructor * @param ctx context * @param M_Requisition_ID id */ public MRequisition (Properties ctx, int M_Requisition_ID, String trxName) { super (ctx, M_Requisition_ID, trxName); if (M_Requisition_ID == 0) setInitialDefaults(); } // MRequisition /** * Set the initial defaults for a new record */ private void setInitialDefaults() { setDateDoc(new Timestamp(System.currentTimeMillis())); setDateRequired (new Timestamp(System.currentTimeMillis())); setDocAction (DocAction.ACTION_Complete); // CO setDocStatus (DocAction.STATUS_Drafted); // DR setPriorityRule (PRIORITYRULE_Medium); // 5 setTotalLines (Env.ZERO); setIsApproved (false); setPosted (false); setProcessed (false); } /** * Load Constructor * @param ctx context * @param rs result set */ public MRequisition (Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); } // MRequisition /** Lines */ private MRequisitionLine[] m_lines = null; /** * Get Requisition Lines * @return array of requisition lines */ public MRequisitionLine[] getLines() { if (m_lines != null) { set_TrxName(m_lines, get_TrxName()); return m_lines; } final String whereClause = I_M_RequisitionLine.COLUMNNAME_M_Requisition_ID+"=?"; List list = new Query(getCtx(), I_M_RequisitionLine.Table_Name, whereClause, get_TrxName()) .setParameters(get_ID()) .setOrderBy(I_M_RequisitionLine.COLUMNNAME_Line+","+I_M_RequisitionLine.COLUMNNAME_M_RequisitionLine_ID) .list(); m_lines = new MRequisitionLine[list.size ()]; list.toArray (m_lines); return m_lines; } // getLines /** * String Representation * @return info */ @Override public String toString () { StringBuilder sb = new StringBuilder ("MRequisition["); sb.append(get_ID()).append("-").append(getDocumentNo()) .append(",Status=").append(getDocStatus()).append(",Action=").append(getDocAction()) .append ("]"); return sb.toString (); } // toString /** * Get Document Info * @return document info */ @Override public String getDocumentInfo() { return Msg.getElement(getCtx(), "M_Requisition_ID") + " " + getDocumentNo(); } // getDocumentInfo /** * Create PDF * @return File or null */ @Override public File createPDF () { try { File temp = File.createTempFile(get_TableName()+get_ID()+"_", ".pdf"); return createPDF (temp); } catch (Exception e) { log.severe("Could not create PDF - " + e.getMessage()); } return null; } // getPDF /** * Create PDF file * @param file output file * @return not implemented, always return null */ public File createPDF (File file) { return null; } // createPDF /** * Set default PriceList */ public void setM_PriceList_ID() { MPriceList defaultPL = MPriceList.getDefault(getCtx(), false); if (defaultPL == null) defaultPL = MPriceList.getDefault(getCtx(), true); if (defaultPL != null) setM_PriceList_ID(defaultPL.getM_PriceList_ID()); } // setM_PriceList_ID() @Override protected boolean beforeSave (boolean newRecord) { // Set default price list if (getM_PriceList_ID() == 0) setM_PriceList_ID(); return true; } // beforeSave @Override protected boolean beforeDelete() { for (MRequisitionLine line : getLines()) { line.deleteEx(true); } return true; } /** * Process document * @param processAction document action * @return true if performed */ @Override public boolean processIt (String processAction) { m_processMsg = null; DocumentEngine engine = new DocumentEngine (this, getDocStatus()); return engine.processIt (processAction, getDocAction()); } // process /** Process Message */ private String m_processMsg = null; /** Just Prepared Flag */ private boolean m_justPrepared = false; /** * Unlock Document. * @return true if success */ @Override public boolean unlockIt() { if (log.isLoggable(Level.INFO)) log.info("unlockIt - " + toString()); setProcessing(false); return true; } // unlockIt /** * Invalidate Document * @return true if success */ @Override public boolean invalidateIt() { if (log.isLoggable(Level.INFO)) log.info("invalidateIt - " + toString()); return true; } // invalidateIt /** * Prepare Document * @return new status (In Progress or Invalid) */ @Override public String prepareIt() { if (log.isLoggable(Level.INFO)) log.info(toString()); m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE); if (m_processMsg != null) return DocAction.STATUS_Invalid; MRequisitionLine[] lines = getLines(); // Invalid if (getAD_User_ID() == 0 || getM_PriceList_ID() == 0 || getM_Warehouse_ID() == 0) { return DocAction.STATUS_Invalid; } if(lines.length == 0) { throw new AdempiereException("@NoLines@"); } // Std Period open? MPeriod.testPeriodOpen(getCtx(), getDateDoc(), MDocType.DOCBASETYPE_PurchaseRequisition, getAD_Org_ID()); // Add up Amounts int precision = MPriceList.getStandardPrecision(getCtx(), getM_PriceList_ID()); BigDecimal totalLines = Env.ZERO; for (int i = 0; i < lines.length; i++) { MRequisitionLine line = lines[i]; BigDecimal lineNet = line.getQty().multiply(line.getPriceActual()); lineNet = lineNet.setScale(precision, RoundingMode.HALF_UP); if (lineNet.compareTo(line.getLineNetAmt()) != 0) { line.setLineNetAmt(lineNet); line.saveEx(); } totalLines = totalLines.add (line.getLineNetAmt()); } if (totalLines.compareTo(getTotalLines()) != 0) { setTotalLines(totalLines); saveEx(); } m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE); if (m_processMsg != null) return DocAction.STATUS_Invalid; m_justPrepared = true; return DocAction.STATUS_InProgress; } // prepareIt /** * Approve Document * @return true if success */ @Override public boolean approveIt() { if (log.isLoggable(Level.INFO)) log.info("approveIt - " + toString()); setIsApproved(true); return true; } // approveIt /** * Reject Approval * @return true if success */ @Override public boolean rejectIt() { if (log.isLoggable(Level.INFO)) log.info("rejectIt - " + toString()); setIsApproved(false); return true; } // rejectIt /** * Complete Document * @return new status (Complete, In Progress, Invalid, Waiting ..) */ @Override public String completeIt() { // Re-Check if (!m_justPrepared) { String status = prepareIt(); m_justPrepared = false; if (!DocAction.STATUS_InProgress.equals(status)) return status; } // Set the definite document number after completed (if needed) setDefiniteDocumentNo(); m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE); if (m_processMsg != null) return DocAction.STATUS_Invalid; // Implicit Approval if (!isApproved()) approveIt(); if (log.isLoggable(Level.INFO)) log.info(toString()); // User Validation String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE); if (valid != null) { m_processMsg = valid; return DocAction.STATUS_Invalid; } // setProcessed(true); setDocAction(ACTION_Close); return DocAction.STATUS_Completed; } // completeIt /** * Set the definite document number after completed */ private void setDefiniteDocumentNo() { MDocType dt = MDocType.get(getCtx(), getC_DocType_ID()); if (dt.isOverwriteDateOnComplete()) { setDateDoc(TimeUtil.getDay(0)); MPeriod.testPeriodOpen(getCtx(), getDateDoc(), MDocType.DOCBASETYPE_PurchaseRequisition, getAD_Org_ID()); } if (dt.isOverwriteSeqOnComplete()) { String value = DB.getDocumentNo(getC_DocType_ID(), get_TrxName(), true, this); if (value != null) setDocumentNo(value); } } /** * Void Document. * Same as Close. * @return true if success */ @Override public boolean voidIt() { if (log.isLoggable(Level.INFO)) log.info("voidIt - " + toString()); // Before Void m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID); if (m_processMsg != null) return false; if (!closeIt()) return false; // After Void m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID); if (m_processMsg != null) return false; return true; } // voidIt /** * Close Document. * Cancel not delivered Qunatities * @return true if success */ @Override public boolean closeIt() { if (log.isLoggable(Level.INFO)) log.info("closeIt - " + toString()); // Before Close m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE); if (m_processMsg != null) return false; // Close Not delivered Qty MRequisitionLine[] lines = getLines(); BigDecimal totalLines = Env.ZERO; for (int i = 0; i < lines.length; i++) { MRequisitionLine line = lines[i]; BigDecimal finalQty = line.getQty(); if (line.getC_OrderLine_ID() == 0) finalQty = Env.ZERO; else { MOrderLine ol = new MOrderLine (getCtx(), line.getC_OrderLine_ID(), get_TrxName()); finalQty = ol.getQtyOrdered(); } // final qty is not line qty if (finalQty.compareTo(line.getQty()) != 0) { String description = line.getDescription(); if (description == null) description = ""; description += " [" + line.getQty() + "]"; line.setDescription(description); line.setQty(finalQty); line.setLineNetAmt(); line.saveEx(); } totalLines = totalLines.add (line.getLineNetAmt()); } if (totalLines.compareTo(getTotalLines()) != 0) { setTotalLines(totalLines); saveEx(); } // After Close m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE); if (m_processMsg != null) return false; return true; } // closeIt /** * Reverse Correction * @return not implemented, always return false */ @Override public boolean reverseCorrectIt() { if (log.isLoggable(Level.INFO)) log.info("reverseCorrectIt - " + toString()); // Before reverseCorrect m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT); if (m_processMsg != null) return false; // After reverseCorrect m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT); if (m_processMsg != null) return false; return false; } // reverseCorrectionIt /** * Reverse Accrual * @return not implemented, always return false */ @Override public boolean reverseAccrualIt() { if (log.isLoggable(Level.INFO)) log.info("reverseAccrualIt - " + toString()); // Before reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSEACCRUAL); if (m_processMsg != null) return false; // After reverseAccrual m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL); if (m_processMsg != null) return false; return false; } // reverseAccrualIt /** * Re-activate * @return true if success */ @Override public boolean reActivateIt() { if (log.isLoggable(Level.INFO)) log.info("reActivateIt - " + toString()); // Before reActivate m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE); if (m_processMsg != null) return false; if (! reverseCorrectIt()) return false; // After reActivate m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE); if (m_processMsg != null) return false; return true; } // reActivateIt /** * Get Summary * @return Summary of Document */ @Override public String getSummary() { StringBuilder sb = new StringBuilder(); sb.append(getDocumentNo()); // - User sb.append(" - ").append(getUserName()); // : Total Lines = 123.00 (#1) sb.append(": "). append(Msg.translate(getCtx(),"TotalLines")).append("=").append(getTotalLines()) .append(" (#").append(getLines().length).append(")"); // - Description if (getDescription() != null && getDescription().length() > 0) sb.append(" - ").append(getDescription()); return sb.toString(); } // getSummary /** * Get Process Message * @return clear text error message */ @Override public String getProcessMsg() { return m_processMsg; } // getProcessMsg /** * Get Document Owner * @return AD_User_ID */ @Override public int getDoc_User_ID() { return getAD_User_ID(); } /** * Get Document Currency * @return C_Currency_ID */ @Override public int getC_Currency_ID() { MPriceList pl = MPriceList.get(getCtx(), getM_PriceList_ID(), get_TrxName()); return pl.getC_Currency_ID(); } /** * Get Document Approval Amount * @return amount */ @Override public BigDecimal getApprovalAmt() { return getTotalLines(); } /** * Get User Name * @return user name */ public String getUserName() { return MUser.get(getCtx(), getAD_User_ID()).getName(); } // getUserName /** * Document Status is Complete, Closed or Reverse * @return true if CO, CL or RE */ public boolean isComplete() { String ds = getDocStatus(); return DOCSTATUS_Completed.equals(ds) || DOCSTATUS_Closed.equals(ds) || DOCSTATUS_Reversed.equals(ds); } // isComplete } // MRequisition