diff --git a/db/ddlutils/oracle/functions/C_PaymentTerm_Discount.sql b/db/ddlutils/oracle/functions/C_PaymentTerm_Discount.sql index 3eca08f287..c403c42a8b 100644 --- a/db/ddlutils/oracle/functions/C_PaymentTerm_Discount.sql +++ b/db/ddlutils/oracle/functions/C_PaymentTerm_Discount.sql @@ -25,6 +25,7 @@ RETURN NUMBER AS v_Precision NUMBER := 0; + v_Currency NUMBER := 0; v_Min NUMBER := 0; Discount NUMBER := 0; CURSOR Cur_PT IS @@ -36,10 +37,20 @@ AS Add1Date NUMBER := 0; Add2Date NUMBER := 0; BEGIN + v_Currency := Currency_ID; + IF (v_Currency = 0) THEN + SELECT COALESCE(MAX(C_Currency_ID),0) + INTO v_Currency + FROM AD_ClientInfo ci, C_AcctSchema s, C_PaymentTerm pt + WHERE ci.AD_Client_ID = s.AD_Client_ID + AND ci.AD_Client_ID = pt.AD_Client_ID + AND pt.C_PaymentTerm_ID = PaymentTerm_ID; + END IF; + SELECT StdPrecision INTO v_Precision FROM C_Currency - WHERE C_Currency_ID = Currency_ID; + WHERE C_Currency_ID = v_Currency; SELECT POWER(1/10,v_Precision) INTO v_Min FROM DUAL; diff --git a/db/ddlutils/postgresql/functions/C_PaymentTerm_Discount.sql b/db/ddlutils/postgresql/functions/C_PaymentTerm_Discount.sql index 5fcbb88256..6fdc1498f0 100644 --- a/db/ddlutils/postgresql/functions/C_PaymentTerm_Discount.sql +++ b/db/ddlutils/postgresql/functions/C_PaymentTerm_Discount.sql @@ -26,6 +26,7 @@ RETURNS NUMERIC AS $body$ DECLARE v_Precision NUMERIC := 0; + v_Currency NUMERIC := 0; v_Min NUMERIC := 0; Discount NUMERIC := 0; Discount1Date timestamp with time zone; @@ -34,10 +35,20 @@ DECLARE Add2Date NUMERIC := 0; p RECORD; BEGIN + v_Currency := Currency_ID; + IF (v_Currency = 0) THEN + SELECT COALESCE(MAX(C_Currency_ID),0) + INTO v_Currency + FROM AD_ClientInfo ci, C_AcctSchema s, C_PaymentTerm pt + WHERE ci.AD_Client_ID = s.AD_Client_ID + AND ci.AD_Client_ID = pt.AD_Client_ID + AND pt.C_PaymentTerm_ID = PaymentTerm_ID; + END IF; + SELECT StdPrecision INTO v_Precision FROM C_Currency - WHERE C_Currency_ID = Currency_ID; + WHERE C_Currency_ID = v_Currency; SELECT 1/10^v_Precision INTO v_Min; diff --git a/migration/i2.0z/oracle/201406031604_IDEMPIERE-1968.sql b/migration/i2.0z/oracle/201406031604_IDEMPIERE-1968.sql new file mode 100644 index 0000000000..cf046995d9 --- /dev/null +++ b/migration/i2.0z/oracle/201406031604_IDEMPIERE-1968.sql @@ -0,0 +1,10 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jun 3, 2014 4:22:36 PM ICT +-- IDEMPIERE-1968 valid check box in info window can manual editable +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_DATE('2014-06-03 16:22:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201639 +; + +SELECT register_migration_script('201406031604_IDEMPIERE-1968.sql') FROM dual +; diff --git a/migration/i2.0z/oracle/201406031605_IDEMPIERE-1968-Access.sql b/migration/i2.0z/oracle/201406031605_IDEMPIERE-1968-Access.sql new file mode 100644 index 0000000000..25b1e80d92 --- /dev/null +++ b/migration/i2.0z/oracle/201406031605_IDEMPIERE-1968-Access.sql @@ -0,0 +1,73 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jun 3, 2014 5:05:09 PM ICT +-- IDEMPIERE-1968 valid check box in info window can manual editable +UPDATE AD_Column SET IsUpdateable='N', FKConstraintType='C',Updated=TO_DATE('2014-06-03 17:05:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=208377 +; + +-- Jun 3, 2014 5:05:16 PM ICT +ALTER TABLE AD_InfoWindow_Access DROP CONSTRAINT adinfowindow_adinfowindowacces +; + +-- Jun 3, 2014 5:05:16 PM ICT +ALTER TABLE AD_InfoWindow_Access ADD CONSTRAINT adinfowindow_adinfowindowacces FOREIGN KEY (AD_InfoWindow_ID) REFERENCES ad_infowindow(ad_infowindow_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 3, 2014 5:13:25 PM ICT +INSERT INTO AD_Tab (ImportFields,Processing,IsSingleRow,AD_Window_ID,SeqNo,IsTranslationTab,IsSortTab,HasTree,IsInfoTab,IsReadOnly,IsInsertRecord,IsAdvancedTab,TabLevel,AD_Tab_UU,EntityType,Name,AD_Tab_ID,AD_Org_ID,Created,CreatedBy,Updated,UpdatedBy,IsActive,AD_Column_ID,AD_Table_ID,AD_Client_ID,TreeDisplayedOn) VALUES ('N','N','Y',385,70,'N','N','N','N','N','Y','N',0,'d7868d02-46bc-4112-af34-35df9e13a79f','D','Role Access',200144,0,TO_DATE('2014-06-03 17:13:24','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-06-03 17:13:24','YYYY-MM-DD HH24:MI:SS'),100,'Y',208377,200054,0,'B') +; + +-- Jun 3, 2014 5:13:52 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,36,'N','N',0,'Y',203051,'N','AD_InfoWindow_Access_UU','ff201a9f-6ce6-4554-8fbf-111507465b96','N','N',100,0,100,TO_DATE('2014-06-03 17:13:51','YYYY-MM-DD HH24:MI:SS'),'Y','N',0,1,'N',0,1,1,'N','N',208373,'D',TO_DATE('2014-06-03 17:13:51','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:53 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,22,'N','N',10,'Y',203052,'Y','A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.','Client/Tenant for this installation.','Client','7bdd6c94-f7dd-4a1d-8188-bd56e3ffe0a6','Y','N',100,0,100,TO_DATE('2014-06-03 17:13:52','YYYY-MM-DD HH24:MI:SS'),'Y','Y',10,1,'N',0,2,1,'N','N',208367,'D',TO_DATE('2014-06-03 17:13:52','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:54 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,IsAllowCopy,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,22,'N','N',20,'Y',203053,'N','An organization is a unit of your client or legal entity - examples are store, department. You can share data between organizations.','Organizational entity within client','Organization','7f47d673-3e32-4b73-bbeb-9409fd67b5ee','Y','N','Y',100,0,100,TO_DATE('2014-06-03 17:13:53','YYYY-MM-DD HH24:MI:SS'),'Y','Y',20,4,'N',0,2,1,'N','N',208368,'D',TO_DATE('2014-06-03 17:13:53','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:55 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,10,'N','N',30,'Y',203054,'N','The Role determines security and access a user who has this Role will have in the System.','Responsibility Role','Role','71b84a87-093a-483e-ae29-19bf3b29f107','Y','N',100,0,100,TO_DATE('2014-06-03 17:13:54','YYYY-MM-DD HH24:MI:SS'),'Y','Y',30,1,'N',0,2,1,'N','N',208376,'D',TO_DATE('2014-06-03 17:13:54','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:56 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,10,'N','N',40,'Y',203055,'N','The Info window is used to search and select records as well as display information relevant to the selection.','Info and search/select Window','Info Window','a1d6782a-7f0e-4261-b018-83bb3299c382','Y','N',100,0,100,TO_DATE('2014-06-03 17:13:55','YYYY-MM-DD HH24:MI:SS'),'Y','Y',40,1,'N',0,2,1,'N','N',208377,'D',TO_DATE('2014-06-03 17:13:55','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:57 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,1,'N','N',50,'Y',203056,'N','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports. +There are two reasons for de-activating and not deleting records: +(1) The system requires the record for audit purposes. +(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.','The record is active in the system','Active','2fde0d03-3be0-4df2-bd56-56efd4d40008','Y','N',100,0,100,TO_DATE('2014-06-03 17:13:56','YYYY-MM-DD HH24:MI:SS'),'Y','Y',50,2,'N',0,1,1,'N','N',208371,'D',TO_DATE('2014-06-03 17:13:56','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:14:23 PM ICT +UPDATE AD_Field SET SeqNo=40, IsDisplayed='Y', XPosition=4,Updated=TO_DATE('2014-06-03 17:14:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:16:04 PM ICT +UPDATE AD_Field SET IsReadOnly='Y', DisplayLogic='@AD_InfoWindow_ID@',Updated=TO_DATE('2014-06-03 17:16:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:17:05 PM ICT +UPDATE AD_Field SET DisplayLogic=NULL, DefaultValue='@AD_InfoWindow_ID@',Updated=TO_DATE('2014-06-03 17:17:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:21:06 PM ICT +UPDATE AD_Tab SET TabLevel=1,Updated=TO_DATE('2014-06-03 17:21:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200144 +; + +-- Jun 3, 2014 5:25:34 PM ICT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_DATE('2014-06-03 17:25:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201645 +; + +-- Jun 3, 2014 5:26:17 PM ICT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_DATE('2014-06-03 17:26:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203053 +; + +SELECT register_migration_script('201406031605_IDEMPIERE-1968-Access.sql') FROM dual +; diff --git a/migration/i2.0z/oracle/201406061832_IDEMPIERE-1856.sql b/migration/i2.0z/oracle/201406061832_IDEMPIERE-1856.sql new file mode 100644 index 0000000000..f18c35efb2 --- /dev/null +++ b/migration/i2.0z/oracle/201406061832_IDEMPIERE-1856.sql @@ -0,0 +1,100 @@ +-- June 6, 2014 18:32:00 PM SGT +-- IDEMPIERE-1856 Amount in database functions and views are hardcoded to round to 2 decimal points + +CREATE OR REPLACE FUNCTION paymentTermDiscount +( + Amount IN NUMBER, + Currency_ID IN NUMBER, + PaymentTerm_ID IN NUMBER, + DocDate IN DATE, + PayDate IN DATE +) +RETURN NUMBER +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2001 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: C_PaymentTerm_Discount.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Calculate Discount + * Description: + * Calculate the allowable Discount Amount of the Payment Term + * + * Test: SELECT C_PaymentTerm_Discount(17777, 103, '10-DEC-1999') FROM DUAL + ************************************************************************/ + +AS + v_Precision NUMBER := 0; + v_Currency NUMBER := 0; + v_Min NUMBER := 0; + Discount NUMBER := 0; + CURSOR Cur_PT IS + SELECT * + FROM C_PaymentTerm + WHERE C_PaymentTerm_ID = PaymentTerm_ID; + Discount1Date DATE; + Discount2Date DATE; + Add1Date NUMBER := 0; + Add2Date NUMBER := 0; +BEGIN + v_Currency := Currency_ID; + IF (v_Currency = 0) THEN + SELECT COALESCE(MAX(C_Currency_ID),0) + INTO v_Currency + FROM AD_ClientInfo ci, C_AcctSchema s, C_PaymentTerm pt + WHERE ci.AD_Client_ID = s.AD_Client_ID + AND ci.AD_Client_ID = pt.AD_Client_ID + AND pt.C_PaymentTerm_ID = PaymentTerm_ID; + END IF; + + SELECT StdPrecision + INTO v_Precision + FROM C_Currency + WHERE C_Currency_ID = v_Currency; + + SELECT POWER(1/10,v_Precision) INTO v_Min FROM DUAL; + + -- No Data - No Discount + IF (Amount IS NULL OR PaymentTerm_ID IS NULL OR DocDate IS NULL) THEN + RETURN 0; + END IF; + + FOR p IN Cur_PT LOOP -- for convineance only +-- DBMS_OUTPUT.PUT_LINE(p.Name || ' - Doc = ' || TO_CHAR(DocDate)); + Discount1Date := TRUNC(DocDate + p.DiscountDays + p.GraceDays); + Discount2Date := TRUNC(DocDate + p.DiscountDays2 + p.GraceDays); + + -- Next Business Day + IF (p.IsNextBusinessDay='Y') THEN + Discount1Date := nextBusinessDay(Discount1Date, p.AD_Client_ID); + Discount2Date := nextBusinessDay(Discount2Date, p.AD_Client_ID); + END IF; + + -- Discount 1 + IF (Discount1Date >= TRUNC(PayDate)) THEN +-- DBMS_OUTPUT.PUT_LINE('Discount 1 ' || TO_CHAR(Discount1Date) || ' ' || p.Discount); + Discount := Amount * p.Discount / 100; + -- Discount 2 + ELSIF (Discount2Date >= TRUNC(PayDate)) THEN +-- DBMS_OUTPUT.PUT_LINE('Discount 2 ' || TO_CHAR(Discount2Date) || ' ' || p.Discount2); + Discount := Amount * p.Discount2 / 100; + END IF; + END LOOP; + + -- Ignore Rounding + IF (Discount > -v_Min AND Discount < v_Min) THEN + Discount := 0; + END IF; + + -- Round to currency precision + Discount := ROUND(COALESCE(Discount,0), v_Precision); + + RETURN Discount; +END paymentTermDiscount; +/ + +SELECT register_migration_script('201406061832_IDEMPIERE-1856.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/oracle/201406261439_IDEMPIERE-2023.sql b/migration/i2.0z/oracle/201406261439_IDEMPIERE-2023.sql new file mode 100644 index 0000000000..e58c5b55ad --- /dev/null +++ b/migration/i2.0z/oracle/201406261439_IDEMPIERE-2023.sql @@ -0,0 +1,14 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jun 26, 2014 1:04:37 PM SGT +-- IDEMPIERE-2023 Scheduler Recipient record has incorrect defaults +UPDATE AD_Column SET DefaultValue='-1',Updated=TO_DATE('2014-06-26 13:04:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=11504 +; + +-- Jun 26, 2014 1:04:54 PM SGT +UPDATE AD_Column SET DefaultValue='-1',Updated=TO_DATE('2014-06-26 13:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=11512 +; + +SELECT register_migration_script('201406261439_IDEMPIERE-2023.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/oracle/201407011455_IDEMPIERE-2029.sql b/migration/i2.0z/oracle/201407011455_IDEMPIERE-2029.sql new file mode 100644 index 0000000000..4aef955950 --- /dev/null +++ b/migration/i2.0z/oracle/201407011455_IDEMPIERE-2029.sql @@ -0,0 +1,10 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jul 1, 2014 2:53:42 PM SGT +-- IDEMPIERE-2029 Performance gadgets portlet is not sized correctly on login +INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200057,'C','500','70b3fe79-cbe4-40d5-89b4-a4c5c9c5a845',TO_DATE('2014-07-01 14:53:41','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-07-01 14:53:41','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'ZK_DASHBOARD_PERFORMANCE_TIMEOUT',0,'D') +; + +SELECT register_migration_script('201407011455_IDEMPIERE-2029.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/oracle/201407021018_1003719.sql b/migration/i2.0z/oracle/201407021018_1003719.sql new file mode 100644 index 0000000000..187cac48b1 --- /dev/null +++ b/migration/i2.0z/oracle/201407021018_1003719.sql @@ -0,0 +1,43 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Jul 1, 2014 3:44:10 PM MYT +-- 1003719 Modify "Update Costing" process to create a cost adjustment document +UPDATE AD_Process_Para SET SeqNo=120,Updated=TO_DATE('2014-07-01 15:44:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53378 +; + +-- Jul 1, 2014 3:46:18 PM MYT +INSERT INTO AD_Process_Para (AD_Process_Para_ID,IsRange,AD_Process_Para_UU,AD_Process_ID,AD_Reference_ID,AD_Val_Rule_ID,IsMandatory,DisplayLogic,EntityType,Name,ColumnName,FieldLength,IsCentrallyMaintained,SeqNo,IsActive,UpdatedBy,Updated,CreatedBy,AD_Org_ID,IsEncrypted,AD_Client_ID,Created) VALUES (200102,'N','8e8036a8-ae8d-4470-a607-9cd048741419',219,19,200050,'N','@IsUpdateCosting@=''Y''','D','Cost Adjustment Document Type','C_DocType_ID',10,'N',110,'Y',100,TO_DATE('2014-07-01 15:46:18','YYYY-MM-DD HH24:MI:SS'),100,0,'N',0,TO_DATE('2014-07-01 15:46:18','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:51:17 PM MYT +INSERT INTO AD_Element (ColumnName,AD_Element_ID,Help,Name,Description,PrintName,AD_Element_UU,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType,Created) VALUES ('M_CostingLine_ID',202750,'The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Cost Adjustment Line','Unique line in an Inventory cost adjustment document','Cost Adjustment Line','e60cd491-bd9f-4f5f-b031-7401461264c1',TO_DATE('2014-07-01 15:51:16','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D',TO_DATE('2014-07-01 15:51:16','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:53:05 PM MYT +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,CreatedBy,Updated,IsActive,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Org_ID,Created) VALUES (0,'N',0,211562,'N','N','N',0,'N',10,'N','N','N','Y','044a1793-a72b-49a0-aa64-f1b99565a884','Y','M_CostingLine_ID','Unique line in an Inventory cost adjustment document','The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Cost Adjustment Line','N',100,TO_DATE('2014-07-01 15:53:04','YYYY-MM-DD HH24:MI:SS'),'Y',100,'N','N',0,'D','N','N','N',202750,30,296,572,0,TO_DATE('2014-07-01 15:53:04','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:53:13 PM MYT +UPDATE AD_Column SET FKConstraintType='N', FKConstraintName='MCostingLine_IInventory',Updated=TO_DATE('2014-07-01 15:53:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211562 +; + +-- Jul 1, 2014 3:53:13 PM MYT +ALTER TABLE I_Inventory ADD M_CostingLine_ID NUMBER(10) DEFAULT NULL +; + +-- Jul 1, 2014 3:53:15 PM MYT +ALTER TABLE I_Inventory ADD CONSTRAINT MCostingLine_IInventory FOREIGN KEY (M_CostingLine_ID) REFERENCES m_inventoryline(m_inventoryline_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jul 1, 2014 3:54:41 PM MYT +UPDATE AD_Field SET SeqNo=300, SeqNoGrid=300,Updated=TO_DATE('2014-07-01 15:54:41','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=6697 +; + +-- Jul 1, 2014 3:56:40 PM MYT +INSERT INTO AD_Field (SortNo,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,AD_Tab_ID,EntityType,Created) VALUES (0,'N',0,'N','N',290,'Y',203261,'N','The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Unique line in an Inventory cost adjustment document','Cost Adjustment Line','c8667068-b4f9-43dd-a80d-2b910584a565','Y','N',100,0,100,TO_DATE('2014-07-01 15:56:39','YYYY-MM-DD HH24:MI:SS'),'Y','Y',290,1,'N',0,2,1,'N','N',211562,481,'D',TO_DATE('2014-07-01 15:56:39','YYYY-MM-DD HH24:MI:SS')) +; + +SELECT register_migration_script('201407021018_1003719.sql') FROM dual +; + diff --git a/migration/i2.0z/oracle/201407151334_IDEMPIERE-1998.sql b/migration/i2.0z/oracle/201407151334_IDEMPIERE-1998.sql new file mode 100644 index 0000000000..dbc4959e71 --- /dev/null +++ b/migration/i2.0z/oracle/201407151334_IDEMPIERE-1998.sql @@ -0,0 +1,27 @@ +-- IDEMPIERE-1998 for backward compatibility insert the creator as scheduler recipient +insert +into ad_schedulerrecipient + ( + ad_schedulerrecipient_id, + ad_client_id, + ad_org_id, + isactive, + created, + createdby, + updated, + updatedby, + ad_scheduler_id, + ad_user_id, + ad_role_id, + ad_schedulerrecipient_uu + ) +select nextidfunc(921,'N'), s.ad_client_id, s.ad_org_id, s.isactive, sysdate, 100, sysdate, 100, s.ad_scheduler_id, s.createdby, null, generate_uuid() +from ad_scheduler s +where not exists ( select 1 + from ad_schedulerrecipient sr + where s.ad_scheduler_id=sr.ad_scheduler_id) +; + +SELECT register_migration_script('201407151334_IDEMPIERE-1998.sql') FROM dual +; + diff --git a/migration/i2.0z/postgresql/201406031604_IDEMPIERE-1968.sql b/migration/i2.0z/postgresql/201406031604_IDEMPIERE-1968.sql new file mode 100644 index 0000000000..4f7ece05a0 --- /dev/null +++ b/migration/i2.0z/postgresql/201406031604_IDEMPIERE-1968.sql @@ -0,0 +1,7 @@ +-- Jun 3, 2014 4:22:36 PM ICT +-- IDEMPIERE-1968 valid check box in info window can manual editable +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_TIMESTAMP('2014-06-03 16:22:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201639 +; + +SELECT register_migration_script('201406031604_IDEMPIERE-1968.sql') FROM dual +; diff --git a/migration/i2.0z/postgresql/201406031605_IDEMPIERE-1968-Access.sql b/migration/i2.0z/postgresql/201406031605_IDEMPIERE-1968-Access.sql new file mode 100644 index 0000000000..e62a009052 --- /dev/null +++ b/migration/i2.0z/postgresql/201406031605_IDEMPIERE-1968-Access.sql @@ -0,0 +1,70 @@ +-- Jun 3, 2014 5:05:09 PM ICT +-- IDEMPIERE-1968 valid check box in info window can manual editable +UPDATE AD_Column SET IsUpdateable='N', FKConstraintType='C',Updated=TO_TIMESTAMP('2014-06-03 17:05:09','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=208377 +; + +-- Jun 3, 2014 5:05:16 PM ICT +ALTER TABLE AD_InfoWindow_Access DROP CONSTRAINT adinfowindow_adinfowindowacces +; + +-- Jun 3, 2014 5:05:16 PM ICT +ALTER TABLE AD_InfoWindow_Access ADD CONSTRAINT adinfowindow_adinfowindowacces FOREIGN KEY (AD_InfoWindow_ID) REFERENCES ad_infowindow(ad_infowindow_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED +; + +-- Jun 3, 2014 5:13:25 PM ICT +INSERT INTO AD_Tab (ImportFields,Processing,IsSingleRow,AD_Window_ID,SeqNo,IsTranslationTab,IsSortTab,HasTree,IsInfoTab,IsReadOnly,IsInsertRecord,IsAdvancedTab,TabLevel,AD_Tab_UU,EntityType,Name,AD_Tab_ID,AD_Org_ID,Created,CreatedBy,Updated,UpdatedBy,IsActive,AD_Column_ID,AD_Table_ID,AD_Client_ID,TreeDisplayedOn) VALUES ('N','N','Y',385,70,'N','N','N','N','N','Y','N',0,'d7868d02-46bc-4112-af34-35df9e13a79f','D','Role Access',200144,0,TO_TIMESTAMP('2014-06-03 17:13:24','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-06-03 17:13:24','YYYY-MM-DD HH24:MI:SS'),100,'Y',208377,200054,0,'B') +; + +-- Jun 3, 2014 5:13:52 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,36,'N','N',0,'Y',203051,'N','AD_InfoWindow_Access_UU','ff201a9f-6ce6-4554-8fbf-111507465b96','N','N',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:51','YYYY-MM-DD HH24:MI:SS'),'Y','N',0,1,'N',0,1,1,'N','N',208373,'D',TO_TIMESTAMP('2014-06-03 17:13:51','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:53 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,22,'N','N',10,'Y',203052,'Y','A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.','Client/Tenant for this installation.','Client','7bdd6c94-f7dd-4a1d-8188-bd56e3ffe0a6','Y','N',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:52','YYYY-MM-DD HH24:MI:SS'),'Y','Y',10,1,'N',0,2,1,'N','N',208367,'D',TO_TIMESTAMP('2014-06-03 17:13:52','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:54 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,IsAllowCopy,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,22,'N','N',20,'Y',203053,'N','An organization is a unit of your client or legal entity - examples are store, department. You can share data between organizations.','Organizational entity within client','Organization','7f47d673-3e32-4b73-bbeb-9409fd67b5ee','Y','N','Y',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:53','YYYY-MM-DD HH24:MI:SS'),'Y','Y',20,4,'N',0,2,1,'N','N',208368,'D',TO_TIMESTAMP('2014-06-03 17:13:53','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:55 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,10,'N','N',30,'Y',203054,'N','The Role determines security and access a user who has this Role will have in the System.','Responsibility Role','Role','71b84a87-093a-483e-ae29-19bf3b29f107','Y','N',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:54','YYYY-MM-DD HH24:MI:SS'),'Y','Y',30,1,'N',0,2,1,'N','N',208376,'D',TO_TIMESTAMP('2014-06-03 17:13:54','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:56 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,10,'N','N',40,'Y',203055,'N','The Info window is used to search and select records as well as display information relevant to the selection.','Info and search/select Window','Info Window','a1d6782a-7f0e-4261-b018-83bb3299c382','Y','N',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:55','YYYY-MM-DD HH24:MI:SS'),'Y','Y',40,1,'N',0,2,1,'N','N',208377,'D',TO_TIMESTAMP('2014-06-03 17:13:55','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:13:57 PM ICT +INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,Created) VALUES ('N',200144,1,'N','N',50,'Y',203056,'N','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports. +There are two reasons for de-activating and not deleting records: +(1) The system requires the record for audit purposes. +(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.','The record is active in the system','Active','2fde0d03-3be0-4df2-bd56-56efd4d40008','Y','N',100,0,100,TO_TIMESTAMP('2014-06-03 17:13:56','YYYY-MM-DD HH24:MI:SS'),'Y','Y',50,2,'N',0,1,1,'N','N',208371,'D',TO_TIMESTAMP('2014-06-03 17:13:56','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jun 3, 2014 5:14:23 PM ICT +UPDATE AD_Field SET SeqNo=40, IsDisplayed='Y', XPosition=4,Updated=TO_TIMESTAMP('2014-06-03 17:14:23','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:16:04 PM ICT +UPDATE AD_Field SET IsReadOnly='Y', DisplayLogic='@AD_InfoWindow_ID@',Updated=TO_TIMESTAMP('2014-06-03 17:16:04','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:17:05 PM ICT +UPDATE AD_Field SET DisplayLogic=NULL, DefaultValue='@AD_InfoWindow_ID@',Updated=TO_TIMESTAMP('2014-06-03 17:17:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203055 +; + +-- Jun 3, 2014 5:21:06 PM ICT +UPDATE AD_Tab SET TabLevel=1,Updated=TO_TIMESTAMP('2014-06-03 17:21:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200144 +; + +-- Jun 3, 2014 5:25:34 PM ICT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_TIMESTAMP('2014-06-03 17:25:34','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=201645 +; + +-- Jun 3, 2014 5:26:17 PM ICT +UPDATE AD_Field SET IsReadOnly='Y',Updated=TO_TIMESTAMP('2014-06-03 17:26:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=203053 +; + +SELECT register_migration_script('201406031605_IDEMPIERE-1968-Access.sql') FROM dual +; diff --git a/migration/i2.0z/postgresql/201406061832_IDEMPIERE-1856.sql b/migration/i2.0z/postgresql/201406061832_IDEMPIERE-1856.sql new file mode 100644 index 0000000000..806795278d --- /dev/null +++ b/migration/i2.0z/postgresql/201406061832_IDEMPIERE-1856.sql @@ -0,0 +1,100 @@ +-- June 6, 2014 18:32:00 PM SGT +-- IDEMPIERE-1856 Amount in database functions and views are hardcoded to round to 2 decimal points + +create or replace FUNCTION paymenttermDiscount +( + Amount NUMERIC, + Currency_ID NUMERIC, + PaymentTerm_ID NUMERIC, + DocDate timestamp with time zone, + PayDate timestamp with time zone +) +RETURNS NUMERIC AS $body$ +/************************************************************************* + * The contents of this file are subject to the Compiere License. You may + * obtain a copy of the License at http://www.compiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Compiere ERP+CRM + * Copyright (C) 1999-2001 Jorg Janke, ComPiere, Inc. All Rights Reserved. + * + * converted to postgreSQL by Karsten Thiemann (Schaeffer AG), + * kthiemann@adempiere.org + ************************************************************************* + * Title: Calculate Discount + * Description: + * Calculate the allowable Discount Amount of the Payment Term + * + * Test: SELECT paymenttermDiscount(110, 103, 106, now(), now()) FROM TEST; => 2.20 + ************************************************************************/ + +DECLARE + v_Precision NUMERIC := 0; + v_Currency NUMERIC := 0; + v_Min NUMERIC := 0; + Discount NUMERIC := 0; + Discount1Date timestamp with time zone; + Discount2Date timestamp with time zone; + Add1Date NUMERIC := 0; + Add2Date NUMERIC := 0; + p RECORD; +BEGIN + v_Currency := Currency_ID; + IF (v_Currency = 0) THEN + SELECT COALESCE(MAX(C_Currency_ID),0) + INTO v_Currency + FROM AD_ClientInfo ci, C_AcctSchema s, C_PaymentTerm pt + WHERE ci.AD_Client_ID = s.AD_Client_ID + AND ci.AD_Client_ID = pt.AD_Client_ID + AND pt.C_PaymentTerm_ID = PaymentTerm_ID; + END IF; + + SELECT StdPrecision + INTO v_Precision + FROM C_Currency + WHERE C_Currency_ID = v_Currency; + + SELECT 1/10^v_Precision INTO v_Min; + + -- No Data - No Discount + IF (Amount IS NULL OR PaymentTerm_ID IS NULL OR DocDate IS NULL) THEN + RETURN 0; + END IF; + + FOR p IN + SELECT * + FROM C_PaymentTerm + WHERE C_PaymentTerm_ID = PaymentTerm_ID + LOOP -- for convineance only + Discount1Date := TRUNC(DocDate + p.DiscountDays + p.GraceDays); + Discount2Date := TRUNC(DocDate + p.DiscountDays2 + p.GraceDays); + + -- Next Business Day + IF (p.IsNextBusinessDay='Y') THEN + Discount1Date := nextBusinessDay(Discount1Date, p.AD_Client_ID); + Discount2Date := nextBusinessDay(Discount2Date, p.AD_Client_ID); + END IF; + + -- Discount 1 + IF (Discount1Date >= TRUNC(PayDate)) THEN + Discount := Amount * p.Discount / 100; + -- Discount 2 + ELSIF (Discount2Date >= TRUNC(PayDate)) THEN + Discount := Amount * p.Discount2 / 100; + END IF; + END LOOP; + + -- Ignore Rounding + IF (Discount > -v_Min AND Discount < v_Min) THEN + Discount := 0; + END IF; + + -- Round to currency precision + Discount := ROUND(COALESCE(Discount,0), v_Precision); + + RETURN Discount; +END; + +$body$ LANGUAGE plpgsql; + +SELECT register_migration_script('201406061832_IDEMPIERE-1856.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/postgresql/201406261439_IDEMPIERE-2023.sql b/migration/i2.0z/postgresql/201406261439_IDEMPIERE-2023.sql new file mode 100644 index 0000000000..47cde8cb53 --- /dev/null +++ b/migration/i2.0z/postgresql/201406261439_IDEMPIERE-2023.sql @@ -0,0 +1,11 @@ +-- Jun 26, 2014 1:04:37 PM SGT +-- IDEMPIERE-2023 Scheduler Recipient record has incorrect defaults +UPDATE AD_Column SET DefaultValue='-1',Updated=TO_TIMESTAMP('2014-06-26 13:04:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=11504 +; + +-- Jun 26, 2014 1:04:54 PM SGT +UPDATE AD_Column SET DefaultValue='-1',Updated=TO_TIMESTAMP('2014-06-26 13:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=11512 +; + +SELECT register_migration_script('201406261439_IDEMPIERE-2023.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/postgresql/201407011455_IDEMPIERE-2029.sql b/migration/i2.0z/postgresql/201407011455_IDEMPIERE-2029.sql new file mode 100644 index 0000000000..3279c0b2b8 --- /dev/null +++ b/migration/i2.0z/postgresql/201407011455_IDEMPIERE-2029.sql @@ -0,0 +1,7 @@ +-- Jul 1, 2014 2:53:42 PM SGT +-- IDEMPIERE-2029 Performance gadgets portlet is not sized correctly on login +INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200057,'C','500','70b3fe79-cbe4-40d5-89b4-a4c5c9c5a845',TO_TIMESTAMP('2014-07-01 14:53:41','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-07-01 14:53:41','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'ZK_DASHBOARD_PERFORMANCE_TIMEOUT',0,'D') +; + +SELECT register_migration_script('201407011455_IDEMPIERE-2029.sql') FROM dual +; \ No newline at end of file diff --git a/migration/i2.0z/postgresql/201407021018_1003719.sql b/migration/i2.0z/postgresql/201407021018_1003719.sql new file mode 100644 index 0000000000..6a68f7b73e --- /dev/null +++ b/migration/i2.0z/postgresql/201407021018_1003719.sql @@ -0,0 +1,40 @@ +-- Jul 1, 2014 3:44:10 PM MYT +-- 1003719 Modify "Update Costing" process to create a cost adjustment document +UPDATE AD_Process_Para SET SeqNo=120,Updated=TO_TIMESTAMP('2014-07-01 15:44:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=53378 +; + +-- Jul 1, 2014 3:46:18 PM MYT +INSERT INTO AD_Process_Para (AD_Process_Para_ID,IsRange,AD_Process_Para_UU,AD_Process_ID,AD_Reference_ID,AD_Val_Rule_ID,IsMandatory,DisplayLogic,EntityType,Name,ColumnName,FieldLength,IsCentrallyMaintained,SeqNo,IsActive,UpdatedBy,Updated,CreatedBy,AD_Org_ID,IsEncrypted,AD_Client_ID,Created) VALUES (200102,'N','8e8036a8-ae8d-4470-a607-9cd048741419',219,19,200050,'N','@IsUpdateCosting@=''Y''','D','Cost Adjustment Document Type','C_DocType_ID',10,'N',110,'Y',100,TO_TIMESTAMP('2014-07-01 15:46:18','YYYY-MM-DD HH24:MI:SS'),100,0,'N',0,TO_TIMESTAMP('2014-07-01 15:46:18','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:51:17 PM MYT +INSERT INTO AD_Element (ColumnName,AD_Element_ID,Help,Name,Description,PrintName,AD_Element_UU,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType,Created) VALUES ('M_CostingLine_ID',202750,'The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Cost Adjustment Line','Unique line in an Inventory cost adjustment document','Cost Adjustment Line','e60cd491-bd9f-4f5f-b031-7401461264c1',TO_TIMESTAMP('2014-07-01 15:51:16','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D',TO_TIMESTAMP('2014-07-01 15:51:16','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:53:05 PM MYT +INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,CreatedBy,Updated,IsActive,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Org_ID,Created) VALUES (0,'N',0,211562,'N','N','N',0,'N',10,'N','N','N','Y','044a1793-a72b-49a0-aa64-f1b99565a884','Y','M_CostingLine_ID','Unique line in an Inventory cost adjustment document','The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Cost Adjustment Line','N',100,TO_TIMESTAMP('2014-07-01 15:53:04','YYYY-MM-DD HH24:MI:SS'),'Y',100,'N','N',0,'D','N','N','N',202750,30,296,572,0,TO_TIMESTAMP('2014-07-01 15:53:04','YYYY-MM-DD HH24:MI:SS')) +; + +-- Jul 1, 2014 3:53:13 PM MYT +UPDATE AD_Column SET FKConstraintType='N', FKConstraintName='MCostingLine_IInventory',Updated=TO_TIMESTAMP('2014-07-01 15:53:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211562 +; + +-- Jul 1, 2014 3:53:13 PM MYT +ALTER TABLE I_Inventory ADD COLUMN M_CostingLine_ID NUMERIC(10) DEFAULT NULL +; + +-- Jul 1, 2014 3:53:15 PM MYT +ALTER TABLE I_Inventory ADD CONSTRAINT MCostingLine_IInventory FOREIGN KEY (M_CostingLine_ID) REFERENCES m_inventoryline(m_inventoryline_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Jul 1, 2014 3:54:41 PM MYT +UPDATE AD_Field SET SeqNo=300, SeqNoGrid=300,Updated=TO_TIMESTAMP('2014-07-01 15:54:41','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=6697 +; + +-- Jul 1, 2014 3:56:40 PM MYT +INSERT INTO AD_Field (SortNo,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,CreatedBy,Updated,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,AD_Tab_ID,EntityType,Created) VALUES (0,'N',0,'N','N',290,'Y',203261,'N','The Cost Adjustment Line indicates the inventory cost adjustment document line (if applicable) for this transaction','Unique line in an Inventory cost adjustment document','Cost Adjustment Line','c8667068-b4f9-43dd-a80d-2b910584a565','Y','N',100,0,100,TO_TIMESTAMP('2014-07-01 15:56:39','YYYY-MM-DD HH24:MI:SS'),'Y','Y',290,1,'N',0,2,1,'N','N',211562,481,'D',TO_TIMESTAMP('2014-07-01 15:56:39','YYYY-MM-DD HH24:MI:SS')) +; + +SELECT register_migration_script('201407021018_1003719.sql') FROM dual +; + diff --git a/migration/i2.0z/postgresql/201407151334_IDEMPIERE-1998.sql b/migration/i2.0z/postgresql/201407151334_IDEMPIERE-1998.sql new file mode 100644 index 0000000000..85c51bb958 --- /dev/null +++ b/migration/i2.0z/postgresql/201407151334_IDEMPIERE-1998.sql @@ -0,0 +1,27 @@ +-- IDEMPIERE-1998 for backward compatibility insert the creator as scheduler recipient +insert +into ad_schedulerrecipient + ( + ad_schedulerrecipient_id, + ad_client_id, + ad_org_id, + isactive, + created, + createdby, + updated, + updatedby, + ad_scheduler_id, + ad_user_id, + ad_role_id, + ad_schedulerrecipient_uu + ) +select nextidfunc(921,'N'), s.ad_client_id, s.ad_org_id, s.isactive, statement_timestamp(), 100, statement_timestamp(), 100, s.ad_scheduler_id, s.createdby, null, generate_uuid() +from ad_scheduler s +where not exists ( select 1 + from ad_schedulerrecipient sr + where s.ad_scheduler_id=sr.ad_scheduler_id) +; + +SELECT register_migration_script('201407151334_IDEMPIERE-1998.sql') FROM dual +; + diff --git a/org.adempiere.base.process/src/org/compiere/process/ImportInventory.java b/org.adempiere.base.process/src/org/compiere/process/ImportInventory.java index 29bf96806b..7b599f9147 100644 --- a/org.adempiere.base.process/src/org/compiere/process/ImportInventory.java +++ b/org.adempiere.base.process/src/org/compiere/process/ImportInventory.java @@ -23,6 +23,7 @@ import java.sql.Timestamp; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.compiere.model.I_C_DocType; import org.compiere.model.MAcctSchema; import org.compiere.model.MAttributeSet; import org.compiere.model.MAttributeSetInstance; @@ -31,9 +32,13 @@ import org.compiere.model.MInventory; import org.compiere.model.MInventoryLine; import org.compiere.model.MProduct; import org.compiere.model.MProductCategoryAcct; +import org.compiere.model.PO; import org.compiere.model.X_I_Inventory; +import org.compiere.util.AdempiereUserError; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; import org.compiere.util.TimeUtil; import org.compiere.util.ValueNamePair; @@ -73,7 +78,9 @@ public class ImportInventory extends SvrProcess private int p_AD_OrgTrx_ID = 0; /** Document Action */ private String m_docAction = null; + private MInventory costingDoc = null; + private int p_C_DocType_ID = 0; /** * Prepare - e.g., get Parameters. */ @@ -107,8 +114,10 @@ public class ImportInventory extends SvrProcess p_AD_OrgTrx_ID = ((BigDecimal)para[i].getParameter()).intValue(); else if (name.equals("DocAction")) m_docAction = (String)para[i].getParameter(); + else if (name.equals("C_DocType_ID")) + p_C_DocType_ID = ((BigDecimal)para[i].getParameter()).intValue(); else - log.log(Level.SEVERE, "Unknown Parameter: " + name); + log.log(Level.WARNING, "Unknown Parameter: " + name); } } // prepare @@ -135,6 +144,9 @@ public class ImportInventory extends SvrProcess } if (p_AD_OrgTrx_ID < 0 ) { throw new IllegalArgumentException("AD_OrgTrx required!"); + } + if (p_C_DocType_ID <= 0 ) { + throw new IllegalArgumentException("Cost Adjustment Document Type required!"); } acctSchema = MAcctSchema.get(getCtx(), p_C_AcctSchema_ID, get_TrxName()); } @@ -426,28 +438,7 @@ public class ImportInventory extends SvrProcess noInsertLine++; //@Trifon update Product cost record if Update costing is enabled if (p_UpdateCosting) { - String costingLevel = null; - if(product.getM_Product_Category_ID() > 0){ - MProductCategoryAcct pca = MProductCategoryAcct.get(getCtx(), product.getM_Product_Category_ID(), p_C_AcctSchema_ID, get_TrxName()); - costingLevel = pca.getCostingLevel(); - if (costingLevel == null) { - costingLevel = acctSchema.getCostingLevel(); - } - - } - - int costOrgID = p_AD_OrgTrx_ID; - int costASI = line.getM_AttributeSetInstance_ID(); - if (MAcctSchema.COSTINGLEVEL_Client.equals(costingLevel)){ - costOrgID = 0; - costASI = 0; - } else if (MAcctSchema.COSTINGLEVEL_Organization.equals(costingLevel)) { - costASI = 0; - } - MCost cost = MCost.get (MProduct.get(getCtx(), imp.getM_Product_ID()), costASI - , acctSchema, costOrgID, p_M_CostElement_ID, get_TrxName()); - cost.setCurrentCostPrice( imp.getCurrentCostPrice() ); - cost.saveEx(); + updateCosting(imp, product, line); } } } else { @@ -470,6 +461,21 @@ public class ImportInventory extends SvrProcess inventory.saveEx(); } } + + if (costingDoc != null) { + if (!DocumentEngine.processIt(costingDoc, DocAction.ACTION_Complete)) + { + StringBuilder msg = new StringBuilder(); + I_C_DocType docType = costingDoc.getC_DocType(); + msg.append(Msg.getMsg(getCtx(), "ProcessFailed")).append(": "); + if (Env.isBaseLanguage(getCtx(), I_C_DocType.Table_Name)) + msg.append(docType.getName()); + else + msg.append(((PO)docType).get_Translation(I_C_DocType.COLUMNNAME_Name)); + throw new AdempiereUserError(msg.toString()); + } + costingDoc.saveEx(); + } } catch (Exception e) { @@ -493,4 +499,48 @@ public class ImportInventory extends SvrProcess return ""; } // doIt + + private void updateCosting(X_I_Inventory imp, MProduct product, + MInventoryLine line) { + String costingLevel = null; + if(product.getM_Product_Category_ID() > 0){ + MProductCategoryAcct pca = MProductCategoryAcct.get(getCtx(), product.getM_Product_Category_ID(), p_C_AcctSchema_ID, get_TrxName()); + costingLevel = pca.getCostingLevel(); + if (costingLevel == null) { + costingLevel = acctSchema.getCostingLevel(); + } + + } + + int costOrgID = p_AD_OrgTrx_ID; + int costASI = line.getM_AttributeSetInstance_ID(); + if (MAcctSchema.COSTINGLEVEL_Client.equals(costingLevel)){ + costOrgID = 0; + costASI = 0; + } else if (MAcctSchema.COSTINGLEVEL_Organization.equals(costingLevel)) { + costASI = 0; + } + MCost cost = MCost.get (MProduct.get(getCtx(), imp.getM_Product_ID()), costASI + , acctSchema, costOrgID, p_M_CostElement_ID, get_TrxName()); + + if (costingDoc == null) { + costingDoc = new MInventory(getCtx(), 0, get_TrxName()); + costingDoc.setC_DocType_ID(p_C_DocType_ID); + costingDoc.setCostingMethod(cost.getM_CostElement().getCostingMethod()); + costingDoc.setDocAction(DocAction.ACTION_Complete); + costingDoc.saveEx(); + } + + MInventoryLine costingLine = new MInventoryLine(getCtx(), 0, get_TrxName()); + costingLine.setM_Inventory_ID(costingDoc.getM_Inventory_ID()); + costingLine.setM_Product_ID(cost.getM_Product_ID()); + costingLine.setCurrentCostPrice(cost.getCurrentCostPrice()); + costingLine.setNewCostPrice(imp.getCurrentCostPrice()); + costingLine.setM_Locator_ID(0); + costingLine.saveEx(); + + imp.setM_CostingLine_ID(costingLine.getM_InventoryLine_ID()); + imp.saveEx(); + } + } // ImportInventory diff --git a/org.adempiere.base.process/src/org/compiere/process/InOutGenerate.java b/org.adempiere.base.process/src/org/compiere/process/InOutGenerate.java index 46e941005c..3e3c1d4d42 100644 --- a/org.adempiere.base.process/src/org/compiere/process/InOutGenerate.java +++ b/org.adempiere.base.process/src/org/compiere/process/InOutGenerate.java @@ -525,6 +525,10 @@ public class InOutGenerate extends SvrProcess MInOutLine line = new MInOutLine (m_shipment); line.setOrderLine(orderLine, 0, order.isSOTrx() ? toDeliver : Env.ZERO); line.setQty(toDeliver); + if (orderLine.getQtyEntered().compareTo(orderLine.getQtyOrdered()) != 0) + line.setQtyEntered(line.getMovementQty().multiply(orderLine.getQtyEntered()) + .divide(orderLine.getQtyOrdered(), 12, BigDecimal.ROUND_HALF_UP)); + line.setLine(m_line + orderLine.getLine()); if (!line.save()) throw new IllegalStateException("Could not create Shipment Line"); diff --git a/org.adempiere.base.process/src/org/compiere/process/InfoWindowValidate.java b/org.adempiere.base.process/src/org/compiere/process/InfoWindowValidate.java index a0d17642b7..de4310422e 100644 --- a/org.adempiere.base.process/src/org/compiere/process/InfoWindowValidate.java +++ b/org.adempiere.base.process/src/org/compiere/process/InfoWindowValidate.java @@ -16,11 +16,7 @@ *****************************************************************************/ package org.compiere.process; -import java.sql.PreparedStatement; - -import org.compiere.model.MInfoColumn; import org.compiere.model.MInfoWindow; -import org.compiere.util.DB; /** * Validate Info Window SQL @@ -50,60 +46,10 @@ public class InfoWindowValidate extends SvrProcess throws Exception { MInfoWindow infoWindow = new MInfoWindow(getCtx(), p_AD_InfoWindow_ID, (String)null); - infoWindow.setIsValid(false); + infoWindow.validate(); infoWindow.saveEx(); - - StringBuilder builder = new StringBuilder("SELECT "); - if (infoWindow.isDistinct()) - builder.append("DISTINCT "); - - MInfoColumn[] infoColumns = infoWindow.getInfoColumns(); - if (infoColumns.length == 0) - throw new Exception("NoColumns"); - - for (int columnIndex = 0; columnIndex < infoColumns.length; columnIndex++) { - if (columnIndex > 0) - { - builder.append(", "); - } - builder.append(infoColumns[columnIndex].getSelectClause()); - } - - builder.append( " FROM ").append(infoWindow.getFromClause()); - if (infoWindow.getWhereClause() != null && infoWindow.getWhereClause().trim().length() > 0) { - builder.append(" WHERE ").append(infoWindow.getWhereClause()); - } - - if (infoWindow.getOtherClause() != null && infoWindow.getOtherClause().trim().length() > 0) { - builder.append(" ").append(infoWindow.getOtherClause()); - } - - if (infoWindow.getOrderByClause() != null && infoWindow.getOrderByClause().trim().length() > 0) { - builder.append(" ORDER BY ").append(infoWindow.getOrderByClause()); - } - - while(builder.indexOf("@") >= 0) { - int start = builder.indexOf("@"); - int end = builder.indexOf("@", start+1); - if (start >=0 && end > start) { - builder.replace(start, end+1, "0"); - } else { - break; - } - } - - PreparedStatement pstmt = null; - try { - pstmt = DB.prepareStatement(builder.toString(), get_TrxName()); - pstmt.executeQuery(); - } finally { - DB.close(pstmt); - } - - infoWindow.setIsValid(true); - infoWindow.saveEx(); - - return "Ok"; + + return infoWindow.isValid() ? "@OK@" : "@NotValid@"; } // doIt } // InfoWindowValidate diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java index f9f0700b16..0dc0ecbce8 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVExporter.java @@ -265,7 +265,13 @@ public class GridTabCSVExporter implements IGridTabExporter if (record_id!=null) sValue = queryExecute(columnRef,tableRef,record_id); }else{ - sValue = address.get_Value(columnName); + sValue = address.get_Value(columnName); + if (DisplayType.YesNo == MColumn.get(Env.getCtx(), MLocation.Table_Name, columnName).getAD_Reference_ID()) { + if (sValue != null && (Boolean) sValue) + sValue = "Y"; + else if (sValue != null && ! (Boolean) sValue) + sValue = "N"; + } } row.put(gridTab.getTableName()+">"+specialHeader,sValue); idxfld++; @@ -384,7 +390,13 @@ public class GridTabCSVExporter implements IGridTabExporter if(record_id!=null) sValue = queryExecute(columnRef,tableRef,record_id); }else{ - sValue = address.get_Value(columnName); + sValue = address.get_Value(columnName); + if (DisplayType.YesNo == MColumn.get(Env.getCtx(), MLocation.Table_Name, columnName).getAD_Reference_ID()) { + if (sValue != null && (Boolean) sValue) + sValue = "Y"; + else if (sValue != null && ! (Boolean) sValue) + sValue = "N"; + } } row.put(childTab.getTableName()+">"+specialHeader,sValue); } diff --git a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java index 827e622f07..47277056a3 100644 --- a/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java +++ b/org.adempiere.base/src/org/adempiere/impexp/GridTabCSVImporter.java @@ -758,8 +758,8 @@ public class GridTabCSVImporter implements IGridTabImporter if (field.isParentValue()) continue; - if (field.isReadOnly() && !field.isParentValue()) - return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldIsReadOnly",new Object[] {header.get(i)})); +// if (field.isReadOnly() && !field.isParentValue() && !field.isParentColumn()) +// return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldIsReadOnly",new Object[] {header.get(i)})); if (!(field.isDisplayed() || field.isDisplayedGrid())) return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldNotDisplayed",new Object[] {header.get(i)})); @@ -802,8 +802,8 @@ public class GridTabCSVImporter implements IGridTabImporter if(field == null) return new StringBuilder(Msg.getMsg(Env.getCtx(), "NotAWindowField",new Object[] {sField})); - if(field.isReadOnly() && !field.isParentValue()) - return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldIsReadOnly",new Object[] {field.getColumnName()})); +// if(field.isReadOnly() && !field.isParentValue()) +// return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldIsReadOnly",new Object[] {field.getColumnName()})); if(!(field.isDisplayed() || field.isDisplayedGrid())) return new StringBuilder(Msg.getMsg(Env.getCtx(), "FieldNotDisplayed",new Object[] {field.getColumnName()})); @@ -960,10 +960,10 @@ public class GridTabCSVImporter implements IGridTabImporter if(!field.isDisplayed(true)) continue; - if(!isInsertMode() && !field.isEditable(true) && value!=null){ - logMsg = Msg.getMsg(Env.getCtx(), "FieldNotEditable", new Object[] {header.get(i)}) + "{" + value + "}"; - break; - } +// if(!isInsertMode() && !field.isEditable(true) && value!=null){ +// logMsg = Msg.getMsg(Env.getCtx(), "FieldNotEditable", new Object[] {header.get(i)}) + "{" + value + "}"; +// break; +// } if("(null)".equals(value.toString().trim())){ logMsg = gridTab.setValue(field,null); if(logMsg.equals("")) @@ -1035,9 +1035,18 @@ public class GridTabCSVImporter implements IGridTabImporter isThereRow =true; } } - - if(setValue != null) - logMsg = gridTab.setValue(field,setValue); + + if(setValue != null) { + Object oldValue = gridTab.getValue(field); + if (isValueChanged(oldValue, setValue)) { + if (!field.isEditable(true)) { + return Msg.getMsg(Env.getCtx(), "FieldIsReadOnly",new Object[] {header.get(i)}); + } + logMsg = gridTab.setValue(field,setValue); + } else { + logMsg = ""; + } + } if(logMsg!=null && logMsg.equals("")) logMsg= null; @@ -1286,6 +1295,55 @@ public class GridTabCSVImporter implements IGridTabImporter return id; } + //Copy from GridTable + private boolean isValueChanged(Object oldValue, Object value) + { + if ( isNotNullAndIsEmpty(oldValue) ) { + oldValue = null; + } + + if ( isNotNullAndIsEmpty(value) ) { + value = null; + } + + boolean bChanged = (oldValue == null && value != null) + || (oldValue != null && value == null); + + if (!bChanged && oldValue != null) + { + if (oldValue.getClass().equals(value.getClass())) + { + if (oldValue instanceof Comparable) + { + bChanged = (((Comparable)oldValue).compareTo(value) != 0); + } + else + { + bChanged = !oldValue.equals(value); + } + } + else if(value != null) + { + bChanged = !(oldValue.toString().equals(value.toString())); + } + } + return bChanged; + } + + //Copy from GridTable + private boolean isNotNullAndIsEmpty (Object value) { + if (value != null + && (value instanceof String) + && value.toString().equals("") + ) + { + return true; + } else { + return false; + } + + } + @Override public String getFileExtension() { return "csv"; diff --git a/org.adempiere.base/src/org/adempiere/util/ProcessUtil.java b/org.adempiere.base/src/org/adempiere/util/ProcessUtil.java index 2ae25b537e..2da83f4d2c 100644 --- a/org.adempiere.base/src/org/adempiere/util/ProcessUtil.java +++ b/org.adempiere.base/src/org/adempiere/util/ProcessUtil.java @@ -269,7 +269,7 @@ public final class ProcessUtil { msg = engine.eval(rule.getScript()).toString(); //transaction should rollback if there are error in process - if ("@Error@".equals(msg)) + if (msg.startsWith("@Error@")) success = false; // Parse Variables diff --git a/org.adempiere.base/src/org/compiere/acct/Doc.java b/org.adempiere.base/src/org/compiere/acct/Doc.java index b977607849..17937087a3 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc.java @@ -28,6 +28,13 @@ import java.util.Iterator; import java.util.Properties; import java.util.logging.Level; +import org.compiere.model.I_C_AllocationHdr; +import org.compiere.model.I_C_BankStatement; +import org.compiere.model.I_C_Cash; +import org.compiere.model.I_C_ProjectIssue; +import org.compiere.model.I_M_MatchInv; +import org.compiere.model.I_M_MatchPO; +import org.compiere.model.I_M_Production; import org.compiere.model.MAccount; import org.compiere.model.MAcctSchema; import org.compiere.model.MConversionRate; @@ -122,6 +129,8 @@ public abstract class Doc * M_Requisition POR **************************************************************************/ + private static final String DOC_TYPE_BY_DOC_BASE_TYPE_SQL = "SELECT C_DocType_ID FROM C_DocType WHERE AD_Client_ID=? AND DocBaseType=? AND IsActive='Y'"; + /** AR Invoices - ARI */ public static final String DOCTYPE_ARInvoice = MDocType.DOCBASETYPE_ARInvoice; /** AR Credit Memo */ @@ -1729,6 +1738,58 @@ public abstract class Doc if (ii != null) return ii.intValue(); } + else + { + if (p_po.get_TableName().equals(I_M_MatchPO.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_MatMatchPO); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_M_MatchInv.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_MatMatchInv); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_C_AllocationHdr.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_Allocation); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_C_BankStatement.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_BankStatement); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_C_Cash.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_CashJournal); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_C_ProjectIssue.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_ProjectIssue); + if (docTypeId > 0) + return docTypeId; + } + else if (p_po.get_TableName().equals(I_M_Production.Table_Name)) + { + int docTypeId = DB.getSQLValue((String)null, DOC_TYPE_BY_DOC_BASE_TYPE_SQL, + p_po.getAD_Client_ID(), Doc.DOCTYPE_MatProduction); + if (docTypeId > 0) + return docTypeId; + } + } return 0; } // getC_DocType_ID diff --git a/org.adempiere.base/src/org/compiere/model/GridTab.java b/org.adempiere.base/src/org/compiere/model/GridTab.java index 86745250af..288b1d084e 100644 --- a/org.adempiere.base/src/org/compiere/model/GridTab.java +++ b/org.adempiere.base/src/org/compiere/model/GridTab.java @@ -929,13 +929,13 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable if (keyNo != -1 || uuid != null) { if ( ( keyNo != -1 && keyNo != m_mTable.getKeyID(m_currentRow) ) - || ( uuid != null && uuid.compareTo(m_mTable.getUUID(m_currentRow)) != 0) ) // something changed + || (uuid != null && m_mTable.getUUID(m_currentRow) == null) || ( uuid != null && uuid.compareTo(m_mTable.getUUID(m_currentRow)) != 0) ) // something changed { int size = getRowCount(); for (int i = 0; i < size; i++) { if ( ( keyNo != -1 && keyNo == m_mTable.getKeyID(i) ) - || ( uuid != null && uuid.compareTo(m_mTable.getUUID(i)) == 0) ) + || ( uuid != null && m_mTable.getUUID(i) != null && uuid.compareTo(m_mTable.getUUID(i)) == 0) ) { m_currentRow = i; break; diff --git a/org.adempiere.base/src/org/compiere/model/I_I_Inventory.java b/org.adempiere.base/src/org/compiere/model/I_I_Inventory.java index c82afc09f8..8afe788601 100644 --- a/org.adempiere.base/src/org/compiere/model/I_I_Inventory.java +++ b/org.adempiere.base/src/org/compiere/model/I_I_Inventory.java @@ -247,6 +247,21 @@ public interface I_I_Inventory */ public String getLot(); + /** Column name M_CostingLine_ID */ + public static final String COLUMNNAME_M_CostingLine_ID = "M_CostingLine_ID"; + + /** Set Cost Adjustment Line. + * Unique line in an Inventory cost adjustment document + */ + public void setM_CostingLine_ID (int M_CostingLine_ID); + + /** Get Cost Adjustment Line. + * Unique line in an Inventory cost adjustment document + */ + public int getM_CostingLine_ID(); + + public org.compiere.model.I_M_InventoryLine getM_CostingLine() throws RuntimeException; + /** Column name M_Inventory_ID */ public static final String COLUMNNAME_M_Inventory_ID = "M_Inventory_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/MInOut.java b/org.adempiere.base/src/org/compiere/model/MInOut.java index 5d358d8bf8..0c483f3fb2 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOut.java +++ b/org.adempiere.base/src/org/compiere/model/MInOut.java @@ -1395,7 +1395,7 @@ public class MInOut extends X_M_InOut implements DocAction } } - if (oLine!=null && mtrx!=null) + if (oLine!=null && mtrx!=null && oLine.getQtyOrdered().signum() > 0) { if (sLine.getC_OrderLine_ID() != 0) { @@ -1434,7 +1434,7 @@ public class MInOut extends X_M_InOut implements DocAction m_processMsg = "Cannot correct Inventory OnHand [" + product.getValue() + "] - " + lastError; return DocAction.STATUS_Invalid; } - if (oLine!=null) + if (oLine!=null && oLine.getQtyOrdered().signum() > 0) { if (!MStorageReservation.add(getCtx(), oLine.getM_Warehouse_ID(), sLine.getM_Product_ID(), diff --git a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java index e277a3862b..66e7549ffc 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java @@ -36,7 +36,7 @@ public class MInfoColumn extends X_AD_InfoColumn /** * */ - private static final long serialVersionUID = 4317064257861102601L; + private static final long serialVersionUID = 9198213211937136870L; /** * Stanfard Constructor @@ -60,6 +60,20 @@ public class MInfoColumn extends X_AD_InfoColumn super (ctx, rs, trxName); } // MInfoColumn + /** Parent */ + private MInfoWindow m_parent = null; + + /** + * Get Parent + * @return parent + */ + public MInfoWindow getParent() + { + if (m_parent == null) + m_parent = new MInfoWindow(getCtx(), getAD_InfoWindow_ID(), get_TrxName()); + return m_parent; + } // getParent + /** * check column read access * @param tableInfos @@ -131,5 +145,35 @@ public class MInfoColumn extends X_AD_InfoColumn return true; } + /** + * when change field relate to sql, call valid from infoWindow + */ + @Override + protected boolean afterSave(boolean newRecord, boolean success) { + if (!success) + return success; + // evaluate need valid + boolean isNeedValid = newRecord || is_ValueChanged (MInfoColumn.COLUMNNAME_SelectClause); + + // call valid of parrent + if (isNeedValid){ + getParent().validate(); + getParent().saveEx(get_TrxName()); + } + + return super.afterSave(newRecord, success); + } + + /** + * when delete record, call valid from parent to set state + * when delete all, valid state is false + * when delete a wrong column can make valid state to true + */ + @Override + protected boolean afterDelete(boolean success) { + getParent().validate(); + getParent().saveEx(get_TrxName()); + return super.afterDelete(success); + } } // MInfoColumn diff --git a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java index ee9a3b7d67..19d431cb13 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoWindow.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoWindow.java @@ -329,6 +329,17 @@ public class MInfoWindow extends X_AD_InfoWindow } } } + + // evaluate need valid + boolean isNeedValid = is_new() || is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_AD_Table_ID) || is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_WhereClause) || + is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_FromClause) || is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_OrderByClause) || + is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_OtherClause) || is_ValueChanged (I_AD_InfoWindow.COLUMNNAME_IsDistinct); + + // valid config + if (isNeedValid){ + validate(); + } + return true; } @@ -363,4 +374,76 @@ public class MInfoWindow extends X_AD_InfoWindow } + public void validate () + { + // default, before complete check is invalid + this.setIsValid(false); + + // add DISTINCT clause + StringBuilder builder = new StringBuilder("SELECT "); + if (this.isDistinct()) + builder.append("DISTINCT "); + + MInfoColumn[] infoColumns = this.getInfoColumns(); + // none column make this invalid + if (infoColumns.length == 0){ + return; + } + + // build select clause + for (int columnIndex = 0; columnIndex < infoColumns.length; columnIndex++) { + if (columnIndex > 0) + { + builder.append(", "); + } + builder.append(infoColumns[columnIndex].getSelectClause()); + } + + // build from clause + builder.append( " FROM ").append(this.getFromClause()); + + // build where clause add (1=2) because not need get result, decrease load + if (this.getWhereClause() != null && this.getWhereClause().trim().length() > 0) { + builder.append(" WHERE (1=2) AND (").append(this.getWhereClause()).append(")"); + } else { + builder.append(" WHERE 1=2"); + } + + // build other (having) clause + if (this.getOtherClause() != null && this.getOtherClause().trim().length() > 0) { + builder.append(" ").append(this.getOtherClause()); + } + + // build order (having) clause + if (this.getOrderByClause() != null && this.getOrderByClause().trim().length() > 0) { + builder.append(" ORDER BY ").append(this.getOrderByClause()); + } + + // replace env value by dummy value + while(builder.indexOf("@") >= 0) { + int start = builder.indexOf("@"); + int end = builder.indexOf("@", start+1); + if (start >=0 && end > start) { + builder.replace(start, end+1, "0"); + } else { + break; + } + } + + // try run sql + PreparedStatement pstmt = null; + try { + pstmt = DB.prepareStatement(builder.toString(), null); + pstmt.executeQuery(); + }catch (Exception ex){ + log.log(Level.WARNING, ex.getMessage()); + return; + } finally { + DB.close(pstmt); + } + + // valid state + this.setIsValid(true); + } + } // MInfoWindow diff --git a/org.adempiere.base/src/org/compiere/model/MOrder.java b/org.adempiere.base/src/org/compiere/model/MOrder.java index bf9ac17089..12bb387894 100644 --- a/org.adempiere.base/src/org/compiere/model/MOrder.java +++ b/org.adempiere.base/src/org/compiere/model/MOrder.java @@ -1722,7 +1722,7 @@ public class MOrder extends X_C_Order implements DocAction BigDecimal difference = target .subtract(line.getQtyReserved()) .subtract(line.getQtyDelivered()); - if (difference.signum() == 0) + if (difference.signum() <= 0) { MProduct product = line.getProduct(); if (product != null) diff --git a/org.adempiere.base/src/org/compiere/model/MScheduler.java b/org.adempiere.base/src/org/compiere/model/MScheduler.java index dceea1b6d4..385e28e868 100644 --- a/org.adempiere.base/src/org/compiere/model/MScheduler.java +++ b/org.adempiere.base/src/org/compiere/model/MScheduler.java @@ -221,11 +221,6 @@ public class MScheduler extends X_AD_Scheduler } } } - // Add Updater - if (list.size() == 0) - { - list.add(getCreatedBy()); - } // return list.toArray(new Integer[list.size()]); } // getRecipientAD_User_IDs diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index a16e15b2a0..678aa9fc8d 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -42,7 +42,7 @@ public class MSysConfig extends X_AD_SysConfig /** * */ - private static final long serialVersionUID = 7850399904723862767L; + private static final long serialVersionUID = -4635791167798916808L; public static final String ADDRESS_SAVE_REQUEST_RESPONSE_LOG = "ADDRESS_SAVE_REQUEST_RESPONSE_LOG"; public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION"; @@ -125,7 +125,9 @@ public class MSysConfig extends X_AD_SysConfig public static final String ZK_BROWSER_ICON = "ZK_BROWSER_ICON"; public static final String ZK_BROWSER_TITLE = "ZK_BROWSER_TITLE"; public static final String ZK_BUTTON_STYLE = "ZK_BUTTON_STYLE"; + public static final String ZK_DASHBOARD_PERFORMANCE_TIMEOUT = "ZK_DASHBOARD_PERFORMANCE_TIMEOUT"; public static final String ZK_DASHBOARD_REFRESH_INTERVAL = "ZK_DASHBOARD_REFRESH_INTERVAL"; + public static final String ZK_DECIMALBOX_PROCESS_DOTKEYPAD = "ZK_DECIMALBOX_PROCESS_DOTKEYPAD"; public static final String ZK_DESKTOP_CLASS = "ZK_DESKTOP_CLASS"; public static final String ZK_GRID_EDIT_MODELESS = "ZK_GRID_EDIT_MODELESS"; public static final String ZK_LOGIN_ALLOW_REMEMBER_ME = "ZK_LOGIN_ALLOW_REMEMBER_ME"; @@ -681,4 +683,4 @@ public class MSysConfig extends X_AD_SysConfig +"]"; } -} // MSysConfig; \ No newline at end of file +} // MSysConfig; diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index e50db0f9d8..5c1ba0795f 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -55,7 +55,7 @@ public class MTable extends X_AD_Table /** * */ - private static final long serialVersionUID = 3743087295968040894L; + private static final long serialVersionUID = -1776819186412187384L; public final static int MAX_OFFICIAL_ID = 999999; @@ -536,8 +536,8 @@ public class MTable extends X_AD_Table StringBuffer sb = new StringBuffer("CREATE TABLE ") .append(getTableName()).append(" ("); // - boolean hasPK = false; - boolean hasParents = false; + // boolean hasPK = false; + // boolean hasParents = false; StringBuffer constraints = new StringBuffer(); getColumns(true); for (int i = 0; i < m_columns.length; i++) @@ -553,14 +553,15 @@ public class MTable extends X_AD_Table else // virtual column continue; // - if (column.isKey()) - hasPK = true; - if (column.isParent()) - hasParents = true; + // if (column.isKey()) + // hasPK = true; + // if (column.isParent()) + // hasParents = true; String constraint = column.getConstraint(getTableName()); if (constraint != null && constraint.length() > 0) constraints.append(", ").append(constraint); } + /* IDEMPIERE-1901 - deprecate code that create composite primary key // Multi Column PK if (!hasPK && hasParents) { @@ -578,6 +579,7 @@ public class MTable extends X_AD_Table .append(getTableName()).append("_Key PRIMARY KEY (") .append(cols).append(")"); } + */ sb.append(constraints) .append(")"); diff --git a/org.adempiere.base/src/org/compiere/model/MTreeNode.java b/org.adempiere.base/src/org/compiere/model/MTreeNode.java index e95c77d7ef..98ded4562f 100644 --- a/org.adempiere.base/src/org/compiere/model/MTreeNode.java +++ b/org.adempiere.base/src/org/compiere/model/MTreeNode.java @@ -38,7 +38,7 @@ public class MTreeNode extends DefaultMutableTreeNode /** * */ - private static final long serialVersionUID = 4663753548813509716L; + private static final long serialVersionUID = -6871590404494812487L; /** * Construct Model TreeNode @@ -215,7 +215,18 @@ public class MTreeNode extends DefaultMutableTreeNode return m_description; } // getDescription - + /** + * Set Description + * @param name name + */ + public void setDescription (String description) + { + if (description == null) + m_description = ""; + else + m_description = description; + } // setDescription + /************************************************************************** * Set Summary (allow children) * @param isSummary summary node diff --git a/org.adempiere.base/src/org/compiere/model/X_I_Inventory.java b/org.adempiere.base/src/org/compiere/model/X_I_Inventory.java index 87ede923dd..d30d5fbcbe 100644 --- a/org.adempiere.base/src/org/compiere/model/X_I_Inventory.java +++ b/org.adempiere.base/src/org/compiere/model/X_I_Inventory.java @@ -33,7 +33,7 @@ public class X_I_Inventory extends PO implements I_I_Inventory, I_Persistent /** * */ - private static final long serialVersionUID = 20131031L; + private static final long serialVersionUID = 20140701L; /** Standard Constructor */ public X_I_Inventory (Properties ctx, int I_Inventory_ID, String trxName) @@ -321,6 +321,34 @@ public class X_I_Inventory extends PO implements I_I_Inventory, I_Persistent return (String)get_Value(COLUMNNAME_Lot); } + public org.compiere.model.I_M_InventoryLine getM_CostingLine() throws RuntimeException + { + return (org.compiere.model.I_M_InventoryLine)MTable.get(getCtx(), org.compiere.model.I_M_InventoryLine.Table_Name) + .getPO(getM_CostingLine_ID(), get_TrxName()); } + + /** Set Cost Adjustment Line. + @param M_CostingLine_ID + Unique line in an Inventory cost adjustment document + */ + public void setM_CostingLine_ID (int M_CostingLine_ID) + { + if (M_CostingLine_ID < 1) + set_Value (COLUMNNAME_M_CostingLine_ID, null); + else + set_Value (COLUMNNAME_M_CostingLine_ID, Integer.valueOf(M_CostingLine_ID)); + } + + /** Get Cost Adjustment Line. + @return Unique line in an Inventory cost adjustment document + */ + public int getM_CostingLine_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_M_CostingLine_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + public org.compiere.model.I_M_Inventory getM_Inventory() throws RuntimeException { return (org.compiere.model.I_M_Inventory)MTable.get(getCtx(), org.compiere.model.I_M_Inventory.Table_Name) diff --git a/org.adempiere.base/src/org/compiere/process/SvrProcess.java b/org.adempiere.base/src/org/compiere/process/SvrProcess.java index 040c7fec7e..2c9c00dffb 100644 --- a/org.adempiere.base/src/org/compiere/process/SvrProcess.java +++ b/org.adempiere.base/src/org/compiere/process/SvrProcess.java @@ -211,7 +211,7 @@ public abstract class SvrProcess implements ProcessCall } //transaction should rollback if there are error in process - if ("@Error@".equals(msg)) + if(msg.startsWith("@Error@")) success = false; if (success) diff --git a/org.adempiere.base/src/org/compiere/util/TimeUtil.java b/org.adempiere.base/src/org/compiere/util/TimeUtil.java index 8d2ef215ab..db9b2192f8 100644 --- a/org.adempiere.base/src/org/compiere/util/TimeUtil.java +++ b/org.adempiere.base/src/org/compiere/util/TimeUtil.java @@ -815,4 +815,18 @@ public class TimeUtil return endCal.get(Calendar.YEAR) * 12 + endCal.get(Calendar.MONTH) - (startCal.get(Calendar.YEAR) * 12 + startCal.get(Calendar.MONTH)); } + + /** Returns start date + nbDays which cannot be saturday or sunday or non business days */ + public static Timestamp addOnlyBusinessDays(Timestamp startDate, int nbDays, int clientID, String trxName) + { + Timestamp retValue = startDate; + while (nbDays > 0) { + retValue = TimeUtil.addDays(retValue, 1); + StringBuilder sql = new StringBuilder("SELECT nextBusinessDay(?,?) FROM DUAL"); + retValue = DB.getSQLValueTSEx(trxName, sql.toString(), retValue, clientID); + nbDays--; + } + return retValue; + } + } // TimeUtil diff --git a/org.adempiere.ui.swing/META-INF/MANIFEST.MF b/org.adempiere.ui.swing/META-INF/MANIFEST.MF index 4893a5dbcb..2667429f3b 100644 --- a/org.adempiere.ui.swing/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.swing/META-INF/MANIFEST.MF @@ -58,6 +58,7 @@ Export-Package: com.jgoodies.looks, org.jdesktop.swingx.multisplitpane, org.jdesktop.swingx.painter, org.jdesktop.swingx.painter.effects, + org.jdesktop.swingx.plaf, org.jdesktop.swingx.renderer, org.jdesktop.swingx.rollover, org.jdesktop.swingx.search, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java index cf2de89fd9..f4376f8a63 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowContent.java @@ -142,7 +142,6 @@ public class ADWindowContent extends AbstractADWindowContent LayoutUtils.addSclass("adwindow-status", statusBar); contentArea = new Div(); - contentArea.setRenderdefer(50); contentArea.setParent(layout); contentArea.setVflex("1"); contentArea.setHflex("1"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java index ea8278f2c8..588dcb64e0 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java @@ -523,6 +523,26 @@ public class ADWindowToolbar extends FToolbar implements EventListener { btnCustomize.setDisabled(!enabled); } + + public void enableArchive(boolean enabled) + { + btnArchive.setDisabled(!enabled); + } + + public void enableZoomAcross(boolean enabled) + { + btnZoomAcross.setDisabled(!enabled); + } + + public void enableActiveWorkflows(boolean enabled) + { + btnActiveWorkflows.setDisabled(!enabled); + } + + public void enableRequests(boolean enabled) + { + btnRequests.setDisabled(!enabled); + } public void lock(boolean locked) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index fe1eda60bf..9d9bb0c83c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -1087,7 +1087,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements { ADTabpanel adtab = (ADTabpanel) event.getTarget(); if (adtab == adTabbox.getSelectedTabpanel()) { - toolbar.enableProcessButton(adtab.getToolbarButtons().size() > 0); + toolbar.enableProcessButton(adtab.getToolbarButtons().size() > 0 && !adTabbox.getSelectedGridTab().isNew()); toolbar.dynamicDisplay(); } } @@ -1277,7 +1277,7 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements toolbar.lock(adTabbox.getSelectedGridTab().isLocked()); } - toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted()); + toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted() && !adTabbox.getSelectedGridTab().isNew()); //Deepak-Enabling customize button IDEMPIERE-364 if(!(adTabbox.getSelectedTabpanel() instanceof ADSortTab)) @@ -1612,8 +1612,15 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements adTabbox.evaluate(e); } - toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted() && !adTabbox.getSelectedGridTab().isNew()); - toolbar.enableReport(true); + boolean isNewRow = adTabbox.getSelectedGridTab().getRowCount() == 0 || adTabbox.getSelectedGridTab().isNew(); + toolbar.enableProcessButton(!isNewRow); + toolbar.enableArchive(!isNewRow); + toolbar.enableZoomAcross(!isNewRow); + toolbar.enableActiveWorkflows(!isNewRow); + toolbar.enableRequests(!isNewRow); + + toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted() && !isNewRow); + toolbar.enableReport(!isNewRow); toolbar.enableExport(!adTabbox.getSelectedGridTab().isSortTab()); toolbar.enableFileImport(!changed && !adTabbox.getSelectedGridTab().isSortTab() && adTabbox.getSelectedGridTab().isInsertRecord()); @@ -1781,8 +1788,6 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements breadCrumb.enableLastNavigation(adTabbox.getSelectedGridTab().getCurrentRow() + 1 < adTabbox.getSelectedGridTab().getRowCount()); toolbar.enableTabNavigation(breadCrumb.hasParentLink(), adTabbox.getSelectedDetailADTabpanel() != null); toolbar.enableIgnore(true); - toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted()); - toolbar.enableReport(true); if (adTabbox.getSelectedGridTab().isSingleRow()) { if (adTabbox.getSelectedTabpanel().isGridView()) @@ -1862,8 +1867,6 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements breadCrumb.enableLastNavigation(adTabbox.getSelectedGridTab().getCurrentRow() + 1 < adTabbox.getSelectedGridTab().getRowCount()); toolbar.enableTabNavigation(false); toolbar.enableIgnore(true); - toolbar.enablePrint(adTabbox.getSelectedGridTab().isPrinted()); - toolbar.enableReport(true); if (postCallback != null) postCallback.onCallback(true); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java index 8f50a6090a..5c2a7d5bc1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java @@ -31,6 +31,7 @@ import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.EditorBox; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.NumberBox; +import org.adempiere.webui.component.Rows; import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.util.SortComparator; import org.compiere.model.GridField; @@ -615,8 +616,10 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi if (pageSize > 0 && paging != null) renderer.setPaging(paging); - listbox.setRowRenderer(renderer); listbox.setModel(listModel); + if (listbox.getRows() == null) + listbox.appendChild(new Rows()); + listbox.setRowRenderer(renderer); } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/DocumentSearchController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/DocumentSearchController.java new file mode 100644 index 0000000000..e88cfaf869 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/DocumentSearchController.java @@ -0,0 +1,365 @@ +/****************************************************************************** + * Copyright (C) 2014 Low Heng Sin * + * Copyright (C) 2014 Trek Global * + * 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. * + *****************************************************************************/ +package org.adempiere.webui.apps; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.adempiere.webui.component.Label; +import org.compiere.model.I_AD_SearchDefinition; +import org.compiere.model.MColumn; +import org.compiere.model.MLookup; +import org.compiere.model.MLookupFactory; +import org.compiere.model.MLookupInfo; +import org.compiere.model.MQuery; +import org.compiere.model.MRole; +import org.compiere.model.MSearchDefinition; +import org.compiere.model.MTable; +import org.compiere.model.MWindow; +import org.compiere.model.Query; +import org.compiere.util.DB; +import org.compiere.util.DisplayType; +import org.compiere.util.Env; +import org.compiere.util.Util; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.A; +import org.zkoss.zul.Textbox; +import org.zkoss.zul.Vlayout; + +/** + * @author hengsin + * + */ +public class DocumentSearchController implements EventListener{ + + private static final String SEARCH_RESULT = "search.result"; + private static final String ON_SEARCH_DOCUMENTS = "onSearchDocuments"; + private Vlayout layout; + + /** + * + */ + public DocumentSearchController() { + } + + public void create(Component parent) { + layout = new Vlayout(); + layout.setStyle("padding: 3px;"); + layout.setWidth("200px"); + + parent.appendChild(layout); + + layout.addEventListener(ON_SEARCH_DOCUMENTS, this); + } + + public void search(String value) { + layout.getChildren().clear(); + Events.echoEvent(ON_SEARCH_DOCUMENTS, layout, value); + } + + private void onSearchDocuments(String searchString) { + if (Util.isEmpty(searchString)) { + return; + } + + List list = doSearch(searchString); + if (list.size() > 0) { + Collections.sort(list, new Comparator() { + @Override + public int compare(SearchResult o1, SearchResult o2) { + int r = o1.getWindowName().compareTo(o2.getWindowName()); + if (r == 0) + r = o1.getLabel().compareTo(o2.getLabel()); + return r; + } + }); + String windowName = null; + for(SearchResult result : list) { + if (windowName == null || !windowName.equals(result.getWindowName())) { + windowName = result.getWindowName(); + Label label = new Label(windowName); + label.setStyle("padding: 3px; font-weight: bold; display: inline-block;"); + layout.appendChild(label); + } + A a = new A(); + a.setAttribute(SEARCH_RESULT, result); + a.setLabel(result.getLabel()); + layout.appendChild(a); + a.setStyle("padding-left: 3px; display: inline-block;"); + a.addEventListener(Events.ON_CLICK, this); + } + layout.invalidate(); + } + } + + private List doSearch(String searchString) { + final MRole role = MRole.get(Env.getCtx(), Env.getAD_Role_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()), true); + + List list = new ArrayList(); + Query query = new Query(Env.getCtx(), I_AD_SearchDefinition.Table_Name, "", null); + List definitions = query.setOnlyActiveRecords(true).list(); + for(MSearchDefinition msd : definitions) { + MTable table = new MTable(Env.getCtx(), msd.getAD_Table_ID(), null); + StringBuilder sql = null; + MWindow window = msd.getAD_Window_ID() > 0 && role.getWindowAccess(msd.getAD_Window_ID()) != null ? MWindow.get(Env.getCtx(), msd.getAD_Window_ID()) : null; + MWindow powindow = msd.getPO_Window_ID() > 0 && role.getWindowAccess(msd.getPO_Window_ID()) != null ? MWindow.get(Env.getCtx(), msd.getPO_Window_ID()) : null; + if (window == null && powindow == null) + continue; + List params = new ArrayList(); + // SearchDefinition with a given table and column + if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_TABLE)) { + MColumn column = new MColumn(Env.getCtx(), msd.getAD_Column_ID(), null); + sql = new StringBuilder("SELECT ").append(table.getTableName()).append("_ID, ") + .append(column.getColumnName()); + sql.append(" FROM ") + .append(table.getTableName()) + .append(" "); + // search for an Integer + if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) { + sql.append("WHERE ").append(column.getColumnName()).append("=?"); + // search for a String + } else { + sql.append("WHERE UPPER(").append(column.getColumnName()).append(") LIKE UPPER(?)"); + } + + // search for a Integer + if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) { + params.add(Integer.valueOf(searchString.replaceAll("\\D", ""))); + // search for a String + } else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) { + if (searchString.endsWith("%")) + params.add(searchString); + else + params.add(searchString+"%"); + } + // SearchDefinition with a special query + } else if (msd.getSearchType().equals(MSearchDefinition.SEARCHTYPE_QUERY)) { + sql = new StringBuilder().append(msd.getQuery()); + // count '?' in statement + int count = 1; + for (char c : sql.toString().toCharArray()) { + if (c == '?') { + count++; + } + } + for (int i = 1; i < count; i++) { + if (msd.getDataType().equals(MSearchDefinition.DATATYPE_INTEGER)) { + params.add(Integer.valueOf(searchString.replaceAll("\\D", ""))); + } else if (msd.getDataType().equals(MSearchDefinition.DATATYPE_STRING)) { + if (searchString.endsWith("%")) + params.add(searchString); + else + params.add(searchString+"%"); + } + } + } + MLookupInfo lookupInfo = MLookupFactory.getLookupInfo(Env.getCtx(), -1, -1, DisplayType.Search, Env.getLanguage(Env.getCtx()), table.getTableName() + "_ID", 0, false, null); + MLookup lookup = new MLookup(lookupInfo, -1); + + if (sql != null) { + if (powindow != null) { + if (window != null) { + doRetrieval(msd, sql, params, lookup, window, table.getTableName(), " AND IsSOTrx='Y' ", list); + } + doRetrieval(msd, sql, params, lookup, powindow, table.getTableName(), " AND IsSOTrx='N' ", list); + } else if (window != null) { + doRetrieval(msd, sql, params, lookup, window, table.getTableName(), null, list); + } + + } + } + return list; + } + + private void doRetrieval(MSearchDefinition msd, StringBuilder builder, List params, MLookup lookup, MWindow window, String tableName, + String extraWhereClase, List list) { + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + String sql = builder.toString(); + if (!Util.isEmpty(extraWhereClase)) + sql = sql + extraWhereClase; + pstmt = DB.prepareStatement(sql, (String)null); + if (params.size() > 0) + DB.setParameters(pstmt, params); + pstmt.setQueryTimeout(1); + rs = pstmt.executeQuery(); + int count = 0; + while (rs.next() && count < 3) { + count++; + int id = rs.getInt(1); + SearchResult result = new SearchResult(); + result.setLabel(lookup.getDisplay(id)); + result.setRecordId(id); + result.setWindowName(window.get_Translation("Name")); + result.setWindowId(window.getAD_Window_ID()); + + result.setTableName(tableName); + if (rs.getMetaData().getColumnCount() > 1) { + result.setName(rs.getString(2)); + } + list.add(result); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + DB.close(rs, pstmt); + } + + } + + @Override + public void onEvent(Event event) throws Exception { + if (Events.ON_CLICK.equals(event.getName())) { + if (event.getTarget() instanceof A) { + SearchResult result = (SearchResult) event.getTarget().getAttribute(SEARCH_RESULT); + doZoom(result); + } + } else if (event.getName().equals(ON_SEARCH_DOCUMENTS)) { + onSearchDocuments((String)event.getData()); + } + } + + private void doZoom(SearchResult result) { + MQuery query = new MQuery(); + query.addRestriction(result.getTableName()+"_ID", "=", result.getRecordId()); + AEnv.zoom(result.getWindowId(), query); + } + + private class SearchResult { + private String windowName; + private int windowId; + private String tableName; + private int recordId; + private String label; + private String name; + + /** + * @return the windowId + */ + public int getWindowId() { + return windowId; + } + /** + * @param windowId the windowId to set + */ + public void setWindowId(int windowId) { + this.windowId = windowId; + } + /** + * @return the tableName + */ + public String getTableName() { + return tableName; + } + /** + * @param tableName the tableName to set + */ + public void setTableName(String tableName) { + this.tableName = tableName; + } + + /** + * @return the windowName + */ + public String getWindowName() { + return windowName; + } + /** + * @param windowName the windowName to set + */ + public void setWindowName(String windowName) { + this.windowName = windowName; + } + /** + * @return the recordId + */ + public int getRecordId() { + return recordId; + } + /** + * @param recordId the recordId to set + */ + public void setRecordId(int recordId) { + this.recordId = recordId; + } + /** + * @return the label + */ + public String getLabel() { + return label; + } + /** + * @param label the label to set + */ + public void setLabel(String label) { + this.label = label; + } + /** + * @return the name + */ + public String getName() { + return name; + } + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + } + + public boolean onOk(Textbox textbox) { + String text = textbox.getText(); + if (Util.isEmpty(text)) + return false; + text = text.toLowerCase(); + int size = layout.getChildren().size(); + A firstStart = null; + A exact = null; + for(int i = 0; i < size; i++) { + if (!(layout.getChildren().get(i) instanceof A)) continue; + A a = (A) layout.getChildren().get(i); + SearchResult result = (SearchResult) a.getAttribute(SEARCH_RESULT); + if (result.getLabel().equalsIgnoreCase(text)) { + exact = a; + break; + } else if (text.equalsIgnoreCase(result.getName())) { + exact = a; + break; + } else if (firstStart == null && result.getLabel().toLowerCase().startsWith(text) && text.length() >=3 ) { + firstStart = a; + } + } + + SearchResult result = null; + if (exact != null) + result = (SearchResult) exact.getAttribute(SEARCH_RESULT); + else if (firstStart != null) + result = (SearchResult) firstStart.getAttribute(SEARCH_RESULT); + if (result != null) { + doZoom(result); + } + + return false; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/GlobalSearch.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/GlobalSearch.java new file mode 100644 index 0000000000..e14eeb8c39 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/GlobalSearch.java @@ -0,0 +1,151 @@ +/****************************************************************************** + * Copyright (C) 2014 Low Heng Sin * + * Copyright (C) 2014 Trek Global * + * 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. * + *****************************************************************************/ +package org.adempiere.webui.apps; + +import org.adempiere.webui.component.Bandbox; +import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.InputEvent; +import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Bandpopup; +import org.zkoss.zul.Div; +import org.zkoss.zul.Hlayout; +import org.zkoss.zul.Separator; + +/** + * @author hengsin + * + */ +public class GlobalSearch extends Div implements EventListener { + + private static final String ON_ENTER_KEY = "onEnterKey"; + + private static final String ON_POST_ENTER_KEY = "onPostEnterKey"; + + private static final String ON_CREATE_ECHO = "onCreateEcho"; + + private static final String ON_SEARCH = "onSearch"; + + /** + * generated serial id + */ + private static final long serialVersionUID = -8793878697269469837L; + + private Bandbox bandbox; + + private MenuSearchController menuController; + private DocumentSearchController docController; + + /** + * + */ + public GlobalSearch(MenuSearchController menuController) { + this.menuController = menuController; + docController = new DocumentSearchController(); + init(); + } + + private void init() { + bandbox = new Bandbox(); + appendChild(bandbox); + bandbox.setWidth("100%"); + bandbox.setAutodrop(true); + bandbox.addEventListener(Events.ON_CHANGING, this); + bandbox.setCtrlKeys("#up#down"); + bandbox.addEventListener(Events.ON_CTRL_KEY, this); + + Bandpopup popup = new Bandpopup(); + popup.setHeight("600px"); + bandbox.appendChild(popup); + + Hlayout hlayout = new Hlayout(); + popup.appendChild(hlayout); + menuController.create(hlayout); + + Separator separator = new Separator(); + separator.setHflex("0"); + separator.setOrient("vertical"); + hlayout.appendChild(separator); + docController.create(hlayout); + + addEventListener(ON_SEARCH, this); + addEventListener(ON_CREATE_ECHO, this); + bandbox.addEventListener(ON_ENTER_KEY, this); + addEventListener(ON_POST_ENTER_KEY, this); + } + + @Override + public void onEvent(Event event) throws Exception { + if (Events.ON_CHANGING.equals(event.getName())) { + InputEvent inputEvent = (InputEvent) event; + String value = inputEvent.getValue(); + Events.postEvent(ON_SEARCH, this, value); + } else if (Events.ON_CTRL_KEY.equals(event.getName())) { + KeyEvent ke = (KeyEvent) event; + if (ke.getKeyCode() == KeyEvent.UP) { + if (bandbox.getFirstChild().isVisible()) { + MenuItem selected = menuController.selectPrior(); + if (selected != null) { + bandbox.setText(selected.getLabel()); + } + } + } else if (ke.getKeyCode() == KeyEvent.DOWN) { + if (bandbox.getFirstChild().isVisible()) { + MenuItem selected = menuController.selectNext(); + if (selected != null && !"...".equals(selected.getType())) { + bandbox.setText(selected.getLabel()); + } + } + } + } else if (event.getName().equals(ON_SEARCH)) { + String value = (String) event.getData(); + menuController.search(value); + docController.search(value); + bandbox.focus(); + } else if (event.getName().equals(ON_CREATE_ECHO)) { + StringBuilder script = new StringBuilder("jq('#") + .append(bandbox.getUuid()) + .append("').bind('keydown', function(e) {var code=e.keyCode||e.which;console.log(code);if(code==13){") + .append("var widget=zk.Widget.$(this);") + .append("var event=new zk.Event(widget,'") + .append(ON_ENTER_KEY) + .append("',{},{toServer:true});") + .append("zAu.send(event);") + .append("}});"); + Clients.evalJavaScript(script.toString()); + } else if (event.getName().equals(ON_ENTER_KEY)) { + Clients.showBusy(bandbox, null); + Events.echoEvent(ON_POST_ENTER_KEY, this, null); + } else if (event.getName().equals(ON_POST_ENTER_KEY)) { + Clients.clearBusy(bandbox); + if (menuController.onOk(bandbox)) { + return; + } else { + docController.onOk(bandbox); + } + } + } + + /* (non-Javadoc) + * @see org.zkoss.zk.ui.AbstractComponent#onPageAttached(org.zkoss.zk.ui.Page, org.zkoss.zk.ui.Page) + */ + @Override + public void onPageAttached(Page newpage, Page oldpage) { + super.onPageAttached(newpage, oldpage); + Events.echoEvent(ON_CREATE_ECHO, this, null); + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuItem.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuItem.java new file mode 100644 index 0000000000..48874cfed4 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuItem.java @@ -0,0 +1,87 @@ +/** + * + */ +package org.adempiere.webui.apps; + +/** + * @author hengsin + * + */ +public class MenuItem { + + private String label; + private String description; + private String image; + private String type; + private Object data; + + /** + * + */ + public MenuItem() { + } + + /** + * @return the label + */ + public String getLabel() { + return label; + } + + /** + * @param label the label to set + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the image + */ + public String getImage() { + return image; + } + + /** + * @param image the image to set + */ + public void setImage(String image) { + this.image = image; + } + + public void setData(Object data) { + this.data = data; + } + + public Object getData() { + return data; + } + + /** + * @return the type + */ + public String getType() { + return type; + } + + /** + * @param type the type to set + */ + public void setType(String type) { + this.type = type; + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuSearchController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuSearchController.java new file mode 100644 index 0000000000..d4ab059688 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/MenuSearchController.java @@ -0,0 +1,481 @@ +/****************************************************************************** + * Copyright (C) 2014 Low Heng Sin * + * Copyright (C) 2014 Trek Global * + * 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. * + *****************************************************************************/ +package org.adempiere.webui.apps; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListHead; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.theme.ThemeManager; +import org.adempiere.webui.util.TreeItemAction; +import org.adempiere.webui.util.TreeNodeAction; +import org.adempiere.webui.util.TreeUtils; +import org.compiere.model.MTreeNode; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.compiere.util.Util; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.A; +import org.zkoss.zul.DefaultTreeNode; +import org.zkoss.zul.ListModel; +import org.zkoss.zul.ListModelList; +import org.zkoss.zul.ListModels; +import org.zkoss.zul.ListSubModel; +import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listheader; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; +import org.zkoss.zul.ListitemRendererExt; +import org.zkoss.zul.Textbox; +import org.zkoss.zul.Toolbarbutton; +import org.zkoss.zul.Tree; +import org.zkoss.zul.Treechildren; +import org.zkoss.zul.Treeitem; +import org.zkoss.zul.Vlayout; +import org.zkoss.zul.impl.LabelElement; +import org.zkoss.zul.impl.LabelImageElement; + +/** + * @author hengsin + * + */ +public class MenuSearchController implements EventListener{ + + private static final String ON_SEARCH_ECHO = "onSearchEcho"; + private static final String ON_LOAD_MORE = "onLoadMore"; + private static final String ONSELECT_TIMESTAMP = "onselect.timestamp"; + private Tree tree; + private Listbox listbox; + private ListModelList model; + private Vlayout layout; + private ListModelList fullModel; + + private static final String ON_POST_SELECT_TREEITEM_EVENT = "onPostSelectTreeitem"; + + /** + * + */ + public MenuSearchController(Tree tree) { + this.tree = tree; + } + + public void refreshModel() { + final List list = new ArrayList(); + if (tree.getModel() == null) { + TreeUtils.traverse(tree, new TreeItemAction() { + public void run(Treeitem treeItem) { + if (treeItem.isVisible()) + addTreeItem(list, treeItem); + } + }); + } else { + TreeUtils.traverse(tree.getModel(), new TreeNodeAction() { + public void run(DefaultTreeNode treeNode) { + addTreeItem(list, treeNode); + } + }); + } + model = new ListModelList(list, true); + model.sort(new Comparator() { + + @Override + public int compare(MenuItem o1, MenuItem o2) { + return o1.getLabel().compareTo(o2.getLabel()); + } + }, true); + } + + private void addTreeItem(List list, DefaultTreeNode treeNode) { + MTreeNode mNode = (MTreeNode) treeNode.getData(); + if (!mNode.isLeaf()) + return; + + MenuItem item = new MenuItem(); + item.setLabel(mNode.getName()); + item.setDescription(mNode.getDescription()); + item.setImage(mNode.getImagePath()); + item.setData(treeNode); + list.add(item); + } + + private boolean isFolder(Treeitem treeItem) { + List list = treeItem.getChildren(); + for (Component c : list) { + if (c instanceof Treechildren && ((Treechildren)c).getChildren().size() > 0) { + return true; + } + } + return false; + } + + private void addTreeItem(List list, Treeitem treeItem) { + if (isFolder(treeItem)) + return; + + MenuItem item = new MenuItem(); + item.setLabel(getLabel(treeItem)); + item.setDescription(treeItem.getTooltiptext()); + + String image = getImage(treeItem); + if (image == null || image.length() == 0) + { + image = ThemeManager.getThemeResource("images/Folder16.png"); + } + item.setImage(image); + item.setData(treeItem); + list.add(item); + item.setType((String) treeItem.getAttribute("menu.type")); + } + + private String getLabel(Treeitem treeItem) { + String label = treeItem.getLabel(); + if (label == null || label.trim().length() == 0) + { + if (treeItem.getTreerow().getFirstChild().getFirstChild() != null && + treeItem.getTreerow().getFirstChild().getFirstChild() instanceof LabelElement) + { + LabelElement element = (LabelElement) treeItem.getTreerow().getFirstChild().getFirstChild(); + label = element.getLabel(); + } + } + return label; + } + + private String getImage(Treeitem treeItem) { + String image = treeItem.getImage(); + if (image == null || image.trim().length() == 0) + { + if (treeItem.getTreerow().getFirstChild().getFirstChild() != null && + treeItem.getTreerow().getFirstChild().getFirstChild() instanceof LabelImageElement) + { + LabelImageElement element = (LabelImageElement) treeItem.getTreerow().getFirstChild().getFirstChild(); + image = element.getImage(); + } + } + return image != null ? image.intern() : null; + } + + public void create(Component parent) { + refreshModel(); + + layout = new Vlayout(); + layout.setHeight("100%"); + parent.appendChild(layout); + + Label label = new Label(Util.cleanAmp(Msg.getMsg(Env.getCtx(),"Menu"))); + label.setStyle("padding: 3px; font-weight: bold; display: block;"); + layout.appendChild(label); + listbox = new Listbox(); + listbox.setEmptyMessage(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "FindZeroRecords"))); + listbox.setStyle("border: none"); + listbox.setWidth("500px"); + layout.appendChild(listbox); + listbox.setItemRenderer(new MenuItemRenderer()); + listbox.addEventListener(Events.ON_SELECT, this); + listbox.addEventListener(ON_POST_SELECT_TREEITEM_EVENT, this); + ListHead listhead = new ListHead(); + listbox.appendChild(listhead); + Listheader listheader = new Listheader(); + listhead.appendChild(listheader); + listheader = new Listheader(); + listheader.setWidth("32px"); + listhead.appendChild(listheader); + + layout.addEventListener(ON_SEARCH_ECHO, this); + layout.addEventListener(ON_LOAD_MORE, this); + updateListboxModel(model); + } + + @Override + public void onEvent(Event event) throws Exception { + if (Events.ON_SELECT.equals(event.getName())) { + ListItem selected = listbox.getSelectedItem(); + if (selected == null) return; + onSelect(selected, Boolean.FALSE); + } else if (event.getName().equals(ON_POST_SELECT_TREEITEM_EVENT)) { + onPostSelectTreeitem((Boolean) event.getData()); + } else if (Events.ON_CLICK.equals(event.getName())) { + if (event.getTarget() instanceof ListItem) { + ListItem item = (ListItem) event.getTarget(); + Long onSelect = (Long) item.getAttribute(ONSELECT_TIMESTAMP); + if (onSelect == null) { + onSelect(item, Boolean.FALSE); + } else if (System.currentTimeMillis() - onSelect.longValue() > 1000) { + onSelect(item, Boolean.FALSE); + } + } else if (event.getTarget() instanceof Toolbarbutton) { + ListItem item = null; + Component parent = event.getTarget(); + while (parent != null) { + if (parent instanceof ListItem) { + item = (ListItem) parent; + break; + } + parent = parent.getParent(); + } + if (item != null) { + onSelect(item, Boolean.TRUE); + } + } + } else if (event.getName().equals(ON_SEARCH_ECHO)) { + onSearchEcho((String) event.getData()); + } else if (event.getName().equals(ON_LOAD_MORE)) { + loadMore(); + } + } + + private void onSelect(ListItem selected, Boolean newRecord) { + MenuItem item = selected.getValue(); + if (item == null) return; + if ("...".equals(item.getType())) { + selected.setAttribute(ONSELECT_TIMESTAMP, System.currentTimeMillis()); + Clients.showBusy(selected, null); + Events.echoEvent(ON_LOAD_MORE, layout, null); + } else { + selectTreeitem(item.getData(), newRecord); + selected.setAttribute(ONSELECT_TIMESTAMP, System.currentTimeMillis()); + } + } + + private void loadMore() { + ListModel listModel = listbox.getModel(); + ListModelList lml = (ListModelList) listModel; + lml.remove(lml.size()-1); + List subList = fullModel.subList(50, fullModel.size()); + lml.addAll(subList); + fullModel = null; + listbox.setSelectedIndex(50); + Clients.scrollIntoView(listbox.getSelectedItem()); + } + + private void selectTreeitem(Object node, Boolean newRecord) { + if (Executions.getCurrent().getAttribute(listbox.getUuid()+".selectTreeitem") != null) + return; + + Treeitem treeItem = null; + if (node == null) { + return; + } else if (node instanceof Treeitem) { + treeItem = (Treeitem) node; + } else { + DefaultTreeNode sNode = (DefaultTreeNode) node; + int[] path = tree.getModel().getPath(sNode); + treeItem = tree.renderItemByPath(path); + tree.setSelectedItem(treeItem); + } + if (treeItem != null) { + Executions.getCurrent().setAttribute(listbox.getUuid()+".selectTreeitem", Boolean.TRUE); + + select(treeItem); + Events.postEvent(ON_POST_SELECT_TREEITEM_EVENT, listbox, newRecord); + } + } + + private void select(Treeitem selectedItem) { + Treeitem parent = selectedItem.getParentItem(); + while (parent != null) { + if (!parent.isOpen()) + parent.setOpen(true); + + parent = parent.getParentItem(); + } + selectedItem.getTree().setSelectedItem(selectedItem); + } + + private void onPostSelectTreeitem(Boolean newRecord) { + Event event = null; + if (tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild() instanceof A) + { + event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow().getFirstChild().getFirstChild(), newRecord); + } + else + { + event = new Event(Events.ON_CLICK, tree.getSelectedItem().getTreerow(), newRecord); + } + Events.postEvent(event); + } + + public void search(String value) { + listbox.setVisible(false); + Events.echoEvent(ON_SEARCH_ECHO, layout, value); + } + + public void onSearchEcho(String value) { + ListModelList newModel = null; + if (Util.isEmpty(value)) { + newModel = model; + } else { + @SuppressWarnings("unchecked") + ListSubModel subModel = (ListSubModel) ListModels.toListSubModel(model, new MenuListComparator(value), model.size()); + newModel = (ListModelList) subModel.getSubModel(null, -1); + } + updateListboxModel(newModel); + listbox.setVisible(true); + } + + private void updateListboxModel(ListModelList newModel) { + fullModel = null; + if (newModel.size() > 50) { + List list = newModel.getInnerList(); + List subList = list.subList(0, 50); + fullModel = newModel; + newModel = new ListModelList(subList.toArray(new MenuItem[0])); + MenuItem more = new MenuItem(); + more.setLabel("..."); + more.setType("..."); + newModel.add(more); + } + listbox.setModel(newModel); + } + + private class MenuListComparator implements Comparator { + + private String compare; + + private MenuListComparator(String compare) { + this.compare = compare; + } + + @Override + public int compare(MenuItem o1, MenuItem o2) { + compare = compare.toLowerCase().trim(); + boolean match = false; + if (compare.length() < 3) + { + match = o2.getLabel().toLowerCase().startsWith(compare); + } + else + { + match = o2.getLabel().toLowerCase().contains(compare); + } + return match ? 0 : -1; + } + + } + + public MenuItem selectPrior() { + int i = listbox.getSelectedIndex(); + if (i > 0) { + listbox.setSelectedIndex(i-1); + ListItem selected = listbox.getSelectedItem(); + if (selected == null) return null; + Clients.scrollIntoView(selected); + MenuItem item = selected.getValue(); + return item; + } + return null; + } + + public MenuItem selectNext() { + int i = listbox.getSelectedIndex(); + if (i < 0 && listbox.getItemCount() > 0) { + listbox.setSelectedIndex(0); + ListItem selected = listbox.getSelectedItem(); + if (selected == null) return null; + MenuItem item = selected.getValue(); + return item; + } else if (i+1 < listbox.getItemCount()) { + listbox.setSelectedIndex(i+1); + ListItem selected = listbox.getSelectedItem(); + if (selected == null) return null; + MenuItem item = selected.getValue(); + if (item == null) return null; + if ("...".equals(item.getType())) { + onSelect(selected, Boolean.FALSE); + } + Clients.scrollIntoView(selected); + return item; + } + return null; + } + + public boolean onOk(Textbox textbox) { + String text = textbox.getText(); + if (Util.isEmpty(text)) + return false; + text = text.toLowerCase(); + ListItem exact = null; + ListItem firstStart = null; + int count = listbox.getItemCount(); + for(int i = 0; i < count; i++) { + ListItem item = listbox.getItemAtIndex(i); + String label = item.getLabel(); + if (Util.isEmpty(label)) continue; + if (label.equalsIgnoreCase(text)) { + exact = item; + break; + } else if (firstStart == null && label.toLowerCase().startsWith(text) && text.length() >= 3) { + firstStart = item; + } + } + if (exact != null) { + textbox.setText(exact.getLabel()); + onSelect(exact, false); + return true; + } else if (firstStart != null) { + textbox.setText(firstStart.getLabel()); + onSelect(firstStart, false); + return true; + } + return false; + } + + private class MenuItemRenderer implements ListitemRenderer, ListitemRendererExt { + @Override + public Listitem newListitem(org.zkoss.zul.Listbox listbox) { + return new ListItem(); + } + + @Override + public Listcell newListcell(Listitem item) { + return new Listcell(item.getLabel()); + } + + @Override + public int getControls() { + return ListitemRendererExt.DETACH_ON_RENDER; + } + + @Override + public void render(Listitem item, MenuItem data, int index) + throws Exception { + Listcell cell = new Listcell(data.getLabel(), data.getImage()); + item.appendChild(cell); + cell.setTooltip(data.getDescription()); + item.setValue(data); + item.addEventListener(Events.ON_CLICK, MenuSearchController.this); + + cell = new Listcell(); + item.appendChild(cell); + boolean isWindow = data.getType() != null && data.getType().equals("window"); + if (isWindow) { + Toolbarbutton newBtn = new Toolbarbutton(null, ThemeManager.getThemeResource("images/New16.png")); + newBtn.addEventListener(Events.ON_CLICK, MenuSearchController.this); + newBtn.setSclass("fav-new-btn"); + newBtn.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "New"))); + cell.appendChild(newBtn); + } + } + + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java index 83c80d4ae8..12c7b27dfb 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java @@ -144,6 +144,7 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi dialogContent.setHflex("1"); dialogContent.setVflex("1"); dialogContent.setSclass("dialog-content"); + dialogContent.setStyle("overflow-y: auto;"); dialogBody.appendChild(dialogContent); Div div = new Div(); div.setId("message"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java index 81d8560fb4..4954a72ed6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java @@ -795,6 +795,9 @@ public class ProcessParameterPanel extends Panel implements editor.setMandatory(mField.isMandatory(true)); editor.updateLabelStyle(); } + if (getParent() != null) { + getParent().invalidate(); + } } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java index 72455afab2..269f59d9e5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java @@ -23,6 +23,7 @@ import java.text.ParseException; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.theme.ThemeManager; +import org.compiere.model.MSysConfig; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.zkoss.zk.ui.Page; @@ -47,7 +48,7 @@ public class NumberBox extends Div /** * */ - private static final long serialVersionUID = -3548087521669052891L; + private static final long serialVersionUID = 8543853599051754172L; private Textbox txtCalc = new Textbox(); @@ -84,7 +85,40 @@ public class NumberBox extends Div decimalBox.setStyle("display: inline-block;text-align:right"); decimalBox.setHflex("0"); decimalBox.setSclass("editor-input"); - appendChild(decimalBox); + decimalBox.setId(decimalBox.getUuid()); + + char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator(); + String separator = Character.toString(separatorChar); + boolean processDotKeypad = MSysConfig.getBooleanValue(MSysConfig.ZK_DECIMALBOX_PROCESS_DOTKEYPAD, true, Env.getAD_Client_ID(Env.getCtx())); + if (".".equals(separator)) + processDotKeypad = false; + if (processDotKeypad) { + StringBuffer funct = new StringBuffer(); + funct.append("function(evt)"); + funct.append("{"); + // ignore dot and process it on key up + funct.append(" if (!this._shallIgnore(evt, '0123456789-%").append(separator).append("'))"); + funct.append(" {"); + funct.append(" this.$doKeyPress_(evt);"); + funct.append(" }"); + funct.append("}"); + decimalBox.setWidgetOverride("doKeyPress_", funct.toString()); + funct = new StringBuffer(); + // not working correctly on opera + funct.append("if (window.event)"); + funct.append(" key = event.keyCode;"); + funct.append("else"); + funct.append(" key = event.which;"); + funct.append("if ((key == 110 || key == 190) && !window.opera) {"); + funct.append(" var id = '$'.concat('").append(decimalBox.getId()).append("');"); + funct.append(" var calcText = jq(id)[0];"); + funct.append(" calcText.value += '").append(separator).append("';"); + funct.append(" event.stop;"); + funct.append("};"); + decimalBox.setWidgetListener("onKeyUp", funct.toString()); + } + + appendChild(decimalBox); btn = new Button(); btn.setImage(ThemeManager.getThemeResource("images/Calculator16.png")); @@ -197,13 +231,35 @@ public class NumberBox extends Div Vbox vbox = new Vbox(); char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator(); + String separator = Character.toString(separatorChar); txtCalc = new Textbox(); decimalBox.setId(decimalBox.getUuid()); txtCalc.setId(txtCalc.getUuid()); - - txtCalc.setWidgetListener("onKeyUp", "return calc.validate('" + + + boolean processDotKeypad = MSysConfig.getBooleanValue(MSysConfig.ZK_DECIMALBOX_PROCESS_DOTKEYPAD, true, Env.getAD_Client_ID(Env.getCtx())); + if (".".equals(separator)) + processDotKeypad = false; + + // restrict allowed characters + String decimalSep = separator; + if (!processDotKeypad && !".".equals(separator)) + decimalSep += "."; + StringBuffer funct = new StringBuffer(); + funct.append("function(evt)"); + funct.append("{"); + funct.append(" if (!this._shallIgnore(evt, '= -/()*%+0123456789").append(decimalSep).append("'))"); + funct.append(" {"); + funct.append(" this.$doKeyPress_(evt);"); + funct.append(" }"); + funct.append("}"); + txtCalc.setWidgetOverride("doKeyPress_", funct.toString()); + + txtCalc.setWidgetListener("onKeyUp", "calc.validateUp('" + + decimalBox.getId() + "','" + txtCalc.getId() + + "'," + integral + "," + (int)separatorChar + ", event, " + ( processDotKeypad ? "true" : "false" ) + ");"); + txtCalc.setWidgetListener("onKeyPress", "calc.validatePress('" + decimalBox.getId() + "','" + txtCalc.getId() + "'," + integral + "," + (int)separatorChar + ", event);"); txtCalc.setMaxlength(250); @@ -323,7 +379,6 @@ public class NumberBox extends Div btn0.setLabel("0"); btn0.setWidgetListener("onClick", "calc.append('" + txtCalcId + "', '0')"); - String separator = Character.toString(separatorChar); Button btnDot = new Button(); btnDot.setWidth("30px"); btnDot.setLabel(separator); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPPerformance.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPPerformance.java index 55e5783883..c5f1b41d2f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPPerformance.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPPerformance.java @@ -15,6 +15,8 @@ package org.adempiere.webui.dashboard; import org.adempiere.webui.apps.graph.WPAPanel; import org.adempiere.webui.util.ServerPushTemplate; +import org.compiere.model.MSysConfig; +import org.compiere.util.Env; import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; @@ -81,9 +83,10 @@ public class DPPerformance extends DashboardPanel { removeAttribute(ON_POST_RENDER_ATTR); if (this.getFirstChild() != null) { + int timeout = MSysConfig.getIntValue(MSysConfig.ZK_DASHBOARD_PERFORMANCE_TIMEOUT, 500, Env.getAD_Client_ID(Env.getCtx())); Component grid = this.getFirstChild().getFirstChild(); String script = "setTimeout(function() { var grid = jq('#" + grid.getUuid() + "');"; - script = script + "grid.parent().height(grid.css('height'));}, 500);"; + script = script + "grid.parent().height(grid.css('height'));}, " + timeout + ");"; if (Executions.getCurrent() != null) Clients.response(new AuScript(script)); this.getFirstChild().invalidate(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAccountEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAccountEditor.java index 338685f90a..df35e6344f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAccountEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WAccountEditor.java @@ -80,6 +80,8 @@ public class WAccountEditor extends WEditor implements ContextMenuListener @Override public Object getValue() { + //if (m_mAccount.C_ValidCombination_ID == 0) + // return null; return new Integer (m_mAccount.C_ValidCombination_ID); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java index a294ad922d..4e1b324e99 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java @@ -235,7 +235,7 @@ public class WStringEditor extends WEditor implements ContextMenuListener else if (WEditorPopupMenu.EDITOR_EVENT.equals(evt.getContextEvent())) { adwindowContent = findADWindowContent(); - final WTextEditorDialog dialog = new WTextEditorDialog(this.getColumnName(), getDisplay(), + final WTextEditorDialog dialog = new WTextEditorDialog(gridField.getVO().Header, getDisplay(), isReadWrite(), gridField.getFieldLength()); dialog.addEventListener(DialogEvents.ON_WINDOW_CLOSE, new EventListener() { @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoBPartnerWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoBPartnerWindow.java index 1d2cce7b24..b33544e9fb 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoBPartnerWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoBPartnerWindow.java @@ -16,7 +16,7 @@ public class InfoBPartnerWindow extends InfoWindow { /** * */ - private static final long serialVersionUID = 126054851491958589L; + private static final long serialVersionUID = -5291476382115985651L; /** * @param WindowNo @@ -78,9 +78,12 @@ public class InfoBPartnerWindow extends InfoWindow { ih = null; } // showHistory + /** + * {@inheritDoc} + * set value of checkbox IsVendor and IsCustomer by IsSOTrx flag + */ @Override - protected void createParameterPanel() { - super.createParameterPanel(); + protected void initParameters() { String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx"); if (!isLookup() && Util.isEmpty(isSOTrx)) { isSOTrx = "Y"; @@ -88,6 +91,7 @@ public class InfoBPartnerWindow extends InfoWindow { if (!Util.isEmpty(isSOTrx)) { if ("Y".equals(isSOTrx)) { + // set value of IsCustomer checkbox for (WEditor editor : editors) { if (editor.getGridField() != null && editor.getGridField().getColumnName().equals("IsCustomer")) { editor.setValue("Y"); @@ -95,6 +99,7 @@ public class InfoBPartnerWindow extends InfoWindow { } } } else if ("N".equals(isSOTrx)) { + // set value of IsVendor checkbox for (WEditor editor : editors) { if (editor.getGridField() != null && editor.getGridField().getColumnName().equals("IsVendor")) { editor.setValue("Y"); @@ -103,7 +108,6 @@ public class InfoBPartnerWindow extends InfoWindow { } } } - dynamicDisplay(null); } @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInOutWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInOutWindow.java index 8636d9ac4b..a35bd83adc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInOutWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInOutWindow.java @@ -12,11 +12,10 @@ import org.compiere.util.Util; * */ public class InfoInOutWindow extends InfoWindow { - /** * */ - private static final long serialVersionUID = 3027121642718090785L; + private static final long serialVersionUID = 1687215125029008351L; /** * @param WindowNo @@ -51,14 +50,18 @@ public class InfoInOutWindow extends InfoWindow { whereClause, AD_InfoWindow_ID, lookup); } + /** + * {@inheritDoc} + * set value of checkbox isSoTrx + */ @Override - protected void createParameterPanel() { - super.createParameterPanel(); + protected void initParameters() { String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx"); if (!isLookup() && Util.isEmpty(isSOTrx)) { isSOTrx = "Y"; } + // set value of isSoTrx checkbox by env if (!Util.isEmpty(isSOTrx)) { for (WEditor editor : editors) { if (editor.getGridField() != null && editor.getGridField().getColumnName().equals("IsSOTrx")) { @@ -67,6 +70,6 @@ public class InfoInOutWindow extends InfoWindow { } } } - dynamicDisplay(null); } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInvoiceWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInvoiceWindow.java index 6a11dd6add..bc79bb8e0e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInvoiceWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoInvoiceWindow.java @@ -15,7 +15,7 @@ public class InfoInvoiceWindow extends InfoWindow { /** * */ - private static final long serialVersionUID = -5614659763247990639L; + private static final long serialVersionUID = -3169476148884310274L; /** * @param WindowNo @@ -50,9 +50,11 @@ public class InfoInvoiceWindow extends InfoWindow { whereClause, AD_InfoWindow_ID, lookup); } + /** + * {@inheritDoc} + */ @Override - protected void createParameterPanel() { - super.createParameterPanel(); + protected void initParameters() { String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx"); if (!isLookup() && Util.isEmpty(isSOTrx)) { isSOTrx = "Y"; @@ -77,7 +79,6 @@ public class InfoInvoiceWindow extends InfoWindow { } } } - dynamicDisplay(null); } @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoOrderWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoOrderWindow.java index e54f176f81..f77cdabc49 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoOrderWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoOrderWindow.java @@ -12,11 +12,10 @@ import org.compiere.util.Util; * */ public class InfoOrderWindow extends InfoWindow { - /** * */ - private static final long serialVersionUID = 1241927188305227636L; + private static final long serialVersionUID = -558954356627208290L; /** * @param WindowNo @@ -51,9 +50,11 @@ public class InfoOrderWindow extends InfoWindow { whereClause, AD_InfoWindow_ID, lookup); } + /** + * {@inheritDoc} + */ @Override - protected void createParameterPanel() { - super.createParameterPanel(); + protected void initParameters() { String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx"); if (!isLookup() && Util.isEmpty(isSOTrx)) { isSOTrx = "Y"; @@ -78,6 +79,5 @@ public class InfoOrderWindow extends InfoWindow { } } } - dynamicDisplay(null); } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeInstanceWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeInstanceWindow.java index 60669c6869..6b0ef55890 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeInstanceWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeInstanceWindow.java @@ -46,7 +46,7 @@ public class InfoPAttributeInstanceWindow extends InfoWindow { String whereClause, int AD_InfoWindow_ID, boolean lookup) { super(WindowNo, tableName, keyColumn, queryValue, multipleSelection, whereClause, AD_InfoWindow_ID, lookup); - // TODO Auto-generated constructor stub + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeWindow.java index 4f671fc942..2221ce2fa3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPAttributeWindow.java @@ -28,7 +28,7 @@ public class InfoPAttributeWindow extends InfoWindow { String whereClause, int AD_InfoWindow_ID) { super(WindowNo, tableName, keyColumn, queryValue, multipleSelection, whereClause, AD_InfoWindow_ID); - // TODO Auto-generated constructor stub + } /** @@ -46,7 +46,7 @@ public class InfoPAttributeWindow extends InfoWindow { String whereClause, int AD_InfoWindow_ID, boolean lookup) { super(WindowNo, tableName, keyColumn, queryValue, multipleSelection, whereClause, AD_InfoWindow_ID, lookup); - // TODO Auto-generated constructor stub + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPaymentWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPaymentWindow.java index 1e44708fa7..c26a791e67 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPaymentWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoPaymentWindow.java @@ -12,11 +12,10 @@ import org.compiere.util.Util; * */ public class InfoPaymentWindow extends InfoWindow { - /** * */ - private static final long serialVersionUID = 1322780214387328688L; + private static final long serialVersionUID = -3556977962189259779L; /** * @param WindowNo @@ -51,9 +50,11 @@ public class InfoPaymentWindow extends InfoWindow { whereClause, AD_InfoWindow_ID, lookup); } + /** + * {@inheritDoc} + */ @Override - protected void createParameterPanel() { - super.createParameterPanel(); + protected void initParameters() { String isSOTrx = Env.getContext(Env.getCtx(), p_WindowNo, "IsSOTrx"); if (!isLookup() && Util.isEmpty(isSOTrx)) { isSOTrx = "Y"; @@ -67,6 +68,5 @@ public class InfoPaymentWindow extends InfoWindow { } } } - dynamicDisplay(null); } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java index 075705c862..d9d9dd62e9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java @@ -51,7 +51,7 @@ public class InfoProductWindow extends InfoWindow { /** * */ - private static final long serialVersionUID = 4817648658129732541L; + private static final long serialVersionUID = -1343685368452976048L; private Tabbox tabbedPane; private WListbox warehouseTbl; @@ -136,15 +136,6 @@ public class InfoProductWindow extends InfoWindow { return prevWhereClause; } - @Override - protected void createParameterPanel() { - super.createParameterPanel(); - initParameters(); - dynamicDisplay(null); - // update display of mandatory field - validateParameters(); - } - @Override protected void renderWindow() { super.renderWindow(); @@ -445,7 +436,11 @@ public class InfoProductWindow extends InfoWindow { return 0; } - private void initParameters() { + /** + * {@inheritDoc} + */ + @Override + protected void initParameters() { int M_Warehouse_ID = Env.getContextAsInt(Env.getCtx(), p_WindowNo, "M_Warehouse_ID"); int M_PriceList_ID = Env.getContextAsInt(Env.getCtx(), p_WindowNo, "M_PriceList_ID"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index d20f83a99b..da3d70daec 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -96,7 +96,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL /** * */ - private static final long serialVersionUID = 5015742153094526149L; + private static final long serialVersionUID = 1913208136527058096L; protected Grid parameterGrid; private Borderlayout layout; @@ -1096,6 +1096,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } } evalDisplayLogic(); + initParameters(); + dynamicDisplay(null); } private void evalDisplayLogic() { @@ -1362,6 +1364,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL { if (otherEditor == editor) continue; + + // reset value of WInfoPAttributeEditor to null when change M_AttributeSet_ID if (asiChanged && otherEditor instanceof WInfoPAttributeEditor) ((WInfoPAttributeEditor)otherEditor).clearWhereClause(); @@ -1404,6 +1408,38 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } } + /** + * {@inheritDoc-} + */ + @Override + protected void resetParameters() { + // reset value of parameter to null, just reset display parameter + for (WEditor editor : editors) { + GridField gField = editor.getGridField(); + if (gField == null || !gField.isDisplayed()) { + continue; + } + + // just reset to default Field set explicit DefaultValue + Object resetValue = null; + if (! Util.isEmpty(gField.getVO().DefaultValue, true)) { + resetValue = gField.getDefault(); + } + Object oldValue = gField.getValue(); + gField.setValue(resetValue, true); + + // call valueChange to update env + ValueChangeEvent changeEvent = new ValueChangeEvent (editor, "", oldValue, resetValue); + valueChange (changeEvent); + } + + // init again parameter + initParameters(); + + // filter dynamic value + dynamicDisplay(null); + } + @Override public void onPageAttached(Page newpage, Page oldpage) { super.onPageAttached(newpage, oldpage); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java index 4135df2abf..35645176c3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java @@ -17,6 +17,8 @@ package org.adempiere.webui.panel; +import org.adempiere.webui.apps.GlobalSearch; +import org.adempiere.webui.apps.MenuSearchController; import org.adempiere.webui.component.Panel; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.window.AboutWindow; @@ -49,6 +51,8 @@ public class HeaderPanel extends Panel implements EventListener protected LabelImageElement btnMenu; protected Popup popMenu; + private MenuTreePanel menuTreePanel; + public HeaderPanel() { super(); @@ -62,9 +66,9 @@ public class HeaderPanel extends Panel implements EventListener image.addEventListener(Events.ON_CLICK, this); image.setStyle("cursor: pointer;"); - createSearchPanel(); - createPopupMenu(); + + createSearchPanel(); btnMenu = (LabelImageElement) getFellow("menuButton"); btnMenu.setLabel(Util.cleanAmp(Msg.getMsg(Env.getCtx(),"Menu"))); @@ -74,7 +78,7 @@ public class HeaderPanel extends Panel implements EventListener protected void createPopupMenu() { popMenu = new Popup(); popMenu.setId("menuTreePopup"); - new MenuTreePanel(popMenu); + menuTreePanel = new MenuTreePanel(popMenu); popMenu.setSclass("desktop-menu-popup"); popMenu.setHeight("90%"); popMenu.setWidth("600px"); @@ -82,11 +86,11 @@ public class HeaderPanel extends Panel implements EventListener } protected void createSearchPanel() { - MenuSearchPanel menuSearchPanel = new MenuSearchPanel(this); + GlobalSearch globalSearch = new GlobalSearch(new MenuSearchController(menuTreePanel.getMenuTree())); Component stub = getFellow("menuLookup"); - stub.getParent().insertBefore(menuSearchPanel, stub); + stub.getParent().insertBefore(globalSearch, stub); stub.detach(); - menuSearchPanel.setId("menuLookup"); + globalSearch.setId("menuLookup"); } public void onEvent(Event event) throws Exception { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index b0b7ca5dc0..4b19d07b6d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -62,6 +62,7 @@ import org.compiere.model.MInfoWindow; import org.compiere.model.MPInstance; import org.compiere.model.MProcess; import org.compiere.model.MRole; +import org.compiere.model.MSysConfig; import org.compiere.model.MTable; import org.compiere.model.X_AD_CtxHelp; import org.compiere.process.ProcessInfo; @@ -105,15 +106,16 @@ public abstract class InfoPanel extends Window implements EventListener, /** * */ - private static final long serialVersionUID = -6885406231649824253L; + private static final long serialVersionUID = -6257894588906175658L; - private final static int PAGE_SIZE = 100; + private final static int DEFAULT_PAGE_SIZE = 100; protected List