hg merge release-5.1 (merge release5.1 into default)

This commit is contained in:
Carlos Ruiz 2018-08-29 20:42:42 +02:00
commit ac0b824eee
36 changed files with 616 additions and 346 deletions

View File

@ -0,0 +1,15 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3757
-- Jul 24, 2018 9:30:27 AM CEST
UPDATE AD_Table SET AccessLevel='4',Updated=TO_DATE('2018-07-24 09:30:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Table_ID=116
;
DELETE FROM ad_window_access WHERE ad_window_id=105
AND ad_role_id IN (SELECT ad_role_id FROM ad_role WHERE ismanual='N' AND userlevel NOT LIKE 'S%')
;
SELECT register_migration_script('201807240936_IDEMPIERE-3757.sql') FROM dual
;

View File

@ -0,0 +1,14 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3762 : Fix AD_Column_ID / AD_Field_ID : Loader - Too many records
-- Jul 26, 2018 10:06:34 AM CEST
UPDATE AD_Field SET AD_Reference_ID=30,Updated=TO_DATE('2018-07-26 10:06:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=4599
;
-- Jul 26, 2018 10:06:42 AM CEST
UPDATE AD_Field SET AD_Reference_ID=30,Updated=TO_DATE('2018-07-26 10:06:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=59576
;
SELECT register_migration_script('201807271000_IDEMPIERE-3762.sql') FROM dual
;

View File

@ -0,0 +1,10 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-3769 : IBAN : Invalid message is not translated - force to uppercase
-- Aug 1, 2018 8:56:43 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','IBAN is invalid',0,0,'Y',TO_DATE('2018-08-01 08:56:42','YYYY-MM-DD HH24:MI:SS'),0,TO_DATE('2018-08-01 08:56:42','YYYY-MM-DD HH24:MI:SS'),0,200480,'InvalidIBAN','D','4cc792d9-9af0-4e37-b90a-7dcc9f5e82ec')
;
SELECT register_migration_script('201808010900_IDEMPIERE-3769.sql') FROM dual
;

View File

@ -0,0 +1,31 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-2442 Always using default conversion type in Order & Invoice window's amount summary information
-- Aug 7, 2018 12:22:32 PM CEST
UPDATE AD_StatusLine SET SQLStatement='SELECT COUNT(DISTINCT C_OrderLine_ID) AS Lines,o.TotalLines,o.GrandTotal,c.ISO_Code,
currencyConvert(o.GrandTotal,o.C_Currency_ID,ac.C_Currency_ID,o.DateAcct,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt
FROM C_Order o
INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)
LEFT JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID)
LEFT JOIN AD_ClientInfo ci ON (ci.AD_Client_ID=o.AD_Client_ID)
LEFT JOIN C_AcctSchema ac ON (ci.C_AcctSchema1_ID=ac.C_AcctSchema_ID)
WHERE o.C_Order_ID=@C_Order_ID@
GROUP BY o.C_Currency_ID, ac.C_Currency_ID, o.C_ConversionType_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID',Updated=TO_DATE('2018-08-07 12:22:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_StatusLine_ID=200000
;
-- Aug 7, 2018 12:25:27 PM CEST
UPDATE AD_StatusLine SET SQLStatement='SELECT COUNT(DISTINCT C_InvoiceLine_ID) AS Lines,o.TotalLines,o.GrandTotal,c.ISO_Code,
currencyConvert(o.GrandTotal,o.C_Currency_ID,ac.C_Currency_ID,o.DateAcct,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt
FROM C_Invoice o
INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)
LEFT JOIN C_InvoiceLine l ON (o.C_Invoice_ID=l.C_Invoice_ID)
LEFT JOIN AD_ClientInfo ci ON (ci.AD_Client_ID=o.AD_Client_ID)
LEFT JOIN C_AcctSchema ac ON (ci.C_AcctSchema1_ID=ac.C_AcctSchema_ID)
WHERE o.C_Invoice_ID=@C_Invoice_ID@
GROUP BY o.C_Currency_ID, ac.C_Currency_ID, o.C_ConversionType_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID',Updated=TO_DATE('2018-08-07 12:25:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_StatusLine_ID=200002
;
SELECT register_migration_script('201808071226_IDEMPIERE-2442.sql') FROM dual
;

View File

@ -0,0 +1,12 @@
-- IDEMPIERE-3757
-- Jul 24, 2018 9:30:27 AM CEST
UPDATE AD_Table SET AccessLevel='4',Updated=TO_TIMESTAMP('2018-07-24 09:30:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Table_ID=116
;
DELETE FROM ad_window_access WHERE ad_window_id=105
AND ad_role_id IN (SELECT ad_role_id FROM ad_role WHERE ismanual='N' AND userlevel NOT LIKE 'S%')
;
SELECT register_migration_script('201807240936_IDEMPIERE-3757.sql') FROM dual
;

View File

@ -0,0 +1,11 @@
-- IDEMPIERE-3762 : Fix AD_Column_ID / AD_Field_ID : Loader - Too many records
-- Jul 26, 2018 10:06:34 AM CEST
UPDATE AD_Field SET AD_Reference_ID=30,Updated=TO_TIMESTAMP('2018-07-26 10:06:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=4599
;
-- Jul 26, 2018 10:06:42 AM CEST
UPDATE AD_Field SET AD_Reference_ID=30,Updated=TO_TIMESTAMP('2018-07-26 10:06:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=0 WHERE AD_Field_ID=59576
;
SELECT register_migration_script('201807271000_IDEMPIERE-3762.sql') FROM dual
;

View File

@ -0,0 +1,7 @@
-- IDEMPIERE-3769 : IBAN : Invalid message is not translated - force to uppercase
-- Aug 1, 2018 8:56:43 AM CEST
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','IBAN is invalid',0,0,'Y',TO_TIMESTAMP('2018-08-01 08:56:42','YYYY-MM-DD HH24:MI:SS'),0,TO_TIMESTAMP('2018-08-01 08:56:42','YYYY-MM-DD HH24:MI:SS'),0,200480,'InvalidIBAN','D','4cc792d9-9af0-4e37-b90a-7dcc9f5e82ec')
;
SELECT register_migration_script('201808010900_IDEMPIERE-3769.sql') FROM dual
;

View File

@ -0,0 +1,28 @@
-- IDEMPIERE-2442 Always using default conversion type in Order & Invoice window's amount summary information
-- Aug 7, 2018 12:22:32 PM CEST
UPDATE AD_StatusLine SET SQLStatement='SELECT COUNT(DISTINCT C_OrderLine_ID) AS Lines,o.TotalLines,o.GrandTotal,c.ISO_Code,
currencyConvert(o.GrandTotal,o.C_Currency_ID,ac.C_Currency_ID,o.DateAcct,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt
FROM C_Order o
INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)
LEFT JOIN C_OrderLine l ON (o.C_Order_ID=l.C_Order_ID)
LEFT JOIN AD_ClientInfo ci ON (ci.AD_Client_ID=o.AD_Client_ID)
LEFT JOIN C_AcctSchema ac ON (ci.C_AcctSchema1_ID=ac.C_AcctSchema_ID)
WHERE o.C_Order_ID=@C_Order_ID@
GROUP BY o.C_Currency_ID, ac.C_Currency_ID, o.C_ConversionType_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID',Updated=TO_TIMESTAMP('2018-08-07 12:22:32','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_StatusLine_ID=200000
;
-- Aug 7, 2018 12:25:27 PM CEST
UPDATE AD_StatusLine SET SQLStatement='SELECT COUNT(DISTINCT C_InvoiceLine_ID) AS Lines,o.TotalLines,o.GrandTotal,c.ISO_Code,
currencyConvert(o.GrandTotal,o.C_Currency_ID,ac.C_Currency_ID,o.DateAcct,o.C_ConversionType_ID,o.AD_Client_ID,o.AD_Org_ID) AS ConvAmt
FROM C_Invoice o
INNER JOIN C_Currency c ON (o.C_Currency_ID=c.C_Currency_ID)
LEFT JOIN C_InvoiceLine l ON (o.C_Invoice_ID=l.C_Invoice_ID)
LEFT JOIN AD_ClientInfo ci ON (ci.AD_Client_ID=o.AD_Client_ID)
LEFT JOIN C_AcctSchema ac ON (ci.C_AcctSchema1_ID=ac.C_AcctSchema_ID)
WHERE o.C_Invoice_ID=@C_Invoice_ID@
GROUP BY o.C_Currency_ID, ac.C_Currency_ID, o.C_ConversionType_ID, c.ISO_Code, o.TotalLines, o.GrandTotal, o.DateAcct, o.AD_Client_ID, o.AD_Org_ID',Updated=TO_TIMESTAMP('2018-08-07 12:25:27','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_StatusLine_ID=200002
;
SELECT register_migration_script('201808071226_IDEMPIERE-2442.sql') FROM dual
;

View File

@ -453,8 +453,6 @@ public class CalloutOrder extends CalloutEngine
*/ */
public String bPartnerBill (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value) public String bPartnerBill (Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value)
{ {
if (isCalloutActive())
return "";
Integer bill_BPartner_ID = (Integer)value; Integer bill_BPartner_ID = (Integer)value;
if (bill_BPartner_ID == null || bill_BPartner_ID.intValue() == 0) if (bill_BPartner_ID == null || bill_BPartner_ID.intValue() == 0)
return ""; return "";

View File

@ -25,6 +25,7 @@ import org.compiere.model.MBPartner;
import org.compiere.model.MDocType; import org.compiere.model.MDocType;
import org.compiere.model.MInvoice; import org.compiere.model.MInvoice;
import org.compiere.model.MInvoiceLine; import org.compiere.model.MInvoiceLine;
import org.compiere.model.MPriceList;
import org.compiere.model.MTimeExpense; import org.compiere.model.MTimeExpense;
import org.compiere.model.MTimeExpenseLine; import org.compiere.model.MTimeExpenseLine;
import org.compiere.util.DB; import org.compiere.util.DB;
@ -136,6 +137,10 @@ public class ExpenseAPInvoice extends SvrProcess
break; break;
} }
invoice.setM_PriceList_ID(te.getM_PriceList_ID()); invoice.setM_PriceList_ID(te.getM_PriceList_ID());
MPriceList pl = MPriceList.get(getCtx(), te.getM_PriceList_ID(), get_TrxName());
invoice.setIsTaxIncluded(pl.isTaxIncluded());
invoice.setSalesRep_ID(te.getDoc_User_ID()); invoice.setSalesRep_ID(te.getDoc_User_ID());
StringBuilder descr = new StringBuilder().append(Msg.translate(getCtx(), "S_TimeExpense_ID")) StringBuilder descr = new StringBuilder().append(Msg.translate(getCtx(), "S_TimeExpense_ID"))
.append(": ").append(te.getDocumentNo()).append(" " ) .append(": ").append(te.getDocumentNo()).append(" " )
@ -182,6 +187,7 @@ public class ExpenseAPInvoice extends SvrProcess
// //
// il.setPrice(); // not really a list/limit price for reimbursements // il.setPrice(); // not really a list/limit price for reimbursements
il.setPrice(line.getPriceReimbursed()); // il.setPrice(line.getPriceReimbursed()); //
il.setTax(); il.setTax();
if (!il.save()) if (!il.save())
throw new IllegalStateException("Cannot save Invoice Line"); throw new IllegalStateException("Cannot save Invoice Line");

View File

@ -20,6 +20,7 @@ import java.math.BigDecimal;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import org.compiere.model.MAccount; import org.compiere.model.MAccount;
@ -29,6 +30,7 @@ import org.compiere.model.MAllocationHdr;
import org.compiere.model.MAllocationLine; import org.compiere.model.MAllocationLine;
import org.compiere.model.MCashLine; import org.compiere.model.MCashLine;
import org.compiere.model.MConversionRate; import org.compiere.model.MConversionRate;
import org.compiere.model.MCurrency;
import org.compiere.model.MFactAcct; import org.compiere.model.MFactAcct;
import org.compiere.model.MInvoice; import org.compiere.model.MInvoice;
import org.compiere.model.MInvoiceLine; import org.compiere.model.MInvoiceLine;
@ -197,6 +199,7 @@ public class Doc_AllocationHdr extends Doc
FactLine fl = null; FactLine fl = null;
FactLine flForRGL = null; FactLine flForRGL = null;
MAccount bpAcct = null; // Liability/Receivables MAccount bpAcct = null; // Liability/Receivables
MAccount payAcct = null; // Payment Selection
// //
MPayment payment = null; MPayment payment = null;
if (line.getC_Payment_ID() != 0) if (line.getC_Payment_ID() != 0)
@ -259,7 +262,8 @@ public class Doc_AllocationHdr extends Doc
// Payment/Cash DR // Payment/Cash DR
if (line.getC_Payment_ID() != 0) if (line.getC_Payment_ID() != 0)
{ {
fl = fact.createLine (line, getPaymentAcct(as, line.getC_Payment_ID()), payAcct = getPaymentAcct(as, line.getC_Payment_ID());
fl = fact.createLine (line, payAcct,
getC_Currency_ID(), line.getAmtSource(), null); getC_Currency_ID(), line.getAmtSource(), null);
if (fl != null && payment != null) if (fl != null && payment != null)
fl.setAD_Org_ID(payment.getAD_Org_ID()); fl.setAD_Org_ID(payment.getAD_Org_ID());
@ -389,7 +393,8 @@ public class Doc_AllocationHdr extends Doc
// Payment/Cash CR // Payment/Cash CR
if (isUsingClearing && line.getC_Payment_ID() != 0) // Avoid usage of clearing accounts if (isUsingClearing && line.getC_Payment_ID() != 0) // Avoid usage of clearing accounts
{ {
fl = fact.createLine (line, getPaymentAcct(as, line.getC_Payment_ID()), payAcct = getPaymentAcct(as, line.getC_Payment_ID());
fl = fact.createLine (line, payAcct,
getC_Currency_ID(), null, line.getAmtSource().negate()); getC_Currency_ID(), null, line.getAmtSource().negate());
if (fl != null && payment != null) if (fl != null && payment != null)
fl.setAD_Org_ID(payment.getAD_Org_ID()); fl.setAD_Org_ID(payment.getAD_Org_ID());
@ -430,7 +435,7 @@ public class Doc_AllocationHdr extends Doc
&& (getC_Currency_ID() != as.getC_Currency_ID() // payment allocation in foreign currency && (getC_Currency_ID() != as.getC_Currency_ID() // payment allocation in foreign currency
|| getC_Currency_ID() != line.getInvoiceC_Currency_ID())) // allocation <> invoice currency || getC_Currency_ID() != line.getInvoiceC_Currency_ID())) // allocation <> invoice currency
{ {
p_Error = createRealizedGainLoss (line, as, fact, bpAcct, invoice, p_Error = createRealizedGainLoss (line, as, fact, bpAcct, invoice, payAcct, payment,
allocationSource, allocationAccounted); allocationSource, allocationAccounted);
if (p_Error != null) if (p_Error != null)
return null; return null;
@ -692,102 +697,164 @@ public class Doc_AllocationHdr extends Doc
* Accounted Amount of the Allocation * Accounted Amount of the Allocation
* @param as accounting schema * @param as accounting schema
* @param fact fact * @param fact fact
* @param acct account * @param invAcct invoice account
* @param invoice invoice * @param invoice invoice
* @param payAcct payment account
* @param payment payment
* @param allocationSource source amt * @param allocationSource source amt
* @param allocationAccounted acct amt * @param allocationAccounted acct amt
* @return Error Message or null if OK * @return Error Message or null if OK
*/ */
private String createRealizedGainLoss (DocLine line, MAcctSchema as, Fact fact, MAccount acct, private String createRealizedGainLoss (DocLine line, MAcctSchema as, Fact fact, MAccount invAcct,
MInvoice invoice, BigDecimal allocationSource, BigDecimal allocationAccounted) MInvoice invoice, MAccount payAcct, MPayment payment, BigDecimal allocationSource, BigDecimal allocationAccounted)
{ {
BigDecimal invoiceSource = null; BigDecimal invoiceSource = null;
BigDecimal invoiceAccounted = null; BigDecimal invoiceAccounted = null;
BigDecimal paymentSource = null;
BigDecimal paymentAccounted = null;
// //
StringBuilder sql = new StringBuilder("SELECT ") StringBuilder sql = new StringBuilder()
.append(invoice.isSOTrx() .append("SELECT SUM(AmtSourceDr), SUM(AmtAcctDr), SUM(AmtSourceCr), SUM(AmtAcctCr)")
? "SUM(AmtSourceDr), SUM(AmtAcctDr)" // so
: "SUM(AmtSourceCr), SUM(AmtAcctCr)") // po
.append(" FROM Fact_Acct ") .append(" FROM Fact_Acct ")
.append("WHERE AD_Table_ID=318 AND Record_ID=?") // Invoice .append("WHERE AD_Table_ID=? AND Record_ID=?")
.append(" AND C_AcctSchema_ID=?") .append(" AND C_AcctSchema_ID=?")
.append(" AND PostingType='A'"); .append(" AND PostingType='A'");
//AND C_Currency_ID=102
PreparedStatement pstmt = null; // For Invoice
ResultSet rs = null; List<Object> valuesInv = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
try MInvoice.Table_ID, invoice.getC_Invoice_ID(), as.getC_AcctSchema_ID());
{ if (valuesInv != null) {
pstmt = DB.prepareStatement(sql.toString(), getTrxName()); if (invoice.isSOTrx()) {
pstmt.setInt(1, invoice.getC_Invoice_ID()); invoiceSource = (BigDecimal) valuesInv.get(0); // AmtSourceDr
pstmt.setInt(2, as.getC_AcctSchema_ID()); invoiceAccounted = (BigDecimal) valuesInv.get(1); // AmtAcctDr
rs = pstmt.executeQuery(); } else {
if (rs.next()) invoiceSource = (BigDecimal) valuesInv.get(2); // AmtSourceCr
{ invoiceAccounted = (BigDecimal) valuesInv.get(3); // AmtAcctCr
invoiceSource = rs.getBigDecimal(1);
invoiceAccounted = rs.getBigDecimal(2);
} }
} }
catch (Exception e)
{
log.log(Level.SEVERE, sql.toString(), e);
}
finally {
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
// Requires that Invoice is Posted // Requires that Invoice is Posted
if (invoiceSource == null || invoiceAccounted == null) if (invoiceSource == null || invoiceAccounted == null)
return "Gain/Loss - Invoice not posted yet"; return "Gain/Loss - Invoice not posted yet";
// //
StringBuilder description = new StringBuilder("Invoice=(").append(invoice.getC_Currency_ID()).append(")").append(invoiceSource).append("/").append(invoiceAccounted) String invoiceCur = MCurrency.get(getCtx(), invoice.getC_Currency_ID()).getISO_Code();
.append(" - Allocation=(").append(getC_Currency_ID()).append(")").append(allocationSource).append("/").append(allocationAccounted); String allocCur = MCurrency.get(getCtx(), getC_Currency_ID()).getISO_Code();
if (log.isLoggable(Level.FINE)) log.fine(description.toString()); StringBuilder descriptionInv = new StringBuilder("Invoice=(").append(invoiceCur).append(")").append(invoiceSource).append("/").append(invoiceAccounted)
.append(" - Allocation=(").append(allocCur).append(")").append(allocationSource).append("/").append(allocationAccounted);
if (log.isLoggable(Level.FINE)) log.fine(descriptionInv.toString());
// Allocation not Invoice Currency // Allocation not Invoice Currency
BigDecimal allocationInvoiceSource = allocationSource;
if (getC_Currency_ID() != invoice.getC_Currency_ID()) if (getC_Currency_ID() != invoice.getC_Currency_ID())
{ {
BigDecimal allocationSourceNew = MConversionRate.convert(getCtx(), allocationInvoiceSource = MConversionRate.convert(getCtx(),
allocationSource, getC_Currency_ID(), allocationSource, getC_Currency_ID(),
invoice.getC_Currency_ID(), getDateAcct(), invoice.getC_Currency_ID(), getDateAcct(),
invoice.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID()); invoice.getC_ConversionType_ID(), invoice.getAD_Client_ID(), invoice.getAD_Org_ID());
if (allocationSourceNew == null) if (allocationInvoiceSource == null)
return "Gain/Loss - No Conversion from Allocation->Invoice"; return "Gain/Loss - No Conversion from Allocation->Invoice";
StringBuilder d2 = new StringBuilder("Allocation=(").append(getC_Currency_ID()).append(")").append(allocationSource) StringBuilder d2 = new StringBuilder("Allocation=(").append(allocCur).append(")").append(allocationSource)
.append("->(").append(invoice.getC_Currency_ID()).append(")").append(allocationSourceNew); .append("->(").append(invoiceCur).append(")").append(allocationInvoiceSource);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString()); if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
description.append(" - ").append(d2); descriptionInv.append(" - ").append(d2);
allocationSource = allocationSourceNew;
} }
BigDecimal acctDifference = null; // gain is negative BigDecimal invoiceDifference = null; // gain is negative
// Full Payment in currency // Full Invoice in currency
if (allocationSource.compareTo(invoiceSource) == 0) if (allocationInvoiceSource.compareTo(invoiceSource) == 0)
{ {
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative invoiceDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
StringBuilder d2 = new StringBuilder("(full) = ").append(acctDifference); StringBuilder d2 = new StringBuilder("(full) = ").append(invoiceDifference);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString()); if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
description.append(" - ").append(d2); descriptionInv.append(" - ").append(d2);
} }
else // partial or MC else // partial or MC
{ {
// percent of total payment // percent of total payment
double multiplier = allocationSource.doubleValue() / invoiceSource.doubleValue(); double multiplier = allocationInvoiceSource.doubleValue() / invoiceSource.doubleValue();
// Reduce Orig Invoice Accounted // Reduce Orig Invoice Accounted
invoiceAccounted = invoiceAccounted.multiply(BigDecimal.valueOf(multiplier)); invoiceAccounted = invoiceAccounted.multiply(BigDecimal.valueOf(multiplier));
// Difference based on percentage of Orig Invoice // Difference based on percentage of Orig Invoice
acctDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative invoiceDifference = invoiceAccounted.subtract(allocationAccounted); // gain is negative
// ignore Tolerance // ignore Tolerance
if (acctDifference.abs().compareTo(TOLERANCE) < 0) if (invoiceDifference.abs().compareTo(TOLERANCE) < 0)
acctDifference = Env.ZERO; invoiceDifference = Env.ZERO;
// Round // Round
int precision = as.getStdPrecision(); int precision = as.getStdPrecision();
if (acctDifference.scale() > precision) if (invoiceDifference.scale() > precision)
acctDifference = acctDifference.setScale(precision, BigDecimal.ROUND_HALF_UP); invoiceDifference = invoiceDifference.setScale(precision, BigDecimal.ROUND_HALF_UP);
StringBuilder d2 = new StringBuilder("(partial) = ").append(acctDifference).append(" - Multiplier=").append(multiplier); StringBuilder d2 = new StringBuilder("(partial) = ").append(invoiceDifference).append(" - Multiplier=").append(multiplier);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString()); if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
description.append(" - ").append(d2); descriptionInv.append(" - ").append(d2);
} }
if (acctDifference.signum() == 0) // For Payment
BigDecimal paymentDifference = Env.ZERO;
StringBuilder descriptionPay = null;
if (payment != null && payment.getC_Payment_ID() > 0) {
List<Object> valuesPay = DB.getSQLValueObjectsEx(getTrxName(), sql.toString(),
MPayment.Table_ID, payment.getC_Payment_ID(), as.getC_AcctSchema_ID());
if (valuesPay != null) {
if (invoice.isSOTrx()) {
paymentSource = (BigDecimal) valuesPay.get(2); // AmtSourceCr
paymentAccounted = (BigDecimal) valuesPay.get(3); // AmtAcctCr
} else {
paymentSource = (BigDecimal) valuesPay.get(0); // AmtSourceDr
paymentAccounted = (BigDecimal) valuesPay.get(1); // AmtAcctDr
}
}
// Requires that Payment is Posted
if (paymentSource == null || paymentAccounted == null)
return "Gain/Loss - Payment not posted yet";
//
String paymentCur = MCurrency.get(getCtx(), payment.getC_Currency_ID()).getISO_Code();
descriptionPay = new StringBuilder("Payment=(").append(paymentCur).append(")").append(paymentSource).append("/").append(paymentAccounted)
.append(" - Allocation=(").append(allocCur).append(")").append(allocationSource).append("/").append(allocationAccounted);
if (log.isLoggable(Level.FINE)) log.fine(descriptionPay.toString());
// Allocation not Payment Currency
BigDecimal allocationPaymentSource = allocationSource;
if (getC_Currency_ID() != payment.getC_Currency_ID())
{
allocationPaymentSource = MConversionRate.convert(getCtx(),
allocationSource, getC_Currency_ID(),
payment.getC_Currency_ID(), getDateAcct(),
payment.getC_ConversionType_ID(), payment.getAD_Client_ID(), payment.getAD_Org_ID());
if (allocationPaymentSource == null)
return "Gain/Loss - No Conversion from Allocation->Payment";
StringBuilder d2 = new StringBuilder("Allocation=(").append(allocCur).append(")").append(allocationSource)
.append("->(").append(paymentCur).append(")").append(allocationPaymentSource);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
descriptionPay.append(" - ").append(d2);
}
// Full Payment in currency
if (allocationPaymentSource.compareTo(paymentSource) == 0)
{
paymentDifference = paymentAccounted.subtract(allocationAccounted); // gain is negative
StringBuilder d2 = new StringBuilder("(full) = ").append(paymentDifference);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
descriptionPay.append(" - ").append(d2);
}
else // partial or MC
{
// percent of total payment
double multiplier = allocationPaymentSource.doubleValue() / paymentSource.doubleValue();
// Reduce Orig Payment Accounted
paymentAccounted = paymentAccounted.multiply(BigDecimal.valueOf(multiplier));
// Difference based on percentage of Orig Payment
paymentDifference = paymentAccounted.subtract(allocationAccounted); // gain is negative
// ignore Tolerance
if (paymentDifference.abs().compareTo(TOLERANCE) < 0)
paymentDifference = Env.ZERO;
// Round
int precision = as.getStdPrecision();
if (paymentDifference.scale() > precision)
paymentDifference = paymentDifference.setScale(precision, BigDecimal.ROUND_HALF_UP);
StringBuilder d2 = new StringBuilder("(partial) = ").append(paymentDifference).append(" - Multiplier=").append(multiplier);
if (log.isLoggable(Level.FINE)) log.fine(d2.toString());
descriptionPay.append(" - ").append(d2);
}
}
if (invoiceDifference.signum() == 0 && paymentDifference.signum() == 0)
{ {
log.fine("No Difference"); log.fine("No Difference");
return null; return null;
@ -796,22 +863,44 @@ public class Doc_AllocationHdr extends Doc
MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct()); MAccount gain = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedGain_Acct());
MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct()); MAccount loss = MAccount.get (as.getCtx(), as.getAcctSchemaDefault().getRealizedLoss_Acct());
// //
BigDecimal acctDifference = invoiceDifference.subtract(paymentDifference);
if (invoice.isSOTrx()) if (invoice.isSOTrx())
{ {
FactLine fl = fact.createLine (line, loss, gain, if (acctDifference.signum() != 0) {
as.getC_Currency_ID(), acctDifference); FactLine fl = fact.createLine (line, loss, gain, as.getC_Currency_ID(), acctDifference);
fl.setDescription(description.toString()); StringBuilder description = new StringBuilder(descriptionInv);
fact.createLine (line, acct, if (paymentDifference.signum() != 0 && descriptionPay != null) {
as.getC_Currency_ID(), acctDifference.negate()); description.append(" / ").append(descriptionPay);
}
fl.setDescription(description.toString()); fl.setDescription(description.toString());
} }
if (invoiceDifference.signum() != 0) {
FactLine fl = fact.createLine (line, invAcct, as.getC_Currency_ID(), invoiceDifference.negate());
fl.setDescription(descriptionInv.toString());
}
if (paymentDifference.signum() != 0) {
FactLine fl = fact.createLine (line, payAcct, as.getC_Currency_ID(), paymentDifference);
fl.setDescription(descriptionPay.toString());
}
}
else else
{ {
fact.createLine (line, acct, if (invoiceDifference.signum() != 0) {
as.getC_Currency_ID(), acctDifference); FactLine fl = fact.createLine (line, invAcct, as.getC_Currency_ID(), invoiceDifference);
@SuppressWarnings("unused") fl.setDescription(descriptionInv.toString());
FactLine fl = fact.createLine (line, loss, gain, }
as.getC_Currency_ID(), acctDifference.negate()); if (paymentDifference.signum() != 0) {
FactLine fl = fact.createLine (line, payAcct, as.getC_Currency_ID(), paymentDifference.negate());
fl.setDescription(descriptionPay.toString());
}
if (acctDifference.signum() != 0) {
FactLine fl = fact.createLine (line, loss, gain, as.getC_Currency_ID(), acctDifference.negate());
StringBuilder description = new StringBuilder(descriptionInv);
if (paymentDifference.signum() != 0 && descriptionPay != null) {
description.append(" / ").append(descriptionPay);
}
fl.setDescription(description.toString());
}
} }
return null; return null;
} // createRealizedGainLoss } // createRealizedGainLoss

View File

@ -94,6 +94,9 @@ public class Doc_GLJournal extends Doc
docLine.setAccount (account); docLine.setAccount (account);
// -- Organization of Line was set to Org of Account // -- Organization of Line was set to Org of Account
list.add(docLine); list.add(docLine);
if (docLine.getC_Currency_ID() != getC_Currency_ID())
setIsMultiCurrency(true);
} }
// Return Array // Return Array
int size = list.size(); int size = list.size();
@ -154,7 +157,7 @@ public class Doc_GLJournal extends Doc
@SuppressWarnings("unused") @SuppressWarnings("unused")
FactLine line = fact.createLine (p_lines[i], FactLine line = fact.createLine (p_lines[i],
p_lines[i].getAccount (), p_lines[i].getAccount (),
getC_Currency_ID(), p_lines[i].getC_Currency_ID(),
p_lines[i].getAmtSourceDr (), p_lines[i].getAmtSourceDr (),
p_lines[i].getAmtSourceCr ()); p_lines[i].getAmtSourceCr ());
} }

View File

@ -445,14 +445,41 @@ public class Doc_MatchPO extends Doc
&& mPO[i].getM_MatchPO_ID() != mMatchPO.getM_MatchPO_ID()) && mPO[i].getM_MatchPO_ID() != mMatchPO.getM_MatchPO_ID())
{ {
BigDecimal qty = (isReturnTrx ? mPO[i].getQty().negate() : mPO[i].getQty()); BigDecimal qty = (isReturnTrx ? mPO[i].getQty().negate() : mPO[i].getQty());
BigDecimal orderCost = BigDecimal.ZERO;
if (mPO[i].getM_InOutLine_ID() > 0) if (mPO[i].getM_InOutLine_ID() > 0)
{ {
tQty = tQty.add(qty); tQty = tQty.add(qty);
//IDEMPIERE-3742 Wrong product cost for partial MR
if (m_oLine.getC_Currency_ID() != as.getC_Currency_ID())
{
MOrder order = m_oLine.getParent();
if(MAcctSchema.COSTINGMETHOD_AveragePO.equals(as.getCostingMethod()))
{
orderCost = mPO[i].getM_InOutLine().getC_OrderLine().getPriceActual();
Timestamp dateAcct = mPO[i].getM_InOutLine().getM_InOut().getDateAcct();
BigDecimal rate = MConversionRate.getRate(
order.getC_Currency_ID(), as.getC_Currency_ID(),
dateAcct, order.getC_ConversionType_ID(),
m_oLine.getAD_Client_ID(), m_oLine.getAD_Org_ID());
if (rate == null)
{
p_Error = "Purchase Order not convertible - " + as.getName();
return null;
}
orderCost = orderCost.multiply(rate);
tAmt = tAmt.add(orderCost.multiply(qty));
} else {
tAmt = tAmt.add(poCost.multiply(qty));
}
} //IDEMPIERE-3742 Wrong product cost for partial MR
else {
tAmt = tAmt.add(poCost.multiply(qty)); tAmt = tAmt.add(poCost.multiply(qty));
} }
} }
} }
}
poCost = poCost.multiply(getQty()); // Delivered so far poCost = poCost.multiply(getQty()); // Delivered so far
tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost); tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost);
tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty()); tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty());

View File

@ -728,7 +728,7 @@ public final class FactLine extends X_Fact_Acct
Timestamp convDate = getDateAcct(); Timestamp convDate = getDateAcct();
if ( m_docLine != null && ( m_doc instanceof Doc_BankStatement || m_doc instanceof Doc_AllocationHdr ) ) if (m_docLine != null && m_doc instanceof Doc_BankStatement)
convDate = m_docLine.getDateConv(); convDate = m_docLine.getDateConv();

View File

@ -24,6 +24,7 @@ import org.adempiere.util.PaymentUtil;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.IBAN; import org.compiere.util.IBAN;
import org.compiere.util.Msg;
import org.compiere.util.Util; import org.compiere.util.Util;
/** /**
@ -214,7 +215,7 @@ public class MBPBankAccount extends X_C_BP_BankAccount
if (!Util.isEmpty(getIBAN())) { if (!Util.isEmpty(getIBAN())) {
setIBAN(IBAN.normalizeIBAN(getIBAN())); setIBAN(IBAN.normalizeIBAN(getIBAN()));
if (!IBAN.isValid(getIBAN())) { if (!IBAN.isValid(getIBAN())) {
log.saveError("Error", "IBAN is invalid"); log.saveError("Error", Msg.getMsg(getCtx(), "InvalidIBAN"));
return false; return false;
} }
} }

View File

@ -22,6 +22,7 @@ import java.util.Properties;
import org.compiere.util.CCache; import org.compiere.util.CCache;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.IBAN; import org.compiere.util.IBAN;
import org.compiere.util.Msg;
import org.compiere.util.Util; import org.compiere.util.Util;
@ -136,7 +137,7 @@ public class MBankAccount extends X_C_BankAccount
if (!Util.isEmpty(getIBAN())) { if (!Util.isEmpty(getIBAN())) {
setIBAN(IBAN.normalizeIBAN(getIBAN())); setIBAN(IBAN.normalizeIBAN(getIBAN()));
if (!IBAN.isValid(getIBAN())) { if (!IBAN.isValid(getIBAN())) {
log.saveError("Error", "IBAN is invalid"); log.saveError("Error", Msg.getMsg(getCtx(), "InvalidIBAN"));
return false; return false;
} }
} }

View File

@ -1035,7 +1035,7 @@ public class MInvoiceLine extends X_C_InvoiceLine
{ {
double result = getLineNetAmt().multiply(base).doubleValue(); double result = getLineNetAmt().multiply(base).doubleValue();
result /= total.doubleValue(); result /= total.doubleValue();
lca.setAmt(result, getParent().getC_Currency().getCostingPrecision()); lca.setAmt(result, getParent().getC_Currency().getStdPrecision());
} }
if (!lca.save()){ if (!lca.save()){
msgreturn = new StringBuilder("Cannot save line Allocation = ").append(lca); msgreturn = new StringBuilder("Cannot save line Allocation = ").append(lca);
@ -1170,7 +1170,7 @@ public class MInvoiceLine extends X_C_InvoiceLine
{ {
double result = getLineNetAmt().multiply(base).doubleValue(); double result = getLineNetAmt().multiply(base).doubleValue();
result /= total.doubleValue(); result /= total.doubleValue();
lca.setAmt(result, getParent().getC_Currency().getCostingPrecision()); lca.setAmt(result, getParent().getC_Currency().getStdPrecision());
} }
if (!lca.save()){ if (!lca.save()){
msgreturn = new StringBuilder("Cannot save line Allocation = ").append(lca); msgreturn = new StringBuilder("Cannot save line Allocation = ").append(lca);

View File

@ -527,8 +527,8 @@ public class MJournal extends X_GL_Journal implements DocAction
} }
// end BF [2789319] No check of Actual, Budget, Statistical attribute // end BF [2789319] No check of Actual, Budget, Statistical attribute
AmtSourceDr = AmtSourceDr.add(line.getAmtSourceDr()); AmtSourceDr = AmtSourceDr.add(line.getAmtAcctDr()); // multi-currency
AmtSourceCr = AmtSourceCr.add(line.getAmtSourceCr()); AmtSourceCr = AmtSourceCr.add(line.getAmtAcctCr());
} }
setTotalDr(AmtSourceDr); setTotalDr(AmtSourceDr);
setTotalCr(AmtSourceCr); setTotalCr(AmtSourceCr);

View File

@ -804,7 +804,7 @@ public class MPayment extends X_C_Payment
if (!Util.isEmpty(getIBAN())) { if (!Util.isEmpty(getIBAN())) {
setIBAN(IBAN.normalizeIBAN(getIBAN())); setIBAN(IBAN.normalizeIBAN(getIBAN()));
if (!IBAN.isValid(getIBAN())) { if (!IBAN.isValid(getIBAN())) {
log.saveError("Error", "IBAN is invalid"); log.saveError("Error", Msg.getMsg(getCtx(), "InvalidIBAN"));
return false; return false;
} }
} }

View File

@ -87,7 +87,7 @@ public class MPaymentTransaction extends X_C_PaymentTransaction implements Proce
if (!Util.isEmpty(getIBAN())) { if (!Util.isEmpty(getIBAN())) {
setIBAN(IBAN.normalizeIBAN(getIBAN())); setIBAN(IBAN.normalizeIBAN(getIBAN()));
if (!IBAN.isValid(getIBAN())) { if (!IBAN.isValid(getIBAN())) {
log.saveError("Error", "IBAN is invalid"); log.saveError("Error", Msg.getMsg(getCtx(), "InvalidIBAN"));
return false; return false;
} }
} }

View File

@ -282,7 +282,8 @@ public class MPeriod extends X_C_Period
int idxdate = -1; int idxdate = -1;
if ( tableID == MInventory.Table_ID if ( tableID == MInventory.Table_ID
|| tableID == MMovement.Table_ID || tableID == MMovement.Table_ID
|| tableID == MProduction.Table_ID) { || tableID == MProduction.Table_ID
|| tableID == MProjectIssue.Table_ID) {
idxdate = po.get_ColumnIndex("MovementDate"); idxdate = po.get_ColumnIndex("MovementDate");
} else if ( tableID == MRequisition.Table_ID) { } else if ( tableID == MRequisition.Table_ID) {
idxdate = po.get_ColumnIndex("DateDoc"); idxdate = po.get_ColumnIndex("DateDoc");
@ -333,6 +334,8 @@ public class MPeriod extends X_C_Period
} else if ( tableID == MAssetDisposed.Table_ID } else if ( tableID == MAssetDisposed.Table_ID
|| tableID == MDepreciationExp.Table_ID) { || tableID == MDepreciationExp.Table_ID) {
docBaseType = MDocType.DOCBASETYPE_GLDocument; // seems like a bug of fixed assets - must use GLJournal instead of GLDocument? docBaseType = MDocType.DOCBASETYPE_GLDocument; // seems like a bug of fixed assets - must use GLJournal instead of GLDocument?
} else if (tableID == MProjectIssue.Table_ID) {
docBaseType = MDocType.DOCBASETYPE_ProjectIssue;
} else { } else {
s_log.warning("Could not find C_DocType_ID for " + table.getTableName()); s_log.warning("Could not find C_DocType_ID for " + table.getTableName());
return true; return true;

View File

@ -288,7 +288,7 @@ public class MRequisitionLine extends X_M_RequisitionLine
* IDEMPIERE-178 Orders and Invoices must disallow amount lines without product/charge * IDEMPIERE-178 Orders and Invoices must disallow amount lines without product/charge
*/ */
if (getParent().getC_DocType().isChargeOrProductMandatory()) { if (getParent().getC_DocType().isChargeOrProductMandatory()) {
if (getC_Charge_ID() == 0 && getM_Product_ID() == 0 && getPriceActual().signum() != 0) { if (getC_Charge_ID() == 0 && getM_Product_ID() == 0 && (getPriceActual().signum() != 0 || getQty().signum() != 0)) {
log.saveError("FillMandatory", Msg.translate(getCtx(), "ChargeOrProductMandatory")); log.saveError("FillMandatory", Msg.translate(getCtx(), "ChargeOrProductMandatory"));
return false; return false;
} }

View File

@ -871,14 +871,8 @@ public final class Env
throw new IllegalArgumentException ("Require Context"); throw new IllegalArgumentException ("Require Context");
String s = getContext(ctx, WindowNo, context, false); String s = getContext(ctx, WindowNo, context, false);
// JDBC Format YYYY-MM-DD example 2000-09-11 00:00:00.0 // JDBC Format YYYY-MM-DD example 2000-09-11 00:00:00.0
if (s == null || s.equals("")) if (Util.isEmpty(s))
{
if (!"#date".equalsIgnoreCase(context))
{
log.log(Level.WARNING, "No value for: " + context);
}
return new Timestamp(System.currentTimeMillis()); return new Timestamp(System.currentTimeMillis());
}
// BUG:3075946 KTU - Fix Thai Date // BUG:3075946 KTU - Fix Thai Date
/* /*

View File

@ -26,7 +26,7 @@ public class IBAN {
{ {
if (iban!=null) if (iban!=null)
{ {
return iban.trim().replace(" ", "") ; return iban.trim().replace(" ", "").toUpperCase() ;
} }
return null ; return null ;
} }

View File

@ -1353,7 +1353,7 @@ public class ReportStarter implements ProcessCall, ClientProcess
jasperFile.setLastModified( reportFile.lastModified()); //Synchronize Dates jasperFile.setLastModified( reportFile.lastModified()); //Synchronize Dates
compiledJasperReport = (JasperReport)JRLoader.loadObject(jasperFile); compiledJasperReport = (JasperReport)JRLoader.loadObject(jasperFile);
} catch (JRException e) { } catch (JRException e) {
log.log(Level.SEVERE, "Error", e); throw new AdempiereException(e);
} }
return compiledJasperReport; return compiledJasperReport;
} }

View File

@ -533,7 +533,7 @@ public class WAllocation extends Allocation
allocateButton.setEnabled(true); allocateButton.setEnabled(true);
if (allocation != null) if (allocation != null)
{ {
DocumentLink link = new DocumentLink(allocation.getDocumentNo(), allocation.get_Table_ID(), allocation.get_ID()); DocumentLink link = new DocumentLink(Msg.getElement(Env.getCtx(), MAllocationHdr.COLUMNNAME_C_AllocationHdr_ID) + ": " + allocation.getDocumentNo(), allocation.get_Table_ID(), allocation.get_ID());
statusBar.appendChild(link); statusBar.appendChild(link);
} }
} }

View File

@ -118,7 +118,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
{ {
log.log(Level.SEVERE, "", e); log.log(Level.SEVERE, "", e);
} }
} // init } // WPayPrint
// Static Variables // Static Variables
protected Panel centerPanel = new Panel(); protected Panel centerPanel = new Panel();
@ -234,8 +234,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
bExport.setDisabled(true); bExport.setDisabled(true);
bPrint.setDisabled(true); bPrint.setDisabled(true);
fDepositBatch.setReadWrite(false); fDepositBatch.setReadWrite(false);
fDocumentNo.setReadWrite(false); } // zkInit
} // VPayPrint
/** /**
* Dynamic Init * Dynamic Init

View File

@ -85,8 +85,8 @@ public class WAccountEditor extends WEditor implements ContextMenuListener
@Override @Override
public Object getValue() public Object getValue()
{ {
//if (m_mAccount.C_ValidCombination_ID == 0) if (m_mAccount.C_ValidCombination_ID == 0)
// return null; return null;
return new Integer (m_mAccount.C_ValidCombination_ID); return new Integer (m_mAccount.C_ValidCombination_ID);
} }
@ -101,7 +101,11 @@ public class WAccountEditor extends WEditor implements ContextMenuListener
*/ */
public void cmd_button() public void cmd_button()
{ {
int C_AcctSchema_ID = Env.getContextAsInt(Env.getCtx(), gridField.getWindowNo(), "C_AcctSchema_ID"); int C_AcctSchema_ID;
if (gridField.getGridTab() != null)
C_AcctSchema_ID = Env.getContextAsInt(Env.getCtx(), gridField.getWindowNo(), gridField.getGridTab().getTabNo(), "C_AcctSchema_ID");
else
C_AcctSchema_ID = Env.getContextAsInt(Env.getCtx(), gridField.getWindowNo(), "C_AcctSchema_ID");
// Try to get C_AcctSchema_ID from global context - teo_sarca BF [ 1830531 ] // Try to get C_AcctSchema_ID from global context - teo_sarca BF [ 1830531 ]
if (C_AcctSchema_ID <= 0) if (C_AcctSchema_ID <= 0)
{ {

View File

@ -2649,7 +2649,7 @@ public class FindWindow extends Window implements EventListener<Event>, ValueCha
*/ */
private void setStatusDB (int currentCount) private void setStatusDB (int currentCount)
{ {
StringBuilder text = new StringBuilder(" ").append(currentCount).append(" / ").append(m_total).append(" "); StringBuilder text = new StringBuilder(" ").append(Msg.getMsg(Env.getCtx(), "Records")).append(" = ").append(m_total).append(" ");
statusBar.setStatusDB(text.toString()); statusBar.setStatusDB(text.toString());
} // setDtatusDB } // setDtatusDB
/** END DEVCOFFEE **/ /** END DEVCOFFEE **/

View File

@ -2,6 +2,9 @@ CKEDITOR.editorConfig = function(config) {
config.resize_enabled = false; config.resize_enabled = false;
config.toolbarCanCollapse = true; config.toolbarCanCollapse = true;
config.toolbar = 'MyToolbar'; config.toolbar = 'MyToolbar';
config.coreStyles_bold = { element: 'b', overrides: 'strong' };
config.coreStyles_italic = { element: 'i', overrides: 'em' };
config.coreStyles_strike = { element: 'strike', overrides: 's' };
config.toolbar_MyToolbar = config.toolbar_MyToolbar =
[ [
{ name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] }, { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },

View File

@ -2,6 +2,9 @@ CKEDITOR.editorConfig = function(config) {
config.resize_enabled = false; config.resize_enabled = false;
config.toolbarCanCollapse = true; config.toolbarCanCollapse = true;
config.toolbar = 'MyToolbar'; config.toolbar = 'MyToolbar';
config.coreStyles_bold = { element: 'b', overrides: 'strong' };
config.coreStyles_italic = { element: 'i', overrides: 'em' };
config.coreStyles_strike = { element: 'strike', overrides: 's' };
config.toolbar_MyToolbar = config.toolbar_MyToolbar =
[ [
{ name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] }, { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },

View File

@ -65,10 +65,7 @@ public class CompositeServiceImpl extends AbstractService implements CompositeSe
*/ */
@Override @Override
public CompositeResponsesDocument compositeOperation(CompositeRequestDocument reqs) { public CompositeResponsesDocument compositeOperation(CompositeRequestDocument reqs) {
boolean connected = getCompiereService().isConnected();
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
CompositeResponsesDocument ret = CompositeResponsesDocument.Factory.newInstance(); CompositeResponsesDocument ret = CompositeResponsesDocument.Factory.newInstance();
@ -124,7 +121,6 @@ public class CompositeServiceImpl extends AbstractService implements CompositeSe
return ret; return ret;
} finally { } finally {
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }

View File

@ -76,7 +76,7 @@ public class MWebService extends X_WS_WebService
* @param webServiceValue * @param webServiceValue
* @return Table * @return Table
*/ */
public static MWebService get (Properties ctx, String webServiceValue) public static synchronized MWebService get (Properties ctx, String webServiceValue)
{ {
if (webServiceValue == null) if (webServiceValue == null)
return null; return null;

View File

@ -79,13 +79,13 @@ public class CompiereService {
public final String dateFormatOnlyForCtx = "yyyy-MM-dd"; public final String dateFormatOnlyForCtx = "yyyy-MM-dd";
private boolean m_connected; private int m_connectCount;
/** /**
* *
* @return AD_Client_ID of current request * @return AD_Client_ID of current request
*/ */
public int getAD_Client_ID() { public synchronized int getAD_Client_ID() {
return m_AD_Client_ID; return m_AD_Client_ID;
} }
@ -93,7 +93,7 @@ public class CompiereService {
* *
* @return AD_Org_ID of current request * @return AD_Org_ID of current request
*/ */
public int getAD_Org_ID() { public synchronized int getAD_Org_ID() {
return m_AD_Org_ID; return m_AD_Org_ID;
} }
@ -101,7 +101,7 @@ public class CompiereService {
* *
* @return context of current request * @return context of current request
*/ */
public Properties getCtx() { public synchronized Properties getCtx() {
return Env.getCtx(); return Env.getCtx();
} }
@ -111,20 +111,16 @@ public class CompiereService {
public CompiereService() public CompiereService()
{ {
m_loggedin = false; m_loggedin = false;
m_connected = false; m_connectCount = 0;
} }
/** /**
* setup request * setup request
*/ */
public void connect() public void connect()
{
if (!m_connected)
{ {
CompiereUtil.initWeb(); CompiereUtil.initWeb();
m_connected = true;
ServerContext.setCurrentInstance(new Properties()); ServerContext.setCurrentInstance(new Properties());
Env.setContext(getCtx(), "#AD_Language", "en_US" ); Env.setContext(getCtx(), "#AD_Language", "en_US" );
m_language = Language.getLanguage("en_US"); m_language = Language.getLanguage("en_US");
@ -135,54 +131,39 @@ public class CompiereService {
dateFormatJDBC = DisplayType.getDateFormat_JDBC(); dateFormatJDBC = DisplayType.getDateFormat_JDBC();
dateTimeFormatJDBC = DisplayType.getTimestampFormat_Default(); dateTimeFormatJDBC = DisplayType.getTimestampFormat_Default();
timeFormatJDBC = DisplayType.getTimeFormat_Default(); timeFormatJDBC = DisplayType.getTimeFormat_Default();
m_connectCount++;
} }
/**
* Increase connect count
*/
public synchronized void connectCacheInstance()
{
m_connectCount++;
} }
/** /**
* cleanup request * cleanup request
*/ */
public void disconnect() public synchronized void disconnect()
{ {
m_connectCount--;
// TODO: create a thread that checks expired connected compiereservices and log them out // TODO: create a thread that checks expired connected compiereservices and log them out
if (! isExpired()) { expungeIfExpire();
// do not close, save session in cache
if (! csMap.containsValue(this)) {
String key = getKey(m_AD_Client_ID,
m_AD_Org_ID,
m_userName,
m_AD_Role_ID,
m_M_Warehouse_ID,
m_locale,
m_password,
m_IPAddress);
csMap.put(key.toString(), this);
Properties savedCache = new Properties();
savedCache.putAll(Env.getCtx());
ctxMap.put(key.toString(), savedCache);
if (log.isLoggable(Level.INFO)) log.info("Saving " + this + " in cache");
}
}
}
/**
* @return true if started
*/
public boolean isConnected()
{
return m_connected;
} }
/** /**
* @return Language of current request * @return Language of current request
*/ */
public Language getLanguage() { public synchronized Language getLanguage() {
return m_language; return m_language;
} }
/** /**
* @return true if already logged in * @return true if already logged in
*/ */
public boolean isLoggedIn() { public synchronized boolean isLoggedIn() {
return m_loggedin; return m_loggedin;
} }
@ -196,7 +177,7 @@ public class CompiereService {
* @param AD_Org_ID org * @param AD_Org_ID org
* @param M_Warehouse_ID warehouse * @param M_Warehouse_ID warehouse
*/ */
private String checkLogin (Properties ctx, int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID) private synchronized String checkLogin (Properties ctx, int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID)
{ {
// Get Login Info // Get Login Info
String loginInfo = null; String loginInfo = null;
@ -262,7 +243,7 @@ public class CompiereService {
* @param Lang * @param Lang
* @return true if login is successful * @return true if login is successful
*/ */
public boolean login( int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID, String Lang ) { public synchronized boolean login( int AD_User_ID, int AD_Role_ID, int AD_Client_ID, int AD_Org_ID, int M_Warehouse_ID, String Lang ) {
m_loggedin = false; m_loggedin = false;
String loginInfo = checkLogin (getCtx(), AD_User_ID, AD_Role_ID, AD_Client_ID, AD_Org_ID, M_Warehouse_ID ); String loginInfo = checkLogin (getCtx(), AD_User_ID, AD_Role_ID, AD_Client_ID, AD_Org_ID, M_Warehouse_ID );
if (loginInfo == null) if (loginInfo == null)
@ -315,6 +296,26 @@ public class CompiereService {
session.saveEx(); session.saveEx();
m_loggedin = true; m_loggedin = true;
synchronized (csMap) {
//save session in cache
String key = getKey(m_AD_Client_ID,
m_AD_Org_ID,
m_userName,
m_AD_Role_ID,
m_M_Warehouse_ID,
m_locale,
m_password,
m_IPAddress);
if (! csMap.containsKey(key)) {
csMap.put(key.toString(), this);
Properties savedCache = new Properties();
savedCache.putAll(Env.getCtx());
ctxMap.put(key.toString(), savedCache);
if (log.isLoggable(Level.INFO)) log.info("Saving " + this + " in cache");
}
}
return true; return true;
} }
@ -322,7 +323,7 @@ public class CompiereService {
* *
* @return AD_User_ID of current request * @return AD_User_ID of current request
*/ */
public int getAD_User_ID() { public synchronized int getAD_User_ID() {
return m_AD_User_ID; return m_AD_User_ID;
} }
@ -330,7 +331,7 @@ public class CompiereService {
* *
* @return AD_Role_ID of current request * @return AD_Role_ID of current request
*/ */
public int getAD_Role_ID() { public synchronized int getAD_Role_ID() {
return m_AD_Role_ID; return m_AD_Role_ID;
} }
@ -338,7 +339,7 @@ public class CompiereService {
* *
* @return locale code of current request * @return locale code of current request
*/ */
public String getLocale() { public synchronized String getLocale() {
return m_locale; return m_locale;
} }
@ -346,7 +347,7 @@ public class CompiereService {
* *
* @return M_Warehouse_ID of current request * @return M_Warehouse_ID of current request
*/ */
public int getM_Warehouse_ID() { public synchronized int getM_Warehouse_ID() {
return m_M_Warehouse_ID; return m_M_Warehouse_ID;
} }
@ -354,43 +355,43 @@ public class CompiereService {
* *
* @return logged in user name of current request * @return logged in user name of current request
*/ */
public String getUserName() { public synchronized String getUserName() {
return m_userName; return m_userName;
} }
/** /**
* @return set password * @return set password
*/ */
public void setPassword(String pass) { public synchronized void setPassword(String pass) {
m_password = pass; m_password = pass;
} }
/** /**
* @return logged in password of current request * @return logged in password of current request
*/ */
public String getPassword() { public synchronized String getPassword() {
return m_password; return m_password;
} }
/** /**
* @return set expiry minutes * @return set expiry minutes
*/ */
public void setExpiryMinutes(int expiryMinutes) { public synchronized void setExpiryMinutes(int expiryMinutes) {
m_expiryMinutes = expiryMinutes; m_expiryMinutes = expiryMinutes;
} }
/** /**
* @return logged in expiry minutes of current request * @return logged in expiry minutes of current request
*/ */
public int getExpiryMinutes() { public synchronized int getExpiryMinutes() {
return m_expiryMinutes; return m_expiryMinutes;
} }
public void refreshLastAuthorizationTime() { public synchronized void refreshLastAuthorizationTime() {
m_lastAuthorizationTime = System.currentTimeMillis(); m_lastAuthorizationTime = System.currentTimeMillis();
} }
public void setIPAddress(String remoteAddr) { public synchronized void setIPAddress(String remoteAddr) {
m_IPAddress = remoteAddr; m_IPAddress = remoteAddr;
} }
@ -404,12 +405,11 @@ public class CompiereService {
loginRequest.getPass(), loginRequest.getPass(),
req.getRemoteAddr()); req.getRemoteAddr());
CompiereService l_cs = null; CompiereService l_cs = null;
synchronized (csMap) {
if (csMap.containsKey(key)) { if (csMap.containsKey(key)) {
l_cs = csMap.get(key); l_cs = csMap.get(key);
if (l_cs != null) { if (l_cs != null) {
if (l_cs.isExpired()) { if (l_cs.expungeIfExpire()) {
csMap.remove(key);
ctxMap.remove(key);
l_cs = null; l_cs = null;
} else { } else {
Properties cachedCtx = ctxMap.get(key); Properties cachedCtx = ctxMap.get(key);
@ -418,6 +418,7 @@ public class CompiereService {
} }
} }
} }
}
return l_cs; return l_cs;
} }
@ -442,19 +443,43 @@ public class CompiereService {
return key.toString(); return key.toString();
} }
private boolean isExpired() { private synchronized boolean expungeIfExpire() {
boolean expired = boolean expired =
( (
(getExpiryMinutes() <= 0) (getExpiryMinutes() <= 0)
|| (m_lastAuthorizationTime + (getExpiryMinutes() * 60000) <= System.currentTimeMillis()) || (m_lastAuthorizationTime + (getExpiryMinutes() * 60000) <= System.currentTimeMillis())
); );
if (m_connected && expired) if (m_connectCount==0 && expired)
{ {
synchronized (csMap) {
String key = getKey(m_AD_Client_ID,
m_AD_Org_ID,
m_userName,
m_AD_Role_ID,
m_M_Warehouse_ID,
m_locale,
m_password,
m_IPAddress);
if (csMap.containsKey(key)) {
csMap.remove(key);
}
if (ctxMap.containsKey(key)) {
Properties cachedCtx = ctxMap.remove(key);
Properties currentCtx = ServerContext.getCurrentInstance();
try {
ServerContext.setCurrentInstance(cachedCtx);
if (log.isLoggable(Level.INFO)) log.info("Closing expired/invalid " + this); if (log.isLoggable(Level.INFO)) log.info("Closing expired/invalid " + this);
Env.logout(); Env.logout();
} finally {
if (currentCtx == cachedCtx) {
ServerContext.dispose(); ServerContext.dispose();
} else {
ServerContext.setCurrentInstance(currentCtx);
}
}
}
m_loggedin = false; m_loggedin = false;
m_connected = false; }
} }
return expired; return expired;
} }

View File

@ -168,12 +168,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
* use the runProcess web service * use the runProcess web service
*/ */
public StandardResponseDocument setDocAction(ModelSetDocActionRequestDocument req) { public StandardResponseDocument setDocAction(ModelSetDocActionRequestDocument req) {
boolean connected = getCompiereService().isConnected();
boolean manageTrx = this.manageTrx;
Trx trx=null; Trx trx=null;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance(); StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
@ -289,9 +285,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && !trx.commit()) if (manageTrx && !trx.commit())
return rollbackAndSetError(trx, resp, ret, true, "Cannot commit after docAction"); return rollbackAndSetError(trx, resp, ret, true, "Cannot commit after docAction");
if (manageTrx)
trx.close();
// resp.setError(""); // resp.setError("");
resp.setIsError(false); resp.setIsError(false);
@ -305,7 +298,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }
@ -390,10 +382,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
public RunProcessResponseDocument runProcess(ModelRunProcessRequestDocument req) { public RunProcessResponseDocument runProcess(ModelRunProcessRequestDocument req) {
boolean connected = getCompiereService().isConnected();
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
RunProcessResponseDocument resbadlogin = RunProcessResponseDocument.Factory.newInstance(); RunProcessResponseDocument resbadlogin = RunProcessResponseDocument.Factory.newInstance();
@ -430,16 +419,12 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
requestCtx.put(serviceType+"_Summary", response.getRunProcessResponse().getSummary()); requestCtx.put(serviceType+"_Summary", response.getRunProcessResponse().getSummary());
return response; return response;
} finally { } finally {
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }
public WindowTabDataDocument getList(ModelGetListRequestDocument req) { public WindowTabDataDocument getList(ModelGetListRequestDocument req) {
boolean connected = getCompiereService().isConnected();
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
WindowTabDataDocument resdoc = WindowTabDataDocument.Factory.newInstance(); WindowTabDataDocument resdoc = WindowTabDataDocument.Factory.newInstance();
@ -649,19 +634,13 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
return resdoc; return resdoc;
} finally { } finally {
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} // getList } // getList
public StandardResponseDocument deleteData(ModelCRUDRequestDocument req) { public StandardResponseDocument deleteData(ModelCRUDRequestDocument req) {
boolean connected = getCompiereService().isConnected();
Trx trx = null; Trx trx = null;
boolean manageTrx = this.manageTrx;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance(); StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
@ -727,7 +706,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }
@ -740,14 +718,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
} }
public StandardResponseDocument createData(ModelCRUDRequestDocument req) { public StandardResponseDocument createData(ModelCRUDRequestDocument req) {
boolean connected = getCompiereService().isConnected();
Trx trx = null; Trx trx = null;
boolean manageTrx = this.manageTrx;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance(); StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
@ -849,20 +821,14 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} // createData } // createData
public StandardResponseDocument createUpdateData(ModelCRUDRequestDocument req) { public StandardResponseDocument createUpdateData(ModelCRUDRequestDocument req) {
boolean connected = getCompiereService().isConnected();
Trx trx = null; Trx trx = null;
boolean manageTrx = this.manageTrx;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance(); StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
@ -1058,7 +1024,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} // createUpdateData } // createUpdateData
@ -1234,13 +1199,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
} }
public StandardResponseDocument updateData(ModelCRUDRequestDocument req){ public StandardResponseDocument updateData(ModelCRUDRequestDocument req){
boolean connected = getCompiereService().isConnected();
Trx trx = null; Trx trx = null;
boolean manageTrx = this.manageTrx;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance(); StandardResponseDocument ret = StandardResponseDocument.Factory.newInstance();
@ -1323,16 +1283,12 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} // updateData } // updateData
public WindowTabDataDocument readData(ModelCRUDRequestDocument req) { public WindowTabDataDocument readData(ModelCRUDRequestDocument req) {
boolean connected = getCompiereService().isConnected();
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
WindowTabDataDocument ret = WindowTabDataDocument.Factory.newInstance(); WindowTabDataDocument ret = WindowTabDataDocument.Factory.newInstance();
@ -1423,18 +1379,13 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
return ret; return ret;
} finally { } finally {
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }
public WindowTabDataDocument queryData(ModelCRUDRequestDocument req) { public WindowTabDataDocument queryData(ModelCRUDRequestDocument req) {
boolean connected = getCompiereService().isConnected();
boolean manageTrx = this.manageTrx;
Trx trx=null; Trx trx=null;
try { try {
if (!connected)
getCompiereService().connect(); getCompiereService().connect();
CompiereService m_cs = getCompiereService(); CompiereService m_cs = getCompiereService();
@ -1589,7 +1540,6 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic
if (manageTrx && trx != null) if (manageTrx && trx != null)
trx.close(); trx.close();
if (!connected)
getCompiereService().disconnect(); getCompiereService().disconnect();
} }
} }

View File

@ -14,6 +14,8 @@
package org.idempiere.webservices; package org.idempiere.webservices;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -38,8 +40,9 @@ import org.compiere.model.MWebService;
import org.compiere.model.MWebServiceType; import org.compiere.model.MWebServiceType;
import org.compiere.model.PO; import org.compiere.model.PO;
import org.compiere.model.POInfo; import org.compiere.model.POInfo;
import org.compiere.model.Query;
import org.compiere.model.X_WS_WebServiceMethod; import org.compiere.model.X_WS_WebServiceMethod;
import org.compiere.model.X_WS_WebServiceTypeAccess;
import org.compiere.util.CCache;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.KeyNamePair; import org.compiere.util.KeyNamePair;
@ -64,7 +67,9 @@ import org.idempiere.webservices.fault.IdempiereServiceFault;
*/ */
public class AbstractService { public class AbstractService {
private static final String ROLE_ACCESS_SQL = "SELECT IsActive FROM WS_WebServiceTypeAccess WHERE AD_Role_ID=? " private static final String ROLE_ACCESS_SQL = "SELECT IsActive FROM WS_WebServiceTypeAccess WHERE AD_Role_ID IN ("
+ "SELECT AD_Role_ID FROM AD_Role WHERE AD_Role_ID=? UNION "
+ "SELECT Included_Role_ID as AD_Role_ID FROM AD_Role_Included WHERE AD_Role_ID=?) "
+ "AND WS_WebServiceType_ID=?"; + "AND WS_WebServiceType_ID=?";
private static final String COMPIERE_SERVICE = "CompiereService"; private static final String COMPIERE_SERVICE = "CompiereService";
@Resource @Resource
@ -91,6 +96,7 @@ public class AbstractService {
if (cachedCs != null) { if (cachedCs != null) {
m_cs = cachedCs; m_cs = cachedCs;
req.setAttribute(COMPIERE_SERVICE, cachedCs); req.setAttribute(COMPIERE_SERVICE, cachedCs);
m_cs.connectCacheInstance();
return authenticate(webService, method, serviceType, cachedCs); // already logged with same data return authenticate(webService, method, serviceType, cachedCs); // already logged with same data
} }
} }
@ -201,6 +207,9 @@ public class AbstractService {
return authenticate(webService, method, serviceType, m_cs); return authenticate(webService, method, serviceType, m_cs);
} }
private static CCache<String,MWebServiceType> s_WebServiceTypeCache = new CCache<String,MWebServiceType>(MWebServiceType.Table_Name, 10, 60); //60 minutes
private static CCache<String,Boolean> s_RoleAccessCache = new CCache<>(X_WS_WebServiceTypeAccess.Table_Name, 60, 60);
/** /**
* Authenticate user for requested service type * Authenticate user for requested service type
* @param webServiceValue * @param webServiceValue
@ -219,28 +228,59 @@ public class AbstractService {
if (m_webservicemethod == null || !m_webservicemethod.isActive()) if (m_webservicemethod == null || !m_webservicemethod.isActive())
return "Method " + methodValue + " not registered"; return "Method " + methodValue + " not registered";
MWebServiceType m_webservicetype = new Query(m_cs.getCtx(), MWebServiceType.Table_Name, MWebServiceType m_webservicetype = null;
"AD_Client_ID IN (0,?) AND WS_WebService_ID=? AND WS_WebServiceMethod_ID=? AND Value=?", String key = m_cs.getAD_Client_ID() + "|" + m_webservice.getWS_WebService_ID() + "|"
null) + m_webservicemethod.getWS_WebServiceMethod_ID() + "|" + serviceTypeValue;
.setOnlyActiveRecords(true) synchronized (s_WebServiceTypeCache) {
.setParameters(m_cs.getAD_Client_ID(), m_webservice.getWS_WebService_ID(), m_webservicemethod.getWS_WebServiceMethod_ID(), serviceTypeValue) m_webservicetype = s_WebServiceTypeCache.get(key);
.setOrderBy("AD_Client_ID DESC") // IDEMPIERE-3394 give precedence to tenant defined if there are system+tenant if (m_webservicetype == null) {
.first(); final String sql = "SELECT * FROM WS_WebServiceType " + "WHERE AD_Client_ID=? " + "AND WS_WebService_ID=? "
+ "AND WS_WebServiceMethod_ID=? " + "AND Value=? " + "AND IsActive='Y'";
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_cs.getAD_Client_ID());
pstmt.setInt(2, m_webservice.getWS_WebService_ID());
pstmt.setInt(3, m_webservicemethod.getWS_WebServiceMethod_ID());
pstmt.setString(4, serviceTypeValue);
rs = pstmt.executeQuery();
if (rs.next()) {
m_webservicetype = new MWebServiceType(m_cs.getCtx(), rs, null);
s_WebServiceTypeCache.put(key, m_webservicetype);
}
} catch (Exception e) {
throw new IdempiereServiceFault(e.getClass().toString() + " " + e.getMessage() + " sql=" + sql, e.getCause(), new QName(
"authenticate"));
} finally {
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
}
}
if (m_webservicetype == null) if (m_webservicetype == null)
return "Service type " + serviceTypeValue + " not configured"; return "Service type " + serviceTypeValue + " not configured";
getHttpServletRequest().setAttribute("MWebServiceType", m_webservicetype); getHttpServletRequest().setAttribute("MWebServiceType", m_webservicetype);
int AD_Role_ID = Env.getAD_Role_ID( m_cs.getCtx());
key = AD_Role_ID + "|" + m_webservicetype.get_ID();
synchronized (s_RoleAccessCache) {
Boolean bAccess = s_RoleAccessCache.get(key);
if (bAccess == null) {
// Check if role has access on web-service // Check if role has access on web-service
String hasAccess = DB.getSQLValueStringEx(null, ROLE_ACCESS_SQL, String hasAccess = DB.getSQLValueStringEx(null, ROLE_ACCESS_SQL,
Env.getAD_Role_ID( m_cs.getCtx()), AD_Role_ID, AD_Role_ID, m_webservicetype.get_ID());
m_webservicetype.get_ID()); bAccess = "Y".equals(hasAccess);
s_RoleAccessCache.put(key, bAccess);
if (!"Y".equals(hasAccess)) }
if (!bAccess.booleanValue())
{ {
return "Web Service Error: Login role does not have access to the service type"; return "Web Service Error: Login role does not have access to the service type";
} }
}
String ret=invokeLoginValidator(null, m_cs.getCtx(), m_webservicetype, IWSValidator.TIMING_ON_AUTHORIZATION); String ret=invokeLoginValidator(null, m_cs.getCtx(), m_webservicetype, IWSValidator.TIMING_ON_AUTHORIZATION);
if(ret!=null && ret.length()>0) if(ret!=null && ret.length()>0)