diff --git a/db/ddlutils/oracle/views/RV_C_INVOICELINE.sql b/db/ddlutils/oracle/views/RV_C_INVOICELINE.sql index 5c9feebb8c..d3d1a453af 100644 --- a/db/ddlutils/oracle/views/RV_C_INVOICELINE.sql +++ b/db/ddlutils/oracle/views/RV_C_INVOICELINE.sql @@ -39,13 +39,13 @@ SELECT il.ad_client_id, il.priceentered, CASE WHEN il.pricelist = 0 THEN 0 ELSE currencyRound((il.pricelist - il.priceactual) / il.pricelist * 100,i.C_Currency_ID,'N') END AS discount, CASE WHEN il.pricelimit = 0 THEN 0 ELSE currencyRound((il.priceactual - il.pricelimit) / il.pricelimit * 100,i.C_Currency_ID,'N') END AS margin, - CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced END AS marginamt, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced * i.multiplier END AS marginamt, currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') AS linenetamt, currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced,i.C_Currency_ID,'N') AS linelistamt, CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') ELSE currencyRound(i.multiplier * il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END AS linelimitamt, - currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced - il.linenetamt,i.C_Currency_ID,'N') AS linediscountamt, - CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * il.linenetamt - il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END AS + currencyRound(i.multiplier * (il.pricelist * il.qtyinvoiced - il.linenetamt),i.C_Currency_ID,'N') AS linediscountamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * (il.linenetamt - il.pricelimit * il.qtyinvoiced),i.C_Currency_ID,'N') END AS lineoverlimitamt, il.ad_orgtrx_id, il.a_processed, diff --git a/db/ddlutils/postgresql/views/RV_C_INVOICELINE.sql b/db/ddlutils/postgresql/views/RV_C_INVOICELINE.sql index 1c6bc203ad..d3d1a453af 100644 --- a/db/ddlutils/postgresql/views/RV_C_INVOICELINE.sql +++ b/db/ddlutils/postgresql/views/RV_C_INVOICELINE.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE VIEW rv_c_invoiceline AS +CREATE OR REPLACE VIEW rv_c_invoiceline AS SELECT il.ad_client_id, il.ad_org_id, il.isactive, @@ -39,13 +39,13 @@ SELECT il.ad_client_id, il.priceentered, CASE WHEN il.pricelist = 0 THEN 0 ELSE currencyRound((il.pricelist - il.priceactual) / il.pricelist * 100,i.C_Currency_ID,'N') END AS discount, CASE WHEN il.pricelimit = 0 THEN 0 ELSE currencyRound((il.priceactual - il.pricelimit) / il.pricelimit * 100,i.C_Currency_ID,'N') END AS margin, - CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced END AS marginamt, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced * i.multiplier END AS marginamt, currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') AS linenetamt, currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced,i.C_Currency_ID,'N') AS linelistamt, CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') ELSE currencyRound(i.multiplier * il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END AS linelimitamt, - currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced - il.linenetamt,i.C_Currency_ID,'N') AS linediscountamt, - CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * il.linenetamt - il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END AS + currencyRound(i.multiplier * (il.pricelist * il.qtyinvoiced - il.linenetamt),i.C_Currency_ID,'N') AS linediscountamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * (il.linenetamt - il.pricelimit * il.qtyinvoiced),i.C_Currency_ID,'N') END AS lineoverlimitamt, il.ad_orgtrx_id, il.a_processed, diff --git a/migration/i2.1/oracle/201505271238_IDEMPIERE-2540_unqidx.sql b/migration/i2.1/oracle/201505271238_IDEMPIERE-2540_unqidx.sql new file mode 100644 index 0000000000..7a02b72478 --- /dev/null +++ b/migration/i2.1/oracle/201505271238_IDEMPIERE-2540_unqidx.sql @@ -0,0 +1,31 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-2540 unique index on price break +-- May 27, 2015 12:33:21 PM COT +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201036,'ab4b4d97-9364-451d-9c1d-dbaf2585ff5c',TO_DATE('2015-05-27 12:33:21','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','m_productpricevendorbreak_unq',TO_DATE('2015-05-27 12:33:21','YYYY-MM-DD HH24:MI:SS'),100,53172,'N','Y','N','N','N') +; + +-- May 27, 2015 12:35:21 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201265,'72bb9352-bf69-4ecf-b170-d6107de2fabb',TO_DATE('2015-05-27 12:35:21','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2015-05-27 12:35:21','YYYY-MM-DD HH24:MI:SS'),100,56922,201036,10) +; + +-- May 27, 2015 12:35:42 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201266,'e96ed24c-ed98-4aa2-89a2-47e5779043a7',TO_DATE('2015-05-27 12:35:41','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2015-05-27 12:35:41','YYYY-MM-DD HH24:MI:SS'),100,201036,'COALESCE(C_BPartner_ID,-1)',20) +; + +-- May 27, 2015 12:36:09 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201267,'12feebe5-ace2-4a3a-8f3a-0a6228157967',TO_DATE('2015-05-27 12:36:08','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2015-05-27 12:36:08','YYYY-MM-DD HH24:MI:SS'),100,56921,201036,30) +; + +-- May 27, 2015 12:36:18 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201268,'7ce72777-6a11-4734-bda5-9c1fc2156a13',TO_DATE('2015-05-27 12:36:18','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2015-05-27 12:36:18','YYYY-MM-DD HH24:MI:SS'),100,56929,201036,40) +; + +-- May 27, 2015 12:36:45 PM COT +CREATE UNIQUE INDEX m_productpricevendorbreak_unq ON M_ProductPriceVendorBreak (M_Product_ID,COALESCE(C_BPartner_ID,-1),M_PriceList_Version_ID,BreakValue) +; + +SELECT register_migration_script('201505271238_IDEMPIERE-2540_unqidx.sql') FROM dual +; + diff --git a/migration/i2.1/oracle/201505271631_IDEMPIERE-2550.sql b/migration/i2.1/oracle/201505271631_IDEMPIERE-2550.sql new file mode 100644 index 0000000000..de302c0be6 --- /dev/null +++ b/migration/i2.1/oracle/201505271631_IDEMPIERE-2550.sql @@ -0,0 +1,145 @@ +CREATE OR REPLACE VIEW rv_c_invoiceline AS +SELECT il.ad_client_id, + il.ad_org_id, + il.isactive, + il.created, + il.createdby, + il.updated, + il.updatedby, + il.c_invoiceline_id, + i.c_invoice_id, + i.salesrep_id, + i.c_bpartner_id, + i.c_bp_group_id, + il.m_product_id, + p.m_product_category_id, + i.dateinvoiced, + i.dateacct, + i.issotrx, + i.c_doctype_id, + i.docstatus, + i.ispaid, + il.c_campaign_id, + il.c_project_id, + il.c_activity_id, + il.c_projectphase_id, + il.c_projecttask_id, + il.qtyinvoiced * i.multiplier AS qtyinvoiced, + il.qtyentered * i.multiplier AS qtyentered, + il.m_attributesetinstance_id, + productattribute(il.m_attributesetinstance_id) AS productattribute, + pasi.m_attributeset_id, + pasi.m_lot_id, + pasi.guaranteedate, + pasi.lot, + pasi.serno, + il.pricelist, + il.priceactual, + il.pricelimit, + il.priceentered, + CASE WHEN il.pricelist = 0 THEN 0 ELSE currencyRound((il.pricelist - il.priceactual) / il.pricelist * 100,i.C_Currency_ID,'N') END AS discount, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE currencyRound((il.priceactual - il.pricelimit) / il.pricelimit * 100,i.C_Currency_ID,'N') END AS margin, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced * i.multiplier END AS marginamt, + currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') AS linenetamt, + currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced,i.C_Currency_ID,'N') AS linelistamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') ELSE currencyRound(i.multiplier * il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END + AS linelimitamt, + currencyRound(i.multiplier * (il.pricelist * il.qtyinvoiced - il.linenetamt),i.C_Currency_ID,'N') AS linediscountamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * (il.linenetamt - il.pricelimit * il.qtyinvoiced),i.C_Currency_ID,'N') END AS + lineoverlimitamt, + il.ad_orgtrx_id, + il.a_processed, + il.c_charge_id, + il.c_orderline_id, + il.c_tax_id, + il.c_uom_id AS c_invoiceline_c_uom_id, + il.description AS c_invoiceline_description, + il.isdescription, + il.isprinted, + il.line, + il.linenetamt AS c_invoiceline_linenetamt, + il.linetotalamt, + il.m_inoutline_id, + il.m_rmaline_id, + il.processed, + il.ref_invoiceline_id, + il.rramt, + il.rrstartdate, + il.s_resourceassignment_id, + il.taxamt, + il.user1_id, + il.user2_id, + p.ad_org_id AS m_product_ad_org_id, + p.classification, + p.copyfrom AS m_product_copyfrom, + p.created AS m_product_created, + p.createdby AS m_product_createdby, + p.c_revenuerecognition_id, + p.c_subscriptiontype_id, + p.c_taxcategory_id, + p.c_uom_id AS m_productline_c_uom_id, + p.description AS m_product_description, + p.descriptionurl, + p.discontinued, + p.discontinuedat, + p.documentnote, + p.group1, + p.group2, + p.guaranteedays, + p.guaranteedaysmin, + p.help, + p.imageurl, + p.isactive AS m_product_isactive, + p.isdropship, + p.isexcludeautodelivery, + p.isinvoiceprintdetails, + p.ispicklistprintdetails, + p.ispurchased, + p.isselfservice, + p.issold, + p.isstocked, + p.issummary AS m_product_issummary, + p.isverified, + p.iswebstorefeatured, + p.lowlevel, + p.m_attributeset_id AS m_product_m_attributeset_id, + p.m_freightcategory_id, + p.m_locator_id, + p.m_product_id AS m_product_m_product_id, + p.processing AS m_product_processing, + p.producttype, + p.r_mailtext_id, + p.salesrep_id AS m_product_salesrep_id, + p.s_expensetype_id, + p.shelfdepth, + p.shelfheight, + p.shelfwidth, + p.sku, + p.s_resource_id, + p.unitsperpack, + p.unitsperpallet, + p.updated AS m_product_updated, + p.updatedby AS m_product_updatedby, + p.versionno, + p.volume, + p.weight, + pasi.ad_org_id AS m_asi_ad_org_id, + pasi.created AS m_attributesetinstance_created, + pasi.createdby AS m_asi_createdby, + pasi.description AS m_asi_description, + pasi.isactive AS m_attributesetinstance_isacti, + pasi.serno AS m_attributesetinstance_serno, + pasi.updated AS m_attributesetinstance_updated, + pasi.updatedby AS m_asi_updatedby +FROM rv_c_invoice i + JOIN c_invoiceline il + ON i.c_invoice_id = il.c_invoice_id + LEFT JOIN m_product p + ON il.m_product_id = p.m_product_id + LEFT JOIN m_attributesetinstance pasi + ON il.m_attributesetinstance_id = pasi.m_attributesetinstance_id +; + +SELECT register_migration_script('201505271631_IDEMPIERE-2550.sql') FROM dual +; + diff --git a/migration/i2.1/postgresql/201505271238_IDEMPIERE-2540_unqidx.sql b/migration/i2.1/postgresql/201505271238_IDEMPIERE-2540_unqidx.sql new file mode 100644 index 0000000000..73c8b3175c --- /dev/null +++ b/migration/i2.1/postgresql/201505271238_IDEMPIERE-2540_unqidx.sql @@ -0,0 +1,28 @@ +-- IDEMPIERE-2540 unique index on price break +-- May 27, 2015 12:33:21 PM COT +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201036,'ab4b4d97-9364-451d-9c1d-dbaf2585ff5c',TO_TIMESTAMP('2015-05-27 12:33:21','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','m_productpricevendorbreak_unq',TO_TIMESTAMP('2015-05-27 12:33:21','YYYY-MM-DD HH24:MI:SS'),100,53172,'N','Y','N','N','N') +; + +-- May 27, 2015 12:35:21 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201265,'72bb9352-bf69-4ecf-b170-d6107de2fabb',TO_TIMESTAMP('2015-05-27 12:35:21','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2015-05-27 12:35:21','YYYY-MM-DD HH24:MI:SS'),100,56922,201036,10) +; + +-- May 27, 2015 12:35:42 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201266,'e96ed24c-ed98-4aa2-89a2-47e5779043a7',TO_TIMESTAMP('2015-05-27 12:35:41','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2015-05-27 12:35:41','YYYY-MM-DD HH24:MI:SS'),100,201036,'COALESCE(C_BPartner_ID,-1)',20) +; + +-- May 27, 2015 12:36:09 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201267,'12feebe5-ace2-4a3a-8f3a-0a6228157967',TO_TIMESTAMP('2015-05-27 12:36:08','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2015-05-27 12:36:08','YYYY-MM-DD HH24:MI:SS'),100,56921,201036,30) +; + +-- May 27, 2015 12:36:18 PM COT +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_Column_ID,AD_TableIndex_ID,SeqNo) VALUES (0,0,201268,'7ce72777-6a11-4734-bda5-9c1fc2156a13',TO_TIMESTAMP('2015-05-27 12:36:18','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2015-05-27 12:36:18','YYYY-MM-DD HH24:MI:SS'),100,56929,201036,40) +; + +-- May 27, 2015 12:36:45 PM COT +CREATE UNIQUE INDEX m_productpricevendorbreak_unq ON M_ProductPriceVendorBreak (M_Product_ID,COALESCE(C_BPartner_ID,-1),M_PriceList_Version_ID,BreakValue) +; + +SELECT register_migration_script('201505271238_IDEMPIERE-2540_unqidx.sql') FROM dual +; + diff --git a/migration/i2.1/postgresql/201505271631_IDEMPIERE-2550.sql b/migration/i2.1/postgresql/201505271631_IDEMPIERE-2550.sql new file mode 100644 index 0000000000..de302c0be6 --- /dev/null +++ b/migration/i2.1/postgresql/201505271631_IDEMPIERE-2550.sql @@ -0,0 +1,145 @@ +CREATE OR REPLACE VIEW rv_c_invoiceline AS +SELECT il.ad_client_id, + il.ad_org_id, + il.isactive, + il.created, + il.createdby, + il.updated, + il.updatedby, + il.c_invoiceline_id, + i.c_invoice_id, + i.salesrep_id, + i.c_bpartner_id, + i.c_bp_group_id, + il.m_product_id, + p.m_product_category_id, + i.dateinvoiced, + i.dateacct, + i.issotrx, + i.c_doctype_id, + i.docstatus, + i.ispaid, + il.c_campaign_id, + il.c_project_id, + il.c_activity_id, + il.c_projectphase_id, + il.c_projecttask_id, + il.qtyinvoiced * i.multiplier AS qtyinvoiced, + il.qtyentered * i.multiplier AS qtyentered, + il.m_attributesetinstance_id, + productattribute(il.m_attributesetinstance_id) AS productattribute, + pasi.m_attributeset_id, + pasi.m_lot_id, + pasi.guaranteedate, + pasi.lot, + pasi.serno, + il.pricelist, + il.priceactual, + il.pricelimit, + il.priceentered, + CASE WHEN il.pricelist = 0 THEN 0 ELSE currencyRound((il.pricelist - il.priceactual) / il.pricelist * 100,i.C_Currency_ID,'N') END AS discount, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE currencyRound((il.priceactual - il.pricelimit) / il.pricelimit * 100,i.C_Currency_ID,'N') END AS margin, + CASE WHEN il.pricelimit = 0 THEN 0 ELSE (il.priceactual - il.pricelimit) * il.qtyinvoiced * i.multiplier END AS marginamt, + currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') AS linenetamt, + currencyRound(i.multiplier * il.pricelist * il.qtyinvoiced,i.C_Currency_ID,'N') AS linelistamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN currencyRound(i.multiplier * il.linenetamt,i.C_Currency_ID,'N') ELSE currencyRound(i.multiplier * il.pricelimit * il.qtyinvoiced,i.C_Currency_ID,'N') END + AS linelimitamt, + currencyRound(i.multiplier * (il.pricelist * il.qtyinvoiced - il.linenetamt),i.C_Currency_ID,'N') AS linediscountamt, + CASE WHEN COALESCE(il.pricelimit, 0) = 0 THEN 0 ELSE currencyRound(i.multiplier * (il.linenetamt - il.pricelimit * il.qtyinvoiced),i.C_Currency_ID,'N') END AS + lineoverlimitamt, + il.ad_orgtrx_id, + il.a_processed, + il.c_charge_id, + il.c_orderline_id, + il.c_tax_id, + il.c_uom_id AS c_invoiceline_c_uom_id, + il.description AS c_invoiceline_description, + il.isdescription, + il.isprinted, + il.line, + il.linenetamt AS c_invoiceline_linenetamt, + il.linetotalamt, + il.m_inoutline_id, + il.m_rmaline_id, + il.processed, + il.ref_invoiceline_id, + il.rramt, + il.rrstartdate, + il.s_resourceassignment_id, + il.taxamt, + il.user1_id, + il.user2_id, + p.ad_org_id AS m_product_ad_org_id, + p.classification, + p.copyfrom AS m_product_copyfrom, + p.created AS m_product_created, + p.createdby AS m_product_createdby, + p.c_revenuerecognition_id, + p.c_subscriptiontype_id, + p.c_taxcategory_id, + p.c_uom_id AS m_productline_c_uom_id, + p.description AS m_product_description, + p.descriptionurl, + p.discontinued, + p.discontinuedat, + p.documentnote, + p.group1, + p.group2, + p.guaranteedays, + p.guaranteedaysmin, + p.help, + p.imageurl, + p.isactive AS m_product_isactive, + p.isdropship, + p.isexcludeautodelivery, + p.isinvoiceprintdetails, + p.ispicklistprintdetails, + p.ispurchased, + p.isselfservice, + p.issold, + p.isstocked, + p.issummary AS m_product_issummary, + p.isverified, + p.iswebstorefeatured, + p.lowlevel, + p.m_attributeset_id AS m_product_m_attributeset_id, + p.m_freightcategory_id, + p.m_locator_id, + p.m_product_id AS m_product_m_product_id, + p.processing AS m_product_processing, + p.producttype, + p.r_mailtext_id, + p.salesrep_id AS m_product_salesrep_id, + p.s_expensetype_id, + p.shelfdepth, + p.shelfheight, + p.shelfwidth, + p.sku, + p.s_resource_id, + p.unitsperpack, + p.unitsperpallet, + p.updated AS m_product_updated, + p.updatedby AS m_product_updatedby, + p.versionno, + p.volume, + p.weight, + pasi.ad_org_id AS m_asi_ad_org_id, + pasi.created AS m_attributesetinstance_created, + pasi.createdby AS m_asi_createdby, + pasi.description AS m_asi_description, + pasi.isactive AS m_attributesetinstance_isacti, + pasi.serno AS m_attributesetinstance_serno, + pasi.updated AS m_attributesetinstance_updated, + pasi.updatedby AS m_asi_updatedby +FROM rv_c_invoice i + JOIN c_invoiceline il + ON i.c_invoice_id = il.c_invoice_id + LEFT JOIN m_product p + ON il.m_product_id = p.m_product_id + LEFT JOIN m_attributesetinstance pasi + ON il.m_attributesetinstance_id = pasi.m_attributesetinstance_id +; + +SELECT register_migration_script('201505271631_IDEMPIERE-2550.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/model/MInOut.java b/org.adempiere.base/src/org/compiere/model/MInOut.java index 453297e100..a45bcaf788 100644 --- a/org.adempiere.base/src/org/compiere/model/MInOut.java +++ b/org.adempiere.base/src/org/compiere/model/MInOut.java @@ -1853,7 +1853,7 @@ public class MInOut extends X_M_InOut implements DocAction String MMPolicy = product.getMMPolicy(); Timestamp minGuaranteeDate = getMovementDate(); MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), line.getM_AttributeSetInstance_ID(), - minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName(), true); + minGuaranteeDate, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName(), false); BigDecimal qtyToDeliver = qty; for (MStorageOnHand storage: storages) { @@ -1897,7 +1897,7 @@ public class MInOut extends X_M_InOut implements DocAction private BigDecimal autoBalanceNegative(MInOutLine line, MProduct product,BigDecimal qtyToReceive) { MStorageOnHand[] storages = MStorageOnHand.getWarehouseNegative(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, - null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), line.getM_Locator_ID(), get_TrxName(), true); + null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), line.getM_Locator_ID(), get_TrxName(), false); Timestamp dateMPolicy = null; diff --git a/org.adempiere.base/src/org/compiere/model/MInventory.java b/org.adempiere.base/src/org/compiere/model/MInventory.java index 8431080b4b..646760c2d9 100644 --- a/org.adempiere.base/src/org/compiere/model/MInventory.java +++ b/org.adempiere.base/src/org/compiere/model/MInventory.java @@ -625,7 +625,7 @@ public class MInventory extends X_M_Inventory implements DocAction { //auto balance negative on hand MStorageOnHand[] storages = MStorageOnHand.getWarehouseNegative(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, - null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), line.getM_Locator_ID(), get_TrxName(), true); + null, MClient.MMPOLICY_FiFo.equals(product.getMMPolicy()), line.getM_Locator_ID(), get_TrxName(), false); for (MStorageOnHand storage : storages) { if (storage.getQtyOnHand().signum() < 0) @@ -656,7 +656,7 @@ public class MInventory extends X_M_Inventory implements DocAction { String MMPolicy = product.getMMPolicy(); MStorageOnHand[] storages = MStorageOnHand.getWarehouse(getCtx(), getM_Warehouse_ID(), line.getM_Product_ID(), 0, - null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName(), true); + null, MClient.MMPOLICY_FiFo.equals(MMPolicy), true, line.getM_Locator_ID(), get_TrxName(), false); BigDecimal qtyToDeliver = qtyDiff.negate(); for (MStorageOnHand storage: storages) diff --git a/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java b/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java index 883848fd83..d414a7cca9 100644 --- a/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java +++ b/org.adempiere.base/src/org/compiere/model/MPriceListVersion.java @@ -113,7 +113,7 @@ public class MPriceListVersion extends X_M_PriceList_Version */ public MProductPrice[] getProductPrice (String whereClause) { - String localWhereClause = I_M_ProductPrice.COLUMNNAME_M_PriceList_Version_ID+"=?"+whereClause; + String localWhereClause = I_M_ProductPrice.COLUMNNAME_M_PriceList_Version_ID+"=?"; if (whereClause != null) localWhereClause += " " + whereClause; List list = new Query(getCtx(),I_M_ProductPrice.Table_Name,localWhereClause,get_TrxName()) diff --git a/org.adempiere.base/src/org/compiere/model/MProductionLine.java b/org.adempiere.base/src/org/compiere/model/MProductionLine.java index 93d27de4f9..d395a068d0 100644 --- a/org.adempiere.base/src/org/compiere/model/MProductionLine.java +++ b/org.adempiere.base/src/org/compiere/model/MProductionLine.java @@ -132,7 +132,7 @@ public class MProductionLine extends X_M_ProductionLine { // create transactions and update stock used in production MStorageOnHand[] storages = MStorageOnHand.getAll( getCtx(), getM_Product_ID(), - getM_Locator_ID(), get_TrxName(), true, 120); + getM_Locator_ID(), get_TrxName(), false, 0); MProductionLineMA lineMA = null; MTransaction matTrx = null; @@ -181,6 +181,7 @@ public class MProductionLine extends X_M_ProductionLine { } else { if (log.isLoggable(Level.FINE))log.log(Level.FINE, "Saved transaction for " + toString()); } + DB.getDatabase().forUpdate(storages[sl], 120); storages[sl].changeQtyOnHand(lineQty, false); if ( !storages[sl].save(get_TrxName()) ) { log.log(Level.SEVERE, "Could not update storage for " + toString()); diff --git a/org.adempiere.base/src/org/compiere/util/Env.java b/org.adempiere.base/src/org/compiere/util/Env.java index a38435e474..2dfca06f06 100644 --- a/org.adempiere.base/src/org/compiere/util/Env.java +++ b/org.adempiere.base/src/org/compiere/util/Env.java @@ -581,7 +581,7 @@ public final class Env if (TAB_INFO == TabNo) return s != null ? s : ""; // - if (s == null) + if (Util.isEmpty(s)) return getContext(ctx, WindowNo, context, false); return s; } // getContext @@ -623,7 +623,7 @@ public final class Env if (TAB_INFO == TabNo) return s != null ? s : ""; // - if (s == null && ! onlyTab) + if (Util.isEmpty(s) && ! onlyTab) return getContext(ctx, WindowNo, context, onlyWindow); return s; } // getContext @@ -715,7 +715,7 @@ public final class Env public static int getContextAsInt (Properties ctx, int WindowNo, int TabNo, String context) { String s = getContext(ctx, WindowNo, TabNo, context); - if (s.length() == 0) + if (Util.isEmpty(s)) return 0; // try diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java index 348c043bea..e7a67baf4f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessDialog.java @@ -57,9 +57,11 @@ import org.zkoss.zk.au.out.AuEcho; import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; +import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.A; import org.zkoss.zul.Div; @@ -85,11 +87,10 @@ import com.lowagie.text.pdf.PdfWriter; */ public class ProcessDialog extends AbstractProcessDialog implements EventListener, IHelpContext { - /** * */ - private static final long serialVersionUID = 5958768001208626552L; + private static final long serialVersionUID = -6728929130788829223L; public static final String ON_INITIAL_FOCUS_EVENT = "onInitialFocus"; @@ -106,6 +107,11 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene private HtmlBasedComponent messageResultContent; private HtmlBasedComponent infoResultContent; + /** Window No */ + private int m_WindowNo = -1; + private long prevKeyEventTime = 0; + private KeyEvent prevKeyEvent; + /** * Dialog to start a process/report * @param ctx @@ -121,13 +127,12 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene public ProcessDialog (int AD_Process_ID, boolean isSOTrx) { log.info("Process=" + AD_Process_ID ); - int WindowNo = SessionManager.getAppDesktop().registerWindow(this); - this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, WindowNo); - Env.setContext(Env.getCtx(), WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N"); - + m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); + this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); + Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N"); try { - init(Env.getCtx(), WindowNo, AD_Process_ID, null, false, false); + init(Env.getCtx(), m_WindowNo, AD_Process_ID, null, false, false); querySaved(); addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this); addEventListener(ON_INITIAL_FOCUS_EVENT, this); @@ -138,6 +143,22 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene } } // ProcessDialog + @Override + public void onPageAttached(Page newpage, Page oldpage) { + super.onPageAttached(newpage, oldpage); + try { + SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this); + } catch (Exception e) {} + } + + @Override + public void onPageDetached(Page page) { + super.onPageDetached(page); + try { + SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, this); + } catch (Exception e) {} + } + /** * Set Visible * (set focus to OK if visible) @@ -182,11 +203,40 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene bOK.focus(); } } + } else if (event.getName().equals(Events.ON_CTRL_KEY)) { + KeyEvent keyEvent = (KeyEvent) event; + if (LayoutUtils.isReallyVisible(this)) { + //filter same key event that is too close + //firefox fire key event twice when grid is visible + long time = System.currentTimeMillis(); + if (prevKeyEvent != null && prevKeyEventTime > 0 && + prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() && + prevKeyEvent.getTarget() == keyEvent.getTarget() && + prevKeyEvent.isAltKey() == keyEvent.isAltKey() && + prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() && + prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) { + if ((time - prevKeyEventTime) <= 300) { + return; + } + } + this.onCtrlKeyEvent(keyEvent); + } } else { super.onEvent(event); } } + private void onCtrlKeyEvent(KeyEvent keyEvent) { + if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X + if (m_WindowNo > 0) { + prevKeyEventTime = System.currentTimeMillis(); + prevKeyEvent = keyEvent; + keyEvent.stopPropagation(); + SessionManager.getAppDesktop().closeWindow(m_WindowNo); + } + } + } + private void doOnClick(A btn) { int Record_ID = 0; int AD_Table_ID =0; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java index 60a68db23a..c902b47f31 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessParameterPanel.java @@ -52,6 +52,7 @@ import org.compiere.model.MPInstancePara; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogger; import org.compiere.util.DB; +import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; import org.zkoss.zk.ui.Component; @@ -467,9 +468,20 @@ public class ProcessParameterPanel extends Panel implements } else if ( !Env.ZERO.equals(para.getP_Number()) || !Env.ZERO.equals(para.getP_Number_To()) ) { - editor.setValue(para.getP_Number()); - if (editor2 != null) - editor2.setValue(para.getP_Number_To()); + if (DisplayType.isID(para.getDisplayType())) { + editor.setValue(para.getP_Number().intValue()); + if (editor2 != null) + editor2.setValue(para.getP_Number_To().intValue()); + } else { + editor.setValue(para.getP_Number()); + if (editor2 != null) + editor2.setValue(para.getP_Number_To()); + } + } + if (editor.getValue() != null) { + ValueChangeEvent changeEvent = new ValueChangeEvent(editor, editor.getColumnName(), editor.getValue(), null); + valueChange(changeEvent); + // Note that the second editor2 in ranges has no event verification } log.fine(para.toString()); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ADTreeOnDropListener.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ADTreeOnDropListener.java index 6eb57ee69f..72649cbcb9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ADTreeOnDropListener.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ADTreeOnDropListener.java @@ -153,7 +153,8 @@ public class ADTreeOnDropListener implements EventListener { { tree.onInitRender(); } - tree.renderItemByPath(path); + @SuppressWarnings("unused") + Treeitem movingItem = tree.renderItemByPath(path); //tree.setSelectedItem(movingItem); //Events.sendEvent(tree, new Event(Events.ON_SELECT, tree)); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java index f3db10a76b..1ba2474890 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ZoomCommand.java @@ -70,6 +70,9 @@ public class ZoomCommand implements AuService { MQuery query = new MQuery(tableName); query.addRestriction(columnName, MQuery.EQUAL, code); query.setRecordCount(1); + query.setZoomTableName(tableName); + query.setZoomColumnName(columnName); + query.setZoomValue(code); Events.postEvent(new ZoomEvent(comp, query)); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index e870829207..c05b88f651 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -23,11 +23,13 @@ import net.sf.jasperreports.engine.export.JRXlsExporterParameter; import net.sf.jasperreports.engine.util.LocalJasperReportsContext; import org.adempiere.exceptions.AdempiereException; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Listbox; import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.component.Window; +import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.panel.ITabOnCloseHandler; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; @@ -42,9 +44,11 @@ import org.compiere.util.Util; import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Center; import org.zkoss.zul.Iframe; @@ -58,7 +62,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl /** * */ - private static final long serialVersionUID = -1250003381099609830L; + private static final long serialVersionUID = -7047317766671393738L; private JasperPrint jasperPrint; private Listbox previewType = new Listbox(); @@ -72,6 +76,8 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl /** Window No */ private int m_WindowNo = -1; + private long prevKeyEventTime = 0; + private KeyEvent prevKeyEvent; private String m_title; // local title - embedded windows clear the title @@ -81,9 +87,26 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl m_title = title; this.jasperPrint = jasperPrint; m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); + setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); init(); } - + + @Override + public void onPageAttached(Page newpage, Page oldpage) { + super.onPageAttached(newpage, oldpage); + try { + SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this); + } catch (Exception e) {} + } + + @Override + public void onPageDetached(Page page) { + super.onPageDetached(page); + try { + SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, this); + } catch (Exception e) {} + } + private void init() { final boolean isCanExport=MRole.getDefault().isCanExport(); defaultType = MSysConfig.getValue(MSysConfig.ZK_REPORT_JASPER_OUTPUT_TYPE, "PDF", @@ -230,11 +253,40 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } // cmd_sendMail public void onEvent(Event event) throws Exception { - if(event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) + if (event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) { actionPerformed(event); - + } else if (event.getName().equals(Events.ON_CTRL_KEY)) { + KeyEvent keyEvent = (KeyEvent) event; + if (LayoutUtils.isReallyVisible(this)) { + //filter same key event that is too close + //firefox fire key event twice when grid is visible + long time = System.currentTimeMillis(); + if (prevKeyEvent != null && prevKeyEventTime > 0 && + prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() && + prevKeyEvent.getTarget() == keyEvent.getTarget() && + prevKeyEvent.isAltKey() == keyEvent.isAltKey() && + prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() && + prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) { + if ((time - prevKeyEventTime) <= 300) { + return; + } + } + this.onCtrlKeyEvent(keyEvent); + } + } } - + + private void onCtrlKeyEvent(KeyEvent keyEvent) { + if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X + if (m_WindowNo > 0) { + prevKeyEventTime = System.currentTimeMillis(); + prevKeyEvent = keyEvent; + keyEvent.stopPropagation(); + SessionManager.getAppDesktop().closeWindow(m_WindowNo); + } + } + } + private void renderReport() throws Exception { String reportType; ClassLoader cl = Thread.currentThread().getContextClassLoader(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java index 90bf5dd7df..fdb896c6b8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java @@ -48,6 +48,7 @@ import org.adempiere.webui.component.Mask; import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.component.Window; +import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.editor.WTableDirEditor; import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.DrillEvent; @@ -94,6 +95,7 @@ import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.ext.render.DynamicMedia; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.A; @@ -137,10 +139,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab /** * */ - private static final long serialVersionUID = 3463776496724974142L; + private static final long serialVersionUID = 946000686957291327L; /** Window No */ private int m_WindowNo = -1; + private long prevKeyEventTime = 0; + private KeyEvent prevKeyEvent; /** Print Context */ private Properties m_ctx; /** Setting Values */ @@ -207,6 +211,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab init = false; m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); + setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); Env.setContext(re.getCtx(), m_WindowNo, "_WinInfo_IsReportViewer", "Y"); m_reportEngine = re; m_AD_Table_ID = re.getPrintFormat().getAD_Table_ID(); @@ -222,8 +227,6 @@ public class ZkReportViewer extends Window implements EventListener, ITab addEventListener(ON_RENDER_REPORT_EVENT, this); } - - @Override public void onPageAttached(Page newpage, Page oldpage) { @@ -234,6 +237,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab m_ctx = m_reportEngine.getCtx(); init(); dynInit(); + SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this); } catch(Exception e) { @@ -244,6 +248,14 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } + @Override + public void onPageDetached(Page page) { + super.onPageDetached(page); + try { + SessionManager.getSessionApplication().getKeylistener().removeEventListener(Events.ON_CTRL_KEY, this); + } catch (Exception e) {} + } + private void init() { Borderlayout layout = new Borderlayout(); layout.setStyle("position: absolute; height: 97%; width: 98%; border:none; padding:none; margin:none;"); @@ -767,6 +779,35 @@ public class ZkReportViewer extends Window implements EventListener, ITab else if (event.getName().equals(ON_RENDER_REPORT_EVENT)) { onRenderReportEvent(); + } else if (event.getName().equals(Events.ON_CTRL_KEY)) { + KeyEvent keyEvent = (KeyEvent) event; + if (LayoutUtils.isReallyVisible(this)) { + //filter same key event that is too close + //firefox fire key event twice when grid is visible + long time = System.currentTimeMillis(); + if (prevKeyEvent != null && prevKeyEventTime > 0 && + prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() && + prevKeyEvent.getTarget() == keyEvent.getTarget() && + prevKeyEvent.isAltKey() == keyEvent.isAltKey() && + prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() && + prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) { + if ((time - prevKeyEventTime) <= 300) { + return; + } + } + this.onCtrlKeyEvent(keyEvent); + } + } + } + + private void onCtrlKeyEvent(KeyEvent keyEvent) { + if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X + if (m_WindowNo > 0) { + prevKeyEventTime = System.currentTimeMillis(); + prevKeyEvent = keyEvent; + keyEvent.stopPropagation(); + SessionManager.getAppDesktop().closeWindow(m_WindowNo); + } } } diff --git a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java index 4b73fc370e..8880bfc0b6 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java +++ b/org.idempiere.webservices/WEB-INF/src/org/idempiere/adinterface/ModelADServiceImpl.java @@ -32,7 +32,6 @@ package org.idempiere.adinterface; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.Map; import java.util.Properties; @@ -170,6 +169,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic public StandardResponseDocument setDocAction(ModelSetDocActionRequestDocument req) { boolean connected = getCompiereService().isConnected(); + boolean manageTrx = this.manageTrx; + Trx trx=null; try { if (!connected) getCompiereService().connect(); @@ -211,7 +212,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic manageTrx = true; } - Trx trx = Trx.get(trxName, true); + trx = Trx.get(trxName, true); Map requestCtx = getRequestCtx(); @@ -298,6 +299,9 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic return ret; } finally { + if (manageTrx && trx != null) + trx.close(); + if (!connected) getCompiereService().disconnect(); } @@ -1413,6 +1417,8 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic public WindowTabDataDocument queryData(ModelCRUDRequestDocument req) { boolean connected = getCompiereService().isConnected(); + boolean manageTrx = this.manageTrx; + Trx trx=null; try { if (!connected) getCompiereService().connect(); @@ -1432,10 +1438,10 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic // Validate parameters vs service type validateCRUD(modelCRUD); - + Properties ctx = m_cs.getCtx(); String tableName = modelCRUD.getTableName(); - + Map reqCtx = getRequestCtx(); MWebServiceType m_webservicetype = getWebServiceType(); // get the PO for the tablename and record ID MTable table = MTable.get(ctx, tableName); @@ -1447,12 +1453,42 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic int roleid = reqlogin.getRoleID(); MRole role = new MRole(ctx, roleid, null); - - String sqlquery = "SELECT * FROM " + tableName; - sqlquery = role.addAccessSQL(sqlquery, tableName, true, true); + + // start a trx + String trxName = localTrxName; + + if (trxName == null) { + trxName = Trx.createTrxName("ws_modelQueryData"); + manageTrx = true; + } + trx = Trx.get(trxName, true); + + StringBuilder sqlBuilder = new StringBuilder(role.addAccessSQL("SELECT * FROM " + tableName, tableName, true, true)); + + ArrayList sqlParaList = new ArrayList(); + PO holderPo = table.getPO(0, trxName); + POInfo poinfo = POInfo.getPOInfo(ctx, table.getAD_Table_ID()); if (modelCRUD.getDataRow() != null) { + DataRow dr = modelCRUD.getDataRow(); + DataField fields[] = dr.getFieldArray(); + StandardResponseDocument stdRet = StandardResponseDocument.Factory.newInstance(); + StandardResponse stdResp = stdRet.addNewStandardResponse(); + + StandardResponseDocument retResp = invokeWSValidator(m_webservicetype, IWSValidator.TIMING_BEFORE_PARSE, holderPo, fields, trx, + reqCtx, stdResp, stdRet); + if (retResp != null){ + throw new IdempiereServiceFault(retResp.getStandardResponse().getError(), new QName("queryData")); + } + + retResp = scanFields(fields, m_webservicetype, holderPo, poinfo, trx, stdResp, stdRet); + + if (retResp != null){ + throw new IdempiereServiceFault(retResp.getStandardResponse().getError(), new QName("queryData")); + } + + for (DataField field : modelCRUD.getDataRow().getFieldArray()) { if (m_webservicetype.isInputColumnNameAllowed(field.getColumn())) { @@ -1461,11 +1497,14 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic I_AD_Column col = inputField.getAD_Column(); String sqlType = DisplayType.getSQLDataType(col.getAD_Reference_ID(), col.getColumnName(), col.getFieldLength()); if(sqlType.contains("CHAR")) - sqlquery += " AND " + field.getColumn() + " LIKE ?"; + sqlBuilder.append(" AND ").append(field.getColumn()).append(" LIKE ?"); else - sqlquery += " AND " + field.getColumn() + "=?"; + sqlBuilder.append(" AND ").append(field.getColumn()).append("=?"); + + sqlParaList.add(holderPo.get_Value(field.getColumn())); // End Jan Thielemann Solution for query using the sentence like - } else { + }else if(m_webservicetype.getFieldInput(field.getColumn())==null){ + //If not even ctx variable column throw new IdempiereServiceFault("Web service type " + m_webservicetype.getValue() + ": input column " + field.getColumn() + " not allowed", new QName("queryData")); @@ -1473,10 +1512,11 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic } } - if (modelCRUD.getFilter() != null && modelCRUD.getFilter().length() > 0) - sqlquery += " AND " + modelCRUD.getFilter(); + if (modelCRUD.getFilter() != null && modelCRUD.getFilter().length() > 0){ + String sql = parseSQL(" WHERE " + modelCRUD.getFilter(), sqlParaList, holderPo, poinfo, reqCtx); + sqlBuilder.append(" AND ").append(sql.substring(6)); + } - POInfo poinfo = POInfo.getPOInfo(ctx, table.getAD_Table_ID()); int cnt = 0; int rowCnt = 0; int offset = modelCRUD.getOffset(); @@ -1486,58 +1526,10 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic ResultSet rsquery = null; try { - pstmtquery = DB.prepareStatement (sqlquery, localTrxName); - int p = 1; - if (modelCRUD.getDataRow() != null) - { - for (DataField field : modelCRUD.getDataRow().getFieldArray()) { - int idx = poinfo.getColumnIndex(field.getColumn()); - Class c = poinfo.getColumnClass(idx); - if (c == Integer.class) - { - int value = 0; - if (Util.isEmpty(field.getVal()) && !Util.isEmpty(field.getLval())) - { - Lookup lookup = null; - int idxcol = poinfo.getColumnIndex(field.getColumn()); - X_WS_WebServiceFieldInput fieldInput = m_webservicetype.getFieldInput(field.getColumn()); - if(fieldInput.getAD_Reference_ID() > 0 && fieldInput.getAD_Reference_Value_ID()>0) - { - try{ - lookup = MLookupFactory.get(m_cs.getCtx(),0,poinfo.getAD_Column_ID(poinfo.getColumnName(idxcol)),fieldInput.getAD_Reference_ID(),Env.getLanguage(m_cs.getCtx()),poinfo.getColumnName(idxcol),fieldInput.getAD_Reference_Value_ID(),false,null); - }catch (Exception e) { - throw new IdempiereServiceFault("Exception in resolving overridden lookup ", new QName( - "LookupResolutionFailed")); - } - } - else - { - lookup = poinfo.getColumnLookup(idxcol); - } - - if (lookup == null) { - throw new IdempiereServiceFault(field.getColumn() + " is not lookup column. Pass Value in val element ", new QName( - "LookupResolutionFailed")); - } - - String sql = ADLookup.getDirectAccessSQL(lookup, field.getLval().toUpperCase()); - int id = DB.getSQLValue(localTrxName, sql); - if (id > 0) - value = id; - } - else - { - value = Integer.valueOf(field.getVal()); - } - pstmtquery.setInt(p++, value); - } - else if (c == Timestamp.class) - pstmtquery.setTimestamp(p++, Timestamp.valueOf(field.getVal())); - else if (c == Boolean.class || c == String.class) - pstmtquery.setString(p++, field.getVal()); - } - } - rsquery = pstmtquery.executeQuery (); + pstmtquery = DB.prepareStatement (sqlBuilder.toString(), trxName); + DB.setParameters(pstmtquery, sqlParaList); + + rsquery = pstmtquery.executeQuery(); // Angelo Dabala' (genied) must create just one DataSet, moved outside of the while loop DataSet ds = resp.addNewDataSet(); while (rsquery.next ()) { @@ -1559,6 +1551,7 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic catch (Exception e) { log.log(Level.SEVERE, e.getLocalizedMessage(), e); + throw new IdempiereServiceFault(e); } finally { @@ -1574,6 +1567,9 @@ public class ModelADServiceImpl extends AbstractService implements ModelADServic return ret; } finally { + if (manageTrx && trx != null) + trx.close(); + if (!connected) getCompiereService().disconnect(); } diff --git a/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java b/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java index 55073142c4..ce4df95dbb 100644 --- a/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java +++ b/org.idempiere.webservices/WEB-INF/src/org/idempiere/webservices/AbstractService.java @@ -402,6 +402,7 @@ public class AbstractService { firstInd = sql.indexOf('@'); } + sqlBuilder.append(sql); }