diff --git a/Modules/mip_quotation.pck b/Modules/mip_quotation.pck index 1f46191..7edf111 100644 --- a/Modules/mip_quotation.pck +++ b/Modules/mip_quotation.pck @@ -84,15 +84,19 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS SUBTYPE t_reason IS VARCHAR2(240); SUBTYPE t_internal_or_external IS VARCHAR2(8); - g_internal_reason CONSTANT t_internal_or_external := 'INTERNAL'; - g_external_reason CONSTANT t_internal_or_external := 'EXTERNAL'; + gc_internal_reason CONSTANT t_internal_or_external := 'INTERNAL'; + gc_external_reason CONSTANT t_internal_or_external := 'EXTERNAL'; SUBTYPE t_manual_or_automatic_quote IS VARCHAR2(2); SUBTYPE t_enqu IS enquiries%ROWTYPE; - g_manual_quote CONSTANT t_manual_or_automatic_quote := 'MQ'; - g_automatic_quote CONSTANT t_manual_or_automatic_quote := 'AQ'; + gc_manual_quote CONSTANT t_manual_or_automatic_quote := 'MQ'; + gc_automatic_quote CONSTANT t_manual_or_automatic_quote := 'AQ'; + + g_email_plain_body CLOB; + g_email_html_body CLOB; + gc_newline CONSTANT CHAR(1) DEFAULT chr(13); TYPE t_rec_additional_costs IS RECORD( adit_code additional_items.code%TYPE @@ -102,6 +106,8 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ,cost_price costs.cost_price%TYPE ,delivery_cost costs.delivery_cost%TYPE); + SUBTYPE t_quote_row IS quotes%ROWTYPE; + PROCEDURE add_quote_event(p_qute_id IN quotes.id%TYPE ,p_qust_code quote_statuses.code%TYPE ,p_description quote_events.description%TYPE DEFAULT NULL @@ -204,7 +210,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS END lapse_quotes_job; FUNCTION start_quote(p_enqu_id IN enquiries.id%TYPE - ,p_manual_or_automatic IN VARCHAR2 DEFAULT g_automatic_quote + ,p_manual_or_automatic IN VARCHAR2 DEFAULT gc_automatic_quote ,p_rfq_prty_id IN parties.id%TYPE ,p_owner_prty_id IN parties.id%TYPE) RETURN quotes.id%TYPE IS @@ -279,53 +285,41 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ,p_qute_id); END make_quote_available; - PROCEDURE produce_email(p_enqu_id IN enquiries.id%TYPE) IS - l_manual_or_automatic t_manual_or_automatic_quote; - l_recipient VARCHAR(240); - l_subject VARCHAR2(240); - lg_body CLOB; - lg_html_body CLOB; - lgc_newline CONSTANT CHAR(1) DEFAULT chr(13); - l_description enquiry_types.description%TYPE; + FUNCTION get_system_configuration_value(p_parameter IN system_configuration.parameter%TYPE) + RETURN system_configuration.VALUE%TYPE IS + l_recipient system_configuration.VALUE%TYPE; + BEGIN + SELECT VALUE + INTO l_recipient + FROM system_configuration + WHERE parameter = p_parameter; - PROCEDURE open_body IS - BEGIN - dbms_lob.createtemporary(lob_loc => lg_body - ,cache => TRUE); - dbms_lob.OPEN(lob_loc => lg_body - ,open_mode => dbms_lob.lob_readwrite); - - dbms_lob.createtemporary(lob_loc => lg_html_body - ,cache => TRUE); - dbms_lob.OPEN(lob_loc => lg_html_body - ,open_mode => dbms_lob.lob_readwrite); - dbms_lob.writeappend(lg_html_body - ,length('') - ,''); - END open_body; - - PROCEDURE close_body IS - BEGIN - dbms_lob.writeappend(lg_html_body - ,length('') - ,''); - END close_body; - - PROCEDURE al(p_in IN VARCHAR2) IS - BEGIN - dbms_lob.writeappend(lg_body - ,length(p_in || lgc_newline) - ,p_in || lgc_newline); - - dbms_lob.writeappend(lg_html_body - ,length(p_in || '
') - ,p_in || '
'); - - END al; + RETURN l_recipient; + END get_system_configuration_value; + + FUNCTION get_manual_quote_recipient RETURN system_configuration.VALUE%TYPE IS BEGIN - open_body; + RETURN get_system_configuration_value('EMAIL_ADDRESS_MANUAL_QUOTE'); + END get_manual_quote_recipient; + + FUNCTION get_automatic_quote_recipient + RETURN system_configuration.VALUE%TYPE IS + BEGIN + RETURN get_system_configuration_value('EMAIL_ADDRESS_AUTOMATIC_QUOTE'); + END get_automatic_quote_recipient; + + FUNCTION get_system_name RETURN system_configuration.VALUE%TYPE IS + BEGIN + + RETURN get_system_configuration_value('SYSTEM_NAME'); + END get_system_name; + + FUNCTION get_enty_description(p_enqu_id IN enquiries.id%TYPE) + RETURN enquiry_types.description%TYPE IS + l_description enquiry_types.description%TYPE; + BEGIN SELECT description INTO l_description FROM enquiry_types enty @@ -333,70 +327,118 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS WHERE enty.code = enqu.enty_code AND enqu.id = p_enqu_id; - al('This email has been produced automatically by the WEBMIP quotation system'); - al(' '); - al('Quotations produced in response to Enquiry refererence: ' || - p_enqu_id || ' (' || l_description || ')'); + RETURN l_description; + END get_enty_description; + + PROCEDURE al(p_in IN VARCHAR2) IS + BEGIN + dbms_lob.writeappend(g_email_plain_body + ,length(p_in || gc_newline) + ,p_in || gc_newline); - FOR l_qute IN (SELECT * - FROM quotes - WHERE enqu_id = p_enqu_id) LOOP - l_manual_or_automatic := l_qute.qute_type; - IF l_qute.qute_type = g_automatic_quote THEN - al('Automatic Quote Reference: ' || l_qute.id); - al('Quote Summary:'); - al('This quote is valid from ' || - to_char(l_qute.valid_from - ,'Dth Month YYYY') || ' to ' || - to_char(l_qute.valid_until - ,'Dth Month YYYY')); - - FOR l_sum IN (SELECT * - FROM v_quote_details - WHERE quote_id = l_qute.id) LOOP - - IF l_sum.module_code IS NOT NULL THEN - al('Module code: ' || l_sum.module_code); - END IF; - IF l_sum.lead_time IS NOT NULL THEN - al('Lead time: ' || l_sum.module_code || ' days'); - END IF; - IF l_sum.additional_items IS NOT NULL THEN - al('Additional items: ' || l_sum.additional_items); - END IF; - IF l_sum.bas_code IS NOT NULL THEN - al('Base code: ' || l_sum.bas_code); - END IF; - IF l_sum.qmax IS NOT NULL THEN - al('Qmax: ' || l_sum.qmax); - END IF; - IF l_sum.qmin IS NOT NULL THEN - al('Qmin: ' || l_sum.module_code); - END IF; - IF l_sum.inlet_orientation IS NOT NULL THEN - al('Inlet orientation: ' || l_sum.inlet_orientation); - END IF; - IF l_sum.outlet_orientation IS NOT NULL THEN - al('Outlet orientation: ' || l_sum.outlet_orientation); - END IF; - IF l_sum.total_cost IS NOT NULL THEN - al('Total cost: £' || l_sum.total_cost); - END IF; - END LOOP; - ELSE - al('Manual Quote to be completed against Quote Reference: ' || - l_qute.id); - al('This quote will be valid from ' || - to_char(l_qute.valid_from - ,'Dth Month YYYY') || ' to ' || - to_char(l_qute.valid_until - ,'Dth Month YYYY')); - al(' '); - al('Current Service Level Agreements dictate that a manual quote be provided with 6 days'); + dbms_lob.writeappend(g_email_html_body + ,length(p_in || '
') + ,p_in || '
'); + + END al; + + PROCEDURE open_body IS + BEGIN + dbms_lob.createtemporary(lob_loc => g_email_plain_body + ,cache => TRUE); + dbms_lob.OPEN(lob_loc => g_email_plain_body + ,open_mode => dbms_lob.lob_readwrite); + + dbms_lob.createtemporary(lob_loc => g_email_html_body + ,cache => TRUE); + dbms_lob.OPEN(lob_loc => g_email_html_body + ,open_mode => dbms_lob.lob_readwrite); + dbms_lob.writeappend(g_email_html_body + ,length('') + ,''); + + al('This email has been produced automatically by the ' || + get_system_name || ' quotation system'); + al(' '); + END open_body; + + FUNCTION get_quote_row(p_qute_id IN quotes.id%TYPE) RETURN t_quote_row IS + l_row t_quote_row; + BEGIN + + SELECT * + INTO l_row + FROM quotes + WHERE id = p_qute_id; + + RETURN l_row; + END get_quote_row; + + PROCEDURE produce_quote_summary(p_qute_id IN quotes.id%TYPE) IS + l_quote_row t_quote_row; + BEGIN + + l_quote_row := get_quote_row(p_qute_id); + + al('Quote summary for Quote Reference: ' || p_qute_id); + al('This quote is valid from ' || + to_char(l_quote_row.valid_from + ,'ddth Month YYYY') || ' to ' || + to_char(l_quote_row.valid_until + ,'ddth Month YYYY')); + + FOR l_sum IN (SELECT * + FROM v_quote_details + WHERE quote_id = p_qute_id) LOOP + + IF l_sum.module_code IS NOT NULL THEN + al('Module code: ' || l_sum.module_code); + END IF; + IF l_sum.lead_time IS NOT NULL THEN + al('Lead time: ' || l_sum.lead_time || ' days'); + END IF; + IF l_sum.additional_items IS NOT NULL THEN + al('Additional items: ' || l_sum.additional_items); + END IF; + IF l_sum.bas_code IS NOT NULL THEN + al('Base code: ' || l_sum.bas_code); + END IF; + IF l_sum.hou_code IS NOT NULL THEN + al('Housing code: ' || l_sum.hou_code); + END IF; + IF l_sum.qmax IS NOT NULL THEN + al('Qmax: ' || l_sum.qmax); + END IF; + IF l_sum.qmin IS NOT NULL THEN + al('Qmin: ' || l_sum.qmin); + END IF; + IF l_sum.inlet_orientation IS NOT NULL THEN + al('Inlet orientation: ' || l_sum.inlet_orientation); + END IF; + IF l_sum.outlet_orientation IS NOT NULL THEN + al('Outlet orientation: ' || l_sum.outlet_orientation); + END IF; + IF l_sum.total_cost IS NOT NULL THEN + al('Total cost: £' || l_sum.total_cost); END IF; - al(' '); END LOOP; - al('WEBMIP used the following reasoning in reaching this decision:'); + END produce_quote_summary; + + PROCEDURE close_body IS + BEGIN + al(' '); + al('*** DO NOT REPLY TO THIS EMAIL ***'); + dbms_lob.writeappend(g_email_html_body + ,length('') + ,''); + END close_body; + + PROCEDURE produce_reasoning_summary(p_enqu_id IN enquiries.id%TYPE) IS + BEGIN + al(' '); + al(' '); + al(get_system_name || + ' used the following reasoning in reaching this decision:'); FOR l_rec IN (SELECT reason ,internal_or_external FROM quote_reasoning @@ -404,32 +446,80 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ORDER BY id) LOOP al(l_rec.reason); END LOOP; - al(' '); - al('*** DO NOT REPLY TO THIS EMAIL ***'); + + END produce_reasoning_summary; + + PROCEDURE email_aq_generated(p_enqu_id IN enquiries.id%TYPE) IS + BEGIN + open_body; + + al('Quotations produced in response to Enquiry refererence: ' || + p_enqu_id || ' (' || get_enty_description(p_enqu_id) || ')'); + + FOR l_qute IN (SELECT id + FROM quotes, + v_quote_details v + WHERE enqu_id = p_enqu_id + AND v.QUOTE_ID = id + ORDER BY total_cost) LOOP + + produce_quote_summary(l_qute.id); + + al(' '); + END LOOP; + + produce_reasoning_summary(p_enqu_id); close_body; - IF l_manual_or_automatic = g_automatic_quote THEN - l_subject := 'WEBMIP: Notification of generation of automatic quotes for Enquiry reference: ' || - p_enqu_id; - SELECT VALUE - INTO l_recipient - FROM system_configuration - WHERE parameter = 'EMAIL_ADDRESS_AUTOMATIC_QUOTE'; - ELSE - l_subject := 'WEBMIP: Request for a Manual Quote for Enquiry reference: ' || - p_enqu_id; - SELECT VALUE - INTO l_recipient - FROM system_configuration - WHERE parameter = 'EMAIL_ADDRESS_MANUAL_QUOTE'; - END IF; + mip_email.send_email_clob(p_recipient => get_automatic_quote_recipient + ,p_body => g_email_plain_body + ,p_body_html => g_email_html_body + ,p_subject => get_system_name || + ': Notification of generation of automatic quotes for Enquiry reference: ' || + p_enqu_id); + END email_aq_generated; + + PROCEDURE email_request_for_mq(p_enqu_id IN enquiries.id%TYPE) IS + l_system_name system_configuration.VALUE%TYPE := get_system_name; + l_quote_row quotes%ROWTYPE; + BEGIN - mip_email.send_email_clob(p_recipient => l_recipient - ,p_body => lg_body - ,p_body_html => lg_html_body - ,p_subject => l_subject); - END produce_email; + SELECT * + INTO l_quote_row + FROM quotes + WHERE enqu_id = p_enqu_id; + + open_body; + + al('This email has been produced in response to Enquiry refererence: ' || + p_enqu_id || ' (' || get_enty_description(p_enqu_id) || ')'); + + al(' '); + al(l_system_name || + ' was unable to produce an automatic quote for this Enquiry, therefore a ' || + 'Manual Quote is to be completed against Quote Reference: ' || + l_quote_row.id); + al('This quote will be valid from ' || + to_char(l_quote_row.valid_from + ,'ddth Month YYYY') || ' to ' || + to_char(l_quote_row.valid_until + ,'ddth Month YYYY')); + al(' '); + al('Current Service Level Agreements dictate that a manual quote be provided with 6 days'); + + produce_reasoning_summary(p_enqu_id); + + close_body; + + mip_email.send_email_clob(p_recipient => get_manual_quote_recipient + ,p_body => g_email_plain_body + ,p_body_html => g_email_html_body + ,p_subject => l_system_name || + ': Request for a Manual Quote for Enquiry reference: ' || + p_enqu_id); + + END email_request_for_mq; PROCEDURE request_manual_quote(p_enqu_id IN enquiries.id%TYPE ,p_rfq_prty_id IN parties.id%TYPE @@ -438,11 +528,11 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS BEGIN l_qute_id := start_quote(p_enqu_id => p_enqu_id - ,p_manual_or_automatic => g_manual_quote + ,p_manual_or_automatic => gc_manual_quote ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id); - produce_email(p_enqu_id => p_enqu_id); + email_request_for_mq(p_enqu_id => p_enqu_id); END request_manual_quote; @@ -467,7 +557,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS PROCEDURE add_quote_reason(p_enqu_id IN enquiries.id%TYPE ,p_reason IN quote_reasoning.reason%TYPE - ,p_internal_or_external IN quote_reasoning.internal_or_external%TYPE DEFAULT g_external_reason) IS + ,p_internal_or_external IN quote_reasoning.internal_or_external%TYPE DEFAULT gc_external_reason) IS BEGIN INSERT INTO quote_reasoning @@ -511,6 +601,10 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS RETURN BOOLEAN IS l_dummy NUMBER; BEGIN + IF p_existing_meter_size_code = p_required_meter_size_code THEN + RETURN TRUE; + END IF; + SELECT NULL INTO l_dummy FROM (SELECT code AS existing_mesc @@ -541,7 +635,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS WHERE code = p_enqu.required_svcp_code; IF l_svcpt_code = 'LP' THEN IF p_enqu.enty_code = 'RELOCATE' THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Site Survey is required for relocation.'); END IF; -- RELOCATE @@ -554,7 +648,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS IF NOT valid_meter_size_upgrade(p_existing_meter_size_code => l_existing_meter_size_code ,p_required_meter_size_code => l_required_meter_size_code) THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Site Survey is required for exchange of meter from size ' || l_existing_meter_size_code || ' to ' || @@ -567,61 +661,61 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS PROCEDURE manual_or_automatic_quote(p_enqu IN t_enqu ,p_manual_or_automatic_quote OUT t_manual_or_automatic_quote) IS BEGIN - p_manual_or_automatic_quote := g_automatic_quote; + p_manual_or_automatic_quote := gc_automatic_quote; survey_required(p_enqu => p_enqu ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); IF p_enqu.twin_stream_required = 'YES' THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Twin stream required.'); END IF; IF p_enqu.bypass_required = 'YES' THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Bypass required.'); END IF; IF p_enqu.required_metering_pressure > 21 THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Required metering pressure is greater than 21mbar.'); END IF; IF p_enqu.job_description IS NOT NULL THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Job Description field was entered.'); END IF; IF p_enqu.downstream_booster_or_compress = 'YES' THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Booster or compressor is present downstream of the meter module.'); END IF; IF p_enqu.annual_quantity > 732 THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Required Annual Quantity is in excess of 732MWh.'); END IF; -- check postcode IF NOT mip_regions.valid_postcode_format(p_enqu.install_postcode) THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Installation postcode is of an unrecognized format.'); ELSIF mip_regions.get_region_for_postcode(p_enqu.install_postcode) IS NULL THEN - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu.id ,'Unable to determine pricing region for given installation postcode.'); END IF; - IF p_manual_or_automatic_quote = g_manual_quote THEN + IF p_manual_or_automatic_quote = gc_manual_quote THEN add_quote_reason(p_enqu.id ,'- Manual quote required.' - ,g_internal_reason); + ,gc_internal_reason); END IF; END manual_or_automatic_quote; @@ -796,10 +890,10 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS RETURN l_rec_costs; END get_laco; - PROCEDURE produce_install_quotes(p_enqu IN t_enqu - ,p_rfq_prty_id IN parties.id%TYPE - ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL - ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS + PROCEDURE produce_inst_exch_quotes(p_enqu IN t_enqu + ,p_rfq_prty_id IN parties.id%TYPE + ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL + ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS l_produced_automatic_quote BOOLEAN; l_this_is_automatic_quote BOOLEAN; l_regi_code regions.code%TYPE := mip_regions.get_region_for_postcode(p_enqu.install_postcode); @@ -807,20 +901,35 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS l_additional_costs t_rec_additional_costs; l_quote_document VARCHAR2(240); BEGIN - cout_assert.istrue(p_enqu.enty_code IN ('INSTALL', 'STD INSTALL') - ,'Attempted to produce an install quote for enquiry of type ' || + cout_assert.istrue(p_enqu.enty_code IN + ('INSTALL', 'STD INSTALL', 'EXCHANGE') + ,'Attempted to produce an install or exchange quote for enquiry of type ' || p_enqu.enty_code); cout_assert.isnotnull(l_regi_code - ,'Attempted to produce an install quote for enquiry for a installation postcode (' || + ,'Attempted to produce an install or exchange quote for enquiry for a installation postcode (' || p_enqu.install_postcode || ') without a region.'); - add_quote_reason(p_enqu.id - ,p_reason => 'Attempting an automatic installation quote for ' || - p_enqu.id || '.' || ' Required SVCP ' || - p_enqu.required_svcp_code || ', QMAX=' || - p_enqu.qmax || ', Outlet Pressure=' || - p_enqu.required_metering_pressure || '.' - ,p_internal_or_external => g_internal_reason); + + IF p_enqu.enty_code IN ('INSTALL', 'STD INSTALL') THEN + add_quote_reason(p_enqu.id + ,p_reason => 'Attempting an automatic installation quote for ' || + p_enqu.id || '.' || ' Required SVCP ' || + p_enqu.required_svcp_code || ', QMAX=' || + p_enqu.qmax || ', Outlet Pressure=' || + p_enqu.required_metering_pressure || '.' + ,p_internal_or_external => gc_internal_reason); + ELSIF p_enqu.enty_code IN ('EXCHANGE') THEN + add_quote_reason(p_enqu.id + ,p_reason => 'Attempting an automatic exchange quote for ' || + p_enqu.id || '.' || ' Required SVCP ' || + p_enqu.required_svcp_code || ', QMAX=' || + p_enqu.qmax || ', Outlet Pressure=' || + p_enqu.required_metering_pressure || '.' || + 'Existing meter was a ' || + p_enqu.existing_mesc_code || ' ' || + p_enqu.mety_code + ,p_internal_or_external => gc_internal_reason); + END IF; FOR l_rec_module IN (SELECT modu.code AS modu_code ,modu.selling_price AS modu_selling_price @@ -944,7 +1053,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu.id ,p_reason => 'Considering module : ' || l_rec_module.modu_code - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); -- -- check whether we have the required prices -- if we do not, then we may need to produce a manual quote @@ -955,14 +1064,14 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ,p_reason => 'Unable to find selling price for module ' || l_rec_module.modu_code || CASE l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_rec_module.modu_lead_time IS NULL THEN l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find lead time for module ' || l_rec_module.modu_code || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; l_additional_costs := get_laco(p_enty_code => p_enqu.enty_code @@ -987,7 +1096,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS p_enqu.required_svcp_code || CASE l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF p_enqu.base_required = 'YES' THEN @@ -1002,13 +1111,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for base ' || l_rec_module.bas_code || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; ELSE l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Module is not available with base.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END IF; @@ -1024,13 +1133,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for housing ' || l_rec_module.hou_code || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; ELSE l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Module is not available with housing.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END IF; @@ -1045,13 +1154,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for AMR.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_rec_module.amr_lead_time IS NULL THEN l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find lead time for AMR.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END IF; IF p_enqu.ems_required = 'YES' THEN @@ -1065,13 +1174,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for EMS.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_rec_module.ems_lead_time IS NULL THEN l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find lead time for EMS.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END IF; IF p_enqu.bypass_required = 'YES' THEN @@ -1085,13 +1194,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for BYPASS.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_rec_module.bypass_lead_time IS NULL THEN l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find lead time for BYPASS.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END IF; @@ -1107,13 +1216,13 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find selling price for LIFTING GEAR.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_rec_module.lifting_gear_lead_time IS NULL THEN l_this_is_automatic_quote := FALSE; add_quote_reason(p_enqu.id ,p_reason => 'Unable to find lead time for LIFTING GEAR.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_this_is_automatic_quote THEN @@ -1121,10 +1230,10 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => 'Producing an automatic quote.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); l_qute_id := start_quote(p_enqu_id => p_enqu.id - ,p_manual_or_automatic => g_automatic_quote + ,p_manual_or_automatic => gc_automatic_quote ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id); @@ -1309,7 +1418,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => 'Produced Quote Document ' || l_quote_document || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); make_quote_available(l_qute_id); @@ -1318,21 +1427,600 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS END LOOP; IF l_produced_automatic_quote THEN - p_manual_or_automatic_quote := g_automatic_quote; + p_manual_or_automatic_quote := gc_automatic_quote; add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => '-- Produced an automatic quote.' - ,p_internal_or_external => g_internal_reason); - produce_email(p_enqu.id); + ,p_internal_or_external => gc_internal_reason); +-- email_aq_generated(p_enqu.id); ELSE - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => '-- Automatic quote failed - Manual quote required.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; + END produce_inst_exch_quotes; + + /*PROCEDURE produce_install_quotes(p_enqu IN t_enqu + ,p_rfq_prty_id IN parties.id%TYPE + ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL + ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS + l_produced_automatic_quote BOOLEAN; + l_this_is_automatic_quote BOOLEAN; + l_regi_code regions.code%TYPE := mip_regions.get_region_for_postcode(p_enqu.install_postcode); + l_qute_id quotes.id%TYPE; + l_additional_costs t_rec_additional_costs; + l_quote_document VARCHAR2(240); + BEGIN + cout_assert.istrue(p_enqu.enty_code IN ('INSTALL', 'STD INSTALL') + ,'Attempted to produce an install quote for enquiry of type ' || + p_enqu.enty_code); + + cout_assert.isnotnull(l_regi_code + ,'Attempted to produce an install quote for enquiry for a installation postcode (' || + p_enqu.install_postcode || ') without a region.'); + add_quote_reason(p_enqu.id + ,p_reason => 'Attempting an automatic installation quote for ' || + p_enqu.id || '.' || ' Required SVCP ' || + p_enqu.required_svcp_code || ', QMAX=' || + p_enqu.qmax || ', Outlet Pressure=' || + p_enqu.required_metering_pressure || '.' + ,p_internal_or_external => gc_internal_reason); + + FOR l_rec_module IN (SELECT modu.code AS modu_code + ,modu.selling_price AS modu_selling_price + ,modu.cost_price AS modu_cost_price + ,modu.delivery_cost AS modu_delivery_cost + ,modu.lead_time AS modu_lead_time + ,modu.hou_code AS hou_code + ,modu.inlet_orientation AS modu_inlet_orientation + ,modu.outlet_orientation AS modu_outlet_orientation + ,NULL AS hou_selling_price + ,NULL AS hou_cost_price + ,NULL AS hou_delivery_cost + ,modu.bas_code AS bas_code + ,NULL AS bas_selling_price + ,NULL AS bas_cost_price + ,NULL AS bas_delivery_cost + ,metr.code AS metr_code + ,metr.qnom + ,metr.qmax + ,metr.qmin + ,metr.selling_price AS metr_selling_price + ,metr.cost_price AS metr_cost_price + ,metr.delivery_cost AS metr_delivery_cost + ,metr.mety_code + ,NULL AS laco_mety_code + ,NULL AS laco_svcpt_code + ,NULL AS laco_mesc_code + ,NULL AS laco_selling_price + ,NULL AS laco_cost_price + ,NULL AS laco_delivery_cost + ,NULL AS amr_cost_id + ,NULL AS amr_selling_price + ,NULL AS amr_cost_price + ,NULL AS amr_delivery_cost + ,NULL AS amr_lead_time + ,NULL AS ems_cost_id + ,NULL AS ems_selling_price + ,NULL AS ems_cost_price + ,NULL AS ems_delivery_cost + ,NULL AS ems_lead_time + ,NULL AS bypass_cost_id + ,NULL AS bypass_selling_price + ,NULL AS bypass_cost_price + ,NULL AS bypass_delivery_cost + ,NULL AS bypass_lead_time + ,NULL AS lifting_gear_cost_id + ,NULL AS lifting_gear_selling_price + ,NULL AS lifting_gear_cost_price + ,NULL AS lifting_gear_delivery_cost + ,NULL AS lifting_gear_lead_time + FROM (SELECT modu.code + ,modu.metr_code + ,modu.hou_code + ,modu.bas_code + ,svcp_code + ,outlet_pressure + ,cnor_i.description AS inlet_orientation + ,cnor_o.description AS outlet_orientation + ,selling_price + ,cost_price + ,delivery_cost + ,lead_time + FROM modules modu + ,connection_orientations cnor_i + ,connection_orientations cnor_o + ,(SELECT modu_code + ,selling_price + ,cost_price + ,delivery_cost + FROM (SELECT row_number() over(PARTITION BY modu_code ORDER BY(decode(regi_code, l_regi_code, 1, 999))) AS accuracy + ,modu_code + ,selling_price + ,cost_price + ,delivery_cost + ,ROWID + FROM v_moco cost + WHERE SYSDATE BETWEEN + cost.effective_from AND + cost.effective_to + AND (regi_code = + l_regi_code OR + regi_code IS NULL)) + WHERE accuracy <= 1) cost + WHERE modu.code = cost.modu_code(+) + AND modu.inlet_cnor_code = cnor_i.code + AND modu.outlet_cnor_code = cnor_o.code) modu + ,(SELECT metr.code + ,metr.qmax + ,metr.qmin + ,metr.qnom + ,metr.mety_code + ,selling_price + ,cost_price + ,delivery_cost + FROM meters metr + ,(SELECT metr_code + ,selling_price + ,cost_price + ,delivery_cost + FROM (SELECT row_number() over(PARTITION BY metr_code ORDER BY(decode(regi_code, l_regi_code, 1, 999))) AS accuracy + ,metr_code + ,selling_price + ,cost_price + ,delivery_cost + ,ROWID + FROM v_meco cost + WHERE SYSDATE BETWEEN + cost.effective_from AND + cost.effective_to + AND (regi_code = + l_regi_code OR + regi_code IS NULL)) + WHERE accuracy <= 1) cost + WHERE metr.code = cost.metr_code(+)) metr + WHERE modu.svcp_code = p_enqu.required_svcp_code + AND modu.outlet_pressure = + p_enqu.required_metering_pressure + AND metr.code = modu.metr_code + AND metr.qmax >= p_enqu.qmax) LOOP + l_this_is_automatic_quote := TRUE; + add_quote_reason(p_enqu.id + ,p_reason => 'Considering module : ' || + l_rec_module.modu_code + ,p_internal_or_external => gc_internal_reason); + -- + -- check whether we have the required prices + -- if we do not, then we may need to produce a manual quote + -- + IF l_rec_module.modu_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for module ' || + l_rec_module.modu_code || CASE + l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' + ,p_internal_or_external => gc_internal_reason); + END IF; + IF l_rec_module.modu_lead_time IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find lead time for module ' || + l_rec_module.modu_code || '.' + ,p_internal_or_external => gc_internal_reason); + END IF; + + l_additional_costs := get_laco(p_enty_code => p_enqu.enty_code + ,p_regi_code => l_regi_code + ,p_mety_code => l_rec_module.mety_code + ,p_mesc_code => p_enqu.required_mesc_code + ,p_svcp_code => p_enqu.required_svcp_code); + l_rec_module.laco_svcpt_code := l_additional_costs.svcpt_code; + l_rec_module.laco_selling_price := l_additional_costs.selling_price; + l_rec_module.laco_cost_price := l_additional_costs.cost_price; + l_rec_module.laco_delivery_cost := l_additional_costs.delivery_cost; + IF l_rec_module.laco_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find Labour Cost (selling price) for this Enquiry Type Code: ' || + p_enqu.enty_code || + ', Meter Type Code:' || + l_rec_module.mety_code || + ', Meter Size Code:' || + p_enqu.required_mesc_code || + ', Service Pressure Code:' || + p_enqu.required_svcp_code || CASE + l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' + + ,p_internal_or_external => gc_internal_reason); + END IF; + + IF p_enqu.base_required = 'YES' THEN + IF l_rec_module.bas_code IS NOT NULL THEN + l_additional_costs := get_base(p_bas_code => l_rec_module.bas_code + ,p_regi_code => l_regi_code); + l_rec_module.bas_selling_price := l_additional_costs.selling_price; + l_rec_module.bas_cost_price := l_additional_costs.cost_price; + l_rec_module.bas_delivery_cost := l_additional_costs.delivery_cost; + IF l_rec_module.bas_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for base ' || + l_rec_module.bas_code || '.' + ,p_internal_or_external => gc_internal_reason); + END IF; + ELSE + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Module is not available with base.' + ,p_internal_or_external => gc_internal_reason); + END IF; + END IF; + + IF p_enqu.housing_required = 'YES' THEN + IF l_rec_module.hou_code IS NOT NULL THEN + l_additional_costs := get_housing(p_hou_code => l_rec_module.hou_code + ,p_regi_code => l_regi_code); + l_rec_module.hou_selling_price := l_additional_costs.selling_price; + l_rec_module.hou_cost_price := l_additional_costs.cost_price; + l_rec_module.hou_delivery_cost := l_additional_costs.delivery_cost; + IF l_rec_module.hou_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for housing ' || + l_rec_module.hou_code || '.' + ,p_internal_or_external => gc_internal_reason); + END IF; + ELSE + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Module is not available with housing.' + ,p_internal_or_external => gc_internal_reason); + END IF; + END IF; + + IF p_enqu.amr_required = 'YES' THEN + l_additional_costs := get_aico(p_adit_code => 'AMR' + ,p_regi_code => l_regi_code); + l_rec_module.amr_selling_price := l_additional_costs.selling_price; + l_rec_module.amr_cost_price := l_additional_costs.cost_price; + l_rec_module.amr_delivery_cost := l_additional_costs.delivery_cost; + l_rec_module.amr_lead_time := l_additional_costs.lead_time; + IF l_rec_module.amr_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for AMR.' + ,p_internal_or_external => gc_internal_reason); + END IF; + IF l_rec_module.amr_lead_time IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find lead time for AMR.' + ,p_internal_or_external => gc_internal_reason); + END IF; + END IF; + IF p_enqu.ems_required = 'YES' THEN + l_additional_costs := get_aico(p_adit_code => 'EMS' + ,p_regi_code => l_regi_code); + l_rec_module.ems_selling_price := l_additional_costs.selling_price; + l_rec_module.ems_cost_price := l_additional_costs.cost_price; + l_rec_module.ems_delivery_cost := l_additional_costs.delivery_cost; + l_rec_module.ems_lead_time := l_additional_costs.lead_time; + IF l_rec_module.ems_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for EMS.' + ,p_internal_or_external => gc_internal_reason); + END IF; + IF l_rec_module.ems_lead_time IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find lead time for EMS.' + ,p_internal_or_external => gc_internal_reason); + END IF; + END IF; + IF p_enqu.bypass_required = 'YES' THEN + l_additional_costs := get_aico(p_adit_code => 'BYPASS' + ,p_regi_code => l_regi_code); + l_rec_module.bypass_selling_price := l_additional_costs.selling_price; + l_rec_module.bypass_cost_price := l_additional_costs.cost_price; + l_rec_module.bypass_delivery_cost := l_additional_costs.delivery_cost; + l_rec_module.bypass_lead_time := l_additional_costs.lead_time; + IF l_rec_module.bypass_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for BYPASS.' + ,p_internal_or_external => gc_internal_reason); + END IF; + IF l_rec_module.bypass_lead_time IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find lead time for BYPASS.' + ,p_internal_or_external => gc_internal_reason); + END IF; + + END IF; + \* Always get costs for LIFTING GEAR *\ + + l_additional_costs := get_aico(p_adit_code => 'LIFTING GEAR' + ,p_regi_code => l_regi_code); + l_rec_module.lifting_gear_selling_price := l_additional_costs.selling_price; + l_rec_module.lifting_gear_cost_price := l_additional_costs.cost_price; + l_rec_module.lifting_gear_delivery_cost := l_additional_costs.delivery_cost; + l_rec_module.lifting_gear_lead_time := l_additional_costs.lead_time; + IF l_rec_module.lifting_gear_selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find selling price for LIFTING GEAR.' + ,p_internal_or_external => gc_internal_reason); + END IF; + IF l_rec_module.lifting_gear_lead_time IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find lead time for LIFTING GEAR.' + ,p_internal_or_external => gc_internal_reason); + END IF; + + IF l_this_is_automatic_quote THEN + l_produced_automatic_quote := TRUE; + + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => 'Producing an automatic quote.' + ,p_internal_or_external => gc_internal_reason); + + l_qute_id := start_quote(p_enqu_id => p_enqu.id + ,p_manual_or_automatic => gc_automatic_quote + ,p_rfq_prty_id => p_rfq_prty_id + ,p_owner_prty_id => p_owner_prty_id); + + INSERT INTO quote_items + (id + ,qute_id + ,enty_code + ,mety_code + ,svcpt_code + ,mesc_code + ,cost_price + ,selling_price + ,delivery_price + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,p_enqu.enty_code + ,l_rec_module.laco_mety_code + ,l_rec_module.laco_svcpt_code + ,l_rec_module.laco_mesc_code + ,l_rec_module.laco_cost_price + ,l_rec_module.laco_selling_price + ,l_rec_module.laco_delivery_cost + ,'LQI'); + + INSERT INTO quote_items + (id + ,qute_id + ,modu_code + ,qmax + ,qmin + ,inlet_orientation + ,outlet_orientation + ,cost_price + ,selling_price + ,delivery_price + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,l_rec_module.modu_code + ,l_rec_module.qmax + ,l_rec_module.qmin + ,l_rec_module.modu_inlet_orientation + ,l_rec_module.modu_outlet_orientation + ,l_rec_module.modu_cost_price + ,l_rec_module.modu_selling_price + ,l_rec_module.modu_delivery_cost + ,'MQI'); + + IF p_enqu.housing_required = 'YES' THEN + INSERT INTO quote_items + (id + ,qute_id + ,hou_code + ,cost_price + ,selling_price + ,delivery_price + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,l_rec_module.hou_code + ,l_rec_module.hou_cost_price + ,l_rec_module.hou_selling_price + ,l_rec_module.hou_delivery_cost + ,'HQI'); + END IF; + + IF p_enqu.base_required = 'YES' THEN + INSERT INTO quote_items + (id + ,qute_id + ,bas_code + ,cost_price + ,selling_price + ,delivery_price + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,l_rec_module.bas_code + ,l_rec_module.bas_cost_price + ,l_rec_module.bas_selling_price + ,l_rec_module.bas_delivery_cost + ,'BQI'); + END IF; + + IF p_enqu.amr_required = 'YES' THEN + INSERT INTO quote_items + (id + ,qute_id + ,adit_code + ,cost_price + ,selling_price + ,delivery_price + ,lead_time + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,'AMR' + ,l_rec_module.amr_cost_price + ,l_rec_module.amr_selling_price + ,l_rec_module.amr_delivery_cost + ,l_rec_module.amr_lead_time + ,'AQI'); + END IF; + + IF p_enqu.ems_required = 'YES' THEN + INSERT INTO quote_items + (id + ,qute_id + ,adit_code + ,cost_price + ,selling_price + ,delivery_price + ,lead_time + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,'EMS' + ,l_rec_module.ems_cost_price + ,l_rec_module.ems_selling_price + ,l_rec_module.ems_delivery_cost + ,l_rec_module.ems_lead_time + ,'AQI'); + END IF; + + IF p_enqu.bypass_required = 'YES' THEN + INSERT INTO quote_items + (id + ,qute_id + ,adit_code + ,cost_price + ,selling_price + ,delivery_price + ,lead_time + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,'BYPASS' + ,l_rec_module.bypass_cost_price + ,l_rec_module.bypass_selling_price + ,l_rec_module.bypass_delivery_cost + ,l_rec_module.bypass_lead_time + ,'AQI'); + END IF; + + \* Always include LIFTING GEAR *\ + + INSERT INTO quote_items + (id + ,qute_id + ,adit_code + ,cost_price + ,selling_price + ,delivery_price + ,lead_time + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,'LIFTING GEAR' + ,l_rec_module.lifting_gear_cost_price + ,l_rec_module.lifting_gear_selling_price + ,l_rec_module.lifting_gear_delivery_cost + ,l_rec_module.lifting_gear_lead_time + ,'AQI'); + + -- Generate the quote PDF + \*BEGIN*\ + l_quote_document := mip_quotation_document.generate_quote_pdf(p_quote_id => l_qute_id); + \* EXCEPTION + WHEN OTHERS THEN + cout_err.report_and_stop; + END; + *\ + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => 'Produced Quote Document ' || + l_quote_document || '.' + ,p_internal_or_external => gc_internal_reason); + + make_quote_available(l_qute_id); + + END IF; -- automatic quote + + END LOOP; + + IF l_produced_automatic_quote THEN + p_manual_or_automatic_quote := gc_automatic_quote; + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => '-- Produced an automatic quote.' + ,p_internal_or_external => gc_internal_reason); + email_aq_generated(p_enqu.id); + ELSE + p_manual_or_automatic_quote := gc_manual_quote; + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => '-- Automatic quote failed - Manual quote required.' + ,p_internal_or_external => gc_internal_reason); + + END IF; + + END produce_install_quotes;*/ + + PROCEDURE produce_install_quotes(p_enqu IN t_enqu + ,p_rfq_prty_id IN parties.id%TYPE + ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL + ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS + l_regi_code regions.code%TYPE := mip_regions.get_region_for_postcode(p_enqu.install_postcode); + BEGIN + cout_assert.istrue(p_enqu.enty_code IN ('STD INSTALL', 'INSTALL') + ,'Attempted to produce an installation quote for enquiry of type ' || + p_enqu.enty_code); + + cout_assert.isnotnull(l_regi_code + ,'Attempted to produce an installation quote for enquiry for a installation postcode (' || + p_enqu.install_postcode || ') without a region.'); + + produce_inst_exch_quotes(p_enqu => p_enqu + ,p_rfq_prty_id => p_rfq_prty_id + ,p_owner_prty_id => p_owner_prty_id + ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); + END produce_install_quotes; + PROCEDURE produce_exchange_quotes(p_enqu IN t_enqu + ,p_rfq_prty_id IN parties.id%TYPE + ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL + ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS + l_regi_code regions.code%TYPE := mip_regions.get_region_for_postcode(p_enqu.install_postcode); + BEGIN + cout_assert.istrue(p_enqu.enty_code IN ('EXCHANGE') + ,'Attempted to produce an exchange quote for enquiry of type ' || + p_enqu.enty_code); + + cout_assert.isnotnull(l_regi_code + ,'Attempted to produce an exchange quote for enquiry for a installation postcode (' || + p_enqu.install_postcode || ') without a region.'); + + produce_inst_exch_quotes(p_enqu => p_enqu + ,p_rfq_prty_id => p_rfq_prty_id + ,p_owner_prty_id => p_owner_prty_id + ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); + + END produce_exchange_quotes; + PROCEDURE produce_removal_quotes(p_enqu IN t_enqu ,p_rfq_prty_id IN parties.id%TYPE ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL @@ -1358,7 +2046,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ', Meter Type Code=' || p_enqu.mety_code || ', Meter Size Code=' || p_enqu.existing_mesc_code || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); l_this_is_automatic_quote := TRUE; @@ -1378,7 +2066,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS p_enqu.required_svcp_code || CASE l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; IF l_this_is_automatic_quote THEN @@ -1386,10 +2074,10 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => 'Producing an automatic quote.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); l_qute_id := start_quote(p_enqu_id => p_enqu.id - ,p_manual_or_automatic => g_automatic_quote + ,p_manual_or_automatic => gc_automatic_quote ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id); @@ -1427,34 +2115,150 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => 'Produced Quote Document ' || l_quote_document || '.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); make_quote_available(l_qute_id); END IF; -- automatic quote IF l_produced_automatic_quote THEN - p_manual_or_automatic_quote := g_automatic_quote; + p_manual_or_automatic_quote := gc_automatic_quote; add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => '-- Produced an automatic quote.' - ,p_internal_or_external => g_internal_reason); - produce_email(p_enqu.id); + ,p_internal_or_external => gc_internal_reason); + email_aq_generated(p_enqu.id); ELSE - p_manual_or_automatic_quote := g_manual_quote; + p_manual_or_automatic_quote := gc_manual_quote; add_quote_reason(p_enqu_id => p_enqu.id ,p_reason => '-- Automatic quote failed - Manual quote required.' - ,p_internal_or_external => g_internal_reason); + ,p_internal_or_external => gc_internal_reason); END IF; END produce_removal_quotes; + PROCEDURE produce_gash_quotes(p_enqu IN t_enqu + ,p_rfq_prty_id IN parties.id%TYPE + ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL + ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS + l_produced_automatic_quote BOOLEAN; + l_this_is_automatic_quote BOOLEAN; + l_regi_code regions.code%TYPE := mip_regions.get_region_for_postcode(p_enqu.install_postcode); + l_qute_id quotes.id%TYPE; + l_additional_costs t_rec_additional_costs; + l_quote_document VARCHAR2(240); + BEGIN + cout_assert.istrue(p_enqu.enty_code IN ('REMOVE', 'STD REMOVE') + ,'Attempted to produce a removal quote for enquiry of type ' || + p_enqu.enty_code); + + cout_assert.isnotnull(l_regi_code + ,'Attempted to produce an removal quote for enquiry for a installation postcode (' || + p_enqu.install_postcode || ') without a region.'); + add_quote_reason(p_enqu.id + ,p_reason => 'Attempting an automatic removal quote for ' || + p_enqu.id || '.' || ' Required SVCP ' || + p_enqu.required_svcp_code || + ', Meter Type Code=' || p_enqu.mety_code || + ', Meter Size Code=' || + p_enqu.existing_mesc_code || '.' + ,p_internal_or_external => gc_internal_reason); + + l_this_is_automatic_quote := TRUE; + + l_additional_costs := get_laco(p_enty_code => p_enqu.enty_code + ,p_regi_code => l_regi_code + ,p_mety_code => p_enqu.mety_code + ,p_mesc_code => p_enqu.existing_mesc_code + ,p_svcp_code => p_enqu.required_svcp_code); + IF l_additional_costs.selling_price IS NULL THEN + l_this_is_automatic_quote := FALSE; + add_quote_reason(p_enqu.id + ,p_reason => 'Unable to find Labour Cost (selling price) for this Enquiry Type Code: ' || + p_enqu.enty_code || ', Meter Type Code:' || + p_enqu.mety_code || ', Meter Size Code:' || + p_enqu.existing_mesc_code || + ', Service Pressure Code:' || + p_enqu.required_svcp_code || CASE + l_regi_code WHEN NULL THEN '' ELSE ' for region code ' || l_regi_code END || '.' + + ,p_internal_or_external => gc_internal_reason); + END IF; + + IF l_this_is_automatic_quote THEN + l_produced_automatic_quote := TRUE; + + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => 'Producing an automatic quote.' + ,p_internal_or_external => gc_internal_reason); + + l_qute_id := start_quote(p_enqu_id => p_enqu.id + ,p_manual_or_automatic => gc_automatic_quote + ,p_rfq_prty_id => p_rfq_prty_id + ,p_owner_prty_id => p_owner_prty_id); + + INSERT INTO quote_items + (id + ,qute_id + ,enty_code + ,svcpt_code + ,mesc_code + ,mety_code + ,cost_price + ,selling_price + ,delivery_price + ,quit_type) + VALUES + (quit_seq.NEXTVAL + ,l_qute_id + ,p_enqu.enty_code + ,l_additional_costs.svcpt_code + ,p_enqu.existing_mesc_code + ,p_enqu.mety_code + ,l_additional_costs.cost_price + ,l_additional_costs.selling_price + ,l_additional_costs.delivery_cost + ,'LQI'); + + -- Generate the quote PDF + /*BEGIN*/ + l_quote_document := mip_quotation_document.generate_quote_pdf(p_quote_id => l_qute_id); + /* EXCEPTION + WHEN OTHERS THEN + cout_err.report_and_stop; + END; + */ + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => 'Produced Quote Document ' || + l_quote_document || '.' + ,p_internal_or_external => gc_internal_reason); + + make_quote_available(l_qute_id); + + END IF; -- automatic quote + + IF l_produced_automatic_quote THEN + p_manual_or_automatic_quote := gc_automatic_quote; + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => '-- Produced an automatic quote.' + ,p_internal_or_external => gc_internal_reason); + email_aq_generated(p_enqu.id); + ELSE + p_manual_or_automatic_quote := gc_manual_quote; + add_quote_reason(p_enqu_id => p_enqu.id + ,p_reason => '-- Automatic quote failed - Manual quote required.' + ,p_internal_or_external => gc_internal_reason); + + END IF; + + END produce_gash_quotes; + PROCEDURE produce_automatic_quotes(p_enqu IN t_enqu ,p_rfq_prty_id IN parties.id%TYPE ,p_owner_prty_id IN parties.id%TYPE DEFAULT NULL ,p_manual_or_automatic_quote IN OUT t_manual_or_automatic_quote) IS BEGIN - cout_assert.istrue(p_manual_or_automatic_quote = g_automatic_quote + cout_assert.istrue(p_manual_or_automatic_quote = gc_automatic_quote ,p_message => 'Attempted to produce automatic quote for enquiry marked as manual only'); IF p_enqu.enty_code IN ('INSTALL', 'STD INSTALL') THEN @@ -1462,12 +2266,16 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); + ELSIF p_enqu.enty_code IN ('EXCHANGE') THEN + produce_exchange_quotes(p_enqu => p_enqu + ,p_rfq_prty_id => p_rfq_prty_id + ,p_owner_prty_id => p_owner_prty_id + ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); ELSIF p_enqu.enty_code IN ('REMOVE', 'STD REMOVE') THEN produce_removal_quotes(p_enqu => p_enqu ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id ,p_manual_or_automatic_quote => p_manual_or_automatic_quote); - ELSE cout_err.report_and_stop(p_exception_message => 'Attempted to produce automatic quote for unexpected enquiry type of ' || p_enqu.enty_code); @@ -1493,7 +2301,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS manual_or_automatic_quote(p_enqu => l_enqu ,p_manual_or_automatic_quote => l_manual_or_automatic_quote); - IF l_manual_or_automatic_quote = g_manual_quote THEN + IF l_manual_or_automatic_quote = gc_manual_quote THEN request_manual_quote(p_enqu_id => l_enqu.id ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id); @@ -1502,7 +2310,7 @@ CREATE OR REPLACE PACKAGE BODY mip_quotation IS ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id ,p_manual_or_automatic_quote => l_manual_or_automatic_quote); - IF l_manual_or_automatic_quote = g_manual_quote THEN + IF l_manual_or_automatic_quote = gc_manual_quote THEN request_manual_quote(p_enqu_id => l_enqu.id ,p_rfq_prty_id => p_rfq_prty_id ,p_owner_prty_id => p_owner_prty_id); diff --git a/Schema/V_QUOTE_DETAILS.vw b/Schema/V_QUOTE_DETAILS.vw index ab8d3a4..ee3268c 100644 --- a/Schema/V_QUOTE_DETAILS.vw +++ b/Schema/V_QUOTE_DETAILS.vw @@ -13,6 +13,7 @@ SELECT * ,MAX(t.lead_time) over(PARTITION BY qute_id ORDER BY qute_id) AS lead_time ,get_quote_items(qute_id) AS additional_items ,MAX(t.bas_code) over(PARTITION BY qute_id) AS bas_code + ,MAX(t.hou_code) over(PARTITION BY qute_id) AS hou_code ,MAX(t.qmax) over(PARTITION BY qute_id) AS qmax ,MAX(t.qmin) over(PARTITION BY qute_id) AS qmin ,MAX(t.inlet_orientation) over(PARTITION BY qute_id) AS inlet_orientation @@ -44,3 +45,4 @@ COMMENT ON COLUMN v_quote_details.qmin IS 'The meter module''s Q min.'; COMMENT ON COLUMN v_quote_details.inlet_orientation IS 'The orientation of the meter inlet.'; COMMENT ON COLUMN v_quote_details.outlet_orientation IS 'The orientatino of the meter outlet.'; COMMENT ON COLUMN v_quote_details.total_cost IS 'The total cost of the quote. This figure excludes any lifting gear or purging.'; +/