From 9eef8e0ca8661833adfa49e43262a1a9d4c612e2 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Sun, 4 Jun 2017 17:11:03 +0800 Subject: [PATCH] IDEMPIERE-3352 Enhancement of Batch Level Costing. --- .../oracle/201704201534_IDEMPIERE-3352.sql | 118 ++++++++ .../201704201534_IDEMPIERE-3352.sql | 117 ++++++++ .../process/InventoryCountCreate.java | 4 +- .../src/org/compiere/acct/Doc_InOut.java | 282 +++++++++++++++--- .../src/org/compiere/acct/Doc_Inventory.java | 104 ++++++- .../src/org/compiere/acct/Doc_Movement.java | 42 ++- .../src/org/compiere/acct/Doc_Production.java | 279 ++++++++++++++--- .../org/compiere/model/I_M_AttributeSet.java | 10 + .../compiere/model/MAttributeSetInstance.java | 24 ++ .../src/org/compiere/model/MCostDetail.java | 11 +- .../src/org/compiere/model/MInOut.java | 6 +- .../src/org/compiere/model/MInOutLine.java | 11 +- .../src/org/compiere/model/MInventory.java | 70 ++++- .../src/org/compiere/model/MProduction.java | 19 ++ .../org/compiere/model/MProductionLine.java | 124 +++++++- .../org/compiere/model/MProductionLineMA.java | 20 ++ .../org/compiere/model/MStorageOnHand.java | 24 +- .../src/org/compiere/model/ProductCost.java | 6 + .../org/compiere/model/X_M_AttributeSet.java | 23 +- .../webui/editor/WPAttributeEditor.java | 6 + 20 files changed, 1175 insertions(+), 125 deletions(-) create mode 100644 migration/i4.1/oracle/201704201534_IDEMPIERE-3352.sql create mode 100644 migration/i4.1/postgresql/201704201534_IDEMPIERE-3352.sql diff --git a/migration/i4.1/oracle/201704201534_IDEMPIERE-3352.sql b/migration/i4.1/oracle/201704201534_IDEMPIERE-3352.sql new file mode 100644 index 0000000000..ccc1a5bd44 --- /dev/null +++ b/migration/i4.1/oracle/201704201534_IDEMPIERE-3352.sql @@ -0,0 +1,118 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- Add IsAutoGenerateLot to M_AttributeSet. +-- Apr 20, 2017 3:34:42 PM SGT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203078,0,0,'Y',TO_DATE('2017-04-20 15:34:41','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 15:34:41','YYYY-MM-DD HH24:MI:SS'),100,'IsAutoGenerateLot','IsAutoGenerateLot','Auto Generate Lot','D','01487993-345a-4ddf-8da7-50d88581686b') +; + +-- Apr 20, 2017 3:37:18 PM SGT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (213024,0,'IsAutoGenerateLot',560,'IsAutoGenerateLot',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_DATE('2017-04-20 15:37:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 15:37:17','YYYY-MM-DD HH24:MI:SS'),100,203078,'Y','N','U','N','N','N','Y','ac7ab79e-7b73-48ac-ae20-bec945663a19','Y',0,'N','N') +; + +-- Apr 20, 2017 3:37:27 PM SGT +ALTER TABLE M_AttributeSet ADD IsAutoGenerateLot CHAR(1) DEFAULT 'N' CHECK (IsAutoGenerateLot IN ('Y','N')) +; + +-- Apr 20, 2017 3:37:50 PM SGT +UPDATE AD_Column SET DefaultValue='N',Updated=TO_DATE('2017-04-20 15:37:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213024 +; + +-- Apr 20, 2017 3:45:39 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (204432,'IsAutoGenerateLot',461,213024,'Y',0,220,0,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 15:45:38','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 15:45:38','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','9e9451eb-37c7-4766-9546-97bab80a2478','Y',210,2,2,1,'N','N','N') +; + +-- Apr 20, 2017 4:02:13 PM SGT +UPDATE AD_Field SET DisplayLogic='@IsLot@=Y& @M_LotCtl_ID@ > 0', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 16:02:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204432 +; + +-- Apr 20, 2017 4:06:48 PM SGT +INSERT INTO AD_Tab (AD_Tab_ID,Name,AD_Window_ID,SeqNo,IsSingleRow,AD_Table_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,HasTree,IsInfoTab,IsTranslationTab,IsReadOnly,Processing,ImportFields,TabLevel,IsSortTab,EntityType,IsInsertRecord,IsAdvancedTab,AD_Tab_UU,TreeDisplayedOn) VALUES (200224,'Attributes',53127,40,'Y',765,0,0,'Y',TO_DATE('2017-04-20 16:06:47','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:06:47','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N','N','N',0,'N','U','Y','N','9eced926-7d62-4fb8-9820-75039a2e9856','B') +; + +-- Apr 20, 2017 4:07:04 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (204433,'Client','Client/Tenant for this installation.','A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.',200224,13286,'Y',22,10,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:03','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','b69238c1-336d-48fb-977e-9a9191a1f849','N',2) +; + +-- Apr 20, 2017 4:07:04 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsAllowCopy,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204434,'Organization','Organizational entity within client','An organization is a unit of your client or legal entity - examples are store, department. You can share data between organizations.',200224,13285,'Y',22,20,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','24234f73-569c-499c-8209-f910b6f69050','Y','Y',10,4,2) +; + +-- Apr 20, 2017 4:07:05 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204435,'Attribute Set Instance','Product Attribute Set Instance','The values of the actual Product Attribute Instances. The product level attributes are defined on Product level.',200224,13287,'Y',22,30,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','e328aac8-688c-4229-8a7d-181ebf0e8a38','Y',20,2) +; + +-- Apr 20, 2017 4:07:06 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204436,'Production Line','Document Line representing a production','The Production Line indicates the production document line (if applicable) for this transaction',200224,13288,'Y',22,40,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:05','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:05','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','9d166382-f494-4a29-a01d-160b4621bd6e','Y',30,2) +; + +-- Apr 20, 2017 4:07:06 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204437,'Movement Quantity','Quantity of a product moved.','The Movement Quantity indicates the quantity of a product that has been moved.',200224,13289,'Y',22,50,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','50884b2d-9f35-4711-b80e-af2fe5bbe00a','Y',40,2) +; + +-- Apr 20, 2017 4:07:07 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (204438,'M_ProductionLineMA_UU',200224,60930,'N',36,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','5b9195b5-cb16-4e93-bbf5-b0631871e425','N',2) +; + +-- Apr 20, 2017 4:07:08 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204439,'Date Material Policy','Time used for LIFO and FIFO Material Policy','This field is used to record time used for LIFO and FIFO material policy',200224,210658,'Y',7,60,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:07','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:07','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','698b6efa-db36-4eb4-bc9d-411d34557bfb','Y',50,2) +; + +-- Apr 20, 2017 4:07:09 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204440,'Active','The record is active in the system','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.',200224,13284,'Y',1,70,'N','N','N','N',0,0,'Y',TO_DATE('2017-04-20 16:07:08','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2017-04-20 16:07:08','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','3dc9c715-7866-4b2c-ac0b-62cdd3620097','Y',60,2,2) +; + + +-- Apr 20, 2017 8:17:51 PM SGT +UPDATE AD_Tab SET DisplayLogic='@IsEndProduct@ =''N''',Updated=TO_DATE('2017-04-20 20:17:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:16 PM SGT +UPDATE AD_Tab SET EntityType='D',Updated=TO_DATE('2017-04-20 20:18:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:29 PM SGT +UPDATE AD_Tab SET TabLevel=2,Updated=TO_DATE('2017-04-20 20:18:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:47 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:18:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204433 +; + +-- Apr 20, 2017 8:18:50 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:18:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204434 +; + +-- Apr 20, 2017 8:18:54 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:18:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204435 +; + +-- Apr 20, 2017 8:18:56 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:18:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204436 +; + +-- Apr 20, 2017 8:18:59 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:18:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204437 +; + +-- Apr 20, 2017 8:19:03 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:19:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204439 +; + +-- Apr 20, 2017 8:19:06 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:19:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204440 +; + +-- Apr 20, 2017 8:20:05 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2017-04-20 20:20:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204432 +; + +-- Apr 20, 2017 8:20:21 PM SGT +UPDATE AD_Column SET EntityType='D',Updated=TO_DATE('2017-04-20 20:20:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213024 +; + +SELECT register_migration_script('201704201534_IDEMPIERE-3352.sql') FROM dual +; diff --git a/migration/i4.1/postgresql/201704201534_IDEMPIERE-3352.sql b/migration/i4.1/postgresql/201704201534_IDEMPIERE-3352.sql new file mode 100644 index 0000000000..3609cf6916 --- /dev/null +++ b/migration/i4.1/postgresql/201704201534_IDEMPIERE-3352.sql @@ -0,0 +1,117 @@ +-- Add IsAutoGenerateLot to M_AttributeSet. +-- Apr 20, 2017 3:34:42 PM SGT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203078,0,0,'Y',TO_TIMESTAMP('2017-04-20 15:34:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 15:34:41','YYYY-MM-DD HH24:MI:SS'),100,'IsAutoGenerateLot','IsAutoGenerateLot','Auto Generate Lot','D','01487993-345a-4ddf-8da7-50d88581686b') +; + +-- Apr 20, 2017 3:37:18 PM SGT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure) VALUES (213024,0,'IsAutoGenerateLot',560,'IsAutoGenerateLot',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2017-04-20 15:37:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 15:37:17','YYYY-MM-DD HH24:MI:SS'),100,203078,'Y','N','U','N','N','N','Y','ac7ab79e-7b73-48ac-ae20-bec945663a19','Y',0,'N','N') +; + +-- Apr 20, 2017 3:37:27 PM SGT +ALTER TABLE M_AttributeSet ADD COLUMN IsAutoGenerateLot CHAR(1) DEFAULT 'N' CHECK (IsAutoGenerateLot IN ('Y','N')) +; + +-- Apr 20, 2017 3:37:50 PM SGT +UPDATE AD_Column SET DefaultValue='N',Updated=TO_TIMESTAMP('2017-04-20 15:37:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213024 +; + + +-- Apr 20, 2017 3:45:39 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField) VALUES (204432,'IsAutoGenerateLot',461,213024,'Y',0,220,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 15:45:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 15:45:38','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','9e9451eb-37c7-4766-9546-97bab80a2478','Y',210,2,2,1,'N','N','N') +; + +-- Apr 20, 2017 4:02:13 PM SGT +UPDATE AD_Field SET DisplayLogic='@IsLot@=Y& @M_LotCtl_ID@ > 0', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 16:02:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204432 +; + +-- Apr 20, 2017 4:06:48 PM SGT +INSERT INTO AD_Tab (AD_Tab_ID,Name,AD_Window_ID,SeqNo,IsSingleRow,AD_Table_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,HasTree,IsInfoTab,IsTranslationTab,IsReadOnly,Processing,ImportFields,TabLevel,IsSortTab,EntityType,IsInsertRecord,IsAdvancedTab,AD_Tab_UU,TreeDisplayedOn) VALUES (200224,'Attributes',53127,40,'Y',765,0,0,'Y',TO_TIMESTAMP('2017-04-20 16:06:47','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:06:47','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N','N','N',0,'N','U','Y','N','9eced926-7d62-4fb8-9820-75039a2e9856','B') +; + +-- Apr 20, 2017 4:07:04 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (204433,'Client','Client/Tenant for this installation.','A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.',200224,13286,'Y',22,10,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:03','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:03','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','b69238c1-336d-48fb-977e-9a9191a1f849','N',2) +; + +-- Apr 20, 2017 4:07:04 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsAllowCopy,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204434,'Organization','Organizational entity within client','An organization is a unit of your client or legal entity - examples are store, department. You can share data between organizations.',200224,13285,'Y',22,20,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','24234f73-569c-499c-8209-f910b6f69050','Y','Y',10,4,2) +; + +-- Apr 20, 2017 4:07:05 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204435,'Attribute Set Instance','Product Attribute Set Instance','The values of the actual Product Attribute Instances. The product level attributes are defined on Product level.',200224,13287,'Y',22,30,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:04','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','e328aac8-688c-4229-8a7d-181ebf0e8a38','Y',20,2) +; + +-- Apr 20, 2017 4:07:06 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204436,'Production Line','Document Line representing a production','The Production Line indicates the production document line (if applicable) for this transaction',200224,13288,'Y',22,40,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:05','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:05','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','9d166382-f494-4a29-a01d-160b4621bd6e','Y',30,2) +; + +-- Apr 20, 2017 4:07:06 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204437,'Movement Quantity','Quantity of a product moved.','The Movement Quantity indicates the quantity of a product that has been moved.',200224,13289,'Y',22,50,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','50884b2d-9f35-4711-b80e-af2fe5bbe00a','Y',40,2) +; + +-- Apr 20, 2017 4:07:07 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (204438,'M_ProductionLineMA_UU',200224,60930,'N',36,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:06','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','5b9195b5-cb16-4e93-bbf5-b0631871e425','N',2) +; + +-- Apr 20, 2017 4:07:08 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (204439,'Date Material Policy','Time used for LIFO and FIFO Material Policy','This field is used to record time used for LIFO and FIFO material policy',200224,210658,'Y',7,60,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:07','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:07','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','698b6efa-db36-4eb4-bc9d-411d34557bfb','Y',50,2) +; + +-- Apr 20, 2017 4:07:09 PM SGT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (204440,'Active','The record is active in the system','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.',200224,13284,'Y',1,70,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2017-04-20 16:07:08','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2017-04-20 16:07:08','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','U','3dc9c715-7866-4b2c-ac0b-62cdd3620097','Y',60,2,2) +; + + +-- Apr 20, 2017 8:17:51 PM SGT +UPDATE AD_Tab SET DisplayLogic='@IsEndProduct@ =''N''',Updated=TO_TIMESTAMP('2017-04-20 20:17:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:16 PM SGT +UPDATE AD_Tab SET EntityType='D',Updated=TO_TIMESTAMP('2017-04-20 20:18:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:29 PM SGT +UPDATE AD_Tab SET TabLevel=2,Updated=TO_TIMESTAMP('2017-04-20 20:18:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200224 +; + +-- Apr 20, 2017 8:18:47 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:18:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204433 +; + +-- Apr 20, 2017 8:18:50 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:18:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204434 +; + +-- Apr 20, 2017 8:18:54 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:18:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204435 +; + +-- Apr 20, 2017 8:18:56 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:18:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204436 +; + +-- Apr 20, 2017 8:18:59 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:18:59','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204437 +; + +-- Apr 20, 2017 8:19:03 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:19:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204439 +; + +-- Apr 20, 2017 8:19:06 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:19:06','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204440 +; + +-- Apr 20, 2017 8:20:05 PM SGT +UPDATE AD_Field SET EntityType='D', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2017-04-20 20:20:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204432 +; + +-- Apr 20, 2017 8:20:21 PM SGT +UPDATE AD_Column SET EntityType='D',Updated=TO_TIMESTAMP('2017-04-20 20:20:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213024 +; + +SELECT register_migration_script('201704201534_IDEMPIERE-3352.sql') FROM dual +; + diff --git a/org.adempiere.base.process/src/org/compiere/process/InventoryCountCreate.java b/org.adempiere.base.process/src/org/compiere/process/InventoryCountCreate.java index 6dd0c99664..da75a0c128 100644 --- a/org.adempiere.base.process/src/org/compiere/process/InventoryCountCreate.java +++ b/org.adempiere.base.process/src/org/compiere/process/InventoryCountCreate.java @@ -296,7 +296,7 @@ public class InventoryCountCreate extends SvrProcess return 0; } // Save Old Line info - else if (m_line.getM_AttributeSetInstance_ID() != 0 || oldDateMPolicy != null) + else if (m_line.getM_AttributeSetInstance_ID() != 0 ) { MInventoryLineMA ma = new MInventoryLineMA (m_line, m_line.getM_AttributeSetInstance_ID(), m_line.getQtyBook(),oldDateMPolicy,true); @@ -317,7 +317,7 @@ public class InventoryCountCreate extends SvrProcess } // new line m_line = new MInventoryLine (m_inventory, M_Locator_ID, - M_Product_ID, 0, + M_Product_ID, M_AttributeSetInstance_ID, QtyOnHand, QtyOnHand); // book/count oldDateMPolicy = dateMPolicy; diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java b/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java index e9fb2fd1e8..febb500934 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_InOut.java @@ -33,6 +33,7 @@ import org.compiere.model.MAcctSchema; import org.compiere.model.MCostDetail; import org.compiere.model.MInOut; import org.compiere.model.MInOutLine; +import org.compiere.model.MInOutLineMA; import org.compiere.model.MOrderLine; import org.compiere.model.MProduct; import org.compiere.model.ProductCost; @@ -175,10 +176,40 @@ public class Doc_InOut extends Doc BigDecimal costs = null; if (!isReversal(line)) { - // MZ Goodwill - // if Shipment CostDetail exist then get Cost from Cost Detail - costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); - + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInOutLine ioLine = (MInOutLine) line.getPO(); + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), ioLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + costs = BigDecimal.ZERO; + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + BigDecimal QtyMA = ma.getMovementQty(); + ProductCost pc = line.getProductCost(); + pc.setQty(QtyMA); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + BigDecimal maCosts = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + + costs = costs.add(maCosts); + } + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + } + } + else + { + // MZ Goodwill + // if Shipment CostDetail exist then get Cost from Cost Detail + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + } + // end MZ if (costs == null || costs.signum() == 0) // zero costs OK { @@ -264,17 +295,60 @@ public class Doc_InOut extends Doc } costs = cr.getAcctBalance(); //get original cost } - // - if (line.getM_Product_ID() != 0) - { - if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), - line.get_ID(), 0, - costs, line.getQty(), - line.getDescription(), true, getTrxName())) + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) { - p_Error = "Failed to create cost detail record"; - return null; + MInOutLine ioLine = (MInOutLine) line.getPO(); + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), ioLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, ma.getMovementQty().negate(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + } + else + { + // + if (line.getM_Product_ID() != 0) + { + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + } + else + { + // + if (line.getM_Product_ID() != 0) + { + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } } } } // for all lines @@ -303,11 +377,40 @@ public class Doc_InOut extends Doc BigDecimal costs = null; if (!isReversal(line)) { - // MZ Goodwill - // if Shipment CostDetail exist then get Cost from Cost Detail - costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); - // end MZ - + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInOutLine ioLine = (MInOutLine) line.getPO(); + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), ioLine.get_ID(), getTrxName()); + costs = BigDecimal.ZERO; + if (mas != null && mas.length > 0 ) + { + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + BigDecimal QtyMA = ma.getMovementQty(); + ProductCost pc = line.getProductCost(); + pc.setQty(QtyMA); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + BigDecimal maCosts = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + + costs = costs.add(maCosts); + } + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + } + } + else + { + // MZ Goodwill + // if Shipment CostDetail exist then get Cost from Cost Detail + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + // end MZ + } if (costs == null || costs.signum() == 0) // zero costs OK { if (product.isStocked()) @@ -353,16 +456,57 @@ public class Doc_InOut extends Doc costs = dr.getAcctBalance(); //get original cost } // - if (line.getM_Product_ID() != 0) - { - if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), - line.get_ID(), 0, - costs, line.getQty(), - line.getDescription(), true, getTrxName())) + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) { - p_Error = "Failed to create cost detail record"; - return null; + MInOutLine ioLine = (MInOutLine) line.getPO(); + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), ioLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, ma.getMovementQty(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + } else + { + if (line.getM_Product_ID() != 0) + { + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + } else + { + // + if (line.getM_Product_ID() != 0) + { + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + line.getDescription(), true, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } } } @@ -427,7 +571,8 @@ public class Doc_InOut extends Doc //get costing method for product if (MAcctSchema.COSTINGMETHOD_AveragePO.equals(costingMethod) || MAcctSchema.COSTINGMETHOD_AverageInvoice.equals(costingMethod) || - MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) ) + MAcctSchema.COSTINGMETHOD_LastPOPrice.equals(costingMethod) || + ( MAcctSchema.COSTINGMETHOD_StandardCosting.equals(costingMethod) && MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)))) { // Low - check if c_orderline_id is valid if (orderLine != null) @@ -639,13 +784,43 @@ public class Doc_InOut extends Doc } else { - costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs - } - if (costs == null || costs.signum() == 0) - { - p_Error = "Resubmit - No Costs for " + product.getName(); - log.log(Level.WARNING, p_Error); - return null; + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), ioLine.get_ID(), getTrxName()); + costs = BigDecimal.ZERO; + if (mas != null && mas.length > 0 ) + { + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + BigDecimal QtyMA = ma.getMovementQty(); + ProductCost pc = line.getProductCost(); + pc.setQty(QtyMA); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + BigDecimal maCosts = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InOutLine_ID=?"); + + costs = costs.add(maCosts); + } + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), false); // current costs + } + + if (costs == null || costs.signum() == 0) + { + p_Error = "Resubmit - No Costs for " + product.getName(); + log.log(Level.WARNING, p_Error); + return null; + } } } else @@ -749,11 +924,38 @@ public class Doc_InOut extends Doc { tAmt = tAmt.negate(); } - if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), - line.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, tQty, - line.getDescription(), false, getTrxName())) + MProduct product = line.getProduct(); + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInOutLineMA mas[] = MInOutLineMA.get(getCtx(), line.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + for (int j = 0; j < mas.length; j++) + { + MInOutLineMA ma = mas[j]; + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), + ma.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, ma.getMovementQty().negate(), + line.getDescription(), false, getTrxName())) + return "SaveError"; + } + } + } + else + { + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), + line.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, tQty, + line.getDescription(), false, getTrxName())) + return "SaveError"; + } + } + else { - return "SaveError"; + if (!MCostDetail.createShipment(as, line.getAD_Org_ID(), line.getM_Product_ID(), + line.getM_AttributeSetInstance_ID(), line.get_ID(), 0, tAmt, tQty, + line.getDescription(), false, getTrxName())) + return "SaveError"; } return ""; } diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_Inventory.java b/org.adempiere.base/src/org/compiere/acct/Doc_Inventory.java index 7b14efd797..a819e82fcb 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_Inventory.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_Inventory.java @@ -19,6 +19,7 @@ package org.compiere.acct; import java.math.BigDecimal; import java.sql.ResultSet; import java.util.ArrayList; +import java.util.HashMap; import java.util.logging.Level; import org.compiere.model.MAccount; @@ -30,6 +31,7 @@ import org.compiere.model.MCostElement; import org.compiere.model.MDocType; import org.compiere.model.MInventory; import org.compiere.model.MInventoryLine; +import org.compiere.model.MInventoryLineMA; import org.compiere.model.MProduct; import org.compiere.model.ProductCost; import org.compiere.util.DB; @@ -182,7 +184,7 @@ public class Doc_Inventory extends Doc MInventory inventory = (MInventory) getPO(); boolean costAdjustment = MDocType.DOCSUBTYPEINV_CostAdjustment.equals(parentDocSubTypeInv); String docCostingMethod = inventory.getCostingMethod(); - + HashMap costMap = new HashMap(); for (int i = 0; i < p_lines.length; i++) { DocLine line = p_lines[i]; @@ -213,6 +215,7 @@ public class Doc_Inventory extends Doc if (costAdjustment) { costs = line.getAmtSource(); + product = line.getProduct(); int orgId = line.getAD_Org_ID(); int asiId = line.getM_AttributeSetInstance_ID(); if (MAcctSchema.COSTINGLEVEL_Client.equals(costingLevel)) @@ -236,10 +239,42 @@ public class Doc_Inventory extends Doc { if (!isReversal(line)) { - // MZ Goodwill - // if Physical Inventory CostDetail is exist then get Cost from Cost Detail - costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?"); - // end MZ + product = line.getProduct(); + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInventoryLine invLine = (MInventoryLine) line.getPO(); + MInventoryLineMA mas[] = MInventoryLineMA.get(getCtx(), invLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + costs = BigDecimal.ZERO; + for (int j = 0; j < mas.length; j++) + { + MInventoryLineMA ma = mas[j]; + BigDecimal QtyMA = ma.getMovementQty(); + ProductCost pc = line.getProductCost(); + pc.setQty(QtyMA.negate()); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + BigDecimal maCosts = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?"); + costMap.put(line.get_ID()+ "_"+ ma.getM_AttributeSetInstance_ID(), maCosts); + + costs = costs.add(maCosts); + } + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?"); + } + } + else + { + // MZ Goodwill + // if Physical Inventory CostDetail is exist then get Cost from Cost Detail + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_InventoryLine_ID=?"); + // end MZ + } if (costs == null || costs.signum() == 0) { p_Error = "No Costs for " + line.getProduct().getName(); @@ -322,6 +357,7 @@ public class Doc_Inventory extends Doc if (doPosting || costAdjustment) { + product = line.getProduct(); BigDecimal costDetailAmt = costAdjustment ? adjustmentDiff : costs; if (costAdjustment && getC_Currency_ID() > 0 && getC_Currency_ID() != as.getC_Currency_ID()) { @@ -329,15 +365,57 @@ public class Doc_Inventory extends Doc costDetailAmt, getC_Currency_ID(), as.getC_Currency_ID(), getDateAcct(), 0, getAD_Client_ID(), getAD_Org_ID(), true); } - // Cost Detail - if (!MCostDetail.createInventory(as, line.getAD_Org_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), - line.get_ID(), 0, - costDetailAmt, line.getQty(), - line.getDescription(), getTrxName())) + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(as)) ) { - p_Error = "Failed to create cost detail record"; - return null; + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MInventoryLine invLine = (MInventoryLine) line.getPO(); + MInventoryLineMA mas[] = MInventoryLineMA.get(getCtx(), invLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + costs = BigDecimal.ZERO; + for (int j = 0; j < mas.length; j++) + { + MInventoryLineMA ma = mas[j]; + BigDecimal maCost = costMap.get(line.get_ID()+ "_"+ ma.getM_AttributeSetInstance_ID()); + + if (!MCostDetail.createInventory(as, line.getAD_Org_ID(), + line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + maCost, ma.getMovementQty().negate(), + line.getDescription(), getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + } + else + { + if (!MCostDetail.createInventory(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costDetailAmt, line.getQty(), + line.getDescription(), getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + else + { + // Cost Detail + if (!MCostDetail.createInventory(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costDetailAmt, line.getQty(), + line.getDescription(), getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } } } } diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_Movement.java b/org.adempiere.base/src/org/compiere/acct/Doc_Movement.java index 039ebf82a9..1d26b0096e 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_Movement.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_Movement.java @@ -25,6 +25,8 @@ import org.compiere.model.MAcctSchema; import org.compiere.model.MCostDetail; import org.compiere.model.MMovement; import org.compiere.model.MMovementLine; +import org.compiere.model.MMovementLineMA; +import org.compiere.model.MProduct; import org.compiere.model.ProductCost; import org.compiere.util.Env; @@ -137,10 +139,42 @@ public class Doc_Movement extends Doc if (!isReversal(line)) { - // MZ Goodwill - // if Inventory Move CostDetail exist then get Cost from Cost Detail - costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'"); - // end MZ + MProduct product = (MProduct) line.getProduct(); + String costingLevel = product.getCostingLevel(as); + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(costingLevel) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 ) + { + MMovementLine mLine = (MMovementLine) line.getPO(); + MMovementLineMA mas[] = MMovementLineMA.get(getCtx(), mLine.get_ID(), getTrxName()); + if (mas != null && mas.length > 0 ) + { + costs = BigDecimal.ZERO; + for (int j = 0; j < mas.length; j++) + { + MMovementLineMA ma = mas[j]; + BigDecimal QtyMA = ma.getMovementQty(); + ProductCost pc = line.getProductCost(); + pc.setQty(QtyMA); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + BigDecimal maCosts = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'"); + + costs = costs.add(maCosts); + } + } + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'"); + } + } + else + { + // MZ Goodwill + // if Inventory Move CostDetail exist then get Cost from Cost Detail + costs = line.getProductCosts(as, line.getAD_Org_ID(), true, "M_MovementLine_ID=? AND IsSOTrx='N'"); + // end MZ + } } else { diff --git a/org.adempiere.base/src/org/compiere/acct/Doc_Production.java b/org.adempiere.base/src/org/compiere/acct/Doc_Production.java index 91edc1d9ae..23eb0c210a 100644 --- a/org.adempiere.base/src/org/compiere/acct/Doc_Production.java +++ b/org.adempiere.base/src/org/compiere/acct/Doc_Production.java @@ -26,6 +26,8 @@ import java.util.logging.Level; import org.compiere.model.MAcctSchema; import org.compiere.model.MCostDetail; +import org.compiere.model.MProduct; +import org.compiere.model.MProductionLineMA; import org.compiere.model.ProductCost; import org.compiere.model.X_M_Production; import org.compiere.model.X_M_ProductionLine; @@ -200,28 +202,83 @@ public class Doc_Production extends Doc // Line pointer FactLine fl = null; X_M_Production prod = (X_M_Production)getPO(); + HashMap costMap = new HashMap(); + for (int i = 0; i < p_lines.length; i++) { DocLine line = p_lines[i]; // Calculate Costs - BigDecimal costs = null; + BigDecimal costs = BigDecimal.ZERO; + + X_M_ProductionLine prodline = (X_M_ProductionLine)line.getPO(); + MProductionLineMA mas[] = MProductionLineMA.get(getCtx(), prodline.get_ID(), getTrxName()); + MProduct product = (MProduct) prodline.getM_Product(); + String CostingLevel = product.getCostingLevel(as); + + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel) ) + { + if (line.getM_AttributeSetInstance_ID() == 0 && (mas!=null && mas.length> 0 )) + { + for (int j = 0; j < mas.length; j++) + { + MProductionLineMA ma = mas[j]; + MCostDetail cd = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line.get_ID(), ma.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + if (cd != null) + costs = costs.add(cd.getAmt()); + else + { + ProductCost pc = line.getProductCost(); + pc.setQty(ma.getMovementQty()); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + costs = costs.add(line.getProductCosts(as, line.getAD_Org_ID(), false)); + } + costMap.put(line.get_ID()+ "_"+ ma.getM_AttributeSetInstance_ID(), costs); + } + } + else + { + MCostDetail cd = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line.get_ID(), line.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + if (cd != null) + { + costs = cd.getAmt(); + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), false); + } + costMap.put(line.get_ID()+ "_"+ line.getM_AttributeSetInstance_ID(), costs); + } + + } + else + { + + // MZ Goodwill + // if Production CostDetail exist then get Cost from Cost Detail + MCostDetail cd = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line.get_ID(), line.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + if (cd != null) + { + costs = cd.getAmt(); + } + else + { + costs = line.getProductCosts(as, line.getAD_Org_ID(), false); + } + costMap.put(line.get_ID()+ "_"+ line.getM_AttributeSetInstance_ID(), costs); - // MZ Goodwill - // if Production CostDetail exist then get Cost from Cost Detail - MCostDetail cd = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", - line.get_ID(), line.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); - if (cd != null) { - costs = cd.getAmt(); - } else { - costs = line.getProductCosts(as, line.getAD_Org_ID(), false); } + + BigDecimal bomCost = Env.ZERO; + BigDecimal qtyProduced = null; if (line.isProductionBOM()) { X_M_ProductionLine endProLine = (X_M_ProductionLine)line.getPO(); Object parentEndPro = prod.isUseProductionPlan()?endProLine.getM_ProductionPlan_ID():endProLine.getM_Production_ID(); - // Get BOM Cost - Sum of individual lines - BigDecimal bomCost = Env.ZERO; + // Get BOM Cost - Sum of individual lines for (int ii = 0; ii < p_lines.length; ii++) { DocLine line0 = p_lines[ii]; @@ -231,55 +288,137 @@ public class Doc_Production extends Doc if (!parentBomPro.equals(parentEndPro)) continue; if (!line0.isProductionBOM()) { + MProduct product0 = (MProduct) bomProLine.getM_Product(); + String CostingLevel0 = product0.getCostingLevel(as); + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel0) ) + { + if (bomProLine.getM_AttributeSetInstance_ID() == 0 ) + { + MProductionLineMA bomLineMA[] = MProductionLineMA.get(getCtx(), line0.get_ID(), getTrxName()); + if (bomLineMA!=null && bomLineMA.length> 0 ) + { + // get cost of children for batch costing level (auto generate) + BigDecimal costs0 = BigDecimal.ZERO ; + for (int j = 0; j < bomLineMA.length; j++) + { + BigDecimal maCost = BigDecimal.ZERO ; + MProductionLineMA ma = bomLineMA[j]; + // get cost of children + MCostDetail cd0 = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line0.get_ID(), ma.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + if (cd0 != null) + maCost = cd0.getAmt(); + else + { + ProductCost pc = line0.getProductCost(); + pc.setQty(ma.getMovementQty()); + pc.setM_M_AttributeSetInstance_ID(ma.getM_AttributeSetInstance_ID()); + maCost = line0.getProductCosts(as, line0.getAD_Org_ID(), false); + } + costMap.put(line0.get_ID()+ "_"+ ma.getM_AttributeSetInstance_ID(),maCost); + costs0 = costs0.add(maCost); + } + bomCost = bomCost.add(costs0.setScale(2,BigDecimal.ROUND_HALF_UP)); + } + else + p_Error = "Failed to post - No Attribute Set for line"; + + } + else + { + // get cost of children for batch costing level + MCostDetail cd0 = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line0.get_ID(), line0.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + BigDecimal costs0; + if (cd0 != null) + { + costs0 = cd0.getAmt(); + } + else + { + costs0 = line0.getProductCosts(as, line0.getAD_Org_ID(), false); + } + costMap.put(line0.get_ID()+ "_"+ line0.getM_AttributeSetInstance_ID(),costs0); + bomCost = bomCost.add(costs0.setScale(2,BigDecimal.ROUND_HALF_UP)); + } + + } + else + { // get cost of children - MCostDetail cd0 = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", - line0.get_ID(), line0.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); - BigDecimal costs0; - if (cd0 != null) { - costs0 = cd0.getAmt(); - } else { - costs0 = line0.getProductCosts(as, line0.getAD_Org_ID(), false); + MCostDetail cd0 = MCostDetail.get (as.getCtx(), "M_ProductionLine_ID=?", + line0.get_ID(), line0.getM_AttributeSetInstance_ID(), as.getC_AcctSchema_ID(), getTrxName()); + BigDecimal costs0; + if (cd0 != null) + { + costs0 = cd0.getAmt(); + } + else + { + costs0 = line0.getProductCosts(as, line0.getAD_Org_ID(), false); + } + costMap.put(line0.get_ID()+ "_"+ line0.getM_AttributeSetInstance_ID(),costs0); + bomCost = bomCost.add(costs0.setScale(2,BigDecimal.ROUND_HALF_UP)); } - bomCost = bomCost.add(costs0.setScale(2,BigDecimal.ROUND_HALF_UP)); } } - BigDecimal qtyProduced = manipulateQtyProduced (mQtyProduced, endProLine, prod.isUseProductionPlan(), null); - if (line.getQty().compareTo(qtyProduced) != 0) { + qtyProduced = manipulateQtyProduced (mQtyProduced, endProLine, prod.isUseProductionPlan(), null); + if (line.getQty().compareTo(qtyProduced) != 0) + { BigDecimal factor = line.getQty().divide(qtyProduced, 12, BigDecimal.ROUND_HALF_UP); bomCost = bomCost.multiply(factor).setScale(2,BigDecimal.ROUND_HALF_UP); } - int precision = as.getStdPrecision(); - BigDecimal variance = (costs.setScale(precision, BigDecimal.ROUND_HALF_UP)).subtract(bomCost.negate()); - // only post variance if it's not zero - if (variance.signum() != 0) + + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel)) { - //post variance + //post roll-up fl = fact.createLine(line, - line.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as), - as.getC_Currency_ID(), variance.negate()); + line.getAccount(ProductCost.ACCTTYPE_P_Asset, as), + as.getC_Currency_ID(), bomCost.negate()); if (fl == null) { - p_Error = "Couldn't post variance " + line.getLine() + " - " + line; + p_Error = "Couldn't post roll-up " + line.getLine() + " - " + line; return null; } - fl.setQty(Env.ZERO); + fl.setQty(qtyProduced); + } + else + { + int precision = as.getStdPrecision(); + BigDecimal variance = (costs.setScale(precision, BigDecimal.ROUND_HALF_UP)).subtract(bomCost.negate()); + // only post variance if it's not zero + if (variance.signum() != 0) + { + //post variance + fl = fact.createLine(line, + line.getAccount(ProductCost.ACCTTYPE_P_RateVariance, as), + as.getC_Currency_ID(), variance.negate()); + if (fl == null) + { + p_Error = "Couldn't post variance " + line.getLine() + " - " + line; + return null; + } + fl.setQty(Env.ZERO); + } } - // costs = bomCost.negate(); } // end MZ // Inventory DR CR - fl = fact.createLine(line, - line.getAccount(ProductCost.ACCTTYPE_P_Asset, as), - as.getC_Currency_ID(), costs); - if (fl == null) + if (!(line.isProductionBOM() && MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel))) { - p_Error = "No Costs for Line " + line.getLine() + " - " + line; - return null; + fl = fact.createLine(line, + line.getAccount(ProductCost.ACCTTYPE_P_Asset, as), + as.getC_Currency_ID(), costs); + if (fl == null) + { + p_Error = "No Costs for Line " + line.getLine() + " - " + line; + return null; + } + fl.setM_Locator_ID(line.getM_Locator_ID()); + fl.setQty(line.getQty()); } - fl.setM_Locator_ID(line.getM_Locator_ID()); - fl.setQty(line.getQty()); // Cost Detail String description = line.getDescription(); @@ -287,14 +426,62 @@ public class Doc_Production extends Doc description = ""; if (line.isProductionBOM()) description += "(*)"; - if (!MCostDetail.createProduction(as, line.getAD_Org_ID(), - line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), - line.get_ID(), 0, - costs, line.getQty(), - description, getTrxName())) + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(CostingLevel)) { - p_Error = "Failed to create cost detail record"; - return null; + if (line.isProductionBOM()) + { + if (!MCostDetail.createProduction(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + bomCost.negate(), qtyProduced, + description, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + else if (line.getM_AttributeSetInstance_ID() == 0 && (mas!=null && mas.length> 0 )) + { + for (int j = 0; j < mas.length; j++) + { + MProductionLineMA ma = mas[j]; + BigDecimal maCost = costMap.get(line.get_ID()+ "_"+ ma.getM_AttributeSetInstance_ID()); + if (!MCostDetail.createProduction(as, line.getAD_Org_ID(), + line.getM_Product_ID(), ma.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + maCost, ma.getMovementQty(), + description, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + else + { + + if (!MCostDetail.createProduction(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + description, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } + } + } + else + { + if (!MCostDetail.createProduction(as, line.getAD_Org_ID(), + line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), + line.get_ID(), 0, + costs, line.getQty(), + description, getTrxName())) + { + p_Error = "Failed to create cost detail record"; + return null; + } } } // diff --git a/org.adempiere.base/src/org/compiere/model/I_M_AttributeSet.java b/org.adempiere.base/src/org/compiere/model/I_M_AttributeSet.java index fbcd637548..e015c3dd3e 100644 --- a/org.adempiere.base/src/org/compiere/model/I_M_AttributeSet.java +++ b/org.adempiere.base/src/org/compiere/model/I_M_AttributeSet.java @@ -362,4 +362,14 @@ public interface I_M_AttributeSet /** Get Use Guarantee Date for Material Policy */ public boolean isUseGuaranteeDateForMPolicy(); + + /** Column name IsAutoGenerateLot */ + public static final String COLUMNNAME_IsAutoGenerateLot = "IsAutoGenerateLot"; + + /** Set Auto Generate Lot */ + public void setIsAutoGenerateLot (boolean IsAutoGenerateLot); + + /** Get Auto Generate Lot */ + public boolean isAutoGenerateLot(); + } diff --git a/org.adempiere.base/src/org/compiere/model/MAttributeSetInstance.java b/org.adempiere.base/src/org/compiere/model/MAttributeSetInstance.java index a5c5a756bf..07d2865f76 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttributeSetInstance.java +++ b/org.adempiere.base/src/org/compiere/model/MAttributeSetInstance.java @@ -407,4 +407,28 @@ public class MAttributeSetInstance extends X_M_AttributeSetInstance asi.saveEx(); return asi; } + + /** + * AutoGerate & save a new ASI for given product. + * Automatically creates Lot# + * @param ctx + * @param product + * @param trxName + * @return newly created ASI + */ + public static MAttributeSetInstance generateLot(Properties ctx, MProduct product, String trxName) + { + MAttributeSetInstance asi = new MAttributeSetInstance(ctx, 0, trxName); + asi.setClientOrg(product.getAD_Client_ID(), 0); + asi.setM_AttributeSet_ID(product.getM_AttributeSet_ID()); + // Create new Lot + if (asi.getM_AttributeSet_ID() > 0) + { + asi.getLot(true, product.get_ID()); + } + // + asi.setDescription(); + asi.saveEx(); + return asi; + } } // MAttributeSetInstance diff --git a/org.adempiere.base/src/org/compiere/model/MCostDetail.java b/org.adempiere.base/src/org/compiere/model/MCostDetail.java index 24586d8816..21c10d75e7 100644 --- a/org.adempiere.base/src/org/compiere/model/MCostDetail.java +++ b/org.adempiere.base/src/org/compiere/model/MCostDetail.java @@ -1263,7 +1263,11 @@ public class MCostDetail extends X_M_CostDetail } else if (addition) { - cost.add(amt, qty); + if (getM_ProductionLine().getM_Production().getReversal_ID() < 0) + cost.add(amt, qty); + else + cost.setCurrentQty(cost.getCurrentQty().add(qty)); + // Initial if (cost.getCurrentCostPrice().signum() == 0 && cost.getCurrentCostPriceLL().signum() == 0 @@ -1292,6 +1296,11 @@ public class MCostDetail extends X_M_CostDetail { //Should not happen if (log.isLoggable(Level.FINER)) log.finer("QtyAdjust - ?none? - " + cost); + } + else if (ce.isStandardCosting() && isVendorRMA) + { + cost.add(amt, qty); + } else log.warning("QtyAdjust - " + ce + " - " + cost); diff --git a/org.adempiere.base/src/org/compiere/model/MInOut.java b/org.adempiere.base/src/org/compiere/model/MInOut.java index d21cdc948b..1cf1caa7df 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOut.java +++ b/org.adempiere.base/src/org/compiere/model/MInOut.java @@ -1848,9 +1848,9 @@ public class MInOut extends X_M_InOut implements DocAction MInOutLineMA shipmentMAS[] = MInOutLineMA.getNonReturned(getCtx(), rmaLine.getM_InOutLine_ID(), get_TrxName()); for(MInOutLineMA sMA : shipmentMAS){ - BigDecimal lineMAQty = qtyToReturn; - if(lineMAQty.compareTo(Env.ZERO)>0){ - lineMAQty = Env.ZERO; + BigDecimal lineMAQty = sMA.getMovementQty(); + if(lineMAQty.compareTo(qtyToReturn)>0){ + lineMAQty = qtyToReturn; } MInOutLineMA ma = MInOutLineMA.addOrCreate(line, sMA.getM_AttributeSetInstance_ID(), lineMAQty, sMA.getDateMaterialPolicy(),true); diff --git a/org.adempiere.base/src/org/compiere/model/MInOutLine.java b/org.adempiere.base/src/org/compiere/model/MInOutLine.java index 4ed8de1cb5..7c97b18f4e 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOutLine.java +++ b/org.adempiere.base/src/org/compiere/model/MInOutLine.java @@ -578,7 +578,16 @@ public class MInOutLine extends X_M_InOutLine } } - + I_M_AttributeSet attributeset = getM_Product().getM_AttributeSet(); + boolean isAutoGenerateLot = false; + if (attributeset != null) + isAutoGenerateLot = attributeset.isAutoGenerateLot(); + if (getReversalLine_ID() == 0 && !getParent().isSOTrx() && !getParent().getMovementType().equals(MInOut.MOVEMENTTYPE_VendorReturns) && isAutoGenerateLot + && getM_AttributeSetInstance_ID() == 0) + { + MAttributeSetInstance asi = MAttributeSetInstance.generateLot(getCtx(), (MProduct)getM_Product(), get_TrxName()); + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } // if (getC_Charge_ID() == 0 && getM_Product_ID() == 0) // ; diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 502e7fc28c..77f01c2526 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -696,8 +696,74 @@ public class MInventory extends X_M_Inventory implements DocAction if(qtyDiff.compareTo(Env.ZERO)>0) { - MInventoryLineMA lineMA = MInventoryLineMA.addOrCreate(line, 0, qtyDiff.negate(), getMovementDate(),true); - lineMA.saveEx(); + //AttributeSetInstance enable + I_M_AttributeSet as = line.getM_Product().getM_AttributeSet(); + if (as != null && as.isInstanceAttribute()) + { + //add quantity to last attributesetinstance + storages = MStorageOnHand.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, null, + false, true, 0, get_TrxName()); + for (MStorageOnHand storage : storages) + { + BigDecimal maQty = qtyDiff; + //backward compatibility: -ve in MA is incoming trx, +ve in MA is outgoing trx + MInventoryLineMA lineMA = new MInventoryLineMA(line, storage.getM_AttributeSetInstance_ID(), maQty.negate(), storage.getDateMaterialPolicy(),true); + lineMA.saveEx(); + qtyDiff = qtyDiff.subtract(maQty); + storage.addQtyOnHand(maQty.negate()); + + if (qtyDiff.compareTo(Env.ZERO)==0) + break; + + } + } + if(qtyDiff.compareTo(Env.ZERO)>0) + { + MClientInfo m_clientInfo = MClientInfo.get(getCtx(), getAD_Client_ID(), get_TrxName()); + MAcctSchema acctSchema = new MAcctSchema(getCtx(), m_clientInfo.getC_AcctSchema1_ID(), get_TrxName()); + if (MAcctSchema.COSTINGLEVEL_BatchLot.equals(product.getCostingLevel(acctSchema)) ) + { + String sqlWhere = "M_Product_ID=? AND M_Locator_ID=? AND QtyOnHand = 0 AND M_AttributeSetInstance_ID > 0 "; + MStorageOnHand storage = new Query(getCtx(), MStorageOnHand.Table_Name, sqlWhere, get_TrxName()) + .setParameters(line.getM_Product_ID(), line.getM_Locator_ID()) + .setOrderBy(MStorageOnHand.COLUMNNAME_DateMaterialPolicy+","+ MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID) + .first(); + + if (storage != null ) + { + MInventoryLineMA lineMA = MInventoryLineMA.addOrCreate(line, storage.getM_AttributeSetInstance_ID(), qtyDiff.negate(), getMovementDate(),true); + lineMA.saveEx(); + } + else + { + String costingMethod = product.getCostingMethod(acctSchema); + StringBuilder localWhereClause = new StringBuilder("M_Product_ID =?" ) + .append(" AND C_AcctSchema_ID=?") + .append(" AND ce.CostingMethod = ? ") + .append(" AND CurrentCostPrice <> 0 "); + MCost cost = new Query(getCtx(),I_M_Cost.Table_Name,localWhereClause.toString(),get_TrxName()) + .setParameters(line.getM_Product_ID(), acctSchema.get_ID(), costingMethod) + .addJoinClause(" INNER JOIN M_CostElement ce ON (M_Cost.M_CostElement_ID =ce.M_CostElement_ID ) ") + .setOrderBy("Updated DESC") + .first(); + if (cost != null) + { + MInventoryLineMA lineMA = MInventoryLineMA.addOrCreate(line, cost.getM_AttributeSetInstance_ID(), qtyDiff.negate(), getMovementDate(),true); + lineMA.saveEx(); + } + else + { + m_processMsg = "Cannot retrieve cost of Inventory " ; + } + } + + } else + { + MInventoryLineMA lineMA = MInventoryLineMA.addOrCreate(line, 0, qtyDiff.negate(), getMovementDate(),true); + lineMA.saveEx(); + } + + } } } else // Outgoing Trx diff --git a/org.adempiere.base/src/org/compiere/model/MProduction.java b/org.adempiere.base/src/org/compiere/model/MProduction.java index 30402d564e..8be1b6da0b 100644 --- a/org.adempiere.base/src/org/compiere/model/MProduction.java +++ b/org.adempiere.base/src/org/compiere/model/MProduction.java @@ -711,6 +711,25 @@ public class MProduction extends X_M_Production implements DocAction { reversal.addDescription(msgadd.toString()); reversal.setReversal_ID(getM_Production_ID()); reversal.saveEx(get_TrxName()); + + // Reverse Line Qty + MProductionLine[] sLines = getLines(); + MProductionLine[] tLines = reversal.getLines(); + for (int i = 0; i < sLines.length; i++) + { + // We need to copy MA + if (sLines[i].getM_AttributeSetInstance_ID() == 0) + { + MProductionLineMA mas[] = MProductionLineMA.get(getCtx(), sLines[i].get_ID(), get_TrxName()); + for (int j = 0; j < mas.length; j++) + { + MProductionLineMA ma = new MProductionLineMA (tLines[i], + mas[j].getM_AttributeSetInstance_ID(), + mas[j].getMovementQty().negate(),mas[j].getDateMaterialPolicy()); + ma.saveEx(get_TrxName()); + } + } + } if (!reversal.processIt(DocAction.ACTION_Complete)) { diff --git a/org.adempiere.base/src/org/compiere/model/MProductionLine.java b/org.adempiere.base/src/org/compiere/model/MProductionLine.java index d141eee7a9..c5badcf6f2 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductionLine.java +++ b/org.adempiere.base/src/org/compiere/model/MProductionLine.java @@ -1,12 +1,16 @@ package org.compiere.model; import java.math.BigDecimal; +import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.exceptions.AdempiereException; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Util; @@ -74,10 +78,12 @@ public class MProductionLine extends X_M_ProductionLine { * @return "" for success, error string if failed */ public String createTransactions(Timestamp date, boolean mustBeStocked) { - // delete existing ASI records - int deleted = deleteMA(); - if (log.isLoggable(Level.FINE))log.log(Level.FINE, "Deleted " + deleted + " attribute records "); - + if (getParent().getReversal_ID() <= 0 ) + { + // delete existing ASI records + int deleted = deleteMA(); + if (log.isLoggable(Level.FINE))log.log(Level.FINE, "Deleted " + deleted + " attribute records "); + } MProduct prod = new MProduct(getCtx(), getM_Product_ID(), get_TrxName()); if (log.isLoggable(Level.FINE))log.log(Level.FINE,"Loaded Product " + prod.toString()); @@ -89,6 +95,10 @@ public class MProductionLine extends X_M_ProductionLine { StringBuilder errorString = new StringBuilder(); MAttributeSetInstance asi = new MAttributeSetInstance(getCtx(), getM_AttributeSetInstance_ID(), get_TrxName()); + I_M_AttributeSet attributeset = prod.getM_AttributeSet(); + boolean isAutoGenerateLot = false; + if (attributeset != null) + isAutoGenerateLot = attributeset.isAutoGenerateLot(); String asiString = asi.getDescription(); if ( asiString == null ) asiString = ""; @@ -96,7 +106,11 @@ public class MProductionLine extends X_M_ProductionLine { if (log.isLoggable(Level.FINEST)) log.log(Level.FINEST, "asi Description is: " + asiString); // create transactions for finished goods if ( getM_Product_ID() == getEndProduct_ID()) { - + if (getParent().getReversal_ID() <= 0 && isAutoGenerateLot && getM_AttributeSetInstance_ID() == 0) + { + asi = MAttributeSetInstance.generateLot(getCtx(), (MProduct)getM_Product(), get_TrxName()); + setM_AttributeSetInstance_ID(asi.getM_AttributeSetInstance_ID()); + } Timestamp dateMPolicy = date; if(getM_AttributeSetInstance_ID()>0){ Timestamp t = MStorageOnHand.getDateMaterialPolicy(getM_Product_ID(), getM_AttributeSetInstance_ID(), get_TrxName()); @@ -170,7 +184,7 @@ public class MProductionLine extends X_M_ProductionLine { } matTrx = new MTransaction (getCtx(), getAD_Org_ID(), "P-", - getM_Locator_ID(), getM_Product_ID(), asi.get_ID(), + getM_Locator_ID(), getM_Product_ID(), lineMA.getM_AttributeSetInstance_ID(), lineQty.negate(), date, get_TrxName()); matTrx.setM_ProductionLine_ID(get_ID()); if ( !matTrx.save(get_TrxName()) ) { @@ -191,6 +205,55 @@ public class MProductionLine extends X_M_ProductionLine { } // for available storages } + else if (qtyToMove.signum() < 0 ) + { + + MClientInfo m_clientInfo = MClientInfo.get(getCtx(), getAD_Client_ID(), get_TrxName()); + MAcctSchema acctSchema = new MAcctSchema(getCtx(), m_clientInfo.getC_AcctSchema1_ID(), get_TrxName()); + if (asi.get_ID() == 0 && MAcctSchema.COSTINGLEVEL_BatchLot.equals(prod.getCostingLevel(acctSchema)) ) + { + //add quantity to last attributesetinstance + String sqlWhere = "M_Product_ID=? AND M_Locator_ID=? AND M_AttributeSetInstance_ID > 0 "; + MStorageOnHand storage = new Query(getCtx(), MStorageOnHand.Table_Name, sqlWhere, get_TrxName()) + .setParameters(getM_Product_ID(), getM_Locator_ID()) + .setOrderBy(MStorageOnHand.COLUMNNAME_DateMaterialPolicy+" DESC,"+ MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID +" DESC") + .first(); + + if (storage != null) + { + setM_AttributeSetInstance_ID(storage.getM_AttributeSetInstance_ID()); + asi = new MAttributeSetInstance(getCtx(), storage.getM_AttributeSetInstance_ID(), get_TrxName()); + asiString = asi.getDescription(); + } + else + { + String costingMethod = prod.getCostingMethod(acctSchema); + StringBuilder localWhereClause = new StringBuilder("M_Product_ID =?" ) + .append(" AND C_AcctSchema_ID=?") + .append(" AND ce.CostingMethod = ? ") + .append(" AND CurrentCostPrice <> 0 "); + MCost cost = new Query(getCtx(),I_M_Cost.Table_Name,localWhereClause.toString(),get_TrxName()) + .setParameters(getM_Product_ID(), acctSchema.get_ID(), costingMethod) + .addJoinClause(" INNER JOIN M_CostElement ce ON (M_Cost.M_CostElement_ID =ce.M_CostElement_ID ) ") + .setOrderBy("Updated DESC") + .first(); + if (cost != null) + { + setM_AttributeSetInstance_ID(cost.getM_AttributeSetInstance_ID()); + asi = new MAttributeSetInstance(getCtx(), cost.getM_AttributeSetInstance_ID(), get_TrxName()); + asiString = asi.getDescription(); + + } + else + { + log.log(Level.SEVERE, "Cannot retrieve cost of Product r " + prod.toString()); + errorString.append( "Cannot retrieve cost of Product " +prod.toString() ) ; + } + + } + + } + } if ( !( qtyToMove.signum() == 0) ) { @@ -330,5 +393,52 @@ public class MProductionLine extends X_M_ProductionLine { deleteMA(); return true; } - + + + /** + * Get Parent + * @return parent + */ + public MProduction getParent() { + if (productionParent == null) + productionParent = new MProduction (getCtx(), getM_Production_ID(), get_TrxName()); + return productionParent; + } // getParent + + /** + * + * @return + */ + public MProductionLineMA[] getLineMAs() { + ArrayList list = new ArrayList(); + + String sql = "SELECT pl.M_ProductionLine_ID, pl,M_AttributeSetInstance_ID , pl.MovementQty, pl.DateMaterialPolicy " + + "FROM M_ProductionLineMA pl " + + "WHERE pl.M_ProductionLine_ID = ?"; + + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement(sql, get_TrxName()); + pstmt.setInt(1, get_ID()); + rs = pstmt.executeQuery(); + while (rs.next()) + list.add( new MProductionLineMA( this, rs.getInt(2), rs.getBigDecimal(3), rs.getTimestamp(4) ) ); + } + catch (SQLException ex) + { + throw new AdempiereException("Unable to load production lines", ex); + } + finally + { + DB.close(rs, pstmt); + rs = null; + pstmt = null; + } + + MProductionLineMA[] retValue = new MProductionLineMA[list.size()]; + list.toArray(retValue); + return retValue; + } } diff --git a/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java b/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java index bede164bec..4786cfb80f 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java +++ b/org.adempiere.base/src/org/compiere/model/MProductionLineMA.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.Date; +import java.util.List; import java.util.Properties; import org.compiere.model.X_M_ProductionLineMA; @@ -77,4 +78,23 @@ public class MProductionLineMA extends X_M_ProductionLineMA { Env.ZERO,dateMPolicy); } + /** + * Get Material Allocations for Line + * @param ctx context + * @param M_ProductionLine_ID line + * @param trxName trx + * @return allocations + */ + public static MProductionLineMA[] get (Properties ctx, int M_ProductionLine_ID, String trxName) + { + + Query query = MTable.get(ctx, MProductionLineMA.Table_Name) + .createQuery(I_M_ProductionLineMA.COLUMNNAME_M_ProductionLine_ID+"=?", trxName); + query.setParameters(M_ProductionLine_ID); + List list = query.list(); + MProductionLineMA[] retValue = list.toArray (new MProductionLineMA[0]); + return retValue; + } // get + + } diff --git a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java index 9899988867..c20f5284d2 100644 --- a/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java +++ b/org.adempiere.base/src/org/compiere/model/MStorageOnHand.java @@ -182,7 +182,7 @@ public class MStorageOnHand extends X_M_StorageOnHand } else { - query.setOrderBy(MStorageOnHand.COLUMNNAME_DateMaterialPolicy); + query.setOrderBy(MStorageOnHand.COLUMNNAME_DateMaterialPolicy+","+ MStorageOnHand.COLUMNNAME_M_AttributeSetInstance_ID); } if (forUpdate) { @@ -335,7 +335,9 @@ public class MStorageOnHand extends X_M_StorageOnHand } sql += "ORDER BY l.PriorityNo DESC, DateMaterialPolicy "; if (!FiFo) - sql += " DESC"; + sql += " DESC, s.M_AttributeSetInstance_ID DESC "; + else + sql += ", s.M_AttributeSetInstance_ID "; // All Attribute Set Instances if (allAttributeInstances) { @@ -369,13 +371,17 @@ public class MStorageOnHand extends X_M_StorageOnHand if(product.isUseGuaranteeDateForMPolicy()){ sql += "ORDER BY l.PriorityNo DESC, COALESCE(asi.GuaranteeDate,s.DateMaterialPolicy)"; if (!FiFo) - sql += " DESC"; + sql += " DESC, s.M_AttributeSetInstance_ID DESC "; + else + sql += ", s.M_AttributeSetInstance_ID "; } else { sql += "ORDER BY l.PriorityNo DESC, l.M_Locator_ID, s.DateMaterialPolicy"; if (!FiFo) - sql += " DESC"; + sql += " DESC, s.M_AttributeSetInstance_ID DESC "; + else + sql += ", s.M_AttributeSetInstance_ID "; } sql += ", s.QtyOnHand DESC"; @@ -523,7 +529,9 @@ public class MStorageOnHand extends X_M_StorageOnHand { sql += "ORDER BY l.PriorityNo DESC, l.M_Locator_ID, s.DateMaterialPolicy"; if (!FiFo) - sql += " DESC"; + sql += " DESC, s.M_AttributeSetInstance_ID DESC "; + else + sql += ", s.M_AttributeSetInstance_ID "; } sql += ", s.QtyOnHand DESC"; @@ -894,6 +902,12 @@ public class MStorageOnHand extends X_M_StorageOnHand log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed")); return false; } + + if (getM_AttributeSetInstance_ID() > 0 && getQtyOnHand().signum() < 0) + { + log.saveError("Error", Msg.getMsg(getCtx(), "NegativeInventoryDisallowed")); + return false; + } } } diff --git a/org.adempiere.base/src/org/compiere/model/ProductCost.java b/org.adempiere.base/src/org/compiere/model/ProductCost.java index da243aab49..fd63e86324 100644 --- a/org.adempiere.base/src/org/compiere/model/ProductCost.java +++ b/org.adempiere.base/src/org/compiere/model/ProductCost.java @@ -434,4 +434,10 @@ public class ProductCost return sb.toString (); } // toString + /** + * @param M_AttributeSetInstance_ID the m_M_AttributeSetInstance_ID to set + */ + public void setM_M_AttributeSetInstance_ID(int M_AttributeSetInstance_ID) { + this.m_M_AttributeSetInstance_ID = M_AttributeSetInstance_ID; + } } // ProductCost diff --git a/org.adempiere.base/src/org/compiere/model/X_M_AttributeSet.java b/org.adempiere.base/src/org/compiere/model/X_M_AttributeSet.java index 4fb275a00d..510b10d56e 100644 --- a/org.adempiere.base/src/org/compiere/model/X_M_AttributeSet.java +++ b/org.adempiere.base/src/org/compiere/model/X_M_AttributeSet.java @@ -30,7 +30,7 @@ public class X_M_AttributeSet extends PO implements I_M_AttributeSet, I_Persiste /** * */ - private static final long serialVersionUID = 20161030L; + private static final long serialVersionUID = 20170417L; /** Standard Constructor */ public X_M_AttributeSet (Properties ctx, int M_AttributeSet_ID, String trxName) @@ -516,4 +516,25 @@ public class X_M_AttributeSet extends PO implements I_M_AttributeSet, I_Persiste } return false; } + + /** Set Auto Generated. + @param IsAutoGenerateLot Auto Generate Lot */ + public void setIsAutoGenerateLot (boolean IsAutoGenerateLot) + { + set_ValueNoCheck (COLUMNNAME_IsAutoGenerateLot, Boolean.valueOf(IsAutoGenerateLot)); + } + + /** Get Auto Generate Lot. + @return Auto Generate Lot */ + public boolean isAutoGenerateLot () + { + Object oo = get_Value(COLUMNNAME_IsAutoGenerateLot); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } } \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WPAttributeEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WPAttributeEditor.java index 14377479be..961af4c52c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WPAttributeEditor.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WPAttributeEditor.java @@ -161,6 +161,12 @@ public class WPAttributeEditor extends WEditor implements ContextMenuListener if (m_GridTab != null) { M_Product_ID = Env.getContextAsInt (Env.getCtx (), m_WindowNo, m_GridTab.getTabNo(), "M_Product_ID"); M_ProductBOM_ID = Env.getContextAsInt (Env.getCtx (), m_WindowNo, m_GridTab.getTabNo(), "M_ProductBOM_ID"); + //For third level tab (e.g, LineMA), should take M_Product_ID from Line instead of from Header + if (m_GridTab.getTabLevel() > 1 && m_GridTab.getParentTab() != null && m_GridTab.getField("M_Product_ID")==null) { + int tmp = Env.getContextAsInt (Env.getCtx (), m_WindowNo, m_GridTab.getParentTab().getTabNo(), "M_Product_ID"); + if (tmp > 0) + M_Product_ID = tmp; + } } else { M_Product_ID = Env.getContextAsInt (Env.getCtx (), m_WindowNo, "M_Product_ID"); M_ProductBOM_ID = Env.getContextAsInt (Env.getCtx (), m_WindowNo, "M_ProductBOM_ID");