IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing (#1277)
* IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing * IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing * IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing - Fix rounding error
This commit is contained in:
parent
cfb4ebe785
commit
a41aeb2205
|
@ -0,0 +1,89 @@
|
||||||
|
SELECT register_migration_script('202203290700_IDEMPIERE-5057.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:27:22 PM MYT
|
||||||
|
-- IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,ColumnName,Updated,Name,PrintName,AD_Element_UU,IsActive,Created,CreatedBy,UpdatedBy,AD_Client_ID,EntityType,AD_Org_ID) VALUES (203283,'TaxPostingIndicator',TO_DATE('2022-03-28 15:27:21','YYYY-MM-DD HH24:MI:SS'),'Posting Indicator','Posting Indicator','6de750b3-2872-44ba-a78b-94fa6af96acf','Y',TO_DATE('2022-03-28 15:27:21','YYYY-MM-DD HH24:MI:SS'),100,100,0,'D',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:32:00 PM MYT
|
||||||
|
INSERT INTO AD_Reference (AD_Reference_ID,Name,AD_Reference_UU,IsOrderByValue,ValidationType,Updated,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,EntityType,AD_Org_ID) VALUES (200160,'C_Tax Posting Indicator','429065e5-80c4-458e-a7ae-d20761dcb5a8','N','L',TO_DATE('2022-03-28 15:31:59','YYYY-MM-DD HH24:MI:SS'),'Y',100,100,0,TO_DATE('2022-03-28 15:31:59','YYYY-MM-DD HH24:MI:SS'),'D',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:35:42 PM MYT
|
||||||
|
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Description,AD_Ref_List_UU,Name,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,Updated,EntityType,AD_Reference_ID,Value,AD_Org_ID) VALUES (200446,'Tax is calculated on the full amount of the item and posted separately.','e84b618c-a8b3-47cf-89a6-dd674e52d3e4','Separate Tax Posting','Y',100,100,0,TO_DATE('2022-03-28 15:35:41','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2022-03-28 15:35:41','YYYY-MM-DD HH24:MI:SS'),'D',200160,'0',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:37:59 PM MYT
|
||||||
|
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Description,AD_Ref_List_UU,Name,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,Updated,EntityType,AD_Reference_ID,Value,AD_Org_ID) VALUES (200447,'Tax amount is added to the item amount during account posting time and for updating of Product Cost.','3e8e0d29-29ac-4c67-ae2c-92c0ee43d2e6','Distribute Tax with Relevant Expense','Y',100,100,0,TO_DATE('2022-03-28 15:37:58','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2022-03-28 15:37:58','YYYY-MM-DD HH24:MI:SS'),'D',200160,'1',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:38:05 PM MYT
|
||||||
|
UPDATE AD_Reference SET IsOrderByValue='Y',Updated=TO_DATE('2022-03-28 15:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=200160
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:45 PM MYT
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,ReadOnlyLogic,IsAutocomplete,IsAllowLogging,MandatoryLogic,AD_Column_UU,Updated,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsAlwaysUpdateable,AD_Client_ID,Created,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Reference_ID,IsToolbarButton,AD_Org_ID,IsHtml) VALUES (213805,0,'N',0,'N','N','N',0,'N',1,'N','N','@IsSummary@=Y','N','Y','@IsSummary@=N','e7a97d28-f550-4253-a77b-b6fab1e7b38a',TO_DATE('2022-03-28 15:42:44','YYYY-MM-DD HH24:MI:SS'),'Y','TaxPostingIndicator','0','Posting Indicator','Y','Y',100,100,'N',0,TO_DATE('2022-03-28 15:42:44','YYYY-MM-DD HH24:MI:SS'),'D','N','N','N',203283,200160,261,17,'N',0,'N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:52 PM MYT
|
||||||
|
INSERT INTO AD_TreeNode (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNode_UU) SELECT t.AD_Client_ID, 0, 'Y', SysDate, 100, SysDate, 100,t.AD_Tree_ID, 200012, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='TL' AND t.AD_Table_ID=282 AND NOT EXISTS (SELECT * FROM AD_TreeNode e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200012)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:53 PM MYT
|
||||||
|
ALTER TABLE C_Tax ADD TaxPostingIndicator CHAR(1) DEFAULT '0'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:05 PM MYT
|
||||||
|
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,DisplayLogic,Updated,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID,AD_Org_ID) VALUES (0,205862,'N',0,'N','N',1010,'Y','N','@IsDocumentLevel@=N',TO_DATE('2022-03-28 15:55:04','YYYY-MM-DD HH24:MI:SS'),'Posting Indicator','96a2af5a-4a6f-4d44-ab54-da4713d70fc5','Y','N',100,100,'Y','Y',1010,4,'N',0,TO_DATE('2022-03-28 15:55:04','YYYY-MM-DD HH24:MI:SS'),2,1,'N','N',213805,'D',174,0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=180,SeqNoGrid=180,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=190,SeqNoGrid=190,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=203325
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=200,SeqNoGrid=200,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=203326
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=210,SeqNoGrid=210,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=974
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=220,SeqNoGrid=220,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=976
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=230,SeqNoGrid=230,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=975
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_Field SET SeqNo=240,SeqNoGrid=240,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=977
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_Field SET SeqNo=250,SeqNoGrid=250,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=202402
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:56:15 PM MYT
|
||||||
|
UPDATE AD_Column SET ReadOnlyLogic='@IsDocumentLevel@=Y', MandatoryLogic='@IsDocumentLevel@=N',Updated=TO_DATE('2022-03-28 15:56:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213805
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 6:43:36 PM MYT
|
||||||
|
UPDATE AD_Field SET DisplayLogic='@IsDocumentLevel@=N & @IsSummary@=N', AD_Val_Rule_ID=NULL, AD_Reference_Value_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2022-03-28 18:43:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 8:10:21 PM MYT
|
||||||
|
UPDATE AD_Field SET DisplayLogic='@IsDocumentLevel@=N & @IsSummary@=N & @SOPOType@!S', AD_Val_Rule_ID=NULL, AD_Reference_Value_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2022-03-28 20:10:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 8:10:34 PM MYT
|
||||||
|
INSERT INTO AD_TreeNode (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNode_UU) SELECT t.AD_Client_ID, 0, 'Y', SysDate, 100, SysDate, 100,t.AD_Tree_ID, 200014, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='TL' AND t.AD_Table_ID=282 AND NOT EXISTS (SELECT * FROM AD_TreeNode e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200014)
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
-- IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing
|
||||||
|
SELECT register_migration_script('202204011738_IDEMPIERE-5057.sql') FROM dual;
|
||||||
|
|
||||||
|
SET SQLBLANKLINES ON
|
||||||
|
SET DEFINE OFF
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Element SET Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.',Updated=TO_TIMESTAMP('2022-04-01 17:38:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203283
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Column SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Process_Para SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', AD_Element_ID=203283 WHERE UPPER(ColumnName)='TAXPOSTINGINDICATOR' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Process_Para SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283 AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_InfoColumn SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283 AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Field SET Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203283) AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
SELECT register_migration_script('202203290700_IDEMPIERE-5057.sql') FROM dual
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:27:22 PM MYT
|
||||||
|
-- IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing
|
||||||
|
INSERT INTO AD_Element (AD_Element_ID,ColumnName,Updated,Name,PrintName,AD_Element_UU,IsActive,Created,CreatedBy,UpdatedBy,AD_Client_ID,EntityType,AD_Org_ID) VALUES (203283,'TaxPostingIndicator',TO_TIMESTAMP('2022-03-28 15:27:21','YYYY-MM-DD HH24:MI:SS'),'Posting Indicator','Posting Indicator','6de750b3-2872-44ba-a78b-94fa6af96acf','Y',TO_TIMESTAMP('2022-03-28 15:27:21','YYYY-MM-DD HH24:MI:SS'),100,100,0,'D',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:32:00 PM MYT
|
||||||
|
INSERT INTO AD_Reference (AD_Reference_ID,Name,AD_Reference_UU,IsOrderByValue,ValidationType,Updated,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,EntityType,AD_Org_ID) VALUES (200160,'C_Tax Posting Indicator','429065e5-80c4-458e-a7ae-d20761dcb5a8','N','L',TO_TIMESTAMP('2022-03-28 15:31:59','YYYY-MM-DD HH24:MI:SS'),'Y',100,100,0,TO_TIMESTAMP('2022-03-28 15:31:59','YYYY-MM-DD HH24:MI:SS'),'D',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:35:42 PM MYT
|
||||||
|
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Description,AD_Ref_List_UU,Name,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,Updated,EntityType,AD_Reference_ID,Value,AD_Org_ID) VALUES (200446,'Tax is calculated on the full amount of the item and posted separately.','e84b618c-a8b3-47cf-89a6-dd674e52d3e4','Separate Tax Posting','Y',100,100,0,TO_TIMESTAMP('2022-03-28 15:35:41','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2022-03-28 15:35:41','YYYY-MM-DD HH24:MI:SS'),'D',200160,'0',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:37:59 PM MYT
|
||||||
|
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Description,AD_Ref_List_UU,Name,IsActive,CreatedBy,UpdatedBy,AD_Client_ID,Created,Updated,EntityType,AD_Reference_ID,Value,AD_Org_ID) VALUES (200447,'Tax amount is added to the item amount during account posting time and for updating of Product Cost.','3e8e0d29-29ac-4c67-ae2c-92c0ee43d2e6','Distribute Tax with Relevant Expense','Y',100,100,0,TO_TIMESTAMP('2022-03-28 15:37:58','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2022-03-28 15:37:58','YYYY-MM-DD HH24:MI:SS'),'D',200160,'1',0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:38:05 PM MYT
|
||||||
|
UPDATE AD_Reference SET IsOrderByValue='Y',Updated=TO_TIMESTAMP('2022-03-28 15:38:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=200160
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:45 PM MYT
|
||||||
|
INSERT INTO AD_Column (AD_Column_ID,SeqNoSelection,IsSyncDatabase,Version,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,ReadOnlyLogic,IsAutocomplete,IsAllowLogging,MandatoryLogic,AD_Column_UU,Updated,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,IsActive,CreatedBy,UpdatedBy,IsAlwaysUpdateable,AD_Client_ID,Created,EntityType,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_Value_ID,AD_Table_ID,AD_Reference_ID,IsToolbarButton,AD_Org_ID,IsHtml) VALUES (213805,0,'N',0,'N','N','N',0,'N',1,'N','N','@IsSummary@=Y','N','Y','@IsSummary@=N','e7a97d28-f550-4253-a77b-b6fab1e7b38a',TO_TIMESTAMP('2022-03-28 15:42:44','YYYY-MM-DD HH24:MI:SS'),'Y','TaxPostingIndicator','0','Posting Indicator','Y','Y',100,100,'N',0,TO_TIMESTAMP('2022-03-28 15:42:44','YYYY-MM-DD HH24:MI:SS'),'D','N','N','N',203283,200160,261,17,'N',0,'N')
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:52 PM MYT
|
||||||
|
INSERT INTO AD_TreeNode (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNode_UU) SELECT t.AD_Client_ID, 0, 'Y', statement_timestamp(), 100, statement_timestamp(), 100,t.AD_Tree_ID, 200012, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='TL' AND t.AD_Table_ID=282 AND NOT EXISTS (SELECT * FROM AD_TreeNode e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200012)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:42:53 PM MYT
|
||||||
|
ALTER TABLE C_Tax ADD COLUMN TaxPostingIndicator CHAR(1) DEFAULT '0'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:05 PM MYT
|
||||||
|
INSERT INTO AD_Field (SortNo,AD_Field_ID,IsEncrypted,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,IsReadOnly,DisplayLogic,Updated,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,CreatedBy,UpdatedBy,IsActive,IsDisplayedGrid,SeqNoGrid,XPosition,IsQuickEntry,AD_Client_ID,Created,ColumnSpan,NumLines,IsAdvancedField,IsDefaultFocus,AD_Column_ID,EntityType,AD_Tab_ID,AD_Org_ID) VALUES (0,205862,'N',0,'N','N',1010,'Y','N','@IsDocumentLevel@=N',TO_TIMESTAMP('2022-03-28 15:55:04','YYYY-MM-DD HH24:MI:SS'),'Posting Indicator','96a2af5a-4a6f-4d44-ab54-da4713d70fc5','Y','N',100,100,'Y','Y',1010,4,'N',0,TO_TIMESTAMP('2022-03-28 15:55:04','YYYY-MM-DD HH24:MI:SS'),2,1,'N','N',213805,'D',174,0)
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=180,SeqNoGrid=180,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=190,SeqNoGrid=190,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=203325
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=200,SeqNoGrid=200,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=203326
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=210,SeqNoGrid=210,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=974
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=220,SeqNoGrid=220,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=976
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:55:33 PM MYT
|
||||||
|
UPDATE AD_Field SET SeqNo=230,SeqNoGrid=230,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=975
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_Field SET SeqNo=240,SeqNoGrid=240,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=977
|
||||||
|
;
|
||||||
|
|
||||||
|
UPDATE AD_Field SET SeqNo=250,SeqNoGrid=250,IsDisplayed='Y', Updated=Now(), UpdatedBy=100 WHERE AD_Field_ID=202402
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 3:56:15 PM MYT
|
||||||
|
UPDATE AD_Column SET ReadOnlyLogic='@IsDocumentLevel@=Y', MandatoryLogic='@IsDocumentLevel@=N',Updated=TO_TIMESTAMP('2022-03-28 15:56:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=213805
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 6:43:36 PM MYT
|
||||||
|
UPDATE AD_Field SET DisplayLogic='@IsDocumentLevel@=N & @IsSummary@=N', AD_Val_Rule_ID=NULL, AD_Reference_Value_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2022-03-28 18:43:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 8:10:21 PM MYT
|
||||||
|
UPDATE AD_Field SET DisplayLogic='@IsDocumentLevel@=N & @IsSummary@=N & @SOPOType@!S', AD_Val_Rule_ID=NULL, AD_Reference_Value_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2022-03-28 20:10:21','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=205862
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Mar 28, 2022 8:10:34 PM MYT
|
||||||
|
INSERT INTO AD_TreeNode (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNode_UU) SELECT t.AD_Client_ID, 0, 'Y', statement_timestamp(), 100, statement_timestamp(), 100,t.AD_Tree_ID, 200014, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='TL' AND t.AD_Table_ID=282 AND NOT EXISTS (SELECT * FROM AD_TreeNode e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200014)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
-- IDEMPIERE-5057 Implement Deductible and non deductible input tax for purchasing and costing
|
||||||
|
SELECT register_migration_script('202204011738_IDEMPIERE-5057.sql') FROM dual;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Element SET Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.',Updated=TO_TIMESTAMP('2022-04-01 17:38:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203283
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Column SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Process_Para SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', AD_Element_ID=203283 WHERE UPPER(ColumnName)='TAXPOSTINGINDICATOR' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Process_Para SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283 AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_InfoColumn SET ColumnName='TaxPostingIndicator', Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Element_ID=203283 AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
||||||
|
-- Apr 1, 2022, 5:38:03 PM MYT
|
||||||
|
UPDATE AD_Field SET Name='Posting Indicator', Description='Type of input tax (deductible and non deductible)', Help='Separate Tax Posting: Tax is calculated on the full amount of the item and posted separately.
|
||||||
|
Distribute Tax with Relevant Expense: Tax amount is added to the item amount during account posting time and for updating of Product Cost.', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203283) AND IsCentrallyMaintained='Y'
|
||||||
|
;
|
||||||
|
|
|
@ -31,30 +31,112 @@ import org.compiere.process.ProcessInfo;
|
||||||
*/
|
*/
|
||||||
public interface ITaxProvider {
|
public interface ITaxProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate order tax
|
||||||
|
* @param provider
|
||||||
|
* @param order
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean calculateOrderTaxTotal(MTaxProvider provider, MOrder order);
|
public boolean calculateOrderTaxTotal(MTaxProvider provider, MOrder order);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update order tax for line
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateOrderTax(MTaxProvider provider, MOrderLine line);
|
public boolean updateOrderTax(MTaxProvider provider, MOrderLine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-calculate order tax for line (if line tax id change)
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @param newRecord
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean recalculateTax(MTaxProvider provider, MOrderLine line, boolean newRecord);
|
public boolean recalculateTax(MTaxProvider provider, MOrderLine line, boolean newRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update order tax total
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateHeaderTax(MTaxProvider provider, MOrderLine line);
|
public boolean updateHeaderTax(MTaxProvider provider, MOrderLine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate invoice tax total
|
||||||
|
* @param provider
|
||||||
|
* @param invoice
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean calculateInvoiceTaxTotal(MTaxProvider provider, MInvoice invoice);
|
public boolean calculateInvoiceTaxTotal(MTaxProvider provider, MInvoice invoice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update invoice tax for line
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateInvoiceTax(MTaxProvider provider, MInvoiceLine line);
|
public boolean updateInvoiceTax(MTaxProvider provider, MInvoiceLine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-calculate invoice tax for line (if line tax id change)
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @param newRecord
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean recalculateTax(MTaxProvider provider, MInvoiceLine line, boolean newRecord);
|
public boolean recalculateTax(MTaxProvider provider, MInvoiceLine line, boolean newRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update invoice tax total
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateHeaderTax(MTaxProvider provider, MInvoiceLine line);
|
public boolean updateHeaderTax(MTaxProvider provider, MInvoiceLine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate rma tax total
|
||||||
|
* @param provider
|
||||||
|
* @param rma
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean calculateRMATaxTotal(MTaxProvider provider, MRMA rma);
|
public boolean calculateRMATaxTotal(MTaxProvider provider, MRMA rma);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update rma tax for rma line
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateRMATax(MTaxProvider provider, MRMALine line);
|
public boolean updateRMATax(MTaxProvider provider, MRMALine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-calculate rma tax for ram line (if line tax id change)
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @param newRecord
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean recalculateTax(MTaxProvider provider, MRMALine line, boolean newRecord);
|
public boolean recalculateTax(MTaxProvider provider, MRMALine line, boolean newRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update rma header total
|
||||||
|
* @param provider
|
||||||
|
* @param line
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
public boolean updateHeaderTax(MTaxProvider provider, MRMALine line);
|
public boolean updateHeaderTax(MTaxProvider provider, MRMALine line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param provider
|
||||||
|
* @param pi
|
||||||
|
* @return error message
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public String validateConnection(MTaxProvider provider, ProcessInfo pi) throws Exception;
|
public String validateConnection(MTaxProvider provider, ProcessInfo pi) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import org.compiere.model.I_C_OrderLine;
|
import org.compiere.model.I_C_OrderLine;
|
||||||
|
@ -616,9 +617,57 @@ public class Doc_InOut extends Doc
|
||||||
int stdPrecision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), C_Currency_ID);
|
||||||
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + costs + " - Tax=" + costTax);
|
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + costs + " - Tax=" + costTax);
|
||||||
costs = costs.subtract(costTax);
|
if(tax.isSummary())
|
||||||
|
{
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
List<MTax> toSubtract = new ArrayList<>();
|
||||||
|
for(MTax cTax : cTaxes)
|
||||||
|
{
|
||||||
|
if (!cTax.isDistributeTaxWithLineItem())
|
||||||
|
toSubtract.add(cTax);
|
||||||
|
}
|
||||||
|
if (toSubtract.size() > 0)
|
||||||
|
{
|
||||||
|
BigDecimal base = costs.subtract(costTax);
|
||||||
|
for(MTax cTax : toSubtract)
|
||||||
|
{
|
||||||
|
BigDecimal ts = cTax.calculateTax(base, false, stdPrecision);
|
||||||
|
costs = costs.subtract(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
costs = costs.subtract(costTax);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // correct included Tax
|
} // correct included Tax
|
||||||
|
else if (C_Tax_ID != 0)
|
||||||
|
{
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
|
if(tax.isSummary())
|
||||||
|
{
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
BigDecimal base = costs;
|
||||||
|
for(MTax cTax : cTaxes)
|
||||||
|
{
|
||||||
|
if (cTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
//do not round to stdprecision before multiply qty
|
||||||
|
BigDecimal costTax = cTax.calculateTax(base, false, 12);
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + base + " - Tax=" + costTax);
|
||||||
|
costs = costs.add(costTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
//do not round to stdprecision before multiply qty
|
||||||
|
BigDecimal costTax = tax.calculateTax(costs, false, 12);
|
||||||
|
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + costs + " - Tax=" + costTax);
|
||||||
|
costs = costs.add(costTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
costs = costs.multiply(line.getQty());
|
costs = costs.multiply(line.getQty());
|
||||||
}
|
}
|
||||||
|
@ -781,18 +830,50 @@ public class Doc_InOut extends Doc
|
||||||
MOrderLine originalOrderLine = (MOrderLine) originalInOutLine.getC_OrderLine();
|
MOrderLine originalOrderLine = (MOrderLine) originalInOutLine.getC_OrderLine();
|
||||||
// Goodwill: Correct included Tax
|
// Goodwill: Correct included Tax
|
||||||
int C_Tax_ID = originalOrderLine.getC_Tax_ID();
|
int C_Tax_ID = originalOrderLine.getC_Tax_ID();
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), originalOrderLine.getC_Currency_ID());
|
||||||
if (originalOrderLine.isTaxIncluded() && C_Tax_ID != 0)
|
if (originalOrderLine.isTaxIncluded() && C_Tax_ID != 0)
|
||||||
{
|
{
|
||||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
||||||
if (!tax.isZeroTax())
|
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + costs + " - Tax=" + costTax);
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
costs = costs.subtract(costTax);
|
||||||
|
BigDecimal base = costs;
|
||||||
|
for(MTax cTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (!cTax.isZeroTax() && cTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
costTax = cTax.calculateTax(base, false, stdPrecision);
|
||||||
|
costs = costs.add(costTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tax.isZeroTax() && !tax.isDistributeTaxWithLineItem())
|
||||||
{
|
{
|
||||||
int stdPrecision = MCurrency.getStdPrecision(getCtx(), originalOrderLine.getC_Currency_ID());
|
|
||||||
BigDecimal costTax = tax.calculateTax(costs, true, stdPrecision);
|
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + costs + " - Tax=" + costTax);
|
|
||||||
costs = costs.subtract(costTax);
|
costs = costs.subtract(costTax);
|
||||||
}
|
}
|
||||||
} // correct included Tax
|
} // correct included Tax
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
BigDecimal base = costs;
|
||||||
|
for(MTax cTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (!cTax.isZeroTax() && cTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal costTax = cTax.calculateTax(base, false, stdPrecision);
|
||||||
|
costs = costs.add(costTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal costTax = tax.calculateTax(costs, false, stdPrecision);
|
||||||
|
costs = costs.add(costTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
// different currency
|
// different currency
|
||||||
if (C_Currency_ID != originalOrderLine.getC_Currency_ID())
|
if (C_Currency_ID != originalOrderLine.getC_Currency_ID())
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,9 @@ public class Doc_Invoice extends Doc
|
||||||
|
|
||||||
/** Contained Optional Tax Lines */
|
/** Contained Optional Tax Lines */
|
||||||
protected DocTax[] m_taxes = null;
|
protected DocTax[] m_taxes = null;
|
||||||
|
/** Contained Optional Tax Lines Distributed to Line Item */
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private DocTax[] m_addToLineTaxes = null;
|
||||||
/** Currency Precision */
|
/** Currency Precision */
|
||||||
protected int m_precision = -1;
|
protected int m_precision = -1;
|
||||||
/** All lines are Service */
|
/** All lines are Service */
|
||||||
|
@ -109,6 +112,7 @@ public class Doc_Invoice extends Doc
|
||||||
private DocTax[] loadTaxes()
|
private DocTax[] loadTaxes()
|
||||||
{
|
{
|
||||||
ArrayList<DocTax> list = new ArrayList<DocTax>();
|
ArrayList<DocTax> list = new ArrayList<DocTax>();
|
||||||
|
ArrayList<DocTax> distributeList = new ArrayList<DocTax>();
|
||||||
String sql = "SELECT it.C_Tax_ID, t.Name, t.Rate, it.TaxBaseAmt, it.TaxAmt, t.IsSalesTax "
|
String sql = "SELECT it.C_Tax_ID, t.Name, t.Rate, it.TaxBaseAmt, it.TaxAmt, t.IsSalesTax "
|
||||||
+ "FROM C_Tax t, C_InvoiceTax it "
|
+ "FROM C_Tax t, C_InvoiceTax it "
|
||||||
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Invoice_ID=?";
|
+ "WHERE t.C_Tax_ID=it.C_Tax_ID AND it.C_Invoice_ID=?";
|
||||||
|
@ -129,10 +133,18 @@ public class Doc_Invoice extends Doc
|
||||||
BigDecimal amount = rs.getBigDecimal(5);
|
BigDecimal amount = rs.getBigDecimal(5);
|
||||||
boolean salesTax = "Y".equals(rs.getString(6));
|
boolean salesTax = "Y".equals(rs.getString(6));
|
||||||
//
|
//
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
DocTax taxLine = new DocTax(C_Tax_ID, name, rate,
|
DocTax taxLine = new DocTax(C_Tax_ID, name, rate,
|
||||||
taxBaseAmt, amount, salesTax);
|
taxBaseAmt, amount, salesTax);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine(taxLine.toString());
|
if (log.isLoggable(Level.FINE)) log.fine(taxLine.toString());
|
||||||
list.add(taxLine);
|
if (!tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
list.add(taxLine);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
distributeList.add(taxLine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
|
@ -148,6 +160,9 @@ public class Doc_Invoice extends Doc
|
||||||
// Return Array
|
// Return Array
|
||||||
DocTax[] tl = new DocTax[list.size()];
|
DocTax[] tl = new DocTax[list.size()];
|
||||||
list.toArray(tl);
|
list.toArray(tl);
|
||||||
|
// Distribute list
|
||||||
|
m_addToLineTaxes = distributeList.toArray(new DocTax[0]);
|
||||||
|
|
||||||
return tl;
|
return tl;
|
||||||
} // loadTaxes
|
} // loadTaxes
|
||||||
|
|
||||||
|
@ -184,24 +199,33 @@ public class Doc_Invoice extends Doc
|
||||||
{
|
{
|
||||||
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, getStdPrecision());
|
BigDecimal LineNetAmtTax = tax.calculateTax(LineNetAmt, true, getStdPrecision());
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
|
if (log.isLoggable(Level.FINE)) log.fine("LineNetAmt=" + LineNetAmt + " - Tax=" + LineNetAmtTax);
|
||||||
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
|
||||||
|
|
||||||
if (tax.isSummary()) {
|
if (tax.isSummary()) {
|
||||||
|
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
||||||
|
BigDecimal base = LineNetAmt;
|
||||||
BigDecimal sumChildLineNetAmtTax = Env.ZERO;
|
BigDecimal sumChildLineNetAmtTax = Env.ZERO;
|
||||||
DocTax taxToApplyDiff = null;
|
DocTax taxToApplyDiff = null;
|
||||||
for (MTax childTax : tax.getChildTaxes(false)) {
|
for (MTax childTax : tax.getChildTaxes(false)) {
|
||||||
if (!childTax.isZeroTax())
|
if (!childTax.isZeroTax())
|
||||||
{
|
{
|
||||||
BigDecimal childLineNetAmtTax = childTax.calculateTax(LineNetAmt, false, getStdPrecision());
|
BigDecimal childLineNetAmtTax = childTax.calculateTax(base, false, getStdPrecision());
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("LineNetAmt=" + LineNetAmt + " - Child Tax=" + childLineNetAmtTax);
|
if (log.isLoggable(Level.FINE)) log.fine("LineNetAmt=" + base + " - Child Tax=" + childLineNetAmtTax);
|
||||||
for (int t = 0; t < m_taxes.length; t++)
|
if (childTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
LineNetAmt = LineNetAmt.add(childLineNetAmtTax);
|
||||||
|
LineNetAmtTax = LineNetAmtTax.subtract(childLineNetAmtTax);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (m_taxes[t].getC_Tax_ID() == childTax.getC_Tax_ID())
|
for (int t = 0; t < m_taxes.length; t++)
|
||||||
{
|
{
|
||||||
m_taxes[t].addIncludedTax(childLineNetAmtTax);
|
if (m_taxes[t].getC_Tax_ID() == childTax.getC_Tax_ID())
|
||||||
taxToApplyDiff = m_taxes[t];
|
{
|
||||||
sumChildLineNetAmtTax = sumChildLineNetAmtTax.add(childLineNetAmtTax);
|
m_taxes[t].addIncludedTax(childLineNetAmtTax);
|
||||||
break;
|
taxToApplyDiff = m_taxes[t];
|
||||||
|
sumChildLineNetAmtTax = sumChildLineNetAmtTax.add(childLineNetAmtTax);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,12 +235,16 @@ public class Doc_Invoice extends Doc
|
||||||
taxToApplyDiff.addIncludedTax(diffChildVsSummary);
|
taxToApplyDiff.addIncludedTax(diffChildVsSummary);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int t = 0; t < m_taxes.length; t++)
|
if (!tax.isDistributeTaxWithLineItem())
|
||||||
{
|
{
|
||||||
if (m_taxes[t].getC_Tax_ID() == C_Tax_ID)
|
LineNetAmt = LineNetAmt.subtract(LineNetAmtTax);
|
||||||
|
for (int t = 0; t < m_taxes.length; t++)
|
||||||
{
|
{
|
||||||
m_taxes[t].addIncludedTax(LineNetAmtTax);
|
if (m_taxes[t].getC_Tax_ID() == C_Tax_ID)
|
||||||
break;
|
{
|
||||||
|
m_taxes[t].addIncludedTax(LineNetAmtTax);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +253,29 @@ public class Doc_Invoice extends Doc
|
||||||
PriceList = PriceList.subtract(PriceListTax);
|
PriceList = PriceList.subtract(PriceListTax);
|
||||||
}
|
}
|
||||||
} // correct included Tax
|
} // correct included Tax
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), invoice.getC_Currency_ID());
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
BigDecimal base = LineNetAmt;
|
||||||
|
for(MTax cTax : cTaxes)
|
||||||
|
{
|
||||||
|
if (cTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = cTax.calculateTax(base, false, stdPrecision);
|
||||||
|
LineNetAmt = LineNetAmt.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = tax.calculateTax(LineNetAmt, false, stdPrecision);
|
||||||
|
LineNetAmt = LineNetAmt.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
docLine.setAmount (LineNetAmt, PriceList, Qty); // qty for discount calc
|
docLine.setAmount (LineNetAmt, PriceList, Qty); // qty for discount calc
|
||||||
if (docLine.isItem())
|
if (docLine.isItem())
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.compiere.model.MAcctSchema;
|
||||||
import org.compiere.model.MAcctSchemaElement;
|
import org.compiere.model.MAcctSchemaElement;
|
||||||
import org.compiere.model.MConversionRate;
|
import org.compiere.model.MConversionRate;
|
||||||
import org.compiere.model.MCostDetail;
|
import org.compiere.model.MCostDetail;
|
||||||
|
import org.compiere.model.MCurrency;
|
||||||
import org.compiere.model.MFactAcct;
|
import org.compiere.model.MFactAcct;
|
||||||
import org.compiere.model.MInOut;
|
import org.compiere.model.MInOut;
|
||||||
import org.compiere.model.MInOutLine;
|
import org.compiere.model.MInOutLine;
|
||||||
|
@ -44,6 +45,7 @@ import org.compiere.model.MInvoice;
|
||||||
import org.compiere.model.MInvoiceLine;
|
import org.compiere.model.MInvoiceLine;
|
||||||
import org.compiere.model.MMatchInv;
|
import org.compiere.model.MMatchInv;
|
||||||
import org.compiere.model.MOrderLandedCostAllocation;
|
import org.compiere.model.MOrderLandedCostAllocation;
|
||||||
|
import org.compiere.model.MTax;
|
||||||
import org.compiere.model.MUOM;
|
import org.compiere.model.MUOM;
|
||||||
import org.compiere.model.ProductCost;
|
import org.compiere.model.ProductCost;
|
||||||
import org.compiere.model.Query;
|
import org.compiere.model.Query;
|
||||||
|
@ -533,6 +535,56 @@ public class Doc_MatchInv extends Doc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tAmt = tAmt.add(LineNetAmt); //Invoice Price
|
tAmt = tAmt.add(LineNetAmt); //Invoice Price
|
||||||
|
// adjust for tax
|
||||||
|
MTax tax = MTax.get(getCtx(), m_invoiceLine.getC_Tax_ID());
|
||||||
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), m_invoiceLine.getParent().getC_Currency_ID());
|
||||||
|
if (m_invoiceLine.isTaxIncluded())
|
||||||
|
{
|
||||||
|
BigDecimal tAmtTax = tax.calculateTax(tAmt, true, stdPrecision);
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
tAmt = tAmt.subtract(tAmtTax);
|
||||||
|
BigDecimal base = tAmt;
|
||||||
|
for (MTax childTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (!childTax.isZeroTax())
|
||||||
|
{
|
||||||
|
if (childTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = childTax.calculateTax(base, false, stdPrecision);
|
||||||
|
tAmt = tAmt.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
tAmt = tAmt.subtract(tAmtTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
BigDecimal base = tAmt;
|
||||||
|
for (MTax childTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (!childTax.isZeroTax())
|
||||||
|
{
|
||||||
|
if (childTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = childTax.calculateTax(base, false, stdPrecision);
|
||||||
|
tAmt = tAmt.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = tax.calculateTax(tAmt, false, stdPrecision);
|
||||||
|
tAmt = tAmt.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Different currency
|
// Different currency
|
||||||
MInvoice invoice = m_invoiceLine.getParent();
|
MInvoice invoice = m_invoiceLine.getParent();
|
||||||
|
|
|
@ -286,17 +286,53 @@ public class Doc_MatchPO extends Doc
|
||||||
poCost = m_oLine.getPriceActual();
|
poCost = m_oLine.getPriceActual();
|
||||||
// Goodwill: Correct included Tax
|
// Goodwill: Correct included Tax
|
||||||
int C_Tax_ID = m_oLine.getC_Tax_ID();
|
int C_Tax_ID = m_oLine.getC_Tax_ID();
|
||||||
|
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
||||||
|
int stdPrecision = MCurrency.getStdPrecision(getCtx(), m_oLine.getC_Currency_ID());
|
||||||
if (m_oLine.isTaxIncluded() && C_Tax_ID != 0)
|
if (m_oLine.isTaxIncluded() && C_Tax_ID != 0)
|
||||||
{
|
{
|
||||||
MTax tax = MTax.get(getCtx(), C_Tax_ID);
|
|
||||||
if (!tax.isZeroTax())
|
if (!tax.isZeroTax())
|
||||||
{
|
{
|
||||||
int stdPrecision = MCurrency.getStdPrecision(getCtx(), m_oLine.getC_Currency_ID());
|
|
||||||
BigDecimal costTax = tax.calculateTax(poCost, true, stdPrecision);
|
BigDecimal costTax = tax.calculateTax(poCost, true, stdPrecision);
|
||||||
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + poCost + " - Tax=" + costTax);
|
if (log.isLoggable(Level.FINE)) log.fine("Costs=" + poCost + " - Tax=" + costTax);
|
||||||
poCost = poCost.subtract(costTax);
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
poCost = poCost.subtract(costTax);
|
||||||
|
BigDecimal base = poCost;
|
||||||
|
for (MTax childTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (!childTax.isZeroTax() && childTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = childTax.calculateTax(base, false, stdPrecision);
|
||||||
|
poCost = poCost.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
poCost = poCost.subtract(costTax);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // correct included Tax
|
} // correct included Tax
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tax.isSummary())
|
||||||
|
{
|
||||||
|
BigDecimal base = poCost;
|
||||||
|
for (MTax childTax : tax.getChildTaxes(false))
|
||||||
|
{
|
||||||
|
if (childTax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = childTax.calculateTax(base, false, stdPrecision);
|
||||||
|
poCost = poCost.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (tax.isDistributeTaxWithLineItem())
|
||||||
|
{
|
||||||
|
BigDecimal taxAmt = tax.calculateTax(poCost, false, stdPrecision);
|
||||||
|
poCost = poCost.add(taxAmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MInOutLine receiptLine = new MInOutLine (getCtx(), m_M_InOutLine_ID, getTrxName());
|
MInOutLine receiptLine = new MInOutLine (getCtx(), m_M_InOutLine_ID, getTrxName());
|
||||||
|
@ -383,7 +419,7 @@ public class Doc_MatchPO extends Doc
|
||||||
|
|
||||||
if (MAcctSchema.COSTINGMETHOD_StandardCosting.equals(costingMethod))
|
if (MAcctSchema.COSTINGMETHOD_StandardCosting.equals(costingMethod))
|
||||||
{
|
{
|
||||||
if (m_matchPO.getReversal_ID() > 0)
|
if (m_matchPO.isReversal())
|
||||||
{
|
{
|
||||||
// Product PPV
|
// Product PPV
|
||||||
FactLine cr = fact.createLine(null,
|
FactLine cr = fact.createLine(null,
|
||||||
|
@ -582,7 +618,7 @@ public class Doc_MatchPO extends Doc
|
||||||
tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost);
|
tAmt = tAmt.add(isReturnTrx ? poCost.negate() : poCost);
|
||||||
tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty());
|
tQty = tQty.add(isReturnTrx ? getQty().negate() : getQty());
|
||||||
|
|
||||||
if (mMatchPO.getReversal_ID() > 0)
|
if (mMatchPO.isReversal())
|
||||||
{
|
{
|
||||||
String error = createLandedCostAdjustments(as, landedCostMap, mMatchPO, tQty);
|
String error = createLandedCostAdjustments(as, landedCostMap, mMatchPO, tQty);
|
||||||
if (!Util.isEmpty(error))
|
if (!Util.isEmpty(error))
|
||||||
|
@ -601,7 +637,7 @@ public class Doc_MatchPO extends Doc
|
||||||
return "SaveError";
|
return "SaveError";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMatchPO.getReversal_ID() <= 0)
|
if (!mMatchPO.isReversal())
|
||||||
{
|
{
|
||||||
String error = createLandedCostAdjustments(as, landedCostMap, mMatchPO, tQty);
|
String error = createLandedCostAdjustments(as, landedCostMap, mMatchPO, tQty);
|
||||||
if (!Util.isEmpty(error))
|
if (!Util.isEmpty(error))
|
||||||
|
|
|
@ -22,7 +22,7 @@ import org.compiere.util.KeyNamePair;
|
||||||
|
|
||||||
/** Generated Interface for C_Tax
|
/** Generated Interface for C_Tax
|
||||||
* @author iDempiere (generated)
|
* @author iDempiere (generated)
|
||||||
* @version Release 9
|
* @version Release 10
|
||||||
*/
|
*/
|
||||||
public interface I_C_Tax
|
public interface I_C_Tax
|
||||||
{
|
{
|
||||||
|
@ -44,8 +44,8 @@ public interface I_C_Tax
|
||||||
/** Column name AD_Client_ID */
|
/** Column name AD_Client_ID */
|
||||||
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
|
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
|
||||||
|
|
||||||
/** Get Client.
|
/** Get Tenant.
|
||||||
* Client/Tenant for this installation.
|
* Tenant for this installation.
|
||||||
*/
|
*/
|
||||||
public int getAD_Client_ID();
|
public int getAD_Client_ID();
|
||||||
|
|
||||||
|
@ -53,12 +53,12 @@ public interface I_C_Tax
|
||||||
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
|
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
|
||||||
|
|
||||||
/** Set Organization.
|
/** Set Organization.
|
||||||
* Organizational entity within client
|
* Organizational entity within tenant
|
||||||
*/
|
*/
|
||||||
public void setAD_Org_ID (int AD_Org_ID);
|
public void setAD_Org_ID (int AD_Org_ID);
|
||||||
|
|
||||||
/** Get Organization.
|
/** Get Organization.
|
||||||
* Organizational entity within client
|
* Organizational entity within tenant
|
||||||
*/
|
*/
|
||||||
public int getAD_Org_ID();
|
public int getAD_Org_ID();
|
||||||
|
|
||||||
|
@ -358,6 +358,15 @@ public interface I_C_Tax
|
||||||
*/
|
*/
|
||||||
public String getTaxIndicator();
|
public String getTaxIndicator();
|
||||||
|
|
||||||
|
/** Column name TaxPostingIndicator */
|
||||||
|
public static final String COLUMNNAME_TaxPostingIndicator = "TaxPostingIndicator";
|
||||||
|
|
||||||
|
/** Set Posting Indicator */
|
||||||
|
public void setTaxPostingIndicator (String TaxPostingIndicator);
|
||||||
|
|
||||||
|
/** Get Posting Indicator */
|
||||||
|
public String getTaxPostingIndicator();
|
||||||
|
|
||||||
/** Column name To_Country_ID */
|
/** Column name To_Country_ID */
|
||||||
public static final String COLUMNNAME_To_Country_ID = "To_Country_ID";
|
public static final String COLUMNNAME_To_Country_ID = "To_Country_ID";
|
||||||
|
|
||||||
|
|
|
@ -943,14 +943,49 @@ public class MInvoiceLine extends X_C_InvoiceLine
|
||||||
* author teo_sarca [ 1583825 ]
|
* author teo_sarca [ 1583825 ]
|
||||||
*/
|
*/
|
||||||
protected boolean updateInvoiceTax(boolean oldTax) {
|
protected boolean updateInvoiceTax(boolean oldTax) {
|
||||||
MInvoiceTax tax = MInvoiceTax.get (this, getPrecision(), oldTax, get_TrxName());
|
int C_Tax_ID = getC_Tax_ID();
|
||||||
if (tax != null) {
|
boolean isOldTax = oldTax && is_ValueChanged(MInvoiceTax.COLUMNNAME_C_Tax_ID);
|
||||||
if (!tax.calculateTaxFromLines())
|
if (isOldTax)
|
||||||
return false;
|
{
|
||||||
|
Object old = get_ValueOld(MInvoiceTax.COLUMNNAME_C_Tax_ID);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// red1 - solving BUGS #[ 1701331 ] , #[ 1786103 ]
|
MTax t = MTax.get(C_Tax_ID);
|
||||||
if (!tax.save(get_TrxName()))
|
if (t.isSummary())
|
||||||
return false;
|
{
|
||||||
|
MInvoiceTax[] invoiceTaxes = MInvoiceTax.getChildTaxes(this, getPrecision(), oldTax, get_TrxName());
|
||||||
|
if (invoiceTaxes != null && invoiceTaxes.length > 0)
|
||||||
|
{
|
||||||
|
for(MInvoiceTax tax : invoiceTaxes)
|
||||||
|
{
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MInvoiceTax tax = MInvoiceTax.get (this, getPrecision(), oldTax, get_TrxName());
|
||||||
|
if (tax != null) {
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// red1 - solving BUGS #[ 1701331 ] , #[ 1786103 ]
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.math.BigDecimal;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@ -104,6 +106,74 @@ public class MInvoiceTax extends X_C_InvoiceTax
|
||||||
return retValue;
|
return retValue;
|
||||||
} // get
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Child Tax Lines for Invoice Line
|
||||||
|
* @param line invoice line
|
||||||
|
* @param precision currency precision
|
||||||
|
* @param oldTax if true old tax is returned
|
||||||
|
* @param trxName transaction name
|
||||||
|
* @return existing or new tax
|
||||||
|
*/
|
||||||
|
public static MInvoiceTax[] getChildTaxes(MInvoiceLine line, int precision,
|
||||||
|
boolean oldTax, String trxName)
|
||||||
|
{
|
||||||
|
List<MInvoiceTax> invoiceTaxes = new ArrayList<MInvoiceTax>();
|
||||||
|
|
||||||
|
if (line == null || line.getC_Invoice_ID() == 0)
|
||||||
|
return invoiceTaxes.toArray(new MInvoiceTax[0]);
|
||||||
|
|
||||||
|
int C_Tax_ID = line.getC_Tax_ID();
|
||||||
|
if (oldTax)
|
||||||
|
{
|
||||||
|
Object old = line.get_ValueOld(MInvoiceLine.COLUMNNAME_C_Tax_ID);
|
||||||
|
if (old == null)
|
||||||
|
return invoiceTaxes.toArray(new MInvoiceTax[0]);
|
||||||
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return invoiceTaxes.toArray(new MInvoiceTax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTax tax = MTax.get(C_Tax_ID);
|
||||||
|
if (!tax.isSummary())
|
||||||
|
return invoiceTaxes.toArray(new MInvoiceTax[0]);
|
||||||
|
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
for(MTax cTax : cTaxes) {
|
||||||
|
MInvoiceTax invoiceTax = new Query(line.getCtx(), Table_Name, "C_Invoice_ID=? AND C_Tax_ID=?", trxName)
|
||||||
|
.setParameters(line.getC_Invoice_ID(), cTax.getC_Tax_ID())
|
||||||
|
.firstOnly();
|
||||||
|
if (invoiceTax != null)
|
||||||
|
{
|
||||||
|
invoiceTax.set_TrxName(trxName);
|
||||||
|
invoiceTax.setPrecision(precision);
|
||||||
|
invoiceTaxes.add(invoiceTax);
|
||||||
|
}
|
||||||
|
// If the old tax was required and there is no MInvoiceTax for that
|
||||||
|
// return null, and not create another MInvoiceTax - teo_sarca [ 1583825 ]
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oldTax)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invoiceTax == null)
|
||||||
|
{
|
||||||
|
// Create New
|
||||||
|
invoiceTax = new MInvoiceTax(line.getCtx(), 0, trxName);
|
||||||
|
invoiceTax.set_TrxName(trxName);
|
||||||
|
invoiceTax.setClientOrg(line);
|
||||||
|
invoiceTax.setC_Invoice_ID(line.getC_Invoice_ID());
|
||||||
|
invoiceTax.setC_Tax_ID(line.getC_Tax_ID());
|
||||||
|
invoiceTax.setPrecision(precision);
|
||||||
|
invoiceTax.setIsTaxIncluded(line.isTaxIncluded());
|
||||||
|
invoiceTaxes.add(invoiceTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invoiceTaxes.toArray(new MInvoiceTax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (MInvoiceTax.class);
|
private static CLogger s_log = CLogger.getCLogger (MInvoiceTax.class);
|
||||||
|
|
||||||
|
|
|
@ -1422,4 +1422,16 @@ public class MMatchPO extends X_M_MatchPO
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this is created to reverse another match po document
|
||||||
|
*/
|
||||||
|
public boolean isReversal() {
|
||||||
|
if (getReversal_ID() > 0) {
|
||||||
|
MMatchPO reversal = new MMatchPO (getCtx(), getReversal_ID(), get_TrxName());
|
||||||
|
if (reversal.getM_MatchPO_ID() < getM_MatchPO_ID())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} // MMatchPO
|
} // MMatchPO
|
||||||
|
|
|
@ -980,17 +980,57 @@ public class MOrderLine extends X_C_OrderLine
|
||||||
* author teo_sarca [ 1583825 ]
|
* author teo_sarca [ 1583825 ]
|
||||||
*/
|
*/
|
||||||
public boolean updateOrderTax(boolean oldTax) {
|
public boolean updateOrderTax(boolean oldTax) {
|
||||||
MOrderTax tax = MOrderTax.get (this, getPrecision(), oldTax, get_TrxName());
|
int C_Tax_ID = getC_Tax_ID();
|
||||||
if (tax != null) {
|
boolean isOldTax = oldTax && is_ValueChanged(MOrderLine.COLUMNNAME_C_Tax_ID);
|
||||||
if (!tax.calculateTaxFromLines())
|
if (isOldTax)
|
||||||
return false;
|
{
|
||||||
if (tax.getTaxAmt().signum() != 0) {
|
Object old = get_ValueOld(MOrderLine.COLUMNNAME_C_Tax_ID);
|
||||||
if (!tax.save(get_TrxName()))
|
if (old == null)
|
||||||
return false;
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTax t = MTax.get(C_Tax_ID);
|
||||||
|
if (t.isSummary())
|
||||||
|
{
|
||||||
|
MOrderTax[] taxes = MOrderTax.getChildTaxes(this, getPrecision(), isOldTax, get_TrxName());
|
||||||
|
if (taxes != null && taxes.length > 0)
|
||||||
|
{
|
||||||
|
for(MOrderTax tax : taxes)
|
||||||
|
{
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
|
return false;
|
||||||
|
if (tax.getTaxAmt().signum() != 0) {
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOrderTax tax = MOrderTax.get (this, getPrecision(), oldTax, get_TrxName());
|
||||||
|
if (tax != null) {
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
return false;
|
return false;
|
||||||
|
if (tax.getTaxAmt().signum() != 0) {
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.compiere.model;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@ -124,6 +126,99 @@ public class MOrderTax extends X_C_OrderTax
|
||||||
return retValue;
|
return retValue;
|
||||||
} // get
|
} // get
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Child Tax Line for Order Line
|
||||||
|
* @param line Order line
|
||||||
|
* @param precision currency precision
|
||||||
|
* @param oldTax get old tax
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or new tax
|
||||||
|
*/
|
||||||
|
public static MOrderTax[] getChildTaxes(MOrderLine line, int precision,
|
||||||
|
boolean oldTax, String trxName)
|
||||||
|
{
|
||||||
|
List<MOrderTax> orderTaxes = new ArrayList<MOrderTax>();
|
||||||
|
|
||||||
|
if (line == null || line.getC_Order_ID() == 0)
|
||||||
|
{
|
||||||
|
return orderTaxes.toArray(new MOrderTax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int C_Tax_ID = line.getC_Tax_ID();
|
||||||
|
if (oldTax)
|
||||||
|
{
|
||||||
|
Object old = line.get_ValueOld(MOrderTax.COLUMNNAME_C_Tax_ID);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return orderTaxes.toArray(new MOrderTax[0]);
|
||||||
|
}
|
||||||
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return orderTaxes.toArray(new MOrderTax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTax tax = MTax.get(C_Tax_ID);
|
||||||
|
if (!tax.isSummary())
|
||||||
|
return orderTaxes.toArray(new MOrderTax[0]);
|
||||||
|
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
for(MTax cTax : cTaxes) {
|
||||||
|
MOrderTax orderTax = null;
|
||||||
|
String sql = "SELECT * FROM C_OrderTax WHERE C_Order_ID=? AND C_Tax_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, line.getC_Order_ID());
|
||||||
|
pstmt.setInt (2, cTax.getC_Tax_ID());
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
orderTax = new MOrderTax (line.getCtx(), rs, trxName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null;
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
if (orderTax != null)
|
||||||
|
{
|
||||||
|
orderTax.setPrecision(precision);
|
||||||
|
orderTax.set_TrxName(trxName);
|
||||||
|
orderTaxes.add(orderTax);
|
||||||
|
}
|
||||||
|
// If the old tax was required and there is no MOrderTax for that
|
||||||
|
// return null, and not create another MOrderTax - teo_sarca [ 1583825 ]
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oldTax)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderTax == null)
|
||||||
|
{
|
||||||
|
// Create New
|
||||||
|
orderTax = new MOrderTax(line.getCtx(), 0, trxName);
|
||||||
|
orderTax.set_TrxName(trxName);
|
||||||
|
orderTax.setClientOrg(line);
|
||||||
|
orderTax.setC_Order_ID(line.getC_Order_ID());
|
||||||
|
orderTax.setC_Tax_ID(line.getC_Tax_ID());
|
||||||
|
orderTax.setPrecision(precision);
|
||||||
|
orderTax.setIsTaxIncluded(line.isTaxIncluded());
|
||||||
|
orderTaxes.add(orderTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderTaxes.toArray(new MOrderTax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (MOrderTax.class);
|
private static CLogger s_log = CLogger.getCLogger (MOrderTax.class);
|
||||||
|
|
||||||
|
|
|
@ -378,22 +378,69 @@ public class MRMALine extends X_M_RMALine
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param oldTax true if the old C_Tax_ID should be used
|
||||||
|
* @return true if success, false otherwise
|
||||||
|
*/
|
||||||
protected boolean updateOrderTax(boolean oldTax)
|
protected boolean updateOrderTax(boolean oldTax)
|
||||||
{
|
{
|
||||||
MRMATax tax = MRMATax.get (this, getPrecision(), oldTax, get_TrxName());
|
int C_Tax_ID = getC_Tax_ID();
|
||||||
if (tax != null)
|
boolean isOldTax = oldTax && is_ValueChanged(MRMALine.COLUMNNAME_C_Tax_ID);
|
||||||
|
if (isOldTax)
|
||||||
{
|
{
|
||||||
if (!tax.calculateTaxFromLines())
|
Object old = get_ValueOld(MRMALine.COLUMNNAME_C_Tax_ID);
|
||||||
return false;
|
if (old == null)
|
||||||
if (tax.getTaxAmt().signum() != 0)
|
|
||||||
{
|
{
|
||||||
if (!tax.save(get_TrxName()))
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTax t = MTax.get(C_Tax_ID);
|
||||||
|
if (t.isSummary())
|
||||||
|
{
|
||||||
|
MRMATax[] taxes = MRMATax.getChildTaxes(this, getPrecision(), oldTax, get_TrxName());
|
||||||
|
if (taxes != null && taxes.length > 0)
|
||||||
{
|
{
|
||||||
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
for(MRMATax tax : taxes)
|
||||||
|
{
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
|
return false;
|
||||||
|
if (tax.getTaxAmt().signum() != 0)
|
||||||
|
{
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MRMATax tax = MRMATax.get (this, getPrecision(), oldTax, get_TrxName());
|
||||||
|
if (tax != null)
|
||||||
|
{
|
||||||
|
if (!tax.calculateTaxFromLines())
|
||||||
return false;
|
return false;
|
||||||
|
if (tax.getTaxAmt().signum() != 0)
|
||||||
|
{
|
||||||
|
if (!tax.save(get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!tax.is_new() && !tax.delete(false, get_TrxName()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -16,6 +16,8 @@ package org.compiere.model;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@ -118,6 +120,96 @@ public class MRMATax extends X_M_RMATax
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Child Tax Lines for RMA Line
|
||||||
|
* @param line RMA line
|
||||||
|
* @param precision currency precision
|
||||||
|
* @param oldTax get old tax
|
||||||
|
* @param trxName transaction
|
||||||
|
* @return existing or new tax
|
||||||
|
*/
|
||||||
|
public static MRMATax[] getChildTaxes(MRMALine line, int precision,
|
||||||
|
boolean oldTax, String trxName)
|
||||||
|
{
|
||||||
|
List<MRMATax> rmaTaxes = new ArrayList<MRMATax>();
|
||||||
|
if (line == null || line.getM_RMA_ID() == 0)
|
||||||
|
{
|
||||||
|
return rmaTaxes.toArray(new MRMATax[0]);
|
||||||
|
}
|
||||||
|
int C_Tax_ID = line.getC_Tax_ID();
|
||||||
|
if (oldTax)
|
||||||
|
{
|
||||||
|
Object old = line.get_ValueOld(MRMATax.COLUMNNAME_C_Tax_ID);
|
||||||
|
if (old == null)
|
||||||
|
{
|
||||||
|
return rmaTaxes.toArray(new MRMATax[0]);
|
||||||
|
}
|
||||||
|
C_Tax_ID = ((Integer)old).intValue();
|
||||||
|
}
|
||||||
|
if (C_Tax_ID == 0)
|
||||||
|
{
|
||||||
|
return rmaTaxes.toArray(new MRMATax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTax tax = MTax.get(C_Tax_ID);
|
||||||
|
if (!tax.isSummary())
|
||||||
|
return rmaTaxes.toArray(new MRMATax[0]);
|
||||||
|
|
||||||
|
MTax[] cTaxes = tax.getChildTaxes(false);
|
||||||
|
for(MTax cTax : cTaxes) {
|
||||||
|
MRMATax rmaTax = null;
|
||||||
|
String sql = "SELECT * FROM M_RMATax WHERE M_RMA_ID=? AND C_Tax_ID=?";
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
pstmt = DB.prepareStatement (sql, trxName);
|
||||||
|
pstmt.setInt (1, line.getM_RMA_ID());
|
||||||
|
pstmt.setInt (2, cTax.getC_Tax_ID());
|
||||||
|
rs = pstmt.executeQuery ();
|
||||||
|
if (rs.next ())
|
||||||
|
rmaTax = new MRMATax (line.getCtx(), rs, trxName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
s_log.log(Level.SEVERE, sql, e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
DB.close(rs, pstmt);
|
||||||
|
rs = null;
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
if (rmaTax != null)
|
||||||
|
{
|
||||||
|
rmaTax.setPrecision(precision);
|
||||||
|
rmaTax.set_TrxName(trxName);
|
||||||
|
rmaTaxes.add(rmaTax);
|
||||||
|
}
|
||||||
|
// If the old tax was required and there is no MOrderTax for that
|
||||||
|
// return null, and not create another MOrderTax - teo_sarca [ 1583825 ]
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (oldTax)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rmaTax == null)
|
||||||
|
{
|
||||||
|
// Create New
|
||||||
|
rmaTax = new MRMATax(line.getCtx(), 0, trxName);
|
||||||
|
rmaTax.set_TrxName(trxName);
|
||||||
|
rmaTax.setClientOrg(line);
|
||||||
|
rmaTax.setM_RMA_ID(line.getM_RMA_ID());
|
||||||
|
rmaTax.setC_Tax_ID(line.getC_Tax_ID());
|
||||||
|
rmaTax.setPrecision(precision);
|
||||||
|
rmaTax.setIsTaxIncluded(line.getParent().isTaxIncluded());
|
||||||
|
rmaTaxes.add(rmaTax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rmaTaxes.toArray(new MRMATax[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/** Static Logger */
|
/** Static Logger */
|
||||||
private static CLogger s_log = CLogger.getCLogger (MRMATax.class);
|
private static CLogger s_log = CLogger.getCLogger (MRMATax.class);
|
||||||
|
|
||||||
|
|
|
@ -411,4 +411,12 @@ public class MTax extends X_C_Tax implements ImmutablePOSupport
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true if input tax is added to product cost
|
||||||
|
*/
|
||||||
|
public boolean isDistributeTaxWithLineItem()
|
||||||
|
{
|
||||||
|
return TAXPOSTINGINDICATOR_DistributeTaxWithRelevantExpense.equals(getTaxPostingIndicator());
|
||||||
|
}
|
||||||
} // MTax
|
} // MTax
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.compiere.util.KeyNamePair;
|
||||||
|
|
||||||
/** Generated Model for C_Tax
|
/** Generated Model for C_Tax
|
||||||
* @author iDempiere (generated)
|
* @author iDempiere (generated)
|
||||||
* @version Release 9 - $Id$ */
|
* @version Release 10 - $Id$ */
|
||||||
@org.adempiere.base.Model(table="C_Tax")
|
@org.adempiere.base.Model(table="C_Tax")
|
||||||
public class X_C_Tax extends PO implements I_C_Tax, I_Persistent
|
public class X_C_Tax extends PO implements I_C_Tax, I_Persistent
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ public class X_C_Tax extends PO implements I_C_Tax, I_Persistent
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 20220116L;
|
private static final long serialVersionUID = 20220329L;
|
||||||
|
|
||||||
/** Standard Constructor */
|
/** Standard Constructor */
|
||||||
public X_C_Tax (Properties ctx, int C_Tax_ID, String trxName)
|
public X_C_Tax (Properties ctx, int C_Tax_ID, String trxName)
|
||||||
|
@ -599,6 +599,28 @@ public class X_C_Tax extends PO implements I_C_Tax, I_Persistent
|
||||||
return (String)get_Value(COLUMNNAME_TaxIndicator);
|
return (String)get_Value(COLUMNNAME_TaxIndicator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** TaxPostingIndicator AD_Reference_ID=200160 */
|
||||||
|
public static final int TAXPOSTINGINDICATOR_AD_Reference_ID=200160;
|
||||||
|
/** Separate Tax Posting = 0 */
|
||||||
|
public static final String TAXPOSTINGINDICATOR_SeparateTaxPosting = "0";
|
||||||
|
/** Distribute Tax with Relevant Expense = 1 */
|
||||||
|
public static final String TAXPOSTINGINDICATOR_DistributeTaxWithRelevantExpense = "1";
|
||||||
|
/** Set Posting Indicator.
|
||||||
|
@param TaxPostingIndicator Posting Indicator
|
||||||
|
*/
|
||||||
|
public void setTaxPostingIndicator (String TaxPostingIndicator)
|
||||||
|
{
|
||||||
|
|
||||||
|
set_Value (COLUMNNAME_TaxPostingIndicator, TaxPostingIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get Posting Indicator.
|
||||||
|
@return Posting Indicator */
|
||||||
|
public String getTaxPostingIndicator()
|
||||||
|
{
|
||||||
|
return (String)get_Value(COLUMNNAME_TaxPostingIndicator);
|
||||||
|
}
|
||||||
|
|
||||||
/** Set To.
|
/** Set To.
|
||||||
@param To_Country_ID Receiving Country
|
@param To_Country_ID Receiving Country
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,14 +25,44 @@
|
||||||
package org.idempiere.test.model;
|
package org.idempiere.test.model;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
import org.adempiere.base.Core;
|
import org.adempiere.base.Core;
|
||||||
|
import org.compiere.model.MAccount;
|
||||||
|
import org.compiere.model.MAcctSchema;
|
||||||
import org.compiere.model.MBPartner;
|
import org.compiere.model.MBPartner;
|
||||||
|
import org.compiere.model.MClientInfo;
|
||||||
|
import org.compiere.model.MCost;
|
||||||
|
import org.compiere.model.MDocType;
|
||||||
|
import org.compiere.model.MFactAcct;
|
||||||
|
import org.compiere.model.MInOut;
|
||||||
|
import org.compiere.model.MInOutLine;
|
||||||
|
import org.compiere.model.MInvoice;
|
||||||
|
import org.compiere.model.MInvoiceLine;
|
||||||
|
import org.compiere.model.MMatchPO;
|
||||||
|
import org.compiere.model.MOrder;
|
||||||
|
import org.compiere.model.MOrderLine;
|
||||||
|
import org.compiere.model.MPriceList;
|
||||||
|
import org.compiere.model.MPriceListVersion;
|
||||||
|
import org.compiere.model.MProduct;
|
||||||
|
import org.compiere.model.MProductPrice;
|
||||||
import org.compiere.model.MTax;
|
import org.compiere.model.MTax;
|
||||||
|
import org.compiere.model.MTaxCategory;
|
||||||
|
import org.compiere.model.MWarehouse;
|
||||||
|
import org.compiere.model.ProductCost;
|
||||||
import org.compiere.model.Tax;
|
import org.compiere.model.Tax;
|
||||||
|
import org.compiere.process.DocAction;
|
||||||
|
import org.compiere.process.DocumentEngine;
|
||||||
|
import org.compiere.process.ProcessInfo;
|
||||||
|
import org.compiere.util.CacheMgt;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.TimeUtil;
|
import org.compiere.util.TimeUtil;
|
||||||
|
import org.compiere.wf.MWorkflow;
|
||||||
import org.idempiere.test.AbstractTestCase;
|
import org.idempiere.test.AbstractTestCase;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -46,8 +76,11 @@ public class MTaxTest extends AbstractTestCase {
|
||||||
private static final int STANDARD_TAX_ID = 104;
|
private static final int STANDARD_TAX_ID = 104;
|
||||||
private static final int STANDARD_TAX_CATEGORY_ID=107;
|
private static final int STANDARD_TAX_CATEGORY_ID=107;
|
||||||
|
|
||||||
private final static int BP_JOE_BLOCK = 118;
|
private static final int BP_JOE_BLOCK_ID = 118;
|
||||||
private static final int PRODUCT_MULCH = 137;
|
private static final int PRODUCT_MULCH_ID = 137;
|
||||||
|
private static final int PURCHASE_PRICE_LIST_ID = 102;
|
||||||
|
private static final int BP_PATIO_ID = 121;
|
||||||
|
private static final int MM_RECEIPT_DOCTYPE_ID = 122;
|
||||||
|
|
||||||
public MTaxTest() {
|
public MTaxTest() {
|
||||||
}
|
}
|
||||||
|
@ -73,20 +106,308 @@ public class MTaxTest extends AbstractTestCase {
|
||||||
int taxExemptId = Tax.getExemptTax(Env.getCtx(), getAD_Org_ID(), getTrxName());
|
int taxExemptId = Tax.getExemptTax(Env.getCtx(), getAD_Org_ID(), getTrxName());
|
||||||
assertTrue(taxExemptId>0, "Fail to get tax exempt Id");
|
assertTrue(taxExemptId>0, "Fail to get tax exempt Id");
|
||||||
|
|
||||||
MBPartner bp = new MBPartner(Env.getCtx(), BP_JOE_BLOCK, getTrxName());
|
MBPartner bp = new MBPartner(Env.getCtx(), BP_JOE_BLOCK_ID, getTrxName());
|
||||||
bp.setIsTaxExempt(true);
|
bp.setIsTaxExempt(true);
|
||||||
bp.saveEx();
|
bp.saveEx();
|
||||||
|
|
||||||
int id = Core.getTaxLookup().get(Env.getCtx(), PRODUCT_MULCH, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
int id = Core.getTaxLookup().get(Env.getCtx(), PRODUCT_MULCH_ID, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||||
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
||||||
assertEquals(taxExemptId, id, "Unexpected tax id");
|
assertEquals(taxExemptId, id, "Unexpected tax id");
|
||||||
|
|
||||||
bp.setIsTaxExempt(false);
|
bp.setIsTaxExempt(false);
|
||||||
bp.saveEx();
|
bp.saveEx();
|
||||||
|
|
||||||
id = Core.getTaxLookup().get(Env.getCtx(), PRODUCT_MULCH, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
id = Core.getTaxLookup().get(Env.getCtx(), PRODUCT_MULCH_ID, 0, getLoginDate(), getLoginDate(), getAD_Org_ID(), getM_Warehouse_ID(),
|
||||||
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
bp.getPrimaryC_BPartner_Location_ID(), bp.getPrimaryC_BPartner_Location_ID(), true, null, getTrxName());
|
||||||
assertTrue(id != taxExemptId, "Unexpected tax id: " + id);
|
assertTrue(id != taxExemptId, "Unexpected tax id: " + id);
|
||||||
assertEquals(STANDARD_TAX_ID, id, "Unexpected tax id");
|
assertEquals(STANDARD_TAX_ID, id, "Unexpected tax id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDistributeTaxToProductCost() {
|
||||||
|
MProduct product = null;
|
||||||
|
MTaxCategory category = null;
|
||||||
|
MTax tax = null;
|
||||||
|
try {
|
||||||
|
category = new MTaxCategory(Env.getCtx(), 0, null);
|
||||||
|
category.setName("testDistributeTaxToProductCost");
|
||||||
|
category.saveEx();
|
||||||
|
|
||||||
|
//need to create tax without trx as tax is cache
|
||||||
|
tax = new MTax(Env.getCtx(), 0, null);
|
||||||
|
tax.setC_TaxCategory_ID(category.get_ID());
|
||||||
|
tax.setIsDocumentLevel(false);
|
||||||
|
tax.setIsSummary(false);
|
||||||
|
tax.setRate(new BigDecimal("5.00"));
|
||||||
|
tax.setTaxPostingIndicator(MTax.TAXPOSTINGINDICATOR_DistributeTaxWithRelevantExpense);
|
||||||
|
tax.setSOPOType(MTax.SOPOTYPE_PurchaseTax);
|
||||||
|
tax.setName("testDistributeTaxToProductCost");
|
||||||
|
tax.saveEx();
|
||||||
|
CacheMgt.get().reset();
|
||||||
|
|
||||||
|
//need to create product with trx as order line get product from cache
|
||||||
|
MProduct p = MProduct.get(PRODUCT_MULCH_ID);
|
||||||
|
product = new MProduct(Env.getCtx(), 0, null);
|
||||||
|
product.setM_Product_Category_ID(p.getM_Product_Category_ID());
|
||||||
|
product.setC_TaxCategory_ID(category.get_ID());
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setIsPurchased(true);
|
||||||
|
product.setIsSold(true);
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||||
|
product.setName("testDistributeTaxToProductCost");
|
||||||
|
product.setC_UOM_ID(p.getC_UOM_ID());
|
||||||
|
product.saveEx();
|
||||||
|
|
||||||
|
MPriceList priceList = MPriceList.get(PURCHASE_PRICE_LIST_ID);
|
||||||
|
MPriceListVersion priceListVersion = priceList.getPriceListVersion(null);
|
||||||
|
MProductPrice productPrice = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||||
|
productPrice.setM_PriceList_Version_ID(priceListVersion.get_ID());
|
||||||
|
productPrice.setM_Product_ID(product.getM_Product_ID());
|
||||||
|
productPrice.setPrices(new BigDecimal("2.00"), new BigDecimal("2.00"), new BigDecimal("2.00"));
|
||||||
|
productPrice.saveEx();
|
||||||
|
|
||||||
|
//purchase price of 2 + 5% tax
|
||||||
|
BigDecimal expectedCost = new BigDecimal("2.00").add(new BigDecimal("2.00").multiply(new BigDecimal("0.05"))).setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
MBPartner bpartner = MBPartner.get(Env.getCtx(), BP_PATIO_ID);
|
||||||
|
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||||
|
order.setBPartner(bpartner);
|
||||||
|
order.setIsSOTrx(false);
|
||||||
|
order.setC_DocTypeTarget_ID();
|
||||||
|
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||||
|
order.setDocAction(DocAction.ACTION_Complete);
|
||||||
|
order.saveEx();
|
||||||
|
|
||||||
|
MOrderLine orderLine = new MOrderLine(order);
|
||||||
|
orderLine.setLine(10);
|
||||||
|
orderLine.setProduct(product);
|
||||||
|
orderLine.setQty(new BigDecimal("1"));
|
||||||
|
orderLine.setTax();
|
||||||
|
orderLine.saveEx();
|
||||||
|
|
||||||
|
assertEquals(tax.get_ID(), orderLine.getC_Tax_ID(), "Un-expected tax id");
|
||||||
|
|
||||||
|
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
order.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||||
|
assertEquals(expectedCost, order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), "Un-expected order grand total");
|
||||||
|
|
||||||
|
MInOut receipt = new MInOut(order, MM_RECEIPT_DOCTYPE_ID, order.getDateOrdered()); // MM Receipt
|
||||||
|
receipt.saveEx();
|
||||||
|
|
||||||
|
MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID());
|
||||||
|
int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||||
|
|
||||||
|
MInOutLine receiptLine = new MInOutLine(receipt);
|
||||||
|
receiptLine.setOrderLine(orderLine, M_Locator_ID, new BigDecimal("1"));
|
||||||
|
receiptLine.setLine(10);
|
||||||
|
receiptLine.setQty(new BigDecimal("1"));
|
||||||
|
receiptLine.saveEx();
|
||||||
|
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
receipt.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus());
|
||||||
|
MInvoice invoice = new MInvoice(order, MDocType.getOfDocBaseType(Env.getCtx(), MDocType.DOCBASETYPE_APInvoice)[0].getC_DocType_ID(), order.getDateAcct());
|
||||||
|
invoice.setDocStatus(DocAction.STATUS_Drafted);
|
||||||
|
invoice.setDocAction(DocAction.ACTION_Complete);
|
||||||
|
invoice.saveEx();
|
||||||
|
|
||||||
|
MInvoiceLine invoiceLine = new MInvoiceLine(invoice);
|
||||||
|
invoiceLine.setShipLine(receiptLine);
|
||||||
|
invoiceLine.setLine(10);
|
||||||
|
invoiceLine.setProduct(product);
|
||||||
|
invoiceLine.setQty(new BigDecimal("1"));
|
||||||
|
invoiceLine.saveEx();
|
||||||
|
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
invoice.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus());
|
||||||
|
|
||||||
|
//ensure match po have been posted
|
||||||
|
MMatchPO[] matchPOs = MMatchPO.getOrderLine(Env.getCtx(), orderLine.get_ID(), getTrxName());
|
||||||
|
assertNotNull(matchPOs, "Can't retrive match po for order line");
|
||||||
|
assertEquals(1, matchPOs.length, "Un-expected number of match po record for order line");
|
||||||
|
if (!matchPOs[0].isPosted())
|
||||||
|
DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MMatchPO.Table_ID, matchPOs[0].get_ID(), true, getTrxName());
|
||||||
|
ProductCost productCost = new ProductCost(Env.getCtx(), product.get_ID(), 0, getTrxName());
|
||||||
|
productCost.setQty(new BigDecimal("1"));
|
||||||
|
MAcctSchema schema = MClientInfo.get().getMAcctSchema1();
|
||||||
|
BigDecimal averageCost = productCost.getProductCosts(schema, getAD_Org_ID(), MCost.COSTINGMETHOD_AveragePO, 0, true);
|
||||||
|
if (averageCost == null)
|
||||||
|
averageCost = BigDecimal.ZERO;
|
||||||
|
averageCost = averageCost.setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
assertEquals(expectedCost, averageCost, "Un-expected average cost");
|
||||||
|
|
||||||
|
MAccount acctAsset = productCost.getAccount(ProductCost.ACCTTYPE_P_Asset, schema);
|
||||||
|
String whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MInOut.Table_ID
|
||||||
|
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + receipt.get_ID()
|
||||||
|
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + schema.getC_AcctSchema_ID();
|
||||||
|
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName());
|
||||||
|
BigDecimal totalDebit = new BigDecimal("0.00");
|
||||||
|
for(int id : ids) {
|
||||||
|
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||||
|
if (fa.getAccount_ID() == acctAsset.getAccount_ID()) {
|
||||||
|
totalDebit = totalDebit.add(fa.getAmtAcctDr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(expectedCost, totalDebit.setScale(2, RoundingMode.HALF_EVEN), "Un-expected product asset account posted amount");
|
||||||
|
} finally {
|
||||||
|
rollback();
|
||||||
|
if (product != null && product.get_ID() > 0)
|
||||||
|
product.deleteEx(true);
|
||||||
|
if (tax != null && tax.get_ID() > 0)
|
||||||
|
tax.deleteEx(true);
|
||||||
|
if (category != null && category.get_ID() > 0)
|
||||||
|
category.deleteEx(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSeparateTaxPosting() {
|
||||||
|
MProduct product = null;
|
||||||
|
MTaxCategory category = null;
|
||||||
|
MTax tax = null;
|
||||||
|
try {
|
||||||
|
category = new MTaxCategory(Env.getCtx(), 0, null);
|
||||||
|
category.setName("testSeparateTaxPosting");
|
||||||
|
category.saveEx();
|
||||||
|
|
||||||
|
//need to create tax without trx as tax is cache
|
||||||
|
tax = new MTax(Env.getCtx(), 0, null);
|
||||||
|
tax.setC_TaxCategory_ID(category.get_ID());
|
||||||
|
tax.setIsDocumentLevel(false);
|
||||||
|
tax.setIsSummary(false);
|
||||||
|
tax.setRate(new BigDecimal("5.00"));
|
||||||
|
tax.setTaxPostingIndicator(MTax.TAXPOSTINGINDICATOR_SeparateTaxPosting);
|
||||||
|
tax.setSOPOType(MTax.SOPOTYPE_PurchaseTax);
|
||||||
|
tax.setName("testSeparateTaxPosting");
|
||||||
|
tax.saveEx();
|
||||||
|
CacheMgt.get().reset();
|
||||||
|
|
||||||
|
//need to create product with trx as order line get product from cache
|
||||||
|
MProduct p = MProduct.get(PRODUCT_MULCH_ID);
|
||||||
|
product = new MProduct(Env.getCtx(), 0, null);
|
||||||
|
product.setM_Product_Category_ID(p.getM_Product_Category_ID());
|
||||||
|
product.setC_TaxCategory_ID(category.get_ID());
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setIsPurchased(true);
|
||||||
|
product.setIsSold(true);
|
||||||
|
product.setIsStocked(true);
|
||||||
|
product.setProductType(MProduct.PRODUCTTYPE_Item);
|
||||||
|
product.setName("testSeparateTaxPosting");
|
||||||
|
product.setC_UOM_ID(p.getC_UOM_ID());
|
||||||
|
product.saveEx();
|
||||||
|
|
||||||
|
MPriceList priceList = MPriceList.get(PURCHASE_PRICE_LIST_ID);
|
||||||
|
MPriceListVersion priceListVersion = priceList.getPriceListVersion(null);
|
||||||
|
MProductPrice productPrice = new MProductPrice(Env.getCtx(), 0, getTrxName());
|
||||||
|
productPrice.setM_PriceList_Version_ID(priceListVersion.get_ID());
|
||||||
|
productPrice.setM_Product_ID(product.getM_Product_ID());
|
||||||
|
productPrice.setPrices(new BigDecimal("2.00"), new BigDecimal("2.00"), new BigDecimal("2.00"));
|
||||||
|
productPrice.saveEx();
|
||||||
|
|
||||||
|
//purchase price of 2
|
||||||
|
BigDecimal expectedCost = new BigDecimal("2.00").setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
//purchase price of 2 + 5% tax
|
||||||
|
BigDecimal expectedTotal = new BigDecimal("2.00").add(new BigDecimal("2.00").multiply(new BigDecimal("0.05"))).setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
MBPartner bpartner = MBPartner.get(Env.getCtx(), BP_PATIO_ID);
|
||||||
|
MOrder order = new MOrder(Env.getCtx(), 0, getTrxName());
|
||||||
|
order.setBPartner(bpartner);
|
||||||
|
order.setIsSOTrx(false);
|
||||||
|
order.setC_DocTypeTarget_ID();
|
||||||
|
order.setDocStatus(DocAction.STATUS_Drafted);
|
||||||
|
order.setDocAction(DocAction.ACTION_Complete);
|
||||||
|
order.saveEx();
|
||||||
|
|
||||||
|
MOrderLine orderLine = new MOrderLine(order);
|
||||||
|
orderLine.setLine(10);
|
||||||
|
orderLine.setProduct(product);
|
||||||
|
orderLine.setQty(new BigDecimal("1"));
|
||||||
|
orderLine.setTax();
|
||||||
|
orderLine.saveEx();
|
||||||
|
|
||||||
|
assertEquals(tax.get_ID(), orderLine.getC_Tax_ID(), "Un-expected tax id");
|
||||||
|
|
||||||
|
ProcessInfo info = MWorkflow.runDocumentActionWorkflow(order, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
order.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, order.getDocStatus());
|
||||||
|
assertEquals(expectedTotal, order.getGrandTotal().setScale(2, RoundingMode.HALF_EVEN), "Un-expected order grand total");
|
||||||
|
|
||||||
|
MInOut receipt = new MInOut(order, MM_RECEIPT_DOCTYPE_ID, order.getDateOrdered()); // MM Receipt
|
||||||
|
receipt.saveEx();
|
||||||
|
|
||||||
|
MWarehouse wh = MWarehouse.get(Env.getCtx(), receipt.getM_Warehouse_ID());
|
||||||
|
int M_Locator_ID = wh.getDefaultLocator().getM_Locator_ID();
|
||||||
|
|
||||||
|
MInOutLine receiptLine = new MInOutLine(receipt);
|
||||||
|
receiptLine.setOrderLine(orderLine, M_Locator_ID, new BigDecimal("1"));
|
||||||
|
receiptLine.setLine(10);
|
||||||
|
receiptLine.setQty(new BigDecimal("1"));
|
||||||
|
receiptLine.saveEx();
|
||||||
|
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(receipt, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
receipt.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, receipt.getDocStatus());
|
||||||
|
MInvoice invoice = new MInvoice(order, MDocType.getOfDocBaseType(Env.getCtx(), MDocType.DOCBASETYPE_APInvoice)[0].getC_DocType_ID(), order.getDateAcct());
|
||||||
|
invoice.setDocStatus(DocAction.STATUS_Drafted);
|
||||||
|
invoice.setDocAction(DocAction.ACTION_Complete);
|
||||||
|
invoice.saveEx();
|
||||||
|
|
||||||
|
MInvoiceLine invoiceLine = new MInvoiceLine(invoice);
|
||||||
|
invoiceLine.setShipLine(receiptLine);
|
||||||
|
invoiceLine.setLine(10);
|
||||||
|
invoiceLine.setProduct(product);
|
||||||
|
invoiceLine.setQty(new BigDecimal("1"));
|
||||||
|
invoiceLine.saveEx();
|
||||||
|
|
||||||
|
info = MWorkflow.runDocumentActionWorkflow(invoice, DocAction.ACTION_Complete);
|
||||||
|
assertFalse(info.isError(), info.getSummary());
|
||||||
|
invoice.load(getTrxName());
|
||||||
|
assertEquals(DocAction.STATUS_Completed, invoice.getDocStatus());
|
||||||
|
|
||||||
|
//ensure match po have been posted
|
||||||
|
MMatchPO[] matchPOs = MMatchPO.getOrderLine(Env.getCtx(), orderLine.get_ID(), getTrxName());
|
||||||
|
assertNotNull(matchPOs, "Can't retrive match po for order line");
|
||||||
|
assertEquals(1, matchPOs.length, "Un-expected number of match po record for order line");
|
||||||
|
if (!matchPOs[0].isPosted())
|
||||||
|
DocumentEngine.postImmediate(Env.getCtx(), getAD_Client_ID(), MMatchPO.Table_ID, matchPOs[0].get_ID(), true, getTrxName());
|
||||||
|
ProductCost productCost = new ProductCost(Env.getCtx(), product.get_ID(), 0, getTrxName());
|
||||||
|
productCost.setQty(new BigDecimal("1"));
|
||||||
|
MAcctSchema schema = MClientInfo.get().getMAcctSchema1();
|
||||||
|
BigDecimal averageCost = productCost.getProductCosts(schema, getAD_Org_ID(), MCost.COSTINGMETHOD_AveragePO, 0, true);
|
||||||
|
if (averageCost == null)
|
||||||
|
averageCost = BigDecimal.ZERO;
|
||||||
|
averageCost = averageCost.setScale(2, RoundingMode.HALF_EVEN);
|
||||||
|
assertEquals(expectedCost, averageCost, "Un-expected average cost");
|
||||||
|
|
||||||
|
MAccount acctAsset = productCost.getAccount(ProductCost.ACCTTYPE_P_Asset, schema);
|
||||||
|
String whereClause = MFactAcct.COLUMNNAME_AD_Table_ID + "=" + MInOut.Table_ID
|
||||||
|
+ " AND " + MFactAcct.COLUMNNAME_Record_ID + "=" + receipt.get_ID()
|
||||||
|
+ " AND " + MFactAcct.COLUMNNAME_C_AcctSchema_ID + "=" + schema.getC_AcctSchema_ID();
|
||||||
|
int[] ids = MFactAcct.getAllIDs(MFactAcct.Table_Name, whereClause, getTrxName());
|
||||||
|
BigDecimal totalDebit = new BigDecimal("0.00");
|
||||||
|
for(int id : ids) {
|
||||||
|
MFactAcct fa = new MFactAcct(Env.getCtx(), id, getTrxName());
|
||||||
|
if (fa.getAccount_ID() == acctAsset.getAccount_ID()) {
|
||||||
|
totalDebit = totalDebit.add(fa.getAmtAcctDr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(expectedCost, totalDebit.setScale(2, RoundingMode.HALF_EVEN), "Un-expected product asset account posted amount");
|
||||||
|
} finally {
|
||||||
|
rollback();
|
||||||
|
if (product != null && product.get_ID() > 0)
|
||||||
|
product.deleteEx(true);
|
||||||
|
if (tax != null && tax.get_ID() > 0)
|
||||||
|
tax.deleteEx(true);
|
||||||
|
if (category != null && category.get_ID() > 0)
|
||||||
|
category.deleteEx(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue