This commit is contained in:
parent
c68297f7bb
commit
3b762965b1
|
@ -0,0 +1,510 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 1999-2006 Adempiere, 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. *
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Robert Klein. robeklein@hotmail.com
|
||||||
|
* Contributor(s): Low Heng Sin hengsin@avantz.com
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.pipo.handler;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.xml.transform.sax.TransformerHandler;
|
||||||
|
|
||||||
|
import org.adempiere.pipo.AbstractElementHandler;
|
||||||
|
import org.adempiere.pipo.Element;
|
||||||
|
import org.adempiere.pipo.exception.DatabaseAccessException;
|
||||||
|
import org.adempiere.pipo.exception.POSaveFailedException;
|
||||||
|
import org.compiere.model.MRole;
|
||||||
|
import org.compiere.model.X_AD_Form;
|
||||||
|
import org.compiere.model.X_AD_Package_Exp_Detail;
|
||||||
|
import org.compiere.model.X_AD_Process;
|
||||||
|
import org.compiere.model.X_AD_Role;
|
||||||
|
import org.compiere.model.X_AD_Task;
|
||||||
|
import org.compiere.model.X_AD_User;
|
||||||
|
import org.compiere.model.X_AD_Window;
|
||||||
|
import org.compiere.model.X_AD_Workflow;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.AttributesImpl;
|
||||||
|
|
||||||
|
public class RoleElementHandler extends AbstractElementHandler {
|
||||||
|
|
||||||
|
private List<Integer> roles = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
private OrgRoleElementHandler orgHandler = new OrgRoleElementHandler();
|
||||||
|
private ProcessAccessElementHandler processHandler = new ProcessAccessElementHandler();
|
||||||
|
private UserRoleElementHandler userHandler = new UserRoleElementHandler();
|
||||||
|
private WindowAccessElementHandler windowHandler = new WindowAccessElementHandler();
|
||||||
|
private FormAccessElementHandler formHandler = new FormAccessElementHandler();
|
||||||
|
private TaskAccessElementHandler taskHandler = new TaskAccessElementHandler();
|
||||||
|
private WorkflowAccessElementHandler workflowHandler = new WorkflowAccessElementHandler();
|
||||||
|
|
||||||
|
public void startElement(Properties ctx, Element element)
|
||||||
|
throws SAXException {
|
||||||
|
String elementValue = element.getElementValue();
|
||||||
|
Attributes atts = element.attributes;
|
||||||
|
log.info(elementValue + " " + atts.getValue("Name"));
|
||||||
|
|
||||||
|
String name = atts.getValue("Name");
|
||||||
|
|
||||||
|
int id = get_ID(ctx, "AD_Role", name);
|
||||||
|
MRole m_Role = new MRole(ctx, id, getTrxName(ctx));
|
||||||
|
|
||||||
|
int AD_Backup_ID = -1;
|
||||||
|
String Object_Status = null;
|
||||||
|
if (id > 0) {
|
||||||
|
AD_Backup_ID = copyRecord(ctx, "AD_Role", m_Role);
|
||||||
|
Object_Status = "Update";
|
||||||
|
} else {
|
||||||
|
Object_Status = "New";
|
||||||
|
AD_Backup_ID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Role.setName(name);
|
||||||
|
name = atts.getValue("treemenuname");
|
||||||
|
if (name != null && name.trim().length() > 0) {
|
||||||
|
id = get_IDWithColumn(ctx, "AD_Tree", "Name", name);
|
||||||
|
if (id <= 0) {
|
||||||
|
element.defer = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Role.setAD_Tree_Menu_ID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = atts.getValue("treeorgname");
|
||||||
|
if (name != null && name.trim().length() > 0) {
|
||||||
|
id = get_IDWithColumn(ctx, "AD_Tree", "Name", name);
|
||||||
|
if (id <= 0) {
|
||||||
|
element.defer = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Role.setAD_Tree_Org_ID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = atts.getValue("currencycode");
|
||||||
|
if (name != null && name.trim().length() > 0) {
|
||||||
|
id = get_IDWithColumn(ctx, "C_Currency", "ISO_Code", name);
|
||||||
|
if (id <= 0) {
|
||||||
|
element.defer = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Role.setC_Currency_ID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
name = atts.getValue("supervisorid");
|
||||||
|
if (name != null && name.trim().length() > 0) {
|
||||||
|
id = get_IDWithColumn(ctx, "AD_User", "Name", name);
|
||||||
|
if (id <= 0) {
|
||||||
|
element.defer = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_Role.setC_Currency_ID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Role.setDescription(getStringValue(atts,"Description"));
|
||||||
|
String amtApproval = getStringValue(atts,"AmtApproval");
|
||||||
|
if (amtApproval != null)
|
||||||
|
m_Role.setAmtApproval(new BigDecimal(amtApproval));
|
||||||
|
m_Role.setIsActive(atts.getValue("isActive") != null ? Boolean.valueOf(
|
||||||
|
atts.getValue("isActive")).booleanValue() : true);
|
||||||
|
m_Role
|
||||||
|
.setIsAccessAllOrgs(atts.getValue("isAccessAllOrgs") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isAccessAllOrgs"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role
|
||||||
|
.setIsCanApproveOwnDoc(atts.getValue("isCanApproveOwnDoc") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isCanApproveOwnDoc"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role.setIsCanExport(atts.getValue("isCanExport") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isCanExport")).booleanValue() : true);
|
||||||
|
m_Role.setIsCanReport(atts.getValue("isCanReport") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isCanReport")).booleanValue() : true);
|
||||||
|
m_Role.setIsChangeLog(atts.getValue("isChangeLog") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isChangeLog")).booleanValue() : true);
|
||||||
|
m_Role.setIsManual(atts.getValue("isManual") != null ? Boolean.valueOf(
|
||||||
|
atts.getValue("isManual")).booleanValue() : true);
|
||||||
|
m_Role
|
||||||
|
.setIsPersonalAccess(atts.getValue("isPersonalAccess") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isPersonalAccess"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role
|
||||||
|
.setIsPersonalLock(atts.getValue("isPersonalLock") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isPersonalLock"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role.setIsShowAcct(atts.getValue("isShowAcct") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isShowAcct")).booleanValue() : true);
|
||||||
|
m_Role
|
||||||
|
.setIsUseUserOrgAccess(atts.getValue("isUseUserOrgAccess") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isUseUserOrgAccess"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role
|
||||||
|
.setOverwritePriceLimit(atts.getValue("isOverwritePriceLimit") != null ? Boolean
|
||||||
|
.valueOf(atts.getValue("isOverwritePriceLimit"))
|
||||||
|
.booleanValue()
|
||||||
|
: true);
|
||||||
|
m_Role.setPreferenceType(atts.getValue("PreferenceType"));
|
||||||
|
m_Role.setUserLevel(atts.getValue("UserLevel"));
|
||||||
|
m_Role.setAllow_Info_Account(Boolean.valueOf(atts.getValue("AllowInfoAccount")));
|
||||||
|
m_Role.setAllow_Info_Asset(Boolean.valueOf(atts.getValue("AllowInfoAsset")));
|
||||||
|
m_Role.setAllow_Info_BPartner(Boolean.valueOf(atts.getValue("AllowInfoBPartner")));
|
||||||
|
m_Role.setAllow_Info_CashJournal(Boolean.valueOf(atts.getValue("AllowInfoCashJournal")));
|
||||||
|
m_Role.setAllow_Info_InOut(Boolean.valueOf(atts.getValue("AllowInfoInOut")));
|
||||||
|
m_Role.setAllow_Info_Invoice(Boolean.valueOf(atts.getValue("AllowInfoInvoice")));
|
||||||
|
m_Role.setAllow_Info_Order(Boolean.valueOf(atts.getValue("AllowInfoOrder")));
|
||||||
|
m_Role.setAllow_Info_Payment(Boolean.valueOf(atts.getValue("AllowInfoPayment")));
|
||||||
|
m_Role.setAllow_Info_Product(Boolean.valueOf(atts.getValue("AllowInfoProduct")));
|
||||||
|
m_Role.setAllow_Info_Resource(Boolean.valueOf(atts.getValue("AllowInfoResource")));
|
||||||
|
m_Role.setAllow_Info_Schedule(Boolean.valueOf(atts.getValue("AllowInfoSchedule")));
|
||||||
|
|
||||||
|
if (m_Role.save(getTrxName(ctx)) == true) {
|
||||||
|
|
||||||
|
record_log(ctx, 1, m_Role.getName(), "Role", m_Role.get_ID(),
|
||||||
|
AD_Backup_ID, Object_Status, "AD_Role", get_IDWithColumn(
|
||||||
|
ctx, "AD_Table", "TableName", "AD_Role"));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
record_log(ctx, 0, m_Role.getName(), "Role", m_Role.get_ID(),
|
||||||
|
AD_Backup_ID, Object_Status, "AD_Role", get_IDWithColumn(
|
||||||
|
ctx, "AD_Table", "TableName", "AD_Role"));
|
||||||
|
throw new POSaveFailedException("Role");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endElement(Properties ctx, Element element) throws SAXException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(Properties ctx, TransformerHandler document)
|
||||||
|
throws SAXException {
|
||||||
|
int Role_id = Env.getContextAsInt(ctx,
|
||||||
|
X_AD_Package_Exp_Detail.COLUMNNAME_AD_Role_ID);
|
||||||
|
if (roles.contains(Role_id))
|
||||||
|
return;
|
||||||
|
roles.add(Role_id);
|
||||||
|
X_AD_Role m_Role = new X_AD_Role(ctx, Role_id, null);
|
||||||
|
AttributesImpl atts = new AttributesImpl();
|
||||||
|
createRoleBinding(atts, m_Role);
|
||||||
|
document.startElement("", "", "role", atts);
|
||||||
|
|
||||||
|
// Process org access
|
||||||
|
String sql = "SELECT * FROM AD_Role_OrgAccess WHERE AD_Role_ID= "
|
||||||
|
+ Role_id;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createOrgAccess(ctx, document, rs.getInt("AD_Org_ID"), rs
|
||||||
|
.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Role_OrgAccess", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export organization role access.");
|
||||||
|
}
|
||||||
|
// Process user assignment access
|
||||||
|
sql = "SELECT * FROM AD_User_Roles WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createUserRole(ctx, document, rs.getInt("AD_User_ID"),
|
||||||
|
rs.getInt("AD_Role_ID"), rs.getInt("AD_Org_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_User_Roles", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export user role assignment.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process AD_Window_Access Values
|
||||||
|
sql = "SELECT * FROM AD_Window_Access WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createWindowAccess(ctx, document, rs
|
||||||
|
.getInt("AD_Window_ID"), rs.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Window_Access", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export window access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process AD_Process_Access Values
|
||||||
|
sql = "SELECT * FROM AD_Process_Access WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createProcessAccess(ctx, document, rs
|
||||||
|
.getInt("AD_Process_ID"), rs.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Process_Access", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export process access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process AD_Form_Access Values
|
||||||
|
sql = "SELECT * FROM AD_Form_Access WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createFormAccess(ctx, document, rs.getInt("AD_Form_ID"),
|
||||||
|
rs.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Form_Access", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export form access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process AD_Workflow_Access Values
|
||||||
|
sql = "SELECT * FROM AD_Workflow_Access WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createWorkflowAccess(ctx, document, rs
|
||||||
|
.getInt("AD_Workflow_ID"), rs.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Workflow_Access", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export workflow access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process AD_Task_Access Values
|
||||||
|
sql = "SELECT * FROM AD_Task_Access WHERE AD_Role_ID= " + Role_id;
|
||||||
|
pstmt = null;
|
||||||
|
pstmt = DB.prepareStatement(sql, getTrxName(ctx));
|
||||||
|
try {
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
createTaskAccess(ctx, document, rs.getInt("AD_Task_ID"), rs
|
||||||
|
.getInt("AD_Role_ID"));
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception e) {
|
||||||
|
log.log(Level.SEVERE, "AD_Task_Access", e);
|
||||||
|
throw new DatabaseAccessException("Failed to export task access.");
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
document.endElement("", "", "role");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTaskAccess(Properties ctx, TransformerHandler document,
|
||||||
|
int AD_Task_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_Task.COLUMNNAME_AD_Task_ID, AD_Task_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
taskHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_Task.COLUMNNAME_AD_Task_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createWorkflowAccess(Properties ctx,
|
||||||
|
TransformerHandler document, int AD_Workflow_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_Workflow.COLUMNNAME_AD_Workflow_ID, AD_Workflow_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
workflowHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_Workflow.COLUMNNAME_AD_Workflow_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFormAccess(Properties ctx, TransformerHandler document,
|
||||||
|
int AD_Form_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_Form.COLUMNNAME_AD_Form_ID, AD_Form_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
formHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_Form.COLUMNNAME_AD_Form_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createProcessAccess(Properties ctx,
|
||||||
|
TransformerHandler document, int AD_Process_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_Process.COLUMNNAME_AD_Process_ID, AD_Process_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
processHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_Process.COLUMNNAME_AD_Process_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createWindowAccess(Properties ctx,
|
||||||
|
TransformerHandler document, int AD_Window_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_Window.COLUMNNAME_AD_Window_ID, AD_Window_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
windowHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_Window.COLUMNNAME_AD_Window_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createUserRole(Properties ctx, TransformerHandler document,
|
||||||
|
int AD_User_ID, int AD_Role_ID, int AD_Org_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, X_AD_User.COLUMNNAME_AD_User_ID, AD_User_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
Env.setContext(ctx, "AD_Org_ID", AD_Org_ID);
|
||||||
|
userHandler.create(ctx, document);
|
||||||
|
ctx.remove(X_AD_User.COLUMNNAME_AD_User_ID);
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
ctx.remove("AD_Org_ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createOrgAccess(Properties ctx, TransformerHandler document,
|
||||||
|
int AD_Org_ID, int AD_Role_ID) throws SAXException {
|
||||||
|
Env.setContext(ctx, "AD_Org_ID", AD_Org_ID);
|
||||||
|
Env.setContext(ctx, X_AD_Role.COLUMNNAME_AD_Role_ID, AD_Role_ID);
|
||||||
|
orgHandler.create(ctx, document);
|
||||||
|
ctx.remove("AD_Org_ID");
|
||||||
|
ctx.remove(X_AD_Role.COLUMNNAME_AD_Role_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AttributesImpl createRoleBinding(AttributesImpl atts,
|
||||||
|
X_AD_Role m_Role) {
|
||||||
|
String sql = null;
|
||||||
|
String name = null;
|
||||||
|
atts.clear();
|
||||||
|
|
||||||
|
if (m_Role.getAD_Tree_Menu_ID() > 0) {
|
||||||
|
sql = "SELECT Name FROM AD_Tree WHERE AD_Tree_ID=? AND AD_Tree.TreeType='MM'";
|
||||||
|
name = DB.getSQLValueString(null, sql, m_Role.getAD_Tree_Menu_ID());
|
||||||
|
atts.addAttribute("", "", "treemenuname", "CDATA", name);
|
||||||
|
} else
|
||||||
|
atts.addAttribute("", "", "treemenuname", "CDATA", "");
|
||||||
|
|
||||||
|
if (m_Role.getAD_Tree_Org_ID() > 0) {
|
||||||
|
sql = "SELECT Name FROM AD_Tree WHERE AD_Tree_ID=? AND AD_Tree.TreeType='OO'";
|
||||||
|
name = DB.getSQLValueString(null, sql, m_Role.getAD_Tree_Org_ID());
|
||||||
|
atts.addAttribute("", "", "treeorgname", "CDATA", name);
|
||||||
|
} else
|
||||||
|
atts.addAttribute("", "", "treeorgname", "CDATA", "");
|
||||||
|
|
||||||
|
if (m_Role.getC_Currency_ID() > 0) {
|
||||||
|
sql = "SELECT ISO_Code FROM C_Currency WHERE C_Currency_ID=?";
|
||||||
|
name = DB.getSQLValueString(null, sql, m_Role.getC_Currency_ID());
|
||||||
|
atts.addAttribute("", "", "currencycode", "CDATA", name);
|
||||||
|
} else
|
||||||
|
atts.addAttribute("", "", "currencycode", "CDATA", "");
|
||||||
|
|
||||||
|
if (m_Role.getSupervisor_ID() > 0) {
|
||||||
|
sql = "SELECT Name FROM AD_User WHERE AD_User_ID=?";
|
||||||
|
name = DB.getSQLValueString(null, sql, m_Role.getC_Currency_ID());
|
||||||
|
atts.addAttribute("", "", "supervisorid", "CDATA", name);
|
||||||
|
} else
|
||||||
|
atts.addAttribute("", "", "supervisorid", "CDATA", "");
|
||||||
|
|
||||||
|
atts.addAttribute("", "", "Description", "CDATA", (m_Role
|
||||||
|
.getDescription() != null ? m_Role.getDescription() : ""));
|
||||||
|
atts.addAttribute("", "", "Name", "CDATA",
|
||||||
|
(m_Role.getName() != null ? m_Role.getName() : ""));
|
||||||
|
atts.addAttribute("", "", "AmtApproval", "CDATA", ("" + m_Role
|
||||||
|
.getAmtApproval()));
|
||||||
|
atts.addAttribute("", "", "isAccessAllOrgs", "CDATA", (m_Role
|
||||||
|
.isAccessAllOrgs() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isActive", "CDATA",
|
||||||
|
(m_Role.isActive() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isCanApproveOwnDoc", "CDATA", (m_Role
|
||||||
|
.isCanApproveOwnDoc() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isCanExport", "CDATA",
|
||||||
|
(m_Role.isCanExport() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isCanReport", "CDATA",
|
||||||
|
(m_Role.isCanReport() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isChangeLog", "CDATA",
|
||||||
|
(m_Role.isChangeLog() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isManual", "CDATA",
|
||||||
|
(m_Role.isManual() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isPersonalAccess", "CDATA", (m_Role
|
||||||
|
.isPersonalAccess() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isPersonalLock", "CDATA", (m_Role
|
||||||
|
.isPersonalLock() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isShowAcct", "CDATA",
|
||||||
|
(m_Role.isShowAcct() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isUseUserOrgAccess", "CDATA", (m_Role
|
||||||
|
.isUseUserOrgAccess() == true ? "true" : "false"));
|
||||||
|
atts.addAttribute("", "", "isOverwritePriceLimit", "CDATA", (m_Role
|
||||||
|
.isOverwritePriceLimit() == true ? "true" : "false"));
|
||||||
|
atts
|
||||||
|
.addAttribute("", "", "PreferenceType", "CDATA", (m_Role
|
||||||
|
.getPreferenceType() != null ? m_Role
|
||||||
|
.getPreferenceType() : ""));
|
||||||
|
atts.addAttribute("", "", "UserLevel", "CDATA",
|
||||||
|
(m_Role.getUserLevel() != null ? m_Role.getUserLevel() : ""));
|
||||||
|
|
||||||
|
atts.addAttribute("", "", "AllowInfoAccount", "CDATA", Boolean.toString(m_Role.isAllow_Info_Account()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoAsset", "CDATA", Boolean.toString(m_Role.isAllow_Info_Asset()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoBPartner", "CDATA", Boolean.toString(m_Role.isAllow_Info_BPartner()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoCashJournal", "CDATA", Boolean.toString(m_Role.isAllow_Info_CashJournal()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoInOut", "CDATA", Boolean.toString(m_Role.isAllow_Info_InOut()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoInvoice", "CDATA", Boolean.toString(m_Role.isAllow_Info_Invoice()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoOrder", "CDATA", Boolean.toString(m_Role.isAllow_Info_Order()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoPayment", "CDATA", Boolean.toString(m_Role.isAllow_Info_Payment()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoProduct", "CDATA", Boolean.toString(m_Role.isAllow_Info_Product()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoResource", "CDATA", Boolean.toString(m_Role.isAllow_Info_Resource()));
|
||||||
|
atts.addAttribute("", "", "AllowInfoSchedule", "CDATA", Boolean.toString(m_Role.isAllow_Info_Schedule()));
|
||||||
|
|
||||||
|
return atts;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,738 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.process.DocAction;
|
||||||
|
import org.compiere.process.DocumentEngine;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment Allocation Model.
|
||||||
|
* Allocation Trigger update C_BPartner
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MAllocationHdr.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public final class MAllocationHdr extends X_C_AllocationHdr implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Allocations of Payment
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_Payment_ID payment
|
||||||
|
* @return allocations of payment
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public static MAllocationHdr[] getOfPayment (Properties ctx, int C_Payment_ID, String trxName)
|
||||||
|
{
|
||||||
|
String sql = "SELECT * FROM C_AllocationHdr h "
|
||||||
|
+ "WHERE IsActive='Y'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM C_AllocationLine l "
|
||||||
|
+ "WHERE h.C_AllocationHdr_ID=l.C_AllocationHdr_ID AND l.C_Payment_ID=?)";
|
||||||
|
ArrayList<MAllocationHdr> list = new ArrayList<MAllocationHdr>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, trxName);
|
||||||
|
pstmt.setInt(1, C_Payment_ID);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
list.add (new MAllocationHdr(ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
MAllocationHdr[] retValue = new MAllocationHdr[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getOfPayment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Allocations of Invoice
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_Invoice_ID payment
|
||||||
|
* @return allocations of payment
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public static MAllocationHdr[] getOfInvoice (Properties ctx, int C_Invoice_ID, String trxName)
|
||||||
|
{
|
||||||
|
String sql = "SELECT * FROM C_AllocationHdr h "
|
||||||
|
+ "WHERE IsActive='Y'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM C_AllocationLine l "
|
||||||
|
+ "WHERE h.C_AllocationHdr_ID=l.C_AllocationHdr_ID AND l.C_Invoice_ID=?)";
|
||||||
|
ArrayList<MAllocationHdr> list = new ArrayList<MAllocationHdr>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, trxName);
|
||||||
|
pstmt.setInt(1, C_Invoice_ID);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
list.add (new MAllocationHdr(ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
MAllocationHdr[] retValue = new MAllocationHdr[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getOfInvoice
|
||||||
|
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger(MAllocationHdr.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_AllocationHdr_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MAllocationHdr (Properties ctx, int C_AllocationHdr_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, C_AllocationHdr_ID, trxName);
|
||||||
|
if (C_AllocationHdr_ID == 0)
|
||||||
|
{
|
||||||
|
// setDocumentNo (null);
|
||||||
|
setDateTrx (new Timestamp(System.currentTimeMillis()));
|
||||||
|
setDateAcct (getDateTrx());
|
||||||
|
setDocAction (DOCACTION_Complete); // CO
|
||||||
|
setDocStatus (DOCSTATUS_Drafted); // DR
|
||||||
|
// setC_Currency_ID (0);
|
||||||
|
setApprovalAmt (Env.ZERO);
|
||||||
|
setIsApproved (false);
|
||||||
|
setIsManual (false);
|
||||||
|
//
|
||||||
|
setPosted (false);
|
||||||
|
setProcessed (false);
|
||||||
|
setProcessing(false);
|
||||||
|
}
|
||||||
|
} // MAllocation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mandatory New Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param IsManual manual trx
|
||||||
|
* @param DateTrx date (if null today)
|
||||||
|
* @param C_Currency_ID currency
|
||||||
|
* @param description description
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MAllocationHdr (Properties ctx, boolean IsManual, Timestamp DateTrx,
|
||||||
|
int C_Currency_ID, String description, String trxName)
|
||||||
|
{
|
||||||
|
this (ctx, 0, trxName);
|
||||||
|
setIsManual(IsManual);
|
||||||
|
if (DateTrx != null)
|
||||||
|
{
|
||||||
|
setDateTrx (DateTrx);
|
||||||
|
setDateAcct (DateTrx);
|
||||||
|
}
|
||||||
|
setC_Currency_ID (C_Currency_ID);
|
||||||
|
if (description != null)
|
||||||
|
setDescription(description);
|
||||||
|
} // create Allocation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MAllocationHdr (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MAllocation
|
||||||
|
|
||||||
|
/** Lines */
|
||||||
|
private MAllocationLine[] m_lines = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Lines
|
||||||
|
* @param requery if true requery
|
||||||
|
* @return lines
|
||||||
|
*/
|
||||||
|
public MAllocationLine[] getLines (boolean requery)
|
||||||
|
{
|
||||||
|
if (m_lines != null && m_lines.length != 0 && !requery) {
|
||||||
|
set_TrxName(m_lines, get_TrxName());
|
||||||
|
return m_lines;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
String sql = "SELECT * FROM C_AllocationLine WHERE C_AllocationHdr_ID=?";
|
||||||
|
ArrayList<MAllocationLine> list = new ArrayList<MAllocationLine>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getC_AllocationHdr_ID());
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
{
|
||||||
|
MAllocationLine line = new MAllocationLine(getCtx(), rs, get_TrxName());
|
||||||
|
line.setParent(this);
|
||||||
|
list.add (line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
m_lines = new MAllocationLine[list.size ()];
|
||||||
|
list.toArray (m_lines);
|
||||||
|
return m_lines;
|
||||||
|
} // getLines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Processed
|
||||||
|
* @param processed Processed
|
||||||
|
*/
|
||||||
|
public void setProcessed (boolean processed)
|
||||||
|
{
|
||||||
|
super.setProcessed (processed);
|
||||||
|
if (get_ID() == 0)
|
||||||
|
return;
|
||||||
|
String sql = "UPDATE C_AllocationHdr SET Processed='"
|
||||||
|
+ (processed ? "Y" : "N")
|
||||||
|
+ "' WHERE C_AllocationHdr_ID=" + getC_AllocationHdr_ID();
|
||||||
|
int no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
m_lines = null;
|
||||||
|
log.fine(processed + " - #" + no);
|
||||||
|
} // setProcessed
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord
|
||||||
|
* @return save
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
// Changed from Not to Active
|
||||||
|
if (!newRecord && is_ValueChanged("IsActive") && isActive())
|
||||||
|
{
|
||||||
|
log.severe ("Cannot Re-Activate deactivated Allocations");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Delete.
|
||||||
|
* @return true if acct was deleted
|
||||||
|
*/
|
||||||
|
protected boolean beforeDelete ()
|
||||||
|
{
|
||||||
|
String trxName = get_TrxName();
|
||||||
|
if (trxName == null || trxName.length() == 0)
|
||||||
|
log.warning ("No transaction");
|
||||||
|
if (isPosted())
|
||||||
|
{
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getDateTrx(), MDocType.DOCBASETYPE_PaymentAllocation))
|
||||||
|
{
|
||||||
|
log.warning ("Period Closed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setPosted(false);
|
||||||
|
if (MFactAcct.delete (Table_ID, get_ID(), trxName) < 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Mark as Inactive
|
||||||
|
setIsActive(false); // updated DB for line delete/process
|
||||||
|
String sql = "UPDATE C_AllocationHdr SET IsActive='N' WHERE C_AllocationHdr_ID=?";
|
||||||
|
DB.executeUpdate(sql, getC_AllocationHdr_ID(), trxName);
|
||||||
|
|
||||||
|
// 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(new Integer(line.getC_BPartner_ID()));
|
||||||
|
if (!line.delete(true, trxName))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
updateBP(bps);
|
||||||
|
return true;
|
||||||
|
} // beforeDelete
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Save
|
||||||
|
* @param newRecord
|
||||||
|
* @param success
|
||||||
|
* @return success
|
||||||
|
*/
|
||||||
|
protected boolean afterSave (boolean newRecord, boolean success)
|
||||||
|
{
|
||||||
|
return success;
|
||||||
|
} // afterSave
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
public boolean processIt (String processAction)
|
||||||
|
{
|
||||||
|
m_processMsg = null;
|
||||||
|
DocumentEngine engine = new DocumentEngine (this, getDocStatus());
|
||||||
|
return engine.processIt (processAction, getDocAction());
|
||||||
|
} // processIt
|
||||||
|
|
||||||
|
/** Process Message */
|
||||||
|
private String m_processMsg = null;
|
||||||
|
/** Just Prepared Flag */
|
||||||
|
private boolean m_justPrepared = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setDocAction(DOCACTION_Prepare);
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Std Period open?
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getDateAcct(), MDocType.DOCBASETYPE_PaymentAllocation))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
getLines(false);
|
||||||
|
if (m_lines.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// 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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approve Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
if (!isApproved())
|
||||||
|
approveIt();
|
||||||
|
log.info(toString());
|
||||||
|
|
||||||
|
// Link
|
||||||
|
getLines(false);
|
||||||
|
HashSet<Integer> bps = new HashSet<Integer>();
|
||||||
|
for (int i = 0; i < m_lines.length; i++)
|
||||||
|
{
|
||||||
|
MAllocationLine line = m_lines[i];
|
||||||
|
bps.add(new Integer(line.processIt(false))); // not reverse
|
||||||
|
}
|
||||||
|
updateBP(bps);
|
||||||
|
|
||||||
|
// 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(DOCACTION_Close);
|
||||||
|
return DocAction.STATUS_Completed;
|
||||||
|
} // completeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* Same as Close.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean retValue = reverseIt();
|
||||||
|
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* Cancel not delivered Qunatities
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean retValue = reverseIt();
|
||||||
|
|
||||||
|
// After reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return retValue;
|
||||||
|
} // reverseCorrectionIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual - none
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean retValue = reverseIt();
|
||||||
|
|
||||||
|
// After reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return retValue;
|
||||||
|
} // reverseAccrualIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-activate
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // reActivateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MAllocationHdr[");
|
||||||
|
sb.append(get_ID()).append("-").append(getSummary()).append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
return Msg.getElement(getCtx(), "C_AllocationHdr_ID") + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Get Summary
|
||||||
|
* @return Summary of Document
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getDocumentNo());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"ApprovalAmt")).append("=").append(getApprovalAmt())
|
||||||
|
.append(" (#").append(getLines(false).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
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getCreatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Reverse Allocation.
|
||||||
|
* Period needs to be open
|
||||||
|
* @return true if reversed
|
||||||
|
*/
|
||||||
|
private boolean reverseIt()
|
||||||
|
{
|
||||||
|
if (!isActive())
|
||||||
|
throw new IllegalStateException("Allocation already reversed (not active)");
|
||||||
|
|
||||||
|
// Can we delete posting
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getDateTrx(), MPeriodControl.DOCBASETYPE_PaymentAllocation))
|
||||||
|
throw new IllegalStateException("@PeriodClosed@");
|
||||||
|
|
||||||
|
// Set Inactive
|
||||||
|
setIsActive (false);
|
||||||
|
setDocumentNo(getDocumentNo()+"^");
|
||||||
|
setDocStatus(DOCSTATUS_Reversed); // for direct calls
|
||||||
|
if (!save() || isActive())
|
||||||
|
throw new IllegalStateException("Cannot de-activate allocation");
|
||||||
|
|
||||||
|
// Delete Posting
|
||||||
|
int no = MFactAcct.delete(MAllocationHdr.Table_ID, getC_AllocationHdr_ID(), get_TrxName());
|
||||||
|
log.fine("Fact_Acct deleted #" + no);
|
||||||
|
|
||||||
|
// Unlink Invoices
|
||||||
|
getLines(true);
|
||||||
|
HashSet<Integer> bps = new HashSet<Integer>();
|
||||||
|
for (int i = 0; i < m_lines.length; i++)
|
||||||
|
{
|
||||||
|
MAllocationLine line = m_lines[i];
|
||||||
|
line.setIsActive(false);
|
||||||
|
line.save();
|
||||||
|
bps.add(new Integer(line.processIt(true))); // reverse
|
||||||
|
}
|
||||||
|
updateBP(bps);
|
||||||
|
return true;
|
||||||
|
} // reverse
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Open Balance of BP's
|
||||||
|
* @param bps list of business partners
|
||||||
|
*/
|
||||||
|
private void updateBP(HashSet<Integer> bps)
|
||||||
|
{
|
||||||
|
log.info("#" + bps.size());
|
||||||
|
Iterator<Integer> it = bps.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
int C_BPartner_ID = it.next();
|
||||||
|
MBPartner bp = new MBPartner(getCtx(), C_BPartner_ID, get_TrxName());
|
||||||
|
bp.setTotalOpenBalance(); // recalculates from scratch
|
||||||
|
// bp.setSOCreditStatus(); // called automatically
|
||||||
|
if (bp.save())
|
||||||
|
log.fine(bp.toString());
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "BP not updated - " + bp);
|
||||||
|
}
|
||||||
|
} // updateBP
|
||||||
|
|
||||||
|
} // MAllocation
|
|
@ -0,0 +1,776 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.process.DocAction;
|
||||||
|
import org.compiere.process.DocumentEngine;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.DisplayType;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
import org.compiere.util.TimeUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cash Journal Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MCash.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*
|
||||||
|
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
|
||||||
|
* <li>BF [ 1831997 ] Cash journal allocation reversed
|
||||||
|
* <li>BF [ 1894524 ] Pay an reversed invoice
|
||||||
|
*/
|
||||||
|
public class MCash extends X_C_Cash implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Cash Journal for currency, org and date
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_Currency_ID currency
|
||||||
|
* @param AD_Org_ID org
|
||||||
|
* @param dateAcct date
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return cash
|
||||||
|
*/
|
||||||
|
public static MCash get (Properties ctx, int AD_Org_ID,
|
||||||
|
Timestamp dateAcct, int C_Currency_ID, String trxName)
|
||||||
|
{
|
||||||
|
MCash retValue = null;
|
||||||
|
// Existing Journal
|
||||||
|
String sql;
|
||||||
|
sql = "SELECT * FROM C_Cash c "
|
||||||
|
+ "WHERE c.AD_Org_ID=?" // #1
|
||||||
|
+ " AND TRUNC(c.StatementDate)=?" // #2
|
||||||
|
+ " AND c.Processed='N'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM C_CashBook cb "
|
||||||
|
+ "WHERE c.C_CashBook_ID=cb.C_CashBook_ID AND cb.AD_Org_ID=c.AD_Org_ID"
|
||||||
|
+ " AND cb.C_Currency_ID=?)"; // #3
|
||||||
|
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, AD_Org_ID);
|
||||||
|
pstmt.setTimestamp (2, TimeUtil.getDay(dateAcct));
|
||||||
|
pstmt.setInt (3, C_Currency_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
retValue = new MCash (ctx, rs, trxName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
|
||||||
|
// Get CashBook
|
||||||
|
MCashBook cb = MCashBook.get (ctx, AD_Org_ID, C_Currency_ID);
|
||||||
|
if (cb == null)
|
||||||
|
{
|
||||||
|
s_log.warning("No CashBook for AD_Org_ID=" + AD_Org_ID + ", C_Currency_ID=" + C_Currency_ID);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create New Journal
|
||||||
|
retValue = new MCash (cb, dateAcct);
|
||||||
|
retValue.save(trxName);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Cash Journal for CashBook and date
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_CashBook_ID cashbook
|
||||||
|
* @param dateAcct date
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return cash
|
||||||
|
*/
|
||||||
|
public static MCash get (Properties ctx, int C_CashBook_ID,
|
||||||
|
Timestamp dateAcct, String trxName)
|
||||||
|
{
|
||||||
|
MCash retValue = null;
|
||||||
|
// Existing Journal
|
||||||
|
String sql = "SELECT * FROM C_Cash c "
|
||||||
|
+ "WHERE c.C_CashBook_ID=?" // #1
|
||||||
|
+ " AND TRUNC(c.StatementDate)=?" // #2
|
||||||
|
+ " AND c.Processed='N'";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, C_CashBook_ID);
|
||||||
|
pstmt.setTimestamp (2, TimeUtil.getDay(dateAcct));
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
retValue = new MCash (ctx, rs, trxName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
|
||||||
|
// Get CashBook
|
||||||
|
MCashBook cb = new MCashBook (ctx, C_CashBook_ID, trxName);
|
||||||
|
if (cb.get_ID() ==0)
|
||||||
|
{
|
||||||
|
s_log.warning("Not found C_CashBook_ID=" + C_CashBook_ID);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create New Journal
|
||||||
|
retValue = new MCash (cb, dateAcct);
|
||||||
|
retValue.save(trxName);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/** Static Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MCash.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param C_Cash_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MCash (Properties ctx, int C_Cash_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, C_Cash_ID, trxName);
|
||||||
|
if (C_Cash_ID == 0)
|
||||||
|
{
|
||||||
|
// setC_CashBook_ID (0); // FK
|
||||||
|
setBeginningBalance (Env.ZERO);
|
||||||
|
setEndingBalance (Env.ZERO);
|
||||||
|
setStatementDifference(Env.ZERO);
|
||||||
|
setDocAction(DOCACTION_Complete);
|
||||||
|
setDocStatus(DOCSTATUS_Drafted);
|
||||||
|
//
|
||||||
|
Timestamp today = TimeUtil.getDay(System.currentTimeMillis());
|
||||||
|
setStatementDate (today); // @#Date@
|
||||||
|
setDateAcct (today); // @#Date@
|
||||||
|
String name = DisplayType.getDateFormat(DisplayType.Date).format(today)
|
||||||
|
+ " " + MOrg.get(ctx, getAD_Org_ID()).getValue();
|
||||||
|
setName (name);
|
||||||
|
setIsApproved(false);
|
||||||
|
setPosted (false); // N
|
||||||
|
setProcessed (false);
|
||||||
|
}
|
||||||
|
} // MCash
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MCash (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MCash
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent Constructor
|
||||||
|
* @param cb cash book
|
||||||
|
* @param today date - if null today
|
||||||
|
*/
|
||||||
|
public MCash (MCashBook cb, Timestamp today)
|
||||||
|
{
|
||||||
|
this (cb.getCtx(), 0, cb.get_TrxName());
|
||||||
|
setClientOrg(cb);
|
||||||
|
setC_CashBook_ID(cb.getC_CashBook_ID());
|
||||||
|
if (today != null)
|
||||||
|
{
|
||||||
|
setStatementDate (today);
|
||||||
|
setDateAcct (today);
|
||||||
|
String name = DisplayType.getDateFormat(DisplayType.Date).format(today)
|
||||||
|
+ " " + cb.getName();
|
||||||
|
setName (name);
|
||||||
|
}
|
||||||
|
m_book = cb;
|
||||||
|
} // MCash
|
||||||
|
|
||||||
|
/** Lines */
|
||||||
|
private MCashLine[] m_lines = null;
|
||||||
|
/** CashBook */
|
||||||
|
private MCashBook m_book = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Lines
|
||||||
|
* @param requery requery
|
||||||
|
* @return lines
|
||||||
|
*/
|
||||||
|
public MCashLine[] getLines (boolean requery)
|
||||||
|
{
|
||||||
|
if (m_lines != null && !requery) {
|
||||||
|
set_TrxName(m_lines, get_TrxName());
|
||||||
|
return m_lines;
|
||||||
|
}
|
||||||
|
ArrayList<MCashLine> list = new ArrayList<MCashLine>();
|
||||||
|
String sql = "SELECT * FROM C_CashLine WHERE C_Cash_ID=? ORDER BY Line";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getC_Cash_ID());
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new MCashLine (getCtx(), rs, get_TrxName()));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines = new MCashLine[list.size ()];
|
||||||
|
list.toArray (m_lines);
|
||||||
|
return m_lines;
|
||||||
|
} // getLines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Cash Book
|
||||||
|
* @return cash book
|
||||||
|
*/
|
||||||
|
public MCashBook getCashBook()
|
||||||
|
{
|
||||||
|
if (m_book == null)
|
||||||
|
m_book = MCashBook.get(getCtx(), getC_CashBook_ID());
|
||||||
|
return m_book;
|
||||||
|
} // getCashBook
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document No
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
|
public String getDocumentNo()
|
||||||
|
{
|
||||||
|
return getName();
|
||||||
|
} // getDocumentNo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
return Msg.getElement(getCtx(), "C_Cash_ID") + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
setAD_Org_ID(getCashBook().getAD_Org_ID());
|
||||||
|
if (getAD_Org_ID() == 0)
|
||||||
|
{
|
||||||
|
log.saveError("Error", Msg.parseTranslation(getCtx(), "@AD_Org_ID@"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Calculate End Balance
|
||||||
|
setEndingBalance(getBeginningBalance().add(getStatementDifference()));
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setDocAction(DOCACTION_Prepare);
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Std Period open?
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getDateAcct(), MDocType.DOCBASETYPE_CashJournal))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
MCashLine[] lines = getLines(false);
|
||||||
|
if (lines.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// Add up Amounts
|
||||||
|
BigDecimal difference = Env.ZERO;
|
||||||
|
int C_Currency_ID = getC_Currency_ID();
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MCashLine line = lines[i];
|
||||||
|
if (!line.isActive())
|
||||||
|
continue;
|
||||||
|
if (C_Currency_ID == line.getC_Currency_ID())
|
||||||
|
difference = difference.add(line.getAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BigDecimal amt = MConversionRate.convert(getCtx(), line.getAmount(),
|
||||||
|
line.getC_Currency_ID(), C_Currency_ID, getDateAcct(), 0,
|
||||||
|
getAD_Client_ID(), getAD_Org_ID());
|
||||||
|
if (amt == null)
|
||||||
|
{
|
||||||
|
m_processMsg = "No Conversion Rate found - @C_CashLine_ID@= " + line.getLine();
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
difference = difference.add(amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setStatementDifference(difference);
|
||||||
|
// setEndingBalance(getBeginningBalance().add(getStatementDifference()));
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approve Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
if (!isApproved())
|
||||||
|
approveIt();
|
||||||
|
//
|
||||||
|
log.info(toString());
|
||||||
|
|
||||||
|
MCashLine[] lines = getLines(false);
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MCashLine line = lines[i];
|
||||||
|
if (MCashLine.CASHTYPE_Invoice.equals(line.getCashType()))
|
||||||
|
{
|
||||||
|
// Check if the invoice is completed - teo_sarca BF [ 1894524 ]
|
||||||
|
MInvoice invoice = line.getInvoice();
|
||||||
|
if (!MInvoice.DOCSTATUS_Completed.equals(invoice.getDocStatus())
|
||||||
|
&& !MInvoice.DOCSTATUS_Closed.equals(invoice.getDocStatus()))
|
||||||
|
{
|
||||||
|
m_processMsg = "@Line@ "+line.getLine()+": @InvoiceCreateDocNotCompleted@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
String name = Msg.translate(getCtx(), "C_Cash_ID") + ": " + getName()
|
||||||
|
+ " - " + Msg.translate(getCtx(), "Line") + " " + line.getLine();
|
||||||
|
MAllocationHdr hdr = new MAllocationHdr(getCtx(), false,
|
||||||
|
getDateAcct(), line.getC_Currency_ID(),
|
||||||
|
name, get_TrxName());
|
||||||
|
hdr.setAD_Org_ID(getAD_Org_ID());
|
||||||
|
if (!hdr.save())
|
||||||
|
{
|
||||||
|
m_processMsg = CLogger.retrieveErrorString("Could not create Allocation Hdr");
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// Allocation Line
|
||||||
|
MAllocationLine aLine = new MAllocationLine (hdr, line.getAmount(),
|
||||||
|
line.getDiscountAmt(), line.getWriteOffAmt(), Env.ZERO);
|
||||||
|
aLine.setC_Invoice_ID(line.getC_Invoice_ID());
|
||||||
|
aLine.setC_CashLine_ID(line.getC_CashLine_ID());
|
||||||
|
if (!aLine.save())
|
||||||
|
{
|
||||||
|
m_processMsg = CLogger.retrieveErrorString("Could not create Allocation Line");
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// Should start WF
|
||||||
|
if(!hdr.processIt(DocAction.ACTION_Complete)) {
|
||||||
|
m_processMsg = CLogger.retrieveErrorString("Could not process Allocation");
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
if (!hdr.save()) {
|
||||||
|
m_processMsg = CLogger.retrieveErrorString("Could not save Allocation");
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (MCashLine.CASHTYPE_BankAccountTransfer.equals(line.getCashType()))
|
||||||
|
{
|
||||||
|
// Payment just as intermediate info
|
||||||
|
MPayment pay = new MPayment (getCtx(), 0, get_TrxName());
|
||||||
|
pay.setAD_Org_ID(getAD_Org_ID());
|
||||||
|
String documentNo = getName();
|
||||||
|
pay.setDocumentNo(documentNo);
|
||||||
|
pay.setR_PnRef(documentNo);
|
||||||
|
pay.set_Value("TrxType", "X"); // Transfer
|
||||||
|
pay.set_Value("TenderType", "X");
|
||||||
|
//
|
||||||
|
pay.setC_BankAccount_ID(line.getC_BankAccount_ID());
|
||||||
|
pay.setC_DocType_ID(true); // Receipt
|
||||||
|
pay.setDateTrx(getStatementDate());
|
||||||
|
pay.setDateAcct(getDateAcct());
|
||||||
|
pay.setAmount(line.getC_Currency_ID(), line.getAmount().negate()); // Transfer
|
||||||
|
pay.setDescription(line.getDescription());
|
||||||
|
pay.setDocStatus(MPayment.DOCSTATUS_Closed);
|
||||||
|
pay.setDocAction(MPayment.DOCACTION_None);
|
||||||
|
pay.setPosted(true);
|
||||||
|
pay.setIsAllocated(true); // Has No Allocation!
|
||||||
|
pay.setProcessed(true);
|
||||||
|
if (!pay.save())
|
||||||
|
{
|
||||||
|
m_processMsg = CLogger.retrieveErrorString("Could not create Payment");
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(DOCACTION_Close);
|
||||||
|
return DocAction.STATUS_Completed;
|
||||||
|
} // completeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* Same as Close.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return false;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* Cancel not delivered Qunatities
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return true;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
log.info(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 - none
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
log.info(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
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setProcessed(false);
|
||||||
|
if (reverseCorrectIt())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// After reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
return false;
|
||||||
|
} // reActivateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Processed
|
||||||
|
* @param processed processed
|
||||||
|
*/
|
||||||
|
public void setProcessed (boolean processed)
|
||||||
|
{
|
||||||
|
super.setProcessed (processed);
|
||||||
|
String sql = "UPDATE C_CashLine SET Processed='"
|
||||||
|
+ (processed ? "Y" : "N")
|
||||||
|
+ "' WHERE C_Cash_ID=" + getC_Cash_ID();
|
||||||
|
int noLine = DB.executeUpdate (sql, get_TrxName());
|
||||||
|
m_lines = null;
|
||||||
|
log.fine(processed + " - Lines=" + noLine);
|
||||||
|
} // setProcessed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MCash[");
|
||||||
|
sb.append (get_ID ())
|
||||||
|
.append ("-").append (getName())
|
||||||
|
.append(", Balance=").append(getBeginningBalance())
|
||||||
|
.append("->").append(getEndingBalance())
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Get Summary
|
||||||
|
* @return Summary of Document
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getName());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"BeginningBalance")).append("=").append(getBeginningBalance())
|
||||||
|
.append(",")
|
||||||
|
.append(Msg.translate(getCtx(),"EndingBalance")).append("=").append(getEndingBalance())
|
||||||
|
.append(" (#").append(getLines(false).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
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getCreatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Approval Amount
|
||||||
|
* @return amount difference
|
||||||
|
*/
|
||||||
|
public BigDecimal getApprovalAmt()
|
||||||
|
{
|
||||||
|
return getStatementDifference();
|
||||||
|
} // getApprovalAmt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Currency
|
||||||
|
* @return Currency
|
||||||
|
*/
|
||||||
|
public int getC_Currency_ID ()
|
||||||
|
{
|
||||||
|
return getCashBook().getC_Currency_ID();
|
||||||
|
} // getC_Currency_ID
|
||||||
|
|
||||||
|
} // MCash
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,972 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.*;
|
||||||
|
import java.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.process.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Physical Inventory Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MInventory.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MInventory extends X_M_Inventory implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Inventory from Cache
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Inventory_ID id
|
||||||
|
* @return MInventory
|
||||||
|
*/
|
||||||
|
public static MInventory get (Properties ctx, int M_Inventory_ID)
|
||||||
|
{
|
||||||
|
Integer key = new Integer (M_Inventory_ID);
|
||||||
|
MInventory retValue = (MInventory) s_cache.get (key);
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
retValue = new MInventory (ctx, M_Inventory_ID, null);
|
||||||
|
if (retValue.get_ID () != 0)
|
||||||
|
s_cache.put (key, retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/** Cache */
|
||||||
|
private static CCache<Integer,MInventory> s_cache = new CCache<Integer,MInventory>("M_Inventory", 5, 5);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Inventory_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MInventory (Properties ctx, int M_Inventory_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_Inventory_ID, trxName);
|
||||||
|
if (M_Inventory_ID == 0)
|
||||||
|
{
|
||||||
|
// setName (null);
|
||||||
|
// setM_Warehouse_ID (0); // FK
|
||||||
|
setMovementDate (new Timestamp(System.currentTimeMillis()));
|
||||||
|
setDocAction (DOCACTION_Complete); // CO
|
||||||
|
setDocStatus (DOCSTATUS_Drafted); // DR
|
||||||
|
setIsApproved (false);
|
||||||
|
setMovementDate (new Timestamp(System.currentTimeMillis())); // @#Date@
|
||||||
|
setPosted (false);
|
||||||
|
setProcessed (false);
|
||||||
|
}
|
||||||
|
} // MInventory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MInventory (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MInventory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse Constructor
|
||||||
|
* @param wh warehouse
|
||||||
|
*/
|
||||||
|
public MInventory (MWarehouse wh)
|
||||||
|
{
|
||||||
|
this (wh.getCtx(), 0, wh.get_TrxName());
|
||||||
|
setClientOrg(wh);
|
||||||
|
setM_Warehouse_ID(wh.getM_Warehouse_ID());
|
||||||
|
} // MInventory
|
||||||
|
|
||||||
|
|
||||||
|
/** Lines */
|
||||||
|
private MInventoryLine[] m_lines = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Lines
|
||||||
|
* @param requery requery
|
||||||
|
* @return array of lines
|
||||||
|
*/
|
||||||
|
public MInventoryLine[] getLines (boolean requery)
|
||||||
|
{
|
||||||
|
if (m_lines != null && !requery) {
|
||||||
|
set_TrxName(m_lines, get_TrxName());
|
||||||
|
return m_lines;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
ArrayList<MInventoryLine> list = new ArrayList<MInventoryLine>();
|
||||||
|
String sql = "SELECT * FROM M_InventoryLine WHERE M_Inventory_ID=? ORDER BY Line";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getM_Inventory_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new MInventoryLine (getCtx(), rs, get_TrxName()));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines = new MInventoryLine[list.size ()];
|
||||||
|
list.toArray (m_lines);
|
||||||
|
return m_lines;
|
||||||
|
} // getLines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to Description
|
||||||
|
* @param description text
|
||||||
|
*/
|
||||||
|
public void addDescription (String description)
|
||||||
|
{
|
||||||
|
String desc = getDescription();
|
||||||
|
if (desc == null)
|
||||||
|
setDescription(description);
|
||||||
|
else
|
||||||
|
setDescription(desc + " | " + description);
|
||||||
|
} // addDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite Client/Org - from Import.
|
||||||
|
* @param AD_Client_ID client
|
||||||
|
* @param AD_Org_ID org
|
||||||
|
*/
|
||||||
|
public void setClientOrg (int AD_Client_ID, int AD_Org_ID)
|
||||||
|
{
|
||||||
|
super.setClientOrg(AD_Client_ID, AD_Org_ID);
|
||||||
|
} // setClientOrg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MInventory[");
|
||||||
|
sb.append (get_ID())
|
||||||
|
.append ("-").append (getDocumentNo())
|
||||||
|
.append (",M_Warehouse_ID=").append(getM_Warehouse_ID())
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
return dt.getName() + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
if (getC_DocType_ID() == 0)
|
||||||
|
{
|
||||||
|
MDocType types[] = MDocType.getOfDocBaseType(getCtx(), MDocType.DOCBASETYPE_MaterialPhysicalInventory);
|
||||||
|
if (types.length > 0) // get first
|
||||||
|
setC_DocType_ID(types[0].getC_DocType_ID());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@ @C_DocType_ID@"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Processed.
|
||||||
|
* Propergate to Lines/Taxes
|
||||||
|
* @param processed processed
|
||||||
|
*/
|
||||||
|
public void setProcessed (boolean processed)
|
||||||
|
{
|
||||||
|
super.setProcessed (processed);
|
||||||
|
if (get_ID() == 0)
|
||||||
|
return;
|
||||||
|
String sql = "UPDATE M_InventoryLine SET Processed='"
|
||||||
|
+ (processed ? "Y" : "N")
|
||||||
|
+ "' WHERE M_Inventory_ID=" + getM_Inventory_ID();
|
||||||
|
int noLine = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
m_lines = null;
|
||||||
|
log.fine("Processed=" + processed + " - Lines=" + noLine);
|
||||||
|
} // setProcessed
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
public boolean processIt (String processAction)
|
||||||
|
{
|
||||||
|
m_processMsg = null;
|
||||||
|
DocumentEngine engine = new DocumentEngine (this, getDocStatus());
|
||||||
|
return engine.processIt (processAction, getDocAction());
|
||||||
|
} // processIt
|
||||||
|
|
||||||
|
/** Process Message */
|
||||||
|
private String m_processMsg = null;
|
||||||
|
/** Just Prepared Flag */
|
||||||
|
private boolean m_justPrepared = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setDocAction(DOCACTION_Prepare);
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Std Period open?
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getMovementDate(), MDocType.DOCBASETYPE_MaterialPhysicalInventory))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
MInventoryLine[] lines = getLines(false);
|
||||||
|
if (lines.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add up Amounts
|
||||||
|
// setApprovalAmt();
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approve Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
if (!isApproved())
|
||||||
|
approveIt();
|
||||||
|
log.info(toString());
|
||||||
|
|
||||||
|
//vpj-cd begin e-evolution recalculate the attribute instances and qty.
|
||||||
|
MInventoryLine[] linesup = getLines(false);
|
||||||
|
for (int i = 0; i < linesup.length; i++)
|
||||||
|
{
|
||||||
|
MInventoryLine line = linesup[i];
|
||||||
|
|
||||||
|
String sql1 = "Delete From M_InventoryLineMA "
|
||||||
|
+ " WHERE M_InventoryLine_ID=" +line.getM_InventoryLine_ID();
|
||||||
|
int no = DB.executeUpdate(sql1, get_TrxName());
|
||||||
|
log.info("MA deleted " + no);
|
||||||
|
|
||||||
|
StringBuffer sql = new StringBuffer(
|
||||||
|
"SELECT s.M_Product_ID, s.M_Locator_ID, s.M_AttributeSetInstance_ID,"
|
||||||
|
+ " s.QtyOnHand, p.M_AttributeSet_ID "
|
||||||
|
+ "FROM M_Product p"
|
||||||
|
+ " INNER JOIN M_Storage s ON (s.M_Product_ID=p.M_Product_ID)"
|
||||||
|
+ " INNER JOIN M_Locator l ON (s.M_Locator_ID=l.M_Locator_ID) "
|
||||||
|
+ "WHERE l.M_Warehouse_ID=?"
|
||||||
|
+ " AND p.IsActive='Y' AND p.IsStocked='Y' and p.ProductType='I'"
|
||||||
|
+ " AND s.M_Locator_ID=" +line.getM_Locator_ID()
|
||||||
|
+ " AND s.M_Product_ID=" +line.getM_Product_ID()
|
||||||
|
+ " AND s.QtyOnHand <> 0 "
|
||||||
|
);
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql.toString(), get_TrxName());
|
||||||
|
int index = 1;
|
||||||
|
pstmt.setInt (index++, getM_Warehouse_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
{
|
||||||
|
MInventoryLineMA maup = new MInventoryLineMA (line,
|
||||||
|
rs.getInt(3), rs.getBigDecimal(4));
|
||||||
|
|
||||||
|
if (!maup.save())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql.toString(), e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//vpj-cd e-evolution recalculate the attribute instances and qty END.
|
||||||
|
//
|
||||||
|
MInventoryLine[] lines = getLines(false);
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MInventoryLine line = lines[i];
|
||||||
|
if (!line.isActive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MTransaction trx = null;
|
||||||
|
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||||
|
{
|
||||||
|
BigDecimal qtyDiff = line.getQtyInternalUse().negate();
|
||||||
|
if (qtyDiff.signum() == 0)
|
||||||
|
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
|
||||||
|
//
|
||||||
|
if (qtyDiff.signum() > 0)
|
||||||
|
{
|
||||||
|
// Storage
|
||||||
|
MStorage storage = MStorage.get(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), 0, get_TrxName());
|
||||||
|
if (storage == null)
|
||||||
|
storage = MStorage.getCreate(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), 0, get_TrxName());
|
||||||
|
BigDecimal qtyNew = storage.getQtyOnHand().add(qtyDiff);
|
||||||
|
log.fine("Diff=" + qtyDiff
|
||||||
|
+ " - OnHand=" + storage.getQtyOnHand() + "->" + qtyNew);
|
||||||
|
storage.setQtyOnHand(qtyNew);
|
||||||
|
storage.setDateLastInventory(getMovementDate());
|
||||||
|
if (!storage.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage not updated(1)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
log.fine(storage.toString());
|
||||||
|
// Transaction
|
||||||
|
trx = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_InventoryIn,
|
||||||
|
line.getM_Locator_ID(), line.getM_Product_ID(), 0,
|
||||||
|
qtyDiff, getMovementDate(), get_TrxName());
|
||||||
|
trx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||||
|
if (!trx.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction not inserted(1)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // negative qty
|
||||||
|
{
|
||||||
|
MInventoryLineMA mas[] = MInventoryLineMA.get(getCtx(),
|
||||||
|
line.getM_InventoryLine_ID(), get_TrxName());
|
||||||
|
for (int j = 0; j < mas.length; j++)
|
||||||
|
{
|
||||||
|
MInventoryLineMA ma = mas[j];
|
||||||
|
// Storage
|
||||||
|
MStorage storage = MStorage.get(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
if (storage == null)
|
||||||
|
storage = MStorage.getCreate(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
BigDecimal maxDiff = qtyDiff;
|
||||||
|
if (maxDiff.signum() < 0
|
||||||
|
&& ma.getMovementQty().compareTo(maxDiff.negate()) < 0)
|
||||||
|
maxDiff = ma.getMovementQty().negate();
|
||||||
|
BigDecimal qtyNew = ma.getMovementQty().add(maxDiff); // Storage+Diff
|
||||||
|
log.fine("MA Qty=" + ma.getMovementQty()
|
||||||
|
+ ",Diff=" + qtyDiff + "|" + maxDiff
|
||||||
|
+ " - OnHand=" + storage.getQtyOnHand() + "->" + qtyNew
|
||||||
|
+ " {" + ma.getM_AttributeSetInstance_ID() + "}");
|
||||||
|
//
|
||||||
|
storage.setQtyOnHand(qtyNew);
|
||||||
|
storage.setDateLastInventory(getMovementDate());
|
||||||
|
if (!storage.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage not updated (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
log.fine(storage.toString());
|
||||||
|
|
||||||
|
// Transaction
|
||||||
|
trx = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_InventoryIn,
|
||||||
|
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
|
||||||
|
maxDiff, getMovementDate(), get_TrxName());
|
||||||
|
trx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||||
|
if (!trx.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction not inserted (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
qtyDiff = qtyDiff.subtract(maxDiff);
|
||||||
|
if (qtyDiff.signum() == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // negative qty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback
|
||||||
|
if (trx == null)
|
||||||
|
{
|
||||||
|
// Storage
|
||||||
|
MStorage storage = MStorage.get(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
if (storage == null)
|
||||||
|
storage = MStorage.getCreate(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
BigDecimal qtyDiff = line.getQtyInternalUse().negate();
|
||||||
|
if (Env.ZERO.compareTo(qtyDiff) == 0)
|
||||||
|
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
|
||||||
|
BigDecimal qtyNew = storage.getQtyOnHand().add(qtyDiff);
|
||||||
|
log.fine("Count=" + line.getQtyCount()
|
||||||
|
+ ",Book=" + line.getQtyBook() + ", Difference=" + qtyDiff
|
||||||
|
+ " - OnHand=" + storage.getQtyOnHand() + "->" + qtyNew);
|
||||||
|
//
|
||||||
|
storage.setQtyOnHand(qtyNew);
|
||||||
|
storage.setDateLastInventory(getMovementDate());
|
||||||
|
if (!storage.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage not updated(2)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
log.fine(storage.toString());
|
||||||
|
|
||||||
|
// Transaction
|
||||||
|
trx = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_InventoryIn,
|
||||||
|
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
|
qtyDiff, getMovementDate(), get_TrxName());
|
||||||
|
trx.setM_InventoryLine_ID(line.getM_InventoryLine_ID());
|
||||||
|
if (!trx.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction not inserted(2)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
} // Fallback
|
||||||
|
|
||||||
|
} // for all lines
|
||||||
|
|
||||||
|
// User Validation
|
||||||
|
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||||
|
if (valid != null)
|
||||||
|
{
|
||||||
|
m_processMsg = valid;
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the definite document number after completed (if needed)
|
||||||
|
setDefiniteDocumentNo();
|
||||||
|
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_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()) {
|
||||||
|
setMovementDate(new Timestamp (System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
if (dt.isOverwriteSeqOnComplete()) {
|
||||||
|
String value = DB.getDocumentNo(getC_DocType_ID(), get_TrxName(), true, this);
|
||||||
|
if (value != null)
|
||||||
|
setDocumentNo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Material Policy.
|
||||||
|
* (NOT USED)
|
||||||
|
* Sets line ASI
|
||||||
|
*/
|
||||||
|
private void checkMaterialPolicy()
|
||||||
|
{
|
||||||
|
int no = MInventoryLineMA.deleteInventoryMA(getM_Inventory_ID(), get_TrxName());
|
||||||
|
if (no > 0)
|
||||||
|
log.config("Delete old #" + no);
|
||||||
|
MInventoryLine[] lines = getLines(false);
|
||||||
|
|
||||||
|
// Check Lines
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MInventoryLine line = lines[i];
|
||||||
|
boolean needSave = false;
|
||||||
|
|
||||||
|
// Attribute Set Instance
|
||||||
|
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||||
|
{
|
||||||
|
MProduct product = MProduct.get(getCtx(), line.getM_Product_ID());
|
||||||
|
BigDecimal qtyDiff = line.getQtyInternalUse().negate();
|
||||||
|
if (Env.ZERO.compareTo(qtyDiff) == 0)
|
||||||
|
qtyDiff = line.getQtyCount().subtract(line.getQtyBook());
|
||||||
|
log.fine("Count=" + line.getQtyCount()
|
||||||
|
+ ",Book=" + line.getQtyBook() + ", Difference=" + qtyDiff);
|
||||||
|
if (qtyDiff.signum() > 0) // Incoming Trx
|
||||||
|
{
|
||||||
|
MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), 0, get_TrxName());
|
||||||
|
asi.setClientOrg(getAD_Client_ID(), 0);
|
||||||
|
asi.setM_AttributeSet_ID(product.getM_AttributeSet_ID());
|
||||||
|
if (asi.save())
|
||||||
|
{
|
||||||
|
line.setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID());
|
||||||
|
needSave = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Outgoing Trx
|
||||||
|
{
|
||||||
|
String MMPolicy = product.getMMPolicy();
|
||||||
|
MStorage[] storages = MStorage.getAllWithASI(getCtx(),
|
||||||
|
line.getM_Product_ID(), line.getM_Locator_ID(),
|
||||||
|
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||||
|
BigDecimal qtyToDeliver = qtyDiff.negate();
|
||||||
|
for (int ii = 0; ii < storages.length; ii++)
|
||||||
|
{
|
||||||
|
MStorage storage = storages[ii];
|
||||||
|
if (ii == 0)
|
||||||
|
{
|
||||||
|
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||||
|
{
|
||||||
|
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||||
|
needSave = true;
|
||||||
|
log.config("Direct - " + line);
|
||||||
|
qtyToDeliver = Env.ZERO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.config("Split - " + line);
|
||||||
|
MInventoryLineMA ma = new MInventoryLineMA (line,
|
||||||
|
storage.getM_AttributeSetInstance_ID(),
|
||||||
|
storage.getQtyOnHand().negate());
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||||
|
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // create addl material allocation
|
||||||
|
{
|
||||||
|
MInventoryLineMA ma = new MInventoryLineMA (line,
|
||||||
|
storage.getM_AttributeSetInstance_ID(),
|
||||||
|
qtyToDeliver.negate());
|
||||||
|
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||||
|
qtyToDeliver = Env.ZERO;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ma.setMovementQty(storage.getQtyOnHand().negate());
|
||||||
|
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||||
|
}
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||||
|
}
|
||||||
|
if (qtyToDeliver.signum() == 0)
|
||||||
|
break;
|
||||||
|
} // for all storages
|
||||||
|
|
||||||
|
// No AttributeSetInstance found for remainder
|
||||||
|
if (qtyToDeliver.signum() != 0)
|
||||||
|
{
|
||||||
|
MInventoryLineMA ma = new MInventoryLineMA (line,
|
||||||
|
0, qtyToDeliver.negate());
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
log.fine("##: " + ma);
|
||||||
|
}
|
||||||
|
} // outgoing Trx
|
||||||
|
} // attributeSetInstance
|
||||||
|
|
||||||
|
if (needSave && !line.save())
|
||||||
|
log.severe("NOT saved " + line);
|
||||||
|
} // for all lines
|
||||||
|
|
||||||
|
} // checkMaterialPolicy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (DOCSTATUS_Closed.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Reversed.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Voided.equals(getDocStatus()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Document Closed: " + getDocStatus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not Processed
|
||||||
|
if (DOCSTATUS_Drafted.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Invalid.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_InProgress.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Approved.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_NotApproved.equals(getDocStatus()) )
|
||||||
|
{
|
||||||
|
// Set lines to 0
|
||||||
|
MInventoryLine[] lines = getLines(false);
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MInventoryLine line = lines[i];
|
||||||
|
BigDecimal oldCount = line.getQtyCount();
|
||||||
|
BigDecimal oldInternal = line.getQtyInternalUse();
|
||||||
|
if (oldCount.compareTo(line.getQtyBook()) != 0
|
||||||
|
|| oldInternal.signum() != 0)
|
||||||
|
{
|
||||||
|
line.setQtyInternalUse(Env.ZERO);
|
||||||
|
line.setQtyCount(line.getQtyBook());
|
||||||
|
line.addDescription("Void (" + oldCount + "/" + oldInternal + ")");
|
||||||
|
line.save(get_TrxName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reverseCorrectIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return true;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return true;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType()))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deep Copy
|
||||||
|
MInventory reversal = new MInventory(getCtx(), 0, get_TrxName());
|
||||||
|
copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID());
|
||||||
|
reversal.setDocStatus(DOCSTATUS_Drafted);
|
||||||
|
reversal.setDocAction(DOCACTION_Complete);
|
||||||
|
reversal.setIsApproved (false);
|
||||||
|
reversal.setPosted(false);
|
||||||
|
reversal.setProcessed(false);
|
||||||
|
reversal.addDescription("{->" + getDocumentNo() + ")");
|
||||||
|
if (!reversal.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not create Inventory Reversal";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse Line Qty
|
||||||
|
MInventoryLine[] oLines = getLines(true);
|
||||||
|
for (int i = 0; i < oLines.length; i++)
|
||||||
|
{
|
||||||
|
MInventoryLine oLine = oLines[i];
|
||||||
|
MInventoryLine rLine = new MInventoryLine(getCtx(), 0, get_TrxName());
|
||||||
|
copyValues(oLine, rLine, oLine.getAD_Client_ID(), oLine.getAD_Org_ID());
|
||||||
|
rLine.setM_Inventory_ID(reversal.getM_Inventory_ID());
|
||||||
|
rLine.setParent(reversal);
|
||||||
|
//
|
||||||
|
rLine.setQtyBook (oLine.getQtyCount()); // switch
|
||||||
|
rLine.setQtyCount (oLine.getQtyBook());
|
||||||
|
rLine.setQtyInternalUse (oLine.getQtyInternalUse().negate());
|
||||||
|
if (!rLine.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not create Inventory Reversal Line";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (!reversal.processIt(DocAction.ACTION_Complete))
|
||||||
|
{
|
||||||
|
m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reversal.closeIt();
|
||||||
|
reversal.setDocStatus(DOCSTATUS_Reversed);
|
||||||
|
reversal.setDocAction(DOCACTION_None);
|
||||||
|
reversal.save();
|
||||||
|
m_processMsg = reversal.getDocumentNo();
|
||||||
|
|
||||||
|
// Update Reversed (this)
|
||||||
|
addDescription("(" + reversal.getDocumentNo() + "<-)");
|
||||||
|
// After reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
setProcessed(true);
|
||||||
|
setDocStatus(DOCSTATUS_Reversed); // may come from void
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // reverseCorrectionIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
log.info(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 false
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // reActivateIt
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Get Summary
|
||||||
|
* @return Summary of Document
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getDocumentNo());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"ApprovalAmt")).append("=").append(getApprovalAmt())
|
||||||
|
.append(" (#").append(getLines(false).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
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getUpdatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Currency
|
||||||
|
* @return C_Currency_ID
|
||||||
|
*/
|
||||||
|
public int getC_Currency_ID()
|
||||||
|
{
|
||||||
|
// MPriceList pl = MPriceList.get(getCtx(), getM_PriceList_ID());
|
||||||
|
// return pl.getC_Currency_ID();
|
||||||
|
return 0;
|
||||||
|
} // getC_Currency_ID
|
||||||
|
|
||||||
|
} // MInventory
|
|
@ -0,0 +1,450 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Physical Inventory Line Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MInventoryLine.java,v 1.3 2006/07/30 00:51:02 jjanke Exp $
|
||||||
|
*
|
||||||
|
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
|
||||||
|
* <li>BF [ 1817757 ] Error on saving MInventoryLine in a custom environment
|
||||||
|
*/
|
||||||
|
public class MInventoryLine extends X_M_InventoryLine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Inventory Line with parameters
|
||||||
|
* @param inventory inventory
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID asi
|
||||||
|
* @return line or null
|
||||||
|
*/
|
||||||
|
public static MInventoryLine get (MInventory inventory,
|
||||||
|
int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID)
|
||||||
|
{
|
||||||
|
MInventoryLine retValue = null;
|
||||||
|
String sql = "SELECT * FROM M_InventoryLine "
|
||||||
|
+ "WHERE M_Inventory_ID=? AND M_Locator_ID=?"
|
||||||
|
+ " AND M_Product_ID=? AND M_AttributeSetInstance_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, inventory.get_TrxName());
|
||||||
|
pstmt.setInt (1, inventory.getM_Inventory_ID());
|
||||||
|
pstmt.setInt(2, M_Locator_ID);
|
||||||
|
pstmt.setInt(3, M_Product_ID);
|
||||||
|
pstmt.setInt(4, M_AttributeSetInstance_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
retValue = new MInventoryLine (inventory.getCtx(), rs, inventory.get_TrxName());
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log (Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MInventoryLine.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Default Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_InventoryLine_ID line
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MInventoryLine (Properties ctx, int M_InventoryLine_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_InventoryLine_ID, trxName);
|
||||||
|
if (M_InventoryLine_ID == 0)
|
||||||
|
{
|
||||||
|
// setM_Inventory_ID (0); // Parent
|
||||||
|
// setM_InventoryLine_ID (0); // PK
|
||||||
|
// setM_Locator_ID (0); // FK
|
||||||
|
setLine(0);
|
||||||
|
// setM_Product_ID (0); // FK
|
||||||
|
setM_AttributeSetInstance_ID(0); // FK
|
||||||
|
setInventoryType (INVENTORYTYPE_InventoryDifference);
|
||||||
|
setQtyBook (Env.ZERO);
|
||||||
|
setQtyCount (Env.ZERO);
|
||||||
|
setProcessed(false);
|
||||||
|
}
|
||||||
|
} // MInventoryLine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MInventoryLine (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MInventoryLine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detail Constructor.
|
||||||
|
* Locator/Product/AttributeSetInstance must be unique
|
||||||
|
* @param inventory parent
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID instance
|
||||||
|
* @param QtyBook book value
|
||||||
|
* @param QtyCount count value
|
||||||
|
*/
|
||||||
|
public MInventoryLine (MInventory inventory,
|
||||||
|
int M_Locator_ID, int M_Product_ID, int M_AttributeSetInstance_ID,
|
||||||
|
BigDecimal QtyBook, BigDecimal QtyCount)
|
||||||
|
{
|
||||||
|
this (inventory.getCtx(), 0, inventory.get_TrxName());
|
||||||
|
if (inventory.get_ID() == 0)
|
||||||
|
throw new IllegalArgumentException("Header not saved");
|
||||||
|
m_parent = inventory;
|
||||||
|
setM_Inventory_ID (inventory.getM_Inventory_ID()); // Parent
|
||||||
|
setClientOrg (inventory.getAD_Client_ID(), inventory.getAD_Org_ID());
|
||||||
|
setM_Locator_ID (M_Locator_ID); // FK
|
||||||
|
setM_Product_ID (M_Product_ID); // FK
|
||||||
|
setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID);
|
||||||
|
//
|
||||||
|
if (QtyBook != null)
|
||||||
|
setQtyBook (QtyBook);
|
||||||
|
if (QtyCount != null && QtyCount.signum() != 0)
|
||||||
|
setQtyCount (QtyCount);
|
||||||
|
m_isManualEntry = false;
|
||||||
|
} // MInventoryLine
|
||||||
|
|
||||||
|
/** Manually created */
|
||||||
|
private boolean m_isManualEntry = true;
|
||||||
|
/** Parent */
|
||||||
|
private MInventory m_parent = null;
|
||||||
|
/** Product */
|
||||||
|
private MProduct m_product = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Qty Book
|
||||||
|
* @return Qty Book
|
||||||
|
*/
|
||||||
|
public BigDecimal getQtyBook ()
|
||||||
|
{
|
||||||
|
BigDecimal bd = super.getQtyBook ();
|
||||||
|
if (bd == null)
|
||||||
|
bd = Env.ZERO;
|
||||||
|
return bd;
|
||||||
|
} // getQtyBook
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Qty Count
|
||||||
|
* @return Qty Count
|
||||||
|
*/
|
||||||
|
public BigDecimal getQtyCount ()
|
||||||
|
{
|
||||||
|
BigDecimal bd = super.getQtyCount();
|
||||||
|
if (bd == null)
|
||||||
|
bd = Env.ZERO;
|
||||||
|
return bd;
|
||||||
|
} // getQtyBook
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Product
|
||||||
|
* @return product or null if not defined
|
||||||
|
*/
|
||||||
|
public MProduct getProduct()
|
||||||
|
{
|
||||||
|
int M_Product_ID = getM_Product_ID();
|
||||||
|
if (M_Product_ID == 0)
|
||||||
|
return null;
|
||||||
|
if (m_product != null && m_product.getM_Product_ID() != M_Product_ID)
|
||||||
|
m_product = null; // reset
|
||||||
|
if (m_product == null)
|
||||||
|
m_product = MProduct.get(getCtx(), M_Product_ID);
|
||||||
|
return m_product;
|
||||||
|
} // getProduct
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Count Qty - enforce UOM
|
||||||
|
* @param QtyCount qty
|
||||||
|
*/
|
||||||
|
public void setQtyCount (BigDecimal QtyCount)
|
||||||
|
{
|
||||||
|
if (QtyCount != null)
|
||||||
|
{
|
||||||
|
MProduct product = getProduct();
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
int precision = product.getUOMPrecision();
|
||||||
|
QtyCount = QtyCount.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setQtyCount(QtyCount);
|
||||||
|
} // setQtyCount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Internal Use Qty - enforce UOM
|
||||||
|
* @param QtyInternalUse qty
|
||||||
|
*/
|
||||||
|
public void setQtyInternalUse (BigDecimal QtyInternalUse)
|
||||||
|
{
|
||||||
|
if (QtyInternalUse != null)
|
||||||
|
{
|
||||||
|
MProduct product = getProduct();
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
int precision = product.getUOMPrecision();
|
||||||
|
QtyInternalUse = QtyInternalUse.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setQtyInternalUse(QtyInternalUse);
|
||||||
|
} // setQtyInternalUse
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to Description
|
||||||
|
* @param description text
|
||||||
|
*/
|
||||||
|
public void addDescription (String description)
|
||||||
|
{
|
||||||
|
String desc = getDescription();
|
||||||
|
if (desc == null)
|
||||||
|
setDescription(description);
|
||||||
|
else
|
||||||
|
setDescription(desc + " | " + description);
|
||||||
|
} // addDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Parent
|
||||||
|
* @param parent parent
|
||||||
|
*/
|
||||||
|
protected void setParent(MInventory parent)
|
||||||
|
{
|
||||||
|
m_parent = parent;
|
||||||
|
} // setParent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Parent
|
||||||
|
* @return parent
|
||||||
|
*/
|
||||||
|
public MInventory getParent()
|
||||||
|
{
|
||||||
|
if (m_parent == null)
|
||||||
|
m_parent = new MInventory (getCtx(), getM_Inventory_ID(), get_TrxName());
|
||||||
|
return m_parent;
|
||||||
|
} // getParent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MInventoryLine[");
|
||||||
|
sb.append (get_ID())
|
||||||
|
.append("-M_Product_ID=").append (getM_Product_ID())
|
||||||
|
.append(",QtyCount=").append(getQtyCount())
|
||||||
|
.append(",QtyInternalUse=").append(getQtyInternalUse())
|
||||||
|
.append(",QtyBook=").append(getQtyBook())
|
||||||
|
.append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID())
|
||||||
|
.append("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true if can be saved
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
if (newRecord && m_isManualEntry)
|
||||||
|
{
|
||||||
|
// Product requires ASI
|
||||||
|
if (getM_AttributeSetInstance_ID() == 0)
|
||||||
|
{
|
||||||
|
MProduct product = MProduct.get(getCtx(), getM_Product_ID());
|
||||||
|
if (product != null && product.isASIMandatory(isSOTrx()))
|
||||||
|
{
|
||||||
|
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstance_ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // No ASI
|
||||||
|
} // new or manual
|
||||||
|
|
||||||
|
// Set Line No
|
||||||
|
if (getLine() == 0)
|
||||||
|
{
|
||||||
|
String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_InventoryLine WHERE M_Inventory_ID=?";
|
||||||
|
int ii = DB.getSQLValue (get_TrxName(), sql, getM_Inventory_ID());
|
||||||
|
setLine (ii);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce Qty UOM
|
||||||
|
if (newRecord || is_ValueChanged("QtyCount"))
|
||||||
|
setQtyCount(getQtyCount());
|
||||||
|
if (newRecord || is_ValueChanged("QtyInternalUse"))
|
||||||
|
setQtyInternalUse(getQtyInternalUse());
|
||||||
|
|
||||||
|
// InternalUse Inventory
|
||||||
|
if (getQtyInternalUse().signum() != 0)
|
||||||
|
{
|
||||||
|
if (!INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
|
||||||
|
setInventoryType(INVENTORYTYPE_ChargeAccount);
|
||||||
|
//
|
||||||
|
if (getC_Charge_ID() == 0)
|
||||||
|
{
|
||||||
|
log.saveError("InternalUseNeedsCharge", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (INVENTORYTYPE_ChargeAccount.equals(getInventoryType()))
|
||||||
|
{
|
||||||
|
if (getC_Charge_ID() == 0)
|
||||||
|
{
|
||||||
|
log.saveError("FillMandatory", Msg.getElement(getCtx(), "C_Charge_ID"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (getC_Charge_ID() != 0)
|
||||||
|
setC_Charge_ID(0);
|
||||||
|
|
||||||
|
// Set AD_Org to parent if not charge
|
||||||
|
if (getC_Charge_ID() == 0)
|
||||||
|
setAD_Org_ID(getParent().getAD_Org_ID());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @param success success
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean afterSave (boolean newRecord, boolean success)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Create MA
|
||||||
|
if (newRecord && success
|
||||||
|
&& m_isManualEntry && getM_AttributeSetInstance_ID() == 0)
|
||||||
|
createMA();
|
||||||
|
return true;
|
||||||
|
} // afterSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Material Allocations for new Instances
|
||||||
|
*/
|
||||||
|
private void createMA()
|
||||||
|
{
|
||||||
|
MStorage[] storages = MStorage.getAll(getCtx(), getM_Product_ID(),
|
||||||
|
getM_Locator_ID(), get_TrxName());
|
||||||
|
boolean allZeroASI = true;
|
||||||
|
for (int i = 0; i < storages.length; i++)
|
||||||
|
{
|
||||||
|
if (storages[i].getM_AttributeSetInstance_ID() != 0)
|
||||||
|
{
|
||||||
|
allZeroASI = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allZeroASI)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MInventoryLineMA ma = null;
|
||||||
|
BigDecimal sum = Env.ZERO;
|
||||||
|
for (int i = 0; i < storages.length; i++)
|
||||||
|
{
|
||||||
|
MStorage storage = storages[i];
|
||||||
|
if (storage.getQtyOnHand().signum() == 0)
|
||||||
|
continue;
|
||||||
|
if (ma != null
|
||||||
|
&& ma.getM_AttributeSetInstance_ID() == storage.getM_AttributeSetInstance_ID())
|
||||||
|
ma.setMovementQty(ma.getMovementQty().add(storage.getQtyOnHand()));
|
||||||
|
else
|
||||||
|
ma = new MInventoryLineMA (this,
|
||||||
|
storage.getM_AttributeSetInstance_ID(), storage.getQtyOnHand());
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
sum = sum.add(storage.getQtyOnHand());
|
||||||
|
}
|
||||||
|
if (sum.compareTo(getQtyBook()) != 0)
|
||||||
|
{
|
||||||
|
log.warning("QtyBook=" + getQtyBook() + " corrected to Sum of MA=" + sum);
|
||||||
|
setQtyBook(sum);
|
||||||
|
}
|
||||||
|
} // createMA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is Internal Use Inventory
|
||||||
|
* @return true if is internal use inventory
|
||||||
|
*/
|
||||||
|
public boolean isInternalUseInventory() {
|
||||||
|
/* TODO: need to add M_Inventory.IsInternalUseInventory flag
|
||||||
|
see FR [ 1879029 ] Added IsInternalUseInventory flag to M_Inventory table
|
||||||
|
MInventory parent = getParent();
|
||||||
|
return parent != null && parent.isInternalUseInventory();
|
||||||
|
*/
|
||||||
|
return getQtyInternalUse().signum() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Movement Qty (absolute value)
|
||||||
|
* <li>negative value means outgoing trx
|
||||||
|
* <li>positive value means incoming trx
|
||||||
|
* @return movement qty
|
||||||
|
*/
|
||||||
|
public BigDecimal getMovementQty() {
|
||||||
|
if(isInternalUseInventory()) {
|
||||||
|
return getQtyInternalUse().negate();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return getQtyCount().subtract(getQtyBook());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if is an outgoing transaction
|
||||||
|
*/
|
||||||
|
public boolean isSOTrx() {
|
||||||
|
return getMovementQty().signum() < 0;
|
||||||
|
}
|
||||||
|
} // MInventoryLine
|
|
@ -0,0 +1,149 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inventory Material Allocation
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MInventoryLineMA.java,v 1.3 2006/07/30 00:51:04 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MInventoryLineMA extends X_M_InventoryLineMA
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Material Allocations for Line
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_InventoryLine_ID line
|
||||||
|
* @param trxName trx
|
||||||
|
* @return allocations
|
||||||
|
*/
|
||||||
|
public static MInventoryLineMA[] get (Properties ctx, int M_InventoryLine_ID, String trxName)
|
||||||
|
{
|
||||||
|
ArrayList<MInventoryLineMA> list = new ArrayList<MInventoryLineMA>();
|
||||||
|
String sql = "SELECT * FROM M_InventoryLineMA WHERE M_InventoryLine_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_InventoryLine_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new MInventoryLineMA (ctx, rs, trxName));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log (Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MInventoryLineMA[] retValue = new MInventoryLineMA[list.size ()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all Material Allocation for Inventory
|
||||||
|
* @param M_Inventory_ID inventory
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return number of rows deleted or -1 for error
|
||||||
|
*/
|
||||||
|
public static int deleteInventoryMA (int M_Inventory_ID, String trxName)
|
||||||
|
{
|
||||||
|
String sql = "DELETE FROM M_InventoryLineMA ma WHERE EXISTS "
|
||||||
|
+ "(SELECT * FROM M_InventoryLine l WHERE l.M_InventoryLine_ID=ma.M_InventoryLine_ID"
|
||||||
|
+ " AND M_Inventory_ID=" + M_Inventory_ID + ")";
|
||||||
|
return DB.executeUpdate(sql, trxName);
|
||||||
|
} // deleteInventoryMA
|
||||||
|
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MInventoryLineMA.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_InventoryLineMA_ID ignored
|
||||||
|
* @param trxName trx
|
||||||
|
*/
|
||||||
|
public MInventoryLineMA (Properties ctx, int M_InventoryLineMA_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_InventoryLineMA_ID, trxName);
|
||||||
|
if (M_InventoryLineMA_ID != 0)
|
||||||
|
throw new IllegalArgumentException("Multi-Key");
|
||||||
|
} // MInventoryLineMA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Cosntructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName trx
|
||||||
|
*/
|
||||||
|
public MInventoryLineMA (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, rs, trxName);
|
||||||
|
} // MInventoryLineMA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent Constructor
|
||||||
|
* @param parent parent
|
||||||
|
* @param M_AttributeSetInstance_ID asi
|
||||||
|
* @param MovementQty qty
|
||||||
|
*/
|
||||||
|
public MInventoryLineMA (MInventoryLine parent, int M_AttributeSetInstance_ID, BigDecimal MovementQty)
|
||||||
|
{
|
||||||
|
this (parent.getCtx(), 0, parent.get_TrxName());
|
||||||
|
setClientOrg(parent);
|
||||||
|
setM_InventoryLine_ID(parent.getM_InventoryLine_ID());
|
||||||
|
//
|
||||||
|
setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
|
||||||
|
setMovementQty(MovementQty);
|
||||||
|
} // MInventoryLineMA
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MInventoryLineMA[");
|
||||||
|
sb.append("M_InventoryLine_ID=").append(getM_InventoryLine_ID())
|
||||||
|
.append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID())
|
||||||
|
.append(", Qty=").append(getMovementQty())
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
} // MInventoryLineMA
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,874 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.*;
|
||||||
|
import java.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.process.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GL Journal Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MJournal.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*
|
||||||
|
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
|
||||||
|
* <li>BF [ 1619150 ] Usability/Consistency: reversed gl journal description
|
||||||
|
* <li>BF [ 1775358 ] GL Journal DateAcct/C_Period_ID issue
|
||||||
|
*/
|
||||||
|
public class MJournal extends X_GL_Journal implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param GL_Journal_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MJournal (Properties ctx, int GL_Journal_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, GL_Journal_ID, trxName);
|
||||||
|
if (GL_Journal_ID == 0)
|
||||||
|
{
|
||||||
|
// setGL_Journal_ID (0); // PK
|
||||||
|
// setC_AcctSchema_ID (0);
|
||||||
|
// setC_Currency_ID (0);
|
||||||
|
// setC_DocType_ID (0);
|
||||||
|
// setC_Period_ID (0);
|
||||||
|
//
|
||||||
|
setCurrencyRate (Env.ONE);
|
||||||
|
// setC_ConversionType_ID(0);
|
||||||
|
setDateAcct (new Timestamp(System.currentTimeMillis()));
|
||||||
|
setDateDoc (new Timestamp(System.currentTimeMillis()));
|
||||||
|
// setDescription (null);
|
||||||
|
setDocAction (DOCACTION_Complete);
|
||||||
|
setDocStatus (DOCSTATUS_Drafted);
|
||||||
|
// setDocumentNo (null);
|
||||||
|
// setGL_Category_ID (0);
|
||||||
|
setPostingType (POSTINGTYPE_Actual);
|
||||||
|
setTotalCr (Env.ZERO);
|
||||||
|
setTotalDr (Env.ZERO);
|
||||||
|
setIsApproved (false);
|
||||||
|
setIsPrinted (false);
|
||||||
|
setPosted (false);
|
||||||
|
setProcessed(false);
|
||||||
|
}
|
||||||
|
} // MJournal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MJournal (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MJournal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent Constructor.
|
||||||
|
* @param parent batch
|
||||||
|
*/
|
||||||
|
public MJournal (MJournalBatch parent)
|
||||||
|
{
|
||||||
|
this (parent.getCtx(), 0, parent.get_TrxName());
|
||||||
|
setClientOrg(parent);
|
||||||
|
setGL_JournalBatch_ID(parent.getGL_JournalBatch_ID());
|
||||||
|
setC_DocType_ID(parent.getC_DocType_ID());
|
||||||
|
setPostingType(parent.getPostingType());
|
||||||
|
//
|
||||||
|
setDateDoc(parent.getDateDoc());
|
||||||
|
setC_Period_ID(parent.getC_Period_ID());
|
||||||
|
setDateAcct(parent.getDateAcct());
|
||||||
|
setC_Currency_ID(parent.getC_Currency_ID());
|
||||||
|
} // MJournal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor.
|
||||||
|
* Dos not copy: Dates/Period
|
||||||
|
* @param original original
|
||||||
|
*/
|
||||||
|
public MJournal (MJournal original)
|
||||||
|
{
|
||||||
|
this (original.getCtx(), 0, original.get_TrxName());
|
||||||
|
setClientOrg(original);
|
||||||
|
setGL_JournalBatch_ID(original.getGL_JournalBatch_ID());
|
||||||
|
//
|
||||||
|
setC_AcctSchema_ID(original.getC_AcctSchema_ID());
|
||||||
|
setGL_Budget_ID(original.getGL_Budget_ID());
|
||||||
|
setGL_Category_ID(original.getGL_Category_ID());
|
||||||
|
setPostingType(original.getPostingType());
|
||||||
|
setDescription(original.getDescription());
|
||||||
|
setC_DocType_ID(original.getC_DocType_ID());
|
||||||
|
setControlAmt(original.getControlAmt());
|
||||||
|
//
|
||||||
|
setC_Currency_ID(original.getC_Currency_ID());
|
||||||
|
setC_ConversionType_ID(original.getC_ConversionType_ID());
|
||||||
|
setCurrencyRate(original.getCurrencyRate());
|
||||||
|
|
||||||
|
// setDateDoc(original.getDateDoc());
|
||||||
|
// setDateAcct(original.getDateAcct());
|
||||||
|
// setC_Period_ID(original.getC_Period_ID());
|
||||||
|
} // MJournal
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite Client/Org if required
|
||||||
|
* @param AD_Client_ID client
|
||||||
|
* @param AD_Org_ID org
|
||||||
|
*/
|
||||||
|
public void setClientOrg (int AD_Client_ID, int AD_Org_ID)
|
||||||
|
{
|
||||||
|
super.setClientOrg(AD_Client_ID, AD_Org_ID);
|
||||||
|
} // setClientOrg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Accounting Date.
|
||||||
|
* Set also Period if not set earlier
|
||||||
|
* @param DateAcct date
|
||||||
|
*/
|
||||||
|
public void setDateAcct (Timestamp DateAcct)
|
||||||
|
{
|
||||||
|
super.setDateAcct(DateAcct);
|
||||||
|
if (DateAcct == null)
|
||||||
|
return;
|
||||||
|
if (getC_Period_ID() != 0)
|
||||||
|
return;
|
||||||
|
int C_Period_ID = MPeriod.getC_Period_ID(getCtx(), DateAcct);
|
||||||
|
if (C_Period_ID == 0)
|
||||||
|
log.warning("setDateAcct - Period not found");
|
||||||
|
else
|
||||||
|
setC_Period_ID(C_Period_ID);
|
||||||
|
} // setDateAcct
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Currency Info
|
||||||
|
* @param C_Currency_ID currenct
|
||||||
|
* @param C_ConversionType_ID type
|
||||||
|
* @param CurrencyRate rate
|
||||||
|
*/
|
||||||
|
public void setCurrency (int C_Currency_ID, int C_ConversionType_ID, BigDecimal CurrencyRate)
|
||||||
|
{
|
||||||
|
if (C_Currency_ID != 0)
|
||||||
|
setC_Currency_ID(C_Currency_ID);
|
||||||
|
if (C_ConversionType_ID != 0)
|
||||||
|
setC_ConversionType_ID(C_ConversionType_ID);
|
||||||
|
if (CurrencyRate != null && CurrencyRate.compareTo(Env.ZERO) == 0)
|
||||||
|
setCurrencyRate(CurrencyRate);
|
||||||
|
} // setCurrency
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to Description
|
||||||
|
* @param description text
|
||||||
|
* @since 3.1.4
|
||||||
|
*/
|
||||||
|
public void addDescription (String description)
|
||||||
|
{
|
||||||
|
String desc = getDescription();
|
||||||
|
if (desc == null)
|
||||||
|
setDescription(description);
|
||||||
|
else
|
||||||
|
setDescription(desc + " | " + description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Get Journal Lines
|
||||||
|
* @param requery requery
|
||||||
|
* @return Array of lines
|
||||||
|
*/
|
||||||
|
public MJournalLine[] getLines (boolean requery)
|
||||||
|
{
|
||||||
|
ArrayList<MJournalLine> list = new ArrayList<MJournalLine>();
|
||||||
|
String sql = "SELECT * FROM GL_JournalLine WHERE GL_Journal_ID=? ORDER BY Line";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||||
|
pstmt.setInt(1, getGL_Journal_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
list.add(new MJournalLine (getCtx(), rs, get_TrxName()));
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "getLines", ex);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ex1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
//
|
||||||
|
MJournalLine[] retValue = new MJournalLine[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getLines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Lines from other Journal
|
||||||
|
* @param fromJournal Journal
|
||||||
|
* @param dateAcct date used - if null original
|
||||||
|
* @param typeCR type of copying (C)orrect=negate - (R)everse=flip dr/cr - otherwise just copy
|
||||||
|
* @return number of lines copied
|
||||||
|
*/
|
||||||
|
public int copyLinesFrom (MJournal fromJournal, Timestamp dateAcct, char typeCR)
|
||||||
|
{
|
||||||
|
if (isProcessed() || fromJournal == null)
|
||||||
|
return 0;
|
||||||
|
int count = 0;
|
||||||
|
MJournalLine[] fromLines = fromJournal.getLines(false);
|
||||||
|
for (int i = 0; i < fromLines.length; i++)
|
||||||
|
{
|
||||||
|
MJournalLine toLine = new MJournalLine (getCtx(), 0, fromJournal.get_TrxName());
|
||||||
|
PO.copyValues(fromLines[i], toLine, getAD_Client_ID(), getAD_Org_ID());
|
||||||
|
toLine.setGL_Journal_ID(getGL_Journal_ID());
|
||||||
|
//
|
||||||
|
if (dateAcct != null)
|
||||||
|
toLine.setDateAcct(dateAcct);
|
||||||
|
// Amounts
|
||||||
|
if (typeCR == 'C') // correct
|
||||||
|
{
|
||||||
|
toLine.setAmtSourceDr(fromLines[i].getAmtSourceDr().negate());
|
||||||
|
toLine.setAmtSourceCr(fromLines[i].getAmtSourceCr().negate());
|
||||||
|
}
|
||||||
|
else if (typeCR == 'R') // reverse
|
||||||
|
{
|
||||||
|
toLine.setAmtSourceDr(fromLines[i].getAmtSourceCr());
|
||||||
|
toLine.setAmtSourceCr(fromLines[i].getAmtSourceDr());
|
||||||
|
}
|
||||||
|
toLine.setIsGenerated(true);
|
||||||
|
toLine.setProcessed(false);
|
||||||
|
if (toLine.save())
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (fromLines.length != count)
|
||||||
|
log.log(Level.SEVERE, "Line difference - JournalLines=" + fromLines.length + " <> Saved=" + count);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
} // copyLinesFrom
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Processed.
|
||||||
|
* Propergate to Lines/Taxes
|
||||||
|
* @param processed processed
|
||||||
|
*/
|
||||||
|
public void setProcessed (boolean processed)
|
||||||
|
{
|
||||||
|
super.setProcessed (processed);
|
||||||
|
if (get_ID() == 0)
|
||||||
|
return;
|
||||||
|
String sql = "UPDATE GL_JournalLine SET Processed='"
|
||||||
|
+ (processed ? "Y" : "N")
|
||||||
|
+ "' WHERE GL_Journal_ID=" + getGL_Journal_ID();
|
||||||
|
int noLine = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
log.fine(processed + " - Lines=" + noLine);
|
||||||
|
} // setProcessed
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
// Imported Journals may not have date
|
||||||
|
if (getDateDoc() == null)
|
||||||
|
{
|
||||||
|
if (getDateAcct() == null)
|
||||||
|
setDateDoc(new Timestamp(System.currentTimeMillis()));
|
||||||
|
else
|
||||||
|
setDateDoc(getDateAcct());
|
||||||
|
}
|
||||||
|
if (getDateAcct() == null)
|
||||||
|
setDateAcct(getDateDoc());
|
||||||
|
|
||||||
|
// Update DateAcct on lines - teo_sarca BF [ 1775358 ]
|
||||||
|
if (is_ValueChanged(COLUMNNAME_DateAcct)) {
|
||||||
|
int no = DB.executeUpdate(
|
||||||
|
"UPDATE GL_JournalLine SET "+MJournalLine.COLUMNNAME_DateAcct+"=? WHERE GL_Journal_ID=?",
|
||||||
|
new Object[]{getDateAcct(), getGL_Journal_ID()},
|
||||||
|
false, get_TrxName());
|
||||||
|
log.finest("Updated GL_JournalLine.DateAcct #" + no);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Save.
|
||||||
|
* Update Batch Total
|
||||||
|
* @param newRecord true if new record
|
||||||
|
* @param success true if success
|
||||||
|
* @return success
|
||||||
|
*/
|
||||||
|
protected boolean afterSave (boolean newRecord, boolean success)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
return success;
|
||||||
|
return updateBatch();
|
||||||
|
} // afterSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Delete
|
||||||
|
* @param success true if deleted
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
protected boolean afterDelete (boolean success)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
return success;
|
||||||
|
return updateBatch();
|
||||||
|
} // afterDelete
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Batch total
|
||||||
|
* @return true if ok
|
||||||
|
*/
|
||||||
|
private boolean updateBatch()
|
||||||
|
{
|
||||||
|
String sql = "UPDATE GL_JournalBatch jb"
|
||||||
|
+ " SET (TotalDr, TotalCr) = (SELECT COALESCE(SUM(TotalDr),0), COALESCE(SUM(TotalCr),0)"
|
||||||
|
+ " FROM GL_Journal j WHERE j.IsActive='Y' AND jb.GL_JournalBatch_ID=j.GL_JournalBatch_ID) "
|
||||||
|
+ "WHERE GL_JournalBatch_ID=" + getGL_JournalBatch_ID();
|
||||||
|
int no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 1)
|
||||||
|
log.warning("afterSave - Update Batch #" + no);
|
||||||
|
return no == 1;
|
||||||
|
} // updateBatch
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
|
||||||
|
// Get Period
|
||||||
|
MPeriod period = MPeriod.get (getCtx(), getDateAcct());
|
||||||
|
if (period == null)
|
||||||
|
{
|
||||||
|
log.warning("No Period for " + getDateAcct());
|
||||||
|
m_processMsg = "@PeriodNotFound@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// Standard Period
|
||||||
|
if (period.getC_Period_ID() != getC_Period_ID()
|
||||||
|
&& period.isStandardPeriod())
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodNotValid@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
boolean open = period.isOpen(dt.getDocBaseType(), getDateAcct());
|
||||||
|
if (!open)
|
||||||
|
{
|
||||||
|
log.warning(period.getName()
|
||||||
|
+ ": Not open for " + dt.getDocBaseType() + " (" + getDateAcct() + ")");
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lines
|
||||||
|
MJournalLine[] lines = getLines(true);
|
||||||
|
if (lines.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add up Amounts
|
||||||
|
BigDecimal AmtSourceDr = Env.ZERO;
|
||||||
|
BigDecimal AmtSourceCr = Env.ZERO;
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MJournalLine line = lines[i];
|
||||||
|
if (!isActive())
|
||||||
|
continue;
|
||||||
|
//
|
||||||
|
if (line.isDocControlled())
|
||||||
|
{
|
||||||
|
m_processMsg = "@DocControlledError@ - @Line@=" + line.getLine()
|
||||||
|
+ " - " + line.getAccountElementValue();
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
AmtSourceDr = AmtSourceDr.add(line.getAmtSourceDr());
|
||||||
|
AmtSourceCr = AmtSourceCr.add(line.getAmtSourceCr());
|
||||||
|
}
|
||||||
|
setTotalDr(AmtSourceDr);
|
||||||
|
setTotalCr(AmtSourceCr);
|
||||||
|
|
||||||
|
// Control Amount
|
||||||
|
if (Env.ZERO.compareTo(getControlAmt()) != 0
|
||||||
|
&& getControlAmt().compareTo(getTotalDr()) != 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@ControlAmtError@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbalanced Jornal & Not Suspense
|
||||||
|
if (AmtSourceDr.compareTo(AmtSourceCr) != 0)
|
||||||
|
{
|
||||||
|
MAcctSchemaGL gl = MAcctSchemaGL.get(getCtx(), getC_AcctSchema_ID());
|
||||||
|
if (gl == null || !gl.isUseSuspenseBalancing())
|
||||||
|
{
|
||||||
|
m_processMsg = "@UnbalancedJornal@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DOCACTION_Complete.equals(getDocAction()))
|
||||||
|
setDocAction(DOCACTION_Complete);
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
if (!isApproved())
|
||||||
|
approveIt();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the definite document number after completed (if needed)
|
||||||
|
setDefiniteDocumentNo();
|
||||||
|
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_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(new Timestamp (System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
if (dt.isOverwriteSeqOnComplete()) {
|
||||||
|
String value = DB.getDocumentNo(getC_DocType_ID(), get_TrxName(), true, this);
|
||||||
|
if (value != null)
|
||||||
|
setDocumentNo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean ok_to_void = false;
|
||||||
|
if (DOCSTATUS_Drafted.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Invalid.equals(getDocStatus()))
|
||||||
|
{
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
ok_to_void = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok_to_void;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* Cancel not delivered Qunatities
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean ok_to_close = false;
|
||||||
|
if (DOCSTATUS_Completed.equals(getDocStatus()))
|
||||||
|
{
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
ok_to_close = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok_to_close;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction (in same batch).
|
||||||
|
* As if nothing happened - same date
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
// Before reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean ok_correct = (reverseCorrectIt(getGL_JournalBatch_ID()) != null);
|
||||||
|
|
||||||
|
if (! ok_correct)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok_correct;
|
||||||
|
} // reverseCorrectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction.
|
||||||
|
* As if nothing happened - same date
|
||||||
|
* @param GL_JournalBatch_ID reversal batch
|
||||||
|
* @return reversed Journal or null
|
||||||
|
*/
|
||||||
|
public MJournal reverseCorrectIt (int GL_JournalBatch_ID)
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Journal
|
||||||
|
MJournal reverse = new MJournal (this);
|
||||||
|
reverse.setGL_JournalBatch_ID(GL_JournalBatch_ID);
|
||||||
|
reverse.setDateDoc(getDateDoc());
|
||||||
|
reverse.setC_Period_ID(getC_Period_ID());
|
||||||
|
reverse.setDateAcct(getDateAcct());
|
||||||
|
// Reverse indicator
|
||||||
|
reverse.addDescription("(->" + getDocumentNo() + ")");
|
||||||
|
if (!reverse.save())
|
||||||
|
return null;
|
||||||
|
addDescription("(" + reverse.getDocumentNo() + "<-)");
|
||||||
|
|
||||||
|
// Lines
|
||||||
|
reverse.copyLinesFrom(this, null, 'C');
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return reverse;
|
||||||
|
} // reverseCorrectionIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual (sane batch).
|
||||||
|
* Flip Dr/Cr - Use Today's date
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
// Before reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean ok_reverse = (reverseAccrualIt (getGL_JournalBatch_ID()) != null);
|
||||||
|
|
||||||
|
if (! ok_reverse)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ok_reverse;
|
||||||
|
} // reverseAccrualIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual.
|
||||||
|
* Flip Dr/Cr - Use Today's date
|
||||||
|
* @param GL_JournalBatch_ID reversal batch
|
||||||
|
* @return reversed journal or null
|
||||||
|
*/
|
||||||
|
public MJournal reverseAccrualIt (int GL_JournalBatch_ID)
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Journal
|
||||||
|
MJournal reverse = new MJournal (this);
|
||||||
|
reverse.setGL_JournalBatch_ID(GL_JournalBatch_ID);
|
||||||
|
reverse.setDateDoc(new Timestamp(System.currentTimeMillis()));
|
||||||
|
reverse.set_ValueNoCheck ("C_Period_ID", null); // reset
|
||||||
|
reverse.setDateAcct(reverse.getDateDoc());
|
||||||
|
// Reverse indicator
|
||||||
|
String description = reverse.getDescription();
|
||||||
|
if (description == null)
|
||||||
|
description = "** " + getDocumentNo() + " **";
|
||||||
|
else
|
||||||
|
description += " ** " + getDocumentNo() + " **";
|
||||||
|
reverse.setDescription(description);
|
||||||
|
if (!reverse.save())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Lines
|
||||||
|
reverse.copyLinesFrom(this, reverse.getDateAcct(), 'R');
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return reverse;
|
||||||
|
} // reverseAccrualIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-activate
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // reActivateIt
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Get Summary
|
||||||
|
* @return Summary of Document
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getDocumentNo());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"TotalDr")).append("=").append(getTotalDr())
|
||||||
|
.append(" ")
|
||||||
|
.append(Msg.translate(getCtx(),"TotalCR")).append("=").append(getTotalCr())
|
||||||
|
.append(" (#").append(getLines(false).length).append(")");
|
||||||
|
// - Description
|
||||||
|
if (getDescription() != null && getDescription().length() > 0)
|
||||||
|
sb.append(" - ").append(getDescription());
|
||||||
|
return sb.toString();
|
||||||
|
} // getSummary
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MJournal[");
|
||||||
|
sb.append(get_ID()).append(",").append(getDescription())
|
||||||
|
.append(",DR=").append(getTotalDr())
|
||||||
|
.append(",CR=").append(getTotalCr())
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
return dt.getName() + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Process Message
|
||||||
|
* @return clear text error message
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID (Created)
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getCreatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Approval Amount
|
||||||
|
* @return DR amount
|
||||||
|
*/
|
||||||
|
public BigDecimal getApprovalAmt()
|
||||||
|
{
|
||||||
|
return getTotalDr();
|
||||||
|
} // getApprovalAmt
|
||||||
|
|
||||||
|
} // MJournal
|
|
@ -0,0 +1,838 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.*;
|
||||||
|
import java.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.process.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Journal Batch Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MJournalBatch.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MJournalBatch extends X_GL_JournalBatch implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create new Journal Batch by copying
|
||||||
|
* @param ctx context
|
||||||
|
* @param GL_JournalBatch_ID journal batch
|
||||||
|
* @param dateDoc date of the document date
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return Journal Batch
|
||||||
|
*/
|
||||||
|
public static MJournalBatch copyFrom (Properties ctx, int GL_JournalBatch_ID,
|
||||||
|
Timestamp dateDoc, String trxName)
|
||||||
|
{
|
||||||
|
MJournalBatch from = new MJournalBatch (ctx, GL_JournalBatch_ID, trxName);
|
||||||
|
if (from.getGL_JournalBatch_ID() == 0)
|
||||||
|
throw new IllegalArgumentException ("From Journal Batch not found GL_JournalBatch_ID=" + GL_JournalBatch_ID);
|
||||||
|
//
|
||||||
|
MJournalBatch to = new MJournalBatch (ctx, 0, trxName);
|
||||||
|
PO.copyValues(from, to, from.getAD_Client_ID(), from.getAD_Org_ID());
|
||||||
|
to.set_ValueNoCheck ("DocumentNo", null);
|
||||||
|
to.set_ValueNoCheck ("C_Period_ID", null);
|
||||||
|
to.setDateAcct(dateDoc);
|
||||||
|
to.setDateDoc(dateDoc);
|
||||||
|
to.setDocStatus(DOCSTATUS_Drafted);
|
||||||
|
to.setDocAction(DOCACTION_Complete);
|
||||||
|
to.setIsApproved(false);
|
||||||
|
to.setProcessed (false);
|
||||||
|
//
|
||||||
|
if (!to.save())
|
||||||
|
throw new IllegalStateException("Could not create Journal Batch");
|
||||||
|
|
||||||
|
if (to.copyDetailsFrom(from) == 0)
|
||||||
|
throw new IllegalStateException("Could not create Journal Batch Details");
|
||||||
|
|
||||||
|
return to;
|
||||||
|
} // copyFrom
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Construvtore
|
||||||
|
* @param ctx context
|
||||||
|
* @param GL_JournalBatch_ID id if 0 - create actual batch
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MJournalBatch (Properties ctx, int GL_JournalBatch_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, GL_JournalBatch_ID, trxName);
|
||||||
|
if (GL_JournalBatch_ID == 0)
|
||||||
|
{
|
||||||
|
// setGL_JournalBatch_ID (0); PK
|
||||||
|
// setDescription (null);
|
||||||
|
// setDocumentNo (null);
|
||||||
|
// setC_DocType_ID (0);
|
||||||
|
setPostingType (POSTINGTYPE_Actual);
|
||||||
|
setDocAction (DOCACTION_Complete);
|
||||||
|
setDocStatus (DOCSTATUS_Drafted);
|
||||||
|
setTotalCr (Env.ZERO);
|
||||||
|
setTotalDr (Env.ZERO);
|
||||||
|
setProcessed (false);
|
||||||
|
setProcessing (false);
|
||||||
|
setIsApproved(false);
|
||||||
|
}
|
||||||
|
} // MJournalBatch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MJournalBatch (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MJournalBatch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor.
|
||||||
|
* Dos not copy: Dates/Period
|
||||||
|
* @param original original
|
||||||
|
*/
|
||||||
|
public MJournalBatch (MJournalBatch original)
|
||||||
|
{
|
||||||
|
this (original.getCtx(), 0, original.get_TrxName());
|
||||||
|
setClientOrg(original);
|
||||||
|
setGL_JournalBatch_ID(original.getGL_JournalBatch_ID());
|
||||||
|
//
|
||||||
|
// setC_AcctSchema_ID(original.getC_AcctSchema_ID());
|
||||||
|
// setGL_Budget_ID(original.getGL_Budget_ID());
|
||||||
|
setGL_Category_ID(original.getGL_Category_ID());
|
||||||
|
setPostingType(original.getPostingType());
|
||||||
|
setDescription(original.getDescription());
|
||||||
|
setC_DocType_ID(original.getC_DocType_ID());
|
||||||
|
setControlAmt(original.getControlAmt());
|
||||||
|
//
|
||||||
|
setC_Currency_ID(original.getC_Currency_ID());
|
||||||
|
// setC_ConversionType_ID(original.getC_ConversionType_ID());
|
||||||
|
// setCurrencyRate(original.getCurrencyRate());
|
||||||
|
|
||||||
|
// setDateDoc(original.getDateDoc());
|
||||||
|
// setDateAcct(original.getDateAcct());
|
||||||
|
// setC_Period_ID(original.getC_Period_ID());
|
||||||
|
} // MJournal
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite Client/Org if required
|
||||||
|
* @param AD_Client_ID client
|
||||||
|
* @param AD_Org_ID org
|
||||||
|
*/
|
||||||
|
public void setClientOrg (int AD_Client_ID, int AD_Org_ID)
|
||||||
|
{
|
||||||
|
super.setClientOrg(AD_Client_ID, AD_Org_ID);
|
||||||
|
} // setClientOrg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Accounting Date.
|
||||||
|
* Set also Period if not set earlier
|
||||||
|
* @param DateAcct date
|
||||||
|
*/
|
||||||
|
public void setDateAcct (Timestamp DateAcct)
|
||||||
|
{
|
||||||
|
super.setDateAcct(DateAcct);
|
||||||
|
if (DateAcct == null)
|
||||||
|
return;
|
||||||
|
if (getC_Period_ID() != 0)
|
||||||
|
return;
|
||||||
|
int C_Period_ID = MPeriod.getC_Period_ID(getCtx(), DateAcct);
|
||||||
|
if (C_Period_ID == 0)
|
||||||
|
log.warning("Period not found");
|
||||||
|
else
|
||||||
|
setC_Period_ID(C_Period_ID);
|
||||||
|
} // setDateAcct
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Journal Lines
|
||||||
|
* @param requery requery
|
||||||
|
* @return Array of lines
|
||||||
|
*/
|
||||||
|
public MJournal[] getJournals (boolean requery)
|
||||||
|
{
|
||||||
|
ArrayList<MJournal> list = new ArrayList<MJournal>();
|
||||||
|
String sql = "SELECT * FROM GL_Journal WHERE GL_JournalBatch_ID=? ORDER BY DocumentNo";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, get_TrxName());
|
||||||
|
pstmt.setInt(1, getGL_JournalBatch_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
list.add(new MJournal (getCtx(), rs, get_TrxName()));
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close();
|
||||||
|
}
|
||||||
|
catch (SQLException ex1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
//
|
||||||
|
MJournal[] retValue = new MJournal[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getJournals
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Journal/Lines from other Journal Batch
|
||||||
|
* @param jb Journal Batch
|
||||||
|
* @return number of journals + lines copied
|
||||||
|
*/
|
||||||
|
public int copyDetailsFrom (MJournalBatch jb)
|
||||||
|
{
|
||||||
|
if (isProcessed() || jb == null)
|
||||||
|
return 0;
|
||||||
|
int count = 0;
|
||||||
|
int lineCount = 0;
|
||||||
|
MJournal[] fromJournals = jb.getJournals(false);
|
||||||
|
for (int i = 0; i < fromJournals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal toJournal = new MJournal (getCtx(), 0, jb.get_TrxName());
|
||||||
|
PO.copyValues(fromJournals[i], toJournal, getAD_Client_ID(), getAD_Org_ID());
|
||||||
|
toJournal.setGL_JournalBatch_ID(getGL_JournalBatch_ID());
|
||||||
|
toJournal.set_ValueNoCheck ("DocumentNo", null); // create new
|
||||||
|
toJournal.set_ValueNoCheck ("C_Period_ID", null);
|
||||||
|
toJournal.setDateDoc(getDateDoc()); // dates from this Batch
|
||||||
|
toJournal.setDateAcct(getDateAcct());
|
||||||
|
toJournal.setDocStatus(MJournal.DOCSTATUS_Drafted);
|
||||||
|
toJournal.setDocAction(MJournal.DOCACTION_Complete);
|
||||||
|
toJournal.setTotalCr(Env.ZERO);
|
||||||
|
toJournal.setTotalDr(Env.ZERO);
|
||||||
|
toJournal.setIsApproved(false);
|
||||||
|
toJournal.setIsPrinted(false);
|
||||||
|
toJournal.setPosted(false);
|
||||||
|
toJournal.setProcessed(false);
|
||||||
|
if (toJournal.save())
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
lineCount += toJournal.copyLinesFrom(fromJournals[i], getDateAcct(), 'x');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fromJournals.length != count)
|
||||||
|
log.log(Level.SEVERE, "Line difference - Journals=" + fromJournals.length + " <> Saved=" + count);
|
||||||
|
|
||||||
|
return count + lineCount;
|
||||||
|
} // copyLinesFrom
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info("unlockIt - " + toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info("invalidateIt - " + toString());
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
|
||||||
|
// Std Period open?
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getDateAcct(), dt.getDocBaseType()))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add up Amounts & prepare them
|
||||||
|
MJournal[] journals = getJournals(false);
|
||||||
|
if (journals.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal TotalDr = Env.ZERO;
|
||||||
|
BigDecimal TotalCr = Env.ZERO;
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
continue;
|
||||||
|
// Prepare if not closed
|
||||||
|
if (DOCSTATUS_Closed.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Voided.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Reversed.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Completed.equals(journal.getDocStatus()))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String status = journal.prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
{
|
||||||
|
journal.setDocStatus(status);
|
||||||
|
journal.save();
|
||||||
|
m_processMsg = journal.getProcessMsg();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
journal.setDocStatus(DOCSTATUS_InProgress);
|
||||||
|
journal.save();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
TotalDr = TotalDr.add(journal.getTotalDr());
|
||||||
|
TotalCr = TotalCr.add(journal.getTotalCr());
|
||||||
|
}
|
||||||
|
setTotalDr(TotalDr);
|
||||||
|
setTotalCr(TotalCr);
|
||||||
|
|
||||||
|
// Control Amount
|
||||||
|
if (Env.ZERO.compareTo(getControlAmt()) != 0
|
||||||
|
&& getControlAmt().compareTo(getTotalDr()) != 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@ControlAmtError@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug 1353695 Currency Rate and COnbversion Type should get copied from journal to lines
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
MJournalLine[] lines = journal.getLines(true);
|
||||||
|
if (journal.getCurrencyRate() != null && journal.getCurrencyRate().compareTo(Env.ZERO) != 0)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < lines.length; j++)
|
||||||
|
{
|
||||||
|
MJournalLine line = lines[j];
|
||||||
|
line.setCurrencyRate(journal.getCurrencyRate());
|
||||||
|
line.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (journal.getC_ConversionType_ID() > 0)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < lines.length; j++)
|
||||||
|
{
|
||||||
|
MJournalLine line = lines[j];
|
||||||
|
line.setC_ConversionType_ID(journal.getC_ConversionType_ID());
|
||||||
|
line.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Add up Amounts
|
||||||
|
m_justPrepared = true;
|
||||||
|
return DocAction.STATUS_InProgress;
|
||||||
|
} // prepareIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approve Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info("approveIt - " + toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info("rejectIt - " + toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
log.info("completeIt - " + toString());
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
approveIt();
|
||||||
|
|
||||||
|
// Add up Amounts & complete them
|
||||||
|
MJournal[] journals = getJournals(true);
|
||||||
|
BigDecimal TotalDr = Env.ZERO;
|
||||||
|
BigDecimal TotalCr = Env.ZERO;
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
{
|
||||||
|
journal.setProcessed(true);
|
||||||
|
journal.setDocStatus(DOCSTATUS_Voided);
|
||||||
|
journal.setDocAction(DOCACTION_None);
|
||||||
|
journal.save();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Complete if not closed
|
||||||
|
if (DOCSTATUS_Closed.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Voided.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Reversed.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Completed.equals(journal.getDocStatus()))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String status = journal.completeIt();
|
||||||
|
if (!DocAction.STATUS_Completed.equals(status))
|
||||||
|
{
|
||||||
|
journal.setDocStatus(status);
|
||||||
|
journal.save();
|
||||||
|
m_processMsg = journal.getProcessMsg();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
journal.setDocStatus(DOCSTATUS_Completed);
|
||||||
|
journal.save();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
TotalDr = TotalDr.add(journal.getTotalDr());
|
||||||
|
TotalCr = TotalCr.add(journal.getTotalCr());
|
||||||
|
}
|
||||||
|
setTotalDr(TotalDr);
|
||||||
|
setTotalCr(TotalCr);
|
||||||
|
// User Validation
|
||||||
|
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||||
|
if (valid != null)
|
||||||
|
{
|
||||||
|
m_processMsg = valid;
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the definite document number after completed (if needed)
|
||||||
|
setDefiniteDocumentNo();
|
||||||
|
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_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(new Timestamp (System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
if (dt.isOverwriteSeqOnComplete()) {
|
||||||
|
String value = DB.getDocumentNo(getC_DocType_ID(), get_TrxName(), true, this);
|
||||||
|
if (value != null)
|
||||||
|
setDocumentNo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info("voidIt - " + toString());
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info("closeIt - " + toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MJournal[] journals = getJournals(true);
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive() && !journal.isProcessed())
|
||||||
|
{
|
||||||
|
journal.setProcessed(true);
|
||||||
|
journal.setDocStatus(DOCSTATUS_Voided);
|
||||||
|
journal.setDocAction(DOCACTION_None);
|
||||||
|
journal.save();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (DOCSTATUS_Drafted.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_InProgress.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Invalid.equals(journal.getDocStatus()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Journal not Completed: " + journal.getSummary();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close if not closed
|
||||||
|
if (DOCSTATUS_Closed.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Voided.equals(journal.getDocStatus())
|
||||||
|
|| DOCSTATUS_Reversed.equals(journal.getDocStatus()))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!journal.closeIt())
|
||||||
|
{
|
||||||
|
m_processMsg = "Cannot close: " + journal.getSummary();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
journal.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction.
|
||||||
|
* As if nothing happened - same date
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
log.info("reverseCorrectIt - " + toString());
|
||||||
|
// Before reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MJournal[] journals = getJournals(true);
|
||||||
|
// check prerequisites
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
continue;
|
||||||
|
// All need to be closed/Completed
|
||||||
|
if (DOCSTATUS_Completed.equals(journal.getDocStatus()))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_processMsg = "All Journals need to be Completed: " + journal.getSummary();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse it
|
||||||
|
MJournalBatch reverse = new MJournalBatch (this);
|
||||||
|
reverse.setDateDoc(getDateDoc());
|
||||||
|
reverse.setC_Period_ID(getC_Period_ID());
|
||||||
|
reverse.setDateAcct(getDateAcct());
|
||||||
|
// Reverse indicator
|
||||||
|
String description = reverse.getDescription();
|
||||||
|
if (description == null)
|
||||||
|
description = "** " + getDocumentNo() + " **";
|
||||||
|
else
|
||||||
|
description += " ** " + getDocumentNo() + " **";
|
||||||
|
reverse.setDescription(description);
|
||||||
|
reverse.save();
|
||||||
|
//
|
||||||
|
|
||||||
|
// Reverse Journals
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
continue;
|
||||||
|
if (journal.reverseCorrectIt(reverse.getGL_JournalBatch_ID()) == null)
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not reverse " + journal;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
journal.save();
|
||||||
|
}
|
||||||
|
// After reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // reverseCorrectionIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual.
|
||||||
|
* Flip Dr/Cr - Use Today's date
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
log.info("reverseAccrualIt - " + toString());
|
||||||
|
// Before reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MJournal[] journals = getJournals(true);
|
||||||
|
// check prerequisites
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
continue;
|
||||||
|
// All need to be closed/Completed
|
||||||
|
if (DOCSTATUS_Completed.equals(journal.getDocStatus()))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_processMsg = "All Journals need to be Completed: " + journal.getSummary();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Reverse it
|
||||||
|
MJournalBatch reverse = new MJournalBatch (this);
|
||||||
|
reverse.setC_Period_ID(0);
|
||||||
|
reverse.setDateDoc(new Timestamp(System.currentTimeMillis()));
|
||||||
|
reverse.setDateAcct(reverse.getDateDoc());
|
||||||
|
// Reverse indicator
|
||||||
|
String description = reverse.getDescription();
|
||||||
|
if (description == null)
|
||||||
|
description = "** " + getDocumentNo() + " **";
|
||||||
|
else
|
||||||
|
description += " ** " + getDocumentNo() + " **";
|
||||||
|
reverse.setDescription(description);
|
||||||
|
reverse.save();
|
||||||
|
|
||||||
|
// Reverse Journals
|
||||||
|
for (int i = 0; i < journals.length; i++)
|
||||||
|
{
|
||||||
|
MJournal journal = journals[i];
|
||||||
|
if (!journal.isActive())
|
||||||
|
continue;
|
||||||
|
if (journal.reverseAccrualIt(reverse.getGL_JournalBatch_ID()) == null)
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not reverse " + journal;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
journal.save();
|
||||||
|
}
|
||||||
|
// After reverseAccrual
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSEACCRUAL);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // reverseAccrualIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-activate - same as reverse correct
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info("reActivateIt - " + toString());
|
||||||
|
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// setProcessed(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
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getDocumentNo());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"TotalDr")).append("=").append(getTotalDr())
|
||||||
|
.append(" ")
|
||||||
|
.append(Msg.translate(getCtx(),"TotalCR")).append("=").append(getTotalCr())
|
||||||
|
.append(" (#").append(getJournals(false).length).append(")");
|
||||||
|
// - Description
|
||||||
|
if (getDescription() != null && getDescription().length() > 0)
|
||||||
|
sb.append(" - ").append(getDescription());
|
||||||
|
return sb.toString();
|
||||||
|
} // getSummary
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("MJournalBatch[");
|
||||||
|
sb.append(get_ID()).append(",").append(getDescription())
|
||||||
|
.append(",DR=").append(getTotalDr())
|
||||||
|
.append(",CR=").append(getTotalCr())
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
return dt.getName() + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Process Message
|
||||||
|
* @return clear text error message
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID (Created By)
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getCreatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Approval Amount
|
||||||
|
* @return DR amount
|
||||||
|
*/
|
||||||
|
public BigDecimal getApprovalAmt()
|
||||||
|
{
|
||||||
|
return getTotalDr();
|
||||||
|
} // getApprovalAmt
|
||||||
|
|
||||||
|
} // MJournalBatch
|
|
@ -0,0 +1,304 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse Locator Object
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MLocator.java,v 1.3 2006/07/30 00:58:37 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MLocator extends X_M_Locator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get oldest Default Locator of warehouse with locator
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @return locator or null
|
||||||
|
*/
|
||||||
|
public static MLocator getDefault (Properties ctx, int M_Locator_ID)
|
||||||
|
{
|
||||||
|
String trxName = null;
|
||||||
|
MLocator retValue = null;
|
||||||
|
String sql = "SELECT * FROM M_Locator l "
|
||||||
|
+ "WHERE IsDefault='Y'"
|
||||||
|
+ " AND EXISTS (SELECT * FROM M_Locator lx "
|
||||||
|
+ "WHERE l.M_Warehouse_ID=lx.M_Warehouse_ID AND lx.M_Locator_ID=?) "
|
||||||
|
+ "ORDER BY Created";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_Locator_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
retValue = new MLocator (ctx, rs, trxName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log (Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValue;
|
||||||
|
} // getDefault
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Locator with the combination or create new one
|
||||||
|
* @param ctx Context
|
||||||
|
* @param M_Warehouse_ID warehouse
|
||||||
|
* @param Value value
|
||||||
|
* @param X x
|
||||||
|
* @param Y y
|
||||||
|
* @param Z z
|
||||||
|
* @return locator
|
||||||
|
*/
|
||||||
|
public static MLocator get (Properties ctx, int M_Warehouse_ID, String Value,
|
||||||
|
String X, String Y, String Z)
|
||||||
|
{
|
||||||
|
MLocator retValue = null;
|
||||||
|
String sql = "SELECT * FROM M_Locator WHERE M_Warehouse_ID=? AND X=? AND Y=? AND Z=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, null);
|
||||||
|
pstmt.setInt(1, M_Warehouse_ID);
|
||||||
|
pstmt.setString(2, X);
|
||||||
|
pstmt.setString(3, Y);
|
||||||
|
pstmt.setString(4, Z);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
if (rs.next())
|
||||||
|
retValue = new MLocator (ctx, rs, null);
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, "get", ex);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (retValue == null)
|
||||||
|
{
|
||||||
|
MWarehouse wh = MWarehouse.get (ctx, M_Warehouse_ID);
|
||||||
|
retValue = new MLocator (wh, Value);
|
||||||
|
retValue.setXYZ(X, Y, Z);
|
||||||
|
retValue.save();
|
||||||
|
}
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Locator from Cache
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Locator_ID id
|
||||||
|
* @return MLocator
|
||||||
|
*/
|
||||||
|
public static MLocator get (Properties ctx, int M_Locator_ID)
|
||||||
|
{
|
||||||
|
if (s_cache == null)
|
||||||
|
s_cache = new CCache<Integer,MLocator>("M_Locator", 20);
|
||||||
|
Integer key = new Integer (M_Locator_ID);
|
||||||
|
MLocator retValue = (MLocator) s_cache.get (key);
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
retValue = new MLocator (ctx, M_Locator_ID, null);
|
||||||
|
if (retValue.get_ID () != 0)
|
||||||
|
s_cache.put (key, retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/** Cache */
|
||||||
|
private static CCache<Integer,MLocator> s_cache;
|
||||||
|
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MLocator.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Locator Constructor
|
||||||
|
* @param ctx Context
|
||||||
|
* @param M_Locator_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MLocator (Properties ctx, int M_Locator_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_Locator_ID, trxName);
|
||||||
|
if (M_Locator_ID == 0)
|
||||||
|
{
|
||||||
|
// setM_Locator_ID (0); // PK
|
||||||
|
// setM_Warehouse_ID (0); // Parent
|
||||||
|
setIsDefault (false);
|
||||||
|
setPriorityNo (50);
|
||||||
|
// setValue (null);
|
||||||
|
// setX (null);
|
||||||
|
// setY (null);
|
||||||
|
// setZ (null);
|
||||||
|
}
|
||||||
|
} // MLocator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New Locator Constructor with XYZ=000
|
||||||
|
* @param warehouse parent
|
||||||
|
* @param Value value
|
||||||
|
*/
|
||||||
|
public MLocator (MWarehouse warehouse, String Value)
|
||||||
|
{
|
||||||
|
this (warehouse.getCtx(), 0, warehouse.get_TrxName());
|
||||||
|
setClientOrg(warehouse);
|
||||||
|
setM_Warehouse_ID (warehouse.getM_Warehouse_ID()); // Parent
|
||||||
|
setValue (Value);
|
||||||
|
setXYZ("0","0","0");
|
||||||
|
} // MLocator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MLocator (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MLocator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get String Representation
|
||||||
|
* @return Value
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getValue();
|
||||||
|
} // getValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Location
|
||||||
|
* @param X x
|
||||||
|
* @param Y y
|
||||||
|
* @param Z z
|
||||||
|
*/
|
||||||
|
public void setXYZ (String X, String Y, String Z)
|
||||||
|
{
|
||||||
|
setX (X);
|
||||||
|
setY (Y);
|
||||||
|
setZ (Z);
|
||||||
|
} // setXYZ
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Warehouse Name
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
|
public String getWarehouseName()
|
||||||
|
{
|
||||||
|
MWarehouse wh = MWarehouse.get(getCtx(), getM_Warehouse_ID());
|
||||||
|
if (wh.get_ID() == 0)
|
||||||
|
return "<" + getM_Warehouse_ID() + ">";
|
||||||
|
return wh.getName();
|
||||||
|
} // getWarehouseName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can Locator Store Product
|
||||||
|
* @param M_Product_ID id
|
||||||
|
* @return true if can be stored
|
||||||
|
*/
|
||||||
|
public boolean isCanStoreProduct (int M_Product_ID)
|
||||||
|
{
|
||||||
|
// BF [ 1759245 ] Locator field cleared in Physical Inventory
|
||||||
|
// CarlosRuiz - globalqss comments:
|
||||||
|
// The algorithm to search if a product can be stored is wrong, it looks for:
|
||||||
|
// * M_Storage to see if the product is already in the locator
|
||||||
|
// * If the product has this locator defined as default
|
||||||
|
// This implies that every time you create a new product you must create initial inventory zero for all locators where the product can be stored.
|
||||||
|
// A good enhancement could be a new table to indicate when a locator is exclusive for some products, but I consider current approach not working.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Default Locator
|
||||||
|
if (M_Product_ID == 0 || isDefault())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
// Already Stored
|
||||||
|
String sql = "SELECT COUNT(*) FROM M_Storage s WHERE s.M_Locator_ID=? AND s.M_Product_ID=?";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
|
pstmt.setInt (1, getM_Locator_ID());
|
||||||
|
pstmt.setInt (2, M_Product_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
count = rs.getInt(1);
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log (Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
// Default Product Locator
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
sql = "SELECT COUNT(*) FROM M_Product s WHERE s.M_Locator_ID=? AND s.M_Product_ID=?";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
|
pstmt.setInt (1, getM_Locator_ID());
|
||||||
|
pstmt.setInt (2, M_Product_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
count = rs.getInt(1);
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log (Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count != 0;
|
||||||
|
*/
|
||||||
|
} // isCanStoreProduct
|
||||||
|
|
||||||
|
} // MLocator
|
|
@ -0,0 +1,169 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MMenu.java,v 1.3 2006/07/30 00:58:18 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MMenu extends X_AD_Menu
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get menues with where clause
|
||||||
|
* @param ctx context
|
||||||
|
* @param whereClause where clause w/o the actual WHERE
|
||||||
|
* @return MMenu
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public static MMenu[] get (Properties ctx, String whereClause)
|
||||||
|
{
|
||||||
|
return get(ctx, whereClause, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get menues with where clause
|
||||||
|
* @param ctx context
|
||||||
|
* @param whereClause where clause w/o the actual WHERE
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return MMenu
|
||||||
|
*/
|
||||||
|
public static MMenu[] get (Properties ctx, String whereClause, String trxName)
|
||||||
|
{
|
||||||
|
String sql = "SELECT * FROM AD_Menu";
|
||||||
|
if (whereClause != null && whereClause.length() > 0)
|
||||||
|
sql += " WHERE " + whereClause;
|
||||||
|
ArrayList<MMenu> list = new ArrayList<MMenu>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new MMenu (ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
MMenu[] retValue = new MMenu[list.size()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/** Static Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MMenu.class);
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param AD_Menu_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMenu (Properties ctx, int AD_Menu_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, AD_Menu_ID, trxName);
|
||||||
|
if (AD_Menu_ID == 0)
|
||||||
|
{
|
||||||
|
setEntityType (ENTITYTYPE_UserMaintained); // U
|
||||||
|
setIsReadOnly (false); // N
|
||||||
|
setIsSOTrx (false);
|
||||||
|
setIsSummary (false);
|
||||||
|
// setName (null);
|
||||||
|
}
|
||||||
|
} // MMenu
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Contrusctor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMenu (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MMenu
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
// Reset info
|
||||||
|
if (isSummary() && getAction() != null)
|
||||||
|
setAction(null);
|
||||||
|
String action = getAction();
|
||||||
|
if (action == null)
|
||||||
|
action = "";
|
||||||
|
// Clean up references
|
||||||
|
if (getAD_Window_ID() != 0 && !action.equals(ACTION_Window))
|
||||||
|
setAD_Window_ID(0);
|
||||||
|
if (getAD_Form_ID() != 0 && !action.equals(ACTION_Form))
|
||||||
|
setAD_Form_ID(0);
|
||||||
|
if (getAD_Workflow_ID() != 0 && !action.equals(ACTION_WorkFlow))
|
||||||
|
setAD_Workflow_ID(0);
|
||||||
|
if (getAD_Workbench_ID() != 0 && !action.equals(ACTION_Workbench))
|
||||||
|
setAD_Workbench_ID(0);
|
||||||
|
if (getAD_Task_ID() != 0 && !action.equals(ACTION_Task))
|
||||||
|
setAD_Task_ID(0);
|
||||||
|
if (getAD_Process_ID() != 0
|
||||||
|
&& !(action.equals(ACTION_Process) || action.equals(ACTION_Report)))
|
||||||
|
setAD_Process_ID(0);
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @param success success
|
||||||
|
* @return success
|
||||||
|
*/
|
||||||
|
protected boolean afterSave (boolean newRecord, boolean success)
|
||||||
|
{
|
||||||
|
if (newRecord)
|
||||||
|
insert_Tree(MTree_Base.TREETYPE_Menu);
|
||||||
|
return success;
|
||||||
|
} // afterSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Delete
|
||||||
|
* @param success
|
||||||
|
* @return deleted
|
||||||
|
*/
|
||||||
|
protected boolean afterDelete (boolean success)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
delete_Tree(MTree_Base.TREETYPE_Menu);
|
||||||
|
return success;
|
||||||
|
} // afterDelete
|
||||||
|
|
||||||
|
} // MMenu
|
|
@ -0,0 +1,894 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.*;
|
||||||
|
import java.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.process.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inventory Movement Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MMovement.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MMovement extends X_M_Movement implements DocAction
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Movement_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMovement (Properties ctx, int M_Movement_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_Movement_ID, trxName);
|
||||||
|
if (M_Movement_ID == 0)
|
||||||
|
{
|
||||||
|
// setC_DocType_ID (0);
|
||||||
|
setDocAction (DOCACTION_Complete); // CO
|
||||||
|
setDocStatus (DOCSTATUS_Drafted); // DR
|
||||||
|
setIsApproved (false);
|
||||||
|
setIsInTransit (false);
|
||||||
|
setMovementDate (new Timestamp(System.currentTimeMillis())); // @#Date@
|
||||||
|
setPosted (false);
|
||||||
|
super.setProcessed (false);
|
||||||
|
}
|
||||||
|
} // MMovement
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMovement (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MMovement
|
||||||
|
|
||||||
|
/** Lines */
|
||||||
|
private MMovementLine[] m_lines = null;
|
||||||
|
/** Confirmations */
|
||||||
|
private MMovementConfirm[] m_confirms = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Lines
|
||||||
|
* @param requery requery
|
||||||
|
* @return array of lines
|
||||||
|
*/
|
||||||
|
public MMovementLine[] getLines (boolean requery)
|
||||||
|
{
|
||||||
|
if (m_lines != null && !requery) {
|
||||||
|
set_TrxName(m_lines, get_TrxName());
|
||||||
|
return m_lines;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
ArrayList<MMovementLine> list = new ArrayList<MMovementLine>();
|
||||||
|
String sql = "SELECT * FROM M_MovementLine WHERE M_Movement_ID=? ORDER BY Line";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getM_Movement_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
{
|
||||||
|
list.add (new MMovementLine (getCtx(), rs, get_TrxName()));
|
||||||
|
}
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "getLines", e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lines = new MMovementLine[list.size ()];
|
||||||
|
list.toArray (m_lines);
|
||||||
|
return m_lines;
|
||||||
|
} // getLines
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Confirmations
|
||||||
|
* @param requery requery
|
||||||
|
* @return array of Confirmations
|
||||||
|
*/
|
||||||
|
public MMovementConfirm[] getConfirmations(boolean requery)
|
||||||
|
{
|
||||||
|
if (m_confirms != null && !requery)
|
||||||
|
return m_confirms;
|
||||||
|
|
||||||
|
ArrayList<MMovementConfirm> list = new ArrayList<MMovementConfirm>();
|
||||||
|
String sql = "SELECT * FROM M_MovementConfirm WHERE M_Movement_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getM_Movement_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add(new MMovementConfirm(getCtx(), rs, get_TrxName()));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "getConfirmations", e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_confirms = new MMovementConfirm[list.size ()];
|
||||||
|
list.toArray (m_confirms);
|
||||||
|
return m_confirms;
|
||||||
|
} // getConfirmations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to Description
|
||||||
|
* @param description text
|
||||||
|
*/
|
||||||
|
public void addDescription (String description)
|
||||||
|
{
|
||||||
|
String desc = getDescription();
|
||||||
|
if (desc == null)
|
||||||
|
setDescription(description);
|
||||||
|
else
|
||||||
|
setDescription(desc + " | " + description);
|
||||||
|
} // addDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Info
|
||||||
|
* @return document info (untranslated)
|
||||||
|
*/
|
||||||
|
public String getDocumentInfo()
|
||||||
|
{
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
return dt.getName() + " " + getDocumentNo();
|
||||||
|
} // getDocumentInfo
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PDF
|
||||||
|
* @return File or null
|
||||||
|
*/
|
||||||
|
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 file if success
|
||||||
|
*/
|
||||||
|
public File createPDF (File file)
|
||||||
|
{
|
||||||
|
// ReportEngine re = ReportEngine.get (getCtx(), ReportEngine.INVOICE, getC_Invoice_ID());
|
||||||
|
// if (re == null)
|
||||||
|
return null;
|
||||||
|
// return re.getPDF(file);
|
||||||
|
} // createPDF
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
if (getC_DocType_ID() == 0)
|
||||||
|
{
|
||||||
|
MDocType types[] = MDocType.getOfDocBaseType(getCtx(), MDocType.DOCBASETYPE_MaterialMovement);
|
||||||
|
if (types.length > 0) // get first
|
||||||
|
setC_DocType_ID(types[0].getC_DocType_ID());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.saveError("Error", Msg.parseTranslation(getCtx(), "@NotFound@ @C_DocType_ID@"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Processed.
|
||||||
|
* Propergate to Lines/Taxes
|
||||||
|
* @param processed processed
|
||||||
|
*/
|
||||||
|
public void setProcessed (boolean processed)
|
||||||
|
{
|
||||||
|
super.setProcessed (processed);
|
||||||
|
if (get_ID() == 0)
|
||||||
|
return;
|
||||||
|
String sql = "UPDATE M_MovementLine SET Processed='"
|
||||||
|
+ (processed ? "Y" : "N")
|
||||||
|
+ "' WHERE M_Movement_ID=" + getM_Movement_ID();
|
||||||
|
int noLine = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
m_lines = null;
|
||||||
|
log.fine("Processed=" + processed + " - Lines=" + noLine);
|
||||||
|
} // setProcessed
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Process document
|
||||||
|
* @param processAction document action
|
||||||
|
* @return true if performed
|
||||||
|
*/
|
||||||
|
public boolean processIt (String processAction)
|
||||||
|
{
|
||||||
|
m_processMsg = null;
|
||||||
|
DocumentEngine engine = new DocumentEngine (this, getDocStatus());
|
||||||
|
return engine.processIt (processAction, getDocAction());
|
||||||
|
} // processIt
|
||||||
|
|
||||||
|
/** Process Message */
|
||||||
|
private String m_processMsg = null;
|
||||||
|
/** Just Prepared Flag */
|
||||||
|
private boolean m_justPrepared = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean unlockIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setProcessing(false);
|
||||||
|
return true;
|
||||||
|
} // unlockIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean invalidateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setDocAction(DOCACTION_Prepare);
|
||||||
|
return true;
|
||||||
|
} // invalidateIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare Document
|
||||||
|
* @return new status (In Progress or Invalid)
|
||||||
|
*/
|
||||||
|
public String prepareIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
|
||||||
|
// Std Period open?
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType()))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
MMovementLine[] lines = getLines(false);
|
||||||
|
if (lines.length == 0)
|
||||||
|
{
|
||||||
|
m_processMsg = "@NoLines@";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
// Add up Amounts
|
||||||
|
|
||||||
|
|
||||||
|
checkMaterialPolicy();
|
||||||
|
|
||||||
|
// Confirmation
|
||||||
|
if (dt.isInTransit())
|
||||||
|
createConfirmation();
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Movement Confirmation
|
||||||
|
*/
|
||||||
|
private void createConfirmation()
|
||||||
|
{
|
||||||
|
MMovementConfirm[] confirmations = getConfirmations(false);
|
||||||
|
if (confirmations.length > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create Confirmation
|
||||||
|
MMovementConfirm.create (this, false);
|
||||||
|
} // createConfirmation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approve Document
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean approveIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(true);
|
||||||
|
return true;
|
||||||
|
} // approveIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reject Approval
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean rejectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
setIsApproved(false);
|
||||||
|
return true;
|
||||||
|
} // rejectIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complete Document
|
||||||
|
* @return new status (Complete, In Progress, Invalid, Waiting ..)
|
||||||
|
*/
|
||||||
|
public String completeIt()
|
||||||
|
{
|
||||||
|
// Re-Check
|
||||||
|
if (!m_justPrepared)
|
||||||
|
{
|
||||||
|
String status = prepareIt();
|
||||||
|
if (!DocAction.STATUS_InProgress.equals(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
|
||||||
|
// Outstanding (not processed) Incoming Confirmations ?
|
||||||
|
MMovementConfirm[] confirmations = getConfirmations(true);
|
||||||
|
for (int i = 0; i < confirmations.length; i++)
|
||||||
|
{
|
||||||
|
MMovementConfirm confirm = confirmations[i];
|
||||||
|
if (!confirm.isProcessed())
|
||||||
|
{
|
||||||
|
m_processMsg = "Open: @M_MovementConfirm_ID@ - "
|
||||||
|
+ confirm.getDocumentNo();
|
||||||
|
return DocAction.STATUS_InProgress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implicit Approval
|
||||||
|
if (!isApproved())
|
||||||
|
approveIt();
|
||||||
|
log.info(toString());
|
||||||
|
|
||||||
|
//
|
||||||
|
MMovementLine[] lines = getLines(false);
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MMovementLine line = lines[i];
|
||||||
|
MTransaction trxFrom = null;
|
||||||
|
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||||
|
{
|
||||||
|
MMovementLineMA mas[] = MMovementLineMA.get(getCtx(),
|
||||||
|
line.getM_MovementLine_ID(), get_TrxName());
|
||||||
|
for (int j = 0; j < mas.length; j++)
|
||||||
|
{
|
||||||
|
MMovementLineMA ma = mas[j];
|
||||||
|
//
|
||||||
|
MStorage storageFrom = MStorage.get(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
if (storageFrom == null)
|
||||||
|
storageFrom = MStorage.getCreate(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
MStorage storageTo = MStorage.get(getCtx(), line.getM_LocatorTo_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
if (storageTo == null)
|
||||||
|
storageTo = MStorage.getCreate(getCtx(), line.getM_LocatorTo_ID(),
|
||||||
|
line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
storageFrom.setQtyOnHand(storageFrom.getQtyOnHand().subtract(ma.getMovementQty()));
|
||||||
|
if (!storageFrom.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage From not updated (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
storageTo.setQtyOnHand(storageTo.getQtyOnHand().add(ma.getMovementQty()));
|
||||||
|
if (!storageTo.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage To not updated (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_MovementFrom,
|
||||||
|
line.getM_Locator_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
|
||||||
|
ma.getMovementQty().negate(), getMovementDate(), get_TrxName());
|
||||||
|
trxFrom.setM_MovementLine_ID(line.getM_MovementLine_ID());
|
||||||
|
if (!trxFrom.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction From not inserted (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_MovementTo,
|
||||||
|
line.getM_LocatorTo_ID(), line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(),
|
||||||
|
ma.getMovementQty(), getMovementDate(), get_TrxName());
|
||||||
|
trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID());
|
||||||
|
if (!trxTo.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction To not inserted (MA)";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback - We have ASI
|
||||||
|
if (trxFrom == null)
|
||||||
|
{
|
||||||
|
MStorage storageFrom = MStorage.get(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
if (storageFrom == null)
|
||||||
|
storageFrom = MStorage.getCreate(getCtx(), line.getM_Locator_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
MStorage storageTo = MStorage.get(getCtx(), line.getM_LocatorTo_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), get_TrxName());
|
||||||
|
if (storageTo == null)
|
||||||
|
storageTo = MStorage.getCreate(getCtx(), line.getM_LocatorTo_ID(),
|
||||||
|
line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(), get_TrxName());
|
||||||
|
//
|
||||||
|
storageFrom.setQtyOnHand(storageFrom.getQtyOnHand().subtract(line.getMovementQty()));
|
||||||
|
if (!storageFrom.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage From not updated";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
storageTo.setQtyOnHand(storageTo.getQtyOnHand().add(line.getMovementQty()));
|
||||||
|
if (!storageTo.save(get_TrxName()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Storage To not updated";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
trxFrom = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_MovementFrom,
|
||||||
|
line.getM_Locator_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(),
|
||||||
|
line.getMovementQty().negate(), getMovementDate(), get_TrxName());
|
||||||
|
trxFrom.setM_MovementLine_ID(line.getM_MovementLine_ID());
|
||||||
|
if (!trxFrom.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction From not inserted";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
MTransaction trxTo = new MTransaction (getCtx(), line.getAD_Org_ID(),
|
||||||
|
MTransaction.MOVEMENTTYPE_MovementTo,
|
||||||
|
line.getM_LocatorTo_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstanceTo_ID(),
|
||||||
|
line.getMovementQty(), getMovementDate(), get_TrxName());
|
||||||
|
trxTo.setM_MovementLine_ID(line.getM_MovementLine_ID());
|
||||||
|
if (!trxTo.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Transaction To not inserted";
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
} // Fallback
|
||||||
|
} // for all lines
|
||||||
|
// User Validation
|
||||||
|
String valid = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_COMPLETE);
|
||||||
|
if (valid != null)
|
||||||
|
{
|
||||||
|
m_processMsg = valid;
|
||||||
|
return DocAction.STATUS_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the definite document number after completed (if needed)
|
||||||
|
setDefiniteDocumentNo();
|
||||||
|
|
||||||
|
//
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_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()) {
|
||||||
|
setMovementDate(new Timestamp (System.currentTimeMillis()));
|
||||||
|
}
|
||||||
|
if (dt.isOverwriteSeqOnComplete()) {
|
||||||
|
String value = DB.getDocumentNo(getC_DocType_ID(), get_TrxName(), true, this);
|
||||||
|
if (value != null)
|
||||||
|
setDocumentNo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Material Policy
|
||||||
|
* Sets line ASI
|
||||||
|
*/
|
||||||
|
private void checkMaterialPolicy()
|
||||||
|
{
|
||||||
|
int no = MMovementLineMA.deleteMovementMA(getM_Movement_ID(), get_TrxName());
|
||||||
|
if (no > 0)
|
||||||
|
log.config("Delete old #" + no);
|
||||||
|
MMovementLine[] lines = getLines(false);
|
||||||
|
|
||||||
|
// Check Lines
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MMovementLine line = lines[i];
|
||||||
|
boolean needSave = false;
|
||||||
|
|
||||||
|
// Attribute Set Instance
|
||||||
|
if (line.getM_AttributeSetInstance_ID() == 0)
|
||||||
|
{
|
||||||
|
MProduct product = MProduct.get(getCtx(), line.getM_Product_ID());
|
||||||
|
String MMPolicy = product.getMMPolicy();
|
||||||
|
MStorage[] storages = MStorage.getAllWithASI(getCtx(),
|
||||||
|
line.getM_Product_ID(), line.getM_Locator_ID(),
|
||||||
|
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||||
|
BigDecimal qtyToDeliver = line.getMovementQty();
|
||||||
|
for (int ii = 0; ii < storages.length; ii++)
|
||||||
|
{
|
||||||
|
MStorage storage = storages[ii];
|
||||||
|
if (ii == 0)
|
||||||
|
{
|
||||||
|
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||||
|
{
|
||||||
|
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||||
|
needSave = true;
|
||||||
|
log.config("Direct - " + line);
|
||||||
|
qtyToDeliver = Env.ZERO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.config("Split - " + line);
|
||||||
|
MMovementLineMA ma = new MMovementLineMA (line,
|
||||||
|
storage.getM_AttributeSetInstance_ID(),
|
||||||
|
storage.getQtyOnHand());
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||||
|
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // create addl material allocation
|
||||||
|
{
|
||||||
|
MMovementLineMA ma = new MMovementLineMA (line,
|
||||||
|
storage.getM_AttributeSetInstance_ID(),
|
||||||
|
qtyToDeliver);
|
||||||
|
if (storage.getQtyOnHand().compareTo(qtyToDeliver) >= 0)
|
||||||
|
qtyToDeliver = Env.ZERO;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ma.setMovementQty(storage.getQtyOnHand());
|
||||||
|
qtyToDeliver = qtyToDeliver.subtract(storage.getQtyOnHand());
|
||||||
|
}
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
log.fine("#" + ii + ": " + ma + ", QtyToDeliver=" + qtyToDeliver);
|
||||||
|
}
|
||||||
|
if (qtyToDeliver.signum() == 0)
|
||||||
|
break;
|
||||||
|
} // for all storages
|
||||||
|
|
||||||
|
// No AttributeSetInstance found for remainder
|
||||||
|
if (qtyToDeliver.signum() != 0)
|
||||||
|
{
|
||||||
|
MMovementLineMA ma = new MMovementLineMA (line,
|
||||||
|
0, qtyToDeliver);
|
||||||
|
if (!ma.save())
|
||||||
|
;
|
||||||
|
log.fine("##: " + ma);
|
||||||
|
}
|
||||||
|
} // attributeSetInstance
|
||||||
|
|
||||||
|
if (needSave && !line.save())
|
||||||
|
log.severe("NOT saved " + line);
|
||||||
|
} // for all lines
|
||||||
|
|
||||||
|
} // checkMaterialPolicy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Void Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean voidIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (DOCSTATUS_Closed.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Reversed.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Voided.equals(getDocStatus()))
|
||||||
|
{
|
||||||
|
m_processMsg = "Document Closed: " + getDocStatus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not Processed
|
||||||
|
if (DOCSTATUS_Drafted.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Invalid.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_InProgress.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_Approved.equals(getDocStatus())
|
||||||
|
|| DOCSTATUS_NotApproved.equals(getDocStatus()) )
|
||||||
|
{
|
||||||
|
// Set lines to 0
|
||||||
|
MMovementLine[] lines = getLines(false);
|
||||||
|
for (int i = 0; i < lines.length; i++)
|
||||||
|
{
|
||||||
|
MMovementLine line = lines[i];
|
||||||
|
BigDecimal old = line.getMovementQty();
|
||||||
|
if (old.compareTo(Env.ZERO) != 0)
|
||||||
|
{
|
||||||
|
line.setMovementQty(Env.ZERO);
|
||||||
|
line.addDescription("Void (" + old + ")");
|
||||||
|
line.save(get_TrxName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reverseCorrectIt();
|
||||||
|
}
|
||||||
|
// After Void
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_VOID);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setProcessed(true);
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return true;
|
||||||
|
} // voidIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close Document.
|
||||||
|
* @return true if success
|
||||||
|
*/
|
||||||
|
public boolean closeIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After Close
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Close Not delivered Qty
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
return true;
|
||||||
|
} // closeIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Correction
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reverseCorrectIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MDocType dt = MDocType.get(getCtx(), getC_DocType_ID());
|
||||||
|
if (!MPeriod.isOpen(getCtx(), getMovementDate(), dt.getDocBaseType()))
|
||||||
|
{
|
||||||
|
m_processMsg = "@PeriodClosed@";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deep Copy
|
||||||
|
MMovement reversal = new MMovement(getCtx(), 0, get_TrxName());
|
||||||
|
copyValues(this, reversal, getAD_Client_ID(), getAD_Org_ID());
|
||||||
|
reversal.setDocStatus(DOCSTATUS_Drafted);
|
||||||
|
reversal.setDocAction(DOCACTION_Complete);
|
||||||
|
reversal.setIsApproved (false);
|
||||||
|
reversal.setIsInTransit (false);
|
||||||
|
reversal.setPosted(false);
|
||||||
|
reversal.setProcessed(false);
|
||||||
|
reversal.addDescription("{->" + getDocumentNo() + ")");
|
||||||
|
if (!reversal.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not create Movement Reversal";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse Line Qty
|
||||||
|
MMovementLine[] oLines = getLines(true);
|
||||||
|
for (int i = 0; i < oLines.length; i++)
|
||||||
|
{
|
||||||
|
MMovementLine oLine = oLines[i];
|
||||||
|
MMovementLine rLine = new MMovementLine(getCtx(), 0, get_TrxName());
|
||||||
|
copyValues(oLine, rLine, oLine.getAD_Client_ID(), oLine.getAD_Org_ID());
|
||||||
|
rLine.setM_Movement_ID(reversal.getM_Movement_ID());
|
||||||
|
//
|
||||||
|
rLine.setMovementQty(rLine.getMovementQty().negate());
|
||||||
|
rLine.setTargetQty(Env.ZERO);
|
||||||
|
rLine.setScrappedQty(Env.ZERO);
|
||||||
|
rLine.setConfirmedQty(Env.ZERO);
|
||||||
|
rLine.setProcessed(false);
|
||||||
|
if (!rLine.save())
|
||||||
|
{
|
||||||
|
m_processMsg = "Could not create Movement Reversal Line";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (!reversal.processIt(DocAction.ACTION_Complete))
|
||||||
|
{
|
||||||
|
m_processMsg = "Reversal ERROR: " + reversal.getProcessMsg();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reversal.closeIt();
|
||||||
|
reversal.setDocStatus(DOCSTATUS_Reversed);
|
||||||
|
reversal.setDocAction(DOCACTION_None);
|
||||||
|
reversal.save();
|
||||||
|
m_processMsg = reversal.getDocumentNo();
|
||||||
|
|
||||||
|
// After reverseCorrect
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REVERSECORRECT);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Update Reversed (this)
|
||||||
|
addDescription("(" + reversal.getDocumentNo() + "<-)");
|
||||||
|
setProcessed(true);
|
||||||
|
setDocStatus(DOCSTATUS_Reversed); // may come from void
|
||||||
|
setDocAction(DOCACTION_None);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // reverseCorrectionIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse Accrual - none
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
public boolean reverseAccrualIt()
|
||||||
|
{
|
||||||
|
log.info(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 false
|
||||||
|
*/
|
||||||
|
public boolean reActivateIt()
|
||||||
|
{
|
||||||
|
log.info(toString());
|
||||||
|
// Before reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// After reActivate
|
||||||
|
m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_REACTIVATE);
|
||||||
|
if (m_processMsg != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} // reActivateIt
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Get Summary
|
||||||
|
* @return Summary of Document
|
||||||
|
*/
|
||||||
|
public String getSummary()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append(getDocumentNo());
|
||||||
|
// : Total Lines = 123.00 (#1)
|
||||||
|
sb.append(": ")
|
||||||
|
.append(Msg.translate(getCtx(),"ApprovalAmt")).append("=").append(getApprovalAmt())
|
||||||
|
.append(" (#").append(getLines(false).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
|
||||||
|
*/
|
||||||
|
public String getProcessMsg()
|
||||||
|
{
|
||||||
|
return m_processMsg;
|
||||||
|
} // getProcessMsg
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Owner (Responsible)
|
||||||
|
* @return AD_User_ID
|
||||||
|
*/
|
||||||
|
public int getDoc_User_ID()
|
||||||
|
{
|
||||||
|
return getCreatedBy();
|
||||||
|
} // getDoc_User_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Document Currency
|
||||||
|
* @return C_Currency_ID
|
||||||
|
*/
|
||||||
|
public int getC_Currency_ID()
|
||||||
|
{
|
||||||
|
// MPriceList pl = MPriceList.get(getCtx(), getM_PriceList_ID());
|
||||||
|
// return pl.getC_Currency_ID();
|
||||||
|
return 0;
|
||||||
|
} // getC_Currency_ID
|
||||||
|
|
||||||
|
} // MMovement
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inventory Move Line Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MMovementLine.java,v 1.3 2006/07/30 00:51:03 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MMovementLine extends X_M_MovementLine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Standard Cosntructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_MovementLine_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMovementLine (Properties ctx, int M_MovementLine_ID, String trxName)
|
||||||
|
{
|
||||||
|
super (ctx, M_MovementLine_ID, trxName);
|
||||||
|
if (M_MovementLine_ID == 0)
|
||||||
|
{
|
||||||
|
// setM_LocatorTo_ID (0); // @M_LocatorTo_ID@
|
||||||
|
// setM_Locator_ID (0); // @M_Locator_ID@
|
||||||
|
// setM_MovementLine_ID (0);
|
||||||
|
// setLine (0);
|
||||||
|
// setM_Product_ID (0);
|
||||||
|
setM_AttributeSetInstance_ID(0); // ID
|
||||||
|
setMovementQty (Env.ZERO); // 1
|
||||||
|
setTargetQty (Env.ZERO); // 0
|
||||||
|
setScrappedQty(Env.ZERO);
|
||||||
|
setConfirmedQty(Env.ZERO);
|
||||||
|
setProcessed (false);
|
||||||
|
}
|
||||||
|
} // MMovementLine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MMovementLine (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MMovementLine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent constructor
|
||||||
|
* @param parent parent
|
||||||
|
*/
|
||||||
|
public MMovementLine (MMovement parent)
|
||||||
|
{
|
||||||
|
this (parent.getCtx(), 0, parent.get_TrxName());
|
||||||
|
setClientOrg(parent);
|
||||||
|
setM_Movement_ID(parent.getM_Movement_ID());
|
||||||
|
} // MMovementLine
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get AttributeSetInstance To
|
||||||
|
* @return ASI
|
||||||
|
*/
|
||||||
|
public int getM_AttributeSetInstanceTo_ID ()
|
||||||
|
{
|
||||||
|
int M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstanceTo_ID();
|
||||||
|
if (M_AttributeSetInstanceTo_ID == 0)
|
||||||
|
M_AttributeSetInstanceTo_ID = super.getM_AttributeSetInstance_ID();
|
||||||
|
return M_AttributeSetInstanceTo_ID;
|
||||||
|
} // getM_AttributeSetInstanceTo_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to Description
|
||||||
|
* @param description text
|
||||||
|
*/
|
||||||
|
public void addDescription (String description)
|
||||||
|
{
|
||||||
|
String desc = getDescription();
|
||||||
|
if (desc == null)
|
||||||
|
setDescription(description);
|
||||||
|
else
|
||||||
|
setDescription(desc + " | " + description);
|
||||||
|
} // addDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Product
|
||||||
|
* @return product or null if not defined
|
||||||
|
*/
|
||||||
|
public MProduct getProduct()
|
||||||
|
{
|
||||||
|
if (getM_Product_ID() != 0)
|
||||||
|
return MProduct.get(getCtx(), getM_Product_ID());
|
||||||
|
return null;
|
||||||
|
} // getProduct
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Movement Qty - enforce UOM
|
||||||
|
* @param MovementQty qty
|
||||||
|
*/
|
||||||
|
public void setMovementQty (BigDecimal MovementQty)
|
||||||
|
{
|
||||||
|
if (MovementQty != null)
|
||||||
|
{
|
||||||
|
MProduct product = getProduct();
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
int precision = product.getUOMPrecision();
|
||||||
|
MovementQty = MovementQty.setScale(precision, BigDecimal.ROUND_HALF_UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setMovementQty(MovementQty);
|
||||||
|
} // setMovementQty
|
||||||
|
|
||||||
|
/** Parent */
|
||||||
|
private MMovement m_parent = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Parent
|
||||||
|
* @return Parent Movement
|
||||||
|
*/
|
||||||
|
public MMovement getParent()
|
||||||
|
{
|
||||||
|
if (m_parent == null)
|
||||||
|
m_parent = new MMovement (getCtx(), getM_Movement_ID(), get_TrxName());
|
||||||
|
return m_parent;
|
||||||
|
} // getParent
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeSave (boolean newRecord)
|
||||||
|
{
|
||||||
|
// Set Line No
|
||||||
|
if (getLine() == 0)
|
||||||
|
{
|
||||||
|
String sql = "SELECT COALESCE(MAX(Line),0)+10 AS DefaultValue FROM M_MovementLine WHERE M_Movement_ID=?";
|
||||||
|
int ii = DB.getSQLValue (get_TrxName(), sql, getM_Movement_ID());
|
||||||
|
setLine (ii);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getM_Locator_ID() == getM_LocatorTo_ID())
|
||||||
|
{
|
||||||
|
log.saveError("Error", Msg.parseTranslation(getCtx(), "@M_Locator_ID@ == @M_LocatorTo_ID@"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getMovementQty().signum() == 0)
|
||||||
|
{
|
||||||
|
log.saveError("FillMandatory", Msg.getElement(getCtx(), "MovementQty"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Qty Precision
|
||||||
|
if (newRecord || is_ValueChanged(COLUMNNAME_MovementQty))
|
||||||
|
setMovementQty(getMovementQty());
|
||||||
|
|
||||||
|
// Mandatory Instance
|
||||||
|
MProduct product = getProduct();
|
||||||
|
if (getM_AttributeSetInstance_ID() == 0) {
|
||||||
|
if (product != null && product.isASIMandatory(false)) {
|
||||||
|
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstance_ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getM_AttributeSetInstanceTo_ID() == 0)
|
||||||
|
{
|
||||||
|
if (getM_AttributeSetInstance_ID() != 0) // set to from
|
||||||
|
setM_AttributeSetInstanceTo_ID(getM_AttributeSetInstance_ID());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (product != null && product.isASIMandatory(true))
|
||||||
|
{
|
||||||
|
log.saveError("FillMandatory", Msg.getElement(getCtx(), COLUMNNAME_M_AttributeSetInstanceTo_ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // ASI
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // beforeSave
|
||||||
|
|
||||||
|
|
||||||
|
} // MMovementLine
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,651 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inventory Storage Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MStorage.java,v 1.3 2006/07/30 00:51:05 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MStorage extends X_M_Storage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Storage Info
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID instance
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or null
|
||||||
|
*/
|
||||||
|
public static MStorage get (Properties ctx, int M_Locator_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
|
||||||
|
{
|
||||||
|
MStorage retValue = null;
|
||||||
|
String sql = "SELECT * FROM M_Storage "
|
||||||
|
+ "WHERE M_Locator_ID=? AND M_Product_ID=? AND ";
|
||||||
|
if (M_AttributeSetInstance_ID == 0)
|
||||||
|
sql += "(M_AttributeSetInstance_ID=? OR M_AttributeSetInstance_ID IS NULL)";
|
||||||
|
else
|
||||||
|
sql += "M_AttributeSetInstance_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_Locator_ID);
|
||||||
|
pstmt.setInt (2, M_Product_ID);
|
||||||
|
pstmt.setInt (3, M_AttributeSetInstance_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
retValue = new MStorage (ctx, rs, trxName);
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
if (retValue == null)
|
||||||
|
s_log.fine("Not Found - M_Locator_ID=" + M_Locator_ID
|
||||||
|
+ ", M_Product_ID=" + M_Product_ID + ", M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID);
|
||||||
|
else
|
||||||
|
s_log.fine("M_Locator_ID=" + M_Locator_ID
|
||||||
|
+ ", M_Product_ID=" + M_Product_ID + ", M_AttributeSetInstance_ID=" + M_AttributeSetInstance_ID);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Storages for Product with ASI and QtyOnHand > 0
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param FiFo first in-first-out
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or null
|
||||||
|
*/
|
||||||
|
public static MStorage[] getAllWithASI (Properties ctx, int M_Product_ID, int M_Locator_ID,
|
||||||
|
boolean FiFo, String trxName)
|
||||||
|
{
|
||||||
|
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||||
|
String sql = "SELECT * FROM M_Storage "
|
||||||
|
+ "WHERE M_Product_ID=? AND M_Locator_ID=?"
|
||||||
|
+ " AND M_AttributeSetInstance_ID > 0"
|
||||||
|
+ " AND QtyOnHand > 0 "
|
||||||
|
+ "ORDER BY M_AttributeSetInstance_ID";
|
||||||
|
if (!FiFo)
|
||||||
|
sql += " DESC";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_Product_ID);
|
||||||
|
pstmt.setInt (2, M_Locator_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add(new MStorage (ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
MStorage[] retValue = new MStorage[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getAllWithASI
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Storages for Product
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or null
|
||||||
|
*/
|
||||||
|
public static MStorage[] getAll (Properties ctx,
|
||||||
|
int M_Product_ID, int M_Locator_ID, String trxName)
|
||||||
|
{
|
||||||
|
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||||
|
String sql = "SELECT * FROM M_Storage "
|
||||||
|
+ "WHERE M_Product_ID=? AND M_Locator_ID=?"
|
||||||
|
+ " AND QtyOnHand <> 0 "
|
||||||
|
+ "ORDER BY M_AttributeSetInstance_ID";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_Product_ID);
|
||||||
|
pstmt.setInt (2, M_Locator_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add(new MStorage (ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
pstmt = null;
|
||||||
|
MStorage[] retValue = new MStorage[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getAll
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Storage Info for Product across warehouses
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or null
|
||||||
|
*/
|
||||||
|
public static MStorage[] getOfProduct (Properties ctx, int M_Product_ID, String trxName)
|
||||||
|
{
|
||||||
|
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||||
|
String sql = "SELECT * FROM M_Storage "
|
||||||
|
+ "WHERE M_Product_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, M_Product_ID);
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add(new MStorage (ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
MStorage[] retValue = new MStorage[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getOfProduct
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Storage Info for Warehouse
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Warehouse_ID
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID instance
|
||||||
|
* @param M_AttributeSet_ID attribute set
|
||||||
|
* @param allAttributeInstances if true, all attribute set instances
|
||||||
|
* @param minGuaranteeDate optional minimum guarantee date if all attribute instances
|
||||||
|
* @param FiFo first in-first-out
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing - ordered by location priority (desc) and/or guarantee date
|
||||||
|
*/
|
||||||
|
public static MStorage[] getWarehouse (Properties ctx, int M_Warehouse_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, int M_AttributeSet_ID,
|
||||||
|
boolean allAttributeInstances, Timestamp minGuaranteeDate,
|
||||||
|
boolean FiFo, String trxName)
|
||||||
|
{
|
||||||
|
if (M_Warehouse_ID == 0 || M_Product_ID == 0)
|
||||||
|
return new MStorage[0];
|
||||||
|
|
||||||
|
if (M_AttributeSet_ID == 0)
|
||||||
|
allAttributeInstances = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MAttributeSet mas = MAttributeSet.get(ctx, M_AttributeSet_ID);
|
||||||
|
if (!mas.isInstanceAttribute())
|
||||||
|
allAttributeInstances = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<MStorage> list = new ArrayList<MStorage>();
|
||||||
|
// Specific Attribute Set Instance
|
||||||
|
String sql = "SELECT s.M_Product_ID,s.M_Locator_ID,s.M_AttributeSetInstance_ID,"
|
||||||
|
+ "s.AD_Client_ID,s.AD_Org_ID,s.IsActive,s.Created,s.CreatedBy,s.Updated,s.UpdatedBy,"
|
||||||
|
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.DateLastInventory "
|
||||||
|
+ "FROM M_Storage s"
|
||||||
|
+ " INNER JOIN M_Locator l ON (l.M_Locator_ID=s.M_Locator_ID) "
|
||||||
|
+ "WHERE l.M_Warehouse_ID=?"
|
||||||
|
+ " AND s.M_Product_ID=?"
|
||||||
|
+ " AND COALESCE(s.M_AttributeSetInstance_ID,0)=? "
|
||||||
|
+ "ORDER BY l.PriorityNo DESC, M_AttributeSetInstance_ID";
|
||||||
|
if (!FiFo)
|
||||||
|
sql += " DESC";
|
||||||
|
// All Attribute Set Instances
|
||||||
|
if (allAttributeInstances)
|
||||||
|
{
|
||||||
|
sql = "SELECT s.M_Product_ID,s.M_Locator_ID,s.M_AttributeSetInstance_ID,"
|
||||||
|
+ "s.AD_Client_ID,s.AD_Org_ID,s.IsActive,s.Created,s.CreatedBy,s.Updated,s.UpdatedBy,"
|
||||||
|
+ "s.QtyOnHand,s.QtyReserved,s.QtyOrdered,s.DateLastInventory "
|
||||||
|
+ "FROM M_Storage s"
|
||||||
|
+ " INNER JOIN M_Locator l ON (l.M_Locator_ID=s.M_Locator_ID)"
|
||||||
|
+ " LEFT OUTER JOIN M_AttributeSetInstance asi ON (s.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID) "
|
||||||
|
+ "WHERE l.M_Warehouse_ID=?"
|
||||||
|
+ " AND s.M_Product_ID=? ";
|
||||||
|
if (minGuaranteeDate != null)
|
||||||
|
{
|
||||||
|
sql += "AND (asi.GuaranteeDate IS NULL OR asi.GuaranteeDate>?) "
|
||||||
|
+ "ORDER BY asi.GuaranteeDate, M_AttributeSetInstance_ID";
|
||||||
|
if (!FiFo)
|
||||||
|
sql += " DESC";
|
||||||
|
sql += ", l.PriorityNo DESC, s.QtyOnHand DESC";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql += "ORDER BY l.PriorityNo DESC, l.M_Locator_ID, s.M_AttributeSetInstance_ID";
|
||||||
|
if (!FiFo)
|
||||||
|
sql += " DESC";
|
||||||
|
sql += ", s.QtyOnHand DESC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, trxName);
|
||||||
|
pstmt.setInt(1, M_Warehouse_ID);
|
||||||
|
pstmt.setInt(2, M_Product_ID);
|
||||||
|
if (!allAttributeInstances)
|
||||||
|
pstmt.setInt(3, M_AttributeSetInstance_ID);
|
||||||
|
else if (minGuaranteeDate != null)
|
||||||
|
pstmt.setTimestamp(3, minGuaranteeDate);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
list.add (new MStorage (ctx, rs, trxName));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
MStorage[] retValue = new MStorage[list.size()];
|
||||||
|
list.toArray(retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getWarehouse
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or Get Storage Info
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID instance
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing/new or null
|
||||||
|
*/
|
||||||
|
public static MStorage getCreate (Properties ctx, int M_Locator_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
|
||||||
|
{
|
||||||
|
if (M_Locator_ID == 0)
|
||||||
|
throw new IllegalArgumentException("M_Locator_ID=0");
|
||||||
|
if (M_Product_ID == 0)
|
||||||
|
throw new IllegalArgumentException("M_Product_ID=0");
|
||||||
|
MStorage retValue = get(ctx, M_Locator_ID, M_Product_ID, M_AttributeSetInstance_ID, trxName);
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
|
||||||
|
// Insert row based on locator
|
||||||
|
MLocator locator = new MLocator (ctx, M_Locator_ID, trxName);
|
||||||
|
if (locator.get_ID() != M_Locator_ID)
|
||||||
|
throw new IllegalArgumentException("Not found M_Locator_ID=" + M_Locator_ID);
|
||||||
|
//
|
||||||
|
retValue = new MStorage (locator, M_Product_ID, M_AttributeSetInstance_ID);
|
||||||
|
retValue.save(trxName);
|
||||||
|
s_log.fine("New " + retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getCreate
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Storage Info add.
|
||||||
|
* Called from MProjectIssue
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Warehouse_ID warehouse
|
||||||
|
* @param M_Locator_ID locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID AS Instance
|
||||||
|
* @param reservationAttributeSetInstance_ID reservation AS Instance
|
||||||
|
* @param diffQtyOnHand add on hand
|
||||||
|
* @param diffQtyReserved add reserved
|
||||||
|
* @param diffQtyOrdered add order
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return true if updated
|
||||||
|
*/
|
||||||
|
public static boolean add (Properties ctx, int M_Warehouse_ID, int M_Locator_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, int reservationAttributeSetInstance_ID,
|
||||||
|
BigDecimal diffQtyOnHand,
|
||||||
|
BigDecimal diffQtyReserved, BigDecimal diffQtyOrdered, String trxName)
|
||||||
|
{
|
||||||
|
MStorage storage = null;
|
||||||
|
StringBuffer diffText = new StringBuffer("(");
|
||||||
|
|
||||||
|
// Get Storage
|
||||||
|
if (storage == null)
|
||||||
|
storage = getCreate (ctx, M_Locator_ID,
|
||||||
|
M_Product_ID, M_AttributeSetInstance_ID, trxName);
|
||||||
|
// Verify
|
||||||
|
if (storage.getM_Locator_ID() != M_Locator_ID
|
||||||
|
&& storage.getM_Product_ID() != M_Product_ID
|
||||||
|
&& storage.getM_AttributeSetInstance_ID() != M_AttributeSetInstance_ID)
|
||||||
|
{
|
||||||
|
s_log.severe ("No Storage found - M_Locator_ID=" + M_Locator_ID
|
||||||
|
+ ",M_Product_ID=" + M_Product_ID + ",ASI=" + M_AttributeSetInstance_ID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CarlosRuiz - globalqss - Fix [ 1725383 ] QtyOrdered wrongly updated
|
||||||
|
MProduct prd = new MProduct(ctx, M_Product_ID, trxName);
|
||||||
|
if (prd.getM_AttributeSet_ID() == 0) {
|
||||||
|
// Product doesn't manage attribute set, always reserved with 0
|
||||||
|
reservationAttributeSetInstance_ID = 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
MStorage storage0 = null;
|
||||||
|
if (M_AttributeSetInstance_ID != reservationAttributeSetInstance_ID)
|
||||||
|
{
|
||||||
|
storage0 = get(ctx, M_Locator_ID,
|
||||||
|
M_Product_ID, reservationAttributeSetInstance_ID, trxName);
|
||||||
|
if (storage0 == null) // create if not existing - should not happen
|
||||||
|
{
|
||||||
|
MWarehouse wh = MWarehouse.get(ctx, M_Warehouse_ID);
|
||||||
|
int xM_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||||
|
storage0 = getCreate (ctx, xM_Locator_ID,
|
||||||
|
M_Product_ID, reservationAttributeSetInstance_ID, trxName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boolean changed = false;
|
||||||
|
if (diffQtyOnHand != null && diffQtyOnHand.signum() != 0)
|
||||||
|
{
|
||||||
|
storage.setQtyOnHand (storage.getQtyOnHand().add (diffQtyOnHand));
|
||||||
|
diffText.append("OnHand=").append(diffQtyOnHand);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (diffQtyReserved != null && diffQtyReserved.signum() != 0)
|
||||||
|
{
|
||||||
|
if (storage0 == null)
|
||||||
|
storage.setQtyReserved (storage.getQtyReserved().add (diffQtyReserved));
|
||||||
|
else
|
||||||
|
storage0.setQtyReserved (storage0.getQtyReserved().add (diffQtyReserved));
|
||||||
|
diffText.append(" Reserved=").append(diffQtyReserved);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (diffQtyOrdered != null && diffQtyOrdered.signum() != 0)
|
||||||
|
{
|
||||||
|
if (storage0 == null)
|
||||||
|
storage.setQtyOrdered (storage.getQtyOrdered().add (diffQtyOrdered));
|
||||||
|
else
|
||||||
|
storage0.setQtyOrdered (storage0.getQtyOrdered().add (diffQtyOrdered));
|
||||||
|
diffText.append(" Ordered=").append(diffQtyOrdered);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
diffText.append(") -> ").append(storage.toString());
|
||||||
|
s_log.fine(diffText.toString());
|
||||||
|
if (storage0 != null)
|
||||||
|
storage0.save(trxName); // No AttributeSetInstance (reserved/ordered)
|
||||||
|
return storage.save (trxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // add
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Get Location with highest Locator Priority and a sufficient OnHand Qty
|
||||||
|
* @param M_Warehouse_ID warehouse
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID asi
|
||||||
|
* @param Qty qty
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
|
public static int getM_Locator_ID (int M_Warehouse_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, BigDecimal Qty,
|
||||||
|
String trxName)
|
||||||
|
{
|
||||||
|
int M_Locator_ID = 0;
|
||||||
|
int firstM_Locator_ID = 0;
|
||||||
|
String sql = "SELECT s.M_Locator_ID, s.QtyOnHand "
|
||||||
|
+ "FROM M_Storage s"
|
||||||
|
+ " INNER JOIN M_Locator l ON (s.M_Locator_ID=l.M_Locator_ID)"
|
||||||
|
+ " INNER JOIN M_Product p ON (s.M_Product_ID=p.M_Product_ID)"
|
||||||
|
+ " LEFT OUTER JOIN M_AttributeSet mas ON (p.M_AttributeSet_ID=mas.M_AttributeSet_ID) "
|
||||||
|
+ "WHERE l.M_Warehouse_ID=?"
|
||||||
|
+ " AND s.M_Product_ID=?"
|
||||||
|
+ " AND (mas.IsInstanceAttribute IS NULL OR mas.IsInstanceAttribute='N' OR s.M_AttributeSetInstance_ID=?)"
|
||||||
|
+ " AND l.IsActive='Y' "
|
||||||
|
+ "ORDER BY l.PriorityNo DESC, s.QtyOnHand DESC";
|
||||||
|
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql, trxName);
|
||||||
|
pstmt.setInt(1, M_Warehouse_ID);
|
||||||
|
pstmt.setInt(2, M_Product_ID);
|
||||||
|
pstmt.setInt(3, M_AttributeSetInstance_ID);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
BigDecimal QtyOnHand = rs.getBigDecimal(2);
|
||||||
|
if (QtyOnHand != null && Qty.compareTo(QtyOnHand) <= 0)
|
||||||
|
{
|
||||||
|
M_Locator_ID = rs.getInt(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (firstM_Locator_ID == 0)
|
||||||
|
firstM_Locator_ID = rs.getInt(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException ex)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
if (M_Locator_ID != 0)
|
||||||
|
return M_Locator_ID;
|
||||||
|
return firstM_Locator_ID;
|
||||||
|
} // getM_Locator_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Available Qty.
|
||||||
|
* The call is accurate only if there is a storage record
|
||||||
|
* and assumes that the product is stocked
|
||||||
|
* @param M_Warehouse_ID wh
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID masi
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return qty available (QtyOnHand-QtyReserved) or null
|
||||||
|
* @deprecated Since 331b. Please use {@link #getQtyAvailable(int, int, int, int, String)}.
|
||||||
|
*/
|
||||||
|
public static BigDecimal getQtyAvailable (int M_Warehouse_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
|
||||||
|
{
|
||||||
|
return getQtyAvailable(M_Warehouse_ID, 0, M_Product_ID, M_AttributeSetInstance_ID, trxName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Warehouse/Locator Available Qty.
|
||||||
|
* The call is accurate only if there is a storage record
|
||||||
|
* and assumes that the product is stocked
|
||||||
|
* @param M_Warehouse_ID wh (if the M_Locator_ID!=0 then M_Warehouse_ID is ignored)
|
||||||
|
* @param M_Locator_ID locator (if 0, the whole warehouse will be evaluated)
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID masi
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return qty available (QtyOnHand-QtyReserved) or null if error
|
||||||
|
*/
|
||||||
|
public static BigDecimal getQtyAvailable (int M_Warehouse_ID, int M_Locator_ID,
|
||||||
|
int M_Product_ID, int M_AttributeSetInstance_ID, String trxName)
|
||||||
|
{
|
||||||
|
ArrayList<Object> params = new ArrayList<Object>();
|
||||||
|
StringBuffer sql = new StringBuffer("SELECT COALESCE(SUM(s.QtyOnHand-s.QtyReserved),0)")
|
||||||
|
.append(" FROM M_Storage s")
|
||||||
|
.append(" WHERE s.M_Product_ID=?");
|
||||||
|
params.add(M_Product_ID);
|
||||||
|
// Warehouse level
|
||||||
|
if (M_Locator_ID == 0) {
|
||||||
|
sql.append(" AND EXISTS (SELECT 1 FROM M_Locator l WHERE s.M_Locator_ID=l.M_Locator_ID AND l.M_Warehouse_ID=?)");
|
||||||
|
params.add(M_Warehouse_ID);
|
||||||
|
}
|
||||||
|
// Locator level
|
||||||
|
else {
|
||||||
|
sql.append(" AND s.M_Locator_ID=?");
|
||||||
|
params.add(M_Locator_ID);
|
||||||
|
}
|
||||||
|
// With ASI
|
||||||
|
if (M_AttributeSetInstance_ID != 0) {
|
||||||
|
sql.append(" AND s.M_AttributeSetInstance_ID=?");
|
||||||
|
params.add(M_AttributeSetInstance_ID);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
BigDecimal retValue = DB.getSQLValueBD(trxName, sql.toString(), params);
|
||||||
|
if (CLogMgt.isLevelFine())
|
||||||
|
s_log.fine("M_Warehouse_ID=" + M_Warehouse_ID + ", M_Locator_ID=" + M_Locator_ID
|
||||||
|
+ ",M_Product_ID=" + M_Product_ID + " = " + retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getQtyAvailable
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Persistency Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param ignored ignored
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MStorage (Properties ctx, int ignored, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, 0, trxName);
|
||||||
|
if (ignored != 0)
|
||||||
|
throw new IllegalArgumentException("Multi-Key");
|
||||||
|
//
|
||||||
|
setQtyOnHand (Env.ZERO);
|
||||||
|
setQtyOrdered (Env.ZERO);
|
||||||
|
setQtyReserved (Env.ZERO);
|
||||||
|
} // MStorage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MStorage (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MStorage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full NEW Constructor
|
||||||
|
* @param locator (parent) locator
|
||||||
|
* @param M_Product_ID product
|
||||||
|
* @param M_AttributeSetInstance_ID attribute
|
||||||
|
*/
|
||||||
|
private MStorage (MLocator locator, int M_Product_ID, int M_AttributeSetInstance_ID)
|
||||||
|
{
|
||||||
|
this (locator.getCtx(), 0, locator.get_TrxName());
|
||||||
|
setClientOrg(locator);
|
||||||
|
setM_Locator_ID (locator.getM_Locator_ID());
|
||||||
|
setM_Product_ID (M_Product_ID);
|
||||||
|
setM_AttributeSetInstance_ID (M_AttributeSetInstance_ID);
|
||||||
|
} // MStorage
|
||||||
|
|
||||||
|
/** Log */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MStorage.class);
|
||||||
|
/** Warehouse */
|
||||||
|
private int m_M_Warehouse_ID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change Qty OnHand
|
||||||
|
* @param qty quantity
|
||||||
|
* @param add add if true
|
||||||
|
*/
|
||||||
|
public void changeQtyOnHand (BigDecimal qty, boolean add)
|
||||||
|
{
|
||||||
|
if (qty == null || qty.signum() == 0)
|
||||||
|
return;
|
||||||
|
if (add)
|
||||||
|
setQtyOnHand(getQtyOnHand().add(qty));
|
||||||
|
else
|
||||||
|
setQtyOnHand(getQtyOnHand().subtract(qty));
|
||||||
|
} // changeQtyOnHand
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get M_Warehouse_ID of Locator
|
||||||
|
* @return warehouse
|
||||||
|
*/
|
||||||
|
public int getM_Warehouse_ID()
|
||||||
|
{
|
||||||
|
if (m_M_Warehouse_ID == 0)
|
||||||
|
{
|
||||||
|
MLocator loc = MLocator.get(getCtx(), getM_Locator_ID());
|
||||||
|
m_M_Warehouse_ID = loc.getM_Warehouse_ID();
|
||||||
|
}
|
||||||
|
return m_M_Warehouse_ID;
|
||||||
|
} // getM_Warehouse_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer("MStorage[")
|
||||||
|
.append("M_Locator_ID=").append(getM_Locator_ID())
|
||||||
|
.append(",M_Product_ID=").append(getM_Product_ID())
|
||||||
|
.append(",M_AttributeSetInstance_ID=").append(getM_AttributeSetInstance_ID())
|
||||||
|
.append(": OnHand=").append(getQtyOnHand())
|
||||||
|
.append(",Reserved=").append(getQtyReserved())
|
||||||
|
.append(",Ordered=").append(getQtyOrdered())
|
||||||
|
.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
} // MStorage
|
|
@ -0,0 +1,236 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warehouse Model
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: MWarehouse.java,v 1.3 2006/07/30 00:58:05 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class MWarehouse extends X_M_Warehouse
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get from Cache
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Warehouse_ID id
|
||||||
|
* @return warehouse
|
||||||
|
*/
|
||||||
|
public static MWarehouse get (Properties ctx, int M_Warehouse_ID)
|
||||||
|
{
|
||||||
|
Integer key = new Integer(M_Warehouse_ID);
|
||||||
|
MWarehouse retValue = (MWarehouse)s_cache.get(key);
|
||||||
|
if (retValue != null)
|
||||||
|
return retValue;
|
||||||
|
//
|
||||||
|
retValue = new MWarehouse (ctx, M_Warehouse_ID, null);
|
||||||
|
s_cache.put (key, retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Warehouses for Org
|
||||||
|
* @param ctx context
|
||||||
|
* @param AD_Org_ID id
|
||||||
|
* @return warehouse
|
||||||
|
*/
|
||||||
|
public static MWarehouse[] getForOrg (Properties ctx, int AD_Org_ID)
|
||||||
|
{
|
||||||
|
ArrayList<MWarehouse> list = new ArrayList<MWarehouse>();
|
||||||
|
String sql = "SELECT * FROM M_Warehouse WHERE AD_Org_ID=? ORDER BY Created";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
|
pstmt.setInt (1, AD_Org_ID);
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new MWarehouse (ctx, rs, null));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
MWarehouse[] retValue = new MWarehouse[list.size ()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
|
||||||
|
/** Cache */
|
||||||
|
private static CCache<Integer,MWarehouse> s_cache = new CCache<Integer,MWarehouse>("M_Warehouse", 5);
|
||||||
|
/** Static Logger */
|
||||||
|
private static CLogger s_log = CLogger.getCLogger (MWarehouse.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param M_Warehouse_ID id
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MWarehouse (Properties ctx, int M_Warehouse_ID, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, M_Warehouse_ID, trxName);
|
||||||
|
if (M_Warehouse_ID == 0)
|
||||||
|
{
|
||||||
|
// setValue (null);
|
||||||
|
// setName (null);
|
||||||
|
// setC_Location_ID (0);
|
||||||
|
setSeparator ("*"); // *
|
||||||
|
}
|
||||||
|
} // MWarehouse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Constructor
|
||||||
|
* @param ctx context
|
||||||
|
* @param rs result set
|
||||||
|
* @param trxName transaction
|
||||||
|
*/
|
||||||
|
public MWarehouse (Properties ctx, ResultSet rs, String trxName)
|
||||||
|
{
|
||||||
|
super(ctx, rs, trxName);
|
||||||
|
} // MWarehouse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organization Constructor
|
||||||
|
* @param org parent
|
||||||
|
*/
|
||||||
|
public MWarehouse (MOrg org)
|
||||||
|
{
|
||||||
|
this (org.getCtx(), 0, org.get_TrxName());
|
||||||
|
setClientOrg(org);
|
||||||
|
setValue (org.getValue());
|
||||||
|
setName (org.getName());
|
||||||
|
if (org.getInfo() != null)
|
||||||
|
setC_Location_ID (org.getInfo().getC_Location_ID());
|
||||||
|
} // MWarehouse
|
||||||
|
|
||||||
|
/** Warehouse Locators */
|
||||||
|
private MLocator[] m_locators = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Locators
|
||||||
|
* @param reload if true reload
|
||||||
|
* @return array of locators
|
||||||
|
*/
|
||||||
|
public MLocator[] getLocators(boolean reload)
|
||||||
|
{
|
||||||
|
if (!reload && m_locators != null)
|
||||||
|
return m_locators;
|
||||||
|
//
|
||||||
|
String sql = "SELECT * FROM M_Locator WHERE M_Warehouse_ID=? ORDER BY X,Y,Z";
|
||||||
|
ArrayList<MLocator> list = new ArrayList<MLocator>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
|
pstmt.setInt (1, getM_Warehouse_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add(new MLocator (getCtx(), rs, null));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
m_locators = new MLocator[list.size()];
|
||||||
|
list.toArray (m_locators);
|
||||||
|
return m_locators;
|
||||||
|
} // getLocators
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Default Locator
|
||||||
|
* @return (first) default locator
|
||||||
|
*/
|
||||||
|
public MLocator getDefaultLocator()
|
||||||
|
{
|
||||||
|
MLocator[] locators = getLocators(false);
|
||||||
|
for (int i = 0; i < locators.length; i++)
|
||||||
|
{
|
||||||
|
if (locators[i].isDefault() && locators[i].isActive())
|
||||||
|
return locators[i];
|
||||||
|
}
|
||||||
|
// No Default - first one
|
||||||
|
if (locators.length > 0)
|
||||||
|
{
|
||||||
|
log.warning("No default locator for " + getName());
|
||||||
|
return locators[0];
|
||||||
|
}
|
||||||
|
// No Locator - create one
|
||||||
|
MLocator loc = new MLocator (this, "Standard");
|
||||||
|
loc.setIsDefault(true);
|
||||||
|
loc.save();
|
||||||
|
log.info("Created default locator for " + getName());
|
||||||
|
return loc;
|
||||||
|
} // getLocators
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After Save
|
||||||
|
* @param newRecord new
|
||||||
|
* @param success success
|
||||||
|
* @return success
|
||||||
|
*/
|
||||||
|
protected boolean afterSave (boolean newRecord, boolean success)
|
||||||
|
{
|
||||||
|
if (newRecord && success)
|
||||||
|
insert_Accounting("M_Warehouse_Acct", "C_AcctSchema_Default", null);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
} // afterSave
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before Delete
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
protected boolean beforeDelete ()
|
||||||
|
{
|
||||||
|
return delete_Accounting("M_Warehouse_Acct");
|
||||||
|
} // beforeDelete
|
||||||
|
|
||||||
|
} // MWarehouse
|
|
@ -0,0 +1,162 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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 *
|
||||||
|
* Contributor(s) : Layda Salas - globalqss *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Validator
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: ModelValidator.java,v 1.2 2006/07/30 00:58:18 jjanke Exp $
|
||||||
|
*
|
||||||
|
* 2007/02/26 laydasalasc - globalqss - Add new timings for all before/after events on documents
|
||||||
|
*/
|
||||||
|
public interface ModelValidator
|
||||||
|
{
|
||||||
|
/** Model Change Type New */
|
||||||
|
public static final int TYPE_BEFORE_NEW = 1; // teo_sarca [ 1675490 ]
|
||||||
|
public static final int TYPE_NEW = 1;
|
||||||
|
public static final int CHANGETYPE_NEW = 1; // Compatibility with Compiere 260c
|
||||||
|
public static final int TYPE_AFTER_NEW = 4; // teo_sarca [ 1675490 ]
|
||||||
|
/** Model Change Type Change */
|
||||||
|
public static final int TYPE_BEFORE_CHANGE = 2; // teo_sarca [ 1675490 ]
|
||||||
|
public static final int TYPE_CHANGE = 2;
|
||||||
|
public static final int CHANGETYPE_CHANGE = 2; // Compatibility with Compiere 260c
|
||||||
|
public static final int TYPE_AFTER_CHANGE = 5; // teo_sarca [ 1675490 ]
|
||||||
|
/** Model Change Type Delete */
|
||||||
|
public static final int TYPE_BEFORE_DELETE = 3; // teo_sarca [ 1675490 ]
|
||||||
|
public static final int TYPE_DELETE = 3;
|
||||||
|
public static final int CHANGETYPE_DELETE = 3; // Compatibility with Compiere 260c
|
||||||
|
public static final int TYPE_AFTER_DELETE = 6; // teo_sarca [ 1675490 ]
|
||||||
|
|
||||||
|
// Correlation between constant events and list of event script model validators
|
||||||
|
public static String[] tableEventValidators = new String[] {
|
||||||
|
"", // 0
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeNew, // TYPE_BEFORE_NEW = 1
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeChange, // TYPE_BEFORE_CHANGE = 2
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableBeforeDelete, // TYPE_BEFORE_DELETE = 3
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterNew, // TYPE_AFTER_NEW = 4
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterChange, // TYPE_AFTER_CHANGE = 5
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_TableAfterDelete // TYPE_AFTER_DELETE = 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Called before document is prepared */
|
||||||
|
public static final int TIMING_BEFORE_PREPARE = 1;
|
||||||
|
public static final int DOCTIMING_BEFORE_PREPARE = 1; // Compatibility with Compiere 260c
|
||||||
|
/** Called before document is void */
|
||||||
|
public static final int TIMING_BEFORE_VOID = 2;
|
||||||
|
/** Called before document is close */
|
||||||
|
public static final int TIMING_BEFORE_CLOSE = 3;
|
||||||
|
/** Called before document is reactivate */
|
||||||
|
public static final int TIMING_BEFORE_REACTIVATE = 4;
|
||||||
|
/** Called before document is reversecorrect */
|
||||||
|
public static final int TIMING_BEFORE_REVERSECORRECT = 5;
|
||||||
|
/** Called before document is reverseaccrual */
|
||||||
|
public static final int TIMING_BEFORE_REVERSEACCRUAL = 6;
|
||||||
|
/** Called before document is completed */
|
||||||
|
public static final int TIMING_BEFORE_COMPLETE = 7;
|
||||||
|
/** Called after document is prepared */
|
||||||
|
public static final int TIMING_AFTER_PREPARE = 8;
|
||||||
|
/** Called after document is completed */
|
||||||
|
public static final int TIMING_AFTER_COMPLETE = 9;
|
||||||
|
public static final int DOCTIMING_AFTER_COMPLETE = 9; // Compatibility with Compiere 260c
|
||||||
|
/** Called after document is void */
|
||||||
|
public static final int TIMING_AFTER_VOID = 10;
|
||||||
|
/** Called after document is closed */
|
||||||
|
public static final int TIMING_AFTER_CLOSE = 11;
|
||||||
|
/** Called after document is reactivated */
|
||||||
|
public static final int TIMING_AFTER_REACTIVATE = 12;
|
||||||
|
/** Called after document is reversecorrect */
|
||||||
|
public static final int TIMING_AFTER_REVERSECORRECT = 13;
|
||||||
|
/** Called after document is reverseaccrual */
|
||||||
|
public static final int TIMING_AFTER_REVERSEACCRUAL = 14;
|
||||||
|
/** Called before document is posted */
|
||||||
|
public static final int TIMING_BEFORE_POST = 15;
|
||||||
|
/** Called after document is posted */
|
||||||
|
public static final int TIMING_AFTER_POST = 16;
|
||||||
|
|
||||||
|
// Correlation between constant events and list of event script model validators
|
||||||
|
public static String[] documentEventValidators = new String[] {
|
||||||
|
"", // 0
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforePrepare, // TIMING_BEFORE_PREPARE = 1
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeVoid, // TIMING_BEFORE_VOID = 2
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeClose, // TIMING_BEFORE_CLOSE = 3
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeReactivate, // TIMING_BEFORE_REACTIVATE = 4
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeReverseCorrect, // TIMING_BEFORE_REVERSECORRECT = 5
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeReverseAccrual, // TIMING_BEFORE_REVERSEACCRUAL = 6
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforeComplete, // TIMING_BEFORE_COMPLETE = 7
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterPrepare, // TIMING_AFTER_PREPARE = 8
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterComplete, // TIMING_AFTER_COMPLETE = 9
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterVoid, // TIMING_AFTER_VOID = 10
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterClose, // TIMING_AFTER_CLOSE = 11
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterReactivate, // TIMING_AFTER_REACTIVATE = 12
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterReverseCorrect, // TIMING_AFTER_REVERSECORRECT = 13
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterReverseAccrual, // TIMING_AFTER_REVERSEACCRUAL = 14
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentBeforePost, // TIMING_BEFORE_POST = 15
|
||||||
|
X_AD_Table_ScriptValidator.EVENTMODELVALIDATOR_DocumentAfterPost // TIMING_AFTER_POST = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Validation
|
||||||
|
* @param engine validation engine
|
||||||
|
* @param client client
|
||||||
|
*/
|
||||||
|
public void initialize (ModelValidationEngine engine, MClient client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Client to be monitored
|
||||||
|
* @return AD_Client_ID
|
||||||
|
*/
|
||||||
|
public int getAD_Client_ID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User logged in
|
||||||
|
* Called before preferences are set
|
||||||
|
* @param AD_Org_ID org
|
||||||
|
* @param AD_Role_ID role
|
||||||
|
* @param AD_User_ID user
|
||||||
|
* @return error message or null
|
||||||
|
*/
|
||||||
|
public String login (int AD_Org_ID, int AD_Role_ID, int AD_User_ID);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model Change of a monitored Table.
|
||||||
|
* Called after PO.beforeSave/PO.beforeDelete
|
||||||
|
* when you called addModelChange for the table
|
||||||
|
* @param po persistent object
|
||||||
|
* @param type TYPE_
|
||||||
|
* @return error message or null
|
||||||
|
* @exception Exception if the recipient wishes the change to be not accept.
|
||||||
|
*/
|
||||||
|
public String modelChange (PO po, int type) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Document.
|
||||||
|
* Called as first step of DocAction.prepareIt
|
||||||
|
* or at the end of DocAction.completeIt
|
||||||
|
* when you called addDocValidate for the table.
|
||||||
|
* Note that totals, etc. may not be correct before the prepare stage.
|
||||||
|
* @param po persistent object
|
||||||
|
* @param timing see TIMING_ constants
|
||||||
|
* @return error message or null -
|
||||||
|
* if not null, the pocument will be marked as Invalid.
|
||||||
|
*/
|
||||||
|
public String docValidate (PO po, int timing);
|
||||||
|
|
||||||
|
} // ModelValidator
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,212 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import java.math.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice Aging Report.
|
||||||
|
* Based on RV_Aging.
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: Aging.java,v 1.5 2006/10/07 00:58:44 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class Aging extends SvrProcess
|
||||||
|
{
|
||||||
|
/** The date to calculate the days due from */
|
||||||
|
private Timestamp p_StatementDate = null;
|
||||||
|
private boolean p_IsSOTrx = false;
|
||||||
|
private int p_C_Currency_ID = 0;
|
||||||
|
private int p_C_BP_Group_ID = 0;
|
||||||
|
private int p_C_BPartner_ID = 0;
|
||||||
|
private boolean p_IsListInvoices = false;
|
||||||
|
/** Number of days between today and statement date */
|
||||||
|
private int m_statementOffset = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else if (name.equals("StatementDate"))
|
||||||
|
p_StatementDate = (Timestamp)para[i].getParameter();
|
||||||
|
else if (name.equals("IsSOTrx"))
|
||||||
|
p_IsSOTrx = "Y".equals(para[i].getParameter());
|
||||||
|
else if (name.equals("C_Currency_ID"))
|
||||||
|
p_C_Currency_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("C_BP_Group_ID"))
|
||||||
|
p_C_BP_Group_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("C_BPartner_ID"))
|
||||||
|
p_C_BPartner_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("IsListInvoices"))
|
||||||
|
p_IsListInvoices = "Y".equals(para[i].getParameter());
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
if (p_StatementDate == null)
|
||||||
|
p_StatementDate = new Timestamp (System.currentTimeMillis());
|
||||||
|
else
|
||||||
|
m_statementOffset = TimeUtil.getDaysBetween(
|
||||||
|
new Timestamp(System.currentTimeMillis()), p_StatementDate);
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DoIt
|
||||||
|
* @return Message
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception
|
||||||
|
{
|
||||||
|
log.info("StatementDate=" + p_StatementDate + ", IsSOTrx=" + p_IsSOTrx
|
||||||
|
+ ", C_Currency_ID=" + p_C_Currency_ID
|
||||||
|
+ ", C_BP_Group_ID=" + p_C_BP_Group_ID + ", C_BPartner_ID=" + p_C_BPartner_ID
|
||||||
|
+ ", IsListInvoices=" + p_IsListInvoices);
|
||||||
|
//
|
||||||
|
StringBuffer sql = new StringBuffer();
|
||||||
|
sql.append("SELECT bp.C_BP_Group_ID, oi.C_BPartner_ID,oi.C_Invoice_ID,oi.C_InvoicePaySchedule_ID, "
|
||||||
|
+ "oi.C_Currency_ID, oi.IsSOTrx, " // 5..6
|
||||||
|
+ "oi.DateInvoiced, oi.NetDays,oi.DueDate,oi.DaysDue, "); // 7..10
|
||||||
|
if (p_C_Currency_ID == 0)
|
||||||
|
sql.append("oi.GrandTotal, oi.PaidAmt, oi.OpenAmt "); // 11..13
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String s = ",oi.C_Currency_ID," + p_C_Currency_ID + ",oi.DateAcct,oi.C_ConversionType_ID,oi.AD_Client_ID,oi.AD_Org_ID)";
|
||||||
|
sql.append("currencyConvert(oi.GrandTotal").append(s) // 11..
|
||||||
|
.append(", currencyConvert(oi.PaidAmt").append(s)
|
||||||
|
.append(", currencyConvert(oi.OpenAmt").append(s);
|
||||||
|
}
|
||||||
|
sql.append(",oi.C_Activity_ID,oi.C_Campaign_ID,oi.C_Project_ID " // 14
|
||||||
|
+ "FROM RV_OpenItem oi"
|
||||||
|
+ " INNER JOIN C_BPartner bp ON (oi.C_BPartner_ID=bp.C_BPartner_ID) "
|
||||||
|
+ "WHERE oi.ISSoTrx=").append(p_IsSOTrx ? "'Y'" : "'N'");
|
||||||
|
if (p_C_BPartner_ID > 0)
|
||||||
|
sql.append(" AND oi.C_BPartner_ID=").append(p_C_BPartner_ID);
|
||||||
|
else if (p_C_BP_Group_ID > 0)
|
||||||
|
sql.append(" AND bp.C_BP_Group_ID=").append(p_C_BP_Group_ID);
|
||||||
|
sql.append(" ORDER BY oi.C_BPartner_ID, oi.C_Currency_ID, oi.C_Invoice_ID");
|
||||||
|
|
||||||
|
log.finest(sql.toString());
|
||||||
|
String finalSql = MRole.getDefault(getCtx(), false).addAccessSQL(
|
||||||
|
sql.toString(), "oi", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO);
|
||||||
|
log.finer(finalSql);
|
||||||
|
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
//
|
||||||
|
MAging aging = null;
|
||||||
|
int counter = 0;
|
||||||
|
int rows = 0;
|
||||||
|
int AD_PInstance_ID = getAD_PInstance_ID();
|
||||||
|
//
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(finalSql, get_TrxName());
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
int C_BP_Group_ID = rs.getInt(1);
|
||||||
|
int C_BPartner_ID = rs.getInt(2);
|
||||||
|
int C_Invoice_ID = p_IsListInvoices ? rs.getInt(3) : 0;
|
||||||
|
int C_InvoicePaySchedule_ID = p_IsListInvoices ? rs.getInt(4) : 0;
|
||||||
|
int C_Currency_ID = rs.getInt(5);
|
||||||
|
boolean IsSOTrx = "Y".equals(rs.getString(6));
|
||||||
|
//
|
||||||
|
Timestamp DateInvoiced = rs.getTimestamp(7);
|
||||||
|
int NetDays = rs.getInt(8);
|
||||||
|
Timestamp DueDate = rs.getTimestamp(9);
|
||||||
|
// Days Due
|
||||||
|
int DaysDue = rs.getInt(10) // based on today
|
||||||
|
+ m_statementOffset;
|
||||||
|
//
|
||||||
|
BigDecimal GrandTotal = rs.getBigDecimal(11);
|
||||||
|
BigDecimal PaidAmt = rs.getBigDecimal(12);
|
||||||
|
BigDecimal OpenAmt = rs.getBigDecimal(13);
|
||||||
|
//
|
||||||
|
int C_Activity_ID = p_IsListInvoices ? rs.getInt(14) : 0;
|
||||||
|
int C_Campaign_ID = p_IsListInvoices ? rs.getInt(15) : 0;
|
||||||
|
int C_Project_ID = p_IsListInvoices ? rs.getInt(16) : 0;
|
||||||
|
|
||||||
|
rows++;
|
||||||
|
// New Aging Row
|
||||||
|
if (aging == null // Key
|
||||||
|
|| AD_PInstance_ID != aging.getAD_PInstance_ID()
|
||||||
|
|| C_BPartner_ID != aging.getC_BPartner_ID()
|
||||||
|
|| C_Currency_ID != aging.getC_Currency_ID()
|
||||||
|
|| C_Invoice_ID != aging.getC_Invoice_ID()
|
||||||
|
|| C_InvoicePaySchedule_ID != aging.getC_InvoicePaySchedule_ID())
|
||||||
|
{
|
||||||
|
if (aging != null)
|
||||||
|
{
|
||||||
|
if (aging.save())
|
||||||
|
log.fine("#" + ++counter + " - " + aging);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "Not saved " + aging);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aging = new MAging (getCtx(), AD_PInstance_ID, p_StatementDate,
|
||||||
|
C_BPartner_ID, C_Currency_ID,
|
||||||
|
C_Invoice_ID, C_InvoicePaySchedule_ID,
|
||||||
|
C_BP_Group_ID, DueDate, IsSOTrx, get_TrxName());
|
||||||
|
aging.setC_Activity_ID(C_Activity_ID);
|
||||||
|
aging.setC_Campaign_ID(C_Campaign_ID);
|
||||||
|
aging.setC_Project_ID(C_Project_ID);
|
||||||
|
}
|
||||||
|
// Fill Buckets
|
||||||
|
aging.add (DueDate, DaysDue, GrandTotal, OpenAmt);
|
||||||
|
}
|
||||||
|
if (aging != null)
|
||||||
|
{
|
||||||
|
if (aging.save())
|
||||||
|
log.fine("#" + ++counter + " - " + aging);
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Not saved " + aging);
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, finalSql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
log.info("#" + counter + " - rows=" + rows);
|
||||||
|
return "";
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
} // Aging
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,181 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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 *
|
||||||
|
* Portions created by Carlos Ruiz are Copyright (C) 2005 QSS Ltda.
|
||||||
|
* Contributor(s): Carlos Ruiz (globalqss)
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.process;
|
||||||
|
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.logging.*;
|
||||||
|
|
||||||
|
import org.compiere.model.X_M_Product;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Title: Check BOM Structure (free of cycles)
|
||||||
|
* Description:
|
||||||
|
* Tree cannot contain BOMs which are already referenced
|
||||||
|
*
|
||||||
|
* @author Carlos Ruiz (globalqss)
|
||||||
|
* @version $Id: M_Product_BOM_Check.java,v 1.0 2005/09/17 13:32:00 globalqss Exp $
|
||||||
|
* @author Carlos Ruiz (globalqss)
|
||||||
|
* Make T_Selection tables permanent
|
||||||
|
*/
|
||||||
|
public class M_Product_BOM_Check extends SvrProcess
|
||||||
|
{
|
||||||
|
|
||||||
|
/** The Record */
|
||||||
|
private int p_Record_ID = 0;
|
||||||
|
|
||||||
|
private int m_AD_PInstance_ID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
p_Record_ID = getRecord_ID();
|
||||||
|
m_AD_PInstance_ID = getAD_PInstance_ID();
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process
|
||||||
|
* @return message
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception
|
||||||
|
{
|
||||||
|
StringBuffer sql1 = null;
|
||||||
|
int no = 0;
|
||||||
|
|
||||||
|
log.info("Check BOM Structure");
|
||||||
|
|
||||||
|
// Record ID is M_Product_ID of product to be tested
|
||||||
|
X_M_Product xp = new X_M_Product(Env.getCtx(), p_Record_ID, get_TrxName());
|
||||||
|
|
||||||
|
if (! xp.isBOM()) {
|
||||||
|
log.info("NOT BOM Product");
|
||||||
|
// No BOM - should not happen, but no problem
|
||||||
|
xp.setIsVerified(true);
|
||||||
|
xp.save(get_TrxName());
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table to put all BOMs - duplicate will cause exception
|
||||||
|
sql1 = new StringBuffer("DELETE FROM T_Selection2 WHERE Query_ID = 0 AND AD_PInstance_ID="+ m_AD_PInstance_ID);
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
sql1 = new StringBuffer("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) VALUES ("
|
||||||
|
+ m_AD_PInstance_ID
|
||||||
|
+ ", 0, "
|
||||||
|
+ p_Record_ID + ")");
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
// Table of root modes
|
||||||
|
sql1 = new StringBuffer("DELETE FROM T_Selection WHERE AD_PInstance_ID="+ m_AD_PInstance_ID);
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
sql1 = new StringBuffer("INSERT INTO T_Selection (AD_PInstance_ID, T_Selection_ID) VALUES ("
|
||||||
|
+ m_AD_PInstance_ID
|
||||||
|
+ ", "
|
||||||
|
+ p_Record_ID + ")");
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
|
||||||
|
// Get count remaining on t_selection
|
||||||
|
int countno = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PreparedStatement pstmt = DB.prepareStatement
|
||||||
|
("SELECT COUNT(*) FROM T_Selection WHERE AD_PInstance_ID="+ m_AD_PInstance_ID, get_TrxName());
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
if (rs.next())
|
||||||
|
countno = rs.getInt(1);
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
throw new Exception ("count t_selection", e);
|
||||||
|
}
|
||||||
|
log.fine("Count T_Selection =" + countno);
|
||||||
|
|
||||||
|
if (countno == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// if any command fails (no==-1) break and inform failure
|
||||||
|
// Insert BOM Nodes into "All" table
|
||||||
|
sql1 = new StringBuffer("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) "
|
||||||
|
+ "SELECT " + m_AD_PInstance_ID + ", 0, p.M_Product_ID FROM M_Product p WHERE IsBOM='Y' AND EXISTS "
|
||||||
|
+ "(SELECT * FROM M_Product_BOM b WHERE p.M_Product_ID=b.M_ProductBOM_ID AND b.M_Product_ID IN "
|
||||||
|
+ "(SELECT T_Selection_ID FROM T_Selection WHERE AD_PInstance_ID="+ m_AD_PInstance_ID + "))");
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString());
|
||||||
|
// Insert BOM Nodes into temporary table
|
||||||
|
sql1 = new StringBuffer("DELETE FROM T_Selection2 WHERE Query_ID = 1 AND AD_PInstance_ID="+ m_AD_PInstance_ID);
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString());
|
||||||
|
sql1 = new StringBuffer("INSERT INTO T_Selection2 (AD_PInstance_ID, Query_ID, T_Selection_ID) "
|
||||||
|
+ "SELECT " + m_AD_PInstance_ID + ", 1, p.M_Product_ID FROM M_Product p WHERE IsBOM='Y' AND EXISTS "
|
||||||
|
+ "(SELECT * FROM M_Product_BOM b WHERE p.M_Product_ID=b.M_ProductBOM_ID AND b.M_Product_ID IN "
|
||||||
|
+ "(SELECT T_Selection_ID FROM T_Selection WHERE AD_PInstance_ID="+ m_AD_PInstance_ID + "))");
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString());
|
||||||
|
// Copy into root table
|
||||||
|
sql1 = new StringBuffer("DELETE FROM T_Selection WHERE AD_PInstance_ID="+ m_AD_PInstance_ID);
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString());
|
||||||
|
sql1 = new StringBuffer("INSERT INTO T_Selection (AD_PInstance_ID, T_Selection_ID) "
|
||||||
|
+ "SELECT " + m_AD_PInstance_ID + ", T_Selection_ID "
|
||||||
|
+ "FROM T_Selection2 WHERE Query_ID = 1 AND AD_PInstance_ID="+ m_AD_PInstance_ID);
|
||||||
|
no = DB.executeUpdate(sql1.toString(), get_TrxName());
|
||||||
|
if (no == -1) raiseError("InsertingRoot:ERROR", sql1.toString());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new Exception ("root insert", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish process
|
||||||
|
xp.setIsVerified(true);
|
||||||
|
xp.save(get_TrxName());
|
||||||
|
return "OK";
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
private void raiseError(String string, String sql) throws Exception {
|
||||||
|
DB.rollback(false, get_TrxName());
|
||||||
|
String msg = string;
|
||||||
|
ValueNamePair pp = CLogger.retrieveError();
|
||||||
|
if (pp != null)
|
||||||
|
msg = pp.getName() + " - ";
|
||||||
|
msg += sql;
|
||||||
|
throw new AdempiereUserError (msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // M_Product_BOM_Check
|
|
@ -0,0 +1,160 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Order Batch Processing
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: OrderBatchProcess.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class OrderBatchProcess extends SvrProcess
|
||||||
|
{
|
||||||
|
private int p_C_DocTypeTarget_ID = 0;
|
||||||
|
private String p_DocStatus = null;
|
||||||
|
private int p_C_BPartner_ID = 0;
|
||||||
|
private String p_IsSelfService = null;
|
||||||
|
private Timestamp p_DateOrdered_From = null;
|
||||||
|
private Timestamp p_DateOrdered_To = null;
|
||||||
|
private String p_DocAction = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare
|
||||||
|
*/
|
||||||
|
protected void prepare ()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else if (name.equals("C_DocTypeTarget_ID"))
|
||||||
|
p_C_DocTypeTarget_ID = para[i].getParameterAsInt();
|
||||||
|
else if (name.equals("DocStatus"))
|
||||||
|
p_DocStatus = (String)para[i].getParameter();
|
||||||
|
else if (name.equals("IsSelfService"))
|
||||||
|
p_IsSelfService = (String)para[i].getParameter();
|
||||||
|
else if (name.equals("C_BPartner_ID"))
|
||||||
|
p_C_BPartner_ID = para[i].getParameterAsInt();
|
||||||
|
else if (name.equals("DateOrdered"))
|
||||||
|
{
|
||||||
|
p_DateOrdered_From = (Timestamp)para[i].getParameter();
|
||||||
|
p_DateOrdered_To = (Timestamp)para[i].getParameter_To();
|
||||||
|
}
|
||||||
|
else if (name.equals("DocAction"))
|
||||||
|
p_DocAction = (String)para[i].getParameter();
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process
|
||||||
|
* @return msg
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
protected String doIt () throws Exception
|
||||||
|
{
|
||||||
|
log.info("C_DocTypeTarget_ID=" + p_C_DocTypeTarget_ID + ", DocStatus=" + p_DocStatus
|
||||||
|
+ ", IsSelfService=" + p_IsSelfService + ", C_BPartner_ID=" + p_C_BPartner_ID
|
||||||
|
+ ", DateOrdered=" + p_DateOrdered_From + "->" + p_DateOrdered_To
|
||||||
|
+ ", DocAction=" + p_DocAction);
|
||||||
|
|
||||||
|
if (p_C_DocTypeTarget_ID == 0)
|
||||||
|
throw new AdempiereUserError("@NotFound@: @C_DocTypeTarget_ID@");
|
||||||
|
if (p_DocStatus == null || p_DocStatus.length() != 2)
|
||||||
|
throw new AdempiereUserError("@NotFound@: @DocStatus@");
|
||||||
|
if (p_DocAction == null || p_DocAction.length() != 2)
|
||||||
|
throw new AdempiereUserError("@NotFound@: @DocAction@");
|
||||||
|
|
||||||
|
//
|
||||||
|
StringBuffer sql = new StringBuffer("SELECT * FROM C_Order "
|
||||||
|
+ "WHERE C_DocTypeTarget_ID=? AND DocStatus=?");
|
||||||
|
if (p_IsSelfService != null && p_IsSelfService.length() == 1)
|
||||||
|
sql.append(" AND IsSelfService='").append(p_IsSelfService).append("'");
|
||||||
|
if (p_C_BPartner_ID != 0)
|
||||||
|
sql.append(" AND C_BPartner_ID=").append(p_C_BPartner_ID);
|
||||||
|
if (p_DateOrdered_From != null)
|
||||||
|
sql.append(" AND TRUNC(DateOrdered) >= ").append(DB.TO_DATE(p_DateOrdered_From, true));
|
||||||
|
if (p_DateOrdered_To != null)
|
||||||
|
sql.append(" AND TRUNC(DateOrdered) <= ").append(DB.TO_DATE(p_DateOrdered_To, true));
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
int errCounter = 0;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
|
||||||
|
pstmt.setInt(1, p_C_DocTypeTarget_ID);
|
||||||
|
pstmt.setString(2, p_DocStatus);
|
||||||
|
ResultSet rs = pstmt.executeQuery();
|
||||||
|
while (rs.next())
|
||||||
|
{
|
||||||
|
if (process(new MOrder(getCtx(),rs, get_TrxName())))
|
||||||
|
counter++;
|
||||||
|
else
|
||||||
|
errCounter++;
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql.toString(), e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
return "@Updated@=" + counter + ", @Errors@=" + errCounter;
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process Order
|
||||||
|
* @param order order
|
||||||
|
* @return true if ok
|
||||||
|
*/
|
||||||
|
private boolean process (MOrder order)
|
||||||
|
{
|
||||||
|
log.info(order.toString());
|
||||||
|
//
|
||||||
|
order.setDocAction(p_DocAction);
|
||||||
|
if (order.processIt(p_DocAction))
|
||||||
|
{
|
||||||
|
order.save();
|
||||||
|
addLog(0, null, null, order.getDocumentNo() + ": OK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
addLog (0, null, null, order.getDocumentNo() + ": Error " + order.getProcessMsg());
|
||||||
|
return false;
|
||||||
|
} // process
|
||||||
|
|
||||||
|
} // OrderBatchProcess
|
|
@ -0,0 +1,72 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-Open Order Process (from Closed to Completed)
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: OrderOpen.java,v 1.2 2006/07/30 00:51:02 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class OrderOpen extends SvrProcess
|
||||||
|
{
|
||||||
|
/** The Order */
|
||||||
|
private int p_C_Order_ID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else if (name.equals("C_Order_ID"))
|
||||||
|
p_C_Order_ID = para[i].getParameterAsInt();
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "prepare - Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perrform process.
|
||||||
|
* @return Message
|
||||||
|
* @throws Exception if not successful
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception
|
||||||
|
{
|
||||||
|
log.info("doIt - Open C_Order_ID=" + p_C_Order_ID);
|
||||||
|
if (p_C_Order_ID == 0)
|
||||||
|
throw new IllegalArgumentException("C_Order_ID == 0");
|
||||||
|
//
|
||||||
|
MOrder order = new MOrder (getCtx(), p_C_Order_ID, get_TrxName());
|
||||||
|
if (MOrder.DOCSTATUS_Closed.equals(order.getDocStatus()))
|
||||||
|
{
|
||||||
|
order.setDocStatus(MOrder.DOCSTATUS_Completed);
|
||||||
|
return order.save() ? "@OK@" : "@Error@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new IllegalStateException("Order is not closed");
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
} // OrderOpen
|
|
@ -0,0 +1,288 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.process;
|
||||||
|
|
||||||
|
import java.awt.geom.IllegalPathStateException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.compiere.model.MBPartner;
|
||||||
|
import org.compiere.model.MOrder;
|
||||||
|
import org.compiere.model.MOrderLine;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate PO from Sales Order
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: OrderPOCreate.java,v 1.2 2006/07/30 00:51:01 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class OrderPOCreate extends SvrProcess
|
||||||
|
{
|
||||||
|
/** Order Date From */
|
||||||
|
private Timestamp p_DateOrdered_From;
|
||||||
|
/** Order Date To */
|
||||||
|
private Timestamp p_DateOrdered_To;
|
||||||
|
/** Customer */
|
||||||
|
private int p_C_BPartner_ID;
|
||||||
|
/** Vendor */
|
||||||
|
private int p_Vendor_ID;
|
||||||
|
/** Sales Order */
|
||||||
|
private int p_C_Order_ID;
|
||||||
|
/** Drop Ship */
|
||||||
|
private String p_IsDropShip;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else if (name.equals("DateOrdered"))
|
||||||
|
{
|
||||||
|
p_DateOrdered_From = (Timestamp)para[i].getParameter();
|
||||||
|
p_DateOrdered_To = (Timestamp)para[i].getParameter_To();
|
||||||
|
}
|
||||||
|
else if (name.equals("C_BPartner_ID"))
|
||||||
|
p_C_BPartner_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("Vendor_ID"))
|
||||||
|
p_Vendor_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("C_Order_ID"))
|
||||||
|
p_C_Order_ID = ((BigDecimal)para[i].getParameter()).intValue();
|
||||||
|
else if (name.equals("IsDropShip"))
|
||||||
|
p_IsDropShip = (String)para[i].getParameter();
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perrform process.
|
||||||
|
* @return Message
|
||||||
|
* @throws Exception if not successful
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception
|
||||||
|
{
|
||||||
|
log.info("DateOrdered=" + p_DateOrdered_From + " - " + p_DateOrdered_To
|
||||||
|
+ " - C_BPartner_ID=" + p_C_BPartner_ID + " - Vendor_ID=" + p_Vendor_ID
|
||||||
|
+ " - IsDropShip=" + p_IsDropShip + " - C_Order_ID=" + p_C_Order_ID);
|
||||||
|
if (p_C_Order_ID == 0 && p_IsDropShip == null
|
||||||
|
&& p_DateOrdered_From == null && p_DateOrdered_To == null
|
||||||
|
&& p_C_BPartner_ID == 0 && p_Vendor_ID == 0)
|
||||||
|
throw new IllegalPathStateException("You need to restrict selection");
|
||||||
|
//
|
||||||
|
String sql = "SELECT * FROM C_Order o "
|
||||||
|
+ "WHERE o.IsSOTrx='Y'"
|
||||||
|
// No Duplicates
|
||||||
|
// " AND o.Ref_Order_ID IS NULL"
|
||||||
|
+ " AND NOT EXISTS (SELECT * FROM C_OrderLine ol WHERE o.C_Order_ID=ol.C_Order_ID AND ol.Ref_OrderLine_ID IS NOT NULL)"
|
||||||
|
;
|
||||||
|
if (p_C_Order_ID != 0)
|
||||||
|
sql += " AND o.C_Order_ID=?";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p_C_BPartner_ID != 0)
|
||||||
|
sql += " AND o.C_BPartner_ID=?";
|
||||||
|
if (p_IsDropShip != null)
|
||||||
|
sql += " AND o.IsDropShip=?";
|
||||||
|
if (p_Vendor_ID != 0)
|
||||||
|
sql += " AND EXISTS (SELECT * FROM C_OrderLine ol"
|
||||||
|
+ " INNER JOIN M_Product_PO po ON (ol.M_Product_ID=po.M_Product_ID) "
|
||||||
|
+ "WHERE o.C_Order_ID=ol.C_Order_ID AND po.C_BPartner_ID=?)";
|
||||||
|
if (p_DateOrdered_From != null && p_DateOrdered_To != null)
|
||||||
|
sql += "AND TRUNC(o.DateOrdered) BETWEEN ? AND ?";
|
||||||
|
else if (p_DateOrdered_From != null && p_DateOrdered_To == null)
|
||||||
|
sql += "AND TRUNC(o.DateOrdered) >= ?";
|
||||||
|
else if (p_DateOrdered_From == null && p_DateOrdered_To != null)
|
||||||
|
sql += "AND TRUNC(o.DateOrdered) <= ?";
|
||||||
|
}
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
int counter = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
if (p_C_Order_ID != 0)
|
||||||
|
pstmt.setInt (1, p_C_Order_ID);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = 1;
|
||||||
|
if (p_C_BPartner_ID != 0)
|
||||||
|
pstmt.setInt (index++, p_C_BPartner_ID);
|
||||||
|
if (p_IsDropShip != null)
|
||||||
|
pstmt.setString(index++, p_IsDropShip);
|
||||||
|
if (p_Vendor_ID != 0)
|
||||||
|
pstmt.setInt (index++, p_Vendor_ID);
|
||||||
|
if (p_DateOrdered_From != null && p_DateOrdered_To != null)
|
||||||
|
{
|
||||||
|
pstmt.setTimestamp(index++, p_DateOrdered_From);
|
||||||
|
pstmt.setTimestamp(index++, p_DateOrdered_To);
|
||||||
|
}
|
||||||
|
else if (p_DateOrdered_From != null && p_DateOrdered_To == null)
|
||||||
|
pstmt.setTimestamp(index++, p_DateOrdered_From);
|
||||||
|
else if (p_DateOrdered_From == null && p_DateOrdered_To != null)
|
||||||
|
pstmt.setTimestamp(index++, p_DateOrdered_To);
|
||||||
|
}
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
{
|
||||||
|
counter += createPOFromSO (new MOrder (getCtx(), rs, get_TrxName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
if (counter == 0)
|
||||||
|
log.fine(sql);
|
||||||
|
return "@Created@ " + counter;
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PO From SO
|
||||||
|
* @param so sales order
|
||||||
|
* @return number of POs created
|
||||||
|
*/
|
||||||
|
private int createPOFromSO (MOrder so)
|
||||||
|
{
|
||||||
|
log.info(so.toString());
|
||||||
|
MOrderLine[] soLines = so.getLines(true, null);
|
||||||
|
if (soLines == null || soLines.length == 0)
|
||||||
|
{
|
||||||
|
log.warning("No Lines - " + so);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
int counter = 0;
|
||||||
|
// Order Lines with a Product which has a current vendor
|
||||||
|
String sql = "SELECT DISTINCT po.C_BPartner_ID, po.M_Product_ID "
|
||||||
|
+ "FROM M_Product_PO po"
|
||||||
|
+ " INNER JOIN C_OrderLine ol ON (po.M_Product_ID=ol.M_Product_ID) "
|
||||||
|
+ "WHERE ol.C_Order_ID=? AND po.IsCurrentVendor='Y' "
|
||||||
|
+ "ORDER BY 1";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
MOrder po = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, so.getC_Order_ID());
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
{
|
||||||
|
// New Order
|
||||||
|
int C_BPartner_ID = rs.getInt(1);
|
||||||
|
if (po == null || po.getBill_BPartner_ID() != C_BPartner_ID)
|
||||||
|
{
|
||||||
|
po = createPOForVendor(rs.getInt(1), so);
|
||||||
|
addLog(0, null, null, po.getDocumentNo());
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line
|
||||||
|
int M_Product_ID = rs.getInt(2);
|
||||||
|
for (int i = 0; i < soLines.length; i++)
|
||||||
|
{
|
||||||
|
if (soLines[i].getM_Product_ID() == M_Product_ID)
|
||||||
|
{
|
||||||
|
MOrderLine poLine = new MOrderLine (po);
|
||||||
|
poLine.setRef_OrderLine_ID(soLines[i].getC_OrderLine_ID());
|
||||||
|
poLine.setM_Product_ID(soLines[i].getM_Product_ID());
|
||||||
|
poLine.setM_AttributeSetInstance_ID(soLines[i].getM_AttributeSetInstance_ID());
|
||||||
|
poLine.setC_UOM_ID(soLines[i].getC_UOM_ID());
|
||||||
|
poLine.setQtyEntered(soLines[i].getQtyEntered());
|
||||||
|
poLine.setQtyOrdered(soLines[i].getQtyOrdered());
|
||||||
|
poLine.setDescription(soLines[i].getDescription());
|
||||||
|
poLine.setDatePromised(soLines[i].getDatePromised());
|
||||||
|
poLine.setPrice();
|
||||||
|
poLine.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
// Set Reference to PO
|
||||||
|
if (counter == 1 && po != null)
|
||||||
|
{
|
||||||
|
so.setRef_Order_ID(po.getC_Order_ID());
|
||||||
|
so.save();
|
||||||
|
}
|
||||||
|
return counter;
|
||||||
|
} // createPOFromSO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PO for Vendor
|
||||||
|
* @param C_BPartner_ID vendor
|
||||||
|
* @param so sales order
|
||||||
|
*/
|
||||||
|
public MOrder createPOForVendor(int C_BPartner_ID, MOrder so)
|
||||||
|
{
|
||||||
|
MOrder po = new MOrder (getCtx(), 0, get_TrxName());
|
||||||
|
po.setClientOrg(so.getAD_Client_ID(), so.getAD_Org_ID());
|
||||||
|
po.setRef_Order_ID(so.getC_Order_ID());
|
||||||
|
po.setIsSOTrx(false);
|
||||||
|
po.setC_DocTypeTarget_ID();
|
||||||
|
//
|
||||||
|
po.setDescription(so.getDescription());
|
||||||
|
po.setPOReference(so.getDocumentNo());
|
||||||
|
po.setPriorityRule(so.getPriorityRule());
|
||||||
|
po.setSalesRep_ID(so.getSalesRep_ID());
|
||||||
|
po.setM_Warehouse_ID(so.getM_Warehouse_ID());
|
||||||
|
// Set Vendor
|
||||||
|
MBPartner vendor = new MBPartner (getCtx(), C_BPartner_ID, get_TrxName());
|
||||||
|
po.setBPartner(vendor);
|
||||||
|
// Drop Ship
|
||||||
|
po.setIsDropShip(so.isDropShip());
|
||||||
|
if (so.isDropShip())
|
||||||
|
{
|
||||||
|
po.setShip_BPartner_ID(so.getC_BPartner_ID());
|
||||||
|
po.setShip_Location_ID(so.getC_BPartner_Location_ID());
|
||||||
|
po.setShip_User_ID(so.getAD_User_ID());
|
||||||
|
}
|
||||||
|
// References
|
||||||
|
po.setC_Activity_ID(so.getC_Activity_ID());
|
||||||
|
po.setC_Campaign_ID(so.getC_Campaign_ID());
|
||||||
|
po.setC_Project_ID(so.getC_Project_ID());
|
||||||
|
po.setUser1_ID(so.getUser1_ID());
|
||||||
|
po.setUser2_ID(so.getUser2_ID());
|
||||||
|
//
|
||||||
|
po.save();
|
||||||
|
return po;
|
||||||
|
} // createPOForVendor
|
||||||
|
|
||||||
|
} // doIt
|
|
@ -0,0 +1,594 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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 *
|
||||||
|
* Contributor(s): Chris Farley - northernbrewer *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.compiere.process;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.math.*;
|
||||||
|
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replenishment Report
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: ReplenishReport.java,v 1.2 2006/07/30 00:51:01 jjanke Exp $
|
||||||
|
*
|
||||||
|
* Carlos Ruiz globalqss - integrate bug fixing from Chris Farley
|
||||||
|
* [ 1619517 ] Replenish report fails when no records in m_storage
|
||||||
|
*/
|
||||||
|
public class ReplenishReport extends SvrProcess
|
||||||
|
{
|
||||||
|
/** Warehouse */
|
||||||
|
private int p_M_Warehouse_ID = 0;
|
||||||
|
/** Optional BPartner */
|
||||||
|
private int p_C_BPartner_ID = 0;
|
||||||
|
/** Create (POO)Purchse Order or (POR)Requisition or (MMM)Movements */
|
||||||
|
private String p_ReplenishmentCreate = null;
|
||||||
|
/** Document Type */
|
||||||
|
private int p_C_DocType_ID = 0;
|
||||||
|
/** Return Info */
|
||||||
|
private String m_info = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare - e.g., get Parameters.
|
||||||
|
*/
|
||||||
|
protected void prepare()
|
||||||
|
{
|
||||||
|
ProcessInfoParameter[] para = getParameter();
|
||||||
|
for (int i = 0; i < para.length; i++)
|
||||||
|
{
|
||||||
|
String name = para[i].getParameterName();
|
||||||
|
if (para[i].getParameter() == null)
|
||||||
|
;
|
||||||
|
else if (name.equals("M_Warehouse_ID"))
|
||||||
|
p_M_Warehouse_ID = para[i].getParameterAsInt();
|
||||||
|
else if (name.equals("C_BPartner_ID"))
|
||||||
|
p_C_BPartner_ID = para[i].getParameterAsInt();
|
||||||
|
else if (name.equals("ReplenishmentCreate"))
|
||||||
|
p_ReplenishmentCreate = (String)para[i].getParameter();
|
||||||
|
else if (name.equals("C_DocType_ID"))
|
||||||
|
p_C_DocType_ID = para[i].getParameterAsInt();
|
||||||
|
else
|
||||||
|
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||||
|
}
|
||||||
|
} // prepare
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perrform process.
|
||||||
|
* @return Message
|
||||||
|
* @throws Exception if not successful
|
||||||
|
*/
|
||||||
|
protected String doIt() throws Exception
|
||||||
|
{
|
||||||
|
log.info("M_Warehouse_ID=" + p_M_Warehouse_ID
|
||||||
|
+ ", C_BPartner_ID=" + p_C_BPartner_ID
|
||||||
|
+ " - ReplenishmentCreate=" + p_ReplenishmentCreate
|
||||||
|
+ ", C_DocType_ID=" + p_C_DocType_ID);
|
||||||
|
if (p_ReplenishmentCreate != null && p_C_DocType_ID == 0)
|
||||||
|
throw new AdempiereUserError("@FillMandatory@ @C_DocType_ID@");
|
||||||
|
|
||||||
|
MWarehouse wh = MWarehouse.get(getCtx(), p_M_Warehouse_ID);
|
||||||
|
if (wh.get_ID() == 0)
|
||||||
|
throw new AdempiereSystemError("@FillMandatory@ @M_Warehouse_ID@");
|
||||||
|
//
|
||||||
|
prepareTable();
|
||||||
|
fillTable(wh);
|
||||||
|
//
|
||||||
|
if (p_ReplenishmentCreate == null)
|
||||||
|
return "OK";
|
||||||
|
//
|
||||||
|
MDocType dt = MDocType.get(getCtx(), p_C_DocType_ID);
|
||||||
|
if (!dt.getDocBaseType().equals(p_ReplenishmentCreate))
|
||||||
|
throw new AdempiereSystemError("@C_DocType_ID@=" + dt.getName() + " <> " + p_ReplenishmentCreate);
|
||||||
|
//
|
||||||
|
if (p_ReplenishmentCreate.equals("POO"))
|
||||||
|
createPO();
|
||||||
|
else if (p_ReplenishmentCreate.equals("POR"))
|
||||||
|
createRequisition();
|
||||||
|
else if (p_ReplenishmentCreate.equals("MMM"))
|
||||||
|
createMovements();
|
||||||
|
return m_info;
|
||||||
|
} // doIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare/Check Replenishment Table
|
||||||
|
*/
|
||||||
|
private void prepareTable()
|
||||||
|
{
|
||||||
|
// Level_Max must be >= Level_Max
|
||||||
|
String sql = "UPDATE M_Replenish"
|
||||||
|
+ " SET Level_Max = Level_Min "
|
||||||
|
+ "WHERE Level_Max < Level_Min";
|
||||||
|
int no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Corrected Max_Level=" + no);
|
||||||
|
|
||||||
|
// Minimum Order should be 1
|
||||||
|
sql = "UPDATE M_Product_PO"
|
||||||
|
+ " SET Order_Min = 1 "
|
||||||
|
+ "WHERE Order_Min IS NULL OR Order_Min < 1";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Corrected Order Min=" + no);
|
||||||
|
|
||||||
|
// Pack should be 1
|
||||||
|
sql = "UPDATE M_Product_PO"
|
||||||
|
+ " SET Order_Pack = 1 "
|
||||||
|
+ "WHERE Order_Pack IS NULL OR Order_Pack < 1";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Corrected Order Pack=" + no);
|
||||||
|
|
||||||
|
// Set Current Vendor where only one vendor
|
||||||
|
sql = "UPDATE M_Product_PO p"
|
||||||
|
+ " SET IsCurrentVendor='Y' "
|
||||||
|
+ "WHERE IsCurrentVendor<>'Y'"
|
||||||
|
+ " AND EXISTS (SELECT pp.M_Product_ID FROM M_Product_PO pp "
|
||||||
|
+ "WHERE p.M_Product_ID=pp.M_Product_ID "
|
||||||
|
+ "GROUP BY pp.M_Product_ID "
|
||||||
|
+ "HAVING COUNT(*) = 1)";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Corrected CurrentVendor(Y)=" + no);
|
||||||
|
|
||||||
|
// More then one current vendor
|
||||||
|
sql = "UPDATE M_Product_PO p"
|
||||||
|
+ " SET IsCurrentVendor='N' "
|
||||||
|
+ "WHERE IsCurrentVendor = 'Y'"
|
||||||
|
+ " AND EXISTS (SELECT pp.M_Product_ID FROM M_Product_PO pp "
|
||||||
|
+ "WHERE p.M_Product_ID=pp.M_Product_ID AND pp.IsCurrentVendor='Y' "
|
||||||
|
+ "GROUP BY pp.M_Product_ID "
|
||||||
|
+ "HAVING COUNT(*) > 1)";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Corrected CurrentVendor(N)=" + no);
|
||||||
|
|
||||||
|
// Just to be sure
|
||||||
|
sql = "DELETE T_Replenish WHERE AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Delete Existing Temp=" + no);
|
||||||
|
} // prepareTable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill Table
|
||||||
|
* @param wh warehouse
|
||||||
|
*/
|
||||||
|
private void fillTable (MWarehouse wh) throws Exception
|
||||||
|
{
|
||||||
|
String sql = "INSERT INTO T_Replenish "
|
||||||
|
+ "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID,"
|
||||||
|
+ " ReplenishType, Level_Min, Level_Max,"
|
||||||
|
+ " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate) "
|
||||||
|
+ "SELECT " + getAD_PInstance_ID()
|
||||||
|
+ ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID,"
|
||||||
|
+ " r.ReplenishType, r.Level_Min, r.Level_Max,"
|
||||||
|
+ " po.C_BPartner_ID, po.Order_Min, po.Order_Pack, 0, ";
|
||||||
|
if (p_ReplenishmentCreate == null)
|
||||||
|
sql += "null";
|
||||||
|
else
|
||||||
|
sql += "'" + p_ReplenishmentCreate + "'";
|
||||||
|
sql += " FROM M_Replenish r"
|
||||||
|
+ " INNER JOIN M_Product_PO po ON (r.M_Product_ID=po.M_Product_ID) "
|
||||||
|
+ "WHERE po.IsCurrentVendor='Y'" // Only Current Vendor
|
||||||
|
+ " AND r.ReplenishType<>'0'"
|
||||||
|
+ " AND po.IsActive='Y' AND r.IsActive='Y'"
|
||||||
|
+ " AND r.M_Warehouse_ID=" + p_M_Warehouse_ID;
|
||||||
|
if (p_C_BPartner_ID != 0)
|
||||||
|
sql += " AND po.C_BPartner_ID=" + p_C_BPartner_ID;
|
||||||
|
int no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
log.finest(sql);
|
||||||
|
log.fine("Insert (1) #" + no);
|
||||||
|
|
||||||
|
if (p_C_BPartner_ID == 0)
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO T_Replenish "
|
||||||
|
+ "(AD_PInstance_ID, M_Warehouse_ID, M_Product_ID, AD_Client_ID, AD_Org_ID,"
|
||||||
|
+ " ReplenishType, Level_Min, Level_Max,"
|
||||||
|
+ " C_BPartner_ID, Order_Min, Order_Pack, QtyToOrder, ReplenishmentCreate) "
|
||||||
|
+ "SELECT " + getAD_PInstance_ID()
|
||||||
|
+ ", r.M_Warehouse_ID, r.M_Product_ID, r.AD_Client_ID, r.AD_Org_ID,"
|
||||||
|
+ " r.ReplenishType, r.Level_Min, r.Level_Max,"
|
||||||
|
+ " 0, 1, 1, 0, ";
|
||||||
|
if (p_ReplenishmentCreate == null)
|
||||||
|
sql += "null";
|
||||||
|
else
|
||||||
|
sql += "'" + p_ReplenishmentCreate + "'";
|
||||||
|
sql += " FROM M_Replenish r "
|
||||||
|
+ "WHERE r.ReplenishType<>'0' AND r.IsActive='Y'"
|
||||||
|
+ " AND r.M_Warehouse_ID=" + p_M_Warehouse_ID
|
||||||
|
+ " AND NOT EXISTS (SELECT * FROM T_Replenish t "
|
||||||
|
+ "WHERE r.M_Product_ID=t.M_Product_ID"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID() + ")";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
log.fine("Insert (BP) #" + no);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = "UPDATE T_Replenish t SET "
|
||||||
|
+ "QtyOnHand = (SELECT COALESCE(SUM(QtyOnHand),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
|
||||||
|
+ " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID),"
|
||||||
|
+ "QtyReserved = (SELECT COALESCE(SUM(QtyReserved),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
|
||||||
|
+ " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID),"
|
||||||
|
+ "QtyOrdered = (SELECT COALESCE(SUM(QtyOrdered),0) FROM M_Storage s, M_Locator l WHERE t.M_Product_ID=s.M_Product_ID"
|
||||||
|
+ " AND l.M_Locator_ID=s.M_Locator_ID AND l.M_Warehouse_ID=t.M_Warehouse_ID)";
|
||||||
|
if (p_C_DocType_ID != 0)
|
||||||
|
sql += ", C_DocType_ID=" + p_C_DocType_ID;
|
||||||
|
sql += " WHERE AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Update #" + no);
|
||||||
|
|
||||||
|
// Delete inactive products and replenishments
|
||||||
|
sql = "DELETE T_Replenish r "
|
||||||
|
+ "WHERE (EXISTS (SELECT * FROM M_Product p "
|
||||||
|
+ "WHERE p.M_Product_ID=r.M_Product_ID AND p.IsActive='N')"
|
||||||
|
+ " OR EXISTS (SELECT * FROM M_Replenish rr "
|
||||||
|
+ " WHERE rr.M_Product_ID=r.M_Product_ID AND rr.IsActive='N'))"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Delete Inactive=" + no);
|
||||||
|
|
||||||
|
// Ensure Data consistency
|
||||||
|
sql = "UPDATE T_Replenish SET QtyOnHand = 0 WHERE QtyOnHand IS NULL";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
sql = "UPDATE T_Replenish SET QtyReserved = 0 WHERE QtyReserved IS NULL";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
sql = "UPDATE T_Replenish SET QtyOrdered = 0 WHERE QtyOrdered IS NULL";
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
|
||||||
|
// Set Minimum / Maximum Maintain Level
|
||||||
|
// X_M_Replenish.REPLENISHTYPE_ReorderBelowMinimumLevel
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET QtyToOrder = CASE WHEN QtyOnHand - QtyReserved + QtyOrdered <= Level_Min "
|
||||||
|
+ " THEN Level_Max - QtyOnHand + QtyReserved - QtyOrdered "
|
||||||
|
+ " ELSE 0 END "
|
||||||
|
+ "WHERE ReplenishType='1'"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Update Type-1=" + no);
|
||||||
|
//
|
||||||
|
// X_M_Replenish.REPLENISHTYPE_MaintainMaximumLevel
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET QtyToOrder = Level_Max - QtyOnHand + QtyReserved - QtyOrdered "
|
||||||
|
+ "WHERE ReplenishType='2'"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Update Type-2=" + no);
|
||||||
|
|
||||||
|
|
||||||
|
// Minimum Order Quantity
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET QtyToOrder = Order_Min "
|
||||||
|
+ "WHERE QtyToOrder < Order_Min"
|
||||||
|
+ " AND QtyToOrder > 0"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Set MinOrderQty=" + no);
|
||||||
|
|
||||||
|
// Even dividable by Pack
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET QtyToOrder = QtyToOrder - MOD(QtyToOrder, Order_Pack) + Order_Pack "
|
||||||
|
+ "WHERE MOD(QtyToOrder, Order_Pack) <> 0"
|
||||||
|
+ " AND QtyToOrder > 0"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Set OrderPackQty=" + no);
|
||||||
|
|
||||||
|
// Source from other warehouse
|
||||||
|
if (wh.getM_WarehouseSource_ID() != 0)
|
||||||
|
{
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET M_WarehouseSource_ID=" + wh.getM_WarehouseSource_ID()
|
||||||
|
+ " WHERE AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Set Source Warehouse=" + no);
|
||||||
|
}
|
||||||
|
// Check Source Warehouse
|
||||||
|
sql = "UPDATE T_Replenish"
|
||||||
|
+ " SET M_WarehouseSource_ID = NULL "
|
||||||
|
+ "WHERE M_Warehouse_ID=M_WarehouseSource_ID"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Set same Source Warehouse=" + no);
|
||||||
|
|
||||||
|
// Custom Replenishment
|
||||||
|
String className = wh.getReplenishmentClass();
|
||||||
|
if (className != null && className.length() > 0)
|
||||||
|
{
|
||||||
|
// Get Replenishment Class
|
||||||
|
ReplenishInterface custom = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> clazz = Class.forName(className);
|
||||||
|
custom = (ReplenishInterface)clazz.newInstance();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new AdempiereUserError("No custom Replenishment class "
|
||||||
|
+ className + " - " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
X_T_Replenish[] replenishs = getReplenish("ReplenishType='9'");
|
||||||
|
for (int i = 0; i < replenishs.length; i++)
|
||||||
|
{
|
||||||
|
X_T_Replenish replenish = replenishs[i];
|
||||||
|
if (replenish.getReplenishType().equals(X_T_Replenish.REPLENISHTYPE_Custom))
|
||||||
|
{
|
||||||
|
BigDecimal qto = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
qto = custom.getQtyToOrder(wh, replenish);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, custom.toString(), e);
|
||||||
|
}
|
||||||
|
if (qto == null)
|
||||||
|
qto = Env.ZERO;
|
||||||
|
replenish.setQtyToOrder(qto);
|
||||||
|
replenish.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Delete rows where nothing to order
|
||||||
|
sql = "DELETE T_Replenish "
|
||||||
|
+ "WHERE QtyToOrder < 1"
|
||||||
|
+ " AND AD_PInstance_ID=" + getAD_PInstance_ID();
|
||||||
|
no = DB.executeUpdate(sql, get_TrxName());
|
||||||
|
if (no != 0)
|
||||||
|
log.fine("Delete No QtyToOrder=" + no);
|
||||||
|
} // fillTable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PO's
|
||||||
|
*/
|
||||||
|
private void createPO()
|
||||||
|
{
|
||||||
|
int noOrders = 0;
|
||||||
|
String info = "";
|
||||||
|
//
|
||||||
|
MOrder order = null;
|
||||||
|
MWarehouse wh = null;
|
||||||
|
X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL");
|
||||||
|
for (int i = 0; i < replenishs.length; i++)
|
||||||
|
{
|
||||||
|
X_T_Replenish replenish = replenishs[i];
|
||||||
|
if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
|
||||||
|
wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
|
||||||
|
//
|
||||||
|
if (order == null
|
||||||
|
|| order.getC_BPartner_ID() != replenish.getC_BPartner_ID()
|
||||||
|
|| order.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
|
||||||
|
{
|
||||||
|
order = new MOrder(getCtx(), 0, get_TrxName());
|
||||||
|
order.setIsSOTrx(false);
|
||||||
|
order.setC_DocTypeTarget_ID(p_C_DocType_ID);
|
||||||
|
MBPartner bp = new MBPartner(getCtx(), replenish.getC_BPartner_ID(), get_TrxName());
|
||||||
|
order.setBPartner(bp);
|
||||||
|
order.setSalesRep_ID(getAD_User_ID());
|
||||||
|
order.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
|
||||||
|
// Set Org/WH
|
||||||
|
order.setAD_Org_ID(wh.getAD_Org_ID());
|
||||||
|
order.setM_Warehouse_ID(wh.getM_Warehouse_ID());
|
||||||
|
if (!order.save())
|
||||||
|
return;
|
||||||
|
log.fine(order.toString());
|
||||||
|
noOrders++;
|
||||||
|
info += " - " + order.getDocumentNo();
|
||||||
|
}
|
||||||
|
MOrderLine line = new MOrderLine (order);
|
||||||
|
line.setM_Product_ID(replenish.getM_Product_ID());
|
||||||
|
line.setQty(replenish.getQtyToOrder());
|
||||||
|
line.setPrice();
|
||||||
|
line.save();
|
||||||
|
}
|
||||||
|
m_info = "#" + noOrders + info;
|
||||||
|
log.info(m_info);
|
||||||
|
} // createPO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Requisition
|
||||||
|
*/
|
||||||
|
private void createRequisition()
|
||||||
|
{
|
||||||
|
int noReqs = 0;
|
||||||
|
String info = "";
|
||||||
|
//
|
||||||
|
MRequisition requisition = null;
|
||||||
|
MWarehouse wh = null;
|
||||||
|
X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NULL");
|
||||||
|
for (int i = 0; i < replenishs.length; i++)
|
||||||
|
{
|
||||||
|
X_T_Replenish replenish = replenishs[i];
|
||||||
|
if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
|
||||||
|
wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
|
||||||
|
//
|
||||||
|
if (requisition == null
|
||||||
|
|| requisition.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
|
||||||
|
{
|
||||||
|
requisition = new MRequisition (getCtx(), 0, get_TrxName());
|
||||||
|
requisition.setAD_User_ID (getAD_User_ID());
|
||||||
|
requisition.setC_DocType_ID(p_C_DocType_ID);
|
||||||
|
requisition.setDescription(Msg.getMsg(getCtx(), "Replenishment"));
|
||||||
|
// Set Org/WH
|
||||||
|
requisition.setAD_Org_ID(wh.getAD_Org_ID());
|
||||||
|
requisition.setM_Warehouse_ID(wh.getM_Warehouse_ID());
|
||||||
|
if (!requisition.save())
|
||||||
|
return;
|
||||||
|
log.fine(requisition.toString());
|
||||||
|
noReqs++;
|
||||||
|
info += " - " + requisition.getDocumentNo();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
MRequisitionLine line = new MRequisitionLine(requisition);
|
||||||
|
line.setM_Product_ID(replenish.getM_Product_ID());
|
||||||
|
line.setC_BPartner_ID(replenish.getC_BPartner_ID());
|
||||||
|
line.setQty(replenish.getQtyToOrder());
|
||||||
|
line.setPrice();
|
||||||
|
line.save();
|
||||||
|
}
|
||||||
|
m_info = "#" + noReqs + info;
|
||||||
|
log.info(m_info);
|
||||||
|
} // createRequisition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Inventory Movements
|
||||||
|
*/
|
||||||
|
private void createMovements()
|
||||||
|
{
|
||||||
|
int noMoves = 0;
|
||||||
|
String info = "";
|
||||||
|
//
|
||||||
|
MClient client = null;
|
||||||
|
MMovement move = null;
|
||||||
|
int M_Warehouse_ID = 0;
|
||||||
|
int M_WarehouseSource_ID = 0;
|
||||||
|
MWarehouse whSource = null;
|
||||||
|
MWarehouse wh = null;
|
||||||
|
X_T_Replenish[] replenishs = getReplenish("M_WarehouseSource_ID IS NOT NULL");
|
||||||
|
for (int i = 0; i < replenishs.length; i++)
|
||||||
|
{
|
||||||
|
X_T_Replenish replenish = replenishs[i];
|
||||||
|
if (whSource == null || whSource.getM_WarehouseSource_ID() != replenish.getM_WarehouseSource_ID())
|
||||||
|
whSource = MWarehouse.get(getCtx(), replenish.getM_WarehouseSource_ID());
|
||||||
|
if (wh == null || wh.getM_Warehouse_ID() != replenish.getM_Warehouse_ID())
|
||||||
|
wh = MWarehouse.get(getCtx(), replenish.getM_Warehouse_ID());
|
||||||
|
if (client == null || client.getAD_Client_ID() != whSource.getAD_Client_ID())
|
||||||
|
client = MClient.get(getCtx(), whSource.getAD_Client_ID());
|
||||||
|
//
|
||||||
|
if (move == null
|
||||||
|
|| M_WarehouseSource_ID != replenish.getM_WarehouseSource_ID()
|
||||||
|
|| M_Warehouse_ID != replenish.getM_Warehouse_ID())
|
||||||
|
{
|
||||||
|
M_WarehouseSource_ID = replenish.getM_WarehouseSource_ID();
|
||||||
|
M_Warehouse_ID = replenish.getM_Warehouse_ID();
|
||||||
|
|
||||||
|
move = new MMovement (getCtx(), 0, get_TrxName());
|
||||||
|
move.setC_DocType_ID(p_C_DocType_ID);
|
||||||
|
move.setDescription(Msg.getMsg(getCtx(), "Replenishment")
|
||||||
|
+ ": " + whSource.getName() + "->" + wh.getName());
|
||||||
|
// Set Org
|
||||||
|
move.setAD_Org_ID(whSource.getAD_Org_ID());
|
||||||
|
if (!move.save())
|
||||||
|
return;
|
||||||
|
log.fine(move.toString());
|
||||||
|
noMoves++;
|
||||||
|
info += " - " + move.getDocumentNo();
|
||||||
|
}
|
||||||
|
// To
|
||||||
|
int M_LocatorTo_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||||
|
// From: Look-up Storage
|
||||||
|
MProduct product = MProduct.get(getCtx(), replenish.getM_Product_ID());
|
||||||
|
String MMPolicy = product.getMMPolicy();
|
||||||
|
MStorage[] storages = MStorage.getWarehouse(getCtx(),
|
||||||
|
whSource.getM_Warehouse_ID(), replenish.getM_Product_ID(), 0, 0,
|
||||||
|
true, null,
|
||||||
|
MClient.MMPOLICY_FiFo.equals(MMPolicy), get_TrxName());
|
||||||
|
//
|
||||||
|
BigDecimal target = replenish.getQtyToOrder();
|
||||||
|
for (int j = 0; j < storages.length; j++)
|
||||||
|
{
|
||||||
|
MStorage storage = storages[j];
|
||||||
|
if (storage.getQtyOnHand().signum() <= 0)
|
||||||
|
continue;
|
||||||
|
BigDecimal moveQty = target;
|
||||||
|
if (storage.getQtyOnHand().compareTo(moveQty) < 0)
|
||||||
|
moveQty = storage.getQtyOnHand();
|
||||||
|
//
|
||||||
|
MMovementLine line = new MMovementLine(move);
|
||||||
|
line.setM_Product_ID(replenish.getM_Product_ID());
|
||||||
|
line.setMovementQty(moveQty);
|
||||||
|
if (replenish.getQtyToOrder().compareTo(moveQty) != 0)
|
||||||
|
line.setDescription("Total: " + replenish.getQtyToOrder());
|
||||||
|
line.setM_Locator_ID(storage.getM_Locator_ID()); // from
|
||||||
|
line.setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID());
|
||||||
|
line.setM_LocatorTo_ID(M_LocatorTo_ID); // to
|
||||||
|
line.setM_AttributeSetInstanceTo_ID(storage.getM_AttributeSetInstance_ID());
|
||||||
|
line.save();
|
||||||
|
//
|
||||||
|
target = target.subtract(moveQty);
|
||||||
|
if (target.signum() == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (replenishs.length == 0)
|
||||||
|
{
|
||||||
|
m_info = "No Source Warehouse";
|
||||||
|
log.warning(m_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_info = "#" + noMoves + info;
|
||||||
|
log.info(m_info);
|
||||||
|
}
|
||||||
|
} // createRequisition
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Replenish Records
|
||||||
|
* @return replenish
|
||||||
|
*/
|
||||||
|
private X_T_Replenish[] getReplenish (String where)
|
||||||
|
{
|
||||||
|
String sql = "SELECT * FROM T_Replenish "
|
||||||
|
+ "WHERE AD_PInstance_ID=? AND C_BPartner_ID > 0 ";
|
||||||
|
if (where != null && where.length() > 0)
|
||||||
|
sql += " AND " + where;
|
||||||
|
sql += " ORDER BY M_Warehouse_ID, M_WarehouseSource_ID, C_BPartner_ID";
|
||||||
|
ArrayList<X_T_Replenish> list = new ArrayList<X_T_Replenish>();
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, get_TrxName());
|
||||||
|
pstmt.setInt (1, getAD_PInstance_ID());
|
||||||
|
ResultSet rs = pstmt.executeQuery ();
|
||||||
|
while (rs.next ())
|
||||||
|
list.add (new X_T_Replenish (getCtx(), rs, get_TrxName()));
|
||||||
|
rs.close ();
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pstmt != null)
|
||||||
|
pstmt.close ();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
X_T_Replenish[] retValue = new X_T_Replenish[list.size ()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getReplenish
|
||||||
|
|
||||||
|
} // Replenish
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,788 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.apps;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Event;
|
||||||
|
import java.awt.Frame;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
import org.adempiere.apps.graph.PAPanel;
|
||||||
|
import org.compiere.Adempiere;
|
||||||
|
import org.compiere.apps.wf.WFActivity;
|
||||||
|
import org.compiere.apps.wf.WFPanel;
|
||||||
|
import org.compiere.grid.tree.VTreePanel;
|
||||||
|
import org.compiere.model.MRole;
|
||||||
|
import org.compiere.model.MSession;
|
||||||
|
import org.compiere.model.MSysConfig;
|
||||||
|
import org.compiere.model.MSystem;
|
||||||
|
import org.compiere.model.MTreeNode;
|
||||||
|
import org.compiere.model.MUser;
|
||||||
|
import org.compiere.swing.CButton;
|
||||||
|
import org.compiere.swing.CFrame;
|
||||||
|
import org.compiere.swing.CPanel;
|
||||||
|
import org.compiere.swing.CScrollPane;
|
||||||
|
import org.compiere.swing.CTabbedPane;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Ini;
|
||||||
|
import org.compiere.util.Language;
|
||||||
|
import org.compiere.util.Msg;
|
||||||
|
import org.compiere.util.Splash;
|
||||||
|
/**
|
||||||
|
* Application Menu Controller
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: AMenu.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
||||||
|
*
|
||||||
|
* Colin Rooney (croo) RFE#1670185 restrict access to info queries
|
||||||
|
*/
|
||||||
|
public final class AMenu extends CFrame
|
||||||
|
implements ActionListener, PropertyChangeListener, ChangeListener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Application Start and Menu
|
||||||
|
*/
|
||||||
|
public AMenu ()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
log.info("CodeBase=" + Adempiere.getCodeBase());
|
||||||
|
Splash splash = Splash.getSplash();
|
||||||
|
//
|
||||||
|
m_WindowNo = Env.createWindowNo(this);
|
||||||
|
// Login
|
||||||
|
initSystem (splash); // login
|
||||||
|
splash.setText(Msg.getMsg(m_ctx, "Loading"));
|
||||||
|
splash.toFront();
|
||||||
|
splash.paint(splash.getGraphics());
|
||||||
|
|
||||||
|
//
|
||||||
|
if (!Adempiere.startupEnvironment(true)) // Load Environment
|
||||||
|
System.exit(1);
|
||||||
|
MSession.get (Env.getCtx(), true); // Start Session
|
||||||
|
|
||||||
|
// Setting close operation/listner - teo_sarca [ 1684168 ]
|
||||||
|
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
addWindowListener(new WindowListener() {
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
if (!ADialog.ask(0, null, "ExitApplication?"))
|
||||||
|
return;
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
public void windowActivated(WindowEvent e) {}
|
||||||
|
public void windowClosed(WindowEvent e) {}
|
||||||
|
public void windowDeactivated(WindowEvent e) {}
|
||||||
|
public void windowDeiconified(WindowEvent e) {}
|
||||||
|
public void windowIconified(WindowEvent e) {}
|
||||||
|
public void windowOpened(WindowEvent e) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Preparation
|
||||||
|
wfActivity = new WFActivity(this);
|
||||||
|
wfPanel = new WFPanel(this);
|
||||||
|
treePanel = new VTreePanel (m_WindowNo, true, false); // !editable & hasBar
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
jbInit();
|
||||||
|
createMenu();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "AMenu", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize & load tree
|
||||||
|
int AD_Role_ID = Env.getAD_Role_ID(Env.getCtx());
|
||||||
|
int AD_Tree_ID = DB.getSQLValue(null,
|
||||||
|
"SELECT COALESCE(r.AD_Tree_Menu_ID, ci.AD_Tree_Menu_ID)"
|
||||||
|
+ "FROM AD_ClientInfo ci"
|
||||||
|
+ " INNER JOIN AD_Role r ON (ci.AD_Client_ID=r.AD_Client_ID) "
|
||||||
|
+ "WHERE AD_Role_ID=?", AD_Role_ID);
|
||||||
|
if (AD_Tree_ID <= 0)
|
||||||
|
AD_Tree_ID = 10; // Menu
|
||||||
|
treePanel.initTree(AD_Tree_ID);
|
||||||
|
|
||||||
|
// Translate
|
||||||
|
Env.setContext(m_ctx, m_WindowNo, "WindowName", Msg.getMsg(m_ctx, "Menu"));
|
||||||
|
setTitle(Env.getHeader(m_ctx, m_WindowNo));
|
||||||
|
|
||||||
|
progressBar.setString(Msg.getMsg(m_ctx, "SelectProgram"));
|
||||||
|
|
||||||
|
// Finish UI
|
||||||
|
Point loc = Ini.getWindowLocation(0);
|
||||||
|
if (loc == null)
|
||||||
|
loc = new Point(0,0);
|
||||||
|
this.setLocation(loc);
|
||||||
|
this.pack();
|
||||||
|
this.setVisible(true);
|
||||||
|
if (Ini.isPropertyBool(Ini.P_OPEN_WINDOW_MAXIMIZED))
|
||||||
|
this.setExtendedState(Frame.MAXIMIZED_BOTH);
|
||||||
|
else
|
||||||
|
this.setState(Frame.NORMAL);
|
||||||
|
this.validate();
|
||||||
|
m_AD_User_ID = Env.getContextAsInt(m_ctx, "#AD_User_ID");
|
||||||
|
m_AD_Role_ID = Env.getContextAsInt(m_ctx, "#AD_Role_ID");
|
||||||
|
updateInfo();
|
||||||
|
//
|
||||||
|
infoUpdater = new InfoUpdater();
|
||||||
|
infoUpdaterThread = new Thread(infoUpdater, "InfoUpdater");
|
||||||
|
infoUpdaterThread.start();
|
||||||
|
//
|
||||||
|
splash.dispose();
|
||||||
|
splash = null;
|
||||||
|
} // AMenu
|
||||||
|
|
||||||
|
private int m_WindowNo;
|
||||||
|
private Properties m_ctx = Env.getCtx();
|
||||||
|
private boolean m_startingItem = false;
|
||||||
|
/** The User */
|
||||||
|
private int m_AD_User_ID;
|
||||||
|
/** The Role */
|
||||||
|
private int m_AD_Role_ID;
|
||||||
|
|
||||||
|
/** Center Tabbed Pane index: Menu */
|
||||||
|
private int m_tabMenu = 0;
|
||||||
|
/** Center Tabbed Pane index: Activities */
|
||||||
|
private int m_tabActivities = 1;
|
||||||
|
/** Center Tabbed Pane index: Workflow */
|
||||||
|
private int m_tabWorkflow = 2;
|
||||||
|
|
||||||
|
// Links
|
||||||
|
private int m_request_Menu_ID = 0;
|
||||||
|
private int m_note_Menu_ID = 0;
|
||||||
|
private String m_requestSQL = null;
|
||||||
|
// private DecimalFormat m_memoryFormat = DisplayType.getNumberFormat(DisplayType.Integer);
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger log = CLogger.getCLogger(AMenu.class);
|
||||||
|
|
||||||
|
/** The Info Update instance **/
|
||||||
|
private InfoUpdater infoUpdater = null;
|
||||||
|
/** The Info Update thread **/
|
||||||
|
private Thread infoUpdaterThread = null;
|
||||||
|
|
||||||
|
private WindowManager windowManager = new WindowManager();
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Init System.
|
||||||
|
* -- do not get Msg as environment not initialized yet --
|
||||||
|
* <pre>
|
||||||
|
* - Login - in not successful, exit
|
||||||
|
* </pre>
|
||||||
|
* @param splash splash window
|
||||||
|
*/
|
||||||
|
private void initSystem (Splash splash)
|
||||||
|
{
|
||||||
|
// Default Image
|
||||||
|
this.setIconImage(Adempiere.getImage16());
|
||||||
|
|
||||||
|
// Focus Traversal
|
||||||
|
KeyboardFocusManager.setCurrentKeyboardFocusManager(AKeyboardFocusManager.get());
|
||||||
|
// FocusManager.getCurrentManager().setDefaultFocusTraversalPolicy(AFocusTraversalPolicy.get());
|
||||||
|
// this.setFocusTraversalPolicy(AFocusTraversalPolicy.get());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Login Screen - if not successful - exit
|
||||||
|
*/
|
||||||
|
log.finer("Login");
|
||||||
|
|
||||||
|
ALogin login = new ALogin(splash);
|
||||||
|
if (!login.initLogin()) // no automatic login
|
||||||
|
{
|
||||||
|
// Center the window
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AEnv.showCenterScreen(login); // HTML load errors
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.severe(ex.toString());
|
||||||
|
}
|
||||||
|
if (!login.isConnected() || !login.isOKpressed())
|
||||||
|
AEnv.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Build
|
||||||
|
if (!DB.isBuildOK(m_ctx))
|
||||||
|
AEnv.exit(1);
|
||||||
|
|
||||||
|
// Check DB (AppsServer Version checked in Login)
|
||||||
|
DB.isDatabaseOK(m_ctx);
|
||||||
|
} // initSystem
|
||||||
|
|
||||||
|
// UI
|
||||||
|
private CPanel mainPanel = new CPanel();
|
||||||
|
private BorderLayout mainLayout = new BorderLayout();
|
||||||
|
private CTabbedPane centerPane = new CTabbedPane();
|
||||||
|
private CPanel southPanel = new CPanel();
|
||||||
|
private BorderLayout southLayout = new BorderLayout();
|
||||||
|
private JMenuBar menuBar = new JMenuBar();
|
||||||
|
protected JProgressBar progressBar = new JProgressBar(0,100);
|
||||||
|
private CPanel infoPanel = new CPanel();
|
||||||
|
private CButton bNotes = new CButton();
|
||||||
|
private CButton bRequests = new CButton();
|
||||||
|
private GridLayout infoLayout = new GridLayout();
|
||||||
|
private JProgressBar memoryBar = new JProgressBar();
|
||||||
|
// Tabs
|
||||||
|
private PAPanel paPanel = null;
|
||||||
|
private VTreePanel treePanel = null;
|
||||||
|
private WFActivity wfActivity = null;
|
||||||
|
private WFPanel wfPanel = null;
|
||||||
|
private WindowMenu m_WindowMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static Init.
|
||||||
|
* <pre>
|
||||||
|
* - mainPanel
|
||||||
|
* - centerPane
|
||||||
|
* - treePanel
|
||||||
|
* - wfActivity
|
||||||
|
* - wfPanel
|
||||||
|
* - southPanel
|
||||||
|
* - infoPanel
|
||||||
|
* - bNotes
|
||||||
|
* - bTask
|
||||||
|
* - memoryBar
|
||||||
|
* - wfPanel
|
||||||
|
* - progressBar
|
||||||
|
* </pre>
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
void jbInit() throws Exception
|
||||||
|
{
|
||||||
|
this.setName("Menu");
|
||||||
|
this.setLocale(Language.getLoginLanguage().getLocale());
|
||||||
|
this.setJMenuBar(menuBar);
|
||||||
|
//
|
||||||
|
mainPanel.setLayout(mainLayout);
|
||||||
|
mainLayout.setHgap(0);
|
||||||
|
mainLayout.setVgap(2);
|
||||||
|
//
|
||||||
|
treePanel.addPropertyChangeListener(VTreePanel.NODE_SELECTION, this);
|
||||||
|
//
|
||||||
|
infoPanel.setLayout(infoLayout);
|
||||||
|
infoLayout.setColumns(2);
|
||||||
|
infoLayout.setHgap(4);
|
||||||
|
infoLayout.setVgap(0);
|
||||||
|
// bNotes.setRequestFocusEnabled(false);
|
||||||
|
bNotes.setToolTipText("");
|
||||||
|
bNotes.setActionCommand("Notes");
|
||||||
|
bNotes.addActionListener(this);
|
||||||
|
bNotes.setIcon(Env.getImageIcon("GetMail24.gif"));
|
||||||
|
bNotes.setMargin(new Insets(0, 0, 0, 0));
|
||||||
|
// bRequests.setRequestFocusEnabled(false);
|
||||||
|
bRequests.setActionCommand("Requests");
|
||||||
|
bRequests.addActionListener(this);
|
||||||
|
bRequests.setIcon(Env.getImageIcon("Request24.gif"));
|
||||||
|
bRequests.setMargin(new Insets(0, 0, 0, 0));
|
||||||
|
//
|
||||||
|
southLayout.setHgap(0);
|
||||||
|
southLayout.setVgap(1);
|
||||||
|
//
|
||||||
|
memoryBar.setStringPainted(true);
|
||||||
|
memoryBar.setOpaque(false);
|
||||||
|
memoryBar.setBorderPainted(false);
|
||||||
|
memoryBar.addMouseListener(new AMenu_MouseAdapter());
|
||||||
|
//
|
||||||
|
progressBar.setStringPainted(true);
|
||||||
|
progressBar.setOpaque(false);
|
||||||
|
//
|
||||||
|
getContentPane().add(mainPanel);
|
||||||
|
mainPanel.add(centerPane, BorderLayout.CENTER);
|
||||||
|
mainPanel.add(southPanel, BorderLayout.SOUTH);
|
||||||
|
mainPanel.add(Box.createHorizontalStrut(3), BorderLayout.EAST);
|
||||||
|
mainPanel.add(Box.createHorizontalStrut(3), BorderLayout.WEST);
|
||||||
|
|
||||||
|
// Tabs
|
||||||
|
centerPane.setFont(centerPane.getFont().deriveFont(centerPane.getFont().getSize2D()+1));
|
||||||
|
paPanel = PAPanel.get();
|
||||||
|
if (paPanel != null)
|
||||||
|
{
|
||||||
|
//centerPane.add(paPanel, Msg.getMsg(m_ctx, "PAPanel"));
|
||||||
|
centerPane.addTab(Msg.getMsg(m_ctx, "PAPanel"), Env.getImageIcon2("InfoAccount16"), paPanel);
|
||||||
|
m_tabMenu++;
|
||||||
|
m_tabActivities++;
|
||||||
|
m_tabWorkflow++;
|
||||||
|
}
|
||||||
|
treePanel.setBorder(BorderFactory.createEmptyBorder(2,3,2,3));
|
||||||
|
//centerPane.add(treePanel, Msg.getMsg(m_ctx, "Menu"));
|
||||||
|
centerPane.addTab(Msg.getMsg(m_ctx, "Menu"), Env.getImageIcon2("Home16"), treePanel);
|
||||||
|
//centerPane.add(new CScrollPane(wfActivity), Msg.getMsg (m_ctx, "WorkflowActivities") + ": 0");
|
||||||
|
centerPane.addTab(Msg.getMsg (m_ctx, "WorkflowActivities") + ": 0", Env.getImageIcon2("Assignment16"), new CScrollPane(wfActivity));
|
||||||
|
//centerPane.add(new CScrollPane(wfPanel), Msg.getMsg (m_ctx, "WorkflowPanel"));
|
||||||
|
centerPane.addTab(Msg.getMsg (m_ctx, "WorkflowPanel"), Env.getImageIcon2("WorkFlow16"), new CScrollPane(wfPanel));
|
||||||
|
centerPane.addChangeListener (this);
|
||||||
|
//
|
||||||
|
southPanel.setLayout(southLayout);
|
||||||
|
southPanel.add(infoPanel, BorderLayout.NORTH);
|
||||||
|
southPanel.add(progressBar, BorderLayout.SOUTH);
|
||||||
|
//
|
||||||
|
infoPanel.add(bNotes, null);
|
||||||
|
infoPanel.add(bRequests, null);
|
||||||
|
infoPanel.add(memoryBar, null);
|
||||||
|
//
|
||||||
|
int loc = Ini.getDividerLocation();
|
||||||
|
if (loc > 0)
|
||||||
|
treePanel.setDividerLocation(loc);
|
||||||
|
} // jbInit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Preferred Size
|
||||||
|
* @return preferred Size
|
||||||
|
*/
|
||||||
|
public Dimension getPreferredSize()
|
||||||
|
{
|
||||||
|
Dimension dim = Ini.getWindowDimension(0);
|
||||||
|
if (dim == null)
|
||||||
|
dim = new Dimension (350, 500);
|
||||||
|
return dim;
|
||||||
|
} // getPreferredSize
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Menu
|
||||||
|
*/
|
||||||
|
private void createMenu()
|
||||||
|
{
|
||||||
|
// File
|
||||||
|
JMenu mFile = AEnv.getMenu("File");
|
||||||
|
menuBar.add(mFile);
|
||||||
|
AEnv.addMenuItem("PrintScreen", null, KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, 0), mFile, this);
|
||||||
|
AEnv.addMenuItem("ScreenShot", null, KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, KeyEvent.SHIFT_MASK), mFile, this);
|
||||||
|
mFile.addSeparator();
|
||||||
|
AEnv.addMenuItem("Logout", null, KeyStroke.getKeyStroke(KeyEvent.VK_L, Event.SHIFT_MASK+Event.ALT_MASK), mFile, this);
|
||||||
|
AEnv.addMenuItem("Exit", null, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.SHIFT_MASK+Event.ALT_MASK), mFile, this);
|
||||||
|
|
||||||
|
// View
|
||||||
|
JMenu mView = AEnv.getMenu("View");
|
||||||
|
menuBar.add(mView);
|
||||||
|
|
||||||
|
if (MRole.getDefault().isAllow_Info_Product())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoProduct", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_BPartner())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoBPartner", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK+Event.CTRL_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isShowAcct() && MRole.getDefault().isAllow_Info_Account())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAccount", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK+Event.CTRL_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Schedule())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoSchedule", null, null, mView, this);
|
||||||
|
}
|
||||||
|
mView.addSeparator();
|
||||||
|
if (MRole.getDefault().isAllow_Info_Order())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoOrder", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Invoice())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoInvoice", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_InOut())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoInOut", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Payment())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoPayment", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_CashJournal())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoCashLine", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Resource())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAssignment", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Asset())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAsset", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tools
|
||||||
|
JMenu mTools = AEnv.getMenu("Tools");
|
||||||
|
menuBar.add(mTools);
|
||||||
|
AEnv.addMenuItem("Calculator", null, null, mTools, this);
|
||||||
|
AEnv.addMenuItem("Calendar", null, null, mTools, this);
|
||||||
|
AEnv.addMenuItem("Editor", null, null, mTools, this);
|
||||||
|
MUser user = MUser.get(Env.getCtx());
|
||||||
|
if (user.isAdministrator())
|
||||||
|
AEnv.addMenuItem("Script", null, null, mTools, this);
|
||||||
|
if (AEnv.isWorkflowProcess())
|
||||||
|
AEnv.addMenuItem("WorkFlow", null, null, mTools, this);
|
||||||
|
if (MRole.getDefault().isShowPreference())
|
||||||
|
{
|
||||||
|
mTools.addSeparator();
|
||||||
|
AEnv.addMenuItem("Preference", null, null, mTools, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Window Menu
|
||||||
|
m_WindowMenu = new WindowMenu(windowManager, this);
|
||||||
|
menuBar.add(m_WindowMenu);
|
||||||
|
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK);
|
||||||
|
this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, "ShowAllWindow");
|
||||||
|
AppsAction action = new AppsAction("ShowAllWindow", ks, false);
|
||||||
|
this.getRootPane().getActionMap().put("ShowAllWindow", action);
|
||||||
|
action.setDelegate(this);
|
||||||
|
|
||||||
|
// Help
|
||||||
|
JMenu mHelp = AEnv.getMenu("Help");
|
||||||
|
menuBar.add(mHelp);
|
||||||
|
AEnv.addMenuItem("Online", null, null, mHelp, this);
|
||||||
|
AEnv.addMenuItem("EMailSupport", null, null, mHelp, this);
|
||||||
|
AEnv.addMenuItem("About", null, null, mHelp, this);
|
||||||
|
} // createMenu
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose - end system
|
||||||
|
*/
|
||||||
|
public void dispose()
|
||||||
|
{
|
||||||
|
preDispose();
|
||||||
|
//
|
||||||
|
super.dispose();
|
||||||
|
AEnv.exit(0);
|
||||||
|
} // dispose
|
||||||
|
|
||||||
|
private void preDispose() {
|
||||||
|
// clean up - save window state
|
||||||
|
Ini.setWindowDimension(0, getSize());
|
||||||
|
Ini.setDividerLocation(treePanel.getDividerLocation());
|
||||||
|
Ini.setWindowLocation(0, getLocation());
|
||||||
|
Ini.saveProperties(true);
|
||||||
|
//
|
||||||
|
infoUpdater.stop = true;
|
||||||
|
try {
|
||||||
|
infoUpdaterThread.join(50);
|
||||||
|
} catch(InterruptedException ire) {
|
||||||
|
} finally {
|
||||||
|
infoUpdaterThread = null;
|
||||||
|
infoUpdater = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logout()
|
||||||
|
{
|
||||||
|
windowManager.close();
|
||||||
|
preDispose();
|
||||||
|
super.dispose();
|
||||||
|
AEnv.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Window Events - requestFocus
|
||||||
|
* @param e event
|
||||||
|
*/
|
||||||
|
protected void processWindowEvent(WindowEvent e)
|
||||||
|
{
|
||||||
|
super.processWindowEvent(e);
|
||||||
|
if (e.getID() == WindowEvent.WINDOW_OPENED)
|
||||||
|
{
|
||||||
|
treePanel.getSearchField().requestFocusInWindow();
|
||||||
|
// this.toFront();
|
||||||
|
}
|
||||||
|
} // processWindowEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Busy
|
||||||
|
* @param value true if buzy
|
||||||
|
*/
|
||||||
|
protected void setBusy (boolean value)
|
||||||
|
{
|
||||||
|
m_startingItem = value;
|
||||||
|
if (value)
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
else
|
||||||
|
setCursor(Cursor.getDefaultCursor());
|
||||||
|
// setEnabled (!value); // causes flicker
|
||||||
|
} // setBusy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selection in tree - launch Application
|
||||||
|
* @param e PropertyChangeEvent
|
||||||
|
*/
|
||||||
|
public void propertyChange(PropertyChangeEvent e)
|
||||||
|
{
|
||||||
|
MTreeNode nd = (MTreeNode)e.getNewValue();
|
||||||
|
log.info(nd.getNode_ID() + " - " + nd.toString());
|
||||||
|
|
||||||
|
// ignore summary items & when loading
|
||||||
|
if (m_startingItem || nd.isSummary())
|
||||||
|
return;
|
||||||
|
|
||||||
|
String sta = nd.toString();
|
||||||
|
progressBar.setString(sta);
|
||||||
|
int cmd = nd.getNode_ID();
|
||||||
|
|
||||||
|
(new AMenuStartItem(cmd, true, sta, this)).start(); // async load
|
||||||
|
//hengsin, updateInfo is call again in AMenuStartItem
|
||||||
|
//updateInfo();
|
||||||
|
} // propertyChange
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* ActionListener
|
||||||
|
* @param e ActionEvent
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
// Buttons
|
||||||
|
if (e.getSource() == bNotes)
|
||||||
|
gotoNotes();
|
||||||
|
else if (e.getSource() == bRequests)
|
||||||
|
gotoRequests();
|
||||||
|
else if (e.getActionCommand().equals("ShowAllWindow"))
|
||||||
|
m_WindowMenu.expose();
|
||||||
|
else if (!AEnv.actionPerformed(e.getActionCommand(), m_WindowNo, this))
|
||||||
|
log.log(Level.SEVERE, "unknown action=" + e.getActionCommand());
|
||||||
|
//updateInfo();
|
||||||
|
} // actionPerformed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get number of open Notes
|
||||||
|
* @return number of notes
|
||||||
|
*/
|
||||||
|
private int getNotes()
|
||||||
|
{
|
||||||
|
String sql = "SELECT COUNT(1) FROM AD_Note "
|
||||||
|
+ "WHERE AD_Client_ID=? AND AD_User_ID IN (0,?)"
|
||||||
|
+ " AND Processed='N'";
|
||||||
|
int retValue = DB.getSQLValue(null, sql, Env.getAD_Client_ID(Env.getCtx()), m_AD_User_ID);
|
||||||
|
return retValue;
|
||||||
|
} // getNotes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Note Window
|
||||||
|
*/
|
||||||
|
private void gotoNotes()
|
||||||
|
{
|
||||||
|
// AD_Table_ID for AD_Note = 389 HARDCODED
|
||||||
|
if (m_note_Menu_ID == 0)
|
||||||
|
m_note_Menu_ID = DB.getSQLValue(null, "SELECT AD_Menu_ID "
|
||||||
|
+ "FROM AD_Menu m"
|
||||||
|
+ " INNER JOIN AD_TABLE t ON (t.AD_Window_ID=m.AD_Window_ID) "
|
||||||
|
+ "WHERE t.AD_Table_ID=?", 389);
|
||||||
|
if (m_note_Menu_ID == 0)
|
||||||
|
m_note_Menu_ID = 233; // fallback HARDCODED
|
||||||
|
(new AMenuStartItem (m_note_Menu_ID, true, Msg.translate(m_ctx, "AD_Note_ID"), this)).start(); // async load
|
||||||
|
} // gotoMessage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ger Number of open Requests
|
||||||
|
* @return number of requests
|
||||||
|
*/
|
||||||
|
private int getRequests()
|
||||||
|
{
|
||||||
|
if (m_requestSQL == null)
|
||||||
|
m_requestSQL = MRole.getDefault().addAccessSQL ("SELECT COUNT(1) FROM R_Request "
|
||||||
|
+ "WHERE (SalesRep_ID=? OR AD_Role_ID=?) AND Processed='N'"
|
||||||
|
+ " AND (DateNextAction IS NULL OR TRUNC(DateNextAction) <= TRUNC(SysDate))"
|
||||||
|
+ " AND (R_Status_ID IS NULL OR R_Status_ID IN (SELECT R_Status_ID FROM R_Status WHERE IsClosed='N'))",
|
||||||
|
"R_Request", false, true); // not qualified - RW
|
||||||
|
int retValue = DB.getSQLValue(null, m_requestSQL, m_AD_User_ID, m_AD_Role_ID);
|
||||||
|
return retValue;
|
||||||
|
} // getRequests
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Request Window
|
||||||
|
*/
|
||||||
|
private void gotoRequests()
|
||||||
|
{
|
||||||
|
// AD_Table_ID for R_Request = 417 HARDCODED
|
||||||
|
// if (m_request_Menu_ID == 0) // Goes to Request (all)
|
||||||
|
// m_request_Menu_ID = DB.getSQLValue (null, "SELECT AD_Menu_ID "
|
||||||
|
// + "FROM AD_Menu m"
|
||||||
|
// + " INNER JOIN AD_TABLE t ON (t.AD_Window_ID=m.AD_Window_ID) "
|
||||||
|
// + "WHERE t.AD_Table_ID=?", 417);
|
||||||
|
if (m_request_Menu_ID == 0)
|
||||||
|
m_request_Menu_ID = 237; // My Requests
|
||||||
|
(new AMenuStartItem (m_request_Menu_ID, true, Msg.translate(m_ctx, "R_Request_ID"), this)).start(); // async load
|
||||||
|
} // gotoRequests
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Memory Info - run GC if required - Update Requests/Memos/Activities
|
||||||
|
*/
|
||||||
|
public void updateInfo()
|
||||||
|
{
|
||||||
|
double total = Runtime.getRuntime().totalMemory() / 1024;
|
||||||
|
double free = Runtime.getRuntime().freeMemory() / 1024;
|
||||||
|
double used = total - free;
|
||||||
|
double percent = used * 100 / total;
|
||||||
|
//
|
||||||
|
memoryBar.setMaximum((int)total);
|
||||||
|
memoryBar.setValue((int)used);
|
||||||
|
String msg = MessageFormat.format("{0,number,integer} MB - {1,number,integer}%",
|
||||||
|
new Object[] {new BigDecimal(total / 1024), new BigDecimal(percent)});
|
||||||
|
memoryBar.setString(msg);
|
||||||
|
//
|
||||||
|
// msg = MessageFormat.format("Total Memory {0,number,integer} kB - Free {1,number,integer} kB",
|
||||||
|
msg = Msg.getMsg(m_ctx, "MemoryInfo",
|
||||||
|
new Object[] {new BigDecimal(total), new BigDecimal(free)});
|
||||||
|
memoryBar.setToolTipText(msg);
|
||||||
|
// progressBar.repaint();
|
||||||
|
|
||||||
|
// CarlosRuiz - globalqss - [ 1881285 ] Remove unnecessary calls to System.gc
|
||||||
|
// if (percent > 50)
|
||||||
|
// System.gc();
|
||||||
|
|
||||||
|
if (DB.isConnected())
|
||||||
|
{
|
||||||
|
// Requests
|
||||||
|
int requests = getRequests();
|
||||||
|
bRequests.setText(Msg.translate(m_ctx, "R_Request_ID") + ": " + requests);
|
||||||
|
// Memo
|
||||||
|
int notes = getNotes();
|
||||||
|
bNotes.setText(Msg.translate(m_ctx, "AD_Note_ID") + ": " + notes);
|
||||||
|
// Activities
|
||||||
|
int activities = wfActivity.getActivitiesCount();
|
||||||
|
centerPane.setTitleAt(m_tabActivities, Msg.getMsg (m_ctx, "WorkflowActivities") + ": " + activities);
|
||||||
|
/*
|
||||||
|
log.config(msg
|
||||||
|
+ ", Processors=" + Runtime.getRuntime().availableProcessors()
|
||||||
|
+ ", Requests=" + requests + ", Notes=" + notes + ", Activities=" + activities
|
||||||
|
+ "," + CConnection.get().getStatus()
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
MSystem.get(m_ctx).info();
|
||||||
|
}
|
||||||
|
} // updateInfo
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update Activities Label
|
||||||
|
*/
|
||||||
|
public void updateActivities(int act_length)
|
||||||
|
{
|
||||||
|
centerPane.setTitleAt(m_tabActivities, Msg.getMsg (m_ctx, "WorkflowActivities") + ": " + act_length);
|
||||||
|
} // updateInfo
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Start Workflow Activity
|
||||||
|
* @param AD_Workflow_ID id
|
||||||
|
*/
|
||||||
|
protected void startWorkFlow (int AD_Workflow_ID)
|
||||||
|
{
|
||||||
|
centerPane.setSelectedIndex(m_tabWorkflow); // switch
|
||||||
|
wfPanel.load(AD_Workflow_ID, false);
|
||||||
|
} // startWorkFlow
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change Listener (tab)
|
||||||
|
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
|
||||||
|
* @param e event
|
||||||
|
*/
|
||||||
|
public void stateChanged (ChangeEvent e)
|
||||||
|
{
|
||||||
|
//updateInfo();
|
||||||
|
// show activities
|
||||||
|
if (centerPane.getSelectedIndex() == m_tabActivities)
|
||||||
|
{
|
||||||
|
wfActivity.loadActivities();
|
||||||
|
wfActivity.display();
|
||||||
|
}
|
||||||
|
} // stateChanged
|
||||||
|
|
||||||
|
public WindowManager getWindowManager() {
|
||||||
|
return windowManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Mouse Listener
|
||||||
|
*/
|
||||||
|
class AMenu_MouseAdapter extends MouseAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Invoked when the mouse has been clicked on a component.
|
||||||
|
* @param e evant
|
||||||
|
*/
|
||||||
|
public void mouseClicked(MouseEvent e)
|
||||||
|
{
|
||||||
|
if (e.getClickCount() > 1)
|
||||||
|
{
|
||||||
|
System.gc();
|
||||||
|
//updateInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // AMenu_MouseAdapter
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* OS Start
|
||||||
|
* @param args Array of String arguments (ignored)
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
Splash.getSplash();
|
||||||
|
Adempiere.startup(true); // needs to be here for UI
|
||||||
|
new AMenu();
|
||||||
|
} // main
|
||||||
|
|
||||||
|
class InfoUpdater implements Runnable
|
||||||
|
{
|
||||||
|
boolean stop = false;
|
||||||
|
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
int sleep = MSysConfig.getIntValue("MENU_INFOUPDATER_SLEEP_MS", 60000, Env.getAD_Client_ID(Env.getCtx()));
|
||||||
|
while(stop == false)
|
||||||
|
{
|
||||||
|
updateInfo();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleep);
|
||||||
|
} catch(InterruptedException ire) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // AMenu
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,140 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.apps;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applet Start
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: AStart.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public final class AStart extends JApplet
|
||||||
|
{
|
||||||
|
boolean isStandalone = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a parameter value
|
||||||
|
*/
|
||||||
|
public String getParameter(String key, String def)
|
||||||
|
{
|
||||||
|
return isStandalone ? System.getProperty(key, def) :
|
||||||
|
(getParameter(key) != null ? getParameter(key) : def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the applet
|
||||||
|
*/
|
||||||
|
public AStart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the applet
|
||||||
|
*/
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
jbInit();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component initialization
|
||||||
|
*/
|
||||||
|
private void jbInit() throws Exception
|
||||||
|
{
|
||||||
|
this.setSize(new Dimension(400,300));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the applet
|
||||||
|
*/
|
||||||
|
public void start()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the applet
|
||||||
|
*/
|
||||||
|
public void stop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the applet
|
||||||
|
*/
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Applet information
|
||||||
|
*/
|
||||||
|
public String getAppletInfo()
|
||||||
|
{
|
||||||
|
return "Start Applet";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get parameter info
|
||||||
|
*/
|
||||||
|
public String[][] getParameterInfo()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main method
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
AStart applet = new AStart();
|
||||||
|
applet.isStandalone = true;
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
//EXIT_ON_CLOSE == 3
|
||||||
|
frame.setDefaultCloseOperation(3);
|
||||||
|
frame.setTitle("Start Applet");
|
||||||
|
frame.getContentPane().add(applet, BorderLayout.CENTER);
|
||||||
|
applet.init();
|
||||||
|
applet.start();
|
||||||
|
frame.setSize(400,320);
|
||||||
|
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//static initializer for setting look & feel
|
||||||
|
static
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
//UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // AStert
|
|
@ -0,0 +1,438 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.apps.form;
|
||||||
|
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.awt.Event;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
|
import org.compiere.apps.AEnv;
|
||||||
|
import org.compiere.apps.AGlassPane;
|
||||||
|
import org.compiere.apps.AMenu;
|
||||||
|
import org.compiere.apps.Help;
|
||||||
|
import org.compiere.apps.WindowMenu;
|
||||||
|
import org.compiere.model.MRole;
|
||||||
|
import org.compiere.model.MUser;
|
||||||
|
import org.compiere.swing.CFrame;
|
||||||
|
import org.compiere.util.CLogger;
|
||||||
|
import org.compiere.util.DB;
|
||||||
|
import org.compiere.util.Env;
|
||||||
|
import org.compiere.util.Trace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form Framework
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: FormFrame.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $
|
||||||
|
*
|
||||||
|
* Colin Rooney 2007/03/20 RFE#1670185 & BUG#1684142
|
||||||
|
* Extend security to Info Queries
|
||||||
|
*/
|
||||||
|
public class FormFrame extends CFrame
|
||||||
|
implements ActionListener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create Form.
|
||||||
|
* Need to call openForm
|
||||||
|
*/
|
||||||
|
public FormFrame ()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
addWindowListener(new java.awt.event.WindowAdapter()
|
||||||
|
{
|
||||||
|
public void windowOpened(java.awt.event.WindowEvent evt)
|
||||||
|
{
|
||||||
|
formWindowOpened(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_WindowNo = Env.createWindowNo (this);
|
||||||
|
setGlassPane(m_glassPane);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
jbInit();
|
||||||
|
createMenu();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "", e);
|
||||||
|
}
|
||||||
|
} // FormFrame
|
||||||
|
|
||||||
|
/** WindowNo */
|
||||||
|
private int m_WindowNo;
|
||||||
|
/** The GlassPane */
|
||||||
|
private AGlassPane m_glassPane = new AGlassPane();
|
||||||
|
/** Description */
|
||||||
|
private String m_Description = null;
|
||||||
|
/** Help */
|
||||||
|
private String m_Help = null;
|
||||||
|
/** Menu Bar */
|
||||||
|
private JMenuBar menuBar = new JMenuBar();
|
||||||
|
/** The Panel to be displayed */
|
||||||
|
private FormPanel m_panel = null;
|
||||||
|
/** Maximize Window */
|
||||||
|
public boolean m_maximize = false;
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger log = CLogger.getCLogger(FormFrame.class);
|
||||||
|
|
||||||
|
/** Form ID */
|
||||||
|
private int p_AD_Form_ID = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static Init
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private void jbInit() throws Exception
|
||||||
|
{
|
||||||
|
this.setIconImage(org.compiere.Adempiere.getImage16());
|
||||||
|
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
|
this.setJMenuBar(menuBar);
|
||||||
|
} // jbInit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Menu
|
||||||
|
*/
|
||||||
|
private void createMenu()
|
||||||
|
{
|
||||||
|
// File
|
||||||
|
JMenu mFile = AEnv.getMenu("File");
|
||||||
|
menuBar.add(mFile);
|
||||||
|
AEnv.addMenuItem("PrintScreen", null, KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, 0), mFile, this);
|
||||||
|
AEnv.addMenuItem("ScreenShot", null, KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, Event.SHIFT_MASK), mFile, this);
|
||||||
|
AEnv.addMenuItem("Report", null, KeyStroke.getKeyStroke(KeyEvent.VK_P, Event.ALT_MASK), mFile, this);
|
||||||
|
mFile.addSeparator();
|
||||||
|
AEnv.addMenuItem("End", null, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.ALT_MASK), mFile, this);
|
||||||
|
AEnv.addMenuItem("Exit", null, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.SHIFT_MASK+Event.ALT_MASK), mFile, this);
|
||||||
|
|
||||||
|
// View
|
||||||
|
JMenu mView = AEnv.getMenu("View");
|
||||||
|
menuBar.add(mView);
|
||||||
|
|
||||||
|
if (MRole.getDefault().isAllow_Info_Product())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoProduct", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_BPartner())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoBPartner", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK+Event.CTRL_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isShowAcct() && MRole.getDefault().isAllow_Info_Account())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAccount", null, KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.ALT_MASK+Event.CTRL_MASK), mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Schedule())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoSchedule", null, null, mView, this);
|
||||||
|
}
|
||||||
|
mView.addSeparator();
|
||||||
|
if (MRole.getDefault().isAllow_Info_Order())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoOrder", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Invoice())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoInvoice", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_InOut())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoInOut", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Payment())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoPayment", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_CashJournal())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoCashLine", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Resource())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAssignment", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
if (MRole.getDefault().isAllow_Info_Asset())
|
||||||
|
{
|
||||||
|
AEnv.addMenuItem("InfoAsset", "Info", null, mView, this);
|
||||||
|
}
|
||||||
|
// Tools
|
||||||
|
JMenu mTools = AEnv.getMenu("Tools");
|
||||||
|
menuBar.add(mTools);
|
||||||
|
AEnv.addMenuItem("Calculator", null, null, mTools, this);
|
||||||
|
AEnv.addMenuItem("Calendar", null, null, mTools, this);
|
||||||
|
AEnv.addMenuItem("Editor", null, null, mTools, this);
|
||||||
|
MUser user = MUser.get(Env.getCtx());
|
||||||
|
if (user.isAdministrator())
|
||||||
|
AEnv.addMenuItem("Script", null, null, mTools, this);
|
||||||
|
if (MRole.getDefault().isShowPreference())
|
||||||
|
{
|
||||||
|
mTools.addSeparator();
|
||||||
|
AEnv.addMenuItem("Preference", null, null, mTools, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window
|
||||||
|
AMenu aMenu = (AMenu)Env.getWindow(0);
|
||||||
|
JMenu mWindow = new WindowMenu(aMenu.getWindowManager(), this);
|
||||||
|
menuBar.add(mWindow);
|
||||||
|
|
||||||
|
// Help
|
||||||
|
JMenu mHelp = AEnv.getMenu("Help");
|
||||||
|
menuBar.add(mHelp);
|
||||||
|
AEnv.addMenuItem("Help", "Help", KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0), mHelp, this);
|
||||||
|
AEnv.addMenuItem("Online", null, null, mHelp, this);
|
||||||
|
AEnv.addMenuItem("EMailSupport", null, null, mHelp, this);
|
||||||
|
AEnv.addMenuItem("About", null, null, mHelp, this);
|
||||||
|
} // createMenu
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose
|
||||||
|
*/
|
||||||
|
public void dispose()
|
||||||
|
{
|
||||||
|
log.config("");
|
||||||
|
// recursive calls
|
||||||
|
if (Trace.isCalledFrom("JFrame") && m_panel != null) // [x] close window pressed
|
||||||
|
m_panel.dispose();
|
||||||
|
m_panel = null;
|
||||||
|
Env.clearWinContext(m_WindowNo);
|
||||||
|
super.dispose();
|
||||||
|
} // dispose
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Form
|
||||||
|
* @param AD_Form_ID form
|
||||||
|
* @return true if form opened
|
||||||
|
*/
|
||||||
|
public boolean openForm (int AD_Form_ID)
|
||||||
|
{
|
||||||
|
Properties ctx = Env.getCtx();
|
||||||
|
//
|
||||||
|
String name = null;
|
||||||
|
String className = null;
|
||||||
|
String sql = "SELECT Name, Description, ClassName, Help FROM AD_Form WHERE AD_Form_ID=?";
|
||||||
|
boolean trl = !Env.isBaseLanguage(ctx, "AD_Form");
|
||||||
|
if (trl)
|
||||||
|
sql = "SELECT t.Name, t.Description, f.ClassName, t.Help "
|
||||||
|
+ "FROM AD_Form f INNER JOIN AD_Form_Trl t"
|
||||||
|
+ " ON (f.AD_Form_ID=t.AD_Form_ID AND AD_Language=?)"
|
||||||
|
+ "WHERE f.AD_Form_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, null);
|
||||||
|
if (trl)
|
||||||
|
{
|
||||||
|
pstmt.setString(1, Env.getAD_Language(ctx));
|
||||||
|
pstmt.setInt(2, AD_Form_ID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pstmt.setInt(1, AD_Form_ID);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
if (rs.next())
|
||||||
|
{
|
||||||
|
name = rs.getString(1);
|
||||||
|
m_Description = rs.getString(2);
|
||||||
|
className = rs.getString(3);
|
||||||
|
m_Help = rs.getString(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null; pstmt = null;
|
||||||
|
}
|
||||||
|
if (className == null)
|
||||||
|
return false;
|
||||||
|
//
|
||||||
|
return openForm(AD_Form_ID, className, name);
|
||||||
|
} // openForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open Form
|
||||||
|
* @param AD_Form_ID Form
|
||||||
|
* @param className class name
|
||||||
|
* @param name title
|
||||||
|
* @return true if started
|
||||||
|
*/
|
||||||
|
protected boolean openForm (int AD_Form_ID, String className, String name)
|
||||||
|
{
|
||||||
|
log.info("AD_Form_ID=" + AD_Form_ID + " - Class=" + className);
|
||||||
|
Properties ctx = Env.getCtx();
|
||||||
|
Env.setContext(ctx, m_WindowNo, "WindowName", name);
|
||||||
|
setTitle(Env.getHeader(ctx, m_WindowNo));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create instance w/o parameters
|
||||||
|
m_panel = (FormPanel)Class.forName(className).newInstance();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "Class=" + className + ", AD_Form_ID=" + AD_Form_ID, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
m_panel.init(m_WindowNo, this);
|
||||||
|
p_AD_Form_ID = AD_Form_ID;
|
||||||
|
return true;
|
||||||
|
} // openForm
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Form Panel
|
||||||
|
* @return form panel
|
||||||
|
*/
|
||||||
|
public FormPanel getFormPanel()
|
||||||
|
{
|
||||||
|
return m_panel;
|
||||||
|
} // getFormPanel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action Listener
|
||||||
|
* @param e event
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
String cmd = e.getActionCommand();
|
||||||
|
if (cmd.equals("End"))
|
||||||
|
dispose();
|
||||||
|
else if (cmd.equals("Help"))
|
||||||
|
actionHelp();
|
||||||
|
else if (!AEnv.actionPerformed(cmd, m_WindowNo, this))
|
||||||
|
log.log(Level.SEVERE, "Not handeled=" + cmd);
|
||||||
|
} // actionPerformed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show Help
|
||||||
|
*/
|
||||||
|
private void actionHelp()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
if (m_Description != null && m_Description.length() > 0)
|
||||||
|
sb.append("<h2>").append(m_Description).append("</h2>");
|
||||||
|
if (m_Help != null && m_Help.length() > 0)
|
||||||
|
sb.append("<p>").append(m_Help);
|
||||||
|
Help hlp = new Help (Env.getFrame(this), this.getTitle(), sb.toString());
|
||||||
|
hlp.setVisible(true);
|
||||||
|
} // actionHelp
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Set Window Busy
|
||||||
|
* @param busy busy
|
||||||
|
*/
|
||||||
|
public void setBusy (boolean busy)
|
||||||
|
{
|
||||||
|
if (busy == m_glassPane.isVisible())
|
||||||
|
return;
|
||||||
|
log.info("Busy=" + busy);
|
||||||
|
if (busy)
|
||||||
|
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
else
|
||||||
|
setCursor(Cursor.getDefaultCursor());
|
||||||
|
m_glassPane.setMessage(null);
|
||||||
|
m_glassPane.setVisible(busy);
|
||||||
|
m_glassPane.requestFocus();
|
||||||
|
} // setBusy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Busy Message
|
||||||
|
* @param AD_Message message
|
||||||
|
*/
|
||||||
|
public void setBusyMessage (String AD_Message)
|
||||||
|
{
|
||||||
|
m_glassPane.setMessage(AD_Message);
|
||||||
|
} // setBusyMessage
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set and start Busy Counter
|
||||||
|
* @param time in seconds
|
||||||
|
*/
|
||||||
|
public void setBusyTimer (int time)
|
||||||
|
{
|
||||||
|
m_glassPane.setBusyTimer (time);
|
||||||
|
} // setBusyTimer
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Maximize Window
|
||||||
|
* @param max maximize
|
||||||
|
*/
|
||||||
|
public void setMaximize (boolean max)
|
||||||
|
{
|
||||||
|
m_maximize = max;
|
||||||
|
} // setMaximize
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form Window Opened.
|
||||||
|
* Maximize window if required
|
||||||
|
* @param evt event
|
||||||
|
*/
|
||||||
|
private void formWindowOpened(java.awt.event.WindowEvent evt)
|
||||||
|
{
|
||||||
|
if (m_maximize == true)
|
||||||
|
{
|
||||||
|
super.setVisible(true);
|
||||||
|
super.setExtendedState(JFrame.MAXIMIZED_BOTH);
|
||||||
|
}
|
||||||
|
} // formWindowOpened
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Batch
|
||||||
|
* @param process
|
||||||
|
* @return running thread
|
||||||
|
*/
|
||||||
|
public Thread startBatch (final Runnable process)
|
||||||
|
{
|
||||||
|
Thread worker = new Thread()
|
||||||
|
{
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
setBusy(true);
|
||||||
|
process.run();
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
worker.start();
|
||||||
|
return worker;
|
||||||
|
} // startBatch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the AD_Form_ID.
|
||||||
|
*/
|
||||||
|
public int getAD_Form_ID ()
|
||||||
|
{
|
||||||
|
return p_AD_Form_ID;
|
||||||
|
} // getAD_Window_ID
|
||||||
|
|
||||||
|
} // FormFrame
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,524 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.grid.ed;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import org.compiere.apps.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import org.compiere.swing.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
|
||||||
|
import org.adempiere.interfaces.*;
|
||||||
|
import org.adempiere.model.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog to enter Location Info (Address)
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: VLocationDialog.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $
|
||||||
|
*
|
||||||
|
* @author Teo Sarca, SC ARHIPAC SERVICE SRL
|
||||||
|
* <li>BF [ 1831060 ] Location dialog should use Address1, Address2 ... elements
|
||||||
|
*/
|
||||||
|
public class VLocationDialog extends CDialog
|
||||||
|
implements ActionListener
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Lookup result */
|
||||||
|
//private Object[][] data = null;
|
||||||
|
|
||||||
|
/** Lookup result header */
|
||||||
|
private Object[] header = null;
|
||||||
|
|
||||||
|
//private int m_WindowNo = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param frame parent
|
||||||
|
* @param title title (field name)
|
||||||
|
* @param location Model Location
|
||||||
|
*/
|
||||||
|
public VLocationDialog (Frame frame, String title, MLocation location)
|
||||||
|
{
|
||||||
|
super(frame, title, true);
|
||||||
|
//m_WindowNo = WindowNo;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
jbInit();
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, ex.getMessage());
|
||||||
|
}
|
||||||
|
m_location = location;
|
||||||
|
if (m_location == null)
|
||||||
|
m_location = new MLocation (Env.getCtx(), 0, null);
|
||||||
|
// Overwrite title
|
||||||
|
if (m_location.getC_Location_ID() == 0)
|
||||||
|
setTitle(Msg.getMsg(Env.getCtx(), "LocationNew"));
|
||||||
|
else
|
||||||
|
setTitle(Msg.getMsg(Env.getCtx(), "LocationUpdate"));
|
||||||
|
|
||||||
|
// Current Country
|
||||||
|
MCountry.setDisplayLanguage(Env.getAD_Language(Env.getCtx()));
|
||||||
|
fCountry = new CComboBox(MCountry.getCountries(Env.getCtx()));
|
||||||
|
fCountry.setSelectedItem(m_location.getCountry());
|
||||||
|
m_origCountry_ID = m_location.getC_Country_ID();
|
||||||
|
// Current Region
|
||||||
|
fRegion = new CComboBox(MRegion.getRegions(Env.getCtx(), m_origCountry_ID));
|
||||||
|
if (m_location.getCountry().isHasRegion())
|
||||||
|
lRegion.setText(m_location.getCountry().getRegionName()); // name for region
|
||||||
|
fRegion.setSelectedItem(m_location.getRegion());
|
||||||
|
//
|
||||||
|
initLocation();
|
||||||
|
fCountry.addActionListener(this);
|
||||||
|
fOnline.addActionListener(this);
|
||||||
|
AEnv.positionCenterWindow(frame, this);
|
||||||
|
|
||||||
|
|
||||||
|
} // VLocationDialog
|
||||||
|
|
||||||
|
private boolean m_change = false;
|
||||||
|
private MLocation m_location;
|
||||||
|
private int m_origCountry_ID;
|
||||||
|
private int s_oldCountry_ID = 0;
|
||||||
|
/** Logger */
|
||||||
|
private static CLogger log = CLogger.getCLogger(VLocationDialog.class);
|
||||||
|
|
||||||
|
private CPanel panel = new CPanel();
|
||||||
|
private CPanel mainPanel = new CPanel();
|
||||||
|
private CPanel southPanel = new CPanel();
|
||||||
|
private BorderLayout panelLayout = new BorderLayout();
|
||||||
|
private GridBagLayout gridBagLayout = new GridBagLayout();
|
||||||
|
private ConfirmPanel confirmPanel = new ConfirmPanel(true);
|
||||||
|
private BorderLayout southLayout = new BorderLayout();
|
||||||
|
//
|
||||||
|
private CLabel lAddress1 = new CLabel(Msg.getElement(Env.getCtx(), "Address1"));
|
||||||
|
private CLabel lAddress2 = new CLabel(Msg.getElement(Env.getCtx(), "Address2"));
|
||||||
|
private CLabel lAddress3 = new CLabel(Msg.getElement(Env.getCtx(), "Address3"));
|
||||||
|
private CLabel lAddress4 = new CLabel(Msg.getElement(Env.getCtx(), "Address4"));
|
||||||
|
private CLabel lCity = new CLabel(Msg.getMsg(Env.getCtx(), "City"));
|
||||||
|
private CLabel lCountry = new CLabel(Msg.getMsg(Env.getCtx(), "Country"));
|
||||||
|
private CLabel lRegion = new CLabel(Msg.getMsg(Env.getCtx(), "Region"));
|
||||||
|
private CLabel lPostal = new CLabel(Msg.getMsg(Env.getCtx(), "Postal"));
|
||||||
|
private CLabel lPostalAdd = new CLabel(Msg.getMsg(Env.getCtx(), "PostalAdd"));
|
||||||
|
private CLabel lOnline = new CLabel(""); // dummy to use addLine without error....
|
||||||
|
private CTextField fAddress1 = new CTextField(20); // length=60
|
||||||
|
private CTextField fAddress2 = new CTextField(20); // length=60
|
||||||
|
private CTextField fAddress3 = new CTextField(20); // length=60
|
||||||
|
private CTextField fAddress4 = new CTextField(20); // length=60
|
||||||
|
private CTextField fCity = new CTextField(15); // length=60
|
||||||
|
private CComboBox fCountry;
|
||||||
|
private CComboBox fRegion;
|
||||||
|
private CTextField fPostal = new CTextField(5); // length=10
|
||||||
|
private CTextField fPostalAdd = new CTextField(5); // length=10
|
||||||
|
private CButton fOnline = new CButton();
|
||||||
|
//
|
||||||
|
private GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
private Insets labelInsets = new Insets(2,15,2,0); // top,left,bottom,right
|
||||||
|
private Insets fieldInsets = new Insets(2,5,2,10);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static component init
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
void jbInit() throws Exception
|
||||||
|
{
|
||||||
|
panel.setLayout(panelLayout);
|
||||||
|
southPanel.setLayout(southLayout);
|
||||||
|
mainPanel.setLayout(gridBagLayout);
|
||||||
|
panelLayout.setHgap(5);
|
||||||
|
panelLayout.setVgap(10);
|
||||||
|
getContentPane().add(panel);
|
||||||
|
panel.add(mainPanel, BorderLayout.CENTER);
|
||||||
|
panel.add(southPanel, BorderLayout.SOUTH);
|
||||||
|
southPanel.add(confirmPanel, BorderLayout.NORTH);
|
||||||
|
//
|
||||||
|
confirmPanel.addActionListener(this);
|
||||||
|
} // jbInit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynanmic Init & fill fields - Called when Country changes!
|
||||||
|
*/
|
||||||
|
private void initLocation()
|
||||||
|
{
|
||||||
|
MCountry country = m_location.getCountry();
|
||||||
|
log.fine(country.getName() + ", Region=" + country.isHasRegion() + " " + country.getDisplaySequence()
|
||||||
|
+ ", C_Location_ID=" + m_location.getC_Location_ID());
|
||||||
|
// new Region
|
||||||
|
if (m_location.getC_Country_ID() != s_oldCountry_ID && country.isHasRegion())
|
||||||
|
{
|
||||||
|
fRegion = new CComboBox(MRegion.getRegions(Env.getCtx(), country.getC_Country_ID()));
|
||||||
|
if (m_location.getRegion() != null)
|
||||||
|
fRegion.setSelectedItem(m_location.getRegion());
|
||||||
|
lRegion.setText(country.getRegionName());
|
||||||
|
s_oldCountry_ID = m_location.getC_Country_ID();
|
||||||
|
}
|
||||||
|
|
||||||
|
gbc.anchor = GridBagConstraints.NORTHWEST;
|
||||||
|
gbc.gridy = 0; // line
|
||||||
|
gbc.gridx = 0;
|
||||||
|
gbc.gridwidth = 1;
|
||||||
|
gbc.insets = fieldInsets;
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.weightx = 0;
|
||||||
|
gbc.weighty = 0;
|
||||||
|
|
||||||
|
mainPanel.add(Box.createVerticalStrut(5), gbc); // top gap
|
||||||
|
|
||||||
|
int line = 1;
|
||||||
|
addLine(line++, lAddress1, fAddress1);
|
||||||
|
addLine(line++, lAddress2, fAddress2);
|
||||||
|
addLine(line++, lAddress3, fAddress3);
|
||||||
|
addLine(line++, lAddress4, fAddress4);
|
||||||
|
|
||||||
|
// sequence of City Postal Region - @P@ @C@ - @C@, @R@ @P@
|
||||||
|
String ds = country.getDisplaySequence();
|
||||||
|
if (ds == null || ds.length() == 0)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "DisplaySequence empty - " + country);
|
||||||
|
ds = ""; // @C@, @P@
|
||||||
|
}
|
||||||
|
StringTokenizer st = new StringTokenizer(ds, "@", false);
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String s = st.nextToken();
|
||||||
|
if (s.startsWith("C"))
|
||||||
|
addLine(line++, lCity, fCity);
|
||||||
|
else if (s.startsWith("P"))
|
||||||
|
addLine(line++, lPostal, fPostal);
|
||||||
|
else if (s.startsWith("A"))
|
||||||
|
addLine(line++, lPostalAdd, fPostalAdd);
|
||||||
|
else if (s.startsWith("R") && m_location.getCountry().isHasRegion())
|
||||||
|
addLine(line++, lRegion, fRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addLine(line++, lOnline, fOnline);
|
||||||
|
|
||||||
|
// Country Last
|
||||||
|
addLine(line++, lCountry, fCountry);
|
||||||
|
|
||||||
|
// Fill it
|
||||||
|
if (m_location.getC_Location_ID() != 0)
|
||||||
|
{
|
||||||
|
fAddress1.setText(m_location.getAddress1());
|
||||||
|
fAddress2.setText(m_location.getAddress2());
|
||||||
|
fAddress3.setText(m_location.getAddress3());
|
||||||
|
fAddress4.setText(m_location.getAddress4());
|
||||||
|
fCity.setText(m_location.getCity());
|
||||||
|
fPostal.setText(m_location.getPostal());
|
||||||
|
fPostalAdd.setText(m_location.getPostal_Add());
|
||||||
|
fOnline.setText(Msg.getMsg(Env.getCtx(), "Online"));
|
||||||
|
if (m_location.getCountry().isHasRegion())
|
||||||
|
{
|
||||||
|
lRegion.setText(m_location.getCountry().getRegionName());
|
||||||
|
fRegion.setSelectedItem(m_location.getRegion());
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable online if this country doesn't have post code lookup
|
||||||
|
if (m_location.getCountry().isPostcodeLookup()) {
|
||||||
|
fOnline.setEnabled(true);
|
||||||
|
fOnline.setVisible(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fOnline.setEnabled(false);
|
||||||
|
fOnline.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fCountry.setSelectedItem(country);
|
||||||
|
}
|
||||||
|
// Update UI
|
||||||
|
pack();
|
||||||
|
} // initLocation
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Line to screen
|
||||||
|
*
|
||||||
|
* @param line line number (zero based)
|
||||||
|
* @param label label
|
||||||
|
* @param field field
|
||||||
|
*/
|
||||||
|
private void addLine(int line, JLabel label, JComponent field)
|
||||||
|
{
|
||||||
|
gbc.gridy = line;
|
||||||
|
// label
|
||||||
|
gbc.insets = labelInsets;
|
||||||
|
gbc.gridx = 0;
|
||||||
|
gbc.weightx = 0.0;
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
label.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||||
|
mainPanel.add(label, gbc);
|
||||||
|
// Field
|
||||||
|
gbc.insets = fieldInsets;
|
||||||
|
gbc.gridx = 1;
|
||||||
|
gbc.weightx = 1.0;
|
||||||
|
gbc.fill = GridBagConstraints.NONE;
|
||||||
|
gbc.insets = fieldInsets;
|
||||||
|
mainPanel.add(field, gbc);
|
||||||
|
|
||||||
|
} // addLine
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ActionListener
|
||||||
|
* @param e ActionEvent
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
if (e.getActionCommand().equals(ConfirmPanel.A_OK))
|
||||||
|
{
|
||||||
|
action_OK();
|
||||||
|
m_change = true;
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
else if (e.getActionCommand().equals(ConfirmPanel.A_CANCEL))
|
||||||
|
{
|
||||||
|
m_change = false;
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Country Changed - display in new Format
|
||||||
|
else if (e.getSource() == fCountry)
|
||||||
|
{
|
||||||
|
// Modifier for Mouse selection is 16 - for any key selection 0
|
||||||
|
MCountry c = (MCountry)fCountry.getSelectedItem();
|
||||||
|
m_location.setCountry(c);
|
||||||
|
|
||||||
|
// refresh online button for new country
|
||||||
|
if (c.isPostcodeLookup()) {
|
||||||
|
fOnline.setEnabled(true);
|
||||||
|
fOnline.setVisible(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fOnline.setEnabled(false);
|
||||||
|
fOnline.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the region name if regions are enabled for this country
|
||||||
|
if (c.isHasRegion())
|
||||||
|
{
|
||||||
|
lRegion.setText(c.getRegionName());
|
||||||
|
fRegion.setSelectedItem(m_location.getRegion());
|
||||||
|
|
||||||
|
// TODO: fix bug that occurs when the new region name is shorter than the old region name
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh
|
||||||
|
mainPanel.removeAll();
|
||||||
|
|
||||||
|
initLocation();
|
||||||
|
fCountry.requestFocus(); // allows to use Keybord selection
|
||||||
|
}
|
||||||
|
else if (e.getSource() == fOnline)
|
||||||
|
{
|
||||||
|
|
||||||
|
// check to see if we have a postcode lookup plugin for this country
|
||||||
|
MCountry c = (MCountry)fCountry.getSelectedItem();
|
||||||
|
if (c.isPostcodeLookup())
|
||||||
|
{
|
||||||
|
lookupPostcode(c, fPostal.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // actionPerformed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OK - check for changes (save them) & Exit
|
||||||
|
*/
|
||||||
|
private void action_OK()
|
||||||
|
{
|
||||||
|
m_location.setAddress1(fAddress1.getText());
|
||||||
|
m_location.setAddress2(fAddress2.getText());
|
||||||
|
m_location.setAddress3(fAddress3.getText());
|
||||||
|
m_location.setAddress4(fAddress4.getText());
|
||||||
|
m_location.setCity(fCity.getText());
|
||||||
|
m_location.setPostal(fPostal.getText());
|
||||||
|
m_location.setPostal_Add(fPostalAdd.getText());
|
||||||
|
// Country/Region
|
||||||
|
MCountry c = (MCountry)fCountry.getSelectedItem();
|
||||||
|
m_location.setCountry(c);
|
||||||
|
if (m_location.getCountry().isHasRegion())
|
||||||
|
{
|
||||||
|
MRegion r = (MRegion)fRegion.getSelectedItem();
|
||||||
|
m_location.setRegion(r);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_location.setC_Region_ID(0);
|
||||||
|
// Save changes
|
||||||
|
m_location.save();
|
||||||
|
} // actionOK
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get result
|
||||||
|
* @return true, if changed
|
||||||
|
*/
|
||||||
|
public boolean isChanged()
|
||||||
|
{
|
||||||
|
return m_change;
|
||||||
|
} // getChange
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get edited Value (MLocation)
|
||||||
|
* @return location
|
||||||
|
*/
|
||||||
|
public MLocation getValue()
|
||||||
|
{
|
||||||
|
return m_location;
|
||||||
|
} // getValue
|
||||||
|
/**
|
||||||
|
* lookupPostcode
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param country
|
||||||
|
* @param postcode
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String lookupPostcode(MCountry country, String postcode)
|
||||||
|
{
|
||||||
|
// Initialise the lookup class.
|
||||||
|
PostcodeLookupInterface pcLookup = null;
|
||||||
|
try {
|
||||||
|
PostcodeLookupInterface pcLookupTmp = (PostcodeLookupInterface) Class
|
||||||
|
.forName(country.getLookupClassName()).newInstance();
|
||||||
|
pcLookup = pcLookupTmp.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "lookupAddress(): " + e.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove any spaces from the postcode and convert to upper case
|
||||||
|
postcode = postcode.replaceAll(" ", "").toUpperCase();
|
||||||
|
log.fine("Looking up postcode: " + postcode);
|
||||||
|
|
||||||
|
// Lookup postcode on server.
|
||||||
|
pcLookup.setServerUrl(country.getLookupUrl());
|
||||||
|
pcLookup.setClientID(country.getLookupClientID());
|
||||||
|
pcLookup.setPassword(country.getLookupPassword());
|
||||||
|
if (pcLookup.lookupPostcode(postcode)==1){
|
||||||
|
// Success
|
||||||
|
fillLocation(pcLookup.getPostCodeData(), country);
|
||||||
|
fAddress1.requestFocusInWindow();
|
||||||
|
} else
|
||||||
|
return "Postcode Lookup Error";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Fills the location field using the information retrieved from postcode
|
||||||
|
* servers.
|
||||||
|
*
|
||||||
|
* @param ctx
|
||||||
|
* Context
|
||||||
|
* @param pkeyData
|
||||||
|
* Lookup results
|
||||||
|
* @param windowNo
|
||||||
|
* Window No.
|
||||||
|
* @param tab
|
||||||
|
* Tab
|
||||||
|
* @param field
|
||||||
|
* Field
|
||||||
|
*/
|
||||||
|
private void fillLocation(HashMap<String, Object> postcodeData, MCountry country) {
|
||||||
|
|
||||||
|
// If it's not empty warn the user.
|
||||||
|
if (fAddress1 != null || fAddress2 != null
|
||||||
|
|| fAddress3 != null
|
||||||
|
|| fAddress4 != null || fCity != null) {
|
||||||
|
String warningMsg = "Existing address information will be overwritten. Proceed?";
|
||||||
|
String warningTitle = "Warning";
|
||||||
|
int response = JOptionPane.showConfirmDialog(null, warningMsg,
|
||||||
|
warningTitle, JOptionPane.YES_NO_OPTION);
|
||||||
|
if (response == JOptionPane.NO_OPTION)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Set<String> pcodeKeys = postcodeData.keySet();
|
||||||
|
Iterator<String> iterator = pcodeKeys.iterator();
|
||||||
|
header = null;
|
||||||
|
|
||||||
|
// Allocate the header array
|
||||||
|
header = new Object[pcodeKeys.size()];
|
||||||
|
|
||||||
|
String headerStr = null;
|
||||||
|
|
||||||
|
// need to check how many records returned
|
||||||
|
// TODO - check number of records returns - size() method is incorrect
|
||||||
|
if (pcodeKeys.size() > 2)
|
||||||
|
{
|
||||||
|
// TODO: Implement ResultData Grid and get return (for premises level data)
|
||||||
|
System.out.println("Too many postcodes returned from Postcode Lookup - need to Implement ResultData");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
for (int i = 0; (headerStr = (iterator.hasNext() ? iterator.next() : null)) != null
|
||||||
|
|| iterator.hasNext(); i++) {
|
||||||
|
header[i] = headerStr;
|
||||||
|
Postcode values = (Postcode) postcodeData.get(headerStr);
|
||||||
|
|
||||||
|
// Overwrite the values in location field.
|
||||||
|
fAddress1.setText(values.getStreet1());
|
||||||
|
fCity.setText(values.getCity());
|
||||||
|
fPostal.setText(values.getPostcode());
|
||||||
|
|
||||||
|
// Do region lookup
|
||||||
|
if (country.isHasRegion())
|
||||||
|
{
|
||||||
|
// get all regions for this country
|
||||||
|
MRegion[] regions = MRegion.getRegions(country.getCtx(), country.getC_Country_ID());
|
||||||
|
|
||||||
|
// If regions were loaded
|
||||||
|
if ( regions.length > 0)
|
||||||
|
{
|
||||||
|
// loop through regions array to attempt a region match - don't finish loop if region found
|
||||||
|
boolean found = false;
|
||||||
|
for (i = 0; i < regions.length && !found; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (regions[i].getName().equals(values.getRegion()) )
|
||||||
|
{
|
||||||
|
// found county
|
||||||
|
fRegion.setSelectedItem(regions[i]);
|
||||||
|
log.fine("Found region: " + regions[i].getName());
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
// add new region
|
||||||
|
MRegion region = new MRegion(country, values.getRegion());
|
||||||
|
if (region.save())
|
||||||
|
{
|
||||||
|
log.fine("Added new region from web service: " + values.getRegion());
|
||||||
|
fRegion.setSelectedItem(values);
|
||||||
|
} else
|
||||||
|
log.severe("Error saving new region: " + region.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
log.severe("Region lookup failed for Country: " + country.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // VLocationDialog
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,114 @@
|
||||||
|
CREATE OR REPLACE VIEW C_INVOICE_LINETAX_V
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, C_INVOICE_ID, C_INVOICELINE_ID,
|
||||||
|
C_TAX_ID, TAXAMT, LINETOTALAMT, TAXINDICATOR, LINE,
|
||||||
|
M_PRODUCT_ID, QTYINVOICED, QTYENTERED, UOMSYMBOL, NAME,
|
||||||
|
DESCRIPTION, DOCUMENTNOTE, UPC, SKU, PRODUCTVALUE,
|
||||||
|
RESOURCEDESCRIPTION, PRICELIST, PRICEENTEREDLIST, DISCOUNT, PRICEACTUAL,
|
||||||
|
PRICEENTERED, LINENETAMT, M_ATTRIBUTESETINSTANCE_ID, M_ATTRIBUTESET_ID, SERNO,
|
||||||
|
LOT, M_LOT_ID, GUARANTEEDATE, PRODUCTDESCRIPTION, IMAGEURL,
|
||||||
|
C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID, C_PROJECTPHASE_ID, C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
il.C_Tax_ID, il.TaxAmt, il.LineTotalAmt, t.TaxIndicator,
|
||||||
|
il.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN il.QtyInvoiced<>0 OR il.M_Product_ID IS NOT NULL THEN il.QtyInvoiced END AS QtyInvoiced,
|
||||||
|
CASE WHEN il.QtyEntered<>0 OR il.M_Product_ID IS NOT NULL THEN il.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN il.QtyEntered<>0 OR il.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
COALESCE(c.Name,p.Name||productAttribute(il.M_AttributeSetInstance_ID), il.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(c.Name,p.Name) IS NOT NULL THEN il.Description END AS Description, -- second line
|
||||||
|
p.DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, COALESCE(pp.VendorProductNo,p.Value) AS ProductValue,
|
||||||
|
ra.Description AS ResourceDescription, -- forth line
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList<>0
|
||||||
|
THEN il.PriceList END AS PriceList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList<>0 AND il.QtyEntered<>0
|
||||||
|
THEN il.PriceList*il.QtyInvoiced/il.QtyEntered END AS PriceEnteredList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList>il.PriceActual AND il.PriceList<>0
|
||||||
|
THEN (il.PriceList-il.PriceActual)/il.PriceList*100 END AS Discount,
|
||||||
|
CASE WHEN il.PriceActual<>0 OR il.M_Product_ID IS NOT NULL THEN il.PriceActual END AS PriceActual,
|
||||||
|
CASE WHEN il.PriceEntered<>0 OR il.M_Product_ID IS NOT NULL THEN il.PriceEntered END AS PriceEntered,
|
||||||
|
CASE WHEN il.LineNetAmt<>0 OR il.M_Product_ID IS NOT NULL THEN il.LineNetAmt END AS LineNetAmt,
|
||||||
|
il.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID,
|
||||||
|
asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
p.Description as ProductDescription, p.ImageURL,
|
||||||
|
il.C_Campaign_ID, il.C_Project_ID, il.C_Activity_ID, il.C_ProjectPhase_ID, il.C_ProjectTask_ID
|
||||||
|
FROM C_InvoiceLine il
|
||||||
|
INNER JOIN C_UOM uom ON (il.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN C_Invoice i ON (il.C_Invoice_ID=i.C_Invoice_ID)
|
||||||
|
LEFT OUTER JOIN C_Tax t ON (il.C_Tax_ID=t.C_Tax_ID)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (il.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (il.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
LEFT OUTER JOIN C_BPartner_Product pp ON (il.M_Product_ID=pp.M_Product_ID AND i.C_BPartner_ID=pp.C_BPartner_ID)
|
||||||
|
LEFT OUTER JOIN S_ResourceAssignment ra ON (il.S_ResourceAssignment_ID=ra.S_ResourceAssignment_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (il.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
UNION -- bom lines
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
il.C_Tax_ID, il.TaxAmt, il.LineTotalAmt, t.TaxIndicator,
|
||||||
|
il.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
il.QtyInvoiced*b.BOMQty AS QtyInvoiced,
|
||||||
|
il.QtyEntered*b.BOMQty AS QtyEntered,
|
||||||
|
uom.UOMSymbol,
|
||||||
|
p.Name, -- main
|
||||||
|
b.Description,
|
||||||
|
p.DocumentNote, p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
null, null, null, null, null, null, null,
|
||||||
|
il.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
p.Description as ProductDescription, p.ImageURL,
|
||||||
|
il.C_Campaign_ID, il.C_Project_ID, il.C_Activity_ID, il.C_ProjectPhase_ID, il.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN C_InvoiceLine il ON (b.M_Product_ID=il.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=il.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsInvoicePrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
LEFT OUTER JOIN C_Tax t ON (il.C_Tax_ID=t.C_Tax_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (il.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
UNION -- comment lines
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
'en_US', il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
null, null, null, null,
|
||||||
|
il.Line, null,
|
||||||
|
null, null, null,
|
||||||
|
il.Description,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null
|
||||||
|
FROM C_InvoiceLine il
|
||||||
|
WHERE il.C_UOM_ID IS NULL
|
||||||
|
UNION -- empty line
|
||||||
|
SELECT AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy, Updated, UpdatedBy,
|
||||||
|
'en_US', C_Invoice_ID, null,
|
||||||
|
null, null, null, null,
|
||||||
|
9998, null,
|
||||||
|
null, null, null,
|
||||||
|
null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null
|
||||||
|
FROM C_Invoice
|
||||||
|
UNION -- tax lines
|
||||||
|
SELECT it.AD_Client_ID, it.AD_Org_ID, it.IsActive, it.Created, it.CreatedBy, it.Updated, it.UpdatedBy,
|
||||||
|
'en_US', it.C_Invoice_ID, null,
|
||||||
|
it.C_Tax_ID, null, null, t.TaxIndicator,
|
||||||
|
9999, null,
|
||||||
|
null, null, null,
|
||||||
|
t.Name,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN it.TaxAmt ELSE it.TaxBaseAmt END,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN it.TaxAmt ELSE it.TaxBaseAmt END,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN NULL ELSE it.TaxAmt END,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null
|
||||||
|
FROM C_InvoiceTax it
|
||||||
|
INNER JOIN C_Tax t ON (it.C_Tax_ID=t.C_Tax_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
CREATE OR REPLACE VIEW C_INVOICE_LINETAX_VT
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, C_INVOICE_ID, C_INVOICELINE_ID,
|
||||||
|
C_TAX_ID, TAXAMT, LINETOTALAMT, TAXINDICATOR, LINE,
|
||||||
|
M_PRODUCT_ID, QTYINVOICED, QTYENTERED, UOMSYMBOL, NAME,
|
||||||
|
DESCRIPTION, DOCUMENTNOTE, UPC, SKU, PRODUCTVALUE,
|
||||||
|
RESOURCEDESCRIPTION, PRICELIST, PRICEENTEREDLIST, DISCOUNT, PRICEACTUAL,
|
||||||
|
PRICEENTERED, LINENETAMT, M_ATTRIBUTESETINSTANCE_ID, M_ATTRIBUTESET_ID, SERNO,
|
||||||
|
LOT, M_LOT_ID, GUARANTEEDATE, PRODUCTDESCRIPTION, IMAGEURL,
|
||||||
|
C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID, C_PROJECTPHASE_ID, C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
il.C_Tax_ID, il.TaxAmt, il.LineTotalAmt, t.TaxIndicator,
|
||||||
|
il.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN il.QtyInvoiced<>0 OR il.M_Product_ID IS NOT NULL THEN il.QtyInvoiced END AS QtyInvoiced,
|
||||||
|
CASE WHEN il.QtyEntered<>0 OR il.M_Product_ID IS NOT NULL THEN il.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN il.QtyEntered<>0 OR il.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
COALESCE(c.Name,COALESCE(pt.Name,p.Name)||productAttribute(il.M_AttributeSetInstance_ID), il.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(c.Name,pt.Name,p.Name) IS NOT NULL THEN il.Description END AS Description, -- second line
|
||||||
|
COALESCE(pt.DocumentNote,p.DocumentNote) AS DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, COALESCE(pp.VendorProductNo,p.Value) AS ProductValue,
|
||||||
|
ra.Description AS ResourceDescription, -- forth line
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList<>0
|
||||||
|
THEN il.PriceList END AS PriceList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList<>0 AND il.QtyEntered<>0
|
||||||
|
THEN il.PriceList*il.QtyInvoiced/il.QtyEntered END AS PriceEnteredList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND il.PriceList>il.PriceActual AND il.PriceList<>0
|
||||||
|
THEN (il.PriceList-il.PriceActual)/il.PriceList*100 END AS Discount,
|
||||||
|
CASE WHEN il.PriceActual<>0 OR il.M_Product_ID IS NOT NULL THEN il.PriceActual END AS PriceActual,
|
||||||
|
CASE WHEN il.PriceEntered<>0 OR il.M_Product_ID IS NOT NULL THEN il.PriceEntered END AS PriceEntered,
|
||||||
|
CASE WHEN il.LineNetAmt<>0 OR il.M_Product_ID IS NOT NULL THEN il.LineNetAmt END AS LineNetAmt,
|
||||||
|
il.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
pt.Description as ProductDescription, p.ImageURL,
|
||||||
|
il.C_Campaign_ID, il.C_Project_ID, il.C_Activity_ID, il.C_ProjectPhase_ID, il.C_ProjectTask_ID
|
||||||
|
FROM C_InvoiceLine il
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (il.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN C_Invoice i ON (il.C_Invoice_ID=i.C_Invoice_ID)
|
||||||
|
LEFT OUTER JOIN C_Tax_Trl t ON (il.C_Tax_ID=t.C_Tax_ID AND uom.AD_Language=t.AD_Language)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (il.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (il.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
LEFT OUTER JOIN C_BPartner_Product pp ON (il.M_Product_ID=pp.M_Product_ID AND i.C_BPartner_ID=pp.C_BPartner_ID)
|
||||||
|
LEFT OUTER JOIN M_Product_Trl pt ON (il.M_Product_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
LEFT OUTER JOIN S_ResourceAssignment ra ON (il.S_ResourceAssignment_ID=ra.S_ResourceAssignment_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (il.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
UNION -- bom lines
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
il.C_Tax_ID, il.TaxAmt, il.LineTotalAmt, t.TaxIndicator,
|
||||||
|
il.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
il.QtyInvoiced*b.BOMQty AS QtyInvoiced,
|
||||||
|
il.QtyEntered*b.BOMQty AS QtyEntered,
|
||||||
|
uom.UOMSymbol,
|
||||||
|
COALESCE(pt.Name,p.Name) AS Name, -- main
|
||||||
|
b.Description,
|
||||||
|
COALESCE(pt.DocumentNote,p.DocumentNote) AS DocumentNote, p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
null, null, null, null, null, null, null,
|
||||||
|
il.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
pt.Description as ProductDescription, p.ImageURL,
|
||||||
|
il.C_Campaign_ID, il.C_Project_ID, il.C_Activity_ID, il.C_ProjectPhase_ID, il.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN C_InvoiceLine il ON (b.M_Product_ID=il.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=il.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsInvoicePrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN M_Product_Trl pt ON (b.M_ProductBOM_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
LEFT OUTER JOIN C_Tax t ON (il.C_Tax_ID=t.C_Tax_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (il.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
UNION -- comment line
|
||||||
|
SELECT il.AD_Client_ID, il.AD_Org_ID, il.IsActive, il.Created, il.CreatedBy, il.Updated, il.UpdatedBy,
|
||||||
|
l.AD_Language, il.C_Invoice_ID, il.C_InvoiceLine_ID,
|
||||||
|
null, null, null, null,
|
||||||
|
il.Line, null,
|
||||||
|
null, null, null,
|
||||||
|
il.Description,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_InvoiceLine il, AD_Language l
|
||||||
|
WHERE il.C_UOM_ID IS NULL
|
||||||
|
AND l.IsBaseLanguage='N' AND l.IsSystemLanguage='Y'
|
||||||
|
UNION -- empty line
|
||||||
|
SELECT i.AD_Client_ID, i.AD_Org_ID, i.IsActive, i.Created, i.CreatedBy, i.Updated, i.UpdatedBy,
|
||||||
|
AD_Language, i.C_Invoice_ID, null,
|
||||||
|
null, null, null, null,
|
||||||
|
9998, null,
|
||||||
|
null, null, null,
|
||||||
|
null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_Invoice i, AD_Language l
|
||||||
|
WHERE l.IsBaseLanguage='N' AND l.IsSystemLanguage='Y'
|
||||||
|
UNION -- tax lines
|
||||||
|
SELECT it.AD_Client_ID, it.AD_Org_ID, it.IsActive, it.Created, it.CreatedBy, it.Updated, it.UpdatedBy,
|
||||||
|
t.AD_Language, it.C_Invoice_ID, null,
|
||||||
|
it.C_Tax_ID, null, null, t.TaxIndicator,
|
||||||
|
9999, null,
|
||||||
|
null, null, null,
|
||||||
|
t.Name,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN it.TaxAmt ELSE it.TaxBaseAmt END,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN it.TaxAmt ELSE it.TaxBaseAmt END,
|
||||||
|
CASE WHEN it.IsTaxIncluded='Y' THEN NULL ELSE it.TaxAmt END,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_InvoiceTax it
|
||||||
|
INNER JOIN C_Tax_Trl t ON (it.C_Tax_ID=t.C_Tax_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
CREATE OR REPLACE VIEW C_ORDER_LINETAX_V
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, C_ORDER_ID, C_ORDERLINE_ID,
|
||||||
|
C_TAX_ID, TAXINDICATOR, C_BPARTNER_ID, C_BPARTNER_LOCATION_ID, BPNAME,
|
||||||
|
C_LOCATION_ID, LINE, M_PRODUCT_ID, QTYORDERED, QTYENTERED,
|
||||||
|
UOMSYMBOL, NAME, DESCRIPTION, DOCUMENTNOTE, UPC,
|
||||||
|
SKU, PRODUCTVALUE, RESOURCEDESCRIPTION, PRICELIST, PRICEENTEREDLIST,
|
||||||
|
DISCOUNT, PRICEACTUAL, PRICEENTERED, LINENETAMT, PRODUCTDESCRIPTION,
|
||||||
|
IMAGEURL, C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID, C_PROJECTPHASE_ID,
|
||||||
|
C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT ol.AD_Client_ID, ol.AD_Org_ID, ol.IsActive, ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
ol.C_Order_ID, ol.C_OrderLine_ID, ol.C_Tax_ID, t.TaxIndicator,
|
||||||
|
ol.C_BPartner_ID, ol.C_BPartner_Location_ID, bp.Name AS BPName, bpl.C_Location_ID,
|
||||||
|
ol.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN ol.QtyOrdered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.QtyOrdered END AS QtyOrdered,
|
||||||
|
CASE WHEN ol.QtyEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN ol.QtyEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
COALESCE(c.Name,p.Name||productAttribute(ol.M_AttributeSetInstance_ID), ol.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(c.Name,p.Name) IS NOT NULL THEN ol.Description END AS Description, -- second line
|
||||||
|
p.DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, COALESCE(pp.VendorProductNo,p.Value) AS ProductValue,
|
||||||
|
ra.Description AS ResourceDescription, -- forth line
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList<>0
|
||||||
|
THEN ol.PriceList END AS PriceList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList<>0 AND ol.QtyEntered<>0
|
||||||
|
THEN ol.PriceList*ol.QtyOrdered/ol.QtyEntered END AS PriceEnteredList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList>ol.PriceActual AND ol.PriceList<>0
|
||||||
|
THEN (ol.PriceList-ol.PriceActual)/ol.PriceList*100 END AS Discount,
|
||||||
|
CASE WHEN ol.PriceActual<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.PriceActual END AS PriceActual,
|
||||||
|
CASE WHEN ol.PriceEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.PriceEntered END AS PriceEntered,
|
||||||
|
CASE WHEN ol.LineNetAmt<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.LineNetAmt END AS LineNetAmt,
|
||||||
|
p.Description as ProductDescription, p.ImageURL,
|
||||||
|
ol.C_Campaign_ID, ol.C_Project_ID, ol.C_Activity_ID, ol.C_ProjectPhase_ID, ol.C_ProjectTask_ID
|
||||||
|
FROM C_OrderLine ol
|
||||||
|
INNER JOIN C_UOM uom ON (ol.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN C_Order i ON (ol.C_Order_ID=i.C_Order_ID)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (ol.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN S_ResourceAssignment ra ON (ol.S_ResourceAssignment_ID=ra.S_ResourceAssignment_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (ol.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
LEFT OUTER JOIN C_BPartner_Product pp ON (ol.M_Product_ID=pp.M_Product_ID AND i.C_BPartner_ID=pp.C_BPartner_ID)
|
||||||
|
INNER JOIN C_BPartner bp ON (ol.C_BPartner_ID=bp.C_BPartner_ID)
|
||||||
|
INNER JOIN C_BPartner_Location bpl ON (ol.C_BPartner_Location_ID=bpl.C_BPartner_Location_ID)
|
||||||
|
LEFT OUTER JOIN C_Tax t ON (ol.C_Tax_ID=t.C_Tax_ID)
|
||||||
|
UNION
|
||||||
|
SELECT ol.AD_Client_ID, ol.AD_Org_ID, ol.IsActive, ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
ol.C_Order_ID, ol.C_OrderLine_ID, ol.C_Tax_ID, null,
|
||||||
|
null, null, null, null,
|
||||||
|
ol.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
ol.QtyOrdered*b.BOMQty AS QtyInvoiced, ol.QtyEntered*b.BOMQty AS QtyEntered, uom.UOMSymbol,
|
||||||
|
p.Name, -- main
|
||||||
|
b.Description,
|
||||||
|
p.DocumentNote, p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
null, null, null, null, null, null, null, p.Description as ProductDescription, p.ImageURL,
|
||||||
|
ol.C_Campaign_ID, ol.C_Project_ID, ol.C_Activity_ID, ol.C_ProjectPhase_ID, ol.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN C_OrderLine ol ON (b.M_Product_ID=ol.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=ol.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsInvoicePrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
UNION
|
||||||
|
SELECT AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy, Updated, UpdatedBy,
|
||||||
|
'en_US', C_Order_ID, null, null, null,
|
||||||
|
null,
|
||||||
|
null, null, null,
|
||||||
|
null, null, null, null,
|
||||||
|
null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_Order
|
||||||
|
UNION
|
||||||
|
SELECT ot.AD_Client_ID, ot.AD_Org_ID, ot.IsActive, ot.Created, ot.CreatedBy, ot.Updated, ot.UpdatedBy,
|
||||||
|
'en_US', ot.C_Order_ID, null, ot.C_Tax_ID, t.TaxIndicator,
|
||||||
|
null, null, null, null,
|
||||||
|
null, null,
|
||||||
|
null, null, null,
|
||||||
|
t.Name,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN ot.TaxAmt ELSE ot.TaxBaseAmt END,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN ot.TaxAmt ELSE ot.TaxBaseAmt END,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN NULL ELSE ot.TaxAmt END,
|
||||||
|
null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_OrderTax ot
|
||||||
|
INNER JOIN C_Tax t ON (ot.C_Tax_ID=t.C_Tax_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
CREATE OR REPLACE VIEW C_ORDER_LINETAX_VT
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, C_ORDER_ID, C_ORDERLINE_ID,
|
||||||
|
C_TAX_ID, TAXINDICATOR, C_BPARTNER_ID, C_BPARTNER_LOCATION_ID, BPNAME,
|
||||||
|
C_LOCATION_ID, LINE, M_PRODUCT_ID, QTYORDERED, QTYENTERED,
|
||||||
|
UOMSYMBOL, NAME, DESCRIPTION, DOCUMENTNOTE, UPC,
|
||||||
|
SKU, PRODUCTVALUE, RESOURCEDESCRIPTION, PRICELIST, PRICEENTEREDLIST,
|
||||||
|
DISCOUNT, PRICEACTUAL, PRICEENTERED, LINENETAMT, PRODUCTDESCRIPTION,
|
||||||
|
IMAGEURL, C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID, C_PROJECTPHASE_ID,
|
||||||
|
C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT ol.AD_Client_ID, ol.AD_Org_ID, ol.IsActive, ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
ol.C_Order_ID, ol.C_OrderLine_ID, ol.C_Tax_ID, t.TaxIndicator,
|
||||||
|
ol.C_BPartner_ID, ol.C_BPartner_Location_ID, bp.Name AS BPName, bpl.C_Location_ID,
|
||||||
|
ol.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN ol.QtyOrdered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.QtyOrdered END AS QtyOrdered,
|
||||||
|
CASE WHEN ol.QtyEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN ol.QtyEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
COALESCE(pt.Name, c.Name,p.Name||productAttribute(ol.M_AttributeSetInstance_ID), ol.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(c.Name,pt.Name, p.Name) IS NOT NULL THEN ol.Description END AS Description, -- second line
|
||||||
|
COALESCE(pt.DocumentNote, p.DocumentNote) AS DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, COALESCE(pp.VendorProductNo,p.Value) AS ProductValue,
|
||||||
|
ra.Description AS ResourceDescription, -- forth line
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList<>0
|
||||||
|
THEN ol.PriceList END AS PriceList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList<>0 AND ol.QtyEntered<>0
|
||||||
|
THEN ol.PriceList*ol.QtyOrdered/ol.QtyEntered END AS PriceEnteredList,
|
||||||
|
CASE WHEN i.IsDiscountPrinted='Y' AND ol.PriceList>ol.PriceActual AND ol.PriceList<>0
|
||||||
|
THEN (ol.PriceList-ol.PriceActual)/ol.PriceList*100 END AS Discount,
|
||||||
|
CASE WHEN ol.PriceActual<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.PriceActual END AS PriceActual,
|
||||||
|
CASE WHEN ol.PriceEntered<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.PriceEntered END AS PriceEntered,
|
||||||
|
CASE WHEN ol.LineNetAmt<>0 OR ol.M_Product_ID IS NOT NULL THEN ol.LineNetAmt END AS LineNetAmt,
|
||||||
|
pt.Description as ProductDescription, p.ImageURL,
|
||||||
|
ol.C_Campaign_ID, ol.C_Project_ID, ol.C_Activity_ID, ol.C_ProjectPhase_ID, ol.C_ProjectTask_ID
|
||||||
|
FROM C_OrderLine ol
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (ol.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN C_Order i ON (ol.C_Order_ID=i.C_Order_ID)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (ol.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN M_Product_Trl pt ON (ol.M_Product_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
LEFT OUTER JOIN S_ResourceAssignment ra ON (ol.S_ResourceAssignment_ID=ra.S_ResourceAssignment_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (ol.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
LEFT OUTER JOIN C_BPartner_Product pp ON (ol.M_Product_ID=pp.M_Product_ID AND i.C_BPartner_ID=pp.C_BPartner_ID)
|
||||||
|
INNER JOIN C_BPartner bp ON (ol.C_BPartner_ID=bp.C_BPartner_ID)
|
||||||
|
INNER JOIN C_BPartner_Location bpl ON (ol.C_BPartner_Location_ID=bpl.C_BPartner_Location_ID)
|
||||||
|
LEFT OUTER JOIN C_Tax_Trl t ON (ol.C_Tax_ID=t.C_Tax_ID AND uom.AD_Language=t.AD_Language)
|
||||||
|
UNION
|
||||||
|
SELECT ol.AD_Client_ID, ol.AD_Org_ID, ol.IsActive, ol.Created, ol.CreatedBy, ol.Updated, ol.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
ol.C_Order_ID, ol.C_OrderLine_ID, ol.C_Tax_ID, null,
|
||||||
|
null, null, null, null,
|
||||||
|
ol.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
ol.QtyOrdered*b.BOMQty AS QtyInvoiced, ol.QtyEntered*b.BOMQty AS QtyEntered, uom.UOMSymbol,
|
||||||
|
COALESCE(pt.Name, p.Name) AS Name, -- main
|
||||||
|
b.Description,
|
||||||
|
COALESCE(pt.DocumentNote, p.DocumentNote) AS DocumentNote, p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
null, null, null, null, null, null, null, pt.Description AS ProductDescription, p.ImageURL,
|
||||||
|
ol.C_Campaign_ID, ol.C_Project_ID, ol.C_Activity_ID, ol.C_ProjectPhase_ID, ol.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN C_OrderLine ol ON (b.M_Product_ID=ol.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=ol.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsInvoicePrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN M_Product_Trl pt ON (b.M_ProductBOM_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
UNION
|
||||||
|
SELECT o.AD_Client_ID, o.AD_Org_ID, o.IsActive, o.Created, o.CreatedBy, o.Updated, o.UpdatedBy,
|
||||||
|
l.AD_Language, o.C_Order_ID, null, null, null,
|
||||||
|
null,
|
||||||
|
null, null, null,
|
||||||
|
null, null, null, null,
|
||||||
|
null, null,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null, null, null, null, null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_Order o, AD_Language l
|
||||||
|
WHERE l.IsBaseLanguage='N' AND l.IsSystemLanguage='Y'
|
||||||
|
UNION
|
||||||
|
SELECT ot.AD_Client_ID, ot.AD_Org_ID, ot.IsActive, ot.Created, ot.CreatedBy, ot.Updated, ot.UpdatedBy,
|
||||||
|
t.AD_Language, ot.C_Order_ID, null, ot.C_Tax_ID, t.TaxIndicator,
|
||||||
|
null, null, null, null,
|
||||||
|
null, null,
|
||||||
|
null, null, null,
|
||||||
|
t.Name,
|
||||||
|
null, null, null, null, null, null,
|
||||||
|
null, null, null,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN ot.TaxAmt ELSE ot.TaxBaseAmt END,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN ot.TaxAmt ELSE ot.TaxBaseAmt END,
|
||||||
|
CASE WHEN ot.IsTaxIncluded='Y' THEN NULL ELSE ot.TaxAmt END,
|
||||||
|
null, null,
|
||||||
|
null,null,null,null,null
|
||||||
|
FROM C_OrderTax ot
|
||||||
|
INNER JOIN C_Tax_Trl t ON (ot.C_Tax_ID=t.C_Tax_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
CREATE OR REPLACE VIEW M_INOUT_LINE_V
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, M_INOUT_ID, M_INOUTLINE_ID,
|
||||||
|
LINE, M_PRODUCT_ID, MOVEMENTQTY, QTYENTERED, UOMSYMBOL,
|
||||||
|
QTYORDERED, QTYDELIVERED, QTYBACKORDERED, NAME, DESCRIPTION,
|
||||||
|
DOCUMENTNOTE, UPC, SKU, PRODUCTVALUE, M_LOCATOR_ID,
|
||||||
|
M_WAREHOUSE_ID, X, Y, Z, M_ATTRIBUTESETINSTANCE_ID,
|
||||||
|
M_ATTRIBUTESET_ID, SERNO, LOT, M_LOT_ID, GUARANTEEDATE,
|
||||||
|
PRODUCTDESCRIPTION, IMAGEURL, C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID,
|
||||||
|
C_PROJECTPHASE_ID, C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT iol.AD_Client_ID, iol.AD_Org_ID, iol.IsActive, iol.Created, iol.CreatedBy, iol.Updated, iol.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
iol.M_InOut_ID, iol.M_InOutLine_ID,
|
||||||
|
iol.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN iol.MovementQty END AS MovementQty,
|
||||||
|
CASE WHEN iol.QtyEntered<>0 OR iol.M_Product_ID IS NOT NULL THEN iol.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
ol.QtyOrdered, ol.QtyDelivered,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN ol.QtyOrdered-ol.QtyDelivered END AS QtyBackOrdered,
|
||||||
|
COALESCE(p.Name||productAttribute(iol.M_AttributeSetInstance_ID), c.Name, iol.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(c.Name,p.Name) IS NOT NULL THEN iol.Description END AS Description, -- second line
|
||||||
|
p.DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
iol.M_Locator_ID, l.M_Warehouse_ID, l.X, l.Y, l.Z,
|
||||||
|
iol.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
p.Description AS ProductDescription, p.ImageURL,
|
||||||
|
iol.C_Campaign_ID, iol.C_Project_ID, iol.C_Activity_ID, iol.C_ProjectPhase_ID, iol.C_ProjectTask_ID
|
||||||
|
FROM M_InOutLine iol
|
||||||
|
INNER JOIN C_UOM uom ON (iol.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (iol.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (iol.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
LEFT OUTER JOIN M_Locator l ON (iol.M_Locator_ID=l.M_Locator_ID)
|
||||||
|
LEFT OUTER JOIN C_OrderLine ol ON (iol.C_OrderLine_ID=ol.C_OrderLine_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (iol.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
UNION -- BOM lines
|
||||||
|
SELECT iol.AD_Client_ID, iol.AD_Org_ID, iol.IsActive, iol.Created, iol.CreatedBy, iol.Updated, iol.UpdatedBy,
|
||||||
|
'en_US' AS AD_Language,
|
||||||
|
iol.M_InOut_ID, iol.M_InOutLine_ID,
|
||||||
|
iol.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
iol.MovementQty*b.BOMQty AS QtyInvoiced, iol.QtyEntered*b.BOMQty AS QtyEntered, uom.UOMSymbol,
|
||||||
|
null, null, null,
|
||||||
|
p.Name, -- main line
|
||||||
|
b.Description, -- second line
|
||||||
|
p.DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
iol.M_Locator_ID, l.M_Warehouse_ID, l.X, l.Y, l.Z,
|
||||||
|
iol.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
p.Description AS ProductDescription, p.ImageURL,
|
||||||
|
iol.C_Campaign_ID, iol.C_Project_ID, iol.C_Activity_ID, iol.C_ProjectPhase_ID, iol.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN M_InOutLine iol ON (b.M_Product_ID=iol.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=iol.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsPickListPrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (iol.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
LEFT OUTER JOIN M_Locator l ON (iol.M_Locator_ID=l.M_Locator_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
CREATE OR REPLACE VIEW M_INOUT_LINE_VT
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, ISACTIVE, CREATED, CREATEDBY,
|
||||||
|
UPDATED, UPDATEDBY, AD_LANGUAGE, M_INOUT_ID, M_INOUTLINE_ID,
|
||||||
|
LINE, M_PRODUCT_ID, MOVEMENTQTY, QTYENTERED, UOMSYMBOL,
|
||||||
|
QTYORDERED, QTYDELIVERED, QTYBACKORDERED, NAME, DESCRIPTION,
|
||||||
|
DOCUMENTNOTE, UPC, SKU, PRODUCTVALUE, M_LOCATOR_ID,
|
||||||
|
M_WAREHOUSE_ID, X, Y, Z, M_ATTRIBUTESETINSTANCE_ID,
|
||||||
|
M_ATTRIBUTESET_ID, SERNO, LOT, M_LOT_ID, GUARANTEEDATE,
|
||||||
|
PRODUCTDESCRIPTION, IMAGEURL, C_CAMPAIGN_ID, C_PROJECT_ID, C_ACTIVITY_ID,
|
||||||
|
C_PROJECTPHASE_ID, C_PROJECTTASK_ID)
|
||||||
|
AS
|
||||||
|
SELECT iol.AD_Client_ID, iol.AD_Org_ID, iol.IsActive, iol.Created, iol.CreatedBy, iol.Updated, iol.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
iol.M_InOut_ID, iol.M_InOutLine_ID,
|
||||||
|
iol.Line, p.M_Product_ID,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN iol.MovementQty END AS MovementQty,
|
||||||
|
CASE WHEN iol.QtyEntered<>0 OR iol.M_Product_ID IS NOT NULL THEN iol.QtyEntered END AS QtyEntered,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN uom.UOMSymbol END AS UOMSymbol,
|
||||||
|
ol.QtyOrdered, ol.QtyDelivered,
|
||||||
|
CASE WHEN iol.MovementQty<>0 OR iol.M_Product_ID IS NOT NULL THEN ol.QtyOrdered-ol.QtyDelivered END AS QtyBackOrdered,
|
||||||
|
COALESCE(COALESCE(pt.Name,p.Name)||productAttribute(iol.M_AttributeSetInstance_ID), c.Name, iol.Description) AS Name, -- main line
|
||||||
|
CASE WHEN COALESCE(pt.Name,p.Name,c.Name) IS NOT NULL THEN iol.Description END AS Description, -- second line
|
||||||
|
COALESCE(pt.DocumentNote, p.DocumentNote) AS DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
iol.M_Locator_ID, l.M_Warehouse_ID, l.X, l.Y, l.Z,
|
||||||
|
iol.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
pt.Description AS ProductDescription, p.ImageURL,
|
||||||
|
iol.C_Campaign_ID, iol.C_Project_ID, iol.C_Activity_ID, iol.C_ProjectPhase_ID, iol.C_ProjectTask_ID
|
||||||
|
FROM M_InOutLine iol
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (iol.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
LEFT OUTER JOIN M_Product p ON (iol.M_Product_ID=p.M_Product_ID)
|
||||||
|
LEFT OUTER JOIN M_Product_Trl pt ON (iol.M_Product_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (iol.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
LEFT OUTER JOIN M_Locator l ON (iol.M_Locator_ID=l.M_Locator_ID)
|
||||||
|
LEFT OUTER JOIN C_OrderLine ol ON (iol.C_OrderLine_ID=ol.C_OrderLine_ID)
|
||||||
|
LEFT OUTER JOIN C_Charge c ON (iol.C_Charge_ID=c.C_Charge_ID)
|
||||||
|
UNION
|
||||||
|
SELECT iol.AD_Client_ID, iol.AD_Org_ID, iol.IsActive, iol.Created, iol.CreatedBy, iol.Updated, iol.UpdatedBy,
|
||||||
|
uom.AD_Language,
|
||||||
|
iol.M_InOut_ID, iol.M_InOutLine_ID,
|
||||||
|
iol.Line+(b.Line/100) AS Line, p.M_Product_ID,
|
||||||
|
iol.MovementQty*b.BOMQty AS QtyInvoiced, iol.QtyEntered*b.BOMQty AS QtyEntered, uom.UOMSymbol,
|
||||||
|
null, null, null,
|
||||||
|
COALESCE (pt.Name, p.Name) AS Name, -- main line
|
||||||
|
b.Description, -- second line
|
||||||
|
COALESCE (pt.DocumentNote, p.DocumentNote) AS DocumentNote, -- third line
|
||||||
|
p.UPC, p.SKU, p.Value AS ProductValue,
|
||||||
|
iol.M_Locator_ID, l.M_Warehouse_ID, l.X, l.Y, l.Z,
|
||||||
|
iol.M_AttributeSetInstance_ID, asi.M_AttributeSet_ID, asi.SerNo, asi.Lot, asi.M_Lot_ID,asi.GuaranteeDate,
|
||||||
|
pt.Description AS ProductDescription, p.ImageURL,
|
||||||
|
iol.C_Campaign_ID, iol.C_Project_ID, iol.C_Activity_ID, iol.C_ProjectPhase_ID, iol.C_ProjectTask_ID
|
||||||
|
FROM M_Product_BOM b -- BOM lines
|
||||||
|
INNER JOIN M_InOutLine iol ON (b.M_Product_ID=iol.M_Product_ID)
|
||||||
|
INNER JOIN M_Product bp ON (bp.M_Product_ID=iol.M_Product_ID -- BOM Product
|
||||||
|
AND bp.IsBOM='Y' AND bp.IsVerified='Y' AND bp.IsPickListPrintDetails='Y')
|
||||||
|
INNER JOIN M_Product p ON (b.M_ProductBOM_ID=p.M_Product_ID) -- BOM line product
|
||||||
|
INNER JOIN C_UOM_Trl uom ON (p.C_UOM_ID=uom.C_UOM_ID)
|
||||||
|
INNER JOIN M_Product_Trl pt ON (iol.M_Product_ID=pt.M_Product_ID AND uom.AD_Language=pt.AD_Language)
|
||||||
|
LEFT OUTER JOIN M_AttributeSetInstance asi ON (iol.M_AttributeSetInstance_ID=asi.M_AttributeSetInstance_ID)
|
||||||
|
LEFT OUTER JOIN M_Locator l ON (iol.M_Locator_ID=l.M_Locator_ID);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
CREATE OR REPLACE VIEW RV_M_TRANSACTION
|
||||||
|
(AD_CLIENT_ID, AD_ORG_ID, MOVEMENTDATE, MOVEMENTQTY, M_PRODUCT_ID,
|
||||||
|
M_LOCATOR_ID, M_ATTRIBUTESETINSTANCE_ID, M_PRODUCT_CATEGORY_ID, VALUE, C_BPARTNER_ID,
|
||||||
|
PRICEPO, PRICELASTPO, PRICELIST)
|
||||||
|
AS
|
||||||
|
SELECT t.AD_Client_ID,t.AD_Org_ID, t.MovementDate, t.MovementQty,
|
||||||
|
t.M_Product_ID, t.M_Locator_ID, t.M_AttributeSetInstance_ID,
|
||||||
|
p.M_Product_Category_ID, p.Value,
|
||||||
|
po.C_BPartner_ID, po.PricePO, po.PriceLastPO, po.PriceList
|
||||||
|
FROM M_Transaction t
|
||||||
|
INNER JOIN M_Product p ON (t.M_Product_ID=p.M_Product_ID)
|
||||||
|
INNER JOIN M_Product_PO po ON (t.M_Product_ID=po.M_Product_ID)
|
||||||
|
WHERE po.IsCurrentVendor='Y';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
CREATE OR REPLACE VIEW RV_OPENITEM
|
||||||
|
(AD_ORG_ID, AD_CLIENT_ID, DOCUMENTNO, C_INVOICE_ID, C_ORDER_ID,
|
||||||
|
C_BPARTNER_ID, ISSOTRX, DATEINVOICED, DATEACCT, NETDAYS,
|
||||||
|
DUEDATE, DAYSDUE, DISCOUNTDATE, DISCOUNTAMT, GRANDTOTAL,
|
||||||
|
PAIDAMT, OPENAMT, C_CURRENCY_ID, C_CONVERSIONTYPE_ID, C_PAYMENTTERM_ID,
|
||||||
|
ISPAYSCHEDULEVALID, C_INVOICEPAYSCHEDULE_ID, INVOICECOLLECTIONTYPE, C_CAMPAIGN_ID, C_PROJECT_ID,
|
||||||
|
C_ACTIVITY_ID)
|
||||||
|
AS
|
||||||
|
SELECT i.AD_Org_ID, i.AD_Client_ID,
|
||||||
|
i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx,
|
||||||
|
i.DateInvoiced, i.DateAcct,
|
||||||
|
p.NetDays,
|
||||||
|
paymentTermDueDate(i.C_PaymentTerm_ID, i.DateInvoiced) AS DueDate,
|
||||||
|
paymentTermDueDays(i.C_PaymentTerm_ID, i.DateInvoiced, getdate()) AS DaysDue,
|
||||||
|
addDays(i.DateInvoiced,p.DiscountDays) AS DiscountDate,
|
||||||
|
ROUND(i.GrandTotal*p.Discount/100,2) AS DiscountAmt,
|
||||||
|
i.GrandTotal,
|
||||||
|
invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt,
|
||||||
|
invoiceOpen(i.C_Invoice_ID,0) AS OpenAmt,
|
||||||
|
i.C_Currency_ID, i.C_ConversionType_ID,
|
||||||
|
i.C_PaymentTerm_ID,
|
||||||
|
i.IsPayScheduleValid, cast(null as numeric) AS C_InvoicePaySchedule_ID, i.InvoiceCollectionType,
|
||||||
|
i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID
|
||||||
|
FROM RV_C_Invoice i
|
||||||
|
INNER JOIN C_PaymentTerm p ON (i.C_PaymentTerm_ID=p.C_PaymentTerm_ID)
|
||||||
|
WHERE -- i.IsPaid='N'
|
||||||
|
invoiceOpen(i.C_Invoice_ID,0) <> 0
|
||||||
|
AND i.IsPayScheduleValid<>'Y'
|
||||||
|
AND i.DocStatus<>'DR'
|
||||||
|
UNION
|
||||||
|
SELECT i.AD_Org_ID, i.AD_Client_ID,
|
||||||
|
i.DocumentNo, i.C_Invoice_ID, i.C_Order_ID, i.C_BPartner_ID, i.IsSOTrx,
|
||||||
|
i.DateInvoiced, i.DateAcct,
|
||||||
|
daysBetween(ips.DueDate,i.DateInvoiced) AS NetDays,
|
||||||
|
ips.DueDate,
|
||||||
|
daysBetween(getdate(),ips.DueDate) AS DaysDue,
|
||||||
|
ips.DiscountDate,
|
||||||
|
ips.DiscountAmt,
|
||||||
|
ips.DueAmt AS GrandTotal,
|
||||||
|
invoicePaid(i.C_Invoice_ID, i.C_Currency_ID, 1) AS PaidAmt,
|
||||||
|
invoiceOpen(i.C_Invoice_ID, ips.C_InvoicePaySchedule_ID) AS OpenAmt,
|
||||||
|
i.C_Currency_ID, i.C_ConversionType_ID,
|
||||||
|
i.C_PaymentTerm_ID,
|
||||||
|
i.IsPayScheduleValid, ips.C_InvoicePaySchedule_ID, i.InvoiceCollectionType,
|
||||||
|
i.C_Campaign_ID, i.C_Project_ID, i.C_Activity_ID
|
||||||
|
FROM RV_C_Invoice i
|
||||||
|
INNER JOIN C_InvoicePaySchedule ips ON (i.C_Invoice_ID=ips.C_Invoice_ID)
|
||||||
|
WHERE -- i.IsPaid='N'
|
||||||
|
invoiceOpen(i.C_Invoice_ID,ips.C_InvoicePaySchedule_ID) <> 0
|
||||||
|
AND i.IsPayScheduleValid='Y'
|
||||||
|
AND i.DocStatus<>'DR'
|
||||||
|
AND ips.IsValid='Y';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,388 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.server;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.ldap.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
import org.compiere.wf.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adempiere Server Base
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: AdempiereServer.java,v 1.3 2006/10/09 00:23:26 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public abstract class AdempiereServer extends Thread
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create New Server Thead
|
||||||
|
* @param model model
|
||||||
|
* @return server tread or null
|
||||||
|
*/
|
||||||
|
public static AdempiereServer create (AdempiereProcessor model)
|
||||||
|
{
|
||||||
|
if (model instanceof MRequestProcessor)
|
||||||
|
return new RequestProcessor ((MRequestProcessor)model);
|
||||||
|
if (model instanceof MWorkflowProcessor)
|
||||||
|
return new WorkflowProcessor ((MWorkflowProcessor)model);
|
||||||
|
if (model instanceof MAcctProcessor)
|
||||||
|
return new AcctProcessor ((MAcctProcessor)model);
|
||||||
|
if (model instanceof MAlertProcessor)
|
||||||
|
return new AlertProcessor ((MAlertProcessor)model);
|
||||||
|
if (model instanceof MScheduler)
|
||||||
|
return new Scheduler ((MScheduler)model);
|
||||||
|
if (model instanceof MLdapProcessor)
|
||||||
|
return new LdapProcessor((MLdapProcessor)model);
|
||||||
|
//
|
||||||
|
throw new IllegalArgumentException("Unknown Processor");
|
||||||
|
} // create
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Server Base Class
|
||||||
|
* @param model model
|
||||||
|
* @param initialNap delay time running in sec
|
||||||
|
*/
|
||||||
|
protected AdempiereServer (AdempiereProcessor model, int initialNap)
|
||||||
|
{
|
||||||
|
super (AdempiereServerGroup.get(), null, model.getName(), 0);
|
||||||
|
p_model = model;
|
||||||
|
m_ctx = new Properties(model.getCtx());
|
||||||
|
if (p_system == null)
|
||||||
|
p_system = MSystem.get(m_ctx);
|
||||||
|
p_client = MClient.get(m_ctx);
|
||||||
|
Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID());
|
||||||
|
m_initialNap = initialNap;
|
||||||
|
// log.info(model.getName() + " - " + getThreadGroup());
|
||||||
|
} // ServerBase
|
||||||
|
|
||||||
|
/** The Processor Model */
|
||||||
|
protected AdempiereProcessor p_model;
|
||||||
|
/** Initial nap is seconds */
|
||||||
|
private int m_initialNap = 0;
|
||||||
|
|
||||||
|
/** Miliseconds to sleep - 10 Min default */
|
||||||
|
private long m_sleepMS = 600000;
|
||||||
|
/** Sleeping */
|
||||||
|
private volatile boolean m_sleeping = false;
|
||||||
|
/** Server start time */
|
||||||
|
private long m_start = 0;
|
||||||
|
/** Number of Work executions */
|
||||||
|
protected int p_runCount = 0;
|
||||||
|
/** Tine start of work */
|
||||||
|
protected long p_startWork = 0;
|
||||||
|
/** Number MS of last Run */
|
||||||
|
private long m_runLastMS = 0;
|
||||||
|
/** Number of MS total */
|
||||||
|
private long m_runTotalMS = 0;
|
||||||
|
/** When to run next */
|
||||||
|
private long m_nextWork = 0;
|
||||||
|
|
||||||
|
/** Logger */
|
||||||
|
protected CLogger log = CLogger.getCLogger(getClass());
|
||||||
|
/** Context */
|
||||||
|
private Properties m_ctx = null;
|
||||||
|
/** System */
|
||||||
|
protected static MSystem p_system = null;
|
||||||
|
/** Client */
|
||||||
|
protected MClient p_client = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Server Context
|
||||||
|
* @return context
|
||||||
|
*/
|
||||||
|
public Properties getCtx()
|
||||||
|
{
|
||||||
|
return m_ctx;
|
||||||
|
} // getCtx
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the sleepMS.
|
||||||
|
*/
|
||||||
|
public long getSleepMS ()
|
||||||
|
{
|
||||||
|
return m_sleepMS;
|
||||||
|
} // getSleepMS
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sleep for set time
|
||||||
|
* @return true if not interrupted
|
||||||
|
*/
|
||||||
|
public boolean sleep()
|
||||||
|
{
|
||||||
|
if (isInterrupted())
|
||||||
|
{
|
||||||
|
log.info (getName() + ": interrupted");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.fine(getName() + ": sleeping " + TimeUtil.formatElapsed(m_sleepMS));
|
||||||
|
m_sleeping = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sleep (m_sleepMS);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
log.info (getName() + ": interrupted");
|
||||||
|
m_sleeping = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_sleeping = false;
|
||||||
|
return true;
|
||||||
|
} // sleep
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run Now
|
||||||
|
*/
|
||||||
|
public void runNow()
|
||||||
|
{
|
||||||
|
log.info(getName());
|
||||||
|
p_startWork = System.currentTimeMillis();
|
||||||
|
doWork();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
p_runCount++;
|
||||||
|
m_runLastMS = now - p_startWork;
|
||||||
|
m_runTotalMS += m_runLastMS;
|
||||||
|
//
|
||||||
|
p_model.setDateLastRun(new Timestamp(now));
|
||||||
|
p_model.save();
|
||||||
|
//
|
||||||
|
log.fine(getName() + ": " + getStatistics());
|
||||||
|
} // runNow
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Run async
|
||||||
|
*/
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
log.fine(getName() + ": pre-nap - " + m_initialNap);
|
||||||
|
sleep (m_initialNap * 1000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, getName() + ": pre-nap interrupted", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_start = System.currentTimeMillis();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (m_nextWork == 0)
|
||||||
|
{
|
||||||
|
Timestamp dateNextRun = getDateNextRun(true);
|
||||||
|
if (dateNextRun != null)
|
||||||
|
m_nextWork = dateNextRun.getTime();
|
||||||
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (m_nextWork > now)
|
||||||
|
{
|
||||||
|
m_sleepMS = m_nextWork - now;
|
||||||
|
if (!sleep ())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (isInterrupted())
|
||||||
|
{
|
||||||
|
log.info (getName() + ": interrupted");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------
|
||||||
|
p_startWork = System.currentTimeMillis();
|
||||||
|
doWork();
|
||||||
|
now = System.currentTimeMillis();
|
||||||
|
// ---------------
|
||||||
|
|
||||||
|
p_runCount++;
|
||||||
|
m_runLastMS = now - p_startWork;
|
||||||
|
m_runTotalMS += m_runLastMS;
|
||||||
|
//
|
||||||
|
m_sleepMS = calculateSleep();
|
||||||
|
m_nextWork = now + m_sleepMS;
|
||||||
|
//
|
||||||
|
p_model.setDateLastRun(new Timestamp(now));
|
||||||
|
p_model.setDateNextRun(new Timestamp(m_nextWork));
|
||||||
|
p_model.save();
|
||||||
|
//
|
||||||
|
log.fine(getName() + ": " + getStatistics());
|
||||||
|
if (!sleep())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_start = 0;
|
||||||
|
} // run
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Run Statistics
|
||||||
|
* @return Statistic info
|
||||||
|
*/
|
||||||
|
public String getStatistics()
|
||||||
|
{
|
||||||
|
return "Run #" + p_runCount
|
||||||
|
+ " - Last=" + TimeUtil.formatElapsed(m_runLastMS)
|
||||||
|
+ " - Total=" + TimeUtil.formatElapsed(m_runTotalMS)
|
||||||
|
+ " - Next " + TimeUtil.formatElapsed(m_nextWork - System.currentTimeMillis());
|
||||||
|
} // getStatistics
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the actual Work
|
||||||
|
*/
|
||||||
|
protected abstract void doWork();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Server Info
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public abstract String getServerInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Unique ID
|
||||||
|
* @return Unique ID
|
||||||
|
*/
|
||||||
|
public String getServerID()
|
||||||
|
{
|
||||||
|
return p_model.getServerID();
|
||||||
|
} // getServerID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the date Next run
|
||||||
|
* @param requery requery database
|
||||||
|
* @return date next run
|
||||||
|
*/
|
||||||
|
public Timestamp getDateNextRun (boolean requery)
|
||||||
|
{
|
||||||
|
return p_model.getDateNextRun(requery);
|
||||||
|
} // getDateNextRun
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the date Last run
|
||||||
|
* @return date lext run
|
||||||
|
*/
|
||||||
|
public Timestamp getDateLastRun ()
|
||||||
|
{
|
||||||
|
return p_model.getDateLastRun();
|
||||||
|
} // getDateLastRun
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Description
|
||||||
|
* @return Description
|
||||||
|
*/
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return p_model.getDescription();
|
||||||
|
} // getDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Model
|
||||||
|
* @return Model
|
||||||
|
*/
|
||||||
|
public AdempiereProcessor getModel()
|
||||||
|
{
|
||||||
|
return p_model;
|
||||||
|
} // getModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate Sleep ms
|
||||||
|
* @return miliseconds
|
||||||
|
*/
|
||||||
|
private long calculateSleep ()
|
||||||
|
{
|
||||||
|
String frequencyType = p_model.getFrequencyType();
|
||||||
|
int frequency = p_model.getFrequency();
|
||||||
|
if (frequency < 1)
|
||||||
|
frequency = 1;
|
||||||
|
//
|
||||||
|
long typeSec = 600; // 10 minutes
|
||||||
|
if (frequencyType == null)
|
||||||
|
typeSec = 300; // 5 minutes
|
||||||
|
else if (X_R_RequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType))
|
||||||
|
typeSec = 60;
|
||||||
|
else if (X_R_RequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType))
|
||||||
|
typeSec = 3600;
|
||||||
|
else if (X_R_RequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType))
|
||||||
|
typeSec = 86400;
|
||||||
|
//
|
||||||
|
return typeSec * 1000 * frequency; // ms
|
||||||
|
} // calculateSleep
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is Sleeping
|
||||||
|
* @return sleeping
|
||||||
|
*/
|
||||||
|
public boolean isSleeping()
|
||||||
|
{
|
||||||
|
return m_sleeping;
|
||||||
|
} // isSleeping
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer (getName())
|
||||||
|
.append (",Prio=").append(getPriority())
|
||||||
|
.append (",").append (getThreadGroup())
|
||||||
|
.append (",Alive=").append(isAlive())
|
||||||
|
.append (",Sleeping=").append(m_sleeping)
|
||||||
|
.append (",Last=").append(getDateLastRun());
|
||||||
|
if (m_sleeping)
|
||||||
|
sb.append (",Next=").append(getDateNextRun(false));
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Seconds Alive
|
||||||
|
* @return seconds alive
|
||||||
|
*/
|
||||||
|
public int getSecondsAlive()
|
||||||
|
{
|
||||||
|
if (m_start == 0)
|
||||||
|
return 0;
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long ms = (now-m_start) / 1000;
|
||||||
|
return (int)ms;
|
||||||
|
} // getSecondsAlive
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Start Time
|
||||||
|
* @return start time
|
||||||
|
*/
|
||||||
|
public Timestamp getStartTime()
|
||||||
|
{
|
||||||
|
if (m_start == 0)
|
||||||
|
return null;
|
||||||
|
return new Timestamp (m_start);
|
||||||
|
} // getStartTime
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Processor Logs
|
||||||
|
* @return logs
|
||||||
|
*/
|
||||||
|
public AdempiereProcessorLog[] getLogs()
|
||||||
|
{
|
||||||
|
return p_model.getLogs();
|
||||||
|
} // getLogs
|
||||||
|
|
||||||
|
} // AdempiereServer
|
|
@ -0,0 +1,534 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* 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.server;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.*;
|
||||||
|
import org.compiere.*;
|
||||||
|
import org.compiere.model.*;
|
||||||
|
import org.compiere.util.*;
|
||||||
|
import org.compiere.wf.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adempiere Server Manager
|
||||||
|
*
|
||||||
|
* @author Jorg Janke
|
||||||
|
* @version $Id: AdempiereServerMgr.java,v 1.4 2006/10/09 00:23:26 jjanke Exp $
|
||||||
|
*/
|
||||||
|
public class AdempiereServerMgr
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get Adempiere Server Manager
|
||||||
|
* @return mgr
|
||||||
|
*/
|
||||||
|
public static AdempiereServerMgr get()
|
||||||
|
{
|
||||||
|
if (m_serverMgr == null)
|
||||||
|
{
|
||||||
|
// for faster subsequent calls
|
||||||
|
m_serverMgr = new AdempiereServerMgr();
|
||||||
|
m_serverMgr.startServers();
|
||||||
|
m_serverMgr.log.info(m_serverMgr.toString());
|
||||||
|
}
|
||||||
|
return m_serverMgr;
|
||||||
|
} // get
|
||||||
|
|
||||||
|
/** Singleton */
|
||||||
|
private static AdempiereServerMgr m_serverMgr = null;
|
||||||
|
/** Logger */
|
||||||
|
protected CLogger log = CLogger.getCLogger(getClass());
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* Adempiere Server Manager
|
||||||
|
*/
|
||||||
|
private AdempiereServerMgr ()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
startEnvironment();
|
||||||
|
// m_serverMgr.startServers();
|
||||||
|
} // AdempiereServerMgr
|
||||||
|
|
||||||
|
/** The Servers */
|
||||||
|
private ArrayList<AdempiereServer> m_servers = new ArrayList<AdempiereServer>();
|
||||||
|
/** Context */
|
||||||
|
private Properties m_ctx = Env.getCtx();
|
||||||
|
/** Start */
|
||||||
|
private Timestamp m_start = new Timestamp(System.currentTimeMillis());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Environment
|
||||||
|
* @return true if started
|
||||||
|
*/
|
||||||
|
private boolean startEnvironment()
|
||||||
|
{
|
||||||
|
Adempiere.startup(false);
|
||||||
|
log.info("");
|
||||||
|
|
||||||
|
// Set Session
|
||||||
|
MSession session = MSession.get(getCtx(), true);
|
||||||
|
session.setWebStoreSession(false);
|
||||||
|
session.setWebSession("Server");
|
||||||
|
session.save();
|
||||||
|
//
|
||||||
|
return true;
|
||||||
|
} // startEnvironment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Environment
|
||||||
|
* @return true if started
|
||||||
|
*/
|
||||||
|
private boolean startServers()
|
||||||
|
{
|
||||||
|
log.info("");
|
||||||
|
int noServers = 0;
|
||||||
|
// Accounting
|
||||||
|
MAcctProcessor[] acctModels = MAcctProcessor.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < acctModels.length; i++)
|
||||||
|
{
|
||||||
|
MAcctProcessor pModel = acctModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(pModel);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
// Request
|
||||||
|
MRequestProcessor[] requestModels = MRequestProcessor.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < requestModels.length; i++)
|
||||||
|
{
|
||||||
|
MRequestProcessor pModel = requestModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(pModel);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
// Workflow
|
||||||
|
MWorkflowProcessor[] workflowModels = MWorkflowProcessor.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < workflowModels.length; i++)
|
||||||
|
{
|
||||||
|
MWorkflowProcessor pModel = workflowModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(pModel);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
// Alert
|
||||||
|
MAlertProcessor[] alertModels = MAlertProcessor.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < alertModels.length; i++)
|
||||||
|
{
|
||||||
|
MAlertProcessor pModel = alertModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(pModel);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
// Scheduler
|
||||||
|
MScheduler[] schedulerModels = MScheduler.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < schedulerModels.length; i++)
|
||||||
|
{
|
||||||
|
MScheduler pModel = schedulerModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(pModel);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
// LDAP
|
||||||
|
MLdapProcessor[] ldapModels = MLdapProcessor.getActive(m_ctx);
|
||||||
|
for (int i = 0; i < ldapModels.length; i++)
|
||||||
|
{
|
||||||
|
MLdapProcessor lp = ldapModels[i];
|
||||||
|
AdempiereServer server = AdempiereServer.create(lp);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-1);
|
||||||
|
m_servers.add(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.fine("#" + noServers);
|
||||||
|
return startAll();
|
||||||
|
} // startEnvironment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Server Context
|
||||||
|
* @return ctx
|
||||||
|
*/
|
||||||
|
public Properties getCtx()
|
||||||
|
{
|
||||||
|
return m_ctx;
|
||||||
|
} // getCtx
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start all servers
|
||||||
|
* @return true if started
|
||||||
|
*/
|
||||||
|
public boolean startAll()
|
||||||
|
{
|
||||||
|
log.info ("");
|
||||||
|
AdempiereServer[] servers = getInActive();
|
||||||
|
for (int i = 0; i < servers.length; i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = servers[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (server.isAlive())
|
||||||
|
continue;
|
||||||
|
// Wait until dead
|
||||||
|
if (server.isInterrupted())
|
||||||
|
{
|
||||||
|
int maxWait = 10; // 10 iterations = 1 sec
|
||||||
|
while (server.isAlive())
|
||||||
|
{
|
||||||
|
if (maxWait-- == 0)
|
||||||
|
{
|
||||||
|
log.severe ("Wait timeout for interruped " + server);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(100); // 1/10 sec
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "While sleeping", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Do start
|
||||||
|
if (!server.isAlive())
|
||||||
|
{
|
||||||
|
// replace
|
||||||
|
server = AdempiereServer.create (server.getModel());
|
||||||
|
if (server == null)
|
||||||
|
m_servers.remove(i);
|
||||||
|
else
|
||||||
|
m_servers.set(i, server);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "Server: " + server, e);
|
||||||
|
}
|
||||||
|
} // for all servers
|
||||||
|
|
||||||
|
// Final Check
|
||||||
|
int noRunning = 0;
|
||||||
|
int noStopped = 0;
|
||||||
|
for (int i = 0; i < servers.length; i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = servers[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (server.isAlive())
|
||||||
|
{
|
||||||
|
log.info("Alive: " + server);
|
||||||
|
noRunning++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.warning("Dead: " + server);
|
||||||
|
noStopped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "(checking) - " + server, e);
|
||||||
|
noStopped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
|
||||||
|
AdempiereServerGroup.get().dump();
|
||||||
|
return noStopped == 0;
|
||||||
|
} // startAll
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Server if not started yet
|
||||||
|
* @param serverID server ID
|
||||||
|
* @return true if started
|
||||||
|
*/
|
||||||
|
public boolean start (String serverID)
|
||||||
|
{
|
||||||
|
AdempiereServer server = getServer(serverID);
|
||||||
|
if (server == null)
|
||||||
|
return false;
|
||||||
|
if (server.isAlive())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// replace
|
||||||
|
int index = m_servers.indexOf(server);
|
||||||
|
server = AdempiereServer.create (server.getModel());
|
||||||
|
if (server == null)
|
||||||
|
m_servers.remove(index);
|
||||||
|
else
|
||||||
|
m_servers.set(index, server);
|
||||||
|
server.start();
|
||||||
|
server.setPriority(Thread.NORM_PRIORITY-2);
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "Server=" + serverID, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.info(server.toString());
|
||||||
|
AdempiereServerGroup.get().dump();
|
||||||
|
if (server == null)
|
||||||
|
return false;
|
||||||
|
return server.isAlive();
|
||||||
|
} // startIt
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop all Servers
|
||||||
|
* @return true if stopped
|
||||||
|
*/
|
||||||
|
public boolean stopAll()
|
||||||
|
{
|
||||||
|
log.info ("");
|
||||||
|
AdempiereServer[] servers = getActive();
|
||||||
|
// Interrupt
|
||||||
|
for (int i = 0; i < servers.length; i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = servers[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (server.isAlive() && !server.isInterrupted())
|
||||||
|
{
|
||||||
|
server.setPriority(Thread.MAX_PRIORITY-1);
|
||||||
|
server.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "(interrupting) - " + server, e);
|
||||||
|
}
|
||||||
|
} // for all servers
|
||||||
|
Thread.yield();
|
||||||
|
|
||||||
|
// Wait for death
|
||||||
|
for (int i = 0; i < servers.length; i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = servers[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int maxWait = 10; // 10 iterations = 1 sec
|
||||||
|
while (server.isAlive())
|
||||||
|
{
|
||||||
|
if (maxWait-- == 0)
|
||||||
|
{
|
||||||
|
log.severe ("Wait timeout for interruped " + server);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.sleep(100); // 1/10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "(waiting) - " + server, e);
|
||||||
|
}
|
||||||
|
} // for all servers
|
||||||
|
|
||||||
|
// Final Check
|
||||||
|
int noRunning = 0;
|
||||||
|
int noStopped = 0;
|
||||||
|
for (int i = 0; i < servers.length; i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = servers[i];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (server.isAlive())
|
||||||
|
{
|
||||||
|
log.warning ("Alive: " + server);
|
||||||
|
noRunning++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.info ("Stopped: " + server);
|
||||||
|
noStopped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "(checking) - " + server, e);
|
||||||
|
noRunning++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.fine("Running=" + noRunning + ", Stopped=" + noStopped);
|
||||||
|
AdempiereServerGroup.get().dump();
|
||||||
|
return noRunning == 0;
|
||||||
|
} // stopAll
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop Server if not stopped
|
||||||
|
* @param serverID server ID
|
||||||
|
* @return true if interrupted
|
||||||
|
*/
|
||||||
|
public boolean stop (String serverID)
|
||||||
|
{
|
||||||
|
AdempiereServer server = getServer(serverID);
|
||||||
|
if (server == null)
|
||||||
|
return false;
|
||||||
|
if (!server.isAlive())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
server.interrupt();
|
||||||
|
Thread.sleep(10); // 1/100 sec
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.log(Level.SEVERE, "stop", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.info(server.toString());
|
||||||
|
AdempiereServerGroup.get().dump();
|
||||||
|
return !server.isAlive();
|
||||||
|
} // stop
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy
|
||||||
|
*/
|
||||||
|
public void destroy ()
|
||||||
|
{
|
||||||
|
log.info ("");
|
||||||
|
stopAll();
|
||||||
|
m_servers.clear();
|
||||||
|
} // destroy
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Active Servers
|
||||||
|
* @return array of active servers
|
||||||
|
*/
|
||||||
|
protected AdempiereServer[] getActive()
|
||||||
|
{
|
||||||
|
ArrayList<AdempiereServer> list = new ArrayList<AdempiereServer>();
|
||||||
|
for (int i = 0; i < m_servers.size(); i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||||
|
if (server != null && server.isAlive() && !server.isInterrupted())
|
||||||
|
list.add (server);
|
||||||
|
}
|
||||||
|
AdempiereServer[] retValue = new AdempiereServer[list.size ()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getActive
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get InActive Servers
|
||||||
|
* @return array of inactive servers
|
||||||
|
*/
|
||||||
|
protected AdempiereServer[] getInActive()
|
||||||
|
{
|
||||||
|
ArrayList<AdempiereServer> list = new ArrayList<AdempiereServer>();
|
||||||
|
for (int i = 0; i < m_servers.size(); i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||||
|
if (server != null && (!server.isAlive() || !server.isInterrupted()))
|
||||||
|
list.add (server);
|
||||||
|
}
|
||||||
|
AdempiereServer[] retValue = new AdempiereServer[list.size()];
|
||||||
|
list.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getInActive
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Servers
|
||||||
|
* @return array of servers
|
||||||
|
*/
|
||||||
|
public AdempiereServer[] getAll()
|
||||||
|
{
|
||||||
|
AdempiereServer[] retValue = new AdempiereServer[m_servers.size()];
|
||||||
|
m_servers.toArray (retValue);
|
||||||
|
return retValue;
|
||||||
|
} // getAll
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Server with ID
|
||||||
|
* @param serverID server id
|
||||||
|
* @return server or null
|
||||||
|
*/
|
||||||
|
public AdempiereServer getServer (String serverID)
|
||||||
|
{
|
||||||
|
if (serverID == null)
|
||||||
|
return null;
|
||||||
|
for (int i = 0; i < m_servers.size(); i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||||
|
if (serverID.equals(server.getServerID()))
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} // getServer
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Representation
|
||||||
|
* @return info
|
||||||
|
*/
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer ("AdempiereServerMgr[");
|
||||||
|
sb.append("Servers=").append(m_servers.size())
|
||||||
|
.append(",ContextSize=").append(m_ctx.size())
|
||||||
|
.append(",Started=").append(m_start)
|
||||||
|
.append ("]");
|
||||||
|
return sb.toString ();
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Description
|
||||||
|
* @return description
|
||||||
|
*/
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return "$Revision: 1.4 $";
|
||||||
|
} // getDescription
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Number Servers
|
||||||
|
* @return no of servers
|
||||||
|
*/
|
||||||
|
public String getServerCount()
|
||||||
|
{
|
||||||
|
int noRunning = 0;
|
||||||
|
int noStopped = 0;
|
||||||
|
for (int i = 0; i < m_servers.size(); i++)
|
||||||
|
{
|
||||||
|
AdempiereServer server = (AdempiereServer)m_servers.get(i);
|
||||||
|
if (server.isAlive())
|
||||||
|
noRunning++;
|
||||||
|
else
|
||||||
|
noStopped++;
|
||||||
|
}
|
||||||
|
String info = String.valueOf(m_servers.size())
|
||||||
|
+ " - Running=" + noRunning
|
||||||
|
+ " - Stopped=" + noStopped;
|
||||||
|
return info;
|
||||||
|
} // getServerCount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get start date
|
||||||
|
* @return start date
|
||||||
|
*/
|
||||||
|
public Timestamp getStartTime()
|
||||||
|
{
|
||||||
|
return m_start;
|
||||||
|
} // getStartTime
|
||||||
|
|
||||||
|
} // AdempiereServerMgr
|
|
@ -0,0 +1,230 @@
|
||||||
|
/**
|
||||||
|
* Create SQL Java Functions (Oracle)
|
||||||
|
*
|
||||||
|
* Author + Copyright 1999-2005 Jorg Janke
|
||||||
|
* $Header: /cvs/adempiere/sqlj/oracle/createSQLJ.sql,v 1.1 2006/04/21 18:04:47 jjanke Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION adempiereVersion
|
||||||
|
RETURN VARCHAR2
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Adempiere.getVersion() return java.lang.String';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION adempiereProperties
|
||||||
|
RETURN VARCHAR2
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Adempiere.getProperties() return java.lang.String';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION adempiereProperty(p_key VARCHAR2)
|
||||||
|
RETURN VARCHAR2
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Adempiere.getProperty(java.lang.String) return java.lang.String';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Product **/
|
||||||
|
CREATE OR REPLACE FUNCTION productAttribute (M_AttributeSetInstance_ID NUMBER)
|
||||||
|
RETURN NVARCHAR2
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.attributeName(int) return java.lang.String';
|
||||||
|
/
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION bomPriceLimit (M_Product_ID NUMBER, M_PriceList_Version_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomPriceLimit(int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION bomPriceList (M_Product_ID NUMBER, M_PriceList_Version_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomPriceList(int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION bomPriceStd (M_Product_ID NUMBER, M_PriceList_Version_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomPriceStd(int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION bomQtyAvailable (M_Product_ID NUMBER, M_Warehouse_ID NUMBER,
|
||||||
|
M_Locator_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomQtyAvailable(int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION bomQtyOnHand (M_Product_ID NUMBER, M_Warehouse_ID NUMBER,
|
||||||
|
M_Locator_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomQtyOnHand(int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION bomQtyOrdered (M_Product_ID NUMBER, M_Warehouse_ID NUMBER,
|
||||||
|
M_Locator_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomQtyOrdered(int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION bomQtyReserved (M_Product_ID NUMBER, M_Warehouse_ID NUMBER,
|
||||||
|
M_Locator_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Product.bomQtyReserved(int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Currency **/
|
||||||
|
CREATE OR REPLACE FUNCTION currencyBase (Amount NUMBER, C_CurrencyFrom_ID NUMBER,
|
||||||
|
ConversionDate DATE, AD_Client_ID NUMBER, AD_Org_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Currency.base(java.math.BigDecimal,int,java.sql.Timestamp,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION currencyConvert (Amount NUMBER, C_CurrencyFrom_ID NUMBER,
|
||||||
|
C_CurrencyTo_ID NUMBER,
|
||||||
|
ConversionDate DATE, C_ConversionType_ID NUMBER, AD_Client_ID NUMBER, AD_Org_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Currency.convert(java.math.BigDecimal,int,int,java.sql.Timestamp,int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION currencyRate (C_CurrencyFrom_ID NUMBER, C_CurrencyTo_ID NUMBER,
|
||||||
|
ConversionDate DATE, C_ConversionType_ID NUMBER, AD_Client_ID NUMBER, AD_Org_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Currency.rate(int,int,java.sql.Timestamp,int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION currencyRound (Amt NUMBER, C_CurrencyTo_ID NUMBER, IsCosting VARCHAR2)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Currency.round(java.math.BigDecimal,int,java.lang.String) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** BPartner **/
|
||||||
|
CREATE OR REPLACE FUNCTION bpartnerRemitLocation (p_C_BPartner_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.BPartner.remitLocation(int) return int';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Invoice **/
|
||||||
|
CREATE OR REPLACE FUNCTION invoiceOpen (p_C_Invoice_ID NUMBER, p_C_InvoicePaySchedule_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Invoice.open(int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION invoicePaid (p_C_Invoice_ID NUMBER, p_C_Currency_ID NUMBER,
|
||||||
|
p_MultiplierAP NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Invoice.paid(int,int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION invoiceDiscount (p_C_Invoice_ID NUMBER, p_PayDate Date,
|
||||||
|
p_C_InvoicePaySchedule_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Invoice.discount(int,java.sql.Timestamp,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Payment Term **/
|
||||||
|
CREATE OR REPLACE FUNCTION paymentTermDueDays (p_C_PaymentTerm_ID NUMBER, p_DocDate DATE,
|
||||||
|
p_PayDate DATE)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.PaymentTerm.dueDays(int,java.sql.Timestamp,java.sql.Timestamp) return int';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION paymentTermDiscount (p_Amount NUMBER, p_C_Currency_ID NUMBER,
|
||||||
|
p_C_PaymentTerm_ID NUMBER, p_DocDate DATE, p_PayDate DATE)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.PaymentTerm.discount(java.math.BigDecimal,int,int,java.sql.Timestamp,java.sql.Timestamp) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION paymentTermDueDate (p_C_PaymentTerm_ID NUMBER, p_DocDate DATE)
|
||||||
|
RETURN DATE
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.PaymentTerm.dueDate(int,java.sql.Timestamp) return java.sql.Timestamp';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Payment **/
|
||||||
|
CREATE OR REPLACE FUNCTION paymentAllocated (p_C_Payment_ID NUMBER, p_C_Currency_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Payment.allocated(int,int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
CREATE OR REPLACE FUNCTION paymentAvailable (p_C_Payment_ID NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Payment.available(int) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Account **/
|
||||||
|
CREATE OR REPLACE FUNCTION acctBalance (p_Account_ID NUMBER, p_AmtDr NUMBER, p_AmtCr NUMBER)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS LANGUAGE JAVA
|
||||||
|
NAME 'org.compiere.sqlj.Account.balance(int,java.math.BigDecimal,java.math.BigDecimal) return java.math.BigDecimal';
|
||||||
|
/
|
||||||
|
|
||||||
|
/** General **/
|
||||||
|
BEGIN
|
||||||
|
dbms_java.grant_permission('ADEMPIERE','SYS:java.util.PropertyPermission', '*', 'read,write');
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
/** Get Character at Position */
|
||||||
|
CREATE OR REPLACE FUNCTION charAt
|
||||||
|
(
|
||||||
|
p_string VARCHAR2,
|
||||||
|
p_pos NUMBER
|
||||||
|
)
|
||||||
|
RETURN VARCHAR2
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
RETURN SUBSTR(p_string, p_pos, 1);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
/** GetDate */
|
||||||
|
CREATE OR REPLACE FUNCTION getdate
|
||||||
|
RETURN DATE
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
RETURN SysDate;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
/** First Of DD/DY/MM/Q */
|
||||||
|
CREATE OR REPLACE FUNCTION firstOf
|
||||||
|
(
|
||||||
|
p_date DATE,
|
||||||
|
p_datePart VARCHAR2
|
||||||
|
)
|
||||||
|
RETURN DATE
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
RETURN TRUNC(p_date, p_datePart);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
/** Add Number of Days */
|
||||||
|
CREATE OR REPLACE FUNCTION addDays
|
||||||
|
(
|
||||||
|
p_date DATE,
|
||||||
|
p_days NUMBER
|
||||||
|
)
|
||||||
|
RETURN DATE
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
RETURN TRUNC(p_date) + p_days;
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
/** Difference in Days */
|
||||||
|
CREATE OR REPLACE FUNCTION daysBetween
|
||||||
|
(
|
||||||
|
p_date1 DATE,
|
||||||
|
p_date2 DATE
|
||||||
|
)
|
||||||
|
RETURN NUMBER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
RETURN TRUNC(p_date1) - TRUNC(p_date2);
|
||||||
|
END;
|
||||||
|
/
|
||||||
|
|
||||||
|
|
||||||
|
SELECT --adempiereVersion(), adempiereProperty('java.vendor'),
|
||||||
|
TRUNC(getdate()) FROM DUAL
|
||||||
|
/
|
||||||
|
|
||||||
|
EXIT
|
|
@ -0,0 +1,31 @@
|
||||||
|
@Title Build Adempiere Clean
|
||||||
|
@Rem $Header: /cvsroot/adempiere/utils_dev/RUN_build.bat,v 1.22 2005/09/08 21:56:11 jjanke Exp $
|
||||||
|
|
||||||
|
@Rem Check java home
|
||||||
|
@IF NOT EXIST "%JAVA_HOME%\bin" ECHO "** JAVA_HOME NOT found"
|
||||||
|
@SET PATH=%JAVA_HOME%\bin;%PATH%
|
||||||
|
|
||||||
|
@Rem Check jdk
|
||||||
|
@IF NOT EXIST "%JAVA_HOME%\lib\tools.jar" ECHO "** Need Full Java SDK **"
|
||||||
|
|
||||||
|
@Rem Set ant classpath
|
||||||
|
@SET ANT_CLASSPATH=%CLASSPATH%;..\tools\lib\ant.jar;..\tools\lib\ant-launcher.jar;..\tools\lib\ant-swing.jar;..\tools\lib\ant-commons-net.jar;..\tools\lib\commons-net-1.4.0.jar
|
||||||
|
@SET ANT_CLASSPATH=%ANT_CLASSPATH%;"%JAVA_HOME%\lib\tools.jar"
|
||||||
|
|
||||||
|
@SET ANT_OPTS=-Xms128m -Xmx512m
|
||||||
|
|
||||||
|
@echo Cleanup ...
|
||||||
|
@"%JAVA_HOME%\bin\java" %ANT_OPTS% -classpath %ANT_CLASSPATH% -Dant.home="." org.apache.tools.ant.Main clean
|
||||||
|
|
||||||
|
@echo Building ...
|
||||||
|
@"%JAVA_HOME%\bin\java" %ANT_OPTS% -classpath %ANT_CLASSPATH% -Dant.home="." org.apache.tools.ant.Main -logger org.apache.tools.ant.listener.MailLogger complete
|
||||||
|
@IF ERRORLEVEL 1 goto ERROR
|
||||||
|
|
||||||
|
@Echo Done ...
|
||||||
|
@Pause
|
||||||
|
@exit
|
||||||
|
|
||||||
|
:ERROR
|
||||||
|
@Color fc
|
||||||
|
|
||||||
|
@Pause
|
Loading…
Reference in New Issue