--DatabaseObjects
create or replace procedure add_pricelists_30051_deltos_600999(fp_systemuserid in number default 1) is
  --Version 0.1 procedure add_pricelists_30051_deltos_600999
  --Global variables
  gv_user__exception exception;
  gv_message            varchar2(1000);
  gv_replace_counter    number := 0;
  gv_sales_counter      number := 0;
  gv_replacementpriceid generalreplacementprice.generalreplacementprice_id%type;
  gv_salespriceid       generalsalesprice.generalsalesprice_id%type;
  gv_customer600999id   customer.customer_id%type;

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'add_pricelists_30051_deltos_600999', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null;
    end;
  end write_log;

  procedure initialize is
  begin
    --get general replacement price 
    gv_message := 'general replacement price 30051';
    select gp.generalpricelist_id
    into   gv_replacementpriceid
    from   generalpricelist gp
    where  gp.code = '30051'
    and    gp.pricetype = 3;
    --get general sales price
    gv_message := 'general sales price 30051';
    select gp.generalpricelist_id
    into   gv_salespriceid
    from   generalpricelist gp
    where  gp.code = '30051'
    and    gp.pricetype = 4;
    --get customer 
    gv_message := 'customer 600999';
    select c.customer_id into gv_customer600999id from customer c where c.customernumber = 600999;
  end initialize;

  procedure finalize is
  begin
    --finalize
    commit;
    write_log('Inserted ' || to_char(gv_replace_counter) || ' replacement and ' ||
              to_char(gv_sales_counter) || ' sales pricelistpercustomer records', 1);
  end finalize;
begin
  --Main program part
  --initialize
  initialize;
  --CUSTOMER_ID, PRICETYPE, GENERALPRICELIST_ID
  gv_message := 'insert into pricelistpercustomer replacement price';
  insert into pricelistpercustomer
    (pricelistpercustomer_id, customer_id, pricetype, priority, generalpricelist_id, dateactive,
     dateinactive, systemuser_id, timestamp)
    select seq_pricelistpercustomer.nextval, c.customer_id, 3, 15, gv_replacementpriceid,
           c.dateactive, c.dateinactive, nvl(fp_systemuserid, 1), sysdate
    from   customer c
    where  c.debtor_id = gv_customer600999id
    and    not exists (select 1
            from   pricelistpercustomer plc
            where  plc.customer_id = c.customer_id
            and    plc.generalpricelist_id = gv_replacementpriceid
            and    plc.pricetype = 3);
  gv_replace_counter := sql%rowcount;
  --CUSTOMER_ID, PRICETYPE, GENERALPRICELIST_ID
  gv_message := 'insert into pricelistpercustomer sales price';
  insert into pricelistpercustomer
    (pricelistpercustomer_id, customer_id, pricetype, priority, generalpricelist_id, dateactive,
     dateinactive, systemuser_id, timestamp)
    select seq_pricelistpercustomer.nextval, c.customer_id, 4, 15, gv_salespriceid, c.dateactive,
           c.dateinactive, nvl(fp_systemuserid, 1), sysdate
    from   customer c
    where  c.debtor_id = gv_customer600999id
    and    not exists (select 1
            from   pricelistpercustomer plc
            where  plc.customer_id = c.customer_id
            and    plc.generalpricelist_id = gv_salespriceid
            and    plc.pricetype = 4);
  gv_sales_counter := sql%rowcount;
  --finalize
  finalize;
exception
  --Exception handling
  when gv_user__exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error, No Data Found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log('Error ' || sqlerrm || ' ' || gv_message, 3);
    end;
end add_pricelists_30051_deltos_600999;
/

create or replace trigger after_insert_invoiceline
  after insert on invoiceline
  for each row
  when (new.adjustmentreason_id is not null)
begin
  insert into invoicelineadjusted
    (invoiceline_id, systemuser_id, timestamp)
  values
    (:new.invoiceline_id, :new.systemuser_id, :new.timestamp);
end after_insert_invoiceline;
/

create or replace procedure auj_anonymous_wearername(fp_customernumber in number,
                                                     fp_systemuserid   in number,
                                                     fp_dateinactive   in date default trunc(sysdate)) is
  --Version 0.7 auj_anonymous_wearername
  --global variables
  gv_userexception  exception;
  gv_message        abslog.message%type;
  gv_counter        number := 0;
  gv_plantid        plant.plant_id%type;
  gv_customerid     customer.customer_id%type;
  gv_anonymous_name varchar2(5) := '*****';

  --internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'auj_anonymous_wearername', gv_plantid, fp_priority, fp_message,
                             fp_systemuserid);
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_counter := 0;
    if fp_customernumber is null then
      begin
        gv_message := 'Parameter fp_customernumber cannot be left blank!';
        raise gv_userexception;
      end;
    else
      begin
        gv_message := 'Parameter fp_customernumber ' || fp_customernumber;
        select c.customer_id, bu.plant_id
        into   gv_customerid, gv_plantid
        from   customer c
        join   businessunit bu
        on     bu.businessunit_id = c.defaultbusinessunit_id
        where  c.customernumber = fp_customernumber;
      end;
    end if;
    if fp_dateinactive is null then
      begin
        gv_message := 'Parameter fp_dateinactive cannot be left blank!';
        raise gv_userexception;
      end;
    end if;
    if fp_dateinactive > trunc(sysdate) then
      begin
        gv_message := 'Parameter fp_dateinactive cannot be in the future!';
        raise gv_userexception;
      end;
    end if;
    if fp_systemuserid is null then
      begin
        gv_message := 'Parameter fp_systemuserid cannot be left blank!';
        raise gv_userexception;
      end;
    end if;
  end initialize;

  procedure anonymous_wearername is
  
    procedure anonymous(fp_wearerid     in wearer.wearer_id%type,
                        fp_wearernumber in wearer.wearernumber%type) is
    begin
      --anonymous
      gv_message := 'Make wearer number ' || fp_wearernumber || ' for customer ' ||
                    fp_customernumber || ' anonymous';
      --wearer
      update wearer w
      set    w.fullname = gv_anonymous_name, w.searchname = gv_anonymous_name,
             w.emblemname = gv_anonymous_name, w.firstname = gv_anonymous_name,
             w.systemuser_id = fp_systemuserid, w.timestamp = sysdate
      where  w.customer_id = gv_customerid
      and    w.wearer_id = fp_wearerid;
      --weareremployment_link
      update weareremployment_link wel
      set    wel.wearersearchname = gv_anonymous_name, wel.wearername = gv_anonymous_name,
             wel.timestamp = sysdate, wel.systemuser_id = fp_systemuserid
      where  exists (select 1
              from   weareremployment we
              where  we.wearer_id = fp_wearerid
              and    we.weareremployment_id = wel.weareremployment_id);
      --weareremployment
      update weareremployment we
      set    we.timestamp = sysdate, we.systemuser_id = fp_systemuserid
      where  we.wearer_id = fp_wearerid;
      --update invoiceline
      update invoicelineproduct ilp
      set    ilp.wearername = gv_anonymous_name, ilp.timestamp = sysdate,
             ilp.systemuser_id = fp_systemuserid
      where  exists (select 1
              from   weareremployment we
              where  we.weareremployment_id = ilp.weareremployment_link_id
              and    we.wearer_id = fp_wearerid);
      --commit, to let the triggers do their work before we change change tables!
      commit;
      gv_message := 'Make wearer number ' || fp_wearernumber || ' for customer ' ||
                    fp_customernumber || ' anonymous, part II';
    end anonymous;
  begin
    --anonymous_wearername
    gv_message := 'anonymous_wearername';
    for x in (select w.wearer_id, w.wearernumber
              from   wearer w
              where  w.customer_id = gv_customerid
              and    w.dateinactive <= fp_dateinactive) loop
      begin
        --anonymous
        anonymous(x.wearer_id, x.wearernumber);
        --count wearers
        gv_counter := gv_counter + 1;
      end;
    end loop; --x
  end anonymous_wearername;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    commit;
    write_log('Made ' || gv_counter || ' wearers anonymous for customer number ' ||
              fp_customernumber || ' for inactive date ' || to_date(fp_dateinactive, 'dd-mm-yyyy'),
              1);
  end finalize;

begin
  initialize;
  anonymous_wearername;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error No Data Found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log('Error ' || sqlerrm || ' ' || gv_message, 3);
    end;
end auj_anonymous_wearername;
/

create or replace package auj_erp_interface is
  /***************************************************************************\
  *  Author  : ABS                                                            *
  *  Created : 03-12-2019                                                     *
  *  Purpose : Interface for ERP_* tables to and from ABSSolute               *
  *              to rerun for a certain transferid then the parameter         *
  *              fp_rerun>0 and corresponding log record must be there then!  *
  *  Version : 0.82                                                           *
  *  Revision: ABS-97809 Remake Miroku interface adding ERP_O_Miroku          *
  *  20-Mar-2020 ABS-98998 Extend AUJ_ERP_INTERFACE with ERP_O_INV/ARTRANS    *
  *  30-Mar-2020 ABS-98599 ERP interface for Product data for AUJ             *
  *  06-Apr-2020 ABS-98595 ERP interface for Customer data for AUJ            *
  *  20-May-2020 ABS-98598 ERP interface for Contract data for AUJ            *
  *  30-Jul-2020 ABS-98595 Extra changes requested during meetings with AUJ   *
  *  23-Sep-2020 ABS-98595 ERP interface for Customer data for AUJ            *
  *  24-Sep-2020 ABS-105239 ERP interface for Temporary (garment) Rent Stop   *
  *  29-Sep-2020 ABS-105846 ERP interface for Inactivate customer             *
  *  30-Sep-2020 ABS-98834 ERP inteface for Move Route Stop for AUJ           *
  *  28-Oct-2020 We use service employee instead of salesemployee for customer*
  *              Add customer activities when creating a new customer         *
  *              make also customer field active inactive when made inactive  *
  *  02-Nov-2020 ABS-109181 add field CHARGELOSSCHARGE to ERP_I_CUSTOMER      *
  *  19-Nov_2020 ABS-109181 changes made after last meeting                   * 
  *  15-Dec-2020 ABS-111944 Fix for B and D value removed on PLPC             *
  *  15-Jan-2021 ABS-112425 RouteTransaction use deliverypointid and message  *
  *  18-Jan-2021 ABS-112425 Routestop cases Active Y/N deliveryday productdays*
  *  05-Feb-2021 ABS-112425 Routestop only delete per deliveryscheme          *
  *  05-Mar-2021 ABS-115808 Do NOT update debtor info for regular customer    *
  *  10-Mar-2021 ABS-116017 Add transactiontype to ERP_I_CUSTOMERROUTESTOP    *
  *  02-Apr-2021 ABS-117234 When send priority 10, existing 10 will be 11     *
  *                         When send priority 12, existing 12 will be 13     *
  *  09-Apr-2021 ABS-117530 Custspecialcharge, add pricelistpercust if neeeded*
  *  09-Apr-2021 ABS-117537 Adjust erp_i_pricelistpercustomer prio 10-12      *
  *  31-May-2021 ABS-119668 Extend ERP_I_CUSTOMER by adding PAYMENTMETHOD     *
  *  09-Jun-2021 ABS-120390 Extend ERP I_CUSTOMER with DEFAULTSTOCKROOMCODE   *
  *  16-Jun-2021 ABS-120827 Extend ERP_I_TEMPORARYRENTSTOP for AUJ            *
  *  23-Jun-2021 ABS-121102 Extend ERP_I_PRICELISTPERCUSTOMER for AUJ         *
  *  15-Sep-2021 ABS-124466 Priority change for ERP_I_PRICELISTPERCUSTOMER    *
  *  15-Sep-2021 ABS-124465 ERP_I_CUSTOMERROUTESTOP add/cancelling stops      *
  *  21-Oct-2021 ABS-126355 ERP_I_SUPPLIERPRODUCT insert error                *
  *  01-Nov-2021 ABS-126874 Adjust ERP interface for AUJ                      *
  *  19-Nov-2021 ABS-127725 Routestop updating future stops take change date  *
  *  22-Nov-2021 ABS-127827 Do not update ERP_I_PLPC DATEACTIVE               *
  *  20-Jan-2022 ABS-129917 enchancement erp-i-department do not update       *
  *  04-Feb-2022 ABS-130980 Stop status dateinactive ERP_I_CUSTOMERROUTESTOP  *
  *  20-Apr-2022 ABS-134113 Pricelist prio's one 10 and 11, other 12 and 14   *
  *  29-Apr-2022 ABS-134607 ERP interface enhancements - Part 1, 2 and 4      *
  *  12-May-2022 ABS-134607 update ERP_I_CONTRACTPRICELIST for new description*
  *  13-May-2022 ABS-134608 ERP interface enhancements - Part 3               *
  *  29-Jun-2022 ABS-137145 contact person for 'Billing' tab customers change *
  *  06-Sep-2022 ABS-138579 ERP_I_CUSTOMERROUTESTOP not cancelstop 1 daterange*
  *  22-Sep-2022            Extra routetstop checks changes                   *
  *  21-Oct-2022 ABS-141981 Change ERP_Pricelist                              *
  *  08-Nov-2022 ABS-141982 Change ERP_I_Pricelistpercustomer                 *
  *  26-Apr-2023 ABS-150324 update transfer status                            *
  *  25-Aug-2023 ABS-155171 Create customergeneral when creaing customer      *
  *  26-Mar-2025 ABSN-4430 PLPC emblemtemplate keep value when null provided  *
  \***************************************************************************/
  -- I Tables
  --ERP I Tables, Import data into ABSSolute
  --process erp_i_dialogflexfields
  procedure proc_i_dialogflexfields(fp_transferid in erp_i_dialogflexfields.transfer_id%type,
                                    fp_rerun      in number default 0);
  procedure proc_i_dialogflexfields_all;

  --process erp_i_product
  procedure proc_i_prod(fp_transferid in erp_i_product.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_prod_all;

  --process erp_i_pricelist
  procedure proc_i_pricelist(fp_transferid in erp_i_pricelist.transfer_id%type,
                             fp_rerun      in number default 0);
  procedure proc_i_pricelist_all;

  --process erp_i_pricelistpercustomer
  procedure proc_i_pricelistpercustomer(fp_transferid in erp_i_pricelistpercustomer.transfer_id%type,
                                        fp_rerun      in number default 0);
  procedure proc_i_pricelistpercustomer_all;

  --process erp_i_size
  procedure proc_i_size(fp_transferid in erp_i_size.transfer_id%type, fp_rerun in number default 0);
  procedure proc_i_size_all;

  --process erp_i_weighingcategory
  procedure proc_i_weigh(fp_transferid in erp_i_weighingcategory.transfer_id%type,
                         fp_rerun      in number default 0);
  procedure proc_i_weigh_all;

  --process erp_i_supplier
  procedure proc_i_supp(fp_transferid in erp_i_supplier.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_supp_all;

  --process erp_i_supplierproduct
  procedure proc_i_suppproduct(fp_transferid in erp_i_supplierproduct.transfer_id%type,
                               fp_rerun      in number default 0);
  procedure proc_i_suppproduct_all;

  --process erp_i_contract 
  procedure proc_i_contract(fp_transferid in erp_i_contract.transfer_id%type,
                            fp_rerun      in number default 0);
  procedure proc_i_contract_all;

  --process erp_i_contractcustomer
  procedure proc_i_contractcustomer(fp_transferid in erp_i_contractcustomer.transfer_id%type,
                                    fp_rerun      in number default 0);
  procedure proc_i_contractcustomer_all;

  --process erp_i_contractpricelist
  procedure proc_i_contractpricelist(fp_transferid in erp_i_contractpricelist.transfer_id%type,
                                     fp_rerun      in number default 0);
  procedure proc_i_contractpricelist_all;

  --process erp_i_customer
  procedure proc_i_cust(fp_transferid in erp_i_customer.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_cust_all;

  --process erp_i_tempgarmrentstop
  procedure proc_i_tempgarmrentstop(fp_transferid in erp_i_tempgarmentrentstop.transfer_id%type,
                                    fp_rerun      in number default 0);
  procedure proc_i_tempgarmrentstop_all;

  --process erp_i_nonbusinessdays
  procedure proc_i_nonbuday(fp_transferid in erp_i_nonbusinessdays.transfer_id%type,
                            fp_rerun      in number default 0);
  procedure proc_i_nonbudays_all;

  --process erp_i_customerprepcharge
  procedure proc_i_customerprepcharge(fp_transferid in erp_i_customerprepcharge.transfer_id%type,
                                      fp_rerun      in number default 0);
  procedure proc_i_customerprepcharge_all;

  --process erp_i_custspecialcharge
  procedure proc_i_custspecialcharge(fp_transferid in erp_i_customerspecialcharge.transfer_id%type,
                                     fp_rerun      in number default 0);
  procedure proc_i_custspecialcharge_all;

  --process erp_i_customerroutestop
  procedure proc_i_customerroutestop(fp_transferid in erp_i_customerroutestop.transfer_id%type,
                                     fp_rerun      in number default 0);
  procedure proc_i_customerroutestop_all;

  --process erp_i_contactperson
  procedure proc_i_contactper(fp_transferid in erp_i_contactperson.transfer_id%type,
                              fp_rerun      in number default 0);
  procedure proc_i_contactper_all;

  --process erp_i_costcenter
  procedure proc_i_cost(fp_transferid in erp_i_costcenter.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_cost_all;

  --process erp_i_deliverypoint
  procedure proc_i_delp(fp_transferid in erp_i_deliverypoint.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_delp_all;

  --process erp_i_department
  procedure proc_i_depart(fp_transferid in erp_i_department.transfer_id%type,
                          fp_rerun      in number default 0);
  procedure proc_i_depart_all;

  --process erp_i_consumptionpoint
  procedure proc_i_cons(fp_transferid in erp_i_consumptionpoint.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_cons_all;

  --process erp_i_productlistpercustomer
  procedure proc_i_plpc(fp_transferid in erp_i_productlistpercustomer.transfer_id%type,
                        fp_rerun      in number default 0);
  procedure proc_i_plpc_all;

  --process erp_i_inactivate_customer
  --if lost date is 31-12-2099 then it is a reactivation instead!
  procedure proc_i_inactcust(fp_transferid in erp_i_inactivate_customer.transfer_id%type,
                             fp_rerun      in number default 0);
  procedure proc_i_inactcust_all;

  --process erp_i_routechangetransaction
  procedure proc_i_routetransaction(fp_transferid in erp_i_routechangetransaction.transfer_id%type,
                                    fp_rerun      in number default 0);
  procedure proc_i_routetransaction_all;
  ----------------------------------------------------------------------------
  --ERP O Tables, Export date from ABSSolute
  --process erp_o_artransaction
  procedure proc_o_artransaction(fp_cleanup_afterdays in number default null);

  --process proc_o_invoiceheader
  procedure proc_o_invoiceheader(fp_cleanup_afterdays in number default null);
end auj_erp_interface;
/
create or replace package body auj_erp_interface is
  ----------------------------------------------------------------------------
  --internal variables:
  ge_user___exception       exception;
  gv_cleanup_afterdays      number := 33;
  gv_text                   abslog.message%type := null;
  gv_erp_systemuserid       systemuser.systemuser_id%type;
  gv_languageid             languages.language_id%type := 2;
  gv_sizestarid             sizedefinition.sizedefinition_id%type;
  gv_supplierid             supplier.supplier_id%type;
  gv_invoicecolumn          product.invoicecolumn%type;
  gv_endddate               date := to_date('31-12-2099', 'dd-mm-yyyy');
  gv_contractenddatecontrol systemsetting.value%type;
  error_predefinedvalue     exception;
  error_restriction         exception;
  ----------------------------------------------------------------------------
  --internal functions:
  procedure write_o_log(fp_text     in abslog.message%type,
                        fp_priority in abslog.priority%type default 3) is
  begin
    --write_o_log
    abslogwrite.abslog_write(5, 'ERP_Interface', null, fp_priority, fp_text || ' ' || sqlerrm,
                             gv_erp_systemuserid);
  end write_o_log;

  procedure write_log(fp_logtablename    in varchar2,
                      fp_transferid      in number,
                      fp_text            in abslog.message%type,
                      fp_process_status  in number,
                      fp_transfer_status in number default 0) is
    lv_exec_sql_string varchar2(512);
  begin
    begin
      if upper(fp_logtablename) = 'ERP_I_DC_ISSUE_LOG' then
        lv_exec_sql_string := 'INSERT INTO ERP_I_DC_ISSUE_LOG' ||
                              '(transfer_id, transfer_status, text, process_status, reasoncode, qualitygrade ) VALUES(:fp_transferid, :fp_transfer_status, :fp_text, :fp_process_status, '' '', '' '')';
      
      else
        --build insert log string
        lv_exec_sql_string := 'INSERT INTO ' || upper(fp_logtablename) ||
                              '(transfer_id, transfer_status, text, process_status ) VALUES(:fp_transferid, :fp_transfer_status, :fp_text, :fp_process_status)';
      end if;
      --execute insert log string
      execute immediate lv_exec_sql_string
        using fp_transferid, fp_transfer_status, fp_text, fp_process_status;
    exception
      when dup_val_on_index then
        begin
          --build update log string
          lv_exec_sql_string := 'UPDATE ' || upper(fp_logtablename) ||
                                '   SET transfer_status = :fp_transfer_status,' ||
                                '       text            = :fp_text,' ||
                                '       process_status  = :fp_process_status,' ||
                                '       timestamp       = sysdate' ||
                                ' WHERE transfer_id     = :fp_transferid';
          --execute insert log string
          execute immediate lv_exec_sql_string
            using fp_transfer_status, fp_text, fp_process_status, fp_transferid;
        end;
    end;
    commit;
  exception
    when others then
      begin
        --Write message in ABSLOG with debug info when something went wrong!
        rollback;
        write_o_log(fp_text || ' ' || sqlerrm, 3);
      end;
  end write_log;

  function get_formlayout(fp_formlayout in formlayout.code%type,
                          fp_formtype   in formlayout.formtype%type)
    return formlayout.formlayout_id%type is
    lv_formlayoutid formlayout.formlayout_id%type;
  begin
    --get_formlayout
    if fp_formlayout is null then
      return null;
    end if;
    gv_text := 'Get formlayout ' || fp_formlayout || ' for type ' || fp_formtype;
    select fl.formlayout_id
    into   lv_formlayoutid
    from   formlayout fl
    where  fl.code = fp_formlayout
    and    fl.formtype = fp_formtype;
    return lv_formlayoutid;
  end get_formlayout;

  function get_languageid(fp_languagecode in languages.code%type) return languages.language_id%type is
    lv_languageid languages.language_id%type;
  begin
    if fp_languagecode is null then
      return null;
    else
      --get_languageid
      gv_text := ' get_language for code ' || fp_languagecode;
      select l.language_id into lv_languageid from languages l where l.code = fp_languagecode;
      return lv_languageid;
    end if;
  end get_languageid;

  function get_businessunitid(fp_businessunitcode in businessunit.code%type)
    return businessunit.businessunit_id%type is
    lv_businessunitid businessunit.businessunit_id%type;
  begin
    if fp_businessunitcode is null then
      return null;
    else
      begin
        --get_businessunitid
        gv_text := ' get businessunit for code ' || fp_businessunitcode;
        select cy.businessunit_id
        into   lv_businessunitid
        from   businessunit cy
        where  cy.code = fp_businessunitcode;
        return lv_businessunitid;
      end;
    end if;
  end get_businessunitid;

  function get_employeeid(fp_employeenumber in employee.employeenumber%type,
                          fp_plantid        in plant.plant_id%type) return employee.employee_id%type is
    lv_employeeid employee.employee_id%type;
    procedure get_unique_emplnmbr is
    begin
      --might be unique employee over all!
      select em.employee_id
      into   lv_employeeid
      from   employee em
      where  em.employeenumber = fp_employeenumber;
    end get_unique_emplnmbr;
  begin
    --get_employeeid--> unique over all plants!!
    gv_text := ' get employee for number ' || fp_employeenumber;
    if fp_employeenumber is null then
      return null;
    elsif fp_plantid is null then
      begin
        get_unique_emplnmbr;
        return lv_employeeid;
      end;
    else
      begin
        select em.employee_id
        into   lv_employeeid
        from   employee em
        where  em.employeenumber = fp_employeenumber
        and    em.plant_id = fp_plantid;
        return lv_employeeid;
      exception
        when no_data_found then
          begin
            get_unique_emplnmbr;
            return lv_employeeid;
          end;
      end;
    end if;
    return lv_employeeid;
  end get_employeeid;

  function get_emblemfontid(fp_emblemfontdesc in emblemfont.description%type default null)
    return emblemfont.emblemfont_id%type is
    lv_emblemfontid emblemfont.emblemfont_id%type;
  begin
    --get_emblemfontid
    gv_text := ' get emblemfont for description ' || nvl(fp_emblemfontdesc, 'NULL');
    if fp_emblemfontdesc is null then
      return null;
    else
      begin
        select wg.emblemfont_id
        into   lv_emblemfontid
        from   emblemfont wg
        where  wg.description = fp_emblemfontdesc;
      exception
        when no_data_found then
          begin
            insert into emblemfont
              (emblemfont_id, description, active, systemuser_id, timestamp)
            values
              (seq_emblemfont.nextval, fp_emblemfontdesc, 'Y', gv_erp_systemuserid, sysdate)
            returning emblemfont_id into lv_emblemfontid;
          end;
      end;
    end if;
    return lv_emblemfontid;
  end get_emblemfontid;

  function get_emblemtemplateid(fp_customerid         in customer.customer_id%type,
                                fp_emblemtemplatecode in emblemtemplate.code%type)
    return emblemtemplate.emblemtemplate_id%type is
    lv_emblemtemplateid emblemtemplate.emblemtemplate_id%type;
  begin
    --get_emblemtemplateid
    if fp_emblemtemplatecode is null then
      return null;
    else
      begin
        gv_text := 'get emblemtemplate for coded ' || nvl(fp_emblemtemplatecode, 'NULL') ||
                   ' for customer ' || nvl(to_char(fp_customerid), 'NULL');
        select emt.emblemtemplate_id
        into   lv_emblemtemplateid
        from   emblemtemplate emt
        where  emt.code = fp_emblemtemplatecode
        and    emt.customer_id = fp_customerid;
        return lv_emblemtemplateid;
      end;
    end if;
  end get_emblemtemplateid;

  function get_countryid(fp_countrycode in country.code%type) return country.country_id%type is
    lv_countryid country.country_id%type;
  begin
    if fp_countrycode is null then
      return null;
    else
      begin
        --get_countryid
        gv_text := ' get country for code ' || nvl(fp_countrycode, 'NULL');
        select cy.country_id into lv_countryid from country cy where cy.code = fp_countrycode;
        return lv_countryid;
      end;
    end if;
  end get_countryid;

  function get_currencyid(fp_currencycode in currency.code%type) return currency.currency_id%type is
    lv_currencyid currency.currency_id%type;
  begin
    --get_currencyid
    gv_text := ' get currency for code ' || nvl(fp_currencycode, 'NULL');
    if fp_currencycode is null then
      return null;
    else
      begin
        select cy.currency_id into lv_currencyid from currency cy where cy.code = fp_currencycode;
        return lv_currencyid;
      end;
    end if;
  end get_currencyid;

  function get_colorid(fp_colorcode in color.code%type,
                       fp_colordesc in color_desc.description%type default null)
    return color.color_id%type is
    lv_colorid color.color_id%type;
  begin
    --get_colorid
    gv_text := ' get color for code ' || nvl(fp_colorcode, 'NULL');
    if fp_colorcode is null then
      return null;
    else
      begin
        select wg.color_id into lv_colorid from color wg where wg.code = fp_colorcode;
        return lv_colorid;
      end;
    end if;
  exception
    when no_data_found then
      begin
        insert into color
          (color_id, code, ralcode, systemuser_id, timestamp, usedforemblem, pantonecode)
        values
          (seq_color.nextval, fp_colorcode, null /*ralcode*/, gv_erp_systemuserid, sysdate, 'Y'
           /*usedforemblem*/, null /*pantonecode*/)
        returning color_id into lv_colorid;
        insert into color_desc
          (color_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_colorid, gv_languageid, nvl(fp_colordesc, fp_colorcode), gv_erp_systemuserid, sysdate);
        return lv_colorid;
      end;
  end get_colorid;

  function get_contracttypeid(fp_code        in contracttype.code%type,
                              fp_description in contracttype.description%type)
    return contracttype.contracttype_id%type is
    lv_contracttypeid contracttype.contracttype_id%type;
  begin
    --get_contracttypeid
    gv_text := ' get contracttype for code ' || nvl(fp_code, 'NULL');
    if fp_code is null then
      return null;
    end if;
    select ctt.contracttype_id
    into   lv_contracttypeid
    from   contracttype ctt
    where  ctt.code = fp_code;
    return lv_contracttypeid;
  exception
    when no_data_found then
      begin
        insert into contracttype
          (contracttype_id, code, description, systemuser_id, timestamp)
        values
          (seq_contracttype.nextval, fp_code, nvl(fp_description, fp_code), gv_erp_systemuserid,
           sysdate)
        returning contracttype_id into lv_contracttypeid;
        return lv_contracttypeid;
      end;
  end get_contracttypeid;

  function get_deliveryschemeid(fp_deliveryschemcode in deliveryscheme.code%type,
                                fp_frequency         out deliveryscheme.frequency%type)
    return deliveryscheme.deliveryscheme_id%type is
    lv_deliveryschemid deliveryscheme.deliveryscheme_id%type;
  begin
    --get_deliveryschemeid
    if fp_deliveryschemcode is null then
      return null;
    end if;
    gv_text := 'Deliveryscheme.code ' || fp_deliveryschemcode;
    select ds.deliveryscheme_id, ds.frequency
    into   lv_deliveryschemid, fp_frequency
    from   deliveryscheme ds
    where  ds.code = upper(trim(fp_deliveryschemcode));
    return lv_deliveryschemid;
  end get_deliveryschemeid;

  function get_deliveryschemeid(fp_deliveryschemcode in deliveryscheme.code%type)
    return deliveryscheme.deliveryscheme_id%type is
    lv_frequency deliveryscheme.frequency%type;
  begin
    return get_deliveryschemeid(fp_deliveryschemcode, lv_frequency);
  end get_deliveryschemeid;

  function get_fabricid(fp_fabriccode in fabric.code%type) return fabric.fabric_id%type is
    lv_fabricid fabric.fabric_id%type;
  begin
    --get_fabricid
    gv_text := ' get fabric for code ' || nvl(fp_fabriccode, 'NULL');
    select wg.fabric_id into lv_fabricid from fabric wg where wg.code = fp_fabriccode;
    return lv_fabricid;
  exception
    when no_data_found then
      begin
        insert into fabric
          (fabric_id, code, systemuser_id, timestamp, usedforemblem)
        values
          (seq_fabric.nextval, fp_fabriccode, gv_erp_systemuserid, sysdate, 'N')
        returning fabric_id into lv_fabricid;
        insert into fabric_desc
          (fabric_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_fabricid, gv_languageid, fp_fabriccode, gv_erp_systemuserid, sysdate);
        return lv_fabricid;
      end;
  end get_fabricid;

  function get_finishingid(fp_finishingcode in finishingcode.finishingcode%type)
    return finishingcode.finishingcode_id%type is
    lv_finishingid finishingcode.finishingcode_id%type;
  begin
    --get_finishingid
    if fp_finishingcode is null then
      return null;
    end if;
    gv_text := ' get finishing for code ' || fp_finishingcode;
    select rg.finishingcode_id
    into   lv_finishingid
    from   finishingcode rg
    where  rg.finishingcode = fp_finishingcode;
    return lv_finishingid;
  end get_finishingid;

  function get_gainlostreasonid(fp_code          in gainlostreason.code%type,
                                fp_description   in gainlostreason_desc.description%type,
                                fp_gainreason_yn in varchar2 default 'Y',
                                fp_lostreason_yn in varchar2 default 'Y')
    return gainlostreason.gainlostreason_id%type is
    lv_gainlostreasonid gainlostreason.gainlostreason_id%type;
  begin
    --get_gainlostreasonid
    if fp_code is null then
      return null;
    end if;
    gv_text := ' get gainlostreason id for code ' || nvl(fp_code, 'NULL');
    select glr.gainlostreason_id
    into   lv_gainlostreasonid
    from   gainlostreason glr
    where  glr.code = fp_code;
    --
    return lv_gainlostreasonid;
  exception
    when no_data_found then
      begin
        insert into gainlostreason
          (gainlostreason_id, code, systemuser_id, gainreason, timestamp, lostreason)
        values
          (seq_gainlostreason.nextval, fp_code, gv_erp_systemuserid, nvl(fp_gainreason_yn, 'Y'),
           sysdate, nvl(fp_lostreason_yn, 'Y'))
        returning gainlostreason_id into lv_gainlostreasonid;
        insert into gainlostreason_desc
          (gainlostreason_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_gainlostreasonid, gv_languageid, nvl(fp_description, fp_code), gv_erp_systemuserid,
           sysdate);
        return lv_gainlostreasonid;
      end;
  end get_gainlostreasonid;

  function get_competitorid(fp_code competitor.code%type, fp_name competitor.name%type)
    return competitor.competitor_id%type is
    lv_competitorid competitor.competitor_id%type;
  begin
    --get_competitorid
    if fp_code is null then
      return null;
    end if;
    gv_text := ' get competitor for code ' || nvl(fp_code, 'NULL');
    select cp.competitor_id into lv_competitorid from competitor cp where cp.code = fp_code;
    --
    return lv_competitorid;
  exception
    when no_data_found then
      begin
        insert into competitor
          (competitor_id, code, name, systemuser_id, timestamp)
        values
          (seq_competitor.nextval, fp_code, nvl(fp_name, fp_code), gv_erp_systemuserid, sysdate)
        returning competitor_id into lv_competitorid;
        return lv_competitorid;
      end;
  end get_competitorid;

  function get_priceindexid(fp_code        in priceindex.code%type,
                            fp_description in priceindex.description%type)
    return priceindex.priceindex_id%type is
    lv_priceindexid priceindex.priceindex_id%type;
  begin
    --get_priceindexid
    if fp_code is null then
      return null;
    end if;
    gv_text := ' get priceindex for code ' || nvl(fp_code, 'NULL');
    select pi.priceindex_id into lv_priceindexid from priceindex pi where pi.code = fp_code;
    return lv_priceindexid;
  exception
    when no_data_found then
      begin
        insert into priceindex
          (priceindex_id, code, description, systemuser_id, timestamp)
        values
          (seq_priceindex.nextval, fp_code, nvl(fp_description, fp_code), gv_erp_systemuserid,
           sysdate);
        return lv_priceindexid;
      end;
  end get_priceindexid;

  function get_activityid(fp_activitycode in activity.code%type) return activity.activity_id%type is
    lv_activityid activity.activity_id%type;
  begin
    --get_activityid
    gv_text := ' get activity for code ' || nvl(fp_activitycode, 'NULL');
    select cy.activity_id into lv_activityid from activity cy where cy.code = fp_activitycode;
    return lv_activityid;
  end get_activityid;

  function get_marketsegmentid(fp_marketsegmentcode in marketsegment.code%type)
    return marketsegment.marketsegment_id%type is
    lv_marketsegmentid marketsegment.marketsegment_id%type;
  begin
    --get_marketsegmentid
    gv_text := ' get marketsegment for code ' || nvl(fp_marketsegmentcode, 'NULL');
    select cy.marketsegment_id
    into   lv_marketsegmentid
    from   marketsegment cy
    where  cy.code = fp_marketsegmentcode;
    return lv_marketsegmentid;
  end get_marketsegmentid;

  function get_modificationgroupid(fp_modificationgroupcode in modificationgroup.code%type)
    return modificationgroup.modificationgroup_id%type is
    lv_modificationgroupid modificationgroup.modificationgroup_id%type;
  begin
    --get_modificationgroupid
    if fp_modificationgroupcode is null then
      return null;
    else
      begin
        gv_text := ' get modificationgroup for code ' ||
                   nvl(trim(upper(fp_modificationgroupcode)), 'NULL');
        select md.modificationgroup_id
        into   lv_modificationgroupid
        from   modificationgroup md
        where  md.code = trim(upper(fp_modificationgroupcode));
      exception
        when no_data_found then
          begin
            gv_text := ' insert modificationgroup for code ' ||
                       nvl(trim(upper(fp_modificationgroupcode)), 'NULL');
            insert into modificationgroup
              (modificationgroup_id, systemuser_id, timestamp, code)
            values
              (seq_modificationgroup.nextval, gv_erp_systemuserid, sysdate,
               trim(upper(fp_modificationgroupcode)))
            returning modificationgroup_id into lv_modificationgroupid;
            insert into modificationgroup_desc
              (modificationgroup_id, language_id, description, timestamp, systemuser_id)
            values
              (lv_modificationgroupid, gv_languageid, fp_modificationgroupcode, sysdate,
               gv_erp_systemuserid);
          end;
      end;
    end if;
    return lv_modificationgroupid;
  end get_modificationgroupid;

  function get_mrpcodeid(fp_code in mrpcode.code%type) return mrpcode.mrpcode_id%type is
    lv_mrpcodeid mrpcode.mrpcode_id%type;
  begin
    --get_mrpcodeid
    gv_text := ' get_mrpcode for code ' || nvl(fp_code, 'NULL');
    if fp_code is null then
      begin
        return null;
      end;
    else
      begin
        select sc.mrpcode_id into lv_mrpcodeid from mrpcode sc where sc.code = fp_code;
        return lv_mrpcodeid;
      exception
        when no_data_found then
          begin
            --insert into mrpcode
            gv_text := ' get_mrpcodeid. insert mrpcode ' || nvl(fp_code, 'NULL');
            insert into mrpcode
              (mrpcode_id, code, description, active, systemuser_id, timestamp)
            values
              (seq_mrpcode.nextval, fp_code, fp_code, 'Y', gv_erp_systemuserid, sysdate)
            returning mrpcode_id into lv_mrpcodeid;
            return lv_mrpcodeid;
          end;
      end;
    end if;
    return lv_mrpcodeid;
  end get_mrpcodeid;

  function get_nationalaccountid(fp_nationalaccountcode in nationalaccount.code%type)
    return nationalaccount.nationalaccount_id%type is
    lv_nationalaccountid nationalaccount.nationalaccount_id%type;
  begin
    --get_nationalaccountid
    gv_text := ' get nationalaccount id for code ' || nvl(fp_nationalaccountcode, 'NULL');
    if fp_nationalaccountcode is null then
      return null;
    end if;
    select na.nationalaccount_id
    into   lv_nationalaccountid
    from   nationalaccount na
    where  na.code = fp_nationalaccountcode;
    return lv_nationalaccountid;
  exception
    when no_data_found then
      begin
        gv_text := gv_text || ' no data found!';
        raise ge_user___exception;
      end;
  end get_nationalaccountid;

  function get_salesareaid(fp_salesareacode in salesarea.code%type)
    return salesarea.salesarea_id%type is
    lv_salesareaid salesarea.salesarea_id%type;
  begin
    --get_salesareaid
    gv_text := ' get salesarea for code ' || nvl(fp_salesareacode, 'NULL');
    select cy.salesarea_id into lv_salesareaid from salesarea cy where cy.code = fp_salesareacode;
    return lv_salesareaid;
  end get_salesareaid;

  function get_chainid(fp_chaincode in chain.code%type) return chain.chain_id%type is
    lv_chainid chain.chain_id%type;
  begin
    --get_chainid
    gv_text := ' get chain for code ' || nvl(fp_chaincode, 'NULL');
    if fp_chaincode is null then
      return null;
    else
      select cy.chain_id into lv_chainid from chain cy where cy.code = fp_chaincode;
      return lv_chainid;
    end if;
  end get_chainid;

  function get_customerid(fp_customernumber   in customer.customernumber%type,
                          fp_check_payby_cust in number default 0,
                          fp_dateactive       out nocopy date,
                          fp_dateinactive     out nocopy date,
                          fp_businessunitid   out nocopy number) return customer.customer_id%type is
    lv_customerid    customer.customer_id%type;
    lv_paybycustomer customerbillinginfo.paybycustomer%type;
  begin
    --get_customerid
    gv_text := ' get customer for number ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      begin
        return null;
      end;
    else
      select c.customer_id, c.dateactive, c.dateinactive, c.defaultbusinessunit_id
      into   lv_customerid, fp_dateactive, fp_dateinactive, fp_businessunitid
      from   customer c
      where  c.customernumber = fp_customernumber;
      if nvl(fp_check_payby_cust, 0) <> 0 then
        begin
          select max(cbi.paybycustomer)
          into   lv_paybycustomer
          from   customerbillinginfo cbi
          where  cbi.customer_id = lv_customerid;
          if nvl(lv_paybycustomer, 0) = 0 then
            begin
              gv_text := 'customer ' || to_char(fp_customernumber) || ' is not a paybycustomer!';
              raise ge_user___exception;
            end;
          end if;
        end;
      end if;
      return lv_customerid;
    end if;
  end get_customerid;

  function get_customerid(fp_customernumber   in customer.customernumber%type,
                          fp_check_payby_cust in number default 0) return customer.customer_id%type is
    lv_dateactive     date; --not used here
    lv_dateinactive   date; --not used here
    lv_businessunitid number; --not used here
  begin
    --get_customerid
    return get_customerid(fp_customernumber, fp_check_payby_cust, lv_dateactive, lv_dateinactive,
                          lv_businessunitid);
  end get_customerid;

  function get_customerid2(fp_customernumber in customer.customernumber%type,
                           fp_currencyid     out nocopy customer.currency_id%type)
    return customer.customer_id%type is
    fp_customerid customer.customer_id%type;
  begin
    --get_customerid2
    gv_text := ' get customer for number ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      fp_currencyid := null;
      return null;
    else
      select c.customer_id, c.currency_id
      into   fp_customerid, fp_currencyid
      from   customer c
      where  c.customernumber = fp_customernumber;
      return fp_customerid;
    end if;
  end get_customerid2;

  function get_deliverypointid(fp_deliverypointcode in deliverypoint.code%type,
                               fp_customerid        in customer.customer_id%type)
    return deliverypoint.deliverypoint_id%type is
    lv_deliverypointid deliverypoint.deliverypoint_id%type;
  begin
    --get_deliverypointid
    if fp_deliverypointcode is null then
      begin
        return null;
      end;
    end if;
    gv_text := ' get_deliverypoint for code ' || nvl(fp_deliverypointcode, 'NULL');
    select cc.deliverypoint_id
    into   lv_deliverypointid
    from   deliverypoint cc
    where  cc.code = fp_deliverypointcode
    and    cc.customer_id = fp_customerid;
    return lv_deliverypointid;
  end get_deliverypointid;

  function get_contactpersonid(fp_customerid          in contactperson.customer_id%type,
                               fp_supplierid          in contactperson.supplier_id%type default null,
                               fp_contactpersonnumber in contactperson.contactpersonnumber%type)
    return contactperson.contactperson_id%type is
    lv_contactpersonid contactperson.contactperson_id%type;
  begin
    --get_contactpersonid
    gv_text := ' get contactperson for number ' || nvl(to_char(fp_contactpersonnumber), 'NULL');
    if (fp_customerid is null and fp_supplierid is null) or (fp_contactpersonnumber is null) then
      return null;
    end if;
    if fp_customerid is not null then
      begin
        select cp.contactperson_id
        into   lv_contactpersonid
        from   contactperson cp
        where  cp.customer_id = fp_customerid
        and    cp.supplier_id is null
        and    cp.contactpersonnumber = fp_contactpersonnumber;
        return lv_contactpersonid;
      end;
    end if;
    if fp_supplierid is not null then
      begin
        select cp.contactperson_id
        into   lv_contactpersonid
        from   contactperson cp
        where  cp.customer_id is null
        and    cp.supplier_id = fp_supplierid
        and    cp.contactpersonnumber = fp_contactpersonnumber;
        return lv_contactpersonid;
      end;
    end if;
  end get_contactpersonid;

  function get_contractid(fp_contractcode in contract.code%type,
                          fp_startdate    out nocopy contract.startdate%type,
                          fp_enddate      out nocopy contract.enddate%type)
    return contract.contract_id%type is
    lv_contractid contract.contract_id%type;
  begin
    --get_contractid
    gv_text := ' get contract code ' || nvl(fp_contractcode, 'NULL');
    if fp_contractcode is null then
      begin
        fp_startdate := null;
        fp_enddate   := null;
        return null;
      end;
    else
      begin
        select contract_id, startdate, enddate
        into   lv_contractid, fp_startdate, fp_enddate
        from   contract
        where  code = fp_contractcode;
        return lv_contractid;
      end;
    end if;
  end get_contractid;

  function get_communicationmethodid(fp_communicationmethod in communicationmethod.code%type)
    return communicationmethod.communicationmethod_id%type is
    lv_communicationmethodid communicationmethod.communicationmethod_id%type;
  begin
    if fp_communicationmethod is null then
      return null;
    end if;
    --get_communicationmethodid
    gv_text := 'get communicationmethod ' || nvl(fp_communicationmethod, 'NULL');
    select cm.communicationmethod_id
    into   lv_communicationmethodid
    from   communicationmethod cm
    where  cm.code = fp_communicationmethod;
    return lv_communicationmethodid;
  exception
    when no_data_found then
      begin
        insert into communicationmethod
          (communicationmethod_id, code, systemuser_id, timestamp, defaultcommunicationmethod)
        values
          (seq_communicationmethod.nextval, fp_communicationmethod, gv_erp_systemuserid, sysdate,
           'N')
        returning communicationmethod_id into lv_communicationmethodid;
        insert into communicationmethod_desc
          (communicationmethod_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_communicationmethodid, gv_languageid, fp_communicationmethod, gv_erp_systemuserid,
           sysdate);
        return lv_communicationmethodid;
      end;
  end get_communicationmethodid;

  function get_costcenterid(fp_costcentercode in costcenter.code%type,
                            fp_customerid     in customer.customer_id%type)
    return costcenter.costcenter_id%type is
    lv_costcenterid costcenter.costcenter_id%type;
  begin
    --get_costcenterid
    gv_text := ' get_costcenter code ' || nvl(fp_costcentercode, 'NULL');
    select cc.costcenter_id
    into   lv_costcenterid
    from   costcenter cc
    where  cc.code = fp_costcentercode
    and    cc.customer_id = fp_customerid;
    return lv_costcenterid;
  end get_costcenterid;

  procedure get_contract_purchaseorder(fp_customerid       in customer.customer_id%type,
                                       lv_ponumber         out nocopy varchar2,
                                       lv_poexpirationdate out nocopy date) is
    lv_contractofthecustomerid number;
    lv_customercontractusage   customer.contractusage%type;
  begin
    --first check contractcustomer
    select max(cc.contractcustomer_id)
    into   lv_contractofthecustomerid
    from   contractcustomer cc
    join   contract c
    on     c.contract_id = cc.contract_id
    where  cc.customer_link_id = fp_customerid
    and    trunc(sysdate) between cc.startdate and cc.enddate
    and    coalesce(cc.purchaseordernumber, c.purchaseorder) is not null
    and    coalesce(cc.expirationdate, c.purchaseorderexpirationdate,
                    to_date('31-12-2099', 'dd-mm-yyyy')) > sysdate;
    if lv_contractofthecustomerid is not null then
      begin
        select coalesce(cc.purchaseordernumber, c.purchaseorder),
               coalesce(cc.expirationdate, c.purchaseorderexpirationdate)
        into   lv_ponumber, lv_poexpirationdate
        from   contractcustomer cc
        join   contract c
        on     c.contract_id = cc.contract_id
        where  cc.contractcustomer_id = lv_contractofthecustomerid;
      end;
    else
      begin
        --get contractspercustomer
        --if customer.contractusage = 0 then take from contractspercustomer
        --else take from contract
        gv_text := 'get contractspercustomer for customer out table';
        select c.contractusage
        into   lv_customercontractusage
        from   customer c
        where  c.customer_id = fp_customerid;
        if lv_customercontractusage = 0 then
          begin
            select max(cpc.contractspercustomer_id)
            into   lv_contractofthecustomerid
            from   contractspercustomer cpc
            where  cpc.customer_id = fp_customerid
            and    trunc(sysdate) between cpc.dateactive and cpc.dateinactive
            and    cpc.purchaseorder is not null
            and    nvl(cpc.purchaseorderexpirationdate, to_date('31-12-2099', 'dd-mm-yyyy')) >
                   sysdate;
            --select for found
            select cpc.purchaseorder, cpc.purchaseorderexpirationdate
            into   lv_ponumber, lv_poexpirationdate
            from   contractspercustomer cpc
            where  cpc.contractspercustomer_id = lv_contractofthecustomerid;
          end;
        else
          begin
            select max(cpc.contract_id)
            into   lv_contractofthecustomerid
            from   contract cpc
            where  cpc.customer_link_id = fp_customerid
            and    trunc(sysdate) between cpc.startdate and cpc.enddate
            and    cpc.purchaseorder is not null
            and    nvl(cpc.purchaseorderexpirationdate, to_date('31-12-2099', 'dd-mm-yyyy')) >
                   sysdate;
            --select for found
            select cpc.purchaseorder, cpc.purchaseorderexpirationdate
            into   lv_ponumber, lv_poexpirationdate
            from   contract cpc
            where  cpc.contract_id = lv_contractofthecustomerid;
          end;
        end if;
      end;
    end if;
  exception
    when no_data_found then
      begin
        lv_ponumber         := null;
        lv_poexpirationdate := null;
      end;
  end get_contract_purchaseorder;

  function get_departmentid(fp_departmentnumber in department.departmentnumber%type,
                            fp_customerid       in customer.customer_id%type)
    return department.department_id%type is
    lv_departmentid department.department_id%type;
  begin
    --get_departmentid
    gv_text := ' department number ' || nvl(to_char(fp_departmentnumber), 'NULL');
    if fp_departmentnumber is null then
      return null;
    end if;
    select t.department_id
    into   lv_departmentid
    from   department t
    where  t.departmentnumber = fp_departmentnumber
    and    t.customer_id = fp_customerid;
    return lv_departmentid;
  end get_departmentid;

  function get_distributionpointid(fp_distributionpointnumber in distributionpoint.distributionpointnumber%type,
                                   fp_departmentid            in distributionpoint.department_id%type,
                                   fp_delpointid              out distributionpoint.deliverypoint_id%type)
    return distributionpoint.distributionpoint_id%type is
    lv_distributionpointid distributionpoint.distributionpoint_id%type;
  begin
    --get_distributionpointid
    gv_text := ' consumptionpoint for ' || nvl(to_char(fp_distributionpointnumber), 'NULL') ||
               ' for department ' || nvl(to_char(fp_departmentid), 'NULL');
    select dp.distributionpoint_id, dp.deliverypoint_id
    into   lv_distributionpointid, fp_delpointid
    from   distributionpoint dp
    where  dp.distributionpointnumber = fp_distributionpointnumber
    and    dp.department_id = fp_departmentid;
    return lv_distributionpointid;
  end get_distributionpointid;

  function get_distributionpointid(fp_distributionpointnumber in distributionpoint.distributionpointnumber%type,
                                   fp_departmentid            in distributionpoint.department_id%type)
    return distributionpoint.distributionpoint_id%type is
    lv_distributionpointid distributionpoint.distributionpoint_id%type;
  begin
    --get_distributionpointid
    gv_text := ' consumptionpoint for ' || nvl(to_char(fp_distributionpointnumber), 'NULL') ||
               ' for department ' || nvl(to_char(fp_departmentid), 'NULL');
    select dp.distributionpoint_id
    into   lv_distributionpointid
    from   distributionpoint dp
    where  dp.distributionpointnumber = fp_distributionpointnumber
    and    dp.department_id = fp_departmentid;
    return lv_distributionpointid;
  end get_distributionpointid;

  function get_paymenttermsid(fp_paymenttermscode in paymentterms.code%type)
    return paymentterms.paymentterms_id%type is
    lv_paymenttermsid paymentterms.paymentterms_id%type;
  begin
    --get_paymenttermsid
    gv_text := ' get paymentterms for code ' || nvl(fp_paymenttermscode, 'NULL');
    if fp_paymenttermscode is null then
      return null;
    end if;
    select cy.paymentterms_id
    into   lv_paymenttermsid
    from   paymentterms cy
    where  cy.code = fp_paymenttermscode;
    return lv_paymenttermsid;
  end get_paymenttermsid;

  function get_bankinstitutionid(fp_bankinstitutionidcode in bankinstitution.idcode%type)
    return bankinstitution.bankinstitution_id%type is
    lv_bankinstitutionid bankinstitution.bankinstitution_id%type;
  begin
    --get_bankinstitutionid
    gv_text := ' get bankinstitution for code ' || fp_bankinstitutionidcode;
    select cy.bankinstitution_id
    into   lv_bankinstitutionid
    from   bankinstitution cy
    where  cy.idcode = fp_bankinstitutionidcode;
    return lv_bankinstitutionid;
  end get_bankinstitutionid;

  function get_registrationunitid(fp_registrationunitcode in registrationunit.code%type)
    return registrationunit.registrationunit_id%type is
    lv_registrationunitid registrationunit.registrationunit_id%type;
  begin
    --get_registrationunitid
    gv_text := ' get registrationunit for code ' || fp_registrationunitcode;
    if fp_registrationunitcode is null then
      return null;
    end if;
    select rg.registrationunit_id
    into   lv_registrationunitid
    from   registrationunit rg
    where  rg.code = fp_registrationunitcode;
    return lv_registrationunitid;
  end get_registrationunitid;

  function get_weighingcategoryid(fp_weighingcategorycode in weighingcategory.code%type)
    return weighingcategory.weighingcategory_id%type is
    lv_weighingcategoryid weighingcategory.weighingcategory_id%type;
  begin
    --get_weighingcategoryid
    gv_text := ' get weighingcategory for code ' || fp_weighingcategorycode;
    if fp_weighingcategorycode is null then
      return null;
    end if;
    select wg.weighingcategory_id
    into   lv_weighingcategoryid
    from   weighingcategory wg
    where  wg.code = fp_weighingcategorycode;
    return lv_weighingcategoryid;
  end get_weighingcategoryid;

  function get_supplierid(fp_suppliernumber in supplier.suppliernumber%type)
    return supplier.supplier_id%type is
    lv_supplierid supplier.supplier_id%type;
  begin
    --get_supplierid
    gv_text := ' get supplier for number ' || fp_suppliernumber;
    select wg.supplier_id
    into   lv_supplierid
    from   supplier wg
    where  wg.suppliernumber = fp_suppliernumber;
    return lv_supplierid;
  end get_supplierid;

  function get_finishingmethodid(fp_finishingmethodcode in finishingmethod.code%type)
    return finishingmethod.finishingmethod_id%type is
    lv_finishingmethodid finishingmethod.finishingmethod_id%type;
  begin
    --get_finishingmethodid
    if fp_finishingmethodcode is null then
      begin
        return null;
      end;
    end if;
    gv_text := ' get finishingmethod for code ' || fp_finishingmethodcode;
    select rg.finishingmethod_id
    into   lv_finishingmethodid
    from   finishingmethod rg
    where  rg.code = fp_finishingmethodcode;
    return lv_finishingmethodid;
  end get_finishingmethodid;

  function get_qualitygradeid(fp_qualitygradecode in qualitygrade.code%type)
    return qualitygrade.qualitygrade_id%type is
    lv_qualitygradeid qualitygrade.qualitygrade_id%type;
  begin
    --get_qualitygradeid
    gv_text := ' get qualitygrade for code ' || fp_qualitygradecode;
    if fp_qualitygradecode is null then
      return null;
    end if;
    select pg.qualitygrade_id
    into   lv_qualitygradeid
    from   qualitygrade pg
    where  pg.code = fp_qualitygradecode;
    return lv_qualitygradeid;
  end get_qualitygradeid;

  function get_plantid(fp_plantcode in plant.code%type) return plant.plant_id%type is
    lv_plantid plant.plant_id%type;
  begin
    --get_plantid
    gv_text := ' get plant for code ' || nvl(fp_plantcode, 'NULL');
    select pt.plant_id into lv_plantid from plant pt where pt.code = fp_plantcode;
    return lv_plantid;
  exception
    when no_data_found then
      begin
        gv_text := gv_text || ' no data found!';
        raise ge_user___exception;
      end;
  end get_plantid;

  function get_productid(fp_productcode       in product.code%type,
                         fp_productgroupid    out product.productgroup_id%type,
                         fp_rec_passive_stock in product.recordpassivestock%type default null,
                         fp_tom_product       in number default 0) return product.product_id%type is
    lv_productid   product.product_id%type;
    lv_tom_product product.typeofmerchandise%type;
  begin
    --get_productid
    if fp_productcode is null then
      begin
        return null;
      end;
    end if;
    if fp_rec_passive_stock is null then
      begin
        gv_text := ' get_product for code ' || nvl(fp_productcode, 'NULL');
        select s.product_id, s.typeofmerchandise, s.supplier_id, s.productgroup_id
        into   lv_productid, lv_tom_product, gv_supplierid, fp_productgroupid
        from   product s
        where  s.code = fp_productcode;
      end;
    else
      begin
        gv_text := ' get_product for code ' || nvl(fp_productcode, 'NULL') ||
                   ' with record passive stock is ' || fp_rec_passive_stock;
        select s.product_id, s.typeofmerchandise, s.supplier_id
        into   lv_productid, lv_tom_product, gv_supplierid
        from   product s
        where  s.code = fp_productcode
        and    s.recordpassivestock = fp_rec_passive_stock;
      end;
    end if;
    if fp_tom_product <> 0 and fp_tom_product <> lv_tom_product then
      begin
        gv_text := ' product ' || nvl(fp_productcode, 'NULL') || ' has TOM ' ||
                   to_char(lv_tom_product) || ' required is ' || fp_tom_product;
        raise ge_user___exception;
      end;
    end if;
    return lv_productid;
  end get_productid;

  function get_productid(fp_productcode       in product.code%type,
                         fp_rec_passive_stock in product.recordpassivestock%type default null,
                         fp_tom_product       in number default 0) return product.product_id%type is
    lv_productgroupid productgroup.productgroup_id%type;
  begin
    return get_productid(fp_productcode, lv_productgroupid, fp_rec_passive_stock, fp_tom_product);
  end get_productid;

  function get_productsortgroupid(fp_productsortgroupcode in productsortgroup.code%type)
    return productsortgroup.productsortgroup_id%type is
    lv_productsortgroupid productsortgroup.productsortgroup_id%type;
  begin
    if fp_productsortgroupcode is null then
      return null;
    else
      begin
        --get_productsortgroupid
        gv_text := ' get_productsortgroupid for code ' || nvl(fp_productsortgroupcode, 'NULL');
        select pg.productsortgroup_id
        into   lv_productsortgroupid
        from   productsortgroup pg
        where  pg.code = fp_productsortgroupcode;
      exception
        when no_data_found then
          begin
            insert into productsortgroup
              (productsortgroup_id, code, description, systemuser_id, timestamp)
            values
              (seq_productsortgroup.nextval, fp_productsortgroupcode, fp_productsortgroupcode,
               gv_erp_systemuserid, sysdate)
            returning productsortgroup_id into lv_productsortgroupid;
          end;
      end;
    end if;
    return lv_productsortgroupid;
  end get_productsortgroupid;

  function get_productranking(fp_ranking in productranking.ranking%type)
    return productranking.productranking_id%type is
    lv_productrankingid productranking.productranking_id%type;
    lv_priority         productranking.priority%type;
  begin
    if fp_ranking is null then
      return null;
    else
      begin
        --get_productranking
        gv_text := ' get_productranking ' || nvl(upper(trim(fp_ranking)), 'NULL');
        select pr.productranking_id
        into   lv_productrankingid
        from   productranking pr
        where  pr.ranking = upper(trim(fp_ranking));
      exception
        when no_data_found then
          begin
            select max(pr.priority) into lv_priority from productranking pr;
            insert into productranking
              (productranking_id, priority, ranking, systemuser_id, timestamp)
            values
              (seq_productranking.nextval, nvl(lv_priority, 0) + 1, upper(trim(fp_ranking)),
               gv_erp_systemuserid, sysdate);
          end;
      end;
    end if;
    return lv_productrankingid;
  end get_productranking;

  function get_generalpricelistid(fp_code      in generalpricelist.code%type,
                                  fp_pricetype in generalpricelist.pricetype%type)
    return generalpricelist.generalpricelist_id%type is
    lv_generalpricelistid generalpricelist.generalpricelist_id%type;
  begin
    --get_generalpricelistid
    gv_text := ' get generalpricelist for code ' || nvl(fp_code, 'NULL') || ' for pricetype ' ||
               nvl(to_char(fp_pricetype), 'NULL');
    if fp_code is null or fp_pricetype is null then
      return null;
    end if;
    --get generalpricelist
    select gpl.generalpricelist_id
    into   lv_generalpricelistid
    from   generalpricelist gpl
    where  gpl.code = fp_code
    and    gpl.pricetype = fp_pricetype;
    --return value
    return lv_generalpricelistid;
  end get_generalpricelistid;

  function get_labellayout(fp_code      in labellayout.code%type,
                           fp_labeltype in labellayout.labeltype%type)
    return labellayout.labellayout_id%type is
    lv_labellayoutid labellayout.labellayout_id%type;
  begin
    --get_labellayout
    if fp_code is null then
      return null;
    end if;
    gv_text := ' get labellayout for code ' || nvl(fp_code, 'NULL') || ' type ' ||
               nvl(to_char(fp_labeltype), 'NULL');
    select ll.labellayout_id
    into   lv_labellayoutid
    from   labellayout ll
    where  ll.code = fp_code
    and    ll.labeltype = fp_labeltype;
    return lv_labellayoutid;
  end get_labellayout;

  function get_reasoncodeid(fp_reasoncodecode in reasoncode.code%type)
    return reasoncode.reasoncode_id%type is
    lv_reasoncodeid reasoncode.reasoncode_id%type;
  begin
    --get_reasoncodeid
    gv_text := ' get reasoncode for code ' || nvl(fp_reasoncodecode, 'NULL');
    if fp_reasoncodecode is null then
      return null;
    end if;
    select pg.reasoncode_id
    into   lv_reasoncodeid
    from   reasoncode pg
    where  pg.code = fp_reasoncodecode;
    return lv_reasoncodeid;
  exception
    when no_data_found then
      begin
        gv_text := gv_text || ' no data found!';
        raise ge_user___exception;
      end;
  end get_reasoncodeid;

  function get_repairtypeid(fp_code in repairtype.code%type) return repairtype.repairtype_id%type is
    lv_repairtypeid repairtype.repairtype_id%type;
  begin
    --get_repairtypeid
    gv_text := ' get_repairtype for code ' || nvl(fp_code, 'NULL');
    if fp_code is null then
      begin
        return null;
      end;
    else
      begin
        select sc.repairtype_id into lv_repairtypeid from repairtype sc where sc.code = fp_code;
        return lv_repairtypeid;
      end;
    end if;
  end get_repairtypeid;

  function get_residualvalueschemeid(fp_code in residualvaluescheme.code%type)
    return residualvaluescheme.residualvaluescheme_id%type is
    lv_residualvalueschemeid residualvaluescheme.residualvaluescheme_id%type;
  begin
    --get_residualvalueschemeid
    gv_text := ' get_residualvaluescheme for code ' || nvl(fp_code, 'NULL');
    if fp_code is null then
      begin
        return null;
      end;
    else
      begin
        select rvs.residualvaluescheme_id
        into   lv_residualvalueschemeid
        from   residualvaluescheme rvs
        where  rvs.code = fp_code;
        return lv_residualvalueschemeid;
      end;
    end if;
  end get_residualvalueschemeid;

  function get_sizegroupingid(fp_sizegroupingcode in sizegroupingcode.code%type,
                              fp_sizegroupingdesc in sizegroupingcode.description%type)
    return sizegroupingcode.sizegroupingcode_id%type is
    lv_sizegroupingcodeid sizegroupingcode.sizegroupingcode_id%type;
  begin
    --check if sizegroupingcode is null
    if fp_sizegroupingcode is null then
      begin
        return null;
      end;
    else
      begin
        --get_sizegroupingid
        gv_text := ' get sizegrouping for code ' || fp_sizegroupingcode;
        select sg.sizegroupingcode_id
        into   lv_sizegroupingcodeid
        from   sizegroupingcode sg
        where  sg.code = fp_sizegroupingcode;
        return lv_sizegroupingcodeid;
      exception
        when no_data_found then
          begin
            --insert sizegroupingcode
            gv_text := ' get sizegrouping id, insert for code ' || fp_sizegroupingcode;
            select seq_sizegroupingcode.nextval into lv_sizegroupingcodeid from dual;
            insert into sizegroupingcode
              (sizegroupingcode_id, code, description, systemuser_id, timestamp)
            values
              (lv_sizegroupingcodeid, fp_sizegroupingcode,
               coalesce(fp_sizegroupingdesc, fp_sizegroupingcode), gv_erp_systemuserid, sysdate);
            return lv_sizegroupingcodeid;
          end;
      end;
    end if;
  end get_sizegroupingid;

  function get_sizetypeid(fp_sizetypecode in sizetype.code%type) return sizetype.sizetype_id%type is
    lv_sizetypeid sizetype.sizetype_id%type;
  begin
    --get_sizetypeid
    if fp_sizetypecode is null then
      return null;
    end if;
    gv_text := ' get sizetype for code ' || nvl(fp_sizetypecode, 'NULL');
    select pg.sizetype_id into lv_sizetypeid from sizetype pg where pg.code = fp_sizetypecode;
    return lv_sizetypeid;
  exception
    when no_data_found then
      begin
        --insert sizetype
        gv_text := ' get_sizetypeid. insert sizetype for code ' || nvl(fp_sizetypecode, 'NULL');
        select seq_sizetype.nextval into lv_sizetypeid from dual;
        insert into sizetype
          (sizetype_id, code, systemuser_id, timestamp)
        values
          (lv_sizetypeid, fp_sizetypecode, gv_erp_systemuserid, sysdate);
        insert into sizetype_desc
          (sizetype_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_sizetypeid, gv_languageid, fp_sizetypecode, gv_erp_systemuserid, sysdate);
        return lv_sizetypeid;
      end;
  end get_sizetypeid;

  function get_sizeid(fp_sizecode               in sizedefinition.code%type,
                      fp_create_if_not_exist    in number, --1=Yes, 0=No, other is No
                      fp_description            in erp_i_productsize.size_description%type default null,
                      fp_width                  in erp_i_productsize.width%type default null,
                      fp_length                 in erp_i_productsize.length%type default null,
                      fp_unfinishedsizedcode    in erp_i_productsize.unfinishedsizedefinitioncode%type default null,
                      fp_unfinishedlength       in erp_i_productsize.unfinishedlength%type default 'N',
                      fp_reservealternativesize in erp_i_productsize.reservealternativesize%type default 'N',
                      fp_usedforemblem          in erp_i_productsize.size_usedforemblem%type default 'N')
    return sizedefinition.sizedefinition_id%type is
    lv_sizeid            sizedefinition.sizedefinition_id%type;
    lv_unfinished_sizeid sizedefinition.sizedefinition_id%type;
  begin
    --get_sizeid
    if fp_sizecode is null then
      begin
        return null;
      end;
    end if;
    gv_text := ' get_size for code ' || nvl(fp_sizecode, 'NULL');
    select s.sizedefinition_id into lv_sizeid from sizedefinition s where s.code = fp_sizecode;
    return lv_sizeid;
  exception
    when no_data_found then
      begin
        if fp_create_if_not_exist <> 1 then
          begin
            raise no_data_found;
          end;
        else
          begin
            if fp_unfinishedsizedcode is null then
              lv_unfinished_sizeid := null;
            else
              lv_unfinished_sizeid := get_sizeid(fp_unfinishedsizedcode, 0);
            end if;
            --insert size id
            gv_text := ' get_size. insert size for code ' || nvl(fp_sizecode, 'NULL');
            select seq_sizedefinition.nextval into lv_sizeid from dual;
            --insert into size tables
            insert into sizedefinition
              (sizedefinition_id, code, systemuser_id, unfinishedlength, legacysizecode, width,
               timestamp, length, usedforemblem, unfinishedsizedefinition_id, reservealternativesize)
            values
              (lv_sizeid, fp_sizecode, gv_erp_systemuserid, nvl(fp_unfinishedlength, 'N'), null,
               fp_width, sysdate, fp_length, nvl(fp_usedforemblem, 'N'), lv_unfinished_sizeid,
               nvl(fp_reservealternativesize, 'N'));
            insert into sizedefinition_desc
              (sizedefinition_id, language_id, description, systemuser_id, timestamp)
            values
              (lv_sizeid, gv_languageid, nvl(fp_description, fp_sizecode), gv_erp_systemuserid,
               sysdate);
            insert into sizedefinition_link
              (sizedefinition_link_id, sizedefinition_id, code, systemuser_id, legacysizecode,
               timestamp)
            values
              (lv_sizeid, lv_sizeid, fp_sizecode, gv_erp_systemuserid, null, sysdate);
            insert into sizedefinition_link_desc
              (sizedefinition_link_id, language_id, description, systemuser_id, timestamp)
            values
              (lv_sizeid, gv_languageid, nvl(fp_description, fp_sizecode), gv_erp_systemuserid,
               sysdate);
            return lv_sizeid;
          end;
        end if;
      end;
  end get_sizeid;

  function get_specialchargeid(fp_code in specialcharge.code%type)
    return specialcharge.specialcharge_id%type is
    lv_specialchargeid specialcharge.specialcharge_id%type;
  begin
    --get_specialchargeid
    gv_text := ' get_specialcharge for code ' || nvl(fp_code, 'NULL');
    if fp_code is null then
      begin
        return null;
      end;
    else
      begin
        select sc.specialcharge_id
        into   lv_specialchargeid
        from   specialcharge sc
        where  sc.code = fp_code;
        return lv_specialchargeid;
      end;
    end if;
  end get_specialchargeid;

  function get_stockroomid(fp_stockroomcode in stockroom.code%type)
    return stockroom.stockroom_id%type is
    lv_stockroomid stockroom.stockroom_id%type;
  begin
    --get_stockroomid
    gv_text := ' get_stockroom for code ' || nvl(fp_stockroomcode, 'NULL');
    if fp_stockroomcode is null then
      begin
        return null;
      end;
    else
      begin
        select s.stockroom_id into lv_stockroomid from stockroom s where s.code = fp_stockroomcode;
        return lv_stockroomid;
      end;
    end if;
  end get_stockroomid;

  function get_turnovergroupid(fp_turnovergroupcode in turnovergroup.code%type,
                               fp_name              in varchar2 default null,
                               fp_productgroupid    in number default null)
    return turnovergroup.turnovergroup_id%type is
    lv_turnovergroupid turnovergroup.turnovergroup_id%type;
  begin
    --get_turnovergroupid
    if fp_turnovergroupcode is null then
      begin
        if fp_name is null and fp_productgroupid is null then
          begin
            return null;
          end;
        else
          begin
            case fp_name
              when 'wash' then
                select pg.washturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'rent' then
                select pg.rentturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'sales' then
                select pg.salesturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'replacement' then
                select pg.replacementturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'loss' then
                select pg.lossturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'advance' then
                select pg.advanceturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'corrections' then
                select pg.correctionsturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              when 'washcog' then
                select pg.washcogturnovergroup_id
                into   lv_turnovergroupid
                from   productgroup pg
                where  pg.productgroup_id = fp_productgroupid;
              else
                lv_turnovergroupid := null;
            end case;
            return lv_turnovergroupid;
          end;
        end if;
      end;
    else
      begin
        gv_text := ' get turnovergroup for code ' || nvl(fp_turnovergroupcode, 'NULL');
        select cy.turnovergroup_id
        into   lv_turnovergroupid
        from   turnovergroup cy
        where  cy.code = fp_turnovergroupcode;
        return lv_turnovergroupid;
      end;
    end if;
  end get_turnovergroupid;

  function get_treatmentcheckid(fp_code in treatmentcheckscheme.code%type) return number is
    lv_treatmentcheckid treatmentcheckscheme.treatmentcheckscheme_id%type;
  begin
    --get treatmentcheckscheme_id for code
    gv_text := 'treatmentcheckscheme ' || to_char(fp_code, 'NULL');
    if fp_code is null then
      return null;
    else
      begin
        select ts.treatmentcheckscheme_id
        into   lv_treatmentcheckid
        from   treatmentcheckscheme ts
        where  ts.code = fp_code;
      end;
    end if;
    return lv_treatmentcheckid;
  end get_treatmentcheckid;

  function get_usergroupid(fp_groupname usergroup.groupname%type) return usergroup.usergroup_id%type is
    lv_usergroupid usergroup.usergroup_id%type;
  begin
    --get_usergroupid
    if fp_groupname is null then
      return null;
    end if;
    gv_text := ' get usergroup for groupname ' || nvl(fp_groupname, 'NULL');
    select ug.usergroup_id into lv_usergroupid from usergroup ug where ug.groupname = fp_groupname;
    return lv_usergroupid;
  end get_usergroupid;

  function get_flagid(fp_flagcode in flag.code%type, fp_flagtype in flag.flagtype%type)
    return flag.flag_id%type is
    lv_flagid flag.flag_id%type;
  begin
    --get_flagid
    if fp_flagcode is null then
      return null;
    else
      begin
        gv_text := ' get flag for code ' || nvl(fp_flagcode, 'NULL') || ' flag type ' ||
                   nvl(to_char(fp_flagtype), 'NULL');
        select f.flag_id
        into   lv_flagid
        from   flag f
        where  f.code = fp_flagcode
        and    f.flagtype = fp_flagtype;
        return lv_flagid;
      end;
    end if;
  end get_flagid;

  function get_washingprocess(fp_washingprocesscode in washingprocess.code%type)
    return washingprocess.washingprocess_id%type is
    lv_washingprocessid washingprocess.washingprocess_id%type;
  begin
    --get the washingprocess id
    if fp_washingprocesscode is null then
      return null;
    else
      begin
        gv_text := 'washingprocess ' || fp_washingprocesscode;
        select wp.washingprocess_id
        into   lv_washingprocessid
        from   washingprocess wp
        where  wp.code = fp_washingprocesscode;
        return lv_washingprocessid;
      end;
    end if;
  end get_washingprocess;

  function insert_or_update_addressid(fp_addressid      in address.address_id%type,
                                      fp_street         in address.street%type,
                                      fp_street2        in address.street%type,
                                      fp_zipcode        in address.zipcode%type,
                                      fp_city           in address.city%type,
                                      fp_nullallowed_yn in varchar2,
                                      fp_cust_addressid in address.address_id%type,
                                      fp_state          in address.state%type,
                                      fp_county         in address.county%type)
    return address.address_id%type is
    lv_addressid address.address_id%type;
  
    procedure insert_address is
    begin
      --insert_address
      gv_text := 'insert_or_update_addressid.insert';
      select seq_address.nextval into lv_addressid from dual;
      insert into address
        (address_id, street, street2, zipcode, city, systemuser_id, timestamp, state, county)
      values
        (lv_addressid, fp_street, fp_street2, fp_zipcode, fp_city, gv_erp_systemuserid, sysdate,
         fp_state, fp_county);
    end insert_address;
  begin
    --insert_or_update_addressid
    if fp_city is null and fp_zipcode is null and fp_nullallowed_yn = 'Y' then
      begin
        --it is meant to be made empty, or can be left empty
        return fp_cust_addressid;
      end;
    else
      if fp_nullallowed_yn = 'Y' and fp_addressid = fp_cust_addressid then
        begin
          --add specific address
          insert_address;
          return lv_addressid;
        end;
      end if;
      if fp_addressid is not null then
        begin
          --update
          select ad.address_id
          into   lv_addressid
          from   address ad
          where  ad.address_id = fp_addressid;
          gv_text := 'insert_or_update_addressid.update';
          update address ad
          set    ad.street = fp_street, ad.street2 = fp_street2,
                 ad.zipcode = nvl(fp_zipcode, ad.zipcode), ad.city = nvl(fp_city, ad.city),
                 ad.systemuser_id = gv_erp_systemuserid, ad.timestamp = sysdate,
                 ad.state = nvl(fp_state, ad.state), ad.county = nvl(fp_county, ad.county)
          where  ad.address_id = fp_addressid;
          return lv_addressid;
        end;
      else
        begin
          insert_address;
          return lv_addressid;
        end;
      end if;
    end if;
  exception
    when no_data_found then
      begin
        insert_address;
        return lv_addressid;
      end;
  end insert_or_update_addressid;
  ----------------------------------------------------------------------------
  --external procedures
  --ERP I TABLES---------

  --process erp_i_dialogflexfields
  --AUJ will only use it for CUSTOMER
  procedure proc_i_dialogflexfields_one(fp_transferid in erp_i_dialogflexfields.transfer_id%type,
                                        fp_rerun      in number default 0) is
    lv_rec_erp_i_dialogflexfields erp_i_dialogflexfields%rowtype;
    lv_log_tablename              varchar2(32) := 'ERP_I_DIALOGFLEXFIELDS_LOG';
    lv_process_status             number := 0;
    lv_dialogflexfield_id         dialogflexfields.dialogflexfield_id%type;
    -------------
    --internal procedure functions from proc_i_dialogflexfields_one
    function read_line return number is
    begin
      --read_line erp_i_dialogflexfields
      select eif.*
      into   lv_rec_erp_i_dialogflexfields
      from   erp_i_dialogflexfields eif
      where  eif.transfer_id = fp_transferid
      and    (eif.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_dialogflexfields eif
      set    eif.transfer_status = 1
      where  eif.transfer_id = fp_transferid;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_dialogflexfields is
      lv_dialogid                    dialogs.dialog_id%type;
      lv_characteristicpredefvalueid characteristicpredefvalue.characteristicpredefvalue_id%type;
      lv_customerid                  customer.customer_id%type;
      lv_rec_characteristic          characteristic%rowtype;
    begin
      --get dialog
      gv_text := 'Get dialog for code ' || lv_rec_erp_i_dialogflexfields.dialogcode;
      select d.dialog_id
      into   lv_dialogid
      from   dialogs d
      where  d.code = lv_rec_erp_i_dialogflexfields.dialogcode;
      --get characteristic
      gv_text := 'Characteristic code ' || lv_rec_erp_i_dialogflexfields.characteristiccode ||
                 ' for dialog ' || lv_rec_erp_i_dialogflexfields.dialogcode;
      select chr.*
      into   lv_rec_characteristic
      from   characteristic chr
      where  chr.code = lv_rec_erp_i_dialogflexfields.characteristiccode
      and    chr.dialog_id = lv_dialogid;
      --get customer id
      gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1;
      select c.customer_id
      into   lv_customerid
      from   customer c
      where  c.customernumber = lv_rec_erp_i_dialogflexfields.entity_number1;
      --check predefined value
      lv_characteristicpredefvalueid := null;
      case lv_rec_characteristic.datatype
        when 1 then
          -- Number
          begin
            if (lv_rec_characteristic.maxvalue is not null and
               lv_rec_erp_i_dialogflexfields.numbervalue > lv_rec_characteristic.maxvalue) or
               (lv_rec_characteristic.minvalue is not null and
               lv_rec_erp_i_dialogflexfields.numbervalue < lv_rec_characteristic.minvalue) then
              gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                         ' Characteristic code ' ||
                         lv_rec_erp_i_dialogflexfields.characteristiccode || ' number value ' ||
                         lv_rec_erp_i_dialogflexfields.numbervalue || ' for dialog Customer';
              raise error_restriction;
            end if;
          end;
        when 2 then
          -- String
          begin
            if (lv_rec_characteristic.length > 0 and
               length(lv_rec_erp_i_dialogflexfields.stringvalue) > lv_rec_characteristic.length) then
              gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                         ' Characteristic code ' ||
                         lv_rec_erp_i_dialogflexfields.characteristiccode || ' String value ' ||
                         lv_rec_erp_i_dialogflexfields.stringvalue || ' for dialog Customer';
              raise error_restriction;
            end if;
          end;
        when 3 then
          -- Date
          begin
            if lv_rec_erp_i_dialogflexfields.datevalue is null then
              gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                         ' Characteristic code ' ||
                         lv_rec_erp_i_dialogflexfields.characteristiccode || ' Date value ' ||
                         lv_rec_erp_i_dialogflexfields.datevalue || ' for dialog Customer';
              raise error_restriction;
            end if;
          end;
        when 5 then
          -- Predefined value
          begin
            if lv_rec_erp_i_dialogflexfields.predefinedvalue = 'Y' then
              gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                         ' Characteristic code ' ||
                         lv_rec_erp_i_dialogflexfields.characteristiccode || ' string value ' ||
                         lv_rec_erp_i_dialogflexfields.stringvalue || ' for dialog Customer';
              begin
                select pdv.characteristicpredefvalue_id
                into   lv_characteristicpredefvalueid
                from   characteristicpredefvalue pdv
                where  pdv.characteristic_id = lv_rec_characteristic.characteristic_id
                and    pdv.stringvalue = lv_rec_erp_i_dialogflexfields.stringvalue;
              exception
                when no_data_found then
                  begin
                    raise error_predefinedvalue;
                  end;
              end;
            end if;
          end;
        else
          begin
            gv_text := 'Customer number ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                       ' Characteristic code ' || lv_rec_erp_i_dialogflexfields.characteristiccode ||
                       ' wrong type: ' || lv_rec_characteristic.datatype || ' for dialog Customer';
            raise error_predefinedvalue;
          end;
      end case;
      --insert into dialogflexfields
      gv_text := 'insert into dialogflexfields Characteristic code ' ||
                 lv_rec_erp_i_dialogflexfields.characteristiccode || ' for customer ' ||
                 lv_rec_erp_i_dialogflexfields.entity_number1;
      begin
        --select dialogflexfield
        select df.dialogflexfield_id
        into   lv_dialogflexfield_id
        from   dialogflexfields df
        where  df.dialog_id = lv_dialogid
        and    df.entity_id = lv_customerid
        and    df.characteristic_id = lv_rec_characteristic.characteristic_id;
        --update when found
        update dialogflexfields df
        set    df.numbervalue = lv_rec_erp_i_dialogflexfields.numbervalue,
               df.stringvalue = lv_rec_erp_i_dialogflexfields.stringvalue,
               df.datevalue = lv_rec_erp_i_dialogflexfields.datevalue,
               df.characteristicpredefvalue_id = lv_characteristicpredefvalueid,
               df.systemuser_id = gv_erp_systemuserid, df.timestamp = sysdate
        where  df.dialogflexfield_id = lv_dialogflexfield_id;
      exception
        when no_data_found then
          begin
            insert into dialogflexfields
              (dialogflexfield_id, dialog_id, entity_id, characteristic_id, numbervalue,
               stringvalue, datevalue, characteristicpredefvalue_id, systemuser_id, timestamp)
            values
              (seq_dialogflexfields.nextval, lv_dialogid, lv_customerid,
               lv_rec_characteristic.characteristic_id, lv_rec_erp_i_dialogflexfields.numbervalue,
               lv_rec_erp_i_dialogflexfields.stringvalue, lv_rec_erp_i_dialogflexfields.datevalue,
               lv_characteristicpredefvalueid, gv_erp_systemuserid, sysdate /*timestamp*/);
          end;
      end;
    end process_dialogflexfields;
  
  begin
    --proc_i_dialogflexfields_one
    gv_text := 'proc_i_dialogflexfields_one process erp_i_dialogflexfields for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_dialogflexfields;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_dialogflexfields_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select ef.transfer_id
            from   erp_i_dialogflexfields ef
            where  ef.transfer_id = f.transfer_id
            and    ef.entity_number1 = lv_rec_erp_i_dialogflexfields.entity_number1
            and    ef.characteristiccode = lv_rec_erp_i_dialogflexfields.characteristiccode)
    and    f.transfer_id < lv_rec_erp_i_dialogflexfields.transfer_id
    and    f.process_status <> 0;
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
               ' characteristiccode ' || lv_rec_erp_i_dialogflexfields.characteristiccode,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || 'For customer ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                   ' characteristiccode ' || lv_rec_erp_i_dialogflexfields.characteristiccode, 1, 0);
      end;
    when error_restriction then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid, gv_text, 1, 0);
      end;
    when error_predefinedvalue then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || 'For customer ' || lv_rec_erp_i_dialogflexfields.entity_number1 ||
                   ' characteristiccode ' ||
                   ' import_customer_flexfields, predefined values not found ' ||
                   lv_rec_erp_i_dialogflexfields.stringvalue, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' ||
                   lv_rec_erp_i_dialogflexfields.entity_number1 || ' characteristiccode ' ||
                   lv_rec_erp_i_dialogflexfields.characteristiccode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' ||
                   lv_rec_erp_i_dialogflexfields.entity_number1 || ' characteristiccode ' ||
                   lv_rec_erp_i_dialogflexfields.characteristiccode, 1, 0);
      end;
  end proc_i_dialogflexfields_one;

  --process proc_i_dialogflexfields
  procedure proc_i_dialogflexfields(fp_transferid in erp_i_dialogflexfields.transfer_id%type,
                                    fp_rerun      in number default 0) is
    transferstatus erp_i_dialogflexfields.transfer_status%type;
  begin
    for xa in (select eid.entity_number1, eid.characteristiccode
               from   erp_i_dialogflexfields eid
               where  eid.transfer_id = fp_transferid
               and    (eid.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for ya in (select max(eidx.transfer_id) transfer_id
                   from   erp_i_dialogflexfields eidx
                   where  eidx.entity_number1 = xa.entity_number1
                   and    eidx.characteristiccode = xa.characteristiccode) loop
          begin
            if fp_transferid < ya.transfer_id then
              begin
                update erp_i_dialogflexfields eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            select transfer_status
            into   transferstatus
            from   erp_i_dialogflexfields
            where  transfer_id = ya.transfer_id;
            if (transferstatus = 0 or fp_rerun > 0) then
              proc_i_dialogflexfields_one(ya.transfer_id, fp_rerun);
            end if;
          end;
        end loop; --ya
      end;
    end loop; --xa
  end proc_i_dialogflexfields;

  --process proc_i_ar_balans_all
  procedure proc_i_dialogflexfields_all is
  begin
    for aba in (select l.transfer_id
                from   erp_i_dialogflexfields l
                where  l.transfer_status = 0
                and    l.dialogcode = 'Customer'
                and    exists
                 (select 1 from customer c where c.customernumber = l.entity_number1)
                order  by l.transfer_id) loop
      begin
        proc_i_dialogflexfields(aba.transfer_id);
      end;
    end loop; --aba
  end proc_i_dialogflexfields_all;

  ----------------------------------------------------------------------------
  --external procedures
  --ERP I TABLES---------
  --process erp_i_product
  procedure proc_i_prod_one(fp_transferid in erp_i_product.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_product erp_i_product%rowtype;
    lv_rec_product       product%rowtype;
    lv_rec_emblemproduct emblemproduct%rowtype;
    lv_log_tablename     varchar2(32) := 'ERP_I_PRODUCT_LOG';
    lv_process_status    number := 0;
    lv_addedproductsizes number;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_product
      select eip.*
      into   lv_rec_erp_i_product
      from   erp_i_product eip
      where  eip.transfer_id = fp_transferid
      and    (eip.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_product eip
      set    eip.transfer_status = 1
      where  eip.transfer_id <= fp_transferid
      and    eip.code = lv_rec_erp_i_product.code
      and    eip.transfer_status = 0;
      --initialize the count of added product sizes
      lv_addedproductsizes := 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_product is
      -------------
      lv_new_pg_activityid  activity.activity_id%type;
      lv_old_pg_activityid  activity.activity_id%type;
      lv_old_productgroupid productgroup.productgroup_id%type;
      --internal procedure functions from process_product
      procedure get_current_activity is
      begin
        --get_current_activity of productgroup
        gv_text := 'get current activity of the productgroup';
        select pg.productgroup_id, pg.activity_id
        into   lv_old_productgroupid, lv_old_pg_activityid
        from   productgroup pg
        where  pg.productgroup_id = lv_rec_product.productgroup_id;
      exception
        when no_data_found then
          begin
            gv_text := 'productgroup ' || to_char(lv_rec_product.productgroup_id) ||
                       ' not found for product';
            raise ge_user___exception;
          end;
      end get_current_activity;
    
      function get_productgroupid(fp_productgroupcode in productgroup.code%type,
                                  fp_check            in number)
        return productgroup.productgroup_id%type is
        lv_productgroupid   productgroup.productgroup_id%type;
        lv_old_activitycode activity.code%type;
        lv_new_activitycode activity.code%type;
      begin
        --get_productgroupid
        if fp_productgroupcode is null then
          return null;
        end if;
        gv_text := ' get productgroup for code ' || fp_productgroupcode;
        select pg.productgroup_id, pg.activity_id
        into   lv_productgroupid, lv_new_pg_activityid
        from   productgroup pg
        where  pg.code = fp_productgroupcode;
        if fp_check = 1 and lv_old_pg_activityid <> lv_new_pg_activityid then
          begin
            --not allowed, new product group has different activity code!
            gv_text := 'get old and new activity codes';
            --old activity code
            select a.code
            into   lv_old_activitycode
            from   activity a
            where  a.activity_id = lv_old_pg_activityid;
            --new activity code
            select a.code
            into   lv_new_activitycode
            from   activity a
            where  a.activity_id = lv_new_pg_activityid;
            --write message
            gv_text := 'Error; new product group has different activity code, current activity code ' ||
                       lv_old_activitycode || ' new activity code ' || lv_new_activitycode;
            raise ge_user___exception;
          end;
        end if;
        if lv_old_productgroupid <> lv_productgroupid then
          begin
            insert into productgrouppercustomer
              (productgroup_id, customer_id, invoicegroupingcode, customcode, customdescritpion,
               systemuser_id, timestamp, active)
              select g.productgroup_id, l.customer_id, null, null, null, 1, sysdate, 'Y'
              from   product p
              join   productgroup g
              on     g.productgroup_id = p.productgroup_id
              join   productlistpercustomer l
              on     l.product_id = p.product_id
              where  p.product_id = lv_rec_product.product_id
              and    not exists (select x.productgroup_id, x.customer_id
                      from   productgrouppercustomer x
                      where  x.productgroup_id = g.productgroup_id
                      and    x.customer_id = l.customer_id)
              group  by g.productgroup_id, l.customer_id;
          end;
        end if;
        return lv_productgroupid;
      end get_productgroupid;
    
      function get_washingprocessid(fp_washingprocesscode in washingprocess.code%type)
        return washingprocess.washingprocess_id%type is
        lv_washingprocessid washingprocess.washingprocess_id%type;
      begin
        --get_washingprocessid
        if fp_washingprocesscode is null then
          return null;
        end if;
        gv_text := ' get washingprocess for code ' || fp_washingprocesscode;
        select wg.washingprocess_id
        into   lv_washingprocessid
        from   washingprocess wg
        where  wg.code = fp_washingprocesscode;
        return lv_washingprocessid;
      end get_washingprocessid;
    
      procedure init_product is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_product';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'PRODUCT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_product;
        close rcur_typ;
        --get id
        select seq_product.nextval into lv_rec_product.product_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_product.code              := lv_rec_erp_i_product.code;
        lv_rec_product.typeofmerchandise := nvl(lv_rec_erp_i_product.typeofmerchandise, 2);
        --set missing defaults
        lv_rec_product.autoreplacement          := 0;
        lv_rec_product.minimumturnaround        := 0;
        lv_rec_product.packingsequence          := 0;
        lv_rec_product.garmentset               := 'N';
        lv_rec_product.pack                     := 'N';
        lv_rec_product.model                    := 'N';
        lv_rec_product.parentproduct_id         := lv_rec_product.product_id;
        lv_rec_product.volumeunits              := 1;
        lv_rec_product.invoicecolumn            := 0;
        lv_rec_product.maxwashes                := 0;
        lv_rec_product.storeactivestocklocation := 'N';
        lv_rec_product.allowprewash             := 0;
        lv_rec_product.productgroup_id          := get_productgroupid(nvl(lv_rec_erp_i_product.productgroupcode,
                                                                          '-'), 0);
        --get current activity
        select pg.activity_id
        into   lv_old_pg_activityid
        from   productgroup pg
        where  pg.productgroup_id = lv_rec_product.productgroup_id;
        --fill invoicecolumn system setting GARMENTRENTCOLUMN1
        if lv_rec_product.typeofmerchandise = 5 then
          begin
            --cannot be used
            lv_rec_product.invoicecolumn := 0;
          end;
        else
          begin
            lv_rec_product.invoicecolumn := gv_invoicecolumn;
          end;
        end if;
      end init_product;
    
      procedure update_rec_product is
      begin
        --update_rec_product
        gv_text                                    := 'update_rec_product';
        lv_rec_product.active                      := lv_rec_erp_i_product.active;
        lv_rec_product.legacyproductcode           := lv_rec_erp_i_product.legacyproductcode;
        lv_rec_product.shortdescription            := lv_rec_erp_i_product.shortdescription;
        lv_rec_product.registrationunit_id         := coalesce(get_registrationunitid(lv_rec_erp_i_product.registrationunitcode),
                                                               lv_rec_product.registrationunit_id,
                                                               get_registrationunitid('-'));
        lv_rec_product.productgroup_id             := coalesce(get_productgroupid(lv_rec_erp_i_product.productgroupcode,
                                                                                  1),
                                                               lv_rec_product.productgroup_id,
                                                               get_productgroupid('-', 1));
        lv_rec_product.weighingcategory_id         := get_weighingcategoryid(lv_rec_erp_i_product.weighingcategorycode);
        lv_rec_product.color_id                    := get_colorid(lv_rec_erp_i_product.colorcode);
        lv_rec_product.fabric_id                   := coalesce(get_fabricid(lv_rec_erp_i_product.fabriccode),
                                                               lv_rec_product.fabric_id,
                                                               get_fabricid('-'));
        lv_rec_product.washingprocess_id           := coalesce(get_washingprocessid(lv_rec_erp_i_product.washingprocesscode),
                                                               lv_rec_product.washingprocess_id,
                                                               get_washingprocessid('-'));
        lv_rec_product.supplier_id                 := get_supplierid(lv_rec_erp_i_product.suppliernumber);
        lv_rec_product.exchangemethod              := coalesce(lv_rec_erp_i_product.exchangemethod,
                                                               lv_rec_product.exchangemethod, 1);
        lv_rec_product.soilcountmethod             := coalesce(lv_rec_erp_i_product.soilcountmethod,
                                                               lv_rec_product.soilcountmethod, 0);
        lv_rec_product.finishingcode_id            := coalesce(get_finishingid(lv_rec_erp_i_product.finishingcode),
                                                               lv_rec_product.finishingcode_id,
                                                               get_finishingid('-'));
        lv_rec_product.putuptype                   := lv_rec_erp_i_product.putuptype;
        lv_rec_product.recordpassivestock          := coalesce(lv_rec_erp_i_product.recordpassivestock,
                                                               lv_rec_product.recordpassivestock, 'Y');
        lv_rec_product.occupancyrelated            := coalesce(lv_rec_erp_i_product.occupancyrelated,
                                                               lv_rec_product.occupancyrelated, 'N');
        lv_rec_product.uniquepoolitem              := coalesce(lv_rec_erp_i_product.uniquepoolitem,
                                                               lv_rec_product.uniquepoolitem, 'Y');
        lv_rec_product.defaultreturngrade_id       := coalesce(get_qualitygradeid(lv_rec_erp_i_product.defaultreturngradecode),
                                                               lv_rec_product.defaultreturngrade_id,
                                                               get_qualitygradeid('U'));
        lv_rec_product.sizetype_id                 := coalesce(get_sizetypeid(lv_rec_erp_i_product.sizetypecode),
                                                               lv_rec_product.sizetype_id,
                                                               get_sizetypeid('-'));
        lv_rec_product.specialsize                 := coalesce(lv_rec_erp_i_product.specialsize,
                                                               lv_rec_product.specialsize, 'N');
        lv_rec_product.alternativesizereservation  := lv_rec_erp_i_product.alternativesizereservation;
        lv_rec_product.packingamount               := coalesce(lv_rec_erp_i_product.packingamount,
                                                               lv_rec_product.packingamount, 1);
        lv_rec_product.theoreticalweight           := coalesce(lv_rec_erp_i_product.theoreticalweight,
                                                               lv_rec_product.theoreticalweight, 0);
        lv_rec_product.lotnumberrequired           := nvl(lv_rec_erp_i_product.lotnumberrequiredyn,
                                                          lv_rec_product.lotnumberrequired);
        lv_rec_product.packtype                    := coalesce(lv_rec_erp_i_product.packtype,
                                                               lv_rec_product.packtype, 0);
        lv_rec_product.orpackcontentsallowed       := coalesce(lv_rec_erp_i_product.orpackcontentsallowed,
                                                               lv_rec_product.orpackcontentsallowed,
                                                               0);
        lv_rec_product.productsortgroup_id         := get_productsortgroupid(lv_rec_erp_i_product.productsortgroupcode);
        lv_rec_product.eannumber                   := lv_rec_erp_i_product.eannumber;
        lv_rec_product.confirmproductonpda         := coalesce(lv_rec_erp_i_product.confirmproductonpda,
                                                               lv_rec_product.confirmproductonpda, 1);
        lv_rec_product.totalpackweight             := lv_rec_erp_i_product.totalpackweight;
        lv_rec_product.packvolumeunits             := coalesce(lv_rec_erp_i_product.packvolumeunits,
                                                               lv_rec_product.packvolumeunits, 1);
        lv_rec_product.systemuser_id               := gv_erp_systemuserid;
        lv_rec_product.timestamp                   := sysdate;
        lv_rec_product.rentturnovergroup_id        := get_turnovergroupid(lv_rec_erp_i_product.turnovergrouprent,
                                                                          'rent',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.washturnovergroup_id        := get_turnovergroupid(lv_rec_erp_i_product.turnovergroupwash,
                                                                          'wash',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.replacementturnovergroup_id := get_turnovergroupid(lv_rec_erp_i_product.turnovergrouprepl,
                                                                          'replacement',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.salesturnovergroup_id       := get_turnovergroupid(lv_rec_erp_i_product.turnovergroupsales,
                                                                          'sales',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.lossturnovergroup_id        := get_turnovergroupid(lv_rec_erp_i_product.turnovergrouploss,
                                                                          'loss',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.advanceturnovergroup_id     := get_turnovergroupid(lv_rec_erp_i_product.turnovergroupadvance,
                                                                          'advance',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.correctionsturnovergroup_id := get_turnovergroupid(lv_rec_erp_i_product.turnovergroupcorrections,
                                                                          'corrections',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.washcogturnovergroup_id     := get_turnovergroupid(lv_rec_erp_i_product.turnovergroupwashcog,
                                                                          'washcog',
                                                                          lv_rec_product.productgroup_id);
        lv_rec_product.salesonly                   := nvl(lv_rec_erp_i_product.salesonly,
                                                          lv_rec_product.salesonly);
        lv_rec_product.mrpcode_id                  := nvl(get_mrpcodeid(lv_rec_erp_i_product.mrpcode),
                                                          lv_rec_product.mrpcode_id);
        if lv_rec_product.packtype in (1, 2) and lv_rec_product.pack <> 'Y' then
          begin
            lv_rec_product.pack := 'Y';
          end;
        end if;
        if lv_rec_product.typeofmerchandise = 4 then
          begin
            lv_rec_emblemproduct.emblemtype     := nvl(lv_rec_erp_i_product.emblemtype, 1);
            lv_rec_emblemproduct.textcolor_id   := get_colorid(lv_rec_erp_i_product.emblemtextcolor,
                                                               lv_rec_erp_i_product.emblemtextcolor_description);
            lv_rec_emblemproduct.bordercolor_id := get_colorid(lv_rec_erp_i_product.emblembordercolor,
                                                               lv_rec_erp_i_product.emblembordercolor_description);
            lv_rec_emblemproduct.emblemfont_id  := get_emblemfontid(lv_rec_erp_i_product.emblemfontdescription);
          end;
        end if;
        lv_rec_product.productranking_id := get_productranking(lv_rec_erp_i_product.productranking);
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_product;
    
      procedure add_productwashingprocess is
        lv_pwpcount number;
      begin
        --add_productwashingprocess
        if lv_rec_product.typeofmerchandise = 5 and lv_rec_product.washingprocess_id is not null then
          begin
            gv_text := 'update_rec_product.add_productwashingprocess';
            select count(1)
            into   lv_pwpcount
            from   productwashingprocess pwp
            where  pwp.product_id = lv_rec_product.product_id
            and    pwp.washingprocess_id = lv_rec_product.washingprocess_id;
            if lv_pwpcount = 0 then
              begin
                --not there yet insert it then
                insert into productwashingprocess
                  (productwashingprocess_id, product_id, washingprocess_id, systemuser_id,
                   timestamp)
                values
                  (seq_productwashingprocess.nextval, lv_rec_product.product_id,
                   lv_rec_product.washingprocess_id, gv_erp_systemuserid, sysdate);
              exception
                when dup_val_on_index then
                  null; --ok no problem is already there
              end;
            end if;
          end;
        end if;
      end add_productwashingprocess;
      -------------
    begin
      --process_product select
      gv_text := 'proc_i_prod.process_product for product code ' || lv_rec_erp_i_product.code;
      select p.* into lv_rec_product from product p where p.code = lv_rec_erp_i_product.code;
      --get current activity id
      get_current_activity;
      --update_rec_product
      update_rec_product;
      --update product
      gv_text := 'proc_i_prod.process_product update for product code ' ||
                 lv_rec_erp_i_product.code;
      update product p set row = lv_rec_product where p.product_id = lv_rec_product.product_id;
      --update emblemproduct if TOM=4
      if lv_rec_product.typeofmerchandise = 4 then
        begin
          gv_text := 'proc_i_prod.process_product update for emblemproduct code ' ||
                     lv_rec_erp_i_product.code;
          update emblemproduct emp
          set    emp.emblemtype = lv_rec_emblemproduct.emblemtype,
                 emp.textcolor_id = lv_rec_emblemproduct.textcolor_id,
                 emp.bordercolor_id = lv_rec_emblemproduct.bordercolor_id,
                 emp.emblemfont_id = lv_rec_emblemproduct.emblemfont_id,
                 emp.systemuser_id = gv_erp_systemuserid, emp.timestamp = sysdate
          where  emp.product_id = lv_rec_product.product_id;
        end;
      end if;
      add_productwashingprocess;
    exception
      when no_data_found then
        begin
          --process_product insert
          init_product;
          --update_rec_product
          update_rec_product;
          --insert record
          gv_text := 'proc_i_prod.process_product insert for product code ' ||
                     lv_rec_erp_i_product.code;
          insert into product values lv_rec_product;
          add_productwashingprocess;
          --insert emblem product if TOM=4
          if lv_rec_product.typeofmerchandise = 4 then
            begin
              gv_text := 'insert into emblemproduct for product code ' || lv_rec_erp_i_product.code;
              insert into emblemproduct
                (product_id, emblemtype, textcolor_id, bordercolor_id, systemuser_id, timestamp,
                 emblemfont_id)
              values
                (lv_rec_product.product_id, lv_rec_emblemproduct.emblemtype,
                 lv_rec_emblemproduct.textcolor_id, lv_rec_emblemproduct.bordercolor_id,
                 gv_erp_systemuserid, sysdate, lv_rec_emblemproduct.emblemfont_id);
            end;
          end if;
        end;
    end process_product;
  
    procedure process_product_desc(fp_productdesc in product_desc.description%type,
                                   fp_productlong in product_desc.longdescription%type,
                                   fp_languageid  in languages.language_id%type) is
    begin
      begin
        --process_product_desc
        gv_text := 'proc_i_prod.process_product_desc for product code ' ||
                   lv_rec_erp_i_product.code;
        --update product_desc
        update product_desc pd
        set    pd.description = fp_productdesc, pd.longdescription = fp_productlong,
               pd.systemuser_id = lv_rec_product.systemuser_id, pd.timestamp = sysdate
        where  pd.product_id = lv_rec_product.product_id
        and    pd.language_id = fp_languageid;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --insert into product_desc
            insert into product_desc
              (product_id, language_id, description, systemuser_id, timestamp, longdescription)
            values
              (lv_rec_product.product_id, fp_languageid, fp_productdesc,
               lv_rec_product.systemuser_id, sysdate, fp_productlong);
          end;
      end;
      begin
        --update record product_link_desc
        update product_link_desc pld
        set    pld.description = fp_productdesc, pld.longdescription = fp_productlong,
               pld.registrationunitdescription = lv_rec_erp_i_product.registrationunitcode,
               pld.systemuser_id = lv_rec_product.systemuser_id, pld.timestamp = sysdate
        where  pld.language_id = fp_languageid
        and    pld.product_link_id = lv_rec_product.product_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link desc record
            insert into product_link_desc
              (product_link_id, language_id, description, longdescription, systemuser_id, timestamp,
               registrationunitdescription)
            values
              (lv_rec_product.product_id, fp_languageid, fp_productdesc, fp_productlong,
               lv_rec_product.systemuser_id, sysdate, lv_rec_erp_i_product.registrationunitcode);
          end;
      end;
    end process_product_desc;
  
    procedure process_product_links(fp_languageid in languages.language_id%type) is
    begin
      --process_product_links
      gv_text := 'proc_i_prod.process_product_links for product code ' || lv_rec_erp_i_product.code;
      begin
        --update record product_link
        update product_link pk
        set    pk.code = lv_rec_product.code,
               pk.legacyproductcode = lv_rec_product.legacyproductcode,
               pk.productgroupcode = lv_rec_erp_i_product.productgroupcode,
               pk.timestamp = lv_rec_product.timestamp,
               pk.systemuser_id = lv_rec_product.systemuser_id
        where  pk.product_id = lv_rec_product.product_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link record
            insert into product_link
              (product_link_id, product_id, code, systemuser_id, legacyproductcode, timestamp,
               productgroupcode)
            values
              (lv_rec_product.product_id, lv_rec_product.product_id, lv_rec_product.code,
               lv_rec_product.systemuser_id, lv_rec_product.legacyproductcode,
               lv_rec_product.timestamp, lv_rec_erp_i_product.productgroupcode);
          end;
      end;
      --process_product_desc
      process_product_desc(lv_rec_erp_i_product.description, lv_rec_erp_i_product.longdescription,
                           fp_languageid);
    end process_product_links;
  
    procedure process_product_tax is
      lv_rec_productax      producttax%rowtype;
      lv_current_taxgroupid taxgroup.taxgroup_id%type;
    begin
      --Always only one TAX group per product!
      --process_product_tax
      gv_text := 'proc_i_prod.process_product_tax tax ' || lv_rec_erp_i_product.taxgroupcode ||
                 ' for product code ' || lv_rec_product.code;
      for x in (select tx.taxgroup_id, tx.country_id
                from   taxgroup tx
                where  tx.code = nvl(lv_rec_erp_i_product.taxgroupcode, 'XXX')
                group  by tx.taxgroup_id, tx.country_id) loop
        begin
          --fill values
          lv_rec_productax.taxgroup_id   := x.taxgroup_id;
          lv_rec_productax.country_id    := x.country_id;
          lv_rec_productax.product_id    := lv_rec_product.product_id;
          lv_rec_productax.systemuser_id := gv_erp_systemuserid;
          lv_rec_productax.timestamp     := sysdate;
          begin
            --check if it already exists
            select pt.taxgroup_id
            into   lv_current_taxgroupid
            from   producttax pt
            where  pt.product_id = lv_rec_product.product_id
            and    pt.country_id = lv_rec_productax.country_id;
            --different?
            if lv_current_taxgroupid <> lv_rec_productax.taxgroup_id then
              begin
                --if different update
                gv_text := gv_text || ' update';
                update producttax pt
                set    pt.taxgroup_id = lv_rec_productax.taxgroup_id,
                       pt.systemuser_id = gv_erp_systemuserid, pt.timestamp = sysdate
                where  pt.product_id = lv_rec_product.product_id
                and    pt.country_id = lv_rec_productax.country_id;
              end;
            end if;
            --else its already ok.
          exception
            when no_data_found then
              begin
                --does not exist, then create.
                gv_text := gv_text || ' insert';
                insert into producttax values lv_rec_productax;
              end;
          end;
        end;
      end loop; --x
    end process_product_tax;
  
    procedure process_product_orpack is
      lv_rec_productorpack productorpack%rowtype;
      -------------
      --internal procedure functions from process_product_orpack
      procedure set_treatmenttypeid is
      begin
        --get_treatmenttypeid
        gv_text := ' get treatmenttype for code ' ||
                   nvl(lv_rec_erp_i_product.orpack_treatmenttypecode, 'NULL');
        if lv_rec_erp_i_product.orpack_treatmenttypecode is null then
          lv_rec_productorpack.treatmenttype_id := null;
        else
          begin
            select tmt.treatmenttype_id
            into   lv_rec_productorpack.treatmenttype_id
            from   treatmenttype tmt
            where  tmt.code = lv_rec_erp_i_product.orpack_treatmenttypecode;
          end;
        end if;
      end set_treatmenttypeid;
    
      procedure set_expirationcodeid is
      begin
        --set_expirationcodeid
        gv_text := ' get expirationcode for code ' ||
                   nvl(lv_rec_erp_i_product.orpack_expirationcode, 'NULL');
        if lv_rec_erp_i_product.orpack_expirationcode is null then
          lv_rec_productorpack.expirationcode_id := null;
        else
          begin
            select exp.expirationcode_id
            into   lv_rec_productorpack.expirationcode_id
            from   expirationcode exp
            where  exp.code = lv_rec_erp_i_product.orpack_expirationcode;
          end;
        end if;
      end set_expirationcodeid;
    
      procedure set_assemblylabellayoutid is
      begin
        --set_assemblylabellayoutid
        gv_text := ' get set_assemblylabellayout for code ' ||
                   nvl(lv_rec_erp_i_product.orpack_assemblylabellayout, 'NULL');
        if lv_rec_erp_i_product.packtype = 3 then
          lv_rec_productorpack.assemblylabellayout_id := get_labellayout(lv_rec_erp_i_product.orpack_assemblylabellayout,
                                                                         7);
        else
          lv_rec_productorpack.assemblylabellayout_id := get_labellayout(lv_rec_erp_i_product.orpack_assemblylabellayout,
                                                                         4);
        end if;
      end set_assemblylabellayoutid;
      -------------
    begin
      --process_product_orpack
      gv_text := 'proc_i_prod.process_product_orpack for product code ' ||
                 lv_rec_erp_i_product.code;
      if lv_rec_erp_i_product.packtype in (2, 3) then
        --for OR pack and clean room products
        begin
          lv_rec_productorpack.product_id          := lv_rec_product.product_id;
          lv_rec_productorpack.sterile             := coalesce(lv_rec_erp_i_product.orpack_sterile,
                                                               lv_rec_productorpack.sterile, 0);
          lv_rec_productorpack.minactivestocklevel := lv_rec_erp_i_product.orpack_minactivestocklevel;
          lv_rec_productorpack.systemuser_id       := lv_rec_product.systemuser_id;
          lv_rec_productorpack.timestamp           := lv_rec_product.timestamp;
          set_treatmenttypeid;
          set_expirationcodeid;
          set_assemblylabellayoutid;
          --update or insert productorpack
          begin
            --update
            gv_text := 'proc_i_prod.process_product_orpack update for product code ' ||
                       lv_rec_erp_i_product.code;
            update productorpack pop
            set    row = lv_rec_productorpack
            where  pop.product_id = lv_rec_product.product_id;
            if sql%rowcount < 1 then
              raise no_data_found;
            end if;
          exception
            when no_data_found then
              begin
                --insert
                gv_text := 'proc_i_prod.process_product_orpack insert for product code ' ||
                           lv_rec_erp_i_product.code;
                insert into productorpack values lv_rec_productorpack;
              end;
          end;
        end;
      end if;
    end process_product_orpack;
  
    procedure process_productsize is
      lv_rec_productsize       productsize%rowtype;
      lv_rec_erp_i_productsize erp_i_productsize%rowtype;
      -------------
      --internal procedure functions from process_productsize
      procedure init_productsize is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_productsize';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'PRODUCTSIZE'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_productsize;
        close rcur_typ;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_productsize.product_id        := lv_rec_product.product_id;
        lv_rec_productsize.sizedefinition_id := get_sizeid(lv_rec_erp_i_productsize.sizecode, 1,
                                                           lv_rec_erp_i_productsize.size_description,
                                                           lv_rec_erp_i_productsize.width,
                                                           lv_rec_erp_i_productsize.length,
                                                           lv_rec_erp_i_productsize.unfinishedsizedefinitioncode,
                                                           lv_rec_erp_i_productsize.unfinishedlength,
                                                           lv_rec_erp_i_productsize.reservealternativesize,
                                                           lv_rec_erp_i_productsize.size_usedforemblem);
        --counter
        lv_addedproductsizes := lv_addedproductsizes + 1;
      end init_productsize;
    
      procedure update_rec_productsize is
        lv_sizegroupingcodeid sizegroupingcode.sizegroupingcode_id%type;
      begin
        --update_rec_productsize
        gv_text                                := 'update_rec_productsize';
        lv_rec_productsize.sequencenumber      := lv_rec_erp_i_productsize.sequencenumber * -1;
        lv_rec_productsize.specialsize         := lv_rec_erp_i_productsize.specialsize;
        lv_rec_productsize.packingamount       := coalesce(lv_rec_erp_i_productsize.packingamount,
                                                           lv_rec_productsize.packingamount, 1);
        lv_rec_productsize.theoreticalweight   := coalesce(lv_rec_erp_i_productsize.theoreticalweight,
                                                           lv_rec_productsize.theoreticalweight, 0);
        lv_rec_productsize.legacycode          := lv_rec_erp_i_productsize.legacycode;
        lv_rec_productsize.squaremeters        := lv_rec_erp_i_productsize.squaremeters;
        lv_rec_productsize.defaultstockroom_id := get_stockroomid(lv_rec_erp_i_productsize.defaultstockroomcode);
        lv_rec_productsize.fixedstockroom      := coalesce(lv_rec_erp_i_productsize.fixedstockroom,
                                                           lv_rec_productsize.fixedstockroom, 'N');
        lv_rec_productsize.systemuser_id       := lv_rec_product.systemuser_id;
        lv_rec_productsize.timestamp           := lv_rec_product.timestamp;
        lv_rec_productsize.standardlength      := coalesce(lv_rec_erp_i_productsize.standardlength,
                                                           lv_rec_productsize.standardlength, 'N');
        lv_rec_productsize.active              := coalesce(lv_rec_erp_i_productsize.active_yn,
                                                           lv_rec_productsize.active, 'Y');
        --update selected size its sizegroupingcode_id
        lv_sizegroupingcodeid := get_sizegroupingid(lv_rec_erp_i_productsize.sizegroupingcode,
                                                    lv_rec_erp_i_productsize.sizegroupingdescription);
        update sizedefinition s
        set    s.sizegroupingcode_id = lv_sizegroupingcodeid, s.systemuser_id = gv_erp_systemuserid,
               s.timestamp = sysdate
        where  s.sizedefinition_id = lv_rec_productsize.sizedefinition_id
        and    s.sizegroupingcode_id <> lv_sizegroupingcodeid;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_productsize;
    begin
      --process_productsize
      gv_text := 'proc_i_prod.process_productsize';
      for x in (select s.rowid
                from   erp_i_productsize s
                where  s.transfer_id = fp_transferid
                and    (s.transfer_status = 0 or fp_rerun > 0)) loop
        begin
          --update status
          update erp_i_productsize eis
          set    eis.transfer_status = 1
          where  eis.transfer_id = fp_transferid
          and    eis.rowid = x.rowid;
          --select record
          select eis.*
          into   lv_rec_erp_i_productsize
          from   erp_i_productsize eis
          where  eis.transfer_id = fp_transferid
          and    eis.rowid = x.rowid;
          begin
            --get_size
            lv_rec_productsize.sizedefinition_id := get_sizeid(lv_rec_erp_i_productsize.sizecode, 1,
                                                               lv_rec_erp_i_productsize.size_description,
                                                               lv_rec_erp_i_productsize.width,
                                                               lv_rec_erp_i_productsize.length,
                                                               lv_rec_erp_i_productsize.unfinishedsizedefinitioncode,
                                                               lv_rec_erp_i_productsize.unfinishedlength,
                                                               lv_rec_erp_i_productsize.reservealternativesize,
                                                               lv_rec_erp_i_productsize.size_usedforemblem);
          exception
            when no_data_found then
              begin
                gv_text := gv_text || ' no data found!';
                raise ge_user___exception;
              end;
          end;
          --check size * only allowe for TOM=2
          if lv_rec_product.typeofmerchandise <> 2 and lv_rec_erp_i_productsize.sizecode = '*' then
            begin
              gv_text := 'The combination of a non garment product and size * is not allowed';
              raise ge_user___exception;
            end;
          end if;
          begin
            --insert/update product size
            select ps.*
            into   lv_rec_productsize
            from   productsize ps
            where  ps.product_id = lv_rec_product.product_id
            and    ps.sizedefinition_id = lv_rec_productsize.sizedefinition_id;
            --update_rec_productsize
            update_rec_productsize;
            --update product size
            gv_text := 'proc_i_prod.process_productsize.update';
            update productsize ps
            set    row = lv_rec_productsize
            where  ps.product_id = lv_rec_product.product_id
            and    ps.sizedefinition_id = lv_rec_productsize.sizedefinition_id;
          exception
            when no_data_found then
              begin
                --process_productsize insert
                init_productsize;
                --update_rec_product
                update_rec_productsize;
                --insert record
                gv_text := 'proc_i_prod.process_productsize.insert';
                insert into productsize values lv_rec_productsize;
              end;
          end;
          --added size to sizetype if need be
          gv_text := 'proc_i_prod.process_productsize.insert sizespersizetype';
          insert into sizespersizetype
            (sizetype_id, sizedefinition_id, sequencenumber, systemuser_id, timestamp)
            select st.sizetype_id, lv_rec_productsize.sizedefinition_id,
                   nvl((select max(sequencenumber) + 1
                        from   sizespersizetype sps
                        where  sps.sizetype_id = st.sizetype_id), 1), gv_erp_systemuserid, timestamp
            from   sizetype st
            where  st.sizetype_id = lv_rec_product.sizetype_id
            and    not exists
             (select 1
                    from   sizespersizetype sps
                    where  sps.sizetype_id = st.sizetype_id
                    and    sps.sizedefinition_id = lv_rec_productsize.sizedefinition_id);
        end;
      end loop; --x
      begin
        update productsize ps
        set    ps.sequencenumber = ps.sequencenumber * -1
        where  ps.sequencenumber < 0
        and    ps.product_id = lv_rec_product.product_id;
      exception
        when dup_val_on_index then
          begin
            gv_text := 'The productsize sequencenumber is not unique for product ' ||
                       lv_rec_erp_i_product.code;
            raise ge_user___exception;
          end;
      end;
    end process_productsize;
  
    procedure process_productfinishingmethod is
      lv_rec_erp_i_productfinishm erp_i_productfinishingmethod%rowtype;
      lv_rec_productfinishm       productfinishingmethod%rowtype;
      -------------
      --internal procedure functions from process_productfinishingmethod
      procedure update_rec_productfinishm is
      begin
        --update_rec_productsize
        gv_text                              := 'update_rec_productfinishm';
        lv_rec_productfinishm.product_id     := lv_rec_product.product_id;
        lv_rec_productfinishm.expirationdays := coalesce(lv_rec_erp_i_productfinishm.expirationdays,
                                                         lv_rec_productfinishm.expirationdays, 0);
        lv_rec_productfinishm.systemuser_id  := lv_rec_product.systemuser_id;
        lv_rec_productfinishm.timestamp      := lv_rec_product.timestamp;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_productfinishm;
    begin
      --process_productfinishingmethod\
      gv_text := 'proc_i_prod.process_productfinishingmethod';
      for y in (select epf.rowid
                from   erp_i_productfinishingmethod epf
                where  epf.transfer_id = fp_transferid
                and    (epf.transfer_status = 0 or fp_rerun > 0)) loop
        begin
          --update status
          update erp_i_productfinishingmethod epf
          set    epf.transfer_status = 1
          where  epf.transfer_id = fp_transferid
          and    epf.rowid = y.rowid;
          --get record
          select epf.*
          into   lv_rec_erp_i_productfinishm
          from   erp_i_productfinishingmethod epf
          where  epf.transfer_id = fp_transferid
          and    epf.rowid = y.rowid;
          --get finishingmethod
          lv_rec_productfinishm.finishingmethod_id := get_finishingmethodid(lv_rec_erp_i_productfinishm.finishingmethodcode);
          begin
            --insert/update product finishingmethod
            select pf.*
            into   lv_rec_productfinishm
            from   productfinishingmethod pf
            where  pf.product_id = lv_rec_product.product_id
            and    pf.finishingmethod_id = lv_rec_productfinishm.finishingmethod_id;
            --update variables
            update_rec_productfinishm;
            --update product finishingmethod
            update productfinishingmethod pf
            set    row = lv_rec_productfinishm
            where  pf.product_id = lv_rec_productfinishm.product_id
            and    pf.finishingmethod_id = lv_rec_productfinishm.finishingmethod_id;
          exception
            when no_data_found then
              begin
                --update variables
                update_rec_productfinishm;
                lv_rec_productfinishm.finishingmethod_id := get_finishingmethodid(lv_rec_erp_i_productfinishm.finishingmethodcode);
                --insert product finishingmethod
                insert into productfinishingmethod values lv_rec_productfinishm;
              end;
          end;
        end;
      end loop; --y
    end process_productfinishingmethod;
  
    procedure process_productdescriptions is
    begin
      --process_productdescriptions
      gv_text := 'process_productdescriptions';
      for pdx in (select *
                  from   erp_i_productdesc epd
                  where  epd.transfer_id = fp_transferid
                  and    (epd.transfer_status = 0 or fp_rerun > 0)) loop
        begin
          --update status
          update erp_i_productdesc epd
          set    epd.transfer_status = 1
          where  epd.transfer_id = pdx.transfer_id
          and    epd.productcode = pdx.productcode
          and    epd.languagecode = pdx.languagecode;
          --process_product_desc
          process_product_desc(pdx.description, pdx.longdescription,
                               get_languageid(pdx.languagecode));
        end;
      end loop; --pd
    end process_productdescriptions;
  
    procedure process_packcontents is
      lv_rec_packcontents       packcontents%rowtype;
      lv_rec_erp_i_packcontents erp_i_packcontents%rowtype;
      -------------
      --internal procedure functions from process_packcontent
      procedure init_packcontents is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_packcontents';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'PACKCONTENTS'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_packcontents;
        close rcur_typ;
        --set default that CANNOT and MAY NOT be updated
        --key PACK_ID, PACKSEQUENCE, ROWNUMBER, POSITIONNUMBER, DATEACTIVE
        lv_rec_packcontents.pack_id        := lv_rec_product.product_id;
        lv_rec_packcontents.packsequence   := lv_rec_erp_i_packcontents.packsequence;
        lv_rec_packcontents.rownumber      := lv_rec_erp_i_packcontents.rownumber;
        lv_rec_packcontents.positionnumber := lv_rec_erp_i_packcontents.positionnumber;
        lv_rec_packcontents.dateactive     := lv_rec_erp_i_packcontents.dateactive;
        select seq_packcontents.nextval into lv_rec_packcontents.packcontents_id from dual;
      end init_packcontents;
    
      procedure update_rec_packcontents is
      begin
        --update_rec_packcontent
        gv_text := 'update_rec_packcontents';
        ---
        lv_rec_packcontents.product_id         := get_productid(lv_rec_erp_i_packcontents.content_productcode);
        lv_rec_packcontents.sizedefinition_id  := get_sizeid(lv_rec_erp_i_packcontents.content_sizecode,
                                                             1);
        lv_rec_packcontents.finishingmethod_id := get_finishingmethodid(lv_rec_erp_i_packcontents.content_finishingmethod);
        lv_rec_packcontents.amount             := lv_rec_erp_i_packcontents.quantity;
        lv_rec_packcontents.remark             := lv_rec_erp_i_packcontents.remark;
        lv_rec_packcontents.location           := lv_rec_erp_i_packcontents.location;
        lv_rec_packcontents.uniquelycoded      := lv_rec_erp_i_packcontents.uniquelycoded;
        lv_rec_packcontents.dateinactive       := lv_rec_erp_i_packcontents.dateinactive;
        lv_rec_packcontents.allowpackcontents  := lv_rec_erp_i_packcontents.allowpackcontents;
        lv_rec_packcontents.systemuser_id      := lv_rec_product.systemuser_id;
        lv_rec_packcontents.timestamp          := lv_rec_product.timestamp;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_packcontents;
    begin
      --process_packcontent
      gv_text := 'proc_i_prod.process_packcontent';
      if lv_rec_product.packtype <> 0 then
        for x in (select s.rowid
                  from   erp_i_packcontents s
                  where  s.transfer_id = fp_transferid
                  and    (s.transfer_status = 0 or fp_rerun > 0)) loop
          begin
            --update status
            update erp_i_packcontents eis
            set    eis.transfer_status = 1
            where  eis.transfer_id = fp_transferid
            and    eis.rowid = x.rowid;
            --select record
            select eis.*
            into   lv_rec_erp_i_packcontents
            from   erp_i_packcontents eis
            where  eis.transfer_id = fp_transferid
            and    eis.rowid = x.rowid;
            begin
              --insert/update packcontents
              --key PACK_ID, PACKSEQUENCE, ROWNUMBER, POSITIONNUMBER, DATEACTIVE
              select ps.*
              into   lv_rec_packcontents
              from   packcontents ps
              where  ps.pack_id = lv_rec_product.product_id
              and    ps.dateactive = lv_rec_erp_i_packcontents.dateactive
              and    ((ps.packsequence = lv_rec_erp_i_packcontents.packsequence or
                    (ps.packsequence is null and lv_rec_erp_i_packcontents.packsequence is null)) and
                    (ps.rownumber = lv_rec_erp_i_packcontents.rownumber and
                    ps.positionnumber = lv_rec_erp_i_packcontents.positionnumber or
                    (ps.rownumber is null and ps.positionnumber is null and
                    lv_rec_erp_i_packcontents.rownumber is null and
                    lv_rec_erp_i_packcontents.positionnumber is null)));
              --update_rec_packcontent
              update_rec_packcontents;
              --update product size
              gv_text := 'proc_i_prod.process_packcontents.update';
              update packcontents ps
              set    row = lv_rec_packcontents
              where  ps.pack_id = lv_rec_product.product_id
              and    ps.dateactive = lv_rec_erp_i_packcontents.dateactive
              and    ((ps.packsequence = lv_rec_erp_i_packcontents.packsequence or
                    (ps.packsequence is null and lv_rec_erp_i_packcontents.packsequence is null)) and
                    (ps.rownumber = lv_rec_erp_i_packcontents.rownumber and
                    ps.positionnumber = lv_rec_erp_i_packcontents.positionnumber or
                    (ps.rownumber is null and ps.positionnumber is null and
                    lv_rec_erp_i_packcontents.rownumber is null and
                    lv_rec_erp_i_packcontents.positionnumber is null)));
            exception
              when no_data_found then
                begin
                  --process_packcontent insert
                  init_packcontents;
                  --update_rec_product
                  update_rec_packcontents;
                  --insert record
                  gv_text := 'proc_i_prod.process_packcontents.insert';
                  insert into packcontents values lv_rec_packcontents;
                end;
            end;
          end;
        end loop; --x
      end if;
    end process_packcontents;
  
    procedure process_productmodification is
      procedure process_pmg_updateins(fp_sequencenumber    in productmodificationgroup.sequencenumber%type,
                                      fp_modificationgroup in modificationgroup.code%type) is
        lv_modificationgroupid modificationgroup.modificationgroup_id%type;
        lv_existing_mgid       modificationgroup.modificationgroup_id%type;
      begin
        --get_productmodification
        --first get the modification group id
        lv_modificationgroupid := get_modificationgroupid(fp_modificationgroup);
        begin
          --check if it exists
          gv_text := 'get productmodificationgroup sequence ' || fp_sequencenumber ||
                     ' modificationgroup ' || fp_modificationgroup;
          select pmg.modificationgroup_id
          into   lv_existing_mgid
          from   productmodificationgroup pmg
          where  pmg.product_id = lv_rec_product.product_id
          and    pmg.sequencenumber = fp_sequencenumber;
          if lv_existing_mgid <> lv_modificationgroupid then
            begin
              --if exists with anohter modification group, then update the modification group
              gv_text := 'update productmodificationgroup sequence ' || fp_sequencenumber ||
                         ' modificationgroup ' || fp_modificationgroup;
              update productmodificationgroup pmg
              set    pmg.modificationgroup_id = lv_modificationgroupid,
                     pmg.systemuser_id = gv_erp_systemuserid, pmg.timestamp = sysdate
              where  pmg.product_id = lv_rec_product.product_id
              and    pmg.sequencenumber = fp_sequencenumber;
            end;
          end if;
        exception
          when no_data_found then
            begin
              if lv_modificationgroupid is not null then
                begin
                  --insert it if it did not exist
                  --remark, if returns into error, then it exists for same product other sequence
                  gv_text := 'insert productmodificationgroup sequence ' || fp_sequencenumber ||
                             ' modificationgroup ' || fp_modificationgroup;
                  insert into productmodificationgroup
                    (product_id, modificationgroup_id, sequencenumber, systemuser_id, timestamp)
                  values
                    (lv_rec_product.product_id, lv_modificationgroupid, fp_sequencenumber,
                     gv_erp_systemuserid, sysdate);
                end;
              end if;
            end;
        end;
      end process_pmg_updateins;
    begin
      --process_productmodification groups
      process_pmg_updateins(1, lv_rec_erp_i_product.modificationgroup1);
      process_pmg_updateins(2, lv_rec_erp_i_product.modificationgroup2);
      process_pmg_updateins(3, lv_rec_erp_i_product.modificationgroup3);
    end process_productmodification;
  
    procedure process_checks is
    begin
      --update product specialsize
      gv_text := 'update product specialsize';
      update product p
      set    p.specialsize = 'Y'
      where  p.specialsize <> 'Y'
      and    p.product_id = lv_rec_product.product_id
      and    exists (select 1
              from   productsize ps
              where  ps.product_id = p.product_id
              and    ps.specialsize = 'Y');
    end process_checks;
    -------------
  begin
    --proc_i_prod
    gv_text := 'proc_i_prod process erp_i_product for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_product;
          process_product_links(coalesce(get_languageid(lv_rec_erp_i_product.languagecode),
                                         gv_languageid));
          process_product_tax;
          process_product_orpack;
          process_productsize;
          process_productfinishingmethod;
          process_productdescriptions;
          process_packcontents;
          process_productmodification;
          process_checks;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_product_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_product fi
            where  fi.transfer_id = f.transfer_id
            and    fi.code = lv_rec_erp_i_product.code)
    and    f.transfer_id < lv_rec_erp_i_product.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_product_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_product zz
      where  zz.code = lv_rec_erp_i_product.code
      and    zz.transfer_id < lv_rec_erp_i_product.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_product_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid, 'For product ' || lv_rec_erp_i_product.code,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For product ' || lv_rec_erp_i_product.code, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For product ' || lv_rec_erp_i_product.code, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For product ' || lv_rec_erp_i_product.code, 1, 0);
      end;
  end proc_i_prod_one;

  --process proc_i_prod
  procedure proc_i_prod(fp_transferid in erp_i_product.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for x in (select eip.code
              from   erp_i_product eip
              where  eip.transfer_id = fp_transferid
              and    (eip.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for y in (select max(eip.transfer_id) transfer_id
                  from   erp_i_product eip
                  where  eip.code = x.code) loop
          begin
            if fp_transferid < y.transfer_id then
              begin
                update erp_i_product eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_prod_one(y.transfer_id, fp_rerun);
          end;
        end loop;
      end;
    end loop; --x
  end proc_i_prod;

  --process proc_i_prod_all
  procedure proc_i_prod_all is
  begin
    for pda in (select l.transfer_id
                from   erp_i_product l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_prod(pda.transfer_id);
      end;
    end loop; --a
  end proc_i_prod_all;

  --process erp_i_size
  procedure proc_i_size_one(fp_transferid in erp_i_size.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_size     erp_i_size%rowtype;
    lv_rec_sizedefinition sizedefinition%rowtype;
    lv_log_tablename      varchar2(32) := 'ERP_I_SIZE_LOG';
    lv_process_status     number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_size
      select eis.*
      into   lv_rec_erp_i_size
      from   erp_i_size eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_size eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.sizecode = lv_rec_erp_i_size.sizecode
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_sizedefinition is
      -------------
      --internal procedure functions from process_sizedefinition
      procedure init_sizedefinition is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_sizedefinition';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'SIZEDEFINITION'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_sizedefinition;
        close rcur_typ;
        --get id
        select seq_sizedefinition.nextval into lv_rec_sizedefinition.sizedefinition_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_sizedefinition.code := lv_rec_erp_i_size.sizecode;
        --set missing defaults
      end init_sizedefinition;
    
      procedure update_rec_sizedefinition is
      begin
        --update_rec_sizedefinition
        gv_text                                := 'update_rec_sizedefinition';
        lv_rec_sizedefinition.legacysizecode   := lv_rec_erp_i_size.legacysizecode;
        lv_rec_sizedefinition.width            := lv_rec_erp_i_size.width;
        lv_rec_sizedefinition.length           := lv_rec_erp_i_size.length;
        lv_rec_sizedefinition.unfinishedlength := lv_rec_erp_i_size.unfinishedlength;
        if lv_rec_erp_i_size.unfinishedsizedefinitioncode is null then
          begin
            lv_rec_sizedefinition.unfinishedsizedefinition_id := null;
          end;
        else
          begin
            lv_rec_sizedefinition.unfinishedsizedefinition_id := get_sizeid(lv_rec_erp_i_size.unfinishedsizedefinitioncode,
                                                                            0);
          end;
        end if;
        lv_rec_sizedefinition.reservealternativesize := lv_rec_erp_i_size.reservealternativesize;
        lv_rec_sizedefinition.usedforemblem          := lv_rec_erp_i_size.usedforemblem;
        lv_rec_sizedefinition.systemuser_id          := gv_erp_systemuserid;
        lv_rec_sizedefinition.timestamp              := sysdate;
        lv_rec_sizedefinition.sizegroupingcode_id    := get_sizegroupingid(lv_rec_erp_i_size.sizegroupingcode,
                                                                           lv_rec_erp_i_size.sizegroupingdescription);
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_sizedefinition;
      -------------
    begin
      --process_sizedefinition
      gv_text := 'proc_i_size.process_sizedefinition for sizedefinition code ' ||
                 lv_rec_erp_i_size.sizecode;
      --process_sizedefinition UPDATE
      select sp.*
      into   lv_rec_sizedefinition
      from   sizedefinition sp
      where  sp.code = lv_rec_erp_i_size.sizecode;
      --update_rec_sizedefinition
      update_rec_sizedefinition;
      --update record
      gv_text := 'proc_i_size.process_sizedefinition.update for sizedefinition code ' ||
                 lv_rec_erp_i_size.sizecode;
      update sizedefinition sp
      set    row = lv_rec_sizedefinition
      where  sp.sizedefinition_id = lv_rec_sizedefinition.sizedefinition_id;
    exception
      when no_data_found then
        begin
          --process_sizedefinition INSERT
          init_sizedefinition;
          --update_rec_sizedefinition
          update_rec_sizedefinition;
          --insert record
          gv_text := 'proc_i_size.process_sizedefinition.insert for sizedefinition code ' ||
                     lv_rec_erp_i_size.sizecode;
          insert into sizedefinition values lv_rec_sizedefinition;
        end;
    end process_sizedefinition;
  
    procedure process_sizedefinition_desc is
    begin
      --process_sizedefinition_desc
      gv_text := 'proc_i_size.process_sizedefinition_desc for sizedefinition code ' ||
                 lv_rec_erp_i_size.sizecode;
      --update sizedefinition_desc
      update sizedefinition_desc pd
      set    pd.description = lv_rec_erp_i_size.description,
             pd.systemuser_id = lv_rec_sizedefinition.systemuser_id,
             pd.timestamp = lv_rec_sizedefinition.timestamp
      where  pd.sizedefinition_id = lv_rec_sizedefinition.sizedefinition_id
      and    pd.language_id = gv_languageid;
      if sql%rowcount < 1 then
        raise no_data_found;
      end if;
    exception
      when no_data_found then
        begin
          --insert into sizedefinition_desc
          insert into sizedefinition_desc
            (sizedefinition_id, language_id, description, systemuser_id, timestamp)
          values
            (lv_rec_sizedefinition.sizedefinition_id, gv_languageid, lv_rec_erp_i_size.description,
             lv_rec_sizedefinition.systemuser_id, lv_rec_sizedefinition.timestamp);
        end;
    end process_sizedefinition_desc;
  
    procedure process_sizedefinition_links is
    begin
      --process_sizedefinition_links
      gv_text := 'proc_i_size.process_sizedefinition_links for sizedefinition code ' ||
                 lv_rec_erp_i_size.sizecode;
      begin
        --update record sizedefinition_link
        update sizedefinition_link pk
        set    pk.code = lv_rec_sizedefinition.code,
               pk.legacysizecode = lv_rec_sizedefinition.legacysizecode,
               pk.timestamp = lv_rec_sizedefinition.timestamp,
               pk.systemuser_id = lv_rec_sizedefinition.systemuser_id
        where  pk.sizedefinition_id = lv_rec_sizedefinition.sizedefinition_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link record
            insert into sizedefinition_link
              (sizedefinition_link_id, sizedefinition_id, code, systemuser_id, legacysizecode,
               timestamp)
            values
              (lv_rec_sizedefinition.sizedefinition_id, lv_rec_sizedefinition.sizedefinition_id,
               lv_rec_sizedefinition.code, lv_rec_sizedefinition.systemuser_id,
               lv_rec_sizedefinition.legacysizecode, lv_rec_sizedefinition.timestamp);
          end;
      end;
      begin
        --update record sizedefinition_link_desc
        update sizedefinition_link_desc pld
        set    pld.description = lv_rec_erp_i_size.description,
               pld.systemuser_id = lv_rec_sizedefinition.systemuser_id,
               pld.timestamp = lv_rec_sizedefinition.timestamp
        where  pld.language_id = gv_languageid
        and    pld.sizedefinition_link_id = lv_rec_sizedefinition.sizedefinition_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link desc record
            insert into sizedefinition_link_desc
              (sizedefinition_link_id, language_id, description, systemuser_id, timestamp)
            values
              (lv_rec_sizedefinition.sizedefinition_id, gv_languageid,
               lv_rec_erp_i_size.description, lv_rec_sizedefinition.systemuser_id,
               lv_rec_sizedefinition.timestamp);
          end;
      end;
    end process_sizedefinition_links;
    -------------
  begin
    --proc_i_size
    gv_text := 'proc_i_size process erp_i_size for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_sizedefinition;
          process_sizedefinition_desc;
          process_sizedefinition_links;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_size_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_size fi
            where  fi.transfer_id = f.transfer_id
            and    fi.sizecode = lv_rec_erp_i_size.sizecode)
    and    f.transfer_id < lv_rec_erp_i_size.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_size_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_size zi
      where  zi.sizecode = lv_rec_erp_i_size.sizecode
      and    zi.transfer_id < lv_rec_erp_i_size.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_size_log zix where zix.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid, 'For size ' || lv_rec_erp_i_size.sizecode,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For size ' || lv_rec_erp_i_size.sizecode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For size ' || lv_rec_erp_i_size.sizecode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For size ' || lv_rec_erp_i_size.sizecode, 1, 0);
      end;
  end proc_i_size_one;

  --process proc_i_size
  procedure proc_i_size(fp_transferid in erp_i_size.transfer_id%type, fp_rerun in number default 0) is
  begin
    for psbx in (select eis.sizecode
                 from   erp_i_size eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for psby in (select max(eis.transfer_id) transfer_id
                     from   erp_i_size eis
                     where  eis.sizecode = psbx.sizecode) loop
          begin
            if fp_transferid < psby.transfer_id then
              begin
                update erp_i_size eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_size_one(psby.transfer_id, fp_rerun);
          end;
        end loop; --psby
      end;
    end loop; --psbx
  end proc_i_size;

  --process proc_i_size_all
  procedure proc_i_size_all is
  begin
    for psb in (select l.transfer_id
                from   erp_i_size l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_size(psb.transfer_id);
      end;
    end loop; --b
  end proc_i_size_all;

  --process erp_i_weighingcategory
  procedure proc_i_weigh_one(fp_transferid in erp_i_weighingcategory.transfer_id%type,
                             fp_rerun      in number default 0) is
    lv_rec_erp_i_weighingcategory erp_i_weighingcategory%rowtype;
    lv_rec_weighingcategory       weighingcategory%rowtype;
    lv_log_tablename              varchar2(32) := 'ERP_I_WEIGHINGCATEGORY_LOG';
    lv_process_status             number := 0;
    -------------
    --internal procedure functions from proc_i_weigh
    function read_line return number is
    begin
      --read_line erp_i_weighingcategory
      select eis.*
      into   lv_rec_erp_i_weighingcategory
      from   erp_i_weighingcategory eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_weighingcategory eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.weighingcategorycode = lv_rec_erp_i_weighingcategory.weighingcategorycode
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_weighingcategory is
      -------------
      --internal procedure functions from process_weighingcategory
      procedure init_weighingcategory is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_weighingcategory';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'WEIGHINGCATEGORY'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_weighingcategory;
        close rcur_typ;
        --get id
        select seq_weighingcategory.nextval
        into   lv_rec_weighingcategory.weighingcategory_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_weighingcategory.code := lv_rec_erp_i_weighingcategory.weighingcategorycode;
        --set missing defaults
      end init_weighingcategory;
    
      procedure update_rec_weighingcategory is
      begin
        --update_rec_weighingcategory
        gv_text                                            := 'update_rec_weighingcategory';
        lv_rec_weighingcategory.active                     := lv_rec_erp_i_weighingcategory.active;
        lv_rec_weighingcategory.rewash                     := lv_rec_erp_i_weighingcategory.rewash;
        lv_rec_weighingcategory.legacyweighingcategorycode := lv_rec_erp_i_weighingcategory.legacyweighingcategorycode;
        lv_rec_weighingcategory.turnovergroup_id           := get_turnovergroupid(lv_rec_erp_i_weighingcategory.turnovergroupcode);
        lv_rec_weighingcategory.activity_id                := get_activityid(lv_rec_erp_i_weighingcategory.activitycode);
        lv_rec_weighingcategory.residentiallaundry         := lv_rec_erp_i_weighingcategory.residentiallaundry;
        lv_rec_weighingcategory.extrainput                 := lv_rec_erp_i_weighingcategory.extrainput;
        lv_rec_weighingcategory.registrationunit_id        := get_registrationunitid(lv_rec_erp_i_weighingcategory.registrationunitcode);
        lv_rec_weighingcategory.systemuser_id              := gv_erp_systemuserid;
        lv_rec_weighingcategory.timestamp                  := sysdate;
        if lv_rec_weighingcategory.extrainput = 'Y' then
          lv_rec_weighingcategory.weighinguse := 1;
        else
          lv_rec_weighingcategory.weighinguse := 0;
        end if;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_weighingcategory;
      -------------
    begin
      --process_weighingcategory
      gv_text := 'proc_i_weigh.process_weighingcategory for weighingcategory ' ||
                 lv_rec_erp_i_weighingcategory.weighingcategorycode;
      --process_weighingcategory UPDATE
      select wc.*
      into   lv_rec_weighingcategory
      from   weighingcategory wc
      where  wc.code = lv_rec_erp_i_weighingcategory.weighingcategorycode;
      --update_rec_weighingcategory
      update_rec_weighingcategory;
      --update record
      gv_text := 'proc_i_weigh.process_weighingcategory update for weighingcategory ' ||
                 lv_rec_erp_i_weighingcategory.weighingcategorycode;
      update weighingcategory sp
      set    row = lv_rec_weighingcategory
      where  sp.weighingcategory_id = lv_rec_weighingcategory.weighingcategory_id;
    exception
      when no_data_found then
        begin
          --process_weighingcategory INSERT
          init_weighingcategory;
          --update_rec_weighingcategory
          update_rec_weighingcategory;
          --insert record
          gv_text := 'proc_i_weigh.process_weighingcategory insert for weighingcategory ' ||
                     lv_rec_erp_i_weighingcategory.weighingcategorycode;
          insert into weighingcategory values lv_rec_weighingcategory;
        end;
    end process_weighingcategory;
  
    procedure process_weighingcat_desc(fp_description in weighingcategory_desc.description%type,
                                       fp_languageid  in languages.language_id%type) is
    begin
      begin
        --process_weighingcat_desc
        gv_text := 'proc_i_weigh.process_weighingcat_desc for weighingcategory code ' ||
                   lv_rec_erp_i_weighingcategory.weighingcategorycode;
        --update weighingcategory_desc
        update weighingcategory_desc pd
        set    pd.description = fp_description,
               pd.systemuser_id = lv_rec_weighingcategory.systemuser_id,
               pd.timestamp = lv_rec_weighingcategory.timestamp
        where  pd.weighingcategory_id = lv_rec_weighingcategory.weighingcategory_id
        and    pd.language_id = fp_languageid;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --insert into weighingcategory_desc
            insert into weighingcategory_desc
              (weighingcategory_id, language_id, description, systemuser_id, timestamp)
            values
              (lv_rec_weighingcategory.weighingcategory_id, fp_languageid, fp_description,
               lv_rec_weighingcategory.systemuser_id, lv_rec_weighingcategory.timestamp);
          end;
      end;
      begin
        --update record weighingcategory_link_desc
        update weighingcategory_link_desc pld
        set    pld.description = fp_description,
               pld.systemuser_id = lv_rec_weighingcategory.systemuser_id,
               pld.timestamp = lv_rec_weighingcategory.timestamp
        where  pld.language_id = fp_languageid
        and    pld.weighingcategory_link_id = lv_rec_weighingcategory.weighingcategory_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link desc record
            insert into weighingcategory_link_desc
              (weighingcategory_link_id, language_id, description, systemuser_id, timestamp)
            values
              (lv_rec_weighingcategory.weighingcategory_id, fp_languageid, fp_description,
               lv_rec_weighingcategory.systemuser_id, lv_rec_weighingcategory.timestamp);
          end;
      end;
    end process_weighingcat_desc;
  
    procedure process_weighingcategory_links(fp_languageid in languages.language_id%type) is
    begin
      --process_weighingcategory_links
      gv_text := 'proc_i_weigh.process_weighingcategory_links for weighingcategory code ' ||
                 lv_rec_erp_i_weighingcategory.weighingcategorycode;
      begin
        --update record weighingcategory_link
        update weighingcategory_link pk
        set    pk.code = lv_rec_weighingcategory.code,
               pk.legacyweighingcategorycode = lv_rec_weighingcategory.legacyweighingcategorycode,
               pk.timestamp = lv_rec_weighingcategory.timestamp,
               pk.systemuser_id = lv_rec_weighingcategory.systemuser_id
        where  pk.weighingcategory_id = lv_rec_weighingcategory.weighingcategory_id;
        if sql%rowcount < 1 then
          raise no_data_found;
        end if;
      exception
        when no_data_found then
          begin
            --create link record
            insert into weighingcategory_link
              (weighingcategory_link_id, weighingcategory_id, code, systemuser_id,
               legacyweighingcategorycode, timestamp)
            values
              (lv_rec_weighingcategory.weighingcategory_id,
               lv_rec_weighingcategory.weighingcategory_id, lv_rec_weighingcategory.code,
               lv_rec_weighingcategory.systemuser_id,
               lv_rec_weighingcategory.legacyweighingcategorycode, lv_rec_weighingcategory.timestamp);
          end;
      end;
      --process_weighingcat_desc
      process_weighingcat_desc(lv_rec_erp_i_weighingcategory.description, fp_languageid);
    end process_weighingcategory_links;
  
    procedure process_weighingcategory_tax is
      lv_countryid  country.country_id%type;
      lv_taxgroupid taxgroup.taxgroup_id%type;
    begin
      --process_weighingcategory_tax
      lv_countryid := get_countryid(lv_rec_erp_i_weighingcategory.country);
      gv_text      := 'proc_i_weigh.process_weighingcategory_tax get taxgroup ' ||
                      lv_rec_erp_i_weighingcategory.taxgroupcode || ' for country ' ||
                      lv_rec_erp_i_weighingcategory.country;
      select tx.taxgroup_id
      into   lv_taxgroupid
      from   taxgroup tx
      where  tx.code = lv_rec_erp_i_weighingcategory.taxgroupcode
      and    tx.country_id = lv_countryid;
      begin
        insert into weighingcategorytax
          (weighingcategory_id, country_id, taxgroup_id, systemuser_id, timestamp)
        values
          (lv_rec_weighingcategory.weighingcategory_id, lv_countryid, lv_taxgroupid,
           lv_rec_weighingcategory.systemuser_id, lv_rec_weighingcategory.timestamp);
      exception
        when dup_val_on_index then
          null; -- ok when it already exists
      end;
    end process_weighingcategory_tax;
    -------------
  begin
    --proc_i_weigh
    gv_text := 'proc_i_weigh process erp_i_weighingcategory for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_weighingcategory;
          process_weighingcategory_links(gv_languageid);
          process_weighingcategory_tax;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_weighingcategory_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists
     (select fi.transfer_id
            from   erp_i_weighingcategory fi
            where  fi.transfer_id = f.transfer_id
            and    fi.weighingcategorycode = lv_rec_erp_i_weighingcategory.weighingcategorycode)
    and    f.transfer_id < lv_rec_erp_i_weighingcategory.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_weighingcategory_log
      (transfer_id, text, process_status, timestamp)
      select wz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_weighingcategory wz
      where  wz.transfer_status = 1
      and    wz.transfer_id < lv_rec_erp_i_weighingcategory.transfer_id
      and    wz.weighingcategorycode = lv_rec_erp_i_weighingcategory.weighingcategorycode
      and    not exists
       (select 1 from erp_i_weighingcategory_log wzx where wzx.transfer_id = wz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For weight ' || lv_rec_erp_i_weighingcategory.weighingcategorycode, lv_process_status,
              0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For weight ' || lv_rec_erp_i_weighingcategory.weighingcategorycode, 1,
                  0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For weight ' ||
                   lv_rec_erp_i_weighingcategory.weighingcategorycode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || 'For weight ' ||
                   lv_rec_erp_i_weighingcategory.weighingcategorycode, 1, 0);
      end;
  end proc_i_weigh_one;

  --process proc_i_weigh
  procedure proc_i_weigh(fp_transferid in erp_i_weighingcategory.transfer_id%type,
                         fp_rerun      in number default 0) is
  begin
    for wcax in (select eiw.weighingcategorycode
                 from   erp_i_weighingcategory eiw
                 where  eiw.transfer_id = fp_transferid
                 and    (eiw.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for wcay in (select max(eiw.transfer_id) transfer_id
                     from   erp_i_weighingcategory eiw
                     where  eiw.weighingcategorycode = wcax.weighingcategorycode) loop
          begin
            if fp_transferid < wcay.transfer_id then
              begin
                update erp_i_weighingcategory eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_weigh_one(wcay.transfer_id, fp_rerun);
          end;
        end loop; --wcay
      end;
    end loop; --wcax
  end proc_i_weigh;

  --process proc_i_weigh_all
  procedure proc_i_weigh_all is
  begin
    for wca in (select l.transfer_id
                from   erp_i_weighingcategory l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_weigh(wca.transfer_id);
      end;
    end loop; --c
  end proc_i_weigh_all;

  --process erp_i_supplier
  procedure proc_i_supp_one(fp_transferid in erp_i_supplier.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_supplier erp_i_supplier%rowtype;
    lv_log_tablename      varchar2(32) := 'ERP_I_SUPPLIER_LOG';
    lv_process_status     number := 0;
    -------------
    --internal procedure functions from proc_i_supp
    function read_line return number is
    begin
      --read_line erp_i_supplier
      select eis.*
      into   lv_rec_erp_i_supplier
      from   erp_i_supplier eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_supplier eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.suppliernumber = lv_rec_erp_i_supplier.suppliernumber
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_supplier is
      lv_rec_supplier supplier%rowtype;
      -------------
      --internal procedure functions from process_supplier
      procedure init_supplier is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_supplier';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'SUPPLIER'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_supplier;
        close rcur_typ;
        --get id
        select seq_supplier.nextval into lv_rec_supplier.supplier_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_supplier.suppliernumber := lv_rec_erp_i_supplier.suppliernumber;
        --set missing defaults
        lv_rec_supplier.averageshipmentcosts := 0;
        lv_rec_supplier.sendpurchaseorder    := 0;
      end init_supplier;
    
      procedure update_rec_supplier is
      begin
        --update_rec_supplier
        gv_text                         := 'update_rec_supplier';
        lv_rec_supplier.name            := lv_rec_erp_i_supplier.name;
        lv_rec_supplier.suppliertype    := lv_rec_erp_i_supplier.suppliertype;
        lv_rec_supplier.phone           := lv_rec_erp_i_supplier.phone;
        lv_rec_supplier.fax             := lv_rec_erp_i_supplier.fax;
        lv_rec_supplier.email           := lv_rec_erp_i_supplier.email;
        lv_rec_supplier.website         := lv_rec_erp_i_supplier.website;
        lv_rec_supplier.address_id      := insert_or_update_addressid(lv_rec_supplier.address_id,
                                                                      lv_rec_erp_i_supplier.street,
                                                                      lv_rec_erp_i_supplier.street2,
                                                                      lv_rec_erp_i_supplier.zipcode,
                                                                      lv_rec_erp_i_supplier.city, 'N',
                                                                      null, null, null);
        lv_rec_supplier.country_id      := get_countryid(lv_rec_erp_i_supplier.country);
        lv_rec_supplier.currency_id     := get_currencyid(lv_rec_erp_i_supplier.currencycode);
        lv_rec_supplier.orderformremark := lv_rec_erp_i_supplier.orderformremark;
        lv_rec_supplier.paymentterms    := lv_rec_erp_i_supplier.paymentterms;
        lv_rec_supplier.deliveryterms   := lv_rec_erp_i_supplier.deliveryterms;
        lv_rec_supplier.dateactive      := lv_rec_erp_i_supplier.dateactive;
        lv_rec_supplier.dateinactive    := lv_rec_erp_i_supplier.dateinactive;
        lv_rec_supplier.systemuser_id   := gv_erp_systemuserid;
        lv_rec_supplier.timestamp       := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_supplier;
      -------------
    begin
      --process_supplier
      gv_text := 'proc_i_supp.process_supplier for supplier number ' ||
                 lv_rec_erp_i_supplier.suppliernumber;
      --process_supplier UPDATE
      select sp.*
      into   lv_rec_supplier
      from   supplier sp
      where  sp.suppliernumber = lv_rec_erp_i_supplier.suppliernumber;
      --update_rec_supplier
      update_rec_supplier;
      --update record
      gv_text := 'proc_i_supp.process_supplier update for supplier number ' ||
                 lv_rec_erp_i_supplier.suppliernumber;
      update supplier sp
      set    row = lv_rec_supplier
      where  sp.supplier_id = lv_rec_supplier.supplier_id;
    exception
      when no_data_found then
        begin
          --process_supplier INSERT
          init_supplier;
          --update_rec_supplier
          update_rec_supplier;
          --insert record
          gv_text := 'proc_i_supp.process_supplier insert for supplier number ' ||
                     lv_rec_erp_i_supplier.suppliernumber;
          insert into supplier values lv_rec_supplier;
        end;
    end process_supplier;
    -------------
  begin
    --proc_i_supp
    gv_text := 'proc_i_supp process erp_i_supplier for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_supplier;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_supplier_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_supplier fi
            where  fi.transfer_id = f.transfer_id
            and    fi.suppliernumber = lv_rec_erp_i_supplier.suppliernumber)
    and    f.transfer_id < lv_rec_erp_i_supplier.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_supplier_log
      (transfer_id, text, process_status, timestamp)
      select zs.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_supplier zs
      where  zs.suppliernumber = lv_rec_erp_i_supplier.suppliernumber
      and    zs.transfer_id < lv_rec_erp_i_supplier.transfer_id
      and    zs.transfer_status = 1
      and    not exists
       (select 1 from erp_i_supplier_log zzs where zzs.transfer_id = zs.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For supplier ' || lv_rec_erp_i_supplier.suppliernumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || 'For supplier ' || lv_rec_erp_i_supplier.suppliernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For supplier ' ||
                   lv_rec_erp_i_supplier.suppliernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || 'For supplier ' ||
                   lv_rec_erp_i_supplier.suppliernumber, 1, 0);
      end;
  end proc_i_supp_one;

  --process proc_i_supp
  procedure proc_i_supp(fp_transferid in erp_i_supplier.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pscx in (select eis.suppliernumber
                 from   erp_i_supplier eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eis.transfer_id) transfer_id
                     from   erp_i_supplier eis
                     where  eis.suppliernumber = pscx.suppliernumber) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_supplier eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_supp_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_supp;

  --process proc_i_supp_all
  procedure proc_i_supp_all is
  begin
    for psc in (select l.transfer_id
                from   erp_i_supplier l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_supp(psc.transfer_id);
      end;
    end loop; --c
  end proc_i_supp_all;

  --process erp_i_supplierproduct
  procedure proc_i_suppproduct_one(fp_transferid in erp_i_supplierproduct.transfer_id%type,
                                   fp_rerun      in number default 0) is
    lv_rec_erp_i_supplierproduct erp_i_supplierproduct%rowtype;
    lv_rec_supplierproduct       supplierproduct%rowtype;
    lv_log_tablename             varchar2(32) := 'ERP_I_SUPPLIERPRODUCT_LOG';
    lv_process_status            number := 0;
    -------------
    --internal procedure functions from proc_i_supp
    function read_line return number is
    begin
      --read_line erp_i_supplierproduct
      select eis.*
      into   lv_rec_erp_i_supplierproduct
      from   erp_i_supplierproduct eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_supplierproduct eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.suppliernumber = lv_rec_erp_i_supplierproduct.suppliernumber
      and    eis.supplierproductcode = lv_rec_erp_i_supplierproduct.supplierproductcode
      and    eis.laundryproductcode = lv_rec_erp_i_supplierproduct.laundryproductcode
      and    nvl(eis.laundrysizecode, '-') = nvl(lv_rec_erp_i_supplierproduct.laundrysizecode, '-')
      and    ((eis.suppliersizecode = lv_rec_erp_i_supplierproduct.suppliersizecode) or
            (eis.suppliersizecode is null and
            lv_rec_erp_i_supplierproduct.suppliersizecode is null))
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_supplierproduct is
      -------------
      --internal procedure functions from process_supplierproduct
      procedure init_supplierproduct is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_supplierproduct';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'SUPPLIERPRODUCT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_supplierproduct;
        close rcur_typ;
        --get id
        select seq_supplierproduct.nextval
        into   lv_rec_supplierproduct.supplierproduct_id
        from   dual;
        lv_rec_supplierproduct.supplier_id := get_supplierid(lv_rec_erp_i_supplierproduct.suppliernumber);
        --set default that CANNOT and MAY NOT be updated
        lv_rec_supplierproduct.supplierproductcode := lv_rec_erp_i_supplierproduct.supplierproductcode;
        lv_rec_supplierproduct.suppliersizecode    := lv_rec_erp_i_supplierproduct.suppliersizecode;
        --set missing defaults
      end init_supplierproduct;
    
      procedure update_rec_supplierproduct is
      begin
        --update_rec_supplierproduct
        gv_text                                           := 'update_rec_supplierproduct';
        lv_rec_supplierproduct.supplierproductdescription := lv_rec_erp_i_supplierproduct.supplierproductdescription;
        lv_rec_supplierproduct.deliverydays               := coalesce(lv_rec_erp_i_supplierproduct.deliverydays,
                                                                      lv_rec_supplierproduct.deliverydays,
                                                                      1);
        lv_rec_supplierproduct.minorderqty                := lv_rec_erp_i_supplierproduct.minorderqty;
        lv_rec_supplierproduct.boxquantity                := lv_rec_erp_i_supplierproduct.boxquantity;
        lv_rec_supplierproduct.uniqueitem                 := coalesce(lv_rec_erp_i_supplierproduct.uniqueitem,
                                                                      lv_rec_supplierproduct.uniqueitem,
                                                                      'N');
        lv_rec_supplierproduct.remark                     := lv_rec_erp_i_supplierproduct.remark;
        lv_rec_supplierproduct.active                     := coalesce(lv_rec_erp_i_supplierproduct.active,
                                                                      lv_rec_supplierproduct.active,
                                                                      'Y');
        lv_rec_supplierproduct.systemuser_id              := gv_erp_systemuserid;
        lv_rec_supplierproduct.timestamp                  := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_supplierproduct;
      -------------
    begin
      --process_supplierproduct
      gv_text := 'proc_i_supp.process_supplierproduct for supplier ' ||
                 lv_rec_erp_i_supplierproduct.suppliernumber || ' supplier product ' ||
                 lv_rec_erp_i_supplierproduct.supplierproductcode;
      --get supplier id
      lv_rec_supplierproduct.supplier_id := get_supplierid(lv_rec_erp_i_supplierproduct.suppliernumber);
      --process_supplierproduct UPDATE
      --unique index real table SUPPLIER_ID, SUPPLIERPRODUCTCODE, SUPPLIERSIZECODE
      select sp.*
      into   lv_rec_supplierproduct
      from   supplierproduct sp
      where  sp.supplier_id = lv_rec_supplierproduct.supplier_id
      and    sp.supplierproductcode = lv_rec_erp_i_supplierproduct.supplierproductcode
      and    (sp.suppliersizecode = lv_rec_erp_i_supplierproduct.suppliersizecode or
            (sp.suppliersizecode is null and
            lv_rec_erp_i_supplierproduct.suppliersizecode is null));
      --update_rec_supplierproduct
      update_rec_supplierproduct;
      --update record
      gv_text := 'proc_i_supp.process_supplierproduct update for supplierproduct number ' ||
                 lv_rec_erp_i_supplierproduct.supplierproductcode;
      update supplierproduct sp
      set    row = lv_rec_supplierproduct
      where  sp.supplierproduct_id = lv_rec_supplierproduct.supplierproduct_id;
    exception
      when no_data_found then
        begin
          --process_supplierproduct INSERT
          init_supplierproduct;
          --update_rec_supplierproduct
          update_rec_supplierproduct;
          --insert record
          gv_text := 'proc_i_supp.process_supplierproduct insert for supplierproduct number ' ||
                     lv_rec_erp_i_supplierproduct.supplierproductcode;
          insert into supplierproduct values lv_rec_supplierproduct;
        end;
    end process_supplierproduct;
  
    procedure process_productsizepersupplier is
      lv_rec_productsizepersupplier productsizepersupproduct%rowtype;
    begin
      --process_productsizepersupplier
      --Unique index SUPPLIERPRODUCT_ID, PRODUCT_ID, SIZEDEFINITION_ID
      gv_text                                          := 'proc_i_supp.process_productsizepersupplier for supplier ' ||
                                                          lv_rec_erp_i_supplierproduct.suppliernumber ||
                                                          ' supplier product ' ||
                                                          lv_rec_erp_i_supplierproduct.supplierproductcode;
      lv_rec_productsizepersupplier.supplierproduct_id := lv_rec_supplierproduct.supplierproduct_id;
      lv_rec_productsizepersupplier.product_id         := get_productid(lv_rec_erp_i_supplierproduct.laundryproductcode);
      lv_rec_productsizepersupplier.sizedefinition_id  := get_sizeid(nvl(lv_rec_erp_i_supplierproduct.laundrysizecode,
                                                                         '-'), 0);
      --process process_productsizepersupplier update
      select pspp.*
      into   lv_rec_productsizepersupplier
      from   productsizepersupproduct pspp
      where  pspp.supplierproduct_id = lv_rec_productsizepersupplier.supplierproduct_id
      and    pspp.product_id = lv_rec_productsizepersupplier.product_id
      and    pspp.sizedefinition_id = lv_rec_productsizepersupplier.sizedefinition_id;
      --if it exists, its fine, nothing to be done
    exception
      when no_data_found then
        begin
          --get id
          select seq_productsizepersupproduct.nextval
          into   lv_rec_productsizepersupplier.productsizepersupproduct_id
          from   dual;
          --update_rec_supplierproduct
          lv_rec_productsizepersupplier.supplierproduct_id := lv_rec_supplierproduct.supplierproduct_id;
          lv_rec_productsizepersupplier.product_id         := get_productid(lv_rec_erp_i_supplierproduct.laundryproductcode);
          lv_rec_productsizepersupplier.sizedefinition_id  := get_sizeid(nvl(lv_rec_erp_i_supplierproduct.laundrysizecode,
                                                                             '-'), 0);
          lv_rec_productsizepersupplier.systemuser_id      := gv_erp_systemuserid;
          lv_rec_productsizepersupplier.timestamp          := sysdate;
          --insert record
          gv_text := 'proc_i_suppproduct_one.process_productsizepersupplier insert for supplierproduct number ' ||
                     lv_rec_erp_i_supplierproduct.suppliernumber || ' supplier product ' ||
                     lv_rec_erp_i_supplierproduct.supplierproductcode || ' laundry product ' ||
                     lv_rec_erp_i_supplierproduct.laundryproductcode || ' laundry size ' ||
                     lv_rec_erp_i_supplierproduct.laundrysizecode;
          insert into productsizepersupproduct values lv_rec_productsizepersupplier;
        end;
    end process_productsizepersupplier;
  
    procedure process_supplierproductprice is
    begin
      --process_supplierproductprice
      gv_text := 'process_supplierproductprice';
      --only process price if both price related fields are not null
      if lv_rec_erp_i_supplierproduct.purchaseprice is not null and
         lv_rec_erp_i_supplierproduct.purchaseprice_startdate is not null then
        begin
          --first try to update, if it does not exist create it
          gv_text := 'process_supplierproductprice.update';
          update supplierproductprice spp
          set    spp.purchaseprice = lv_rec_erp_i_supplierproduct.purchaseprice,
                 spp.systemuser_id = gv_erp_systemuserid, spp.timestamp = sysdate
          where  spp.supplierproduct_id = lv_rec_supplierproduct.supplierproduct_id
          and    spp.startdate = trunc(lv_rec_erp_i_supplierproduct.purchaseprice_startdate);
          if sql%rowcount = 0 then
            begin
              --insert a new record
              gv_text := 'process_supplierproductprice.insert';
              insert into supplierproductprice
                (supplierproductprice_id, supplierproduct_id, startdate, purchaseprice,
                 systemuser_id, timestamp)
              values
                (seq_supplierproductprice.nextval, lv_rec_supplierproduct.supplierproduct_id,
                 trunc(lv_rec_erp_i_supplierproduct.purchaseprice_startdate),
                 lv_rec_erp_i_supplierproduct.purchaseprice, gv_erp_systemuserid, sysdate);
            end;
          end if;
        end;
      end if;
    end process_supplierproductprice;
    -------------
  begin
    --proc_i_supp
    gv_text := 'proc_i_supp process erp_i_supplierproduct for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_supplierproduct;
          process_productsizepersupplier;
          process_supplierproductprice;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_supplierproduct_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_supplierproduct fi
            where  fi.transfer_id = f.transfer_id
            and    fi.suppliernumber = lv_rec_erp_i_supplierproduct.suppliernumber
            and    fi.supplierproductcode = lv_rec_erp_i_supplierproduct.supplierproductcode
            and    fi.laundryproductcode = lv_rec_erp_i_supplierproduct.laundryproductcode
            and    nvl(fi.laundrysizecode, '-') =
                   nvl(lv_rec_erp_i_supplierproduct.laundrysizecode, '-')
            and    (fi.suppliersizecode = lv_rec_erp_i_supplierproduct.suppliersizecode or
                  (fi.suppliersizecode is null and
                  lv_rec_erp_i_supplierproduct.suppliersizecode is null)))
    and    f.transfer_id < lv_rec_erp_i_supplierproduct.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_supplierproduct_log
      (transfer_id, text, process_status, timestamp)
      select sp.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_supplierproduct sp
      where  sp.suppliernumber = lv_rec_erp_i_supplierproduct.suppliernumber
      and    sp.supplierproductcode = lv_rec_erp_i_supplierproduct.supplierproductcode
      and    (sp.suppliersizecode = lv_rec_erp_i_supplierproduct.suppliersizecode or
            (sp.suppliersizecode is null and
            lv_rec_erp_i_supplierproduct.suppliersizecode is null))
      and    sp.laundryproductcode = lv_rec_erp_i_supplierproduct.laundryproductcode
      and    nvl(sp.laundrysizecode, '-') = nvl(lv_rec_erp_i_supplierproduct.laundrysizecode, '-')
      and    sp.transfer_id < lv_rec_erp_i_supplierproduct.transfer_id
      and    sp.transfer_status = 1
      and    not exists
       (select 1 from erp_i_supplierproduct_log spx where spx.transfer_id = sp.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For supplier ' || lv_rec_erp_i_supplierproduct.suppliernumber ||
               ' supplier product ' || lv_rec_erp_i_supplierproduct.supplierproductcode,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For supplier ' || lv_rec_erp_i_supplierproduct.suppliernumber ||
                   ' supplier product ' || lv_rec_erp_i_supplierproduct.supplierproductcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For supplier ' ||
                   lv_rec_erp_i_supplierproduct.suppliernumber || ' supplier product ' ||
                   lv_rec_erp_i_supplierproduct.supplierproductcode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || 'For supplier ' ||
                   lv_rec_erp_i_supplierproduct.suppliernumber || ' supplier product ' ||
                   lv_rec_erp_i_supplierproduct.supplierproductcode, 1, 0);
      end;
  end proc_i_suppproduct_one;

  --process erp_i_supplierproduct 
  procedure proc_i_suppproduct(fp_transferid in erp_i_supplierproduct.transfer_id%type,
                               fp_rerun      in number default 0) is
    transferstatus erp_i_supplierproduct.transfer_status%type;
  begin
    --unique index real table SUPPLIER_ID, SUPPLIERPRODUCTCODE, SUPPLIERSIZECODE
    for pscx in (select eis.suppliernumber, eis.supplierproductcode, eis.suppliersizecode,
                        eis.laundryproductcode, eis.laundrysizecode
                 from   erp_i_supplierproduct eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eis.transfer_id) transfer_id
                     from   erp_i_supplierproduct eis
                     where  eis.suppliernumber = pscx.suppliernumber
                     and    eis.supplierproductcode = pscx.supplierproductcode
                     and    ((eis.suppliersizecode = pscx.suppliersizecode) or
                           (eis.suppliersizecode is null and pscx.suppliersizecode is null))
                     and    eis.laundryproductcode = pscx.laundryproductcode
                     and    eis.laundrysizecode = pscx.laundrysizecode) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_supplierproduct eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            select transfer_status
            into   transferstatus
            from   erp_i_supplierproduct
            where  transfer_id = pscy.transfer_id;
            if (transferstatus = 0 or fp_rerun > 0) then
              proc_i_suppproduct_one(pscy.transfer_id, fp_rerun);
            end if;
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_suppproduct;

  --process erp_i_supplierproduct all
  procedure proc_i_suppproduct_all is
  begin
    for spc in (select l.transfer_id
                from   erp_i_supplierproduct l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_suppproduct(spc.transfer_id);
      end;
    end loop; --c
  end proc_i_suppproduct_all;

  --process erp_i_contract
  procedure proc_i_contract_one(fp_transferid in erp_i_contract.transfer_id%type,
                                fp_rerun      in number default 0) is
    lv_rec_erp_i_contract erp_i_contract%rowtype;
    lv_rec_contract       contract%rowtype;
    lv_log_tablename      varchar2(32) := 'ERP_I_CONTRACT_LOG';
    lv_process_status     number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_contract
      select eis.*
      into   lv_rec_erp_i_contract
      from   erp_i_contract eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_contract eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.contractcode = lv_rec_erp_i_contract.contractcode
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_contract is
      -------------
      --internal procedure functions from process_contract
      procedure init_contract is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_contract';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'CONTRACT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_contract;
        close rcur_typ;
        --get id
        select seq_contract.nextval into lv_rec_contract.contract_id from dual;
        --set default that CANNOT and MAY NOT be updated or updated differently
        lv_rec_contract.code     := lv_rec_erp_i_contract.contractcode;
        lv_rec_contract.category := lv_rec_erp_i_contract.category;
        lv_rec_contract.enddate  := lv_rec_erp_i_contract.enddate;
        select st.status_id
        into   lv_rec_contract.status_id
        from   status st
        where  st.statustype = 'CO'
        and    st.code = '20';
        --set missing defaults
        --none for now
      end init_contract;
    
      procedure update_rec_contract is
        lv_cust_currencyid currency.currency_id%type;
      
        procedure check_contract is
        begin
          --check_contract
          /*
          1 = Secondary Contract
          3 = Primary Contract
          4 = Route Service Contract (RSC)
          */
          if lv_rec_contract.category not in (1, 3, 4) then
            begin
              gv_text := 'contract.category = ' || to_char(lv_rec_contract.category) ||
                         ' is not allowed!';
              raise ge_user___exception;
            end;
          end if;
          if lv_rec_contract.category = 4 and lv_rec_contract.customer_link_id is not null then
            begin
              gv_text := 'For route service contract (category = 4) you cannot link a customer. Linking customer ' ||
                         lv_rec_erp_i_contract.customernumber || ' is not allowed!';
              raise ge_user___exception;
            end;
          end if;
          if lv_rec_contract.duration not between 1 and 999 then
            begin
              gv_text := 'erp_i_contract.duration must be between 1 and 999!';
              raise ge_user___exception;
            end;
          end if;
          if lv_rec_contract.currency_id is null then
            begin
              gv_text := 'erp_i_contract.currency cannot be left blank!';
              raise ge_user___exception;
            end;
          elsif nvl(lv_cust_currencyid, lv_rec_contract.currency_id) <> lv_rec_contract.currency_id then
            begin
              gv_text := 'Contract ' || lv_rec_erp_i_contract.primarycontractcode ||
                         ' has another currency then the customer ' ||
                         lv_rec_erp_i_contract.customernumber || ' and that is not allowed!';
              raise ge_user___exception;
            end;
          end if;
          --If system setting gv_contractenddatecontrol=1
          --then Contract start date plus duration must equal end date
          if trim(gv_contractenddatecontrol) = '1' then
            begin
              if add_months(trunc(lv_rec_contract.startdate), lv_rec_contract.duration) <>
                 trunc(lv_rec_contract.enddate) then
                begin
                  lv_rec_contract.enddate := add_months(trunc(lv_rec_contract.startdate),
                                                        lv_rec_contract.duration);
                end;
              end if;
            end;
          else
            begin
              --end date must be last day of the month
              if lv_rec_contract.enddate <> last_day(lv_rec_contract.enddate) then
                begin
                  lv_rec_contract.enddate := last_day(lv_rec_contract.enddate);
                end;
              end if;
            end;
          end if;
          if lv_rec_contract.enddate < lv_rec_erp_i_contract.startdate then
            begin
              gv_text := 'erp_i_contract.enddate < erp_i_contract.startdate and that is not allowed!';
              raise ge_user___exception;
            end;
          end if;
          if nvl(lv_rec_contract.salesemployee1percentage, 0) +
             nvl(lv_rec_contract.salesemployee2percentage, 0) > 100 then
            begin
              gv_text := 'Contract SalesEmployee1Percentage + SalesEmployee2Percentage is more then 100! It is ' ||
                         to_char(nvl(lv_rec_contract.salesemployee1percentage, 0) +
                                 nvl(lv_rec_contract.salesemployee2percentage, 0));
              raise ge_user___exception;
            end;
          end if;
        end check_contract;
      begin
        --update_rec_contract
        gv_text := 'update_rec_contract';
        if lv_rec_erp_i_contract.enddate > lv_rec_contract.enddate then
          lv_rec_contract.enddate := lv_rec_erp_i_contract.enddate;
        end if;
        lv_rec_contract.renewaldate                 := lv_rec_erp_i_contract.enddate;
        lv_rec_contract.description                 := lv_rec_erp_i_contract.contractdescription;
        lv_rec_contract.contracttype_id             := get_contracttypeid(lv_rec_erp_i_contract.contracttypecode,
                                                                          lv_rec_erp_i_contract.contracttypedesc);
        lv_rec_contract.contractdocument            := lv_rec_erp_i_contract.contractdocument;
        lv_rec_contract.salesemployee_id            := get_employeeid(lv_rec_erp_i_contract.salesemployeenumber,
                                                                      null);
        lv_rec_contract.commisionpayablesales       := lv_rec_erp_i_contract.commissionpayablesalesyn;
        lv_rec_contract.accountmanager_id           := get_employeeid(lv_rec_erp_i_contract.accountmanagernumber,
                                                                      null);
        lv_rec_contract.commisionpayableaccmgr      := lv_rec_erp_i_contract.commissionpayableaccmgryn;
        lv_rec_contract.customer_link_id            := get_customerid2(lv_rec_erp_i_contract.customernumber,
                                                                       lv_cust_currencyid);
        lv_rec_contract.owner                       := lv_rec_erp_i_contract.owner;
        lv_rec_contract.address_id                  := insert_or_update_addressid(lv_rec_contract.address_id,
                                                                                  lv_rec_erp_i_contract.owner_street,
                                                                                  null,
                                                                                  lv_rec_erp_i_contract.owner_zipcode,
                                                                                  lv_rec_erp_i_contract.owner_city,
                                                                                  'Y', null,
                                                                                  lv_rec_erp_i_contract.owner_state,
                                                                                  lv_rec_erp_i_contract.owner_county);
        lv_rec_contract.country_id                  := get_countryid(lv_rec_erp_i_contract.owner_countrycode);
        lv_rec_contract.cvrnumber                   := lv_rec_erp_i_contract.cvrnumber;
        lv_rec_contract.phonenumber                 := lv_rec_erp_i_contract.phonenumber;
        lv_rec_contract.signdate                    := lv_rec_erp_i_contract.signdate;
        lv_rec_contract.startdate                   := lv_rec_erp_i_contract.startdate;
        lv_rec_contract.duration                    := lv_rec_erp_i_contract.duration;
        lv_rec_contract.termofnotice                := lv_rec_erp_i_contract.termofnotice;
        lv_rec_contract.terminationdate             := lv_rec_erp_i_contract.terminationdate;
        lv_rec_contract.autextensionperiod          := lv_rec_erp_i_contract.autextensionperiod;
        lv_rec_contract.contactperson_id            := get_contactpersonid(lv_rec_contract.customer_link_id,
                                                                           null,
                                                                           lv_rec_erp_i_contract.customercontactpersonnumber);
        lv_rec_contract.contactpersonname           := lv_rec_erp_i_contract.contactpersonname;
        lv_rec_contract.gainreason_id               := get_gainlostreasonid(lv_rec_erp_i_contract.gainreasoncode,
                                                                            lv_rec_erp_i_contract.gainreasondescription);
        lv_rec_contract.lostreason_id               := get_gainlostreasonid(lv_rec_erp_i_contract.lostreasoncode,
                                                                            lv_rec_erp_i_contract.lostreasondescription);
        lv_rec_contract.gaincompetitor_id           := get_competitorid(lv_rec_erp_i_contract.gaincompetitorcode,
                                                                        lv_rec_erp_i_contract.gaincompetitorname);
        lv_rec_contract.lostcompetitor_id           := get_competitorid(lv_rec_erp_i_contract.lostcompetitorcode,
                                                                        lv_rec_erp_i_contract.lostcompetitorname);
        lv_rec_contract.startdatepriceincrease      := lv_rec_erp_i_contract.startdatepriceincrease;
        lv_rec_contract.updateevery                 := lv_rec_erp_i_contract.updateevery;
        lv_rec_contract.previouspriceincrease       := lv_rec_erp_i_contract.previouspriceincrease;
        lv_rec_contract.nextschedulepriceincrease   := lv_rec_erp_i_contract.nextscheduledpriceincrease;
        lv_rec_contract.agreedpriceindex_id         := get_priceindexid(lv_rec_erp_i_contract.agreedpriceindexcode,
                                                                        lv_rec_erp_i_contract.agreedpriceindexdesc);
        lv_rec_contract.notagreedpriceindex_id      := get_priceindexid(lv_rec_erp_i_contract.notagreedpriceindexcode,
                                                                        lv_rec_erp_i_contract.notagreedpriceindexdesc);
        lv_rec_contract.allownotagreedpricelists    := lv_rec_erp_i_contract.allownotagreedpriceindexyn;
        lv_rec_contract.purchaseorder               := lv_rec_erp_i_contract.purchaseorder;
        lv_rec_contract.purchaseordervalue          := lv_rec_erp_i_contract.purchaseordervalue;
        lv_rec_contract.purchaseorderexpirationdate := lv_rec_erp_i_contract.purchaseorderexpirationdate;
        lv_rec_contract.estimatedweeklysales        := lv_rec_erp_i_contract.estimatedweeklysales;
        lv_rec_contract.remark                      := lv_rec_erp_i_contract.remark;
        lv_rec_contract.systemuser_id               := gv_erp_systemuserid;
        lv_rec_contract.timestamp                   := sysdate;
        lv_rec_contract.renegotiationdate           := lv_rec_erp_i_contract.renegotiationdate;
        lv_rec_contract.warnpriceincrease           := lv_rec_erp_i_contract.warnpriceincrease;
        lv_rec_contract.warndayspriceincrease       := lv_rec_erp_i_contract.warndayspriceincrease;
        lv_rec_contract.currency_id                 := get_currencyid(lv_rec_erp_i_contract.currency);
        lv_rec_contract.email                       := lv_rec_erp_i_contract.email;
        lv_rec_contract.garmentscontract            := lv_rec_erp_i_contract.garmentscontract;
        lv_rec_contract.salesemployee2_id           := get_employeeid(lv_rec_erp_i_contract.salesemployeenumber2,
                                                                      null);
        lv_rec_contract.salesemployee1percentage    := coalesce(lv_rec_erp_i_contract.salesemployee1percentage,
                                                                lv_rec_contract.salesemployee1percentage,
                                                                0);
        lv_rec_contract.salesemployee2percentage    := coalesce(lv_rec_erp_i_contract.salesemployee2percentage,
                                                                lv_rec_contract.salesemployee2percentage,
                                                                0);
        lv_rec_contract.salesleademployee_id        := get_employeeid(lv_rec_erp_i_contract.salesleademployeenumber,
                                                                      null);
        lv_rec_contract.allownoncontractembtemp     := coalesce(lv_rec_erp_i_contract.allownoncontractembtemp,
                                                                lv_rec_contract.allownoncontractembtemp,
                                                                'Y');
        lv_rec_contract.allownoncontractwearerfunc  := coalesce(lv_rec_erp_i_contract.allownoncontractwearerfunc,
                                                                lv_rec_contract.allownoncontractwearerfunc,
                                                                'Y');
        lv_rec_contract.allownoncontractproducts    := coalesce(lv_rec_erp_i_contract.allownoncontractproducts,
                                                                lv_rec_contract.allownoncontractproducts,
                                                                'Y');
        ----EXTRA
        check_contract;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_contract;
      -------------
    begin
      --process_contract
      gv_text := 'proc_i_contract.process_contract for contract code ' ||
                 lv_rec_erp_i_contract.contractcode;
      --process_contract UPDATE
      select sp.*
      into   lv_rec_contract
      from   contract sp
      where  sp.code = lv_rec_erp_i_contract.contractcode;
      --update_rec_contract
      update_rec_contract;
      --update record
      gv_text := 'proc_i_contract.process_contract.update for contract code ' ||
                 lv_rec_erp_i_contract.contractcode;
      update contract sp
      set    row = lv_rec_contract
      where  sp.contract_id = lv_rec_contract.contract_id;
    exception
      when no_data_found then
        begin
          --process_contract INSERT
          init_contract;
          --update_rec_contract
          update_rec_contract;
          --insert record
          gv_text := 'proc_i_contract.process_contract.insert for contract code ' ||
                     lv_rec_erp_i_contract.contractcode;
          insert into contract values lv_rec_contract;
        end;
    end process_contract;
  
    procedure process_contractprepcharge is
    begin
      --process_contractprepcharge
      if (lv_rec_erp_i_contract.generalprepchargestartdate is not null and
         lv_rec_erp_i_contract.generalprepchargeprice is not null) then
        begin
          update contractprice sp
          set    sp.price = lv_rec_erp_i_contract.generalprepchargeprice,
                 sp.systemuser_id = gv_erp_systemuserid, sp.timestamp = sysdate
          where  sp.contract_id = lv_rec_contract.contract_id
          and    sp.category = 6
          and    sp.pricetype = 0
          and    sp.startdate = lv_rec_erp_i_contract.generalprepchargestartdate
          and    sp.reasoncode_id is null
          and    sp.price <> lv_rec_erp_i_contract.generalprepchargeprice;
          --no update then we insert the price
          if sql%rowcount = 0 then
            begin
              insert into contractprice
                (contractprice_id, contract_id, category, pricetype, reasoncode_id, startdate,
                 price, creationuser_id, creationtimestamp, systemuser_id, timestamp)
              values
                (seq_contractprice.nextval, lv_rec_contract.contract_id, 6, 0, null,
                 lv_rec_erp_i_contract.generalprepchargestartdate,
                 lv_rec_erp_i_contract.generalprepchargeprice, gv_erp_systemuserid, sysdate,
                 gv_erp_systemuserid, sysdate);
            exception
              when dup_val_on_index then
                begin
                  null; --no problem did already exist
                end;
            end;
          end if;
        end;
      end if;
    end process_contractprepcharge;
    -------------
  begin
    --proc_i_contract_one
    gv_text := 'proc_i_contract process erp_i_contract for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_contract;
          process_contractprepcharge; --contractpricelist
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_contract_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_contract fi
            where  fi.transfer_id = f.transfer_id
            and    fi.contractcode = lv_rec_erp_i_contract.contractcode)
    and    f.transfer_id < lv_rec_erp_i_contract.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_contract_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_contract zi
      where  zi.contractcode = lv_rec_erp_i_contract.contractcode
      and    zi.transfer_id < lv_rec_erp_i_contract.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_contract_log zix where zix.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For contract ' || lv_rec_erp_i_contract.contractcode, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For contract ' || lv_rec_erp_i_contract.contractcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For contract ' || lv_rec_erp_i_contract.contractcode,
                  1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For contract ' ||
                   lv_rec_erp_i_contract.contractcode, 1, 0);
      end;
  end proc_i_contract_one;

  --process erp_i_contract 
  procedure proc_i_contract(fp_transferid in erp_i_contract.transfer_id%type,
                            fp_rerun      in number default 0) is
  begin
    if gv_contractenddatecontrol is null then
      begin
        --get CONTRACTENDDATECONTROL system setting, which is global so MAX value
        select max(st.value)
        into   gv_contractenddatecontrol
        from   systemsetting st
        where  st.name = 'CONTRACTENDDATECONTROL';
      end;
    end if;
    for psbx in (select eis.contractcode
                 from   erp_i_contract eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for psby in (select max(eis.transfer_id) transfer_id
                     from   erp_i_contract eis
                     where  eis.contractcode = psbx.contractcode) loop
          begin
            if fp_transferid < psby.transfer_id then
              begin
                update erp_i_contract eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_contract_one(psby.transfer_id, fp_rerun);
          end;
        end loop; --psby
      end;
    end loop; --psbx
  end proc_i_contract;

  --process erp_i_contract all
  procedure proc_i_contract_all is
  begin
    gv_contractenddatecontrol := null;
    for psb in (select l.transfer_id
                from   erp_i_contract l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_contract(psb.transfer_id);
      end;
    end loop; --b
  end proc_i_contract_all;

  --process erp_i_contractcustomer
  procedure proc_i_contractcustomer_one(fp_transferid in erp_i_contractcustomer.transfer_id%type,
                                        fp_rerun      in number default 0) is
    lv_rec_erp_i_contractcustomer erp_i_contractcustomer%rowtype;
    lv_rec_contractcustomer       contractcustomer%rowtype;
    lv_log_tablename              varchar2(32) := 'ERP_I_CONTRACTCUSTOMER_LOG';
    lv_process_status             number := 0;
    lv_contract_startdate         contract.startdate%type;
    lv_contract_enddate           contract.enddate%type;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_contractcustomer
      select eis.*
      into   lv_rec_erp_i_contractcustomer
      from   erp_i_contractcustomer eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_contractcustomer eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.contractcode = lv_rec_erp_i_contractcustomer.contractcode
      and    eis.customernumber = lv_rec_erp_i_contractcustomer.customernumber
      and    trunc(eis.startdate) = trunc(lv_rec_erp_i_contractcustomer.startdate)
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_contractcustomer is
      -------------
      --internal procedure functions from process_contractcustomer
      procedure init_contractcustomer is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_contractcustomer';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = upper('contractcustomer')
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_contractcustomer;
        close rcur_typ;
        --get id
        select seq_contractcustomer.nextval
        into   lv_rec_contractcustomer.contractcustomer_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_contractcustomer.contract_id      := get_contractid(lv_rec_erp_i_contractcustomer.contractcode,
                                                                   lv_contract_startdate,
                                                                   lv_contract_enddate);
        lv_rec_contractcustomer.customer_link_id := get_customerid(lv_rec_erp_i_contractcustomer.customernumber);
        --set missing defaults
      end init_contractcustomer;
    
      procedure update_rec_contractcustomer is
        procedure check_contractcustomer is
        begin
          if trunc(lv_rec_erp_i_contractcustomer.startdate) < lv_contract_startdate then
            begin
              gv_text := 'erp_i_contractcustomer.startdate < contract.startdate and that is not allowed!';
              raise ge_user___exception;
            end;
          elsif trunc(lv_rec_erp_i_contractcustomer.enddate) > lv_contract_enddate then
            begin
              gv_text := 'erp_i_contractcustomer.enddate > contract.enddate and that is not allowed!';
              raise ge_user___exception;
            end;
          end if;
        end check_contractcustomer;
      begin
        --update_rec_contractcustomer
        gv_text                                := 'update_rec_contractcustomer';
        lv_rec_contractcustomer.startdate      := trunc(lv_rec_erp_i_contractcustomer.startdate);
        lv_rec_contractcustomer.enddate        := trunc(lv_rec_erp_i_contractcustomer.enddate);
        lv_rec_contractcustomer.systemuser_id  := gv_erp_systemuserid;
        lv_rec_contractcustomer.timestamp      := sysdate;
        lv_rec_contractcustomer.expirationdate := lv_rec_erp_i_contractcustomer.expirationdate;
        lv_rec_contractcustomer.postartdate    := trunc(lv_rec_erp_i_contractcustomer.postartdate);
        lv_rec_contractcustomer.installdate    := trunc(lv_rec_erp_i_contractcustomer.installdate);
        ----EXTRA
        check_contractcustomer;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_contractcustomer;
      -------------
    begin
      --process_contractcustomer
      gv_text := 'proc_i_contractcustomer.process_contractcustomer for contract code ' ||
                 lv_rec_erp_i_contractcustomer.contractcode || ' customer ' ||
                 lv_rec_erp_i_contractcustomer.customernumber;
      --get PK values
      lv_rec_contractcustomer.contract_id      := get_contractid(lv_rec_erp_i_contractcustomer.contractcode,
                                                                 lv_contract_startdate,
                                                                 lv_contract_enddate);
      lv_rec_contractcustomer.customer_link_id := get_customerid(lv_rec_erp_i_contractcustomer.customernumber);
      --process_contractcustomer UPDATE
      --real key for AUJ is CONTRACT_ID, CUSTOMER_LINK_ID (NOT STARTDATE)
      select sp.*
      into   lv_rec_contractcustomer
      from   contractcustomer sp
      where  sp.contract_id = lv_rec_contractcustomer.contract_id
      and    sp.customer_link_id = lv_rec_contractcustomer.customer_link_id;
      --do not update records
    exception
      when no_data_found then
        begin
          --process_contractcustomer INSERT
          init_contractcustomer;
          --update_rec_contractcustomer
          update_rec_contractcustomer;
          --insert record
          gv_text := 'proc_i_contractcustomer.process_contractcustomer.insert for contract code ' ||
                     lv_rec_erp_i_contractcustomer.contractcode || ' customer ' ||
                     lv_rec_erp_i_contractcustomer.customernumber;
          insert into contractcustomer values lv_rec_contractcustomer;
        end;
      when too_many_rows then
        begin
          gv_text := 'there can only be one record for combination of contract code / customer number, now there are more';
          raise ge_user___exception;
        end;
    end process_contractcustomer;
    -------------
  begin
    --proc_i_contractcustomer
    gv_text := 'proc_i_contractcustomer process erp_i_contractcustomer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_contractcustomer;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_contractcustomer_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_contractcustomer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.contractcode = lv_rec_erp_i_contractcustomer.contractcode
            and    fi.customernumber = lv_rec_erp_i_contractcustomer.customernumber
            and    trunc(fi.startdate) = trunc(lv_rec_erp_i_contractcustomer.startdate))
    and    f.transfer_id < lv_rec_erp_i_contractcustomer.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_contractcustomer_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_contractcustomer zi
      where  zi.contractcode = lv_rec_erp_i_contractcustomer.contractcode
      and    zi.customernumber = lv_rec_erp_i_contractcustomer.customernumber
      and    trunc(zi.startdate) = trunc(lv_rec_erp_i_contractcustomer.startdate)
      and    zi.transfer_id < lv_rec_erp_i_contractcustomer.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_contractcustomer_log zix where zix.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For contractcustomer contract ' || lv_rec_erp_i_contractcustomer.contractcode ||
               ' customer ' || lv_rec_erp_i_contractcustomer.customernumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For contractcustomer contract code ' ||
                   lv_rec_erp_i_contractcustomer.contractcode || ' customer ' ||
                   lv_rec_erp_i_contractcustomer.customernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For contractcustomer contract code ' ||
                   lv_rec_erp_i_contractcustomer.contractcode || ' customer ' ||
                   lv_rec_erp_i_contractcustomer.customernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For contractcustomer contract code ' ||
                   lv_rec_erp_i_contractcustomer.contractcode || ' customer ' ||
                   lv_rec_erp_i_contractcustomer.customernumber, 1, 0);
      end;
  end proc_i_contractcustomer_one;

  --process erp_i_contractcustomer
  procedure proc_i_contractcustomer(fp_transferid in erp_i_contractcustomer.transfer_id%type,
                                    fp_rerun      in number default 0) is
  begin
    for psbx in (select eis.contractcode, eis.customernumber, eis.startdate
                 from   erp_i_contractcustomer eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for psby in (select max(eis.transfer_id) transfer_id
                     from   erp_i_contractcustomer eis
                     where  eis.contractcode = psbx.contractcode
                     and    eis.customernumber = psbx.customernumber
                     and    trunc(eis.startdate) = trunc(psbx.startdate)) loop
          begin
            if fp_transferid < psby.transfer_id then
              begin
                update erp_i_contractcustomer eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_contractcustomer_one(psby.transfer_id, fp_rerun);
          end;
        end loop; --psby
      end;
    end loop; --psbx
  end proc_i_contractcustomer;

  --process erp_i_contractcustomer all
  procedure proc_i_contractcustomer_all is
  begin
    for psb in (select l.transfer_id
                from   erp_i_contractcustomer l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_contractcustomer(psb.transfer_id);
      end;
    end loop; --b
  end proc_i_contractcustomer_all;

  --process erp_i_contractpricelist
  procedure proc_i_contractpricelist_one(fp_transferid in erp_i_contractpricelist.transfer_id%type,
                                         fp_rerun      in number default 0) is
    lv_rec_erp_i_contractpricelist erp_i_contractpricelist%rowtype;
    lv_rec_contractpricelist       contractpricelist%rowtype;
    lv_log_tablename               varchar2(32) := 'ERP_I_CONTRACTPRICELIST_LOG';
    lv_contract_startdate          contract.startdate%type;
    lv_contract_enddate            contract.enddate%type;
    lv_process_status              number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_contractpricelist
      select eis.*
      into   lv_rec_erp_i_contractpricelist
      from   erp_i_contractpricelist eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_contractpricelist eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.contractcode = lv_rec_erp_i_contractpricelist.contractcode
      and    eis.generalpricelistcode = lv_rec_erp_i_contractpricelist.generalpricelistcode
      and    eis.generalpricetype = lv_rec_erp_i_contractpricelist.generalpricetype
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_contractpricelist is
      -------------
      --internal procedure functions from process_contractpricelist
      procedure init_contractpricelist is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_contractpricelist';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = upper('contractpricelist')
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_contractpricelist;
        close rcur_typ;
        --get id
        select seq_contractpricelist.nextval
        into   lv_rec_contractpricelist.contractpricelist_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated
        select seq_contractpricelist.nextval
        into   lv_rec_contractpricelist.contractpricelist_id
        from   dual;
        lv_rec_contractpricelist.contract_id         := get_contractid(lv_rec_erp_i_contractpricelist.contractcode,
                                                                       lv_contract_startdate,
                                                                       lv_contract_enddate);
        lv_rec_contractpricelist.generalpricelist_id := get_generalpricelistid(lv_rec_erp_i_contractpricelist.generalpricelistcode,
                                                                               lv_rec_erp_i_contractpricelist.generalpricetype);
        lv_rec_contractpricelist.pricetype           := lv_rec_erp_i_contractpricelist.pricetype;
        --set missing defaults
        lv_rec_contractpricelist.agreed := 'Y';
      end init_contractpricelist;
    
      procedure update_rec_contractpricelist is
      begin
        --update_rec_contractpricelist
        gv_text                                := 'update_rec_contractpricelist';
        lv_rec_contractpricelist.startdate     := trunc(lv_rec_erp_i_contractpricelist.startdate);
        lv_rec_contractpricelist.enddate       := trunc(lv_rec_erp_i_contractpricelist.enddate);
        lv_rec_contractpricelist.systemuser_id := gv_erp_systemuserid;
        lv_rec_contractpricelist.timestamp     := sysdate;
        if (lv_rec_erp_i_contractpricelist.generalpricelistcode =
           lv_rec_erp_i_contractpricelist.contractcode and
           lv_rec_erp_i_contractpricelist.usage = 1) then
          begin
            --gets a higher priority adding 1 to the provided priority
            lv_rec_contractpricelist.priority := lv_rec_erp_i_contractpricelist.priority + 1;
          end;
        else
          begin
            lv_rec_contractpricelist.priority := lv_rec_erp_i_contractpricelist.priority;
          end;
        end if;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_contractpricelist;
      -------------
    begin
      --process_contractpricelist
      gv_text := 'proc_i_contractpricelist.process_contractpricelist for contract code ' ||
                 lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
                 lv_rec_erp_i_contractpricelist.generalpricelistcode;
      --get key values
      lv_rec_contractpricelist.contract_id         := get_contractid(lv_rec_erp_i_contractpricelist.contractcode,
                                                                     lv_contract_startdate,
                                                                     lv_contract_enddate);
      lv_rec_contractpricelist.generalpricelist_id := get_generalpricelistid(lv_rec_erp_i_contractpricelist.generalpricelistcode,
                                                                             lv_rec_erp_i_contractpricelist.generalpricetype);
      --process_contractpricelist UPDATE
      --CONTRACT_ID, GENERALPRICELIST_ID, STARTDATE, PRICETYPE
      --not checking startdate, not allowed multiple dates
      select sp.*
      into   lv_rec_contractpricelist
      from   contractpricelist sp
      where  sp.contract_id = lv_rec_contractpricelist.contract_id
      and    sp.generalpricelist_id = lv_rec_contractpricelist.generalpricelist_id
      and    sp.pricetype = lv_rec_erp_i_contractpricelist.pricetype;
      -- update only pricelistdescription only if 
      -- the existing record contains a different start date
      -- and different pricelistdescription
      if trunc(lv_rec_contractpricelist.startdate) <>
         trunc(lv_rec_erp_i_contractpricelist.startdate) then
        begin
          --check if we need to update the generalpricelist description, in this case only
          update generalpricelist gl
          set    gl.description = lv_rec_erp_i_contractpricelist.pricelistdescription,
                 gl.systemuser_id = gv_erp_systemuserid, gl.timestamp = sysdate
          where  gl.generalpricelist_id = lv_rec_contractpricelist.generalpricelist_id
          and    gl.description <>
                 nvl(lv_rec_erp_i_contractpricelist.pricelistdescription, gl.description);
        end;
      end if;
    exception
      when no_data_found then
        begin
          --process_contractpricelist INSERT
          init_contractpricelist;
          --update_rec_contractpricelist
          update_rec_contractpricelist;
          --insert record
          gv_text := 'proc_i_contractpricelist.process_contractpricelist.insert for  for contract code ' ||
                     lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
                     lv_rec_erp_i_contractpricelist.generalpricelistcode;
          insert into contractpricelist values lv_rec_contractpricelist;
        end;
    end process_contractpricelist;
    -------------
  begin
    --proc_i_contractpricelist
    gv_text := 'proc_i_contractpricelist process erp_i_contractpricelist for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_contractpricelist;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_contractpricelist_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully'
    where  exists
     (select fi.transfer_id
            from   erp_i_contractpricelist fi
            where  fi.transfer_id = f.transfer_id
            and    fi.contractcode = lv_rec_erp_i_contractpricelist.contractcode
            and    fi.generalpricelistcode = lv_rec_erp_i_contractpricelist.generalpricelistcode
            and    fi.generalpricetype = lv_rec_erp_i_contractpricelist.generalpricetype)
    and    f.transfer_id < lv_rec_erp_i_contractpricelist.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_contractpricelist_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_contractpricelist zi
      where  zi.contractcode = lv_rec_erp_i_contractpricelist.contractcode
      and    zi.generalpricelistcode = lv_rec_erp_i_contractpricelist.generalpricelistcode
      and    zi.generalpricetype = lv_rec_erp_i_contractpricelist.generalpricetype
      and    zi.transfer_id < lv_rec_erp_i_contractpricelist.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_contractpricelist_log zix where zix.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For contractpricelist for contract code ' ||
               lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
               lv_rec_erp_i_contractpricelist.generalpricelistcode, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For contractpricelist for contract code ' ||
                   lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
                   lv_rec_erp_i_contractpricelist.generalpricelistcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For contractpricelist for contract code ' ||
                   lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
                   lv_rec_erp_i_contractpricelist.generalpricelistcode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For contractpricelist for contract code ' ||
                   lv_rec_erp_i_contractpricelist.contractcode || ' general price list ' ||
                   lv_rec_erp_i_contractpricelist.generalpricelistcode, 1, 0);
      end;
  end proc_i_contractpricelist_one;

  --process proc_i_contractpricelist
  procedure proc_i_contractpricelist(fp_transferid in erp_i_contractpricelist.transfer_id%type,
                                     fp_rerun      in number default 0) is
  begin
    for psbx in (select eis.contractcode, eis.generalpricelistcode, eis.generalpricetype,
                        eis.startdate
                 from   erp_i_contractpricelist eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for psby in (select max(eis.transfer_id) transfer_id
                     from   erp_i_contractpricelist eis
                     where  eis.contractcode = psbx.contractcode
                     and    eis.generalpricelistcode = psbx.generalpricelistcode
                     and    eis.generalpricetype = psbx.generalpricetype) loop
          begin
            if fp_transferid < psby.transfer_id then
              begin
                update erp_i_contractpricelist eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_contractpricelist_one(psby.transfer_id, fp_rerun);
          end;
        end loop; --psby
      end;
    end loop; --psbx
  end proc_i_contractpricelist;

  --process proc_i_contractpricelist_all
  procedure proc_i_contractpricelist_all is
  begin
    for psb in (select l.transfer_id
                from   erp_i_contractpricelist l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_contractpricelist(psb.transfer_id);
      end;
    end loop; --b
  end proc_i_contractpricelist_all;

  --process erp_i_customer
  procedure proc_i_cust_one(fp_transferid in erp_i_customer.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_customer       customer%rowtype;
    lv_rec_erp_i_customer erp_i_customer%rowtype;
    lv_old_debtorid       customer.debtor_id%type;
    lv_log_tablename      varchar2(32) := 'ERP_I_CUSTOMER_LOG';
    lv_process_status     number := 0;
    lv_qualitygradeid     qualitygrade.qualitygrade_id%type;
    -------------
    --internal procedure functions from proc_i_cust
    function read_line return number is
    begin
      --read_line erp_i_customer
      select eis.*
      into   lv_rec_erp_i_customer
      from   erp_i_customer eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status in (0, -1) or fp_rerun > 0);
      --update line as read
      update erp_i_customer eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.customernumber = lv_rec_erp_i_customer.customernumber
      and    eis.transfer_status = 0;
      commit;
      if lv_rec_erp_i_customer.transfer_status = -1 then
        return - 1;
      else
        return 0;
      end if;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure add_automaticflag is
      lv_flagid flag.flag_id%type;
    begin
      --add_automaticflag for the inactive customer 'Customer no longer active'
      gv_text := 'add_automaticflag';
      --get the automatic flag
      select max(af.flag_id) into lv_flagid from automaticflag af where af.automaticflag_id = 18;
      --if flag exists flag non uniqueitems without that flag
      if lv_flagid is not null then
        for aa in (select un.uniqueitem_id
                   from   wearer w
                   join   weareremployment we
                   on     we.wearer_id = w.wearer_id
                   join   uniqueitemnonpool un
                   on     un.weareremployment_id = we.weareremployment_id
                   where  w.customer_id = lv_rec_customer.customer_id
                   and    not exists (select 1
                           from   uniqueitemflag uf
                           where  uf.uniqueitem_id = un.uniqueitem_id
                           and    uf.flag_id = lv_flagid)) loop
          begin
            insert into uniqueitemflag
              (uniqueitem_id, flag_id, startdate, systemuser_id, timestamp)
            values
              (aa.uniqueitem_id, lv_flagid, lv_rec_erp_i_customer.dateinactive, gv_erp_systemuserid,
               sysdate);
          end;
        end loop; --aa
      end if;
    end add_automaticflag;
  
    procedure process_customer is
      lv_businessunitid businessunit.businessunit_id%type;
      lv_defaultinvbu   businessunit.businessunit_id%type;
      lv_plantid        plant.plant_id%type;
      -------------
      --internal procedure functions from process_customer
      procedure init_customer is
        lv_query varchar2(2000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_customer';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'CUSTOMER'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_customer;
        close rcur_typ;
        --get id
        select seq_customer.nextval into lv_rec_customer.customer_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_customer.customernumber := lv_rec_erp_i_customer.customernumber;
        --remark the businessunit CANNOT be updated!!
        lv_rec_customer.defaultbusinessunit_id        := lv_businessunitid;
        lv_rec_customer.defaultinvoicebusinessunit_id := lv_defaultinvbu;
        --set missing defaults
        lv_old_debtorid                            := null;
        lv_rec_customer.occupancyfromstockcount    := 'Y';
        lv_rec_customer.soilcount                  := 'N';
        lv_rec_customer.internetordering           := 'N';
        lv_rec_customer.importoccupancyhht         := 'N';
        lv_rec_customer.codegarmentsuniquely       := 'Y';
        lv_rec_customer.daysnoprepcharge           := 0;
        lv_rec_customer.garmentrentspecification   := 1;
        lv_rec_customer.swingsuitdelivery          := 'N';
        lv_rec_customer.usesgarmentdispenser       := 'N';
        lv_rec_customer.lockermanagement           := 'N';
        lv_rec_customer.daysspecialgrade           := 0;
        lv_rec_customer.allowprepchargepertemplate := 'N';
        lv_rec_customer.emblemspecification        := 1;
        lv_rec_customer.allownegativestockcount    := 'N';
        lv_rec_customer.chargewashfirstissue       := 'N';
        lv_rec_customer.allowautomaticsales        := 'N';
        lv_rec_customer.outscansort                := 0;
        lv_rec_customer.chargerepairs              := 2;
        lv_rec_customer.chargerepaircog            := 2;
        lv_rec_customer.variableservices           := 2;
        lv_rec_customer.minimuminvoiceamount       := 0;
        lv_rec_customer.correctshortages           := 'N';
        lv_rec_customer.standardqtydefinition      := 1;
        lv_rec_customer.correctoverdeliveries      := 'N';
        lv_rec_customer.invoicefrequency_id        := 0;
        lv_rec_customer.chargeresidualvalue        := 'Y';
        lv_rec_customer.rentperiod                 := 0;
        lv_rec_customer.splitinvoices              := 0;
        lv_rec_customer.usesbundles                := 'N';
        lv_rec_customer.scansondeliverynote        := 3;
        lv_rec_customer.directinvdeliveries        := 'N';
        lv_rec_customer.directinvcleanweights      := 'N';
        lv_rec_customer.directinvsoilweights       := 'N';
        lv_rec_customer.directinvminimumamount     := 0;
        lv_rec_customer.associationtype            := 0;
        lv_rec_customer.usecoverpage               := 'N';
        lv_rec_customer.bulkpacking                := 'N';
        lv_rec_customer.ownedcontainer             := 0;
        lv_rec_customer.edimethod                  := 0;
        lv_rec_customer.insurancepricetype         := 1;
        lv_rec_customer.delnoteforbulkputupitems   := 0;
        lv_rec_customer.passerbycustomer           := 'N';
        lv_rec_customer.customerrelated            := 1;
        begin
          --fill qualitygrades customer
          lv_qualitygradeid                  := get_qualitygradeid('U');
          lv_rec_customer.firstdaysgrade_id  := lv_qualitygradeid;
          lv_rec_customer.firstissuegrade_id := lv_qualitygradeid;
          lv_rec_customer.qualitygrade_id    := lv_qualitygradeid;
        exception
          when no_data_found then
            null; --no problem if U does not exists cannot be default.
        end;
      end init_customer;
      procedure update_rec_customer is
        -------------
        --internal procedure functions from update_rec_customer
        function get_bill2customerid return customer.debtor_id%type is
          procedure copy_customerbilltoinfo is
            lv_rec_customerbillinginfo customerbillinginfo%rowtype;
          begin
            --customer billinginfo
            gv_text := 'process_customerbillinginfo.copy_customerbilltoinfo for customer number ' ||
                       lv_rec_erp_i_customer.customernumber || ' from customer old debtor ' ||
                       to_char(lv_old_debtorid);
            select *
            into   lv_rec_customerbillinginfo
            from   customerbillinginfo cbi
            where  cbi.customer_id = lv_old_debtorid;
            --update customer id
            lv_rec_customerbillinginfo.customer_id := lv_rec_customer.customer_id;
            insert into customerbillinginfo values lv_rec_customerbillinginfo;
          end copy_customerbilltoinfo;
        begin
          --if not own bill to delete bill to record
          if lv_rec_erp_i_customer.customernumber <> lv_rec_erp_i_customer.billtocustomernumber then
            begin
              delete from customerbillinginfo cbi
              where  cbi.customer_id = lv_rec_customer.customer_id;
            end;
          elsif nvl(lv_old_debtorid, lv_rec_customer.customer_id) <> lv_rec_customer.customer_id then
            begin
              --copy_customerbilltoinfo
              copy_customerbilltoinfo;
            end;
          end if;
          if lv_rec_erp_i_customer.billtocustomernumber = lv_rec_erp_i_customer.customernumber then
            begin
              return lv_rec_customer.customer_id;
            end;
          else
            begin
              return get_customerid(lv_rec_erp_i_customer.billtocustomernumber);
            end;
          end if;
        end get_bill2customerid;
      
        function get_mastercustomerid(fp_masternumber in customer.customernumber%type)
          return customer.masteraccount_id%type is
        begin
          --get master account number
          gv_text := ' get master acount customer number ' ||
                     lv_rec_erp_i_customer.masteraccountnumber;
          if fp_masternumber is null then
            begin
              --meaning master account is null, then it is its own master account
              lv_rec_customer.masteraccount := 1; -->not applicable
              return lv_rec_customer.customer_id;
            end;
          else
            begin
              if lv_rec_erp_i_customer.masteraccountnumber = lv_rec_erp_i_customer.customernumber then
                begin
                  lv_rec_customer.masteraccount := 2; -->self master account
                  return lv_rec_customer.customer_id;
                end;
              else
                begin
                  lv_rec_customer.masteraccount := 3; -->belongs to a parent master account
                  return get_customerid(fp_masternumber);
                end;
              end if;
            end;
          end if;
        end get_mastercustomerid;
      
        function get_customerrankingid(fp_customerrankingnumber in customerranking.ranking%type)
          return customerranking.customerranking_id%type is
          lv_customerrankingid customerranking.customerranking_id%type;
        begin
          --get_customerrankingid
          gv_text := ' get customerranking for number ' || fp_customerrankingnumber;
          if fp_customerrankingnumber is null then
            return null;
          else
            begin
              select cr.customerranking_id
              into   lv_customerrankingid
              from   customerranking cr
              where  cr.ranking = fp_customerrankingnumber;
              return lv_customerrankingid;
            end;
          end if;
        end get_customerrankingid;
      
        function get_serviceteam(fp_serviceteamcode in serviceteam.code%type)
          return serviceteam.serviceteam_id%type is
          lv_serviceteamid serviceteam.serviceteam_id%type;
        begin
          --get_serviceteam
          gv_text := ' get serviceteam for code ' || fp_serviceteamcode;
          if fp_serviceteamcode is null then
            return null;
          else
            begin
              select st.serviceteam_id
              into   lv_serviceteamid
              from   serviceteam st
              where  st.code = fp_serviceteamcode
              and    st.plant_id = lv_plantid;
            end;
          end if;
          return lv_serviceteamid;
        end get_serviceteam;
        -------------
      begin
        --update_rec_customer
        --fill variables
        gv_text := 'process_customer.update_rec_customer';
        --
        lv_rec_customer.legacycustomernumber   := lv_rec_erp_i_customer.legacycustomernumber;
        lv_rec_customer.name                   := lv_rec_erp_i_customer.customername;
        lv_rec_customer.legalname              := lv_rec_erp_i_customer.legalname;
        lv_rec_customer.debtor_id              := get_bill2customerid;
        lv_rec_customer.searchname             := coalesce(lv_rec_erp_i_customer.searchname,
                                                           lv_rec_customer.searchname,
                                                           substr(upper(trim(lv_rec_customer.name)),
                                                                   1, 10));
        lv_rec_customer.dateactive             := lv_rec_erp_i_customer.dateactive;
        lv_rec_customer.dateinactive           := coalesce(lv_rec_erp_i_customer.dateinactive,
                                                           lv_rec_customer.dateinactive, gv_endddate);
        lv_rec_customer.active                 := lv_rec_erp_i_customer.active;
        lv_rec_customer.mailaddress_id         := insert_or_update_addressid(lv_rec_customer.mailaddress_id,
                                                                             lv_rec_erp_i_customer.mailaddress,
                                                                             lv_rec_erp_i_customer.mailaddress2,
                                                                             lv_rec_erp_i_customer.mailzipcode,
                                                                             lv_rec_erp_i_customer.mailcity,
                                                                             'N', null,
                                                                             lv_rec_erp_i_customer.mailstate,
                                                                             null);
        lv_rec_customer.country_id             := get_countryid(lv_rec_erp_i_customer.country);
        lv_rec_customer.email                  := lv_rec_erp_i_customer.email;
        lv_rec_customer.phoneno                := coalesce(lv_rec_erp_i_customer.phoneno,
                                                           lv_rec_customer.phoneno, '-');
        lv_rec_customer.faxno                  := coalesce(lv_rec_erp_i_customer.faxno,
                                                           lv_rec_customer.faxno, '-');
        lv_rec_customer.language_id            := get_languageid(lv_rec_erp_i_customer.languagecode);
        lv_rec_customer.marketsegment_id       := get_marketsegmentid(lv_rec_erp_i_customer.marketsegmentcode);
        lv_rec_customer.salesarea_id           := get_salesareaid(lv_rec_erp_i_customer.salesareacode);
        lv_rec_customer.chain_id               := get_chainid(lv_rec_erp_i_customer.chaincode);
        lv_rec_customer.masteraccount_id       := get_mastercustomerid(lv_rec_erp_i_customer.masteraccountnumber);
        lv_rec_customer.remark                 := lv_rec_erp_i_customer.remark;
        lv_rec_customer.currency_id            := nvl(get_currencyid(lv_rec_erp_i_customer.currencycode),
                                                      lv_rec_customer.currency_id);
        lv_rec_customer.cocnumber              := coalesce(lv_rec_erp_i_customer.cocnumber,
                                                           lv_rec_customer.cocnumber, '0');
        lv_rec_customer.pnnumber               := coalesce(lv_rec_erp_i_customer.pnnumber, '0');
        lv_rec_customer.customerranking_id     := get_customerrankingid(lv_rec_erp_i_customer.customerranking);
        lv_rec_customer.visitaddress_id        := insert_or_update_addressid(lv_rec_customer.visitaddress_id,
                                                                             lv_rec_erp_i_customer.visitaddress,
                                                                             lv_rec_erp_i_customer.visitaddress2,
                                                                             lv_rec_erp_i_customer.visitzipcode,
                                                                             lv_rec_erp_i_customer.visitcity,
                                                                             'N', null,
                                                                             lv_rec_erp_i_customer.visitstate,
                                                                             null);
        lv_rec_customer.taxable                := coalesce(lv_rec_erp_i_customer.taxable,
                                                           lv_rec_customer.taxable, 'Y');
        lv_rec_customer.vatnumber              := lv_rec_erp_i_customer.vatnumber;
        lv_rec_customer.sendinvoiceto := case
                                           when (lv_rec_erp_i_customer.sendinvoiceto =
                                                lv_rec_erp_i_customer.billtocustomernumber and
                                                lv_rec_erp_i_customer.customernumber <>
                                                lv_rec_erp_i_customer.billtocustomernumber) or
                                                (lv_rec_erp_i_customer.customernumber =
                                                lv_rec_erp_i_customer.billtocustomernumber) then
                                            1
                                           else
                                            0
                                         end;
        lv_rec_customer.extraname1             := lv_rec_erp_i_customer.extraname1;
        lv_rec_customer.extraname2             := lv_rec_erp_i_customer.extraname2;
        lv_rec_customer.invoiceaddress_id      := insert_or_update_addressid(lv_rec_customer.invoiceaddress_id,
                                                                             lv_rec_erp_i_customer.invoiceaddress,
                                                                             lv_rec_erp_i_customer.invoiceaddress2,
                                                                             lv_rec_erp_i_customer.invoicezipcode,
                                                                             lv_rec_erp_i_customer.invoicecity,
                                                                             'Y', null,
                                                                             lv_rec_erp_i_customer.invoicestate,
                                                                             null);
        lv_rec_customer.paymenttype            := lv_rec_erp_i_customer.paymenttype;
        lv_rec_customer.paymentmethod          := coalesce(lv_rec_erp_i_customer.paymentmethod,
                                                           lv_rec_customer.paymentmethod, 1);
        lv_rec_customer.ilnnumber              := lv_rec_erp_i_customer.ilnnumber;
        lv_rec_customer.serviceemployee_id     := get_employeeid(lv_rec_erp_i_customer.salesemployee1,
                                                                 lv_plantid);
        lv_rec_customer.siccode                := lv_rec_erp_i_customer.siccode;
        lv_rec_customer.systemuser_id          := gv_erp_systemuserid;
        lv_rec_customer.timestamp              := sysdate;
        lv_rec_customer.commoncustomer_id      := get_customerid(lv_rec_erp_i_customer.commoncustomernumber);
        lv_rec_customer.returnlinen            := coalesce(lv_rec_erp_i_customer.returnlinen,
                                                           lv_rec_customer.returnlinen, 0);
        lv_rec_customer.serviceteam_id         := get_serviceteam(lv_rec_erp_i_customer.serviceteamcode);
        lv_rec_customer.returngarments         := coalesce(lv_rec_erp_i_customer.returngarments,
                                                           lv_rec_customer.returngarments, 0);
        lv_rec_customer.customermarkinggarment := lv_rec_erp_i_customer.customermarkinggarment;
        lv_rec_customer.codelabellayout_id     := get_labellayout(lv_rec_erp_i_customer.codelabellayout,
                                                                  1);
        lv_rec_customer.namelabellayout_id     := get_labellayout(lv_rec_erp_i_customer.namelabellayout,
                                                                  2);
        lv_rec_customer.garmentinsurance       := coalesce(lv_rec_erp_i_customer.garmentinsurance,
                                                           lv_rec_customer.garmentinsurance, 0);
        lv_rec_customer.invoicecopies          := coalesce(lv_rec_erp_i_customer.invoicecopies,
                                                           lv_rec_customer.invoicecopies, 1);
        lv_rec_customer.communicationmethod_id := coalesce(get_communicationmethodid(lv_rec_erp_i_customer.communicationmethod),
                                                           lv_rec_customer.communicationmethod_id,
                                                           get_communicationmethodid('-'));
        lv_rec_customer.deliverynotelayout_id  := coalesce(get_formlayout(lv_rec_erp_i_customer.deliverynotelayout,
                                                                          'DN'),
                                                           lv_rec_customer.deliverynotelayout_id,
                                                           get_formlayout('1', 'DN'));
        lv_rec_customer.invoicelayout_id       := coalesce(get_formlayout(lv_rec_erp_i_customer.invoicelayoutcode,
                                                                          'IN'),
                                                           lv_rec_customer.invoicelayout_id,
                                                           get_formlayout('1', 'IN'));
        if nvl(lv_rec_erp_i_customer.invoicecurrencycode, lv_rec_erp_i_customer.currencycode) =
           lv_rec_erp_i_customer.currencycode then
          begin
            lv_rec_customer.usespecificinvoicecurrency := 0;
            lv_rec_customer.invoicecurrency_id         := null;
          end;
        else
          begin
            lv_rec_customer.usespecificinvoicecurrency := 1;
            lv_rec_customer.invoicecurrency_id         := get_currencyid(lv_rec_erp_i_customer.invoicecurrencycode);
          end;
        end if;
        if lv_rec_erp_i_customer.dateinactive < to_date('31-12-2099', 'DD-MM-YYYY') then
          begin
            add_automaticflag;
          end;
        end if;
        lv_rec_customer.chargelosscharge     := coalesce(lv_rec_erp_i_customer.chargelosscharge,
                                                         lv_rec_customer.chargelosscharge, 'N');
        lv_rec_customer.orderingstockroom_id := get_stockroomid(lv_rec_erp_i_customer.defaultstockroomcode);
        lv_rec_customer.nationalaccount_id   := get_nationalaccountid(lv_rec_erp_i_customer.nationalaccountcode);
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_customer;
    
      procedure add_customeractivities is
      begin
        --add_customeractivities
        gv_text := 'add_customeractivities based upon businessunitactivities';
        insert into customeractivities
          (customer_id, processbusinessunit_id, activity_id, invoicebusinessunit_id, systemuser_id,
           timestamp, invoicefrequency_id)
          select lv_rec_customer.customer_id, bua.businessunit_id, bua.activity_id,
                 lv_rec_customer.defaultinvoicebusinessunit_id, gv_erp_systemuserid, sysdate,
                 lv_rec_customer.invoicefrequency_id
          from   businessunitactivities bua
          where  bua.businessunit_id = lv_rec_customer.defaultbusinessunit_id;
      end add_customeractivities;
      -------------
    begin
      --process_customer UPDATE
      gv_text := 'businessunit code ' || lv_rec_erp_i_customer.businessunit;
      select bu.plant_id, bu.businessunit_id
      into   lv_plantid, lv_businessunitid
      from   businessunit bu
      where  bu.code = lv_rec_erp_i_customer.businessunit;
      --get inv businessunit code
      gv_text := 'default invoice businessunit code ' ||
                 nvl(lv_rec_erp_i_customer.defaultinvbu, lv_rec_erp_i_customer.businessunit);
      select bu.businessunit_id
      into   lv_defaultinvbu
      from   businessunit bu
      where  bu.code = nvl(lv_rec_erp_i_customer.defaultinvbu, lv_rec_erp_i_customer.businessunit);
      gv_text := 'proc_i_cust.process_customer for customer number ' ||
                 lv_rec_erp_i_customer.customernumber;
      select cu.*
      into   lv_rec_customer
      from   customer cu
      where  cu.customernumber = lv_rec_erp_i_customer.customernumber;
      lv_old_debtorid := lv_rec_customer.debtor_id;
      --update_rec_customer
      update_rec_customer;
      --update record
      gv_text := 'proc_i_cust.process_customer update for customer ' ||
                 lv_rec_erp_i_customer.customernumber;
      update customer cu
      set    row = lv_rec_customer
      where  cu.customer_id = lv_rec_customer.customer_id;
    exception
      when no_data_found then
        begin
          --init_customer
          init_customer;
          --update_rec_customer
          update_rec_customer;
          --insert into customer
          gv_text := 'proc_i_cust.process_customer insert new customer ' ||
                     lv_rec_erp_i_customer.customernumber;
          insert into customer values lv_rec_customer;
          --add customer activities
          add_customeractivities;
        end;
    end process_customer;
  
    procedure process_customerbillinginfo is
      lv_rec_customerbillinginfo customerbillinginfo%rowtype;
      procedure init_customerbillinginfo is
        lv_query varchar2(2000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init_customerbillinginfo
        --init fill the record with all default values
        gv_text := 'init_CUSTOMERBILLINGINFO';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'CUSTOMERBILLINGINFO'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_customerbillinginfo;
        close rcur_typ;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_customerbillinginfo.customer_id := lv_rec_customer.customer_id;
        --set missing defaults
        lv_rec_customerbillinginfo.attachinvoicecopies   := 'N';
        lv_rec_customerbillinginfo.creditsqueezeperc     := 0;
        lv_rec_customerbillinginfo.consolidatedinvoice   := 'N';
        lv_rec_customerbillinginfo.consolidatedreportinv := 'N';
        lv_rec_customerbillinginfo.creditlimit           := 0;
        lv_rec_customerbillinginfo.delinquentmarkafter   := 0;
        lv_rec_customerbillinginfo.highestbalance        := 0;
        lv_rec_customerbillinginfo.statementcopies       := 0;
        lv_rec_customerbillinginfo.statementpercustomer  := 'N';
      end init_customerbillinginfo;
    
      procedure update_customerbillinginfo is
      begin
        --update_customerbillinginfo 
        lv_rec_customerbillinginfo.financechargeputon    := coalesce(lv_rec_erp_i_customer.financechargeputon,
                                                                     lv_rec_customerbillinginfo.financechargeputon,
                                                                     1);
        lv_rec_customerbillinginfo.financechargedays     := coalesce(lv_rec_erp_i_customer.financechargedays,
                                                                     lv_rec_customerbillinginfo.financechargedays,
                                                                     0);
        lv_rec_customerbillinginfo.paymentterms_id       := get_paymenttermsid(lv_rec_erp_i_customer.paymenttermscode);
        lv_rec_customerbillinginfo.paybycustomer         := coalesce(lv_rec_erp_i_customer.paybycustomer,
                                                                     lv_rec_customerbillinginfo.paybycustomer,
                                                                     0);
        lv_rec_customerbillinginfo.paybycustomer_link_id := get_customerid(lv_rec_erp_i_customer.paybycustomernumber,
                                                                           1);
        lv_rec_customerbillinginfo.statementlayout_id    := coalesce(get_formlayout(lv_rec_erp_i_customer.statementlayoutcode,
                                                                                    'ST'),
                                                                     lv_rec_customerbillinginfo.statementlayout_id,
                                                                     get_formlayout('1', 'ST'));
        lv_rec_customerbillinginfo.statementfrequency_id := coalesce(lv_rec_erp_i_customer.statementfrequency,
                                                                     lv_rec_customerbillinginfo.statementfrequency_id,
                                                                     0);
        lv_rec_customerbillinginfo.sendstatement         := coalesce(lv_rec_erp_i_customer.sendstatement,
                                                                     lv_rec_customerbillinginfo.sendstatement,
                                                                     0);
        lv_rec_customerbillinginfo.sendstatementbyemail  := coalesce(lv_rec_erp_i_customer.sendstatementbyemail,
                                                                     lv_rec_customerbillinginfo.sendstatementbyemail,
                                                                     'N');
        lv_rec_customerbillinginfo.timestamp             := sysdate;
        lv_rec_customerbillinginfo.systemuser_id         := gv_erp_systemuserid;
      end update_customerbillinginfo;
    begin
      --process_customerbillinginfo
      gv_text := 'process_customerbillinginfofor customer number ' ||
                 lv_rec_erp_i_customer.customernumber;
      select cbi.*
      into   lv_rec_customerbillinginfo
      from   customerbillinginfo cbi
      where  cbi.customer_id = lv_rec_customer.debtor_id;
      --update customerbillinginfo
      update_customerbillinginfo;
      --update customerbillinginfo 
      gv_text := 'update customerbillinginfo';
      update customerbillinginfo cbi
      set    row = lv_rec_customerbillinginfo
      where  cbi.customer_id = lv_rec_customer.debtor_id;
    exception
      when no_data_found then
        begin
          --init_customerbillinginfo
          init_customerbillinginfo;
          --update customerbillinginfo
          update_customerbillinginfo;
          --insert into customerbillinginfo
          gv_text := 'insert into customerbillinginfo';
          insert into customerbillinginfo values lv_rec_customerbillinginfo;
        end;
    end process_customerbillinginfo;
  
    procedure process_customerbillingcomment is
    begin
      --process_customerbillingcomment billingcommentinvoice
      gv_text := 'process_customerbillingcomment billingcommentinvoice';
      if lv_rec_erp_i_customer.billingcommentinvoice is null then
        begin
          delete from customerbillingcomment cbi
          where  cbi.customer_id = lv_rec_customer.customer_id
          and    cbi.type = 1; --invoice
        end;
      else
        begin
          update customerbillingcomment cbc
          set    cbc.description = lv_rec_erp_i_customer.billingcommentinvoice,
                 cbc.systemuser_id = gv_erp_systemuserid, cbc.timestamp = sysdate
          where  cbc.customer_id = lv_rec_customer.customer_id
          and    cbc.type = 1 --invoice
          and    cbc.startdate = lv_rec_erp_i_customer.dateactive;
          if (sql%rowcount = 0 and lv_rec_erp_i_customer.billingcommentinvoice is not null) then
            begin
              insert into customerbillingcomment
                (customer_id, timestamp, systemuser_id, enddate, startdate, description, type)
              values
                (lv_rec_customer.customer_id, sysdate, gv_erp_systemuserid,
                 lv_rec_erp_i_customer.dateinactive, lv_rec_erp_i_customer.dateactive,
                 lv_rec_erp_i_customer.billingcommentinvoice, 1);
            end;
          end if;
        end;
      end if;
      if lv_rec_erp_i_customer.billingcommentstatement is null then
        begin
          delete from customerbillingcomment cbi
          where  cbi.customer_id = lv_rec_customer.customer_id
          and    cbi.type = 2; --statement
        end;
      else
        begin
          --process_customerbillingcomment billingcommentstatement
          gv_text := 'process_customerbillingcomment billingcommentstatement';
          update customerbillingcomment cbc
          set    cbc.description = lv_rec_erp_i_customer.billingcommentstatement,
                 cbc.systemuser_id = gv_erp_systemuserid, cbc.timestamp = sysdate
          where  cbc.customer_id = lv_rec_customer.customer_id
          and    cbc.type = 2 --statement
          and    cbc.startdate = lv_rec_erp_i_customer.dateactive;
          if (sql%rowcount = 0 and lv_rec_erp_i_customer.billingcommentstatement is not null) then
            begin
              insert into customerbillingcomment
                (customer_id, timestamp, systemuser_id, enddate, startdate, description, type)
              values
                (lv_rec_customer.customer_id, sysdate, gv_erp_systemuserid,
                 lv_rec_erp_i_customer.dateinactive, lv_rec_erp_i_customer.dateactive,
                 lv_rec_erp_i_customer.billingcommentstatement, 2);
            end;
          end if;
        end;
      end if;
    end process_customerbillingcomment;
  
    procedure process_customer_link is
    begin
      --process_customer_link
      gv_text := 'proc_i_cust.process_customer_link for customer number ' ||
                 lv_rec_erp_i_customer.customernumber;
      update customer_link cl
      set    cl.name = lv_rec_erp_i_customer.customername,
             cl.legacycustomernumber = lv_rec_erp_i_customer.legacycustomernumber,
             cl.languagecode = lv_rec_erp_i_customer.languagecode,
             cl.systemuser_id = gv_erp_systemuserid, cl.timestamp = sysdate
      where  cl.customer_id = lv_rec_customer.customer_id;
      if sql%rowcount = 0 then
        begin
          insert into customer_link
            (customer_link_id, customer_id, customernumber, name, systemuser_id,
             legacycustomernumber, timestamp, languagecode)
          values
            (lv_rec_customer.customer_id, lv_rec_customer.customer_id,
             lv_rec_customer.customernumber, lv_rec_customer.name, gv_erp_systemuserid,
             lv_rec_customer.legacycustomernumber, sysdate, lv_rec_erp_i_customer.languagecode);
        end;
      end if;
    end process_customer_link;
  
    procedure process_customercoverpageinfo is
      lv_rec_customercoverpage customercoverpageinfo%rowtype;
      --internal procedure functions from process_customercoverpageinfo
      procedure init_customercoverpageinfo is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_customercoverpageinfo';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'CUSTOMERCOVERPAGEINFO'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_customercoverpage;
        close rcur_typ;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_customercoverpage.customer_id := lv_rec_customer.customer_id;
        --set missing defaults
      end init_customercoverpageinfo;
    
      procedure update_customercoverpageinfo is
      begin
        --update values customercoverpageinfo
        gv_text                                := 'update_customercoverpageinfo';
        lv_rec_customercoverpage.name          := lv_rec_erp_i_customer.coverpage_name;
        lv_rec_customercoverpage.extraname1    := lv_rec_erp_i_customer.coverpage_extraname1;
        lv_rec_customercoverpage.extraname2    := lv_rec_erp_i_customer.coverpage_extraname2;
        lv_rec_customercoverpage.contactperson := lv_rec_erp_i_customer.coverpage_contactperson;
        lv_rec_customercoverpage.address_id    := insert_or_update_addressid(lv_rec_customercoverpage.address_id,
                                                                             lv_rec_erp_i_customer.coverpage_address,
                                                                             lv_rec_erp_i_customer.coverpage_address2,
                                                                             lv_rec_erp_i_customer.coverpage_zipcode,
                                                                             lv_rec_erp_i_customer.coverpage_city,
                                                                             'N', null, null, null);
        lv_rec_customercoverpage.country_id    := get_countryid(lv_rec_erp_i_customer.coverpage_country);
        lv_rec_customercoverpage.systemuser_id := gv_erp_systemuserid;
        lv_rec_customercoverpage.timestamp     := sysdate;
        --update customer use cover page check box
        gv_text := 'update customer use cover page check box';
        update customer c
        set    c.usecoverpage = 'Y'
        where  c.usecoverpage = 'N'
        and    c.customer_id = lv_rec_customer.customer_id;
      end update_customercoverpageinfo;
    begin
      --process_customercoverpageinfo
      gv_text := 'proc_i_cust.process_customercoverpageinfo for customer number ' ||
                 lv_rec_erp_i_customer.customernumber;
      --Only insert cover page info when the fields are not null!
      if lv_rec_erp_i_customer.coverpage_name is not null then
        begin
          --get current record
          select ccp.*
          into   lv_rec_customercoverpage
          from   customercoverpageinfo ccp
          where  ccp.customer_id = lv_rec_customer.customer_id;
          --get updated values
          update_customercoverpageinfo;
          --update record
          gv_text := 'proc_i_cust.process_customercoverpageinfo update for customer number ' ||
                     lv_rec_erp_i_customer.customernumber;
          update customercoverpageinfo
          set    row = lv_rec_customercoverpage
          where  customer_id = lv_rec_customercoverpage.customer_id;
        exception
          when no_data_found then
            begin
              --init_customercoverpageinfo;
              init_customercoverpageinfo;
              --update values
              update_customercoverpageinfo;
              --insert
              gv_text := 'proc_i_cust.process_customercoverpageinfo insert for customer number ' ||
                         lv_rec_erp_i_customer.customernumber;
              insert into customercoverpageinfo values lv_rec_customercoverpage;
            end;
        end;
      else
        begin
          update customer c
          set    c.usecoverpage = 'N'
          where  c.usecoverpage = 'Y'
          and    c.customer_id = lv_rec_customer.customer_id;
        end;
      end if;
    end process_customercoverpageinfo;
  
    procedure process_customergeneral is
    begin
      --process_customergeneral
      gv_text := 'process_customergeneral';
      insert into customergeneral
        (customer_id, nongarmentchargeresidualvalue, nongarmentchargelosscharge, systemuser_id,
         timestamp)
      values
        (lv_rec_customer.customer_id, nvl(lv_rec_customer.chargeresidualvalue, 'N'),
         nvl(lv_rec_customer.chargelosscharge, 'N'), gv_erp_systemuserid, sysdate);
    exception
      when dup_val_on_index then
        null; --when its already there we leave it as is
    end process_customergeneral;
    -------------
  begin
    --proc_i_cust
    gv_text := 'proc_i_cust process erp_i_customer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_customer;
          if lv_rec_customer.customer_id = lv_rec_customer.debtor_id then
            process_customerbillinginfo;
          end if;
          process_customerbillingcomment;
          process_customer_link;
          process_customercoverpageinfo;
          process_customergeneral;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_customer_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_customer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_customer.customernumber)
    and    f.transfer_id < lv_rec_erp_i_customer.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_customer_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_customer zz
      where  zz.customernumber = lv_rec_erp_i_customer.customernumber
      and    zz.transfer_id < lv_rec_erp_i_customer.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_customer_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid, 'For customer ' || lv_rec_customer.customernumber,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer ' || lv_rec_customer.customernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' || lv_rec_customer.customernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' || lv_rec_customer.customernumber, 1,
                  0);
      end;
  end proc_i_cust_one;

  --process proc_i_cust
  procedure proc_i_cust(fp_transferid in erp_i_customer.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber
                 from   erp_i_customer eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status in (0, -1) or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_customer eic
                     where  eic.customernumber = pscx.customernumber) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_customer eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_cust_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_cust;

  --process proc_i_cust_all
  procedure proc_i_cust_all is
  begin
    for pcd in (select l.transfer_id
                from   erp_i_customer l
                where  l.transfer_status in (0, -1)
                order  by l.transfer_id) loop
      begin
        proc_i_cust(pcd.transfer_id);
      end;
    end loop; --d
  end proc_i_cust_all;

  --process proc_i_customerprepcharge_one
  procedure proc_i_customerprepcharge_one(fp_transferid in erp_i_customerprepcharge.transfer_id%type,
                                          fp_rerun      in number default 0) is
    lv_rec_erp_i_custprepcharge erp_i_customerprepcharge%rowtype;
    lv_rec_customerprepcharge   customerprepcharge%rowtype;
    lv_log_tablename            varchar2(32) := 'ERP_I_CUSTOMERPREPCHARGE_LOG';
    lv_process_status           number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_customerprepcharge
      select eis.*
      into   lv_rec_erp_i_custprepcharge
      from   erp_i_customerprepcharge eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_customerprepcharge eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.customernumber = lv_rec_erp_i_custprepcharge.customernumber
      and    eis.startdate = lv_rec_erp_i_custprepcharge.startdate
      and    nvl(eis.reasoncode, 'NULL') = nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL')
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_customerprepcharge is
      -------------
      --internal procedure functions from process_customerprepcharge
      procedure init_customerprepcharge is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_customerprepcharge';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'CUSTOMERPREPCHARGE'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_customerprepcharge;
        close rcur_typ;
        --get id
        select seq_customerprepcharge.nextval
        into   lv_rec_customerprepcharge.customerprepcharge_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated, part of key
        lv_rec_customerprepcharge.customer_id   := get_customerid(lv_rec_erp_i_custprepcharge.customernumber);
        lv_rec_customerprepcharge.startdate     := lv_rec_erp_i_custprepcharge.startdate;
        lv_rec_customerprepcharge.reasoncode_id := get_reasoncodeid(lv_rec_erp_i_custprepcharge.reasoncode);
        --set missing defaults
        --none for now
      end init_customerprepcharge;
    
      procedure update_rec_customerprepcharge is
      begin
        --update_rec_customerprepcharge
        gv_text                                 := 'update_rec_customerprepcharge';
        lv_rec_customerprepcharge.price         := lv_rec_erp_i_custprepcharge.price;
        lv_rec_customerprepcharge.systemuser_id := gv_erp_systemuserid;
        lv_rec_customerprepcharge.timestamp     := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_customerprepcharge;
      -------------
    begin
      --process_customerprepchargeprice
      gv_text := 'proc_i_customerprepcharge.process_customerprepchargeprice for customer ' ||
                 lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
                 nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL');
      --get customer id
      lv_rec_customerprepcharge.customer_id := get_customerid(lv_rec_erp_i_custprepcharge.customernumber);
      if lv_rec_erp_i_custprepcharge.reasoncode = 'REMOVE' then
        begin
          --we will remove the prepcharges for this customer
          delete from customerprepcharge cs
          where  cs.customer_id = lv_rec_customerprepcharge.customer_id;
        end;
      else
        begin
          --get reasoncode_id
          lv_rec_customerprepcharge.reasoncode_id := get_reasoncodeid(lv_rec_erp_i_custprepcharge.reasoncode);
          --process_customerprepchargeprice UPDATE
          select sp.*
          into   lv_rec_customerprepcharge
          from   customerprepcharge sp
          where  sp.customer_id = lv_rec_customerprepcharge.customer_id
          and    sp.startdate = lv_rec_erp_i_custprepcharge.startdate
          and    (sp.reasoncode_id = lv_rec_customerprepcharge.reasoncode_id or
                (sp.reasoncode_id is null and lv_rec_customerprepcharge.reasoncode_id is null));
          --update_rec_customerprepcharge
          update_rec_customerprepcharge;
          --update record
          gv_text := 'proc_i_customerprepcharge.update for customer ' ||
                     lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
                     nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL');
          update customerprepcharge sp
          set    row = lv_rec_customerprepcharge
          where  sp.customerprepcharge_id = lv_rec_customerprepcharge.customerprepcharge_id;
        exception
          when no_data_found then
            begin
              --customerprepcharge INSERT
              init_customerprepcharge;
              --update_rec_customerprepcharge
              update_rec_customerprepcharge;
              --insert record
              gv_text := 'proc_i_customerprepcharge.insert for customer ' ||
                         lv_rec_erp_i_custprepcharge.customernumber ||
                         nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL');
              insert into customerprepcharge values lv_rec_customerprepcharge;
            end;
        end;
      end if;
    end process_customerprepcharge;
  
    procedure customer_chargeprepcharge is
    begin
      --customer_chargeprepcharge
      gv_text := 'customer_chargeprepcharge';
      if lv_rec_erp_i_custprepcharge.reasoncode = 'REMOVE' then
        begin
          update customer c
          set    c.chargeprecharges = 'N', c.timestamp = sysdate,
                 c.systemuser_id = gv_erp_systemuserid
          where  c.customer_id = lv_rec_customerprepcharge.customer_id
          and    nvl(c.chargeprecharges, 'X') <> 'N';
        end;
      else
        begin
          update customer c
          set    c.chargeprecharges = 'Y', c.timestamp = sysdate,
                 c.systemuser_id = gv_erp_systemuserid
          where  c.customer_id = lv_rec_customerprepcharge.customer_id
          and    nvl(c.chargeprecharges, 'X') <> 'Y';
        end;
      end if;
    end customer_chargeprepcharge;
  begin
    --proc_i_CUSTOMERPREPCHARGE_one
    gv_text := 'proc_i_customerprepcharge process erp_i_customerprepcharge for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_customerprepcharge;
          customer_chargeprepcharge;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_customerprepcharge_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists
     (select fi.transfer_id
            from   erp_i_customerprepcharge fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_custprepcharge.customernumber
            and    fi.startdate = lv_rec_erp_i_custprepcharge.startdate
            and    nvl(fi.reasoncode, 'NULL') = nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL'))
    and    f.transfer_id < lv_rec_erp_i_custprepcharge.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_customerprepcharge_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_customerprepcharge zi
      where  zi.customernumber = lv_rec_erp_i_custprepcharge.customernumber
      and    zi.startdate = lv_rec_erp_i_custprepcharge.startdate
      and    nvl(zi.reasoncode, 'NULL') = nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL')
      and    zi.transfer_id < lv_rec_erp_i_custprepcharge.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_customerprepcharge_log epl where epl.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer ' || lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
               nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL'), lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customerprepcharge for customer ' ||
                   lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
                   nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL'), 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customerprepcharge for customer ' ||
                   lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
                   nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL'), 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customerprepcharge for customer ' ||
                   lv_rec_erp_i_custprepcharge.customernumber || ' reasoncode ' ||
                   nvl(lv_rec_erp_i_custprepcharge.reasoncode, 'NULL'), 1, 0);
      end;
  end proc_i_customerprepcharge_one;

  --process erp_i_customerprepcharge
  procedure proc_i_customerprepcharge(fp_transferid in erp_i_customerprepcharge.transfer_id%type,
                                      fp_rerun      in number default 0) is
  begin
    for lcpx in (select eip.customernumber, eip.startdate, eip.reasoncode
                 from   erp_i_customerprepcharge eip
                 where  eip.transfer_id = fp_transferid
                 and    (eip.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for lcpy in (select max(eis.transfer_id) transfer_id
                     from   erp_i_customerprepcharge eis
                     where  eis.customernumber = lcpx.customernumber
                     and    eis.startdate = lcpx.startdate
                     and    nvl(eis.reasoncode, 'NULL') = nvl(lcpx.reasoncode, 'NULL')) loop
          begin
            if fp_transferid < lcpy.transfer_id then
              begin
                update erp_i_customerprepcharge eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_customerprepcharge_one(lcpy.transfer_id, fp_rerun);
          end;
        end loop; --lcpy
      end;
    end loop; --lcpx
  end proc_i_customerprepcharge;

  --process erp_i_customerprepcharge
  procedure proc_i_customerprepcharge_all is
  begin
    for lcp in (select l.transfer_id
                from   erp_i_customerprepcharge l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_customerprepcharge(lcp.transfer_id);
      end;
    end loop; --lcp
  end proc_i_customerprepcharge_all;

  --process erp_i_customerspecialcharge
  procedure proc_i_custspecialcharge_one(fp_transferid in erp_i_customerspecialcharge.transfer_id%type,
                                         fp_rerun      in number default 0) is
    lv_rec_erp_i_custspecialcharge erp_i_customerspecialcharge%rowtype;
    lv_log_tablename               varchar2(32) := 'ERP_I_CUSTSPECIALCHARGE_LOG';
    lv_process_status              number := 0;
    -------------
    --internal procedure functions from proc_i_custspecialcharge_one
    function read_line return number is
    begin
      --read_line erp_i_custspecialcharge
      select eis.*
      into   lv_rec_erp_i_custspecialcharge
      from   erp_i_customerspecialcharge eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_customerspecialcharge eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_custspecialcharge.customernumber
      and    eis.specialchargecode = lv_rec_erp_i_custspecialcharge.specialchargecode
      and    eis.startdate = lv_rec_erp_i_custspecialcharge.startdate;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_custspecialcharge is
      lv_customerid      customer.customer_id%type;
      lv_specialchargeid specialcharge.specialcharge_id%type;
      procedure create_upd_custspecialchargeprice is
      begin
        --create_upd_custspecialchargeprice
        gv_text := 'update customerspecialchargeprice';
        update customerspecialchargeprice cscp
        set    cscp.price = lv_rec_erp_i_custspecialcharge.price,
               cscp.percentage = lv_rec_erp_i_custspecialcharge.percentage,
               cscp.minimumamount = lv_rec_erp_i_custspecialcharge.minimumamount,
               cscp.maximumamount = lv_rec_erp_i_custspecialcharge.maximumamount,
               cscp.systemuser_id = gv_erp_systemuserid, cscp.timestamp = sysdate
        where  cscp.customer_id = lv_customerid
        and    cscp.specialcharge_id = lv_specialchargeid
        and    cscp.startdate = lv_rec_erp_i_custspecialcharge.startdate;
        if sql%rowcount = 0 then
          begin
            --record did not yet exist so we create a new record
            gv_text := 'insert customerspecialchargeprice';
            insert into customerspecialchargeprice
              (customerspecialchargeprice_id, customer_id, specialcharge_id, startdate, price,
               percentage, minimumamount, maximumamount, systemuser_id, timestamp, creationuser_id,
               creationtimestamp)
            values
              (seq_customerspecialchargeprice.nextval, lv_customerid, lv_specialchargeid,
               lv_rec_erp_i_custspecialcharge.startdate, lv_rec_erp_i_custspecialcharge.price,
               lv_rec_erp_i_custspecialcharge.percentage,
               lv_rec_erp_i_custspecialcharge.minimumamount,
               lv_rec_erp_i_custspecialcharge.maximumamount, gv_erp_systemuserid, sysdate,
               gv_erp_systemuserid, sysdate);
          end;
        end if;
      end create_upd_custspecialchargeprice;
    
      procedure check_pricelistpercustomer is
        lv_counter number;
      begin
        --check_pricelistpercustomer
        select count(1)
        into   lv_counter
        from   pricelistpercustomer plp
        where  plp.customer_id = lv_customerid
        and    plp.generalpricelist_id is null
        and    plp.pricetype = 10;
        if lv_counter = 0 then
          begin
            insert into pricelistpercustomer
              (pricelistpercustomer_id, customer_id, pricetype, priority, generalpricelist_id,
               dateactive, dateinactive, systemuser_id, timestamp)
              select seq_pricelistpercustomer.nextval, c.customer_id, 10, 1, null, trunc(sysdate),
                     to_date('31-12-2099', 'dd-mm-yyyy'), gv_erp_systemuserid, sysdate
              from   customer c
              where  c.customer_id = lv_customerid;
          end;
        end if;
      end check_pricelistpercustomer;
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_custspecialcharge.customernumber);
      --get specialcharge id
      if upper(lv_rec_erp_i_custspecialcharge.specialchargecode) = 'REMOVE' then
        begin
          --as agreed we will remove all customer specialcharges
          delete from customerspecialcharge csp where csp.customer_id = lv_customerid;
        end;
      else
        begin
          lv_specialchargeid := get_specialchargeid(lv_rec_erp_i_custspecialcharge.specialchargecode);
          --insert if not exist
          gv_text := 'insert into customerspecialcharge';
          insert into customerspecialcharge
            (customer_id, specialcharge_id, systemuser_id, timestamp)
            select lv_customerid, lv_specialchargeid, gv_erp_systemuserid, sysdate
            from   dual
            where  not exists (select 1
                    from   customerspecialcharge csc
                    where  csc.customer_id = lv_customerid
                    and    csc.specialcharge_id = lv_specialchargeid);
          --check_pricelistpercustomer
          check_pricelistpercustomer;
          --create_upd_custspecialchargeprice
          create_upd_custspecialchargeprice;
        end;
      end if;
    end process_custspecialcharge;
    -------------
  begin
    --proc_i_nonbuday
    gv_text := 'Process erp_i_custspecialcharge for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_custspecialcharge;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_custspecialcharge_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_customerspecialcharge fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_custspecialcharge.customernumber
            and    fi.specialchargecode = lv_rec_erp_i_custspecialcharge.specialchargecode
            and    fi.startdate = lv_rec_erp_i_custspecialcharge.startdate)
    and    f.transfer_id < lv_rec_erp_i_custspecialcharge.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_custspecialcharge_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_customerspecialcharge zz
      where  zz.customernumber = lv_rec_erp_i_custspecialcharge.customernumber
      and    zz.specialchargecode = lv_rec_erp_i_custspecialcharge.specialchargecode
      and    zz.startdate = lv_rec_erp_i_custspecialcharge.startdate
      and    zz.transfer_id < lv_rec_erp_i_custspecialcharge.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_custspecialcharge_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer ' || lv_rec_erp_i_custspecialcharge.customernumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer ' || lv_rec_erp_i_custspecialcharge.customernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' ||
                   lv_rec_erp_i_custspecialcharge.customernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' ||
                   lv_rec_erp_i_custspecialcharge.customernumber, 1, 0);
      end;
  end proc_i_custspecialcharge_one;

  --process erp_i_custspecialcharge
  procedure proc_i_custspecialcharge(fp_transferid in erp_i_customerspecialcharge.transfer_id%type,
                                     fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.specialchargecode, eic.startdate
                 from   erp_i_customerspecialcharge eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_customerspecialcharge eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.specialchargecode = pscx.specialchargecode
                     and    eic.startdate = pscx.startdate) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_customerspecialcharge eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_custspecialcharge_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_custspecialcharge;

  --process proc_i_custspecialcharge
  procedure proc_i_custspecialcharge_all is
  begin
    for pdg in (select l.transfer_id
                from   erp_i_customerspecialcharge l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        --process erp data        
        proc_i_custspecialcharge(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_custspecialcharge_all;

  --process erp_i_tempgarmentrentstop
  procedure proc_i_tempgarmrentstop_one(fp_transferid in erp_i_tempgarmentrentstop.transfer_id%type,
                                        fp_rerun      in number default 0) is
    lv_rec_erp_i_tempgarmrentstop erp_i_tempgarmentrentstop%rowtype;
    lv_log_tablename              varchar2(32) := 'ERP_I_TEMPGARMENTRENTSTOP_LOG';
    lv_process_status             number := 0;
    -------------
    --internal procedure functions from proc_i_tempgarmrentstop_one
    function read_line return number is
    begin
      --read_line erp_i_tempgarmrentstop
      select eis.*
      into   lv_rec_erp_i_tempgarmrentstop
      from   erp_i_tempgarmentrentstop eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_tempgarmentrentstop eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_tempgarmrentstop.customernumber
      and    eis.startyear = lv_rec_erp_i_tempgarmrentstop.startyear
      and    eis.startweek = lv_rec_erp_i_tempgarmrentstop.startweek;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_tempgarmentrentstop is
      lv_customerid        customer.customer_id%type;
      lv_tempgarmrntstopid temporarygarmentrentstop.temporarygarmentrentstop_id%type;
      lv_endyear           number(4);
      lv_endweek           number(2);
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_tempgarmrentstop.customernumber);
      if lv_rec_erp_i_tempgarmrentstop.numberofweeks = 0 then
        begin
          --when for a customer they send 0 numberofweeks we can remove ALL stops
          delete from temporarygarmentrentstop tgr where tgr.customer_id = lv_customerid;
        end;
      else
        begin
          --get end year/week
          gv_text := 'get endyear and endweek based upon start year/week and number of weeks';
          select enddate.year, enddate.week
          into   lv_endyear, lv_endweek
          from   date_yearweekday enddate
          where  enddate.date_ =
                 (select (dyw.date_ + (7 * lv_rec_erp_i_tempgarmrentstop.numberofweeks)) - 1
                  from   date_yearweekday dyw
                  where  dyw.year = lv_rec_erp_i_tempgarmrentstop.startyear
                  and    dyw.week = lv_rec_erp_i_tempgarmrentstop.startweek
                  and    dyw.day = 1);
          --check if data already exists
          select tgr.temporarygarmentrentstop_id
          into   lv_tempgarmrntstopid
          from   temporarygarmentrentstop tgr
          where  tgr.customer_id = lv_customerid
          and    tgr.startyear = lv_rec_erp_i_tempgarmrentstop.startyear
          and    tgr.startweek = lv_rec_erp_i_tempgarmrentstop.startweek;
          --update existing record
          gv_text := 'update temporarygarmentrentstop';
          update temporarygarmentrentstop tgr
          set    tgr.endyear = lv_endyear, tgr.endweek = lv_endweek,
                 tgr.numberweeks = lv_rec_erp_i_tempgarmrentstop.numberofweeks,
                 tgr.timestamp = sysdate, tgr.systemuser_id = gv_erp_systemuserid
          where  tgr.temporarygarmentrentstop_id = lv_tempgarmrntstopid;
        exception
          when no_data_found then
            begin
              --insert into temporarygarmentrentstop
              gv_text := 'insert into temporarygarmentrentstop';
              insert into temporarygarmentrentstop
                (temporarygarmentrentstop_id, customer_id, startyear, startweek, endyear, endweek,
                 numberweeks, systemuser_id, timestamp)
              values
                (seq_temporarygarmentrentstop.nextval, lv_customerid,
                 lv_rec_erp_i_tempgarmrentstop.startyear, lv_rec_erp_i_tempgarmrentstop.startweek,
                 lv_endyear, lv_endweek, lv_rec_erp_i_tempgarmrentstop.numberofweeks,
                 gv_erp_systemuserid, sysdate);
            end;
        end;
      end if;
    end process_tempgarmentrentstop;
    -------------
  begin
    --proc_i_nonbuday
    gv_text := 'Process erp_i_tempgarmrentstop for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_tempgarmentrentstop;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_tempgarmentrentstop_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_tempgarmentrentstop fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_tempgarmrentstop.customernumber
            and    fi.startyear = lv_rec_erp_i_tempgarmrentstop.startyear
            and    fi.startweek = lv_rec_erp_i_tempgarmrentstop.startweek)
    and    f.transfer_id < lv_rec_erp_i_tempgarmrentstop.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_tempgarmentrentstop_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_tempgarmentrentstop zz
      where  zz.customernumber = lv_rec_erp_i_tempgarmrentstop.customernumber
      and    zz.startyear = lv_rec_erp_i_tempgarmrentstop.startyear
      and    zz.startweek = lv_rec_erp_i_tempgarmrentstop.startweek
      and    zz.transfer_id < lv_rec_erp_i_tempgarmrentstop.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_tempgarmentrentstop_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer ' || lv_rec_erp_i_tempgarmrentstop.customernumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer ' || lv_rec_erp_i_tempgarmrentstop.customernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' ||
                   lv_rec_erp_i_tempgarmrentstop.customernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' ||
                   lv_rec_erp_i_tempgarmrentstop.customernumber, 1, 0);
      end;
  end proc_i_tempgarmrentstop_one;

  --process erp_i_tempgarmrentstop
  procedure proc_i_tempgarmrentstop(fp_transferid in erp_i_tempgarmentrentstop.transfer_id%type,
                                    fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.startyear, eic.startweek
                 from   erp_i_tempgarmentrentstop eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_tempgarmentrentstop eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.startyear = pscx.startyear
                     and    eic.startweek = pscx.startweek) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_tempgarmentrentstop eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_tempgarmrentstop_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_tempgarmrentstop;

  --process proc_i_tempgarmrentstop_all
  procedure proc_i_tempgarmrentstop_all is
    lv_min_transferid number;
  
    procedure clean_tempgarmentrentstop(fp_transferid in number) is
    begin
      --clean tempgarmentrentstop for customer, not created this run 24 min check
      delete from temporarygarmentrentstop tgr
      where  exists (select 1
              from   erp_i_tempgarmentrentstop et
              join   customer c
              on     c.customernumber = et.customernumber
              where  c.customer_id = tgr.customer_id
              and    et.transfer_id = fp_transferid)
      and    not exists (select 1
              from   erp_i_tempgarmentrentstop tl
              join   customer c
              on     c.customernumber = tl.customernumber
              where  c.customer_id = tgr.customer_id
              and    tl.startyear = tgr.startyear
              and    tl.startweek = tgr.startweek
              and    tl.transfer_id >= lv_min_transferid);
      commit;
    exception
      when others then
        begin
          rollback;
          write_o_log('could not delete existing temporarygarmentrentstop ' || sqlerrm);
        end;
    end clean_tempgarmentrentstop;
  begin
    lv_min_transferid := null;
    for pdg in (select l.transfer_id
                from   erp_i_tempgarmentrentstop l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        if lv_min_transferid is null then
          lv_min_transferid := pdg.transfer_id;
        end if;
        --cleanup existing tempgarmentrentstop for this customer
        clean_tempgarmentrentstop(pdg.transfer_id);
        --process the erp i table
        proc_i_tempgarmrentstop(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_tempgarmrentstop_all;

  --process erp_i_nonbusinessdays
  procedure proc_i_nonbudays_one(fp_transferid in erp_i_nonbusinessdays.transfer_id%type,
                                 fp_rerun      in number default 0) is
    lv_rec_erp_i_nonbusinessdays erp_i_nonbusinessdays%rowtype;
    lv_log_tablename             varchar2(32) := 'ERP_I_NONBUSINESSDAYS_LOG';
    lv_process_status            number := 0;
    -------------
    --internal procedure functions from proc_i_nonbuday
    function read_line return number is
    begin
      --read_line erp_i_nonbusinessdays
      select eis.*
      into   lv_rec_erp_i_nonbusinessdays
      from   erp_i_nonbusinessdays eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_nonbusinessdays eis
      set    eis.transfer_status = 1
      where  eis.transfer_id = fp_transferid
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_nonbusinessday is
      lv_customerid   customer.customer_id%type;
      lv_departmentid department.department_id%type;
    begin
      lv_customerid   := get_customerid(lv_rec_erp_i_nonbusinessdays.customernumber);
      lv_departmentid := get_departmentid(lv_rec_erp_i_nonbusinessdays.departmentnumber,
                                          lv_customerid);
      --merge into nonbusinessday nd
      merge into nonbusinessday nd
      using (select dyw.date_ nonbusinessday, lv_customerid customer_id,
                    lv_departmentid department_id
             from   date_yearweekday dyw
             where  dyw.date_ between trunc(lv_rec_erp_i_nonbusinessdays.nonbusinessdate_start) and
                    trunc(nvl(lv_rec_erp_i_nonbusinessdays.nonbusinessdate_end,
                              lv_rec_erp_i_nonbusinessdays.nonbusinessdate_start))) mr_nonbu
      on (nd.nonbusinessday = mr_nonbu.nonbusinessday and nd.customer_id = mr_nonbu.customer_id and (nd.department_id = mr_nonbu.department_id or (nd.department_id is null and mr_nonbu.department_id is null)))
      when not matched then
        insert
          (nonbusinessday_id, nonbusinessday, department_id, customer_id, systemuser_id, timestamp,
           closestatus, movedays)
        values
          (seq_nonbusinessday.nextval, mr_nonbu.nonbusinessday, mr_nonbu.department_id,
           mr_nonbu.customer_id, gv_erp_systemuserid, sysdate,
           lv_rec_erp_i_nonbusinessdays.closestatus, 0)
      when matched then
        update
        set    nd.closestatus = lv_rec_erp_i_nonbusinessdays.closestatus, nd.timestamp = sysdate,
               nd.systemuser_id = gv_erp_systemuserid;
    end process_nonbusinessday;
    -------------
  begin
    --proc_i_nonbuday
    gv_text := 'Process erp_i_nonbusinessdays for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_nonbusinessday;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/departmentnumber ' || lv_rec_erp_i_nonbusinessdays.customernumber || '/' ||
               nvl(to_char(lv_rec_erp_i_nonbusinessdays.departmentnumber), 'NULL'),
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/departmentnumber ' ||
                   lv_rec_erp_i_nonbusinessdays.customernumber || '/' ||
                   nvl(to_char(lv_rec_erp_i_nonbusinessdays.departmentnumber), 'NULL'), 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/departmentnumber ' ||
                   lv_rec_erp_i_nonbusinessdays.customernumber || '/' ||
                   nvl(to_char(lv_rec_erp_i_nonbusinessdays.departmentnumber), 'NULL'), 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/departmentnumber ' ||
                   lv_rec_erp_i_nonbusinessdays.customernumber || '/' ||
                   nvl(to_char(lv_rec_erp_i_nonbusinessdays.departmentnumber), 'NULL'), 1, 0);
      end;
  end proc_i_nonbudays_one;

  --process erp_i_nonbusinessdays
  procedure proc_i_nonbuday(fp_transferid in erp_i_nonbusinessdays.transfer_id%type,
                            fp_rerun      in number default 0) is
  begin
    proc_i_nonbudays_one(fp_transferid, fp_rerun);
  end proc_i_nonbuday;

  --process proc_i_nonbudays_all
  procedure proc_i_nonbudays_all is
  begin
    for pdg in (select l.transfer_id
                from   erp_i_nonbusinessdays l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_nonbuday(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_nonbudays_all;

  --process erp_i_pricelist
  procedure proc_i_pricelist_one(fp_transferid in erp_i_pricelist.transfer_id%type,
                                 fp_rerun      in number default 0) is
    lv_rec_erp_i_pricelist  erp_i_pricelist%rowtype;
    lv_log_tablename        varchar2(32) := 'ERP_I_PRICELIST_LOG';
    lv_rec_generalpricelist generalpricelist%rowtype;
    lv_process_status       number := 0;
    -------------
    --internal procedure functions from proc_I_pricelist
    function read_line return number is
    begin
      --read_line erp_i_pricelist
      select eis.*
      into   lv_rec_erp_i_pricelist
      from   erp_i_pricelist eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_pricelist eis
      set    eis.transfer_status = 1
      where  eis.transfer_id = fp_transferid
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_pricelist is
      -------------
      --internal procedure functions from process_pricelist
      procedure init_pricelist is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_pricelist';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'GENERALPRICELIST'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_generalpricelist;
        close rcur_typ;
        --get id
        select seq_generalpricelist.nextval
        into   lv_rec_generalpricelist.generalpricelist_id
        from   dual;
        --set default that CANNOT or MAY NOT be updated
        lv_rec_generalpricelist.usage           := 1; --agreed 20-nov-2020 (Soshi,EMG)
        lv_rec_generalpricelist.autopriceupdate := 'Y';
        lv_rec_generalpricelist.active          := 'Y';
        lv_rec_generalpricelist.code            := lv_rec_erp_i_pricelist.pricelistcode;
        lv_rec_generalpricelist.pricetype       := lv_rec_erp_i_pricelist.pricelisttype;
      end init_pricelist;
    
      procedure update_rec_generalpricelist is
      begin
        --update_rec_generalpricelist
        gv_text                                     := 'update_rec_generalpricelist';
        lv_rec_generalpricelist.priceindexcode      := lv_rec_erp_i_pricelist.priceindexcode;
        lv_rec_generalpricelist.description         := lv_rec_erp_i_pricelist.pricelistdescription;
        lv_rec_generalpricelist.currency_id         := get_currencyid(lv_rec_erp_i_pricelist.currencycode);
        lv_rec_generalpricelist.priceupdatelockdate := lv_rec_erp_i_pricelist.priceupdatelockdate;
        lv_rec_generalpricelist.systemuser_id       := gv_erp_systemuserid;
        lv_rec_generalpricelist.timestamp           := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_generalpricelist;
      -------------
    begin
      --process_pricelist
      gv_text := 'proc_I_pricelist.process_pricelist for pricelist ' ||
                 lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                 lv_rec_erp_i_pricelist.pricelisttype;
      --process_pricelist UPDATE
      select t.*
      into   lv_rec_generalpricelist
      from   generalpricelist t
      where  t.code = lv_rec_erp_i_pricelist.pricelistcode
      and    t.pricetype = lv_rec_erp_i_pricelist.pricelisttype;
      --update_rec_generalpricelist
      update_rec_generalpricelist;
      --update record
      gv_text := 'proc_I_pricelist.process_pricelist update for pricelist ' ||
                 lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                 lv_rec_erp_i_pricelist.pricelisttype;
      update generalpricelist t
      set    row = lv_rec_generalpricelist
      where  t.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id;
    exception
      when no_data_found then
        begin
          --process_pricelist insert
          init_pricelist;
          --update_rec_generalpricelist
          update_rec_generalpricelist;
          --insert record
          gv_text := 'proc_i_pricelist_one.process_pricelist insert for pricelist ' ||
                     lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                     lv_rec_erp_i_pricelist.pricelisttype;
          insert into generalpricelist values lv_rec_generalpricelist;
        end;
    end process_pricelist;
  
    procedure process_prices is
      lv_productid          product.product_id%type;
      lv_sizeid             sizedefinition.sizedefinition_id%type;
      lv_finishingmethodid  finishingmethod.finishingmethod_id%type;
      lv_weighingcategoryid weighingcategory.weighingcategory_id%type;
      lv_specialchargeid    specialcharge.specialcharge_id%type;
      lv_repairtypeid       repairtype.repairtype_id%type;
    
      procedure check_prices is
      begin
        --check_prices
        --check finishingmethod
        if lv_rec_erp_i_pricelist.pricelisttype in (1, 2, 9) then
          if (lv_rec_erp_i_pricelist.pricecomponent is null or
             lv_rec_erp_i_pricelist.finishingmethodcode is not null) and
             lv_finishingmethodid is null then
            begin
              gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                         lv_rec_erp_i_pricelist.pricelisttype ||
                         ' a valid finishingmethod must be provided!';
              raise ge_user___exception;
            end;
          end if;
        end if;
        --Check product
        if lv_rec_erp_i_pricelist.pricelisttype in (1, 2, 3, 4, 7, 8, 9, 12) and
           lv_productid is null then
          begin
            gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                       lv_rec_erp_i_pricelist.pricelisttype || ' a valid product must be provided!';
            raise ge_user___exception;
          end;
        end if;
        --Check size
        if lv_rec_erp_i_pricelist.pricelisttype in (1, 2, 3, 4, 9, 12) and lv_sizeid is null then
          begin
            gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                       lv_rec_erp_i_pricelist.pricelisttype || ' a valid size must be provided!';
            raise ge_user___exception;
          end;
        end if;
        --check weighingcategory
        if lv_rec_erp_i_pricelist.pricelisttype = 5 and lv_weighingcategoryid is null then
          begin
            gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                       lv_rec_erp_i_pricelist.pricelisttype ||
                       ' a valid weighingcategory must be provided!';
            raise ge_user___exception;
          end;
        end if;
        --check repairtype
        if lv_rec_erp_i_pricelist.pricelisttype = 6 and lv_repairtypeid is null then
          begin
            gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                       lv_rec_erp_i_pricelist.pricelisttype ||
                       ' a valid repairtype must be provided!';
            raise ge_user___exception;
          end;
        end if;
        --check specialcharge
        if lv_rec_erp_i_pricelist.pricelisttype = 10 and lv_specialchargeid is null then
          begin
            gv_text := 'for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                       lv_rec_erp_i_pricelist.pricelisttype ||
                       ' a valid specialcharge must be provided!';
            raise ge_user___exception;
          end;
        end if;
        --check rent prices
        if lv_rec_erp_i_pricelist.pricelisttype = 2 then
          begin
            if lv_rec_erp_i_pricelist.rentpricetype in (2, 4) and
               lv_rec_erp_i_pricelist.rentchangesperweek is null then
              begin
                gv_text := 'rentchangesperweek is null for pricelisttype 2 and rentpricetype 2 or 4 and this is not allowed';
                raise ge_user___exception;
              end;
            end if;
            if lv_rec_erp_i_pricelist.rentpricetype is null then
              begin
                gv_text := 'rentpricetype is null for pricelisttype 2 this is not allowed';
                raise ge_user___exception;
              end;
            end if;
          end;
        end if;
      end check_prices;
    
      procedure create_prices is
        lv_price number;
        lv_id    number;
      
        procedure update_prices is
        begin
          --update_prices
          gv_text := 'update_prices, insert price for pricelist ' ||
                     lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                     lv_rec_erp_i_pricelist.pricelisttype;
          case lv_rec_erp_i_pricelist.pricelisttype
            when 1 then
              begin
                -- Update Wash
                update generalwashprice gwp
                set    gwp.price = lv_rec_erp_i_pricelist.price,
                       gwp.systemuser_id = gv_erp_systemuserid, gwp.timestamp = sysdate
                where  gwp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gwp.product_id = lv_productid
                and    gwp.sizedefinition_id = lv_sizeid
                and    gwp.finishingmethod_id = lv_finishingmethodid
                and    gwp.startdate = lv_rec_erp_i_pricelist.startdateprice
                and    gwp.pricetype = lv_rec_erp_i_pricelist.washpricetype;
              end; --End Wash
            when 2 then
              begin
                -- Update Rent
                update generalrentprice grp
                set    grp.price = lv_rec_erp_i_pricelist.price,
                       grp.systemuser_id = gv_erp_systemuserid, grp.timestamp = sysdate
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.product_id = lv_productid
                and    grp.sizedefinition_id = lv_sizeid
                and    grp.finishingmethod_id = lv_finishingmethodid
                and    grp.typeofrent = lv_rec_erp_i_pricelist.rentpricetype
                and    grp.startdate = lv_rec_erp_i_pricelist.startdateprice
                and    grp.changesperweek = lv_rec_erp_i_pricelist.rentchangesperweek
                and    grp.invoicefrequencynumber = 10
                and    grp.sizebillinggroup_id is null;
              end; -- End Rent
            when 3 then
              begin
                -- Update Replacement
                update generalreplacementprice grp
                set    grp.price = lv_rec_erp_i_pricelist.price,
                       grp.systemuser_id = gv_erp_systemuserid, grp.timestamp = sysdate
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.product_id = lv_productid
                and    grp.sizedefinition_id = lv_sizeid
                and    grp.startdate = lv_rec_erp_i_pricelist.startdateprice
                and    grp.sizebillinggroup_id is null;
              end; -- End Replacement
            when 4 then
              begin
                -- Update Sales
                update generalsalesprice gsp
                set    gsp.price = lv_rec_erp_i_pricelist.price,
                       gsp.systemuser_id = gv_erp_systemuserid, gsp.timestamp = sysdate
                where  gsp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gsp.product_id = lv_productid
                and    gsp.sizedefinition_id = lv_sizeid
                and    gsp.startdate = lv_rec_erp_i_pricelist.startdateprice
                and    gsp.volumeprice = lv_rec_erp_i_pricelist.volumeprice
                and    gsp.sizebillinggroup_id is null;
              end; -- End Sales
            when 5 then
              begin
                -- Update Weight
                update generalweightprice gwp
                set    gwp.price = lv_rec_erp_i_pricelist.price,
                       gwp.systemuser_id = gv_erp_systemuserid, gwp.timestamp = sysdate
                where  gwp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gwp.weighingcategory_id = lv_weighingcategoryid
                and    gwp.soil = nvl(lv_rec_erp_i_pricelist.soil, 'Y')
                and    gwp.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; -- End Weight
            when 6 then
              begin
                -- Update Repair
                update generalrepairprice grp
                set    grp.price = lv_rec_erp_i_pricelist.price,
                       grp.priceperminute = lv_rec_erp_i_pricelist.priceperminute,
                       grp.systemuser_id = gv_erp_systemuserid, grp.timestamp = sysdate
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.repairtype_id = lv_repairtypeid
                and    grp.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; -- End Repair
            when 7 then
              begin
                -- Update Emblem
                update generalemblemprice gep
                set    gep.price = lv_rec_erp_i_pricelist.price,
                       gep.systemuser_id = gv_erp_systemuserid, gep.timestamp = sysdate
                where  gep.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gep. product_id = lv_productid
                and    gep.sizedefinition_id = lv_sizeid
                and    gep.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; -- End Emblem/template
            when 8 then
              begin
                -- Update Emblem Template Price
                update generalemblemprice gep
                set    gep.price = lv_rec_erp_i_pricelist.price,
                       gep.systemuser_id = gv_erp_systemuserid, gep.timestamp = sysdate
                where  gep.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gep.product_id = lv_productid
                and    gep.sizedefinition_id = lv_sizeid
                and    gep.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; --end emblem template price
            when 9 then
              begin
                if lv_rec_erp_i_pricelist.pricecomponent is not null then
                  begin
                    --Update 9 = BudgetProtectionPrice
                    update generalbgprotectionprice gcp
                    set    gcp.price = lv_rec_erp_i_pricelist.price,
                           gcp.systemuser_id = gv_erp_systemuserid, gcp.timestamp = sysdate
                    where  gcp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                    and    gcp.product_id = lv_productid
                    and    gcp.sizedefinition_id = lv_sizeid
                    and    gcp.pricecomponent = lv_rec_erp_i_pricelist.pricecomponent
                    and    gcp.startdate = lv_rec_erp_i_pricelist.startdateprice;
                  end;
                else
                  begin
                    --Update 9 = Garment Insurance
                    update generalinsuranceprice gip
                    set    gip.price = lv_rec_erp_i_pricelist.price,
                           gip.systemuser_id = gv_erp_systemuserid, gip.timestamp = sysdate
                    where  gip.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                    and    gip.product_id = lv_productid
                    and    gip.sizedefinition_id = lv_sizeid
                    and    gip.finishingmethod_id = lv_finishingmethodid
                    and    gip.startdate = lv_rec_erp_i_pricelist.startdateprice;
                  end;
                end if;
              end; --End 9 = Garment Insurance
            when 10 then
              begin
                --Update 10=General Special Charge Price
                update generalspecialchargeprice gcp
                set    gcp.price = lv_rec_erp_i_pricelist.price,
                       gcp.percentage = lv_rec_erp_i_pricelist.percentage,
                       gcp.systemuser_id = gv_erp_systemuserid, gcp.timestamp = sysdate
                where  gcp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gcp.specialcharge_id = lv_specialchargeid
                and    gcp.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; --End 10 special charge
            when 12 then
              begin
                --Update Special Size Charge
                update generalspecsizechargeprice gsp
                set    gsp.price = lv_rec_erp_i_pricelist.price,
                       gsp.systemuser_id = gv_erp_systemuserid, gsp.timestamp = sysdate
                where  gsp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gsp.product_id = lv_productid
                and    gsp.sizedefinition_id = lv_sizeid
                and    gsp.startdate = lv_rec_erp_i_pricelist.startdateprice;
              end; --End 12  Special Size Charge
            else
              begin
                --Error unknown price
                gv_text := 'Update_prices. Unknown price type ' ||
                           lv_rec_erp_i_pricelist.pricelisttype || ' for pricelist ' ||
                           lv_rec_erp_i_pricelist.pricelistcode;
                raise ge_user___exception;
              end;
          end case;
        end update_prices;
      begin
        --create_prices
        gv_text := 'create_prices, insert price for pricelist ' ||
                   lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                   lv_rec_erp_i_pricelist.pricelisttype;
        case lv_rec_erp_i_pricelist.pricelisttype
          when 1 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, STARTDATE, PRICETYPE
                select gwp.generalpricelist_id, gwp.price
                into   lv_id, lv_price
                from   generalwashprice gwp
                where  gwp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gwp.product_id = lv_productid
                and    gwp.sizedefinition_id = lv_sizeid
                and    gwp.finishingmethod_id = lv_finishingmethodid
                and    gwp.pricetype = lv_rec_erp_i_pricelist.washpricetype
                and    gwp.startdate =
                       (select max(gwp2.startdate)
                         from   generalwashprice gwp2
                         where  gwp2.generalpricelist_id = gwp.generalpricelist_id
                         and    gwp2.product_id = gwp.product_id
                         and    gwp2.sizedefinition_id = gwp.sizedefinition_id
                         and    gwp2.finishingmethod_id = gwp.finishingmethod_id
                         and    gwp2.pricetype = gwp.pricetype
                         and    gwp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Wash
                  insert into generalwashprice
                    (generalwashprice_id, generalpricelist_id, product_id, sizedefinition_id,
                     finishingmethod_id, price, startdate, systemuser_id, timestamp, pricetype)
                  values
                    (seq_generalwashprice.nextval, lv_rec_generalpricelist.generalpricelist_id,
                     lv_productid, lv_sizeid, lv_finishingmethodid, lv_rec_erp_i_pricelist.price,
                     lv_rec_erp_i_pricelist.startdateprice, gv_erp_systemuserid, sysdate,
                     lv_rec_erp_i_pricelist.washpricetype);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Wash price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; --End Wash
          when 2 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, TYPEOFRENT, STARTDATE, 
                --CHANGESPERWEEK, INVOICEFREQUENCYNUMBER, SIZEBILLINGGROUP_ID,-- MAXINVENTORY from 9.05.03
                select grp.generalrentprice_id, grp.price
                into   lv_id, lv_price
                from   generalrentprice grp
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.product_id = lv_productid
                and    grp.sizedefinition_id = lv_sizeid
                and    grp.finishingmethod_id = lv_finishingmethodid
                and    grp.typeofrent = lv_rec_erp_i_pricelist.rentpricetype
                and    grp.changesperweek = lv_rec_erp_i_pricelist.rentchangesperweek
                and    grp.invoicefrequencynumber = 10
                and    grp.sizebillinggroup_id is null
                and    grp.startdate =
                       (select max(grp2.startdate)
                         from   generalrentprice grp2
                         where  grp2.generalpricelist_id = grp.generalpricelist_id
                         and    grp2.product_id = grp.product_id
                         and    grp2.sizedefinition_id = grp.sizedefinition_id
                         and    grp2.finishingmethod_id = grp.finishingmethod_id
                         and    grp2.typeofrent = grp.typeofrent
                         and    grp2.changesperweek = grp.changesperweek
                         and    grp2.invoicefrequencynumber = grp.invoicefrequencynumber
                         and    grp2.sizebillinggroup_id is null
                         and    grp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Rent
                  insert into generalrentprice
                    (generalrentprice_id, generalpricelist_id, product_id, sizedefinition_id,
                     finishingmethod_id, price, startdate, changesperweek, typeofrent, systemuser_id,
                     timestamp)
                  values
                    (seq_generalrentprice.nextval, lv_rec_generalpricelist.generalpricelist_id,
                     lv_productid, lv_sizeid, lv_finishingmethodid, lv_rec_erp_i_pricelist.price,
                     lv_rec_erp_i_pricelist.startdateprice,
                     nvl(lv_rec_erp_i_pricelist.rentchangesperweek, 0),
                     lv_rec_erp_i_pricelist.rentpricetype, gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Rent price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Rent
          when 3 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE, SIZEBILLINGGROUP_ID
                select grp.generalreplacementprice_id, grp.price
                into   lv_id, lv_price
                from   generalreplacementprice grp
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.product_id = lv_productid
                and    grp.sizedefinition_id = lv_sizeid
                and    grp.sizebillinggroup_id is null
                and    grp.startdate =
                       (select max(grp2.startdate)
                         from   generalreplacementprice grp2
                         where  grp2.generalpricelist_id = grp.generalpricelist_id
                         and    grp2.product_id = grp.product_id
                         and    grp2.sizedefinition_id = grp.sizedefinition_id
                         and    grp2.sizebillinggroup_id is null
                         and    grp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Replacement
                  insert into generalreplacementprice
                    (generalreplacementprice_id, generalpricelist_id, product_id, sizedefinition_id,
                     price, startdate, systemuser_id, timestamp)
                  values
                    (seq_generalreplacementprice.nextval,
                     lv_rec_generalpricelist.generalpricelist_id, lv_productid, lv_sizeid,
                     lv_rec_erp_i_pricelist.price, lv_rec_erp_i_pricelist.startdateprice,
                     gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Replacement price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Replacement
          when 4 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE, VOLUMEPRICE, SIZEBILLINGGROUP_ID
                select gsp.generalsalesprice_id, gsp.price
                into   lv_id, lv_price
                from   generalsalesprice gsp
                where  gsp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gsp.product_id = lv_productid
                and    gsp.sizedefinition_id = lv_sizeid
                and    gsp.volumeprice = lv_rec_erp_i_pricelist.volumeprice
                and    gsp.sizebillinggroup_id is null
                and    gsp.startdate =
                       (select max(gsp2.startdate)
                         from   generalsalesprice gsp2
                         where  gsp2.generalpricelist_id = gsp.generalpricelist_id
                         and    gsp2.product_id = gsp.product_id
                         and    gsp2.sizedefinition_id = gsp.sizedefinition_id
                         and    gsp2.volumeprice = gsp.volumeprice
                         and    gsp2.sizebillinggroup_id is null
                         and    gsp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Sales
                  insert into generalsalesprice
                    (generalsalesprice_id, generalpricelist_id, product_id, sizedefinition_id,
                     price, startdate, systemuser_id, timestamp, volumeprice)
                  values
                    (seq_generalsalesprice.nextval, lv_rec_generalpricelist.generalpricelist_id,
                     lv_productid, lv_sizeid, lv_rec_erp_i_pricelist.price,
                     lv_rec_erp_i_pricelist.startdateprice, gv_erp_systemuserid, sysdate,
                     lv_rec_erp_i_pricelist.volumeprice);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Sales price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Sales
          when 5 then
            begin
              begin
                --GENERALPRICELIST_ID, WEIGHINGCATEGORY_ID, SOIL, STARTDATE
                select gwp.generalweightprice_id, gwp.price
                into   lv_id, lv_price
                from   generalweightprice gwp
                where  gwp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gwp.weighingcategory_id = lv_weighingcategoryid
                and    gwp.soil = nvl(lv_rec_erp_i_pricelist.soil, 'Y')
                and    gwp.startdate =
                       (select max(gwp2.startdate)
                         from   generalweightprice gwp2
                         where  gwp2.generalpricelist_id = gwp.generalpricelist_id
                         and    gwp2.weighingcategory_id = gwp.weighingcategory_id
                         and    gwp2.soil = gwp.soil
                         and    gwp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Weight
                  insert into generalweightprice
                    (generalweightprice_id, generalpricelist_id, price, startdate, soil,
                     weighingcategory_id, systemuser_id, timestamp)
                  values
                    (seq_generalweightprice.nextval, lv_rec_generalpricelist.generalpricelist_id,
                     lv_rec_erp_i_pricelist.price, lv_rec_erp_i_pricelist.startdateprice,
                     nvl(lv_rec_erp_i_pricelist.soil, 'Y'), lv_weighingcategoryid,
                     gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Weight price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Weight
          when 6 then
            begin
              begin
                --GENERALPRICELIST_ID, REPAIRTYPE_ID, STARTDATE
                select grp.generalrepairprice_id, grp.price
                into   lv_id, lv_price
                from   generalrepairprice grp
                where  grp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    grp.repairtype_id = lv_repairtypeid
                and    grp.startdate =
                       (select max(grp2.startdate)
                         from   generalrepairprice grp2
                         where  grp2.generalpricelist_id = grp.generalpricelist_id
                         and    grp2.repairtype_id = grp.repairtype_id
                         and    grp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- Repair
                  insert into generalrepairprice
                    (generalrepairprice_id, generalpricelist_id, repairtype_id, price, startdate,
                     priceperminute, systemuser_id, timestamp)
                  values
                    (seq_generalrepairprice.nextval, lv_rec_generalpricelist.generalpricelist_id,
                     lv_repairtypeid, lv_rec_erp_i_pricelist.price,
                     lv_rec_erp_i_pricelist.startdateprice, lv_rec_erp_i_pricelist.priceperminute,
                     gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Repair price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Repair
          when 7 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
                select gep.generalemblemprice_id, gep.price
                into   lv_id, lv_price
                from   generalemblemprice gep
                where  gep.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gep.product_id = lv_productid
                and    gep.sizedefinition_id = lv_sizeid
                and    gep.startdate =
                       (select max(gep2.startdate)
                         from   generalemblemprice gep2
                         where  gep2.generalpricelist_id = gep.generalpricelist_id
                         and    gep2.product_id = gep.product_id
                         and    gep2.sizedefinition_id = gep.sizedefinition_id
                         and    gep2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  -- General Emblem price
                  insert into generalemblemprice
                    (generalemblemprice_id, product_id, sizedefinition_id, price, startdate,
                     generalpricelist_id, systemuser_id, timestamp)
                  values
                    (seq_generalemblemprice.nextval, lv_productid, lv_sizeid,
                     lv_rec_erp_i_pricelist.price, lv_rec_erp_i_pricelist.startdateprice,
                     lv_rec_generalpricelist.generalpricelist_id, gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Emblem price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; -- End Emblem/template
          when 8 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
                select gep.generalemblemprice_id, gep.price
                into   lv_id, lv_price
                from   generalemblemprice gep
                where  gep.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gep.product_id = lv_productid
                and    gep.sizedefinition_id = lv_sizeid
                and    gep.startdate =
                       (select max(gep2.startdate)
                         from   generalemblemprice gep2
                         where  gep2.generalpricelist_id = gep.generalpricelist_id
                         and    gep2.product_id = gep.product_id
                         and    gep2.sizedefinition_id = gep.sizedefinition_id
                         and    gep2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  --emblem template price
                  insert into generalemblemprice
                    (generalemblemprice_id, product_id, sizedefinition_id, price, startdate,
                     generalpricelist_id, systemuser_id, timestamp)
                  values
                    (seq_generalemblemprice.nextval, lv_productid, lv_sizeid,
                     lv_rec_erp_i_pricelist.price, lv_rec_erp_i_pricelist.startdateprice,
                     lv_rec_generalpricelist.generalpricelist_id, gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Template price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; --end emblem template price
          when 9 then
            begin
              if lv_rec_erp_i_pricelist.pricecomponent is not null then
                begin
                  begin
                    --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, PRICECOMPONENT, STARTDATE
                    select gcp.generalbgprotectionprice_id, gcp.price
                    into   lv_id, lv_price
                    from   generalbgprotectionprice gcp
                    where  gcp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                    and    gcp.product_id = lv_productid
                    and    gcp.sizedefinition_id = lv_sizeid
                    and    gcp.pricecomponent = lv_rec_erp_i_pricelist.pricecomponent
                    and    gcp.startdate =
                           (select max(gcp2.startdate)
                             from   generalbgprotectionprice gcp2
                             where  gcp2.generalpricelist_id = gcp.generalpricelist_id
                             and    gcp2.product_id = gcp.product_id
                             and    gcp2.sizedefinition_id = gcp.sizedefinition_id
                             and    gcp2.pricecomponent = gcp.pricecomponent
                             and    gcp2.startdate <=
                                    greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
                  exception
                    when no_data_found then
                      begin
                        lv_id := null;
                      end;
                  end;
                  if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                    begin
                      --9 = Budget Protection Price
                      insert into generalbgprotectionprice
                        (generalbgprotectionprice_id, generalpricelist_id, product_id,
                         sizedefinition_id, pricecomponent, startdate, price, systemuser_id,
                         timestamp)
                      values
                        (seq_generalbgprotectionprice.nextval,
                         lv_rec_generalpricelist.generalpricelist_id, lv_productid, lv_sizeid,
                         lv_rec_erp_i_pricelist.pricecomponent,
                         lv_rec_erp_i_pricelist.startdateprice, lv_rec_erp_i_pricelist.price,
                         gv_erp_systemuserid, sysdate);
                    end;
                  else
                    begin
                      --we will not insert a new price, when an exact price already exists in the past
                      gv_text := 'An earlier General Budget Protection price did already exists with same price, nothing done ';
                      raise ge_user___exception;
                    end;
                  end if;
                end;
              else
                begin
                  begin
                    --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, STARTDATE
                    select gip.generalinsuranceprice_id, gip.price
                    into   lv_id, lv_price
                    from   generalinsuranceprice gip
                    where  gip.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                    and    gip.product_id = lv_productid
                    and    gip.sizedefinition_id = lv_sizeid
                    and    gip.finishingmethod_id = lv_finishingmethodid
                    and    gip.startdate =
                           (select max(gip2.startdate)
                             from   generalinsuranceprice gip2
                             where  gip2.generalpricelist_id = gip.generalpricelist_id
                             and    gip2.product_id = gip.product_id
                             and    gip2.sizedefinition_id = gip.sizedefinition_id
                             and    gip2.finishingmethod_id = gip.finishingmethod_id
                             and    gip2.startdate <=
                                    greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
                  exception
                    when no_data_found then
                      begin
                        lv_id := null;
                      end;
                  end;
                  if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                    begin
                      --9 = Garment Insurance
                      insert into generalinsuranceprice
                        (generalinsuranceprice_id, generalpricelist_id, product_id,
                         sizedefinition_id, finishingmethod_id, price, startdate, systemuser_id,
                         timestamp)
                      values
                        (seq_generalinsuranceprice.nextval,
                         lv_rec_generalpricelist.generalpricelist_id, lv_productid, lv_sizeid,
                         lv_finishingmethodid, lv_rec_erp_i_pricelist.price,
                         lv_rec_erp_i_pricelist.startdateprice, gv_erp_systemuserid, sysdate);
                    end;
                  else
                    begin
                      --we will not insert a new price, when an exact price already exists in the past
                      gv_text := 'An earlier General Garment Insurance did already exists with same price, nothing done ';
                      raise ge_user___exception;
                    end;
                  end if;
                end;
              end if;
            end; --End 9 = Garment Insurance
          when 10 then
            begin
              begin
                --GENERALPRICELIST_ID, SPECIALCHARGE_ID, STARTDATE
                select gcp.generalspecialchargeprice_id, gcp.price
                into   lv_id, lv_price
                from   generalspecialchargeprice gcp
                where  gcp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gcp.specialcharge_id = lv_specialchargeid
                and    gcp.startdate =
                       (select max(gcp2.startdate)
                         from   generalspecialchargeprice gcp2
                         where  gcp2.generalpricelist_id = gcp.generalpricelist_id
                         and    gcp2.specialcharge_id = gcp.specialcharge_id
                         and    gcp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  --10=General Special Charge Price
                  insert into generalspecialchargeprice
                    (generalspecialchargeprice_id, generalpricelist_id, specialcharge_id, startdate,
                     price, percentage, minimumamount, maximumamount, systemuser_id, timestamp,
                     creationuser_id, creationtimestamp)
                  values
                    (seq_generalspecialchargeprice.nextval,
                     lv_rec_generalpricelist.generalpricelist_id, lv_specialchargeid,
                     lv_rec_erp_i_pricelist.startdateprice, lv_rec_erp_i_pricelist.price,
                     lv_rec_erp_i_pricelist.percentage, null /*min.amount*/, null /*max.amount*/,
                     gv_erp_systemuserid, sysdate, gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Special Charge price did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; --End 10 special charge
          when 12 then
            begin
              begin
                --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
                select gsp.generalspecsizechargeprice_id, gsp.price
                into   lv_id, lv_price
                from   generalspecsizechargeprice gsp
                where  gsp.generalpricelist_id = lv_rec_generalpricelist.generalpricelist_id
                and    gsp.product_id = lv_productid
                and    gsp.sizedefinition_id = lv_sizeid
                and    gsp.startdate =
                       (select max(gsp2.startdate)
                         from   generalsalesprice gsp2
                         where  gsp2.generalpricelist_id = gsp.generalpricelist_id
                         and    gsp2.product_id = gsp.product_id
                         and    gsp2.sizedefinition_id = gsp.sizedefinition_id
                         and    gsp2.startdate <=
                                greatest(trunc(sysdate), lv_rec_erp_i_pricelist.startdateprice));
              exception
                when no_data_found then
                  begin
                    lv_id := null;
                  end;
              end;
              if (lv_id is null or lv_price <> lv_rec_erp_i_pricelist.price) then
                begin
                  --Special Size Charge
                  insert into generalspecsizechargeprice
                    (generalspecsizechargeprice_id, generalpricelist_id, product_id,
                     sizedefinition_id, startdate, price, systemuser_id, timestamp)
                  values
                    (seq_generalspecsizechargeprice.nextval,
                     lv_rec_generalpricelist.generalpricelist_id, lv_productid, lv_sizeid,
                     lv_rec_erp_i_pricelist.startdateprice, lv_rec_erp_i_pricelist.price,
                     gv_erp_systemuserid, sysdate);
                end;
              else
                begin
                  --we will not insert a new price, when an exact price already exists in the past
                  gv_text := 'An earlier General Special Size Charge did already exists with same price, nothing done ';
                  raise ge_user___exception;
                end;
              end if;
            end; --End 12  Special Size Charge
          else
            begin
              --Error unknown price
              gv_text := 'Unknown price type ' || lv_rec_erp_i_pricelist.pricelisttype ||
                         ' for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode;
              raise ge_user___exception;
            end;
        end case;
      exception
        when dup_val_on_index then
          begin
            if lv_rec_erp_i_pricelist.startdateprice < trunc(sysdate) then
              begin
                --Cannot update prices in the past that did already exist, before today
                gv_text := 'The price did already exist in the past! Price is not updated!';
                raise ge_user___exception;
              end;
            else
              begin
                --update_prices
                update_prices;
              end;
            end if;
          end;
      end create_prices;
    begin
      --process_prices
      lv_productid          := get_productid(lv_rec_erp_i_pricelist.productcode);
      lv_sizeid             := get_sizeid(lv_rec_erp_i_pricelist.sizecode, 0);
      lv_finishingmethodid  := get_finishingmethodid(lv_rec_erp_i_pricelist.finishingmethodcode);
      lv_weighingcategoryid := get_weighingcategoryid(lv_rec_erp_i_pricelist.weighingcategorycode);
      lv_repairtypeid       := get_repairtypeid(lv_rec_erp_i_pricelist.repairtypecode);
      lv_specialchargeid    := get_specialchargeid(lv_rec_erp_i_pricelist.specialchargecode);
      --check_prices
      check_prices;
      --create_prices
      create_prices;
    end process_prices;
    -------------
  begin
    --proc_I_pricelist
    gv_text := 'proc_i_pricelist_one process erp_i_pricelist for pricelist ' ||
               lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
               lv_rec_erp_i_pricelist.pricelisttype || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_pricelist;
          process_prices;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For pricelist ' || lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
               lv_rec_erp_i_pricelist.pricelisttype, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' for pricelist ' || lv_rec_erp_i_pricelist.pricelistcode ||
                   ' price type ' || lv_rec_erp_i_pricelist.pricelisttype, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! for pricelist ' ||
                   lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                   lv_rec_erp_i_pricelist.pricelisttype, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' for pricelist ' ||
                   lv_rec_erp_i_pricelist.pricelistcode || ' price type ' ||
                   lv_rec_erp_i_pricelist.pricelisttype, 1, 0);
      end;
  end proc_i_pricelist_one;

  --process proc_I_pricelist
  procedure proc_i_pricelist(fp_transferid in erp_i_pricelist.transfer_id%type,
                             fp_rerun      in number default 0) is
  begin
    proc_i_pricelist_one(fp_transferid, fp_rerun);
  end proc_i_pricelist;

  --process proc_i_pricelist_all
  procedure proc_i_pricelist_all is
  begin
    for pdg in (select l.transfer_id
                from   erp_i_pricelist l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_pricelist_one(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_pricelist_all;

  --process erp_i_pricelistpercustomer
  procedure proc_i_pricelistpercustomer_one(fp_transferid in erp_i_pricelistpercustomer.transfer_id%type,
                                            fp_rerun      in number default 0) is
    lv_rec_erp_i_pricelistpercustomer erp_i_pricelistpercustomer%rowtype;
    lv_rec_pricelistpercustomer       pricelistpercustomer%rowtype;
    lv_log_tablename                  varchar2(32) := 'ERP_I_PRICELISTPERCUST_LOG';
    lv_process_status                 number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_pricelistpercustomer
      select eis.*
      into   lv_rec_erp_i_pricelistpercustomer
      from   erp_i_pricelistpercustomer eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_pricelistpercustomer eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.customernumber = lv_rec_erp_i_pricelistpercustomer.customernumber
      and    (eis.pricelistcode = lv_rec_erp_i_pricelistpercustomer.pricelistcode or
            (eis.pricelistcode is null and
            lv_rec_erp_i_pricelistpercustomer.pricelistcode is null))
      and    eis.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_pricelistpercustomer is
      -------------
      --internal procedure functions from process_pricelistpercustomer
      procedure init_pricelistpercustomer is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_pricelistpercustomer';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = upper('pricelistpercustomer')
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_pricelistpercustomer;
        close rcur_typ;
        --get id
        select seq_pricelistpercustomer.nextval
        into   lv_rec_pricelistpercustomer.pricelistpercustomer_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated
        select seq_pricelistpercustomer.nextval
        into   lv_rec_pricelistpercustomer.pricelistpercustomer_id
        from   dual;
        lv_rec_pricelistpercustomer.customer_id         := get_customerid(lv_rec_erp_i_pricelistpercustomer.customernumber);
        lv_rec_pricelistpercustomer.generalpricelist_id := get_generalpricelistid(lv_rec_erp_i_pricelistpercustomer.pricelistcode,
                                                                                  lv_rec_erp_i_pricelistpercustomer.pricetype);
        lv_rec_pricelistpercustomer.pricetype           := lv_rec_erp_i_pricelistpercustomer.pricetype;
        --only use the priority with the insert
        lv_rec_pricelistpercustomer.priority := lv_rec_erp_i_pricelistpercustomer.priority;
        --agreed to never update the startdate
        lv_rec_pricelistpercustomer.dateactive := trunc(lv_rec_erp_i_pricelistpercustomer.dateactive);
        --update prio's in the agreed way
        if lv_rec_erp_i_pricelistpercustomer.priority = 10 and
           lv_rec_erp_i_pricelistpercustomer.pricelistcode is not null then
          begin
            --update to higher prio's only when doing insert
            gv_text := 'update pricelistpercustomer prio 10-12 range';
            --ABS-134113 Priority update condition change for ERP_I_PRICELISTPERCUSTOMER
            --cut off date to yesterday
            update pricelistpercustomer sp
            set    sp.dateinactive = trunc(sysdate - 1), sp.timestamp = sysdate,
                   sp.systemuser_id = gv_erp_systemuserid
            where  sp.customer_id = lv_rec_pricelistpercustomer.customer_id
            and    sp.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
            and    sp.generalpricelist_id is not null
            and    sp.generalpricelist_id <> lv_rec_pricelistpercustomer.generalpricelist_id
            and    sp.dateinactive >= trunc(sysdate)
            and    sp.priority = 11;
            --increase priority
            update pricelistpercustomer sp
            set    sp.priority = sp.priority + 1, sp.timestamp = sysdate,
                   sp.systemuser_id = gv_erp_systemuserid
            where  sp.customer_id = lv_rec_pricelistpercustomer.customer_id
            and    sp.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
            and    sp.generalpricelist_id is not null
            and    sp.generalpricelist_id <> lv_rec_pricelistpercustomer.generalpricelist_id
            and    sp.priority = 10;
          end;
        end if;
        --also update priorities and inactive the pricelistpercustomer exising prio 14 when now its 13
        if lv_rec_erp_i_pricelistpercustomer.priority in (12, 13) and
           lv_rec_erp_i_pricelistpercustomer.pricelistcode is not null then
          begin
            --update to higher prio's only when doing insert
            gv_text := 'update pricelistpercustomer prio 12-14 range';
            --ABS-124466 + ABS-134113 Priority update condition change for ERP_I_PRICELISTPERCUSTOMER
            --cut off date to yesterday
            update pricelistpercustomer sp
            set    sp.dateinactive = trunc(sysdate - 1), sp.timestamp = sysdate,
                   sp.systemuser_id = gv_erp_systemuserid
            where  sp.customer_id = lv_rec_pricelistpercustomer.customer_id
            and    sp.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
            and    sp.generalpricelist_id is not null
            and    sp.generalpricelist_id <> lv_rec_pricelistpercustomer.generalpricelist_id
            and    sp.dateinactive >= trunc(sysdate)
            and    sp.priority = 14;
            --increase priority
            update pricelistpercustomer sp
            set    sp.priority = sp.priority + 1, sp.timestamp = sysdate,
                   sp.systemuser_id = gv_erp_systemuserid
            where  sp.customer_id = lv_rec_pricelistpercustomer.customer_id
            and    sp.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
            and    sp.generalpricelist_id is not null
            and    sp.generalpricelist_id <> lv_rec_pricelistpercustomer.generalpricelist_id
            and    sp.priority in (12, 13);
          end;
        end if;
      end init_pricelistpercustomer;
    
      procedure update_rec_pricelistpercustomer is
      begin
        --update_rec_pricelistpercustomer
        gv_text                                         := 'update_rec_pricelistpercustomer';
        lv_rec_pricelistpercustomer.dateinactive        := coalesce(trunc(lv_rec_erp_i_pricelistpercustomer.dateinactive),
                                                                    lv_rec_pricelistpercustomer.dateinactive,
                                                                    to_date('31-12-2099',
                                                                             'DD-MM-YYYY'));
        lv_rec_pricelistpercustomer.priceindexcode      := lv_rec_erp_i_pricelistpercustomer.priceindexcode;
        lv_rec_pricelistpercustomer.priceupdatelockdate := lv_rec_erp_i_pricelistpercustomer.priceupdatelockdate;
        lv_rec_pricelistpercustomer.systemuser_id       := gv_erp_systemuserid;
        lv_rec_pricelistpercustomer.timestamp           := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_pricelistpercustomer;
      -------------
    begin
      --process_pricelistpercustomer
      gv_text := 'proc_i_pricelistpercustomer.process_pricelistpercustomer for contract code ' ||
                 lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
                 lv_rec_erp_i_pricelistpercustomer.pricelistcode;
      --get key values
      lv_rec_pricelistpercustomer.customer_id         := get_customerid(lv_rec_erp_i_pricelistpercustomer.customernumber);
      lv_rec_pricelistpercustomer.generalpricelist_id := get_generalpricelistid(lv_rec_erp_i_pricelistpercustomer.pricelistcode,
                                                                                lv_rec_erp_i_pricelistpercustomer.pricetype);
      --process_pricelistpercustomer UPDATE
      --CUSTOMER_ID, PRICETYPE, GENERALPRICELIST_ID
      --not checking startdate, not allowed multiple dates
      select sp.*
      into   lv_rec_pricelistpercustomer
      from   pricelistpercustomer sp
      where  sp.customer_id = lv_rec_pricelistpercustomer.customer_id
      and    (sp.generalpricelist_id = lv_rec_pricelistpercustomer.generalpricelist_id or
            (sp.generalpricelist_id is null and
            lv_rec_pricelistpercustomer.generalpricelist_id is null))
      and    sp.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype;
      --do not update records
      if nvl(lv_rec_erp_i_pricelistpercustomer.dateinactive, to_date('31-12-2099', 'DD-MM-YYYY')) <>
         to_date('31-12-2099', 'DD-MM-YYYY') then
        begin
          --update_rec_pricelistpercustomer
          update_rec_pricelistpercustomer;
          --update record
          update pricelistpercustomer plc
          set    row = lv_rec_pricelistpercustomer
          where  plc.pricelistpercustomer_id = lv_rec_pricelistpercustomer.pricelistpercustomer_id;
        end;
      end if;
    exception
      when no_data_found then
        begin
          --process_pricelistpercustomer INSERT
          init_pricelistpercustomer;
          --update_rec_pricelistpercustomer
          update_rec_pricelistpercustomer;
          --insert record
          gv_text := 'proc_i_pricelistpercustomer.process_pricelistpercustomer.insert for  for contract code ' ||
                     lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
                     lv_rec_erp_i_pricelistpercustomer.pricelistcode;
          insert into pricelistpercustomer values lv_rec_pricelistpercustomer;
        end;
    end process_pricelistpercustomer;
    -------------
  begin
    --proc_i_pricelistpercustomer
    gv_text := 'proc_i_pricelistpercustomer process erp_i_pricelistpercustomer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_pricelistpercustomer;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_pricelistpercust_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_pricelistpercustomer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_pricelistpercustomer.customernumber
            and    (fi.pricelistcode = lv_rec_erp_i_pricelistpercustomer.pricelistcode or
                  (fi.pricelistcode is null and
                  lv_rec_erp_i_pricelistpercustomer.pricelistcode is null))
            and    fi.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype)
    and    f.transfer_id < lv_rec_erp_i_pricelistpercustomer.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_pricelistpercust_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_pricelistpercustomer zi
      where  zi.customernumber = lv_rec_erp_i_pricelistpercustomer.customernumber
      and    (zi.pricelistcode = lv_rec_erp_i_pricelistpercustomer.pricelistcode or
            (zi.pricelistcode is null and
            lv_rec_erp_i_pricelistpercustomer.pricelistcode is null))
      and    zi.pricetype = lv_rec_erp_i_pricelistpercustomer.pricetype
      and    zi.transfer_id < lv_rec_erp_i_pricelistpercustomer.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_pricelistpercust_log zix where zix.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For pricelistpercustomer for contract code ' ||
               lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
               lv_rec_erp_i_pricelistpercustomer.pricelistcode, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For pricelistpercustomer for contract code ' ||
                   lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
                   lv_rec_erp_i_pricelistpercustomer.pricelistcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For pricelistpercustomer for contract code ' ||
                   lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
                   lv_rec_erp_i_pricelistpercustomer.pricelistcode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For pricelistpercustomer for contract code ' ||
                   lv_rec_erp_i_pricelistpercustomer.customernumber || ' general price list ' ||
                   lv_rec_erp_i_pricelistpercustomer.pricelistcode, 1, 0);
      end;
  end proc_i_pricelistpercustomer_one;

  --process erp_i_pricelistpercustomer
  procedure proc_i_pricelistpercustomer(fp_transferid in erp_i_pricelistpercustomer.transfer_id%type,
                                        fp_rerun      in number default 0) is
  begin
    for psbx in (select eis.customernumber, eis.pricelistcode, eis.pricetype
                 from   erp_i_pricelistpercustomer eis
                 where  eis.transfer_id = fp_transferid
                 and    (eis.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for psby in (select max(eis.transfer_id) transfer_id
                     from   erp_i_pricelistpercustomer eis
                     where  eis.customernumber = psbx.customernumber
                     and    (eis.pricelistcode = psbx.pricelistcode or
                           (eis.pricelistcode is null and psbx.pricelistcode is null))
                     and    eis.pricetype = psbx.pricetype) loop
          begin
            if fp_transferid < psby.transfer_id then
              begin
                update erp_i_pricelistpercustomer eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_pricelistpercustomer_one(psby.transfer_id, fp_rerun);
          end;
        end loop; --psby
      end;
    end loop; --psbx
  end proc_i_pricelistpercustomer;

  --process proc_i_pricelistpercustomer_all
  procedure proc_i_pricelistpercustomer_all is
  begin
    for psb in (select l.transfer_id
                from   erp_i_pricelistpercustomer l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_pricelistpercustomer(psb.transfer_id);
      end;
    end loop; --b
  end proc_i_pricelistpercustomer_all;

  --process proc_i_customerroutestop_one
  --workflow will not use routestopnumber it will always be 0
  procedure proc_i_customerroutestop_one(fp_transferid in erp_i_customerroutestop.transfer_id%type,
                                         fp_rerun      in number default 0) is
    lv_rec_erp_i_custroutestop erp_i_customerroutestop%rowtype;
    lv_log_tablename           varchar2(32) := 'ERP_I_CUSTOMERROUTESTOP_LOG';
    lv_process_status          number := 0;
    lv_frequency               deliveryscheme.frequency%type;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_customerroutestop
      select eis.*
      into   lv_rec_erp_i_custroutestop
      from   erp_i_customerroutestop eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_customerroutestop eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.plantcode = lv_rec_erp_i_custroutestop.plantcode
      and    eis.drivingday = lv_rec_erp_i_custroutestop.drivingday
      and    eis.routenumber = lv_rec_erp_i_custroutestop.routenumber
      and    eis.stopnumber = lv_rec_erp_i_custroutestop.stopnumber
      and    eis.customernumber = lv_rec_erp_i_custroutestop.customernumber
      and    ((eis.deliveryschemecode = lv_rec_erp_i_custroutestop.deliveryschemecode) or
            (eis.deliveryschemecode is null and
            lv_rec_erp_i_custroutestop.deliveryschemecode is null))
      and    eis.transfer_status = 0;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
    -------------
    procedure process_customerroutestop is
      lv_plantid          plant.plant_id%type;
      lv_customerid       customer.customer_id%type;
      lv_deliveryschemeid deliveryscheme.deliveryscheme_id%type;
      lv_depotid          depot.depot_id%type;
      lv_deliverypointid  deliverypoint.deliverypoint_id%type;
      lv_routeid          route.route_id%type;
      lv_returnrouteid    route.route_id%type;
      lv_routestopid      routestop.routestop_id%type;
      procedure get_depotcode is
      begin
        --get_depotcode
        if trim(lv_rec_erp_i_custroutestop.depotcode) is null then
          begin
            lv_depotid := null;
          end;
        else
          begin
            gv_text := 'Depotcode ' || lv_rec_erp_i_custroutestop.depotcode || ' for plant ' ||
                       lv_rec_erp_i_custroutestop.plantcode;
            select dp.depot_id
            into   lv_depotid
            from   depot dp
            where  dp.code = upper(trim(lv_rec_erp_i_custroutestop.depotcode))
            and    dp.plant_id = lv_plantid;
          end;
        end if;
      end get_depotcode;
    
      procedure get_route(fp_routenumber in route.routenumber%type,
                          fp_driveday    in route.drivingday_id%type,
                          fp_routeid     out nocopy route.route_id%type) is
        lv_route_depotid depot.depot_id%type;
      begin
        --get route
        gv_text := 'route ' || to_char(fp_routenumber) || ' day ' || to_char(fp_driveday);
        select r.route_id, r.depot_id
        into   fp_routeid, lv_route_depotid
        from   route r
        where  r.plant_id = lv_plantid
        and    r.drivingday_id = fp_driveday
        and    r.routenumber = fp_routenumber;
        if (nvl(lv_route_depotid, -1) <> nvl(lv_depotid, -1) and
           nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) = 0) then
          begin
            --because depot is different we update it, for now depot ONLY
            gv_text := 'update depot for ' || to_char(fp_routenumber) || ' day ' ||
                       to_char(fp_driveday);
            update route r
            set    r.depot_id = lv_depotid, r.timestamp = sysdate,
                   r.systemuser_id = gv_erp_systemuserid
            where  r.route_id = fp_routeid
            and    r.depot_id <> lv_depotid;
          end;
        end if;
      end get_route;
    
      procedure process_route(fp_routenumber in route.routenumber%type,
                              fp_driveday    in route.drivingday_id%type,
                              fp_routeid     out nocopy route.route_id%type) is
      begin
        --process_route
        --get_route
        get_route(fp_routenumber, fp_driveday, fp_routeid);
      exception
        when no_data_found then
          begin
            --no route found create route
            insert into route
              (route_id, plant_id, drivingday_id, routenumber, description, depot_id, systemuser_id,
               codeonlabel, timestamp, driver_id, truck_id, starttime, endtime, packingday_id,
               packingdeadline, loadingdock, putupreportpercustomer, putupreportperroute,
               putupreportperdepot, putupreportroutestop, printsoilticket, printorderform,
               bundletagsflatw, bundletagsgarm, deliveryscheme_id, district_id)
            values
              (seq_route.nextval, lv_plantid, fp_driveday, fp_routenumber, to_char(fp_routenumber),
               lv_depotid, gv_erp_systemuserid, null, sysdate, null, null, null, null, null, null,
               null, 0, 'N', 'N', 0, 'N', 1, 0, 0, lv_deliveryschemeid, 1)
            returning route_id into fp_routeid;
          end;
      end process_route;
    
      procedure get_routestop is
      begin
        --get_routestop
        gv_text := 'proc_i_customerroutestop.process_routestop for customer ' ||
                   lv_rec_erp_i_custroutestop.customernumber || ' routenumber ' ||
                   lv_rec_erp_i_custroutestop.routenumber;
        --unique key ROUTE_ID, CUSTOMER_ID, STOPNUMBER, NVL(DELIVERYPOINT_ID,0), DATEACTIVE
        --AUJ unique key is ROUTE_ID, CUSTOMER_ID, NVL(DELIVERYPOINT_ID,0), really
        begin
          select rs.routestop_id
          into   lv_routestopid
          from   routestop rs
          where  rs.route_id = lv_routeid
          and    rs.customer_id = lv_customerid
          and    nvl(rs.deliverypoint_id, 0) = nvl(lv_deliverypointid, 0);
        exception
          when too_many_rows then
            begin
              select rs.routestop_id
              into   lv_routestopid
              from   routestop rs
              where  rs.route_id = lv_routeid
              and    rs.customer_id = lv_customerid
              and    rs.stopnumber = lv_rec_erp_i_custroutestop.stopnumber
              and    nvl(rs.deliverypoint_id, 0) = nvl(lv_deliverypointid, 0);
            end;
        end;
        if nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) = 0 then
          begin
            --already exists so we update routestop
            update routestop rs
            set    rs.stoptype = lv_rec_erp_i_custroutestop.stoptype,
                   rs.dateactive = lv_rec_erp_i_custroutestop.dateactive,
                   rs.dateinactive = lv_rec_erp_i_custroutestop.dateinactive,
                   rs.soiltickets = lv_rec_erp_i_custroutestop.soiltickets,
                   rs.routelistinstructions = lv_rec_erp_i_custroutestop.routelistinstructions,
                   rs.returnroute_id = nvl(lv_returnrouteid, rs.returnroute_id),
                   rs.systemuser_id = gv_erp_systemuserid, rs.timestamp = sysdate
            where  rs.routestop_id = lv_routestopid;
          end;
        end if;
      end get_routestop;
    
      procedure add_future_stop is
      begin
        --create_stop
        gv_text := 'add stop for routestop id ' || lv_routestopid;
        --only insert for transactiontype = 0, others would needs to be done manually
        if nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) = 0 and
           (lv_rec_erp_i_custroutestop.dateinactive - lv_rec_erp_i_custroutestop.dateactive >= 7) then
          begin
            --insert into stop
            insert into stop
              (stop_id, routecontrol_id, routestop_id, customer_link_id, stopnumber, arrivaltime,
               departuretime, travelminutes, visitminutes, routelistinstructions, systemuser_id,
               timestamp, movedtostop_id, status, chargedeliveryfee, reasoncode_id, containerno,
               soilcountstartdate, inscanstartdate, services, unloadingstatus, sortingstatus,
               scrutinystatus, deliverypoint_id, contactperson_id, stoptype)
              select seq_stop.nextval, rc.routecontrol_id, lv_routestopid, lv_customerid,
                     lv_rec_erp_i_custroutestop.stopnumber, null, null, 0, 0,
                     lv_rec_erp_i_custroutestop.routelistinstructions, gv_erp_systemuserid, sysdate,
                     null, 0, 0, null, null, null, null, 0, 1, 1, 11, lv_deliverypointid, null,
                     lv_rec_erp_i_custroutestop.stoptype
              from   routecontrol rc
              where  rc.route_id = lv_routeid
              and    rc.drivingdate >= trunc(sysdate) -- only add in future
              and    rc.drivingdate >= lv_rec_erp_i_custroutestop.dateactive
              and    rc.drivingdate <= lv_rec_erp_i_custroutestop.dateinactive
              and    rc.settlementstatus in (1, 2);
          end;
        end if;
      end add_future_stop;
    
      procedure process_routestop is
      begin
        --process_routestop
        --get_routestop
        get_routestop;
      exception
        when no_data_found then
          begin
            --only create routestop when transaction type = 0, not for 3
            if nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) = 0 then
              begin
                --create new routestop record
                insert into routestop
                  (routestop_id, route_id, stopnumber, customer_id, contactperson_id,
                   deliverypoint_id, systemuser_id, soiltickets, timestamp, routelistinstructions,
                   returnroute_id, stoptype, dateactive, dateinactive)
                values
                  (seq_routestop.nextval, lv_routeid, lv_rec_erp_i_custroutestop.stopnumber,
                   lv_customerid, null, lv_deliverypointid, gv_erp_systemuserid,
                   lv_rec_erp_i_custroutestop.soiltickets, sysdate,
                   lv_rec_erp_i_custroutestop.routelistinstructions, lv_returnrouteid,
                   lv_rec_erp_i_custroutestop.stoptype, lv_rec_erp_i_custroutestop.dateactive,
                   lv_rec_erp_i_custroutestop.dateinactive)
                returning routestop_id into lv_routestopid;
                --add_future_stop
                add_future_stop;
              end;
            end if;
          end;
      end process_routestop;
    
      procedure process_custdelscheme(fp_driveday in route.drivingday_id%type) is
        lv_activeyn varchar2(1);
      begin
        --process customerdeliveryscheme
        gv_text := 'process customerdeliveryscheme ' ||
                   lv_rec_erp_i_custroutestop.deliveryschemecode;
        select cds.active
        into   lv_activeyn
        from   customerdeliveryscheme cds
        where  cds.customer_id = lv_customerid
        and    cds.deliveryscheme_id = lv_deliveryschemeid
        and    cds.day_id = fp_driveday;
        if lv_activeyn <> lv_rec_erp_i_custroutestop.active then
          begin
            --reactivate customerdeliveryscheme
            update customerdeliveryscheme cds
            set    cds.active = lv_rec_erp_i_custroutestop.active,
                   cds.systemuser_id = gv_erp_systemuserid, cds.timestamp = sysdate
            where  cds.active <> lv_rec_erp_i_custroutestop.active
            and    cds.customer_id = lv_customerid
            and    cds.deliveryscheme_id = lv_deliveryschemeid
            and    cds.day_id = fp_driveday;
          end;
        end if;
      exception
        when no_data_found then
          begin
            --insert missing customerdeliveryscheme
            insert into customerdeliveryscheme
              (customer_id, deliveryscheme_id, day_id, systemuser_id, timestamp, active)
            values
              (lv_customerid, lv_deliveryschemeid, fp_driveday, gv_erp_systemuserid, sysdate,
               lv_rec_erp_i_custroutestop.active);
          end;
      end process_custdelscheme;
    
      procedure process_custdelday(fp_driveday in route.drivingday_id%type) is
        lv_deliverytype customerdeliveryday.deliverytype%type;
      begin
        begin
          --process customerdeliveryday
          gv_text := 'process customerdeliveryday ' || fp_driveday;
          select cd.deliverytype
          into   lv_deliverytype
          from   customerdeliveryday cd
          where  cd.customer_id = lv_customerid
          and    cd.day_id = fp_driveday
          and    cd.typeofmerchadise = lv_rec_erp_i_custroutestop.typeofmerchandise;
          if lv_deliverytype <> lv_rec_erp_i_custroutestop.deliverytype then
            begin
              --update customerdeliveryday deliverytype
              update customerdeliveryday cd
              set    cd.deliverytype = lv_rec_erp_i_custroutestop.deliverytype,
                     cd.timestamp = sysdate, cd.systemuser_id = gv_erp_systemuserid
              where  cd.customer_id = lv_customerid
              and    cd.day_id = fp_driveday
              and    cd.typeofmerchadise = lv_rec_erp_i_custroutestop.typeofmerchandise;
            end;
          end if;
        exception
          when no_data_found then
            begin
              --insert missing customerdeliveryday
              insert into customerdeliveryday
                (customer_id, day_id, timestamp, systemuser_id, deliverytype, typeofmerchadise)
              values
                (lv_customerid, fp_driveday, sysdate, gv_erp_systemuserid,
                 lv_rec_erp_i_custroutestop.deliverytype,
                 lv_rec_erp_i_custroutestop.typeofmerchandise);
            end;
        end;
        --insert for linen as well (nongarments)
        insert into customerdeliveryday
          (customer_id, day_id, timestamp, systemuser_id, deliverytype, typeofmerchadise)
          select c.customer_id, c.day_id, sysdate, c.systemuser_id, c.deliverytype, 1
          from   customerdeliveryday c
          where  c.typeofmerchadise = 2
          and    c.customer_id = lv_customerid
          and    not exists (select 1
                  from   customerdeliveryday cdm
                  where  cdm.customer_id = c.customer_id
                  and    cdm.day_id = c.day_id
                  and    cdm.typeofmerchadise = 1);
      end process_custdelday;
    
      procedure process_delschemeperstop(fp_driveday in route.drivingday_id%type) is
      begin
        --process deliveryschemesperstop
        gv_text := 'process deliveryschemesperstop ' ||
                   lv_rec_erp_i_custroutestop.deliveryschemecode;
        --insert missing records
        insert into deliveryschemesperstop
          (routestop_id, customer_id, deliveryscheme_id, day_id, systemuser_id, timestamp)
        values
          (lv_routestopid, lv_customerid, lv_deliveryschemeid, fp_driveday, gv_erp_systemuserid,
           sysdate);
      exception
        when dup_val_on_index then
          null;
      end process_delschemeperstop;
    
      procedure process_productdeliveryday is
      begin
        --process productdeliveryday
        gv_text := 'process productdeliveryday';
        update productdeliveryday pdd
        set    pdd.deliverytype = lv_rec_erp_i_custroutestop.deliverytype
        where  pdd.day_id = lv_rec_erp_i_custroutestop.drivingday
        and    exists (select 1
                from   productlistpercustomer l
                where  l.productlistpercustomer_id = pdd.productlistpercustomer_id
                and    l.dateinactive >= trunc(sysdate)
                and    l.customer_id = lv_customerid)
        and    exists (select 1
                from   customerdeliveryday cd
                where  cd.day_id = pdd.day_id
                and    cd.customer_id = lv_customerid);
        --add misisng productdeliveryday
        insert into productdeliveryday
          (productlistpercustomer_id, day_id, timestamp, systemuser_id, deliverytype)
          select l.productlistpercustomer_id, lv_rec_erp_i_custroutestop.drivingday, sysdate,
                 gv_erp_systemuserid, lv_rec_erp_i_custroutestop.deliverytype
          from   productlistpercustomer l
          where  l.customer_id = lv_customerid
          and    l.dateinactive >= trunc(sysdate)
          and    not exists
           (select 1
                  from   productdeliveryday pdd
                  where  pdd.productlistpercustomer_id = l.productlistpercustomer_id
                  and    pdd.day_id = lv_rec_erp_i_custroutestop.drivingday);
      end process_productdeliveryday;
    
      procedure inactivate_routestop is
        lv_counter number;
      begin
        --inactivate_routestop
        --Transaction 1=when we need to delete the delivery day
        gv_text := 'inactivate_routestop';
        --inactivate customerdeliveryscheme
        update customerdeliveryscheme cds
        set    cds.active = 'N'
        where  cds.customer_id = lv_customerid
        and    cds.day_id = lv_rec_erp_i_custroutestop.drivingday;
        --delete from deliveryschemesperstop
        delete from deliveryschemesperstop dsps
        where  dsps.routestop_id = lv_routestopid
        and    dsps.customer_id = lv_customerid
        and    dsps.day_id = lv_rec_erp_i_custroutestop.drivingday;
        --delete from customerdeliveryday
        delete from customerdeliveryday cdd
        where  cdd.customer_id = lv_customerid
        and    cdd.day_id = lv_rec_erp_i_custroutestop.drivingday
        and    not exists (select 1
                from   deliveryschemesperstop dsps
                join   routestop rs
                on     rs.routestop_id = dsps.routestop_id
                and    rs.customer_id = dsps.customer_id
                where  dsps.customer_id = cdd.customer_id
                and    dsps.day_id = cdd.day_id
                and    rs.dateinactive > trunc(sysdate));
        --delete from productdeliveryday
        delete from productdeliveryday pdd
        where  pdd.day_id = lv_rec_erp_i_custroutestop.drivingday
        and    exists (select 1
                from   productlistpercustomer l
                where  l.productlistpercustomer_id = pdd.productlistpercustomer_id
                and    l.customer_id = lv_customerid);
        --count deliverydays B
        select count(distinct cdd.day_id)
        into   lv_counter
        from   customerdeliveryday cdd
        where  cdd.customer_id = lv_customerid
        and    cdd.deliverytype = 'B';
        if (lv_counter < 1) then
          begin
            gv_text := 'Please don''t change current data (there must always be 1 billing day left!)';
            raise ge_user___exception;
          end;
        end if;
      end inactivate_routestop;
    
      procedure remove_deliveryschemeperstop is
        lv_counter number;
      begin
        --remove_deliveryschemeperstop
        --transaction 2=when we need to remove the deliveryscheme for the route indicated   
        gv_text := 'remove_deliveryschemeperstop';
        delete from deliveryschemesperstop dsps
        where  dsps.routestop_id = lv_routestopid
        and    dsps.deliveryscheme_id = lv_deliveryschemeid
        and    dsps.day_id = lv_rec_erp_i_custroutestop.drivingday;
        --count if for this day+routestop there is at least 1 deliveryscheme is left
        select count(1)
        into   lv_counter
        from   deliveryschemesperstop dsps
        where  dsps.routestop_id = lv_routestopid
        and    dsps.day_id = lv_rec_erp_i_custroutestop.drivingday;
        if (lv_counter < 1) then
          begin
            gv_text := 'No deliveryschemes left for the routestop on this day!)';
            raise ge_user___exception;
          end;
        end if;
      end remove_deliveryschemeperstop;
    
      procedure remove_routestop is
      begin
        --remove_routestop, transaction = 3
        gv_text := 'remove_routestop';
        update workorder wo
        set    wo.stop_id = null, wo.routecontrol_id = null, wo.routestop_id = null,
               wo.systemuser_id = gv_erp_systemuserid, wo.timestamp = sysdate
        where  wo.routestop_id = lv_routestopid;
        --
        update stop st
        set    st.status = 1, st.timestamp = sysdate, st.systemuser_id = gv_erp_systemuserid,
               st.routestop_id = null
        where  st.routestop_id = lv_routestopid;
        --
        delete from deliveryschemesperstop dsps where dsps.routestop_id = lv_routestopid;
        --
        delete from routestop rs where rs.routestop_id = lv_routestopid;
      end remove_routestop;
    
      procedure cancel_future_routecontrol_stop is
      begin
        --cancel_future_routecontrol_stop
        --do not cancel for transaction = 2, not clear, needs to be done manually
        if nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) in (0, 1) and
           (lv_rec_erp_i_custroutestop.dateinactive - lv_rec_erp_i_custroutestop.dateactive > 1 and
            lv_rec_erp_i_custroutestop.dateinactive <> to_date('31-12-2099', 'dd-mm-yyyy')) then
          begin
            gv_text := 'cancel_future_routecontrol_stop';
            update stop st
            set    st.status = 1, st.timestamp = sysdate, st.systemuser_id = gv_erp_systemuserid
            where  st.routestop_id = lv_routestopid
            and    st.status <> 1
            and    exists (select 1
                    from   routecontrol rc
                    where  rc.routecontrol_id = st.routecontrol_id
                    and    rc.drivingdate >= trunc(sysdate) --do not cancel in past..
                    and    (rc.drivingdate < lv_rec_erp_i_custroutestop.dateactive or
                          rc.drivingdate >= lv_rec_erp_i_custroutestop.dateinactive)
                    and    rc.settlementstatus in (1, 2));
          end;
        end if;
      end cancel_future_routecontrol_stop;
    begin
      --process_customerroutestopprice
      gv_text := 'proc_i_customerroutestop.process_customerroutestop for customer ' ||
                 lv_rec_erp_i_custroutestop.customernumber || ' routenumber ' ||
                 lv_rec_erp_i_custroutestop.routenumber || ' stop ' ||
                 lv_rec_erp_i_custroutestop.stopnumber;
      --get fixed values plant, customer, deliveryscheme and optional depot, deliverypoint
      lv_plantid          := get_plantid(lv_rec_erp_i_custroutestop.plantcode);
      lv_customerid       := get_customerid(lv_rec_erp_i_custroutestop.customernumber);
      lv_deliveryschemeid := get_deliveryschemeid(lv_rec_erp_i_custroutestop.deliveryschemecode,
                                                  lv_frequency);
      get_depotcode;
      lv_deliverypointid := get_deliverypointid(lv_rec_erp_i_custroutestop.deliverypoint,
                                                lv_customerid);
      if (lv_rec_erp_i_custroutestop.active = 'Y' and
         nvl(lv_rec_erp_i_custroutestop.transactiontype, 0) = 0) then
        begin
          --ACTIVE--
          --process route
          process_route(lv_rec_erp_i_custroutestop.routenumber,
                        lv_rec_erp_i_custroutestop.drivingday, lv_routeid);
          --process return route
          process_route(lv_rec_erp_i_custroutestop.returnroutenumber,
                        lv_rec_erp_i_custroutestop.returnrouteday, lv_returnrouteid);
          --process_routestop
          process_routestop;
          --process_productdeliveryday
          process_productdeliveryday;
          --process customerdeliveryscheme
          process_custdelscheme(lv_rec_erp_i_custroutestop.drivingday);
          --process customerdeliveryday
          process_custdelday(lv_rec_erp_i_custroutestop.drivingday);
          --process deliveryschemesperstop 
          process_delschemeperstop(lv_rec_erp_i_custroutestop.drivingday);
        end;
      else
        begin
          --get_route
          get_route(lv_rec_erp_i_custroutestop.routenumber, lv_rec_erp_i_custroutestop.drivingday,
                    lv_routeid);
          --process_routestop
          process_routestop;
          case lv_rec_erp_i_custroutestop.transactiontype
            when 1 then
              begin
                --1=when we need to delete the delivery day
                inactivate_routestop;
              end;
            when 2 then
              begin
                --2=when we need to remove the deliveryscheme for the route indicated
                remove_deliveryschemeperstop;
              end;
            when 3 then
              begin
                --3=When customer route stop is inactivated, existing stop in route control should be canceled
                remove_routestop;
              end;
            else
              begin
                --should never happen, not an valid option now
                gv_text := 'Unknown transactiontype ' ||
                           to_char(lv_rec_erp_i_custroutestop.transactiontype);
                raise ge_user___exception;
              end;
          end case;
        end;
      end if;
      --cancel_future_routecontrol_stop
      cancel_future_routecontrol_stop;
    end process_customerroutestop;
  begin
    --proc_i_customerroutestop_one
    gv_text := 'proc_i_customerroutestop process erp_i_customerroutestop for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_customerroutestop;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_customerroutestop_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  f.process_status <> 0
    and    f.transfer_id < lv_rec_erp_i_custroutestop.transfer_id
    and    exists
     (select fi.transfer_id
            from   erp_i_customerroutestop fi
            where  fi.transfer_id = f.transfer_id
            and    fi.plantcode = lv_rec_erp_i_custroutestop.plantcode
            and    fi.drivingday = lv_rec_erp_i_custroutestop.drivingday
            and    fi.routenumber = lv_rec_erp_i_custroutestop.routenumber
            and    fi.customernumber = lv_rec_erp_i_custroutestop.customernumber
            and    fi.stopnumber = lv_rec_erp_i_custroutestop.stopnumber
            and    fi.typeofmerchandise = lv_rec_erp_i_custroutestop.typeofmerchandise
            and    ((fi.deliveryschemecode = lv_rec_erp_i_custroutestop.deliveryschemecode) or
                  (fi.deliveryschemecode is null and
                  lv_rec_erp_i_custroutestop.deliveryschemecode is null))
            and    fi.transfer_id < lv_rec_erp_i_custroutestop.transfer_id);
    --insert existing
    insert into erp_i_customerroutestop_log
      (transfer_id, text, process_status, timestamp)
      select zi.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_customerroutestop zi
      where  zi.plantcode = lv_rec_erp_i_custroutestop.plantcode
      and    zi.drivingday = lv_rec_erp_i_custroutestop.drivingday
      and    zi.routenumber = lv_rec_erp_i_custroutestop.routenumber
      and    zi.customernumber = lv_rec_erp_i_custroutestop.customernumber
      and    zi.stopnumber = lv_rec_erp_i_custroutestop.stopnumber
      and    zi.typeofmerchandise = lv_rec_erp_i_custroutestop.typeofmerchandise
      and    ((zi.deliveryschemecode = lv_rec_erp_i_custroutestop.deliveryschemecode) or
            (zi.deliveryschemecode is null and
            lv_rec_erp_i_custroutestop.deliveryschemecode is null))
      and    zi.transfer_id < lv_rec_erp_i_custroutestop.transfer_id
      and    zi.transfer_status = 1
      and    not exists
       (select 1 from erp_i_customerroutestop_log epl where epl.transfer_id = zi.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              ' For customerroutestop for customer ' || lv_rec_erp_i_custroutestop.customernumber ||
               ' routenumber ' || lv_rec_erp_i_custroutestop.routenumber || ' stop ' ||
               lv_rec_erp_i_custroutestop.stopnumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customerroutestop for customer ' ||
                   lv_rec_erp_i_custroutestop.customernumber || ' routenumber ' ||
                   lv_rec_erp_i_custroutestop.routenumber || ' stop ' ||
                   lv_rec_erp_i_custroutestop.stopnumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customerroutestop for customer ' ||
                   lv_rec_erp_i_custroutestop.customernumber || ' routenumber ' ||
                   lv_rec_erp_i_custroutestop.routenumber || ' stop ' ||
                   lv_rec_erp_i_custroutestop.stopnumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customerroutestop for customer ' ||
                   lv_rec_erp_i_custroutestop.customernumber || ' routenumber ' ||
                   lv_rec_erp_i_custroutestop.routenumber || ' stop ' ||
                   lv_rec_erp_i_custroutestop.stopnumber, 1, 0);
      end;
  end proc_i_customerroutestop_one;

  --process erp_i_customerroutestop
  procedure proc_i_customerroutestop(fp_transferid in erp_i_customerroutestop.transfer_id%type,
                                     fp_rerun      in number default 0) is
  begin
    for lcpx in (select eip.plantcode, eip.drivingday, eip.routenumber, eip.customernumber,
                        eip.deliveryschemecode, eip.typeofmerchandise, eip.stopnumber
                 from   erp_i_customerroutestop eip
                 where  eip.transfer_id = fp_transferid
                 and    (eip.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for lcpy in (select max(eis.transfer_id) transfer_id
                     from   erp_i_customerroutestop eis
                     where  eis.plantcode = lcpx.plantcode
                     and    eis.drivingday = lcpx.drivingday
                     and    eis.routenumber = lcpx.routenumber
                     and    eis.customernumber = lcpx.customernumber
                     and    eis.stopnumber = lcpx.stopnumber
                     and    eis.typeofmerchandise = lcpx.typeofmerchandise
                     and    eis.deliveryschemecode = lcpx.deliveryschemecode) loop
          begin
            if fp_transferid < lcpy.transfer_id then
              begin
                update erp_i_customerroutestop eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_customerroutestop_one(lcpy.transfer_id, fp_rerun);
          end;
        end loop; --lcpy
      end;
    end loop; --lcpx
  end proc_i_customerroutestop;

  --process erp_i_customerroutestop
  procedure proc_i_customerroutestop_all is
  begin
    for lcp in (select l.transfer_id
                from   erp_i_customerroutestop l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_customerroutestop(lcp.transfer_id);
      end;
    end loop; --lcp
  end proc_i_customerroutestop_all;

  --process erp_i_contactperson
  procedure proc_i_contactper_one(fp_transferid in erp_i_contactperson.transfer_id%type,
                                  fp_rerun      in number default 0) is
    lv_rec_erp_i_contactperson erp_i_contactperson%rowtype;
    lv_log_tablename           varchar2(32) := 'ERP_I_CONTACTPERSON_LOG';
    lv_rec_contactperson       contactperson%rowtype;
    lv_process_status          number := 0;
    lv_customerid              contactperson.customer_id%type;
    -------------
    --internal procedure functions from proc_i_contactper
    function read_line return number is
    begin
      --read_line erp_i_contactperson
      select eis.*
      into   lv_rec_erp_i_contactperson
      from   erp_i_contactperson eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_contactperson eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_contactperson.customernumber
      and    eis.contactpersonnumber = lv_rec_erp_i_contactperson.contactpersonnumber;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure init_contactperson is
      lv_query varchar2(1000);
      type cur_typ is ref cursor;
      rcur_typ cur_typ;
    begin
      --init fill the record with all default values
      gv_text := 'init_contactperson';
      for rec in (select data_default, data_type
                  from   user_tab_columns
                  where  table_name = 'CONTACTPERSON'
                  order  by column_id) loop
        if rec.data_default is null then
          lv_query := lv_query || ', null';
        else
          lv_query := lv_query || ', ' || rec.data_default;
        end if;
      end loop;
      lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
      open rcur_typ for lv_query;
      fetch rcur_typ
        into lv_rec_contactperson;
      close rcur_typ;
      --get id
      select seq_contactperson.nextval into lv_rec_contactperson.contactperson_id from dual;
      --set default that CANNOT and MAY NOT be updated
      lv_rec_contactperson.contactpersonnumber := lv_rec_erp_i_contactperson.contactpersonnumber;
      lv_rec_contactperson.customer_id         := lv_customerid;
      --set missing defaults
      --none
    end init_contactperson;
  
    procedure process_contactperson is
      -------------
      --internal procedure functions from process_contactperson
      procedure check_invoicecontactperson is
      begin
        --check_invoicecontactperson
        gv_text := 'check_invoicecontactperson';
        if lv_rec_erp_i_contactperson.invoicecontactperson = 'Y' then
          begin
            update contactperson cp
            set    cp.invoicecontactperson = 'N', cp.timestamp = sysdate,
                   cp.systemuser_id = gv_erp_systemuserid
            where  cp.invoicecontactperson = 'Y'
            and    cp.customer_id = lv_customerid
            and    cp.contactpersonnumber <> lv_rec_contactperson.contactpersonnumber;
          end;
        end if;
      end check_invoicecontactperson;
    
      procedure update_rec_contactperson is
        procedure get_create_contactpersfunc is
        begin
          --get_create_contactpersfunc
          gv_text := 'lookup contactpersonfunction code ' ||
                     lv_rec_erp_i_contactperson.contactpersonfunctioncode;
          select cpf.contactpersonfunction_id
          into   lv_rec_contactperson.contactpersonfunction_id
          from   contactpersonfunction cpf
          where  cpf.code = lv_rec_erp_i_contactperson.contactpersonfunctioncode;
        exception
          when no_data_found then
            begin
              --insert contactpersonfunction
              gv_text := 'contactpersonfunction code ' ||
                         lv_rec_erp_i_contactperson.contactpersonfunctioncode;
              insert into contactpersonfunction
                (contactpersonfunction_id, code, systemuser_id, timestamp)
              values
                (seq_contactpersonfunction.nextval,
                 lv_rec_erp_i_contactperson.contactpersonfunctioncode, gv_erp_systemuserid, sysdate)
              returning contactpersonfunction_id into lv_rec_contactperson.contactpersonfunction_id;
              insert into contactpersonfunction_desc
                (contactpersonfunction_id, language_id, description, systemuser_id, timestamp)
              values
                (lv_rec_contactperson.contactpersonfunction_id, gv_languageid,
                 lv_rec_erp_i_contactperson.contactpersonfunctioncode, gv_erp_systemuserid, sysdate);
            end;
        end get_create_contactpersfunc;
      begin
        --update_rec_contactperson
        check_invoicecontactperson;
        gv_text                                   := 'update_rec_contactperson';
        lv_rec_contactperson.name                 := lv_rec_erp_i_contactperson.name;
        lv_rec_contactperson.phone                := lv_rec_erp_i_contactperson.phone;
        lv_rec_contactperson.email                := lv_rec_erp_i_contactperson.email;
        lv_rec_contactperson.mobilephone          := lv_rec_erp_i_contactperson.mobilephone;
        lv_rec_contactperson.invoicecontactperson := lv_rec_erp_i_contactperson.invoicecontactperson;
        lv_rec_contactperson.fax                  := lv_rec_erp_i_contactperson.fax;
        lv_rec_contactperson.active               := lv_rec_erp_i_contactperson.active;
        lv_rec_contactperson.systemuser_id        := gv_erp_systemuserid;
        lv_rec_contactperson.timestamp            := sysdate;
        get_create_contactpersfunc;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_contactperson;
      -------------
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_contactperson.customernumber);
      --process_contactperson
      gv_text := 'proc_i_contactper.process_contactperson for contactperson ' ||
                 lv_rec_erp_i_contactperson.contactpersonnumber || ' customer ' ||
                 lv_rec_erp_i_contactperson.customernumber;
      --process_contactperson UPDATE
      select t.*
      into   lv_rec_contactperson
      from   contactperson t
      where  t.contactpersonnumber = lv_rec_erp_i_contactperson.contactpersonnumber
      and    t.customer_id = lv_customerid;
      --update_rec_contactperson
      update_rec_contactperson;
      --update record
      gv_text := 'proc_i_contactper.process_contactperson update for contactperson ' ||
                 lv_rec_erp_i_contactperson.contactpersonnumber || ' customer ' ||
                 lv_rec_erp_i_contactperson.customernumber;
      update contactperson t
      set    row = lv_rec_contactperson
      where  t.contactperson_id = lv_rec_contactperson.contactperson_id;
    exception
      when no_data_found then
        begin
          --process_contactperson insert
          init_contactperson;
          --update_rec_contactperson
          update_rec_contactperson;
          --insert record
          gv_text := 'proc_i_contactper_one.process_contactperson insert for contactperson ' ||
                     lv_rec_erp_i_contactperson.contactpersonnumber || ' customer ' ||
                     lv_rec_erp_i_contactperson.customernumber;
          insert into contactperson values lv_rec_contactperson;
        end;
    end process_contactperson;
    -------------
  begin
    --proc_i_contactper
    gv_text := 'proc_i_contactper_one process erp_i_contactperson for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_contactperson;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_contactperson_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully'
    where  exists (select fi.transfer_id
            from   erp_i_contactperson fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_contactperson.customernumber
            and    fi.contactpersonnumber = lv_rec_erp_i_contactperson.contactpersonnumber)
    and    f.transfer_id < lv_rec_erp_i_contactperson.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_contactperson_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_contactperson zz
      where  zz.customernumber = lv_rec_erp_i_contactperson.customernumber
      and    zz.contactpersonnumber = lv_rec_erp_i_contactperson.contactpersonnumber
      and    zz.transfer_id < lv_rec_erp_i_contactperson.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_contactperson_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/contactperson ' || lv_rec_erp_i_contactperson.customernumber || '/' ||
               lv_rec_erp_i_contactperson.contactpersonnumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/contactperson ' ||
                   lv_rec_erp_i_contactperson.customernumber || '/' ||
                   lv_rec_erp_i_contactperson.contactpersonnumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/contactperson ' ||
                   lv_rec_erp_i_contactperson.customernumber || '/' ||
                   lv_rec_erp_i_contactperson.contactpersonnumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/contactperson ' ||
                   lv_rec_erp_i_contactperson.customernumber || '/' ||
                   lv_rec_erp_i_contactperson.contactpersonnumber, 1, 0);
      end;
  end proc_i_contactper_one;

  --process proc_i_contactper
  procedure proc_i_contactper(fp_transferid in erp_i_contactperson.transfer_id%type,
                              fp_rerun      in number default 0) is
    transferstatus erp_i_contactperson.transfer_status%type;
  begin
    for pscx in (select eic.customernumber, eic.contactpersonnumber
                 from   erp_i_contactperson eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_contactperson eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.contactpersonnumber = pscx.contactpersonnumber) loop
          begin
            select transfer_status
            into   transferstatus
            from   erp_i_contactperson
            where  transfer_id = pscy.transfer_id;
            if (transferstatus = 0 or fp_rerun > 0) then
              proc_i_contactper_one(pscy.transfer_id, fp_rerun);
            end if;
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_contactper;

  --process proc_i_contactper_all
  procedure proc_i_contactper_all is
  begin
    for pdg in (select l.transfer_id
                from   erp_i_contactperson l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_contactper(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_contactper_all;

  --process erp_i_costcenter
  procedure proc_i_cost_one(fp_transferid in erp_i_costcenter.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_costcenter erp_i_costcenter%rowtype;
    lv_log_tablename        varchar2(32) := 'ERP_I_COSTCENTER_LOG';
    lv_process_status       number := 0;
    -------------
    --internal procedure functions from proc_i_costc
    function read_line return number is
    begin
      --read_line erp_i_costcenter
      select eis.*
      into   lv_rec_erp_i_costcenter
      from   erp_i_costcenter eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_costcenter eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_costcenter.customernumber
      and    eis.costcentercode = lv_rec_erp_i_costcenter.costcentercode;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_costcenter is
      lv_rec_costcenter costcenter%rowtype;
      lv_customerid     costcenter.customer_id%type;
      -------------
      --internal procedure functions from process_costcenter
      procedure init_costcenter is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_costcenter';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'COSTCENTER'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_costcenter;
        close rcur_typ;
        --get id
        select seq_costcenter.nextval into lv_rec_costcenter.costcenter_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_costcenter.code        := lv_rec_erp_i_costcenter.costcentercode;
        lv_rec_costcenter.customer_id := lv_customerid;
        --set missing defaults
      end init_costcenter;
    
      procedure update_rec_costcenter is
      begin
        --update_rec_costcenter
        lv_rec_costcenter.description       := lv_rec_erp_i_costcenter.description;
        lv_rec_costcenter.exportedi         := lv_rec_erp_i_costcenter.exportedi;
        lv_rec_costcenter.invoiceaddress_id := insert_or_update_addressid(lv_rec_costcenter.invoiceaddress_id,
                                                                          lv_rec_erp_i_costcenter.invoiceaddress,
                                                                          lv_rec_erp_i_costcenter.invoiceaddress2,
                                                                          lv_rec_erp_i_costcenter.invoicezipcode,
                                                                          lv_rec_erp_i_costcenter.invoicecity,
                                                                          'Y', null, null, null);
        lv_rec_costcenter.systemuser_id     := gv_erp_systemuserid;
        lv_rec_costcenter.timestamp         := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_costcenter;
    
      procedure update_costcenter_link is
      begin
        --update_costcenter_link
        gv_text := 'proc_i_cost.update_costcenter_link for costcenter code ' ||
                   lv_rec_erp_i_costcenter.costcentercode || ' customer ' ||
                   lv_rec_erp_i_costcenter.customernumber;
        update costcenter_link cl
        set    cl.description = lv_rec_costcenter.description
        where  cl.costcenter_id = lv_rec_costcenter.costcenter_id;
        if sql%rowcount = 0 then
          begin
            insert into costcenter_link
              (costcenter_link_id, customer_link_id, costcenter_id, code, description,
               systemuser_id, timestamp)
            values
              (lv_rec_costcenter.costcenter_id, lv_rec_costcenter.customer_id,
               lv_rec_costcenter.costcenter_id, lv_rec_costcenter.code,
               lv_rec_costcenter.description, gv_erp_systemuserid, sysdate);
          end;
        end if;
      end update_costcenter_link;
      -------------
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_costcenter.customernumber);
      begin
        --process_costcenter
        gv_text := 'proc_i_cost.process_costcenter for costcenter code ' ||
                   lv_rec_erp_i_costcenter.costcentercode || ' customer ' ||
                   lv_rec_erp_i_costcenter.customernumber;
        --process_costcenter UPDATE
        select cc.*
        into   lv_rec_costcenter
        from   costcenter cc
        where  cc.code = lv_rec_erp_i_costcenter.costcentercode
        and    cc.customer_id = lv_customerid;
        --update_rec_costcenter
        update_rec_costcenter;
        --update record
        gv_text := 'proc_i_cost.process_costcenter update for costcenter code ' ||
                   lv_rec_erp_i_costcenter.costcentercode || ' customer ' ||
                   lv_rec_erp_i_costcenter.customernumber;
        update costcenter cc
        set    row = lv_rec_costcenter
        where  cc.costcenter_id = lv_rec_costcenter.costcenter_id;
      exception
        when no_data_found then
          begin
            --init_costcenter
            init_costcenter;
            --update_rec_costcenter
            update_rec_costcenter;
            --lv_rec_costcenter
            insert into costcenter values lv_rec_costcenter;
          end;
      end;
      --update_costcenterlink
      update_costcenter_link;
    end process_costcenter;
    -------------
  begin
    --proc_i_costc
    gv_text := 'proc_i_cost process erp_i_costcenter for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_costcenter;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_costcenter_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_costcenter fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_costcenter.customernumber
            and    fi.costcentercode = lv_rec_erp_i_costcenter.costcentercode)
    and    f.transfer_id < lv_rec_erp_i_costcenter.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_costcenter_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_costcenter zz
      where  zz.customernumber = lv_rec_erp_i_costcenter.customernumber
      and    zz.costcentercode = lv_rec_erp_i_costcenter.costcentercode
      and    zz.transfer_id < lv_rec_erp_i_costcenter.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_costcenter_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/costcenter ' || lv_rec_erp_i_costcenter.customernumber || '/' ||
               lv_rec_erp_i_costcenter.costcentercode, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/costcenter ' || lv_rec_erp_i_costcenter.customernumber || '/' ||
                   lv_rec_erp_i_costcenter.costcentercode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/costcenter ' ||
                   lv_rec_erp_i_costcenter.customernumber || '/' ||
                   lv_rec_erp_i_costcenter.costcentercode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/costcenter ' ||
                   lv_rec_erp_i_costcenter.customernumber || '/' ||
                   lv_rec_erp_i_costcenter.costcentercode, 1, 0);
      end;
  end proc_i_cost_one;

  --process proc_i_cost
  procedure proc_i_cost(fp_transferid in erp_i_costcenter.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.costcentercode
                 from   erp_i_costcenter eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_costcenter eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.costcentercode = pscx.costcentercode) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_costcenter eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_cost_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_cost;

  --process proc_i_cost_all
  procedure proc_i_cost_all is
  begin
    for pce in (select l.transfer_id
                from   erp_i_costcenter l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_cost(pce.transfer_id);
      end;
    end loop; --e
  end proc_i_cost_all;

  --process erp_i_deliverypoint
  procedure proc_i_delp_one(fp_transferid in erp_i_deliverypoint.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_deliverypoint erp_i_deliverypoint%rowtype;
    lv_log_tablename           varchar2(32) := 'ERP_I_DELIVERYPOINT_LOG';
    lv_process_status          number := 0;
    -------------
    --internal procedure functions from proc_i_delp
    function read_line return number is
    begin
      --read_line erp_i_deliverypoint
      select eis.*
      into   lv_rec_erp_i_deliverypoint
      from   erp_i_deliverypoint eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_deliverypoint eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_deliverypoint.customernumber
      and    eis.deliverypointcode = lv_rec_erp_i_deliverypoint.deliverypointcode;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_deliverypoint is
      lv_rec_deliverypoint deliverypoint%rowtype;
      lv_customerid        deliverypoint.customer_id%type;
      -------------
      --internal procedure functions from process_DELIVERYPOINT
      procedure init_deliverypoint is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_deliverypoint';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'DELIVERYPOINT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_deliverypoint;
        close rcur_typ;
        --get id
        select seq_deliverypoint.nextval into lv_rec_deliverypoint.deliverypoint_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_deliverypoint.code        := lv_rec_erp_i_deliverypoint.deliverypointcode;
        lv_rec_deliverypoint.customer_id := lv_customerid;
        --set missing defaults
        --...
      end init_deliverypoint;
    
      procedure update_rec_deliverypoint is
        lv_custdel_addrrid customer.visitaddress_id%type;
      begin
        --get customer visit address
        select c.visitaddress_id
        into   lv_custdel_addrrid
        from   customer c
        where  c.customer_id = lv_customerid;
        --update_rec_deliverypoint
        lv_rec_deliverypoint.description        := lv_rec_erp_i_deliverypoint.description;
        lv_rec_deliverypoint.deliveryaddress_id := insert_or_update_addressid(lv_rec_deliverypoint.deliveryaddress_id,
                                                                              lv_rec_erp_i_deliverypoint.address,
                                                                              lv_rec_erp_i_deliverypoint.address2,
                                                                              lv_rec_erp_i_deliverypoint.zipcode,
                                                                              lv_rec_erp_i_deliverypoint.city,
                                                                              'Y', lv_custdel_addrrid,
                                                                              null, null);
        lv_rec_deliverypoint.systemuser_id      := gv_erp_systemuserid;
        lv_rec_deliverypoint.timestamp          := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_deliverypoint;
    
      procedure update_deliverypoint_link is
      begin
        --update_deliverypoint_link
        gv_text := 'proc_i_delp.update_deliverypoint_link for deliverypoint code ' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode || ' customer ' ||
                   lv_rec_erp_i_deliverypoint.customernumber;
        update deliverypoint_link cl
        set    cl.description = lv_rec_deliverypoint.description
        where  cl.deliverypoint_id = lv_rec_deliverypoint.deliverypoint_id;
        if sql%rowcount = 0 then
          begin
            insert into deliverypoint_link
              (deliverypoint_link_id, deliverypoint_id, customer_link_id, code, description,
               systemuser_id, timestamp)
            values
              (lv_rec_deliverypoint.deliverypoint_id, lv_rec_deliverypoint.deliverypoint_id,
               lv_customerid, lv_rec_deliverypoint.code, lv_rec_deliverypoint.description,
               gv_erp_systemuserid, sysdate);
          end;
        end if;
      end update_deliverypoint_link;
      -------------
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_deliverypoint.customernumber);
      begin
        --process_deliverypoint
        gv_text := 'proc_i_delp.process_deliverypoint for deliverypoint code ' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode || ' customer ' ||
                   lv_rec_erp_i_deliverypoint.customernumber;
        --process_deliverypoint UPDATE
        select dp.*
        into   lv_rec_deliverypoint
        from   deliverypoint dp
        where  dp.code = lv_rec_erp_i_deliverypoint.deliverypointcode
        and    dp.customer_id = lv_customerid;
        --update_rec_deliverypoint
        update_rec_deliverypoint;
        --update record
        gv_text := 'proc_i_delp.process_deliverypoint update for deliverypoint code ' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode || ' customer ' ||
                   lv_rec_erp_i_deliverypoint.customernumber;
        update deliverypoint dp
        set    row = lv_rec_deliverypoint
        where  dp.deliverypoint_id = lv_rec_deliverypoint.deliverypoint_id;
      exception
        when no_data_found then
          begin
            --init_deliverypoint
            init_deliverypoint;
            --update_rec_deliverypoint
            update_rec_deliverypoint;
            --insert new deliverypoint
            gv_text := 'proc_i_delp.process_deliverypoint insert new deliverypoint code ' ||
                       lv_rec_erp_i_deliverypoint.deliverypointcode || ' customer ' ||
                       lv_rec_erp_i_deliverypoint.customernumber;
            insert into deliverypoint values lv_rec_deliverypoint;
          end;
      end;
      -- update deliverypoint link
      update_deliverypoint_link;
    end process_deliverypoint;
    -------------
  begin
    --proc_i_delp
    gv_text := 'proc_i_delp process erp_i_deliverypoint for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_deliverypoint;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_deliverypoint_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_deliverypoint fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_deliverypoint.customernumber
            and    fi.deliverypointcode = lv_rec_erp_i_deliverypoint.deliverypointcode)
    and    f.transfer_id < lv_rec_erp_i_deliverypoint.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_deliverypoint_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_deliverypoint zz
      where  zz.customernumber = lv_rec_erp_i_deliverypoint.customernumber
      and    zz.deliverypointcode = lv_rec_erp_i_deliverypoint.deliverypointcode
      and    zz.transfer_id < lv_rec_erp_i_deliverypoint.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_deliverypoint_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/del.point ' || lv_rec_erp_i_deliverypoint.customernumber || '/' ||
               lv_rec_erp_i_deliverypoint.deliverypointcode, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/del.point ' ||
                   lv_rec_erp_i_deliverypoint.customernumber || '/' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/del.point ' ||
                   lv_rec_erp_i_deliverypoint.customernumber || '/' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/del.point ' ||
                   lv_rec_erp_i_deliverypoint.customernumber || '/' ||
                   lv_rec_erp_i_deliverypoint.deliverypointcode, 1, 0);
      end;
  end proc_i_delp_one;

  --process proc_i_delp
  procedure proc_i_delp(fp_transferid in erp_i_deliverypoint.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.deliverypointcode
                 from   erp_i_deliverypoint eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_deliverypoint eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.deliverypointcode = pscx.deliverypointcode) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_deliverypoint eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_delp_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_delp;

  --process proc_i_delp_all
  procedure proc_i_delp_all is
  begin
    for pfa in (select l.transfer_id
                from   erp_i_deliverypoint l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_delp(pfa.transfer_id);
      end;
    end loop; --f
  end proc_i_delp_all;

  --process erp_i_department
  procedure proc_i_depart_one(fp_transferid in erp_i_department.transfer_id%type,
                              fp_rerun      in number default 0) is
    lv_rec_erp_i_department erp_i_department%rowtype;
    lv_log_tablename        varchar2(32) := 'ERP_I_DEPARTMENT_LOG';
    lv_process_status       number := 0;
    lv_customerid           department.customer_id%type;
    -------------
    --internal procedure functions from proc_i_depart
    function read_line return number is
    begin
      --read_line erp_i_department
      select eis.*
      into   lv_rec_erp_i_department
      from   erp_i_department eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_department eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_department.customernumber
      and    eis.departmentnumber = lv_rec_erp_i_department.departmentnumber;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_department is
      lv_rec_department department%rowtype;
      -------------
      --internal procedure functions from process_department
      procedure init_department is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_department';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'DEPARTMENT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_department;
        close rcur_typ;
        --get id
        select seq_department.nextval into lv_rec_department.department_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_department.departmentnumber := lv_rec_erp_i_department.departmentnumber;
        lv_rec_department.customer_id      := lv_customerid;
        --set missing defaults
        lv_rec_department.occupancy          := 100;
        lv_rec_department.standardpackamount := 'Y';
        lv_rec_department.active             := 'Y';
        lv_rec_department.delnotetoemail     := 'N';
        lv_rec_department.bulkdeliveriesdept := 'N';
      end init_department;
    
      procedure update_rec_department is
      begin
        --update_rec_department
        lv_rec_department.description          := lv_rec_erp_i_department.description;
        lv_rec_department.costcenter_id        := get_costcenterid(lv_rec_erp_i_department.costcentercode,
                                                                   lv_customerid);
        lv_rec_department.legacydepartmentcode := substr(to_char(lv_rec_erp_i_department.departmentnumber_old),
                                                         1, 12);
        lv_rec_department.systemuser_id        := gv_erp_systemuserid;
        lv_rec_department.timestamp            := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_department;
    
      procedure update_department_link is
      begin
        --update_department_link
        gv_text := 'proc_i_depart.update_department_link for department ' ||
                   lv_rec_erp_i_department.departmentnumber || ' customer ' ||
                   lv_rec_erp_i_department.customernumber;
        update department_link cl
        set    cl.description = lv_rec_erp_i_department.description
        where  cl.department_id = lv_rec_department.department_id;
        if sql%rowcount = 0 then
          begin
            insert into department_link
              (department_link_id, department_id, customer_link_id, departmentnumber, description,
               systemuser_id, legacydepartmentcode, timestamp)
            values
              (lv_rec_department.department_id, lv_rec_department.department_id, lv_customerid,
               lv_rec_department.departmentnumber, lv_rec_erp_i_department.description,
               gv_erp_systemuserid,
               substr(to_char(lv_rec_erp_i_department.departmentnumber_old), 1, 12), sysdate);
          end;
        end if;
      end update_department_link;
      -------------
    begin
      begin
        --process_department
        gv_text := 'proc_i_depart.process_department for department ' ||
                   lv_rec_erp_i_department.departmentnumber || ' customer ' ||
                   lv_rec_erp_i_department.customernumber;
        --process_department UPDATE
        select t.*
        into   lv_rec_department
        from   department t
        where  t.departmentnumber = lv_rec_erp_i_department.departmentnumber
        and    t.customer_id = lv_customerid;
        --update_rec_department
        update_rec_department;
        --update record
        gv_text := 'proc_i_depart.process_department update for department ' ||
                   lv_rec_erp_i_department.departmentnumber || ' customer ' ||
                   lv_rec_erp_i_department.customernumber;
        update department t
        set    row = lv_rec_department
        where  t.department_id = lv_rec_department.department_id;
      exception
        when no_data_found then
          begin
            --init_department
            init_department;
            --update_rec_department
            update_rec_department;
            --insert department
            gv_text := 'proc_i_depart.process_department insert for department ' ||
                       lv_rec_erp_i_department.departmentnumber || ' customer ' ||
                       lv_rec_erp_i_department.customernumber;
            insert into department values lv_rec_department;
          end;
      end;
      --update_department_link
      update_department_link;
    end process_department;
  
    procedure check_for_departments is
      lv_counter number;
    begin
      gv_text := 'check_for_departments';
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_department.customernumber);
      select count(1)
      into   lv_counter
      from   department t
      where  t.customer_id = lv_customerid
      and    t.active = 'Y';
      --ABS-129917 only add department when customer has none, never update
      if lv_counter = 0 then
        begin
          --process_department
          process_department;
        end;
      end if;
    end check_for_departments;
    -------------
  begin
    --proc_i_depart
    gv_text := 'proc_i_depart process erp_i_department for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          check_for_departments;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_department_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_department fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_department.customernumber
            and    fi.departmentnumber = lv_rec_erp_i_department.departmentnumber)
    and    f.transfer_id < lv_rec_erp_i_department.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_department_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_department zz
      where  zz.customernumber = lv_rec_erp_i_department.customernumber
      and    zz.departmentnumber = lv_rec_erp_i_department.departmentnumber
      and    zz.transfer_id < lv_rec_erp_i_department.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_department_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/department ' || lv_rec_erp_i_department.customernumber || '/' ||
               lv_rec_erp_i_department.departmentnumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/department ' || lv_rec_erp_i_department.customernumber || '/' ||
                   lv_rec_erp_i_department.departmentnumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/department ' ||
                   lv_rec_erp_i_department.customernumber || '/' ||
                   lv_rec_erp_i_department.departmentnumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/department ' ||
                   lv_rec_erp_i_department.customernumber || '/' ||
                   lv_rec_erp_i_department.departmentnumber, 1, 0);
      end;
  end proc_i_depart_one;

  --process proc_i_depart
  procedure proc_i_depart(fp_transferid in erp_i_department.transfer_id%type,
                          fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.departmentnumber
                 from   erp_i_department eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_department eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.departmentnumber = pscx.departmentnumber) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_department eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_depart_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_depart;

  --process proc_i_depart_all
  procedure proc_i_depart_all is
  begin
    for pdg in (select l.transfer_id
                from   erp_i_department l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_depart(pdg.transfer_id);
      end;
    end loop; --g
  end proc_i_depart_all;

  --process erp_i_consumptionpoint
  procedure proc_i_cons_one(fp_transferid in erp_i_consumptionpoint.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_rec_erp_i_consumptionpoint erp_i_consumptionpoint%rowtype;
    lv_rec_distributionpoint      distributionpoint%rowtype;
    lv_log_tablename              varchar2(32) := 'ERP_I_CONSUMPTIONPOINT_LOG';
    lv_process_status             number := 0;
    -------------
    --internal procedure functions from proc_i_cons
    function read_line return number is
    begin
      --read_line erp_i_consumptionpoint
      select eis.*
      into   lv_rec_erp_i_consumptionpoint
      from   erp_i_consumptionpoint eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_consumptionpoint eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.customernumber = lv_rec_erp_i_consumptionpoint.customernumber
      and    eis.departmentnumber = lv_rec_erp_i_consumptionpoint.departmentnumber
      and    eis.consumptionpointnumber = lv_rec_erp_i_consumptionpoint.consumptionpointnumber;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_consumptionpoint is
      lv_customerid   customer.customer_id%type;
      lv_departmentid department.department_id%type;
      -------------
      --internal procedure functions from process_consumptionpoint
      procedure init_consumptionpoint is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_DISTRIBUTIONPOINT';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'DISTRIBUTIONPOINT'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_distributionpoint;
        close rcur_typ;
        --get id
        select seq_distributionpoint.nextval
        into   lv_rec_distributionpoint.distributionpoint_id
        from   dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_distributionpoint.department_id           := lv_departmentid;
        lv_rec_distributionpoint.distributionpointnumber := lv_rec_erp_i_consumptionpoint.consumptionpointnumber;
        --set missing defaults
        lv_rec_distributionpoint.packremarkenddate    := gv_endddate;
        lv_rec_distributionpoint.deliverremarkenddate := gv_endddate;
      end init_consumptionpoint;
      procedure update_rec_consumptionpoint is
      begin
        --update_rec_consumptionpoint
        lv_rec_distributionpoint.legacydistributionpointnumber := lv_rec_erp_i_consumptionpoint.legacydistributionpointnumber;
        lv_rec_distributionpoint.description                   := lv_rec_erp_i_consumptionpoint.description;
        lv_rec_distributionpoint.deliverypoint_id              := get_deliverypointid(lv_rec_erp_i_consumptionpoint.deliverypointcode,
                                                                                      lv_customerid);
        lv_rec_distributionpoint.costcenter_id                 := get_costcenterid(lv_rec_erp_i_consumptionpoint.costcentercode,
                                                                                   lv_customerid);
        lv_rec_distributionpoint.active                        := lv_rec_erp_i_consumptionpoint.active;
        lv_rec_distributionpoint.systemuser_id                 := gv_erp_systemuserid;
        lv_rec_distributionpoint.timestamp                     := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_consumptionpoint;
    
      procedure update_consumptionpoint_link is
      begin
        --update_consumptionpoint_link
        gv_text := 'proc_i_cons.update_consumptionpoint_link for consumptionpoint ' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber || ' customer ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber;
        update distributionpoint_link dl
        set    dl.description = lv_rec_erp_i_consumptionpoint.description
        where  dl.distributionpoint_id = lv_rec_distributionpoint.distributionpoint_id;
        if sql%rowcount = 0 then
          begin
            insert into distributionpoint_link
              (distributionpoint_link_id, distributionpoint_id, department_link_id,
               distributionpointnumber, description, systemuser_id, legacydistributionpointnumber,
               timestamp)
            values
              (lv_rec_distributionpoint.distributionpoint_id,
               lv_rec_distributionpoint.distributionpoint_id, lv_departmentid,
               lv_rec_distributionpoint.distributionpointnumber,
               lv_rec_erp_i_consumptionpoint.description, gv_erp_systemuserid,
               substr(to_char(lv_rec_erp_i_consumptionpoint.consumptionpointnumber_old), 1, 6),
               sysdate);
          end;
        end if;
      end update_consumptionpoint_link;
    
      procedure process_standarddelivery is
        lv_standarddeliveryid standarddelivery.standarddelivery_id%type;
      begin
        --process_standarddelivery
        gv_text := 'process_standarddelivery';
        select min(std.standarddelivery_id)
        into   lv_standarddeliveryid
        from   standarddelivery std
        where  std.distributionpoint_id = lv_rec_distributionpoint.distributionpoint_id;
        if lv_standarddeliveryid is null then
          begin
            gv_text := 'insert into standarddelivery';
            insert into standarddelivery
              (standarddelivery_id, sequencenumber, deliversterile, plantdepartment_id, cleanreturn,
               transportarticle_id, generatezerolines, numberoftransportarticles,
               distributionpoint_id, lastpackingdate, truckloadposition, correctoverdeliveries,
               correctshortages, systemuser_id, timestamp)
              select seq_standarddelivery.nextval, 1, 'N', null, 'N', ts.transportarticle_id, 'N', 1,
                     lv_rec_distributionpoint.distributionpoint_id, null, 'N', 'N', 'N',
                     gv_erp_systemuserid, sysdate
              from   transportarticle ts
              where  rownum = 1;
          end;
        end if;
      end process_standarddelivery;
      -------------
    begin
      --get customer id
      lv_customerid := get_customerid(lv_rec_erp_i_consumptionpoint.customernumber);
      --get department id
      lv_departmentid := get_departmentid(lv_rec_erp_i_consumptionpoint.departmentnumber,
                                          lv_customerid);
      begin
        --process_consumptionpoint
        gv_text := 'proc_i_cons.process_consumptionpoint for consumptionpoint ' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber || ' customer ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber || ' department ' ||
                   lv_rec_erp_i_consumptionpoint.departmentnumber;
        --process_consumptionpoint UPDATE
        select dp.*
        into   lv_rec_distributionpoint
        from   distributionpoint dp
        where  dp.distributionpointnumber = lv_rec_erp_i_consumptionpoint.consumptionpointnumber
        and    dp.department_id = lv_departmentid;
        --update_rec_consumptionpoint
        update_rec_consumptionpoint;
        --update record
        gv_text := 'proc_i_cons.process_consumptionpoint update consumptionpoint ' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber || ' customer ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber || ' department ' ||
                   lv_rec_erp_i_consumptionpoint.departmentnumber;
        update distributionpoint t
        set    row = lv_rec_distributionpoint
        where  t.distributionpoint_id = lv_rec_distributionpoint.distributionpoint_id;
      exception
        when no_data_found then
          begin
            --init_consumptionpoint
            init_consumptionpoint;
            --update_rec_consumptionpoint
            update_rec_consumptionpoint;
            --insert into distributionpoint
            gv_text := 'proc_i_cons.process_consumptionpoint insert consumptionpoint ' ||
                       lv_rec_erp_i_consumptionpoint.consumptionpointnumber || ' customer ' ||
                       lv_rec_erp_i_consumptionpoint.customernumber || ' department ' ||
                       lv_rec_erp_i_consumptionpoint.departmentnumber;
            insert into distributionpoint values lv_rec_distributionpoint;
          end;
      end;
      --update_consumptionpoint_link
      update_consumptionpoint_link;
      --process_standarddelivery
      process_standarddelivery;
    end process_consumptionpoint;
    -------------
  begin
    --proc_i_cons
    gv_text := 'proc_i_cons process erp_i_consumptionpoint for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_consumptionpoint;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_consumptionpoint_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists
     (select fi.transfer_id
            from   erp_i_consumptionpoint fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_consumptionpoint.customernumber
            and    fi.departmentnumber = lv_rec_erp_i_consumptionpoint.departmentnumber
            and    fi.consumptionpointnumber = lv_rec_erp_i_consumptionpoint.consumptionpointnumber)
    and    f.transfer_id < lv_rec_erp_i_consumptionpoint.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_consumptionpoint_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_consumptionpoint zz
      where  zz.customernumber = lv_rec_erp_i_consumptionpoint.customernumber
      and    zz.departmentnumber = lv_rec_erp_i_consumptionpoint.departmentnumber
      and    zz.consumptionpointnumber = lv_rec_erp_i_consumptionpoint.consumptionpointnumber
      and    zz.transfer_id < lv_rec_erp_i_consumptionpoint.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_consumptionpoint_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer/department/cons. ' || lv_rec_erp_i_consumptionpoint.customernumber || '/' ||
               lv_rec_erp_i_consumptionpoint.departmentnumber || '/' ||
               lv_rec_erp_i_consumptionpoint.consumptionpointnumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer/department/cons. ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.departmentnumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer/department/cons. ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.departmentnumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer/department/cons. ' ||
                   lv_rec_erp_i_consumptionpoint.customernumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.departmentnumber || '/' ||
                   lv_rec_erp_i_consumptionpoint.consumptionpointnumber, 1, 0);
      end;
  end proc_i_cons_one;

  --process proc_i_cons
  procedure proc_i_cons(fp_transferid in erp_i_consumptionpoint.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.customernumber, eic.departmentnumber, eic.consumptionpointnumber
                 from   erp_i_consumptionpoint eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_consumptionpoint eic
                     where  eic.customernumber = pscx.customernumber
                     and    eic.departmentnumber = pscx.departmentnumber
                     and    eic.consumptionpointnumber = pscx.consumptionpointnumber) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_consumptionpoint eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_cons_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_cons;

  --process proc_i_cons_all
  procedure proc_i_cons_all is
  begin
    for pcga in (select l.transfer_id
                 from   erp_i_consumptionpoint l
                 where  l.transfer_status = 0
                 order  by l.transfer_id) loop
      begin
        proc_i_cons(pcga.transfer_id);
      end;
    end loop; --g
  end proc_i_cons_all;

  --process erp_i_productlistpercustomer
  procedure proc_i_plpc_one(fp_transferid in erp_i_productlistpercustomer.transfer_id%type,
                            fp_rerun      in number default 0) is
    lv_log_tablename  varchar2(32) := 'ERP_I_PRODUCTLISTPERCUST_LOG';
    lv_process_status number := 0;
    lv_rec_erp_i_plpc erp_i_productlistpercustomer%rowtype;
    -------------
    --internal procedure functions from proc_i_cust
    function read_line return number is
    begin
      --read_line ERP_i_plpc
      select eis.*
      into   lv_rec_erp_i_plpc
      from   erp_i_productlistpercustomer eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_productlistpercustomer eis
      set    eis.transfer_status = 1
      where  eis.transfer_id = fp_transferid;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_plpc is
      --process_plpc locale variables
      lv_plpcid                productlistpercustomer.productlistpercustomer_id%type;
      lv_customerid            customer.customer_id%type;
      lv_dateactive            date;
      lv_dateinactive          date;
      lv_businessunitid        number;
      lv_plantid               plant.plant_id%type;
      lv_productid             product.product_id%type;
      lv_productgroupid        productgroup.productgroup_id%type;
      lv_sizeid                sizedefinition.sizedefinition_id%type;
      lv_finishingmethodid     finishingmethod.finishingmethod_id%type;
      lv_emblemtemplateid      emblemtemplate.emblemtemplate_id%type;
      lv_salesemployeeid       employee.employee_id%type;
      lv_salesemployee2id      employee.employee_id%type;
      lv_gaincompetitorid      competitor.competitor_id%type;
      lv_gainreasonid          gainlostreason.gainlostreason_id%type;
      lv_lostcompetitorid      competitor.competitor_id%type;
      lv_lostreasonid          gainlostreason.gainlostreason_id%type;
      lv_residualvalueschemeid residualvaluescheme.residualvaluescheme_id%type;
      lv_deedeliveryschemeid   productlistpercustomer.deedeliveryscheme_id%type;
      lv_defaultstockroomid    stockroom.stockroom_id%type;
      lv_deliverylabellayoutid labellayout.labellayout_id%type;
      lv_treatmentcheckschemid treatmentcheckscheme.treatmentcheckscheme_id%type;
      lv_washingprocessid      washingprocess.washingprocess_id%type;
    
      procedure get_childinfo is
        procedure getplantid4bu is
        begin
          --getplantid4bu
          gv_text := 'get plant for businessunit (customer) ' ||
                     nvl(to_char(lv_businessunitid), 'NULL');
          select bu.plant_id
          into   lv_plantid
          from   businessunit bu
          where  bu.businessunit_id = lv_businessunitid;
        end getplantid4bu;
      begin
        --get_childinfo
        gv_text := 'get_childinfo';
        --get customer id
        lv_customerid := get_customerid(lv_rec_erp_i_plpc.customernumber, 0, lv_dateactive,
                                        lv_dateinactive, lv_businessunitid);
        --get plant for customers default BU
        getplantid4bu;
        --get product id
        lv_productid := get_productid(lv_rec_erp_i_plpc.productcode, lv_productgroupid);
        --get size id
        lv_sizeid := get_sizeid(lv_rec_erp_i_plpc.sizecode, 0);
        --get finishingmethod id
        lv_finishingmethodid := get_finishingmethodid(lv_rec_erp_i_plpc.finishingmethodcode);
        --get sales employee
        lv_salesemployeeid  := get_employeeid(lv_rec_erp_i_plpc.salesemployeenumber, lv_plantid);
        lv_salesemployee2id := get_employeeid(lv_rec_erp_i_plpc.salesemployeenumber2, lv_plantid);
        --get emblemtemplate id
        lv_emblemtemplateid := get_emblemtemplateid(lv_customerid, lv_rec_erp_i_plpc.emblemtemplate);
        --get gainlostreason / competitor
        lv_gainreasonid     := get_gainlostreasonid(lv_rec_erp_i_plpc.gainreasoncode,
                                                    lv_rec_erp_i_plpc.gainreasondescription);
        lv_gaincompetitorid := get_competitorid(lv_rec_erp_i_plpc.gaincompetitorcode,
                                                lv_rec_erp_i_plpc.gaincompetitorname);
        lv_lostreasonid     := get_gainlostreasonid(lv_rec_erp_i_plpc.lostreasoncode,
                                                    lv_rec_erp_i_plpc.lostreasondescription);
        lv_lostcompetitorid := get_competitorid(lv_rec_erp_i_plpc.lostcompetitorcode,
                                                lv_rec_erp_i_plpc.lostcompetitorname);
        --get deedeliveryschemeid
        lv_deedeliveryschemeid := get_deliveryschemeid(lv_rec_erp_i_plpc.ddedeliveryschemecode);
        --get residualvalue scheme id
        lv_residualvalueschemeid := get_residualvalueschemeid(lv_rec_erp_i_plpc.residualvalueschemecode);
        --get default stockroom
        lv_defaultstockroomid := get_stockroomid(lv_rec_erp_i_plpc.defaultstockroom);
        --5 OR Delivery label 
        lv_deliverylabellayoutid := get_labellayout(lv_rec_erp_i_plpc.deliverylabellayout, 5);
        --get treatment check scheme
        lv_treatmentcheckschemid := get_treatmentcheckid(lv_rec_erp_i_plpc.treatmentcheckschemecode);
        --get washing process
        lv_washingprocessid := get_washingprocess(lv_rec_erp_i_plpc.washingprocesscode);
      end get_childinfo;
    
      procedure check_plpc_data is
      begin
        --check_plpc_data
        gv_text := 'add missing productgrouppercustomer';
        insert into productgrouppercustomer
          (productgroup_id, customer_id, systemuser_id, timestamp, active)
          select pg.productgroup_id, lv_customerid, gv_erp_systemuserid, sysdate, 'Y'
          from   productgroup pg
          where  pg.productgroup_id = lv_productgroupid
          and    not exists (select 1
                  from   productgrouppercustomer pgx
                  where  pgx.customer_id = lv_customerid
                  and    pgx.productgroup_id = pg.productgroup_id);
      end check_plpc_data;
    
      --process_plpc
      procedure process_plpc is
        procedure update_plpc is
        begin
          --update_plpc
          gv_text := 'update_plpc';
          --unique value for interface customer/product/size/finishingmethod
          update productlistpercustomer l
          set    l.dateinactive = nvl(lv_rec_erp_i_plpc.dateinactive, l.dateinactive),
                 l.codeuniquely = nvl(lv_rec_erp_i_plpc.codeuniquely, l.codeuniquely),
                 l.soilweight = nvl(lv_rec_erp_i_plpc.soilweight, l.soilweight),
                 l.onsiteinventorycount = nvl(lv_rec_erp_i_plpc.onsiteinventorycount,
                                               l.onsiteinventorycount),
                 l.billingmethod = lv_rec_erp_i_plpc.billingmethod,
                 l.changesperweek = nvl(lv_rec_erp_i_plpc.changesperweek, l.changesperweek),
                 l.chargeoveruse = nvl(lv_rec_erp_i_plpc.chargeoveruse, l.chargeoveruse),
                 l.minimumfrequency = nvl(lv_rec_erp_i_plpc.minimumfrequency, l.minimumfrequency),
                 l.minimumturnaround = nvl(lv_rec_erp_i_plpc.minimumturnaround, l.minimumturnaround),
                 l.minimumquantity = nvl(lv_rec_erp_i_plpc.minimumquantity, l.minimumquantity),
                 l.inventorybillingtype = nvl(lv_rec_erp_i_plpc.inventorybillingtype,
                                               l.inventorybillingtype),
                 l.percentageafterdepreciation = nvl(lv_rec_erp_i_plpc.percentafterdepreciation,
                                                      l.percentageafterdepreciation),
                 l.soilcountmethod = nvl(lv_rec_erp_i_plpc.soilcountmethod, l.soilcountmethod),
                 l.cleancount = nvl(lv_rec_erp_i_plpc.cleancount, l.cleancount),
                 l.srcmethod = nvl(lv_rec_erp_i_plpc.srcmethod, l.srcmethod),
                 l.srcfrequency = nvl(lv_rec_erp_i_plpc.srcfrequency, l.srcfrequency),
                 l.srcpercentagesoilcount = nvl(lv_rec_erp_i_plpc.srcpercentagesoilcount,
                                                 l.srcpercentagesoilcount),
                 l.srcpercentageinventory = nvl(lv_rec_erp_i_plpc.srcpercentageinventory,
                                                 l.srcpercentageinventory),
                 l.srcquantity = nvl(lv_rec_erp_i_plpc.srcquantity, l.srcquantity),
                 l.deliverreplacementqty = nvl(lv_rec_erp_i_plpc.deliverreplacementqty,
                                                l.deliverreplacementqty),
                 l.chargestockroominventory = nvl(lv_rec_erp_i_plpc.chargestockroominventory,
                                                   l.chargestockroominventory),
                 l.qtyfreeofcharge = nvl(lv_rec_erp_i_plpc.qtyfreeofcharge, l.qtyfreeofcharge),
                 l.customcode = lv_rec_erp_i_plpc.customcode,
                 l.customdescription = lv_rec_erp_i_plpc.customdescription,
                 l.custombundlesize = nvl(lv_rec_erp_i_plpc.custombundlesize, l.custombundlesize),
                 l.gaincompetitor_id = lv_gaincompetitorid,
                 l.lostcompetitor_id = lv_lostcompetitorid, l.gainreason_id = lv_gainreasonid,
                 l.lostreason_id = lv_lostreasonid,
                 l.residualvaluescheme_id = nvl(lv_residualvalueschemeid, l.residualvaluescheme_id),
                 l.delayedevenexchange = case
                                           when (lv_rec_erp_i_plpc.delayedevenexchange is null and
                                                lv_rec_erp_i_plpc.ddedeliveryschemecode is null and
                                                l.delayedevenexchange = 7) then
                                            0
                                           else
                                            nvl(lv_rec_erp_i_plpc.delayedevenexchange,
                                                l.delayedevenexchange)
                                         end,
                 l.quantityreturned = nvl(lv_rec_erp_i_plpc.quantityreturned, l.quantityreturned),
                 l.eannumber = lv_rec_erp_i_plpc.plpceannumber,
                 l.specificputuptype = nvl(lv_rec_erp_i_plpc.specificputuptype, l.specificputuptype),
                 l.salesemployee_id = lv_salesemployeeid,
                 l.returnstockallowed = nvl(lv_rec_erp_i_plpc.returnstockallowed,
                                             l.returnstockallowed),
                 l.straightevenexchange = nvl(lv_rec_erp_i_plpc.straightevenexchange,
                                               l.straightevenexchange),
                 l.customerrelated = nvl(lv_rec_erp_i_plpc.issuecustomerrelated, l.customerrelated),
                 l.deedeliveryscheme_id = lv_deedeliveryschemeid,
                 l.remark = lv_rec_erp_i_plpc.remark,
                 l.location = nvl(lv_rec_erp_i_plpc.location, l.location),
                 l.chargewashesonlyforcog = nvl(lv_rec_erp_i_plpc.chargewashesonlyforcog,
                                                 l.chargewashesonlyforcog),
                 l.rentpriceperfrequency = nvl(lv_rec_erp_i_plpc.rentpriceperfrequency,
                                                l.rentpriceperfrequency),
                 l.priceusage = nvl(lv_rec_erp_i_plpc.priceusage, l.priceusage),
                 l.emblemtemplate_id = nvl(lv_emblemtemplateid, l.emblemtemplate_id),
                 l.srcchargerent = nvl(lv_rec_erp_i_plpc.srcchargerent, l.srcchargerent),
                 l.treatmentcheckscheme_id = lv_treatmentcheckschemid,
                 l.deliverylabellayout_id = lv_deliverylabellayoutid,
                 l.salesemployee2_id = lv_salesemployee2id,
                 l.defaultstockroom_id = lv_defaultstockroomid,
                 l.fixedstockroom = nvl(lv_rec_erp_i_plpc.fixedstockroom, l.fixedstockroom),
                 l.orderviaweb = nvl(lv_rec_erp_i_plpc.orderviaweb, l.orderviaweb),
                 l.freeqtyfrequency = nvl(lv_rec_erp_i_plpc.freeqtyfrequency, l.freeqtyfrequency),
                 l.internalcalcpercentagelog = nvl(lv_rec_erp_i_plpc.internalcalcpercentagelog,
                                                    l.internalcalcpercentagelog),
                 l.internalcalcpercentagecog = nvl(lv_rec_erp_i_plpc.internalcalcpercentagecog,
                                                    l.internalcalcpercentagecog),
                 l.chargeexcess = nvl(lv_rec_erp_i_plpc.chargeexcess, l.chargeexcess),
                 l.budgetusage = nvl(lv_rec_erp_i_plpc.budgetusage, l.budgetusage),
                 l.depositstockallowed = nvl(lv_rec_erp_i_plpc.depositstockallowed,
                                              l.depositstockallowed),
                 l.depositstockchargepercentage = nvl(lv_rec_erp_i_plpc.depositstockchargepercentage,
                                                       l.depositstockchargepercentage),
                 l.bm1fixedwearers = nvl(lv_rec_erp_i_plpc.bm1fixedwearers, l.bm1fixedwearers),
                 l.sterilisationrequired = nvl(lv_rec_erp_i_plpc.sterilisationrequired,
                                                l.sterilisationrequired),
                 l.imagecare = nvl(lv_rec_erp_i_plpc.imagecare, l.imagecare),
                 l.allowreturntostock = nvl(lv_rec_erp_i_plpc.allowreturntostock,
                                             l.allowreturntostock),
                 l.seasonalrent = nvl(lv_rec_erp_i_plpc.seasonalrent, l.seasonalrent),
                 l.autosoilpercentage = nvl(lv_rec_erp_i_plpc.autosoilpercentage,
                                             l.autosoilpercentage),
                 --FOR HIGHER ABSSOLUTE VESION ADD/CHECK TODO--
                 --l.budgetcode = nvl(lv_rec_erp_i_plpc.budgetcode, l.budgetcode),
                 --l.mmpspecificpercentage = nvl(lv_rec_erp_i_plpc.mmpspecificpercentage,
                 --                              l.mmpspecificpercentage),
                 --l.garmentsetup = nvl(lv_rec_erp_i_plpc.garmentsetup, l.garmentsetup),
                 --l.garmentmaintenance = nvl(lv_rec_erp_i_plpc.garmentmaintenance, l.garmentmaintenance),
                 --l.garmentloss = nvl(lv_rec_erp_i_plpc.garmentloss, l.garmentloss),
                 --l.garmentrepair = nvl(lv_rec_erp_i_plpc.garmentrepair,l.garmentrepair),
                 --l.contractcode = nvl(lv_rec_erp_i_plpc.contractcode, l.contractcode),
                 --l.mbyoppercentage = nvl(lv_rec_erp_i_plpc.mbyoppercentage, l.mbyoppercentage),
                 --l.seasontypecode = nvl(lv_rec_erp_i_plpc.seasontypecode, l.seasontypecode),
                 --l.chargewashinactiveseason = nvl(lv_rec_erp_i_plpc.chargewashinactiveseason,
                 --                                 l.chargewashinactiveseason),
                 --l.default_suppliernumber = nvl(lv_rec_erp_i_plpc.default_suppliernumber,
                 --                               l.default_suppliernumber),
                 --l.garmentlosspercentage = nvl(lv_rec_erp_i_plpc.garmentlosspercentage,
                 --                              l.garmentlosspercentage),
                 --l.garmentemblem = nvl(lv_rec_erp_i_plpc.garmentemblem, l.garmentemblem),
                 l.systemuser_id = gv_erp_systemuserid, l.timestamp = sysdate
          where  l.customer_id = lv_customerid
          and    l.product_id = lv_productid
          and    l.sizedefinition_id = lv_sizeid
          and    l.finishingmethod_id = lv_finishingmethodid
          returning l.productlistpercustomer_id into lv_plpcid;
        end update_plpc;
        procedure create_plpc is
        begin
          --create_plpc
          gv_text := 'create_plpc';
          insert into productlistpercustomer
            (productlistpercustomer_id, product_id, dateactive, dateinactive, finishingmethod_id,
             codeuniquely, customer_id, onsiteinventorycount, sizedefinition_id, systemuser_id,
             percentageafterdepreciation, timestamp, billingmethod, soilcountmethod, srcmethod,
             cleancount, srcpercentagesoilcount, srcpercentageinventory, srcquantity, srcfrequency,
             chargestockroominventory, minimumturnaround, minimumquantity, qtyfreeofcharge,
             customcode, customdescription, custombundlesize, gaincompetitor_id, gainreason_id,
             lostreason_id, lostcompetitor_id, residualvaluescheme_id, delayedevenexchange,
             emblemtemplate_id, chargeoveruse, changesperweek, deliverreplacementqty,
             minimumfrequency, washingprocess_id, automaticsales, autoreplafterlifetime,
             customerrelated, seasontype_id, rentpriceperfrequency, chargerentinactiveseason,
             chargewashespack, quantityreturned, straightevenexchange, finishingcode_id,
             specificputuptype, inventorybillingtype, freeqtyfrequency, salesemployee_id,
             returnstockallowed, maxwashes, remark, salesemployee2_id, eannumber, soilweight,
             deedeliveryscheme_id, allowreturntostock, seasonalrent, autosoilpercentage)
          values
            (seq_productlistpercustomer.nextval, lv_productid,
             nvl(lv_rec_erp_i_plpc.dateactive, lv_dateactive),
             nvl(lv_rec_erp_i_plpc.dateinactive, lv_dateinactive), lv_finishingmethodid,
             nvl(lv_rec_erp_i_plpc.codeuniquely, 'Y'), lv_customerid,
             nvl(lv_rec_erp_i_plpc.onsiteinventorycount, 'N'), lv_sizeid, gv_erp_systemuserid,
             nvl(lv_rec_erp_i_plpc.percentafterdepreciation, 100), sysdate,
             lv_rec_erp_i_plpc.billingmethod, nvl(lv_rec_erp_i_plpc.soilcountmethod, 0),
             nvl(lv_rec_erp_i_plpc.srcmethod, 0), nvl(lv_rec_erp_i_plpc.cleancount, 'N'),
             nvl(lv_rec_erp_i_plpc.srcpercentagesoilcount, 0),
             nvl(lv_rec_erp_i_plpc.srcpercentageinventory, 0), nvl(lv_rec_erp_i_plpc.srcquantity, 0),
             nvl(lv_rec_erp_i_plpc.srcfrequency, 0),
             nvl(lv_rec_erp_i_plpc.chargestockroominventory, 'N'),
             nvl(lv_rec_erp_i_plpc.minimumturnaround, 0), nvl(lv_rec_erp_i_plpc.minimumquantity, 0),
             nvl(lv_rec_erp_i_plpc.qtyfreeofcharge, 0), lv_rec_erp_i_plpc.customcode,
             lv_rec_erp_i_plpc.customdescription, nvl(lv_rec_erp_i_plpc.custombundlesize, 0),
             lv_gaincompetitorid, lv_gainreasonid, lv_lostreasonid, lv_lostcompetitorid,
             lv_residualvalueschemeid,
             case when lv_rec_erp_i_plpc.delayedevenexchange is null and
              lv_rec_erp_i_plpc.ddedeliveryschemecode is not null then 7 else
              nvl(lv_rec_erp_i_plpc.delayedevenexchange, 0) end, lv_emblemtemplateid,
             nvl(lv_rec_erp_i_plpc.chargeoveruse, 'N'), nvl(lv_rec_erp_i_plpc.changesperweek, 'N'),
             'N', nvl(lv_rec_erp_i_plpc.minimumfrequency, 0), lv_washingprocessid, 'N', 'N',
             nvl(lv_rec_erp_i_plpc.issuecustomerrelated, 'N'), null,
             nvl(lv_rec_erp_i_plpc.rentpriceperfrequency, 'N'), 'N', 1,
             nvl(lv_rec_erp_i_plpc.quantityreturned, 0),
             nvl(lv_rec_erp_i_plpc.straightevenexchange, 'N'), null, 0,
             nvl(lv_rec_erp_i_plpc.inventorybillingtype, 0),
             nvl(lv_rec_erp_i_plpc.freeqtyfrequency, 0), lv_salesemployeeid,
             nvl(lv_rec_erp_i_plpc.returnstockallowed, 'N'), 0, lv_rec_erp_i_plpc.remark,
             lv_salesemployee2id, lv_rec_erp_i_plpc.plpceannumber,
             nvl(lv_rec_erp_i_plpc.soilweight, 0), lv_deedeliveryschemeid,
             nvl(lv_rec_erp_i_plpc.allowreturntostock, 0), nvl(lv_rec_erp_i_plpc.seasonalrent, 0),
             nvl(lv_rec_erp_i_plpc.autosoilpercentage, 0))
          returning productlistpercustomer_id into lv_plpcid;
        end create_plpc;
      begin
        --process_plpc
        gv_text := 'process_plpc';
        --update_plpc
        update_plpc;
        if sql%rowcount = 0 then
          begin
            --create_plpc
            create_plpc;
            --update_plpc
            update_plpc;
          end;
        end if;
      end process_plpc;
    
      procedure update_plpcextrainfo is
      begin
        --update_plpcextrainfo
        gv_text := 'update plpcextrainfo';
        if lv_rec_erp_i_plpc.specificbulkpackingtype is not null then
          begin
            update plpcextrainfo pce
            set    pce.specificbulkpackingtype = nvl(lv_rec_erp_i_plpc.specificbulkpackingtype,
                                                      pce.specificbulkpackingtype),
                   pce.systemuser_id = gv_erp_systemuserid, pce.timestamp = sysdate
            where  exists
             (select 1
                    from   productlistpercustomer l
                    where  l.customer_id = lv_customerid
                    and    l.product_id = lv_productid
                    and    l.sizedefinition_id = lv_sizeid
                    and    l.finishingmethod_id = lv_finishingmethodid
                    and    l.productlistpercustomer_id = pce.productlistpercustomer_id);
            if sql%rowcount = 0 then
              begin
                gv_text := 'insert plpcextrainfo ';
                insert into plpcextrainfo
                  (productlistpercustomer_id, systemuser_id, timestamp, specificbulkpackingtype)
                  select l.productlistpercustomer_id, gv_erp_systemuserid, sysdate,
                         nvl(lv_rec_erp_i_plpc.specificbulkpackingtype, 0)
                  from   productlistpercustomer l
                  where  l.customer_id = lv_customerid
                  and    l.product_id = lv_productid
                  and    l.sizedefinition_id = lv_sizeid
                  and    l.finishingmethod_id = lv_finishingmethodid;
              end;
            end if;
          end;
        end if;
      end update_plpcextrainfo;
    
      procedure update_plpcchargepercentage is
      begin
        --update_plpcchargepercentage
        gv_text := 'update_plpcchargepercentage';
        --insert into plpcchargepercentage
        if (lv_rec_erp_i_plpc.losschargepercentage is not null or
           lv_rec_erp_i_plpc.srchargepercentage is not null) then
          begin
            update plpcchargepercentage pcp
            set    pcp.losschargepercentage = nvl(lv_rec_erp_i_plpc.losschargepercentage,
                                                   pcp.losschargepercentage),
                   pcp.srchargepercentage = nvl(lv_rec_erp_i_plpc.srchargepercentage,
                                                 pcp.srchargepercentage),
                   pcp.systemuser_id = gv_erp_systemuserid, pcp.timestamp = sysdate
            where  exists
             (select 1
                    from   productlistpercustomer l
                    where  l.customer_id = lv_customerid
                    and    l.product_id = lv_productid
                    and    l.sizedefinition_id = lv_sizeid
                    and    l.finishingmethod_id = lv_finishingmethodid
                    and    l.productlistpercustomer_id = pcp.productlistpercustomer_id);
            if sql%rowcount = 0 then
              begin
                gv_text := 'insert plpcextrainfo ';
                insert into plpcchargepercentage
                  (productlistpercustomer_id, losschargepercentage, srchargepercentage,
                   systemuser_id, timestamp)
                  select l.productlistpercustomer_id,
                         nvl(lv_rec_erp_i_plpc.losschargepercentage, 100),
                         nvl(lv_rec_erp_i_plpc.srchargepercentage, 100), gv_erp_systemuserid,
                         sysdate
                  from   productlistpercustomer l
                  where  l.customer_id = lv_customerid
                  and    l.product_id = lv_productid
                  and    l.sizedefinition_id = lv_sizeid
                  and    l.finishingmethod_id = lv_finishingmethodid;
              end;
            end if;
          end;
        end if;
      end update_plpcchargepercentage;
    
      procedure update_rentalqtyadjustment is
        lv_productlistperdistribpointid productlistperdistribpoint.productlistperdistribpoint_id%type;
        lv_reasoncodeid                 reasoncode.reasoncode_id%type;
        lv_minqualitygradeid            qualitygrade.qualitygrade_id%type;
      
        procedure get_plpd is
          lv_plpdpsequence       productlistperdistribpoint.countsequence%type;
          lv_distributionpointid distributionpoint.distributionpoint_id%type;
        begin
          ----get_plpd get product list per distributionpoint id
          gv_text := 'get_plpd get product list per distributionpoint id';
          select min(distributionpoint_id)
          into   lv_distributionpointid
          from   distributionpoint
          where  department_id =
                 (select min(department_id) from department where customer_id = lv_customerid);
          select min(plpd.productlistperdistribpoint_id)
          into   lv_productlistperdistribpointid
          from   productlistperdistribpoint plpd
          where  plpd.distributionpoint_id = lv_distributionpointid
          and    plpd.product_id = lv_productid
          and    plpd.sizedefinition_id = lv_sizeid
          and    plpd.finishingmethod_id = lv_finishingmethodid;
          if lv_productlistperdistribpointid is null then
            begin
              select max(countsequence) + 1
              into   lv_plpdpsequence
              from   productlistperdistribpoint plpd
              where  plpd.distributionpoint_id = lv_distributionpointid;
              if lv_plpdpsequence is null then
                lv_plpdpsequence := 1;
              end if;
              insert into productlistperdistribpoint
                (productlistperdistribpoint_id, distributionpoint_id, product_id, sizedefinition_id,
                 finishingmethod_id, countsequence, orderingmethod, holidayusagefactor,
                 systemuser_id, timestamp)
              values
                (seq_productlistperdistribpoint.nextval, lv_distributionpointid, lv_productid,
                 lv_sizeid, lv_finishingmethodid, lv_plpdpsequence, 2, 100, gv_erp_systemuserid,
                 sysdate)
              returning productlistperdistribpoint_id into lv_productlistperdistribpointid;
            end;
          end if;
        end get_plpd;
      
        procedure get_reasoncodeid is
        begin
          --get default reasoncode for reason code dash (-)
          gv_text := 'get default reasoncode for reason code dash (-)';
          select reasoncode_id into lv_reasoncodeid from reasoncode where reasoncode.code = '-';
        end get_reasoncodeid;
      
        procedure get_minqualitygradeid is
        begin
          --get_minqualitygradeid
          gv_text := 'get_minqualitygradeid';
          select min(q.qualitygrade_id) into lv_minqualitygradeid from qualitygrade q;
        end get_minqualitygradeid;
      begin
        --update_rentalqtyadjustment
        gv_text := 'update_rentalqtyadjustment';
        if (lv_rec_erp_i_plpc.sizecode <> '*' and
           (lv_rec_erp_i_plpc.fixedquantity > 0 or lv_rec_erp_i_plpc.circulatinginventory >= 0)) then
          begin
            --get_plpd get product list per distributionpoint id
            get_plpd;
            --get_reasoncodeid
            get_reasoncodeid;
            --get_minqualitygradeid
            get_minqualitygradeid;
            if lv_rec_erp_i_plpc.circulatinginventory >= 0 then
              begin
                --PRODUCTLISTPERDISTRIBPOINT_ID, ADJUSTMENTDATE, REASONCODE_ID, 
                --CANCELLATIONTIMESTAMP, DELIVERYVARIATIONS_ID
                update rentalqtyadjustment rqa
                set    rqa.quantity = lv_rec_erp_i_plpc.circulatinginventory,
                       rqa.timestamp = sysdate, rqa.systemuser_id = gv_erp_systemuserid
                where  rqa.productlistperdistribpoint_id = lv_productlistperdistribpointid
                and    rqa.adjustmentdate = nvl(lv_rec_erp_i_plpc.dateactive, lv_dateactive)
                and    rqa.reasoncode_id = lv_reasoncodeid
                and    rqa.cancellationtimestamp is null
                and    rqa.deliveryvariations_id is null;
                if sql%rowcount = 0 then
                  begin
                    insert into rentalqtyadjustment
                      (rentalqtyadjustment_id, productlistperdistribpoint_id, remark, quantity,
                       adjustmentdate, reasoncode_id, timestamp, systemuser_id, qualitygrade_id,
                       quantityfirstdelivery)
                    values
                      (seq_rentalqtyadjustment.nextval, lv_productlistperdistribpointid, null,
                       lv_rec_erp_i_plpc.circulatinginventory,
                       nvl(lv_rec_erp_i_plpc.dateactive, lv_dateactive), lv_reasoncodeid, sysdate,
                       gv_erp_systemuserid, lv_minqualitygradeid,
                       nvl(lv_rec_erp_i_plpc.circulatinginventory, 0));
                  end;
                end if;
              end;
            end if;
            if lv_rec_erp_i_plpc.fixedquantity >= 0 then
              begin
                null;
                --todo update std delline fixedamount
                --not used for now
              end;
            end if;
          end;
        end if;
      end update_rentalqtyadjustment;
    
      procedure create_productdeliveryday(fp_dayid                in productdeliveryday.day_id%type,
                                          fp_deliverytype         in productdeliveryday.deliverytype%type,
                                          fp_circulatinginventory in i_productlistpercustomer.circulatinginventory%type,
                                          fp_percentage           in i_productlistpercustomer.srcpercentagesoilcount%type) is
        lv_no_of_days       number;
        lv_deliveryschemeid customerdeliveryscheme.deliveryscheme_id%type;
        procedure add_autosoil is
          lv_autosoil_systemsetting systemsetting.value%type;
        begin
          gv_text := 'add_autosoil';
          begin
            --get system setting AUTOSOIL
            select st.value
            into   lv_autosoil_systemsetting
            from   systemsetting st
            where  st.name = 'AUTOSOIL'
            and    st.plant_id = lv_plantid;
          exception
            when no_data_found then
              lv_autosoil_systemsetting := '0';
          end;
          --add_autosoil
          update autosoilquantity asq
          set    asq.quantity = case lv_autosoil_systemsetting
                                   when '1' then
                                    round((fp_percentage * nvl(fp_circulatinginventory, 0) / 100))
                                   when '2' then
                                    nvl(fp_circulatinginventory, 0)
                                   else
                                    0
                                 end, asq.systemuser_id = gv_erp_systemuserid,
                 asq.timestamp = sysdate
          where  asq.productlistpercustomer_id = lv_plpcid
          and    asq.day_id = fp_dayid;
          if sql%rowcount = 0 then
            begin
              insert into autosoilquantity
                (autosoilquantity_id, productlistpercustomer_id, day_id, quantity, systemuser_id,
                 timestamp)
              values
                (seq_autosoilquantity.nextval, lv_plpcid, fp_dayid,
                 case lv_autosoil_systemsetting when '1' then
                  round((fp_percentage * nvl(fp_circulatinginventory, 0) / 100)) when '2' then
                  nvl(fp_circulatinginventory, 0) else 0 end, gv_erp_systemuserid, sysdate);
            end;
          end if;
        end add_autosoil;
        procedure check_deliveryscheme is
          procedure add_deliveryscheme is
          begin
            --add_deliveryscheme
            gv_text := 'add_deliveryscheme';
            insert into customerdeliveryday
              (customer_id, day_id, timestamp, systemuser_id, deliverytype, typeofmerchadise)
              select lv_customerid, fp_dayid, sysdate, gv_erp_systemuserid, fp_deliverytype,
                     p.typeofmerchandise
              from   productlistpercustomer plpc
              join   product p
              on     plpc.product_id = p.product_id
              where  plpc.productlistpercustomer_id = lv_plpcid
              and    plpc.customer_id = lv_customerid;
            --insert into customerdeliveryscheme
            gv_text := 'insert into customerdeliveryscheme';
            insert into customerdeliveryscheme
              (customer_id, deliveryscheme_id, day_id, systemuser_id, timestamp, active)
              select lv_customerid, lv_deliveryschemeid, fp_dayid, gv_erp_systemuserid, sysdate, 'Y'
              from   dual
              where  not exists (select 1
                      from   customerdeliveryscheme cdd
                      where  cdd.customer_id = lv_customerid
                      and    cdd.day_id = fp_dayid
                      and    cdd.deliveryscheme_id = lv_deliveryschemeid);
          end add_deliveryscheme;
        begin
          --check_deliveryscheme
          gv_text := 'check_deliveryscheme';
          select max(cs.deliveryscheme_id)
          into   lv_deliveryschemeid
          from   customerdeliveryscheme cs
          where  cs.customer_id = lv_customerid
          and    cs.active = 'Y';
          if lv_deliveryschemeid is null then
            begin
              select max(ds.deliveryscheme_id)
              into   lv_deliveryschemeid
              from   deliveryscheme ds
              where  ds.code = lv_rec_erp_i_plpc.ddedeliveryschemecode;
              if lv_deliveryschemeid is null then
                begin
                  select max(cs.deliveryscheme_id)
                  into   lv_deliveryschemeid
                  from   customerdeliveryscheme cs
                  where  cs.customer_id = lv_customerid;
                end;
              end if;
            end;
          end if;
          if lv_deliveryschemeid is null then
            begin
              gv_text := 'Delivery days cannot be added. Missing delivery scheme on customer level';
              raise ge_user___exception;
            end;
          end if;
          select count(1)
          into   lv_no_of_days
          from   customerdeliveryday cd
          where  cd.day_id = fp_dayid
          and    cd.customer_id = lv_customerid
          and    cd.deliverytype = fp_deliverytype;
          if lv_no_of_days = 0 then
            begin
              --add_deliveryscheme
              add_deliveryscheme;
            end;
          end if;
        end check_deliveryscheme;
      begin
        if fp_deliverytype is null then
          begin
            delete from productdeliveryday pdd
            where  pdd.productlistpercustomer_id = lv_plpcid
            and    pdd.day_id = fp_dayid;
          end;
        else
          begin
            --check_deliveryscheme
            check_deliveryscheme;
            --process productdeliveryday
            gv_text := 'process productdeliveryday';
            update productdeliveryday pdd
            set    pdd.deliverytype = fp_deliverytype
            where  pdd.productlistpercustomer_id = lv_plpcid
            and    pdd.day_id = fp_dayid
            and    exists (select 1
                    from   customerdeliveryday cd
                    where  cd.day_id = fp_dayid
                    and    cd.customer_id = lv_customerid);
            if sql%rowcount = 0 then
              begin
                insert into productdeliveryday
                  (productlistpercustomer_id, day_id, timestamp, systemuser_id, deliverytype)
                values
                  (lv_plpcid, fp_dayid, sysdate, gv_erp_systemuserid, fp_deliverytype);
              end;
            end if;
            --add_autosoil
            add_autosoil;
          end;
        end if;
      end create_productdeliveryday;
    begin
      --process_plpc
      gv_text := 'process_plpc';
      --get_childinfo
      get_childinfo;
      --check_plpc_data
      check_plpc_data;
      --process_plpc
      process_plpc;
      --update_plpcextrainfo
      update_plpcextrainfo;
      --update_plpcchargepercentage
      update_plpcchargepercentage;
      --update_rentalqtyadjustment
      update_rentalqtyadjustment;
      --create_productdeliveryday
      create_productdeliveryday(1, lv_rec_erp_i_plpc.deliverydaymo,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(2, lv_rec_erp_i_plpc.deliverydaytu,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(3, lv_rec_erp_i_plpc.deliverydaywe,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(4, lv_rec_erp_i_plpc.deliverydayth,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(5, lv_rec_erp_i_plpc.deliverydayfr,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(6, lv_rec_erp_i_plpc.deliverydaysa,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
      create_productdeliveryday(7, lv_rec_erp_i_plpc.deliverydaysu,
                                lv_rec_erp_i_plpc.circulatinginventory,
                                lv_rec_erp_i_plpc.autosoilpercentage);
    end process_plpc;
    -------------
  begin
    --proc_i_plpc_one
    gv_text := 'proc_i_plpc_one process erp_i_productlistpercustomer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_plpc;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_productlistpercust_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists (select fi.transfer_id
            from   erp_i_productlistpercustomer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_plpc.customernumber
            and    fi.productcode = lv_rec_erp_i_plpc.productcode
            and    fi.sizecode = lv_rec_erp_i_plpc.sizecode
            and    fi.finishingmethodcode = lv_rec_erp_i_plpc.finishingmethodcode)
    and    f.transfer_id < fp_transferid
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_productlistpercust_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_productlistpercustomer zz
      where  zz.customernumber = lv_rec_erp_i_plpc.customernumber
      and    zz.productcode = lv_rec_erp_i_plpc.productcode
      and    zz.sizecode = lv_rec_erp_i_plpc.sizecode
      and    zz.finishingmethodcode = lv_rec_erp_i_plpc.finishingmethodcode
      and    zz.transfer_id < lv_rec_erp_i_plpc.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_productlistpercust_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid, 'Ok', lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer ' || lv_rec_erp_i_plpc.customernumber || ' product ' ||
                   lv_rec_erp_i_plpc.productcode, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' || lv_rec_erp_i_plpc.customernumber ||
                   ' product ' || lv_rec_erp_i_plpc.productcode, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' || lv_rec_erp_i_plpc.customernumber ||
                   ' product ' || lv_rec_erp_i_plpc.productcode, 1, 0);
      end;
  end proc_i_plpc_one;

  --process erp_i_productlistpercustomer
  procedure proc_i_plpc(fp_transferid in erp_i_productlistpercustomer.transfer_id%type,
                        fp_rerun      in number default 0) is
  begin
    for pl in (select l.customernumber, l.productcode, l.sizecode, l.finishingmethodcode
               from   erp_i_productlistpercustomer l
               where  l.transfer_id = fp_transferid
               and    (l.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for ply in (select max(l.transfer_id) transfer_id
                    from   erp_i_productlistpercustomer l
                    where  l.customernumber = pl.customernumber
                    and    l.productcode = pl.productcode
                    and    l.sizecode = pl.sizecode
                    and    l.finishingmethodcode = pl.finishingmethodcode) loop
          begin
            if fp_transferid < ply.transfer_id then
              begin
                update erp_i_productlistpercustomer eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_plpc_one(ply.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_plpc;

  --process proc_i_plpc_all
  procedure proc_i_plpc_all is
  begin
    for pcd in (select l.transfer_id
                from   erp_i_productlistpercustomer l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_plpc(pcd.transfer_id);
      end;
    end loop; --d
  end proc_i_plpc_all;

  --process erp_i_inactivate_customer
  --if lost date is 31-12-2099 then it is a reactivation instead!
  procedure proc_i_inactcust_one(fp_transferid in erp_i_inactivate_customer.transfer_id%type,
                                 fp_rerun      in number default 0) is
    lv_rec_erp_i_inactivate_customer erp_i_inactivate_customer%rowtype;
    lv_log_tablename                 varchar2(32) := 'ERP_I_INACTIVATE_CUSTOMER_LOG';
    lv_process_status                number := 0;
    lv_dateactive                    date;
    lv_dateinactive                  date;
    lv_businessunitid                number;
    -------------
    --internal procedure functions 
    function read_line return number is
    begin
      --read_line erp_i_inactivate_customer
      select eis.*
      into   lv_rec_erp_i_inactivate_customer
      from   erp_i_inactivate_customer eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_inactivate_customer eis
      set    eis.transfer_status = 1
      where  eis.transfer_id <= fp_transferid
      and    eis.transfer_status = 0
      and    eis.lost_customernumber = lv_rec_erp_i_inactivate_customer.lost_customernumber;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_inactcust is
      lv_customerid   customer.customer_id%type;
      lv_lostreasonid gainlostreason.gainlostreason_id%type;
      lv_competitorid competitor.competitor_id%type;
    
      procedure makeplpcinactive is
      begin
        --makeplpcinactive
        gv_text := 'make plpc inactive';
        update productlistpercustomer l
        set    l.lostreason_id = lv_lostreasonid, l.lostcompetitor_id = lv_competitorid,
               l.dateinactive = lv_rec_erp_i_inactivate_customer.lost_date,
               l.systemuser_id = gv_erp_systemuserid, l.timestamp = sysdate
        where  l.customer_id = lv_customerid
        and    ((l.dateinactive > lv_rec_erp_i_inactivate_customer.lost_date) or
              (lv_dateinactive < lv_rec_erp_i_inactivate_customer.lost_date and
              l.dateinactive = lv_dateinactive));
      end makeplpcinactive;
    
      procedure markwearersinactiv is
      begin
        --markwearersinactiv
        if lv_rec_erp_i_inactivate_customer.markwearerinactive_yn = 'Y' then
          begin
            gv_text := 'make wearer inactive';
            update wearer w
            set    w.dateinactive = lv_rec_erp_i_inactivate_customer.lost_date,
                   w.systemuser_id = gv_erp_systemuserid, w.timestamp = sysdate
            where  w.customer_id = lv_customerid
            and    ((w.dateinactive > lv_rec_erp_i_inactivate_customer.lost_date) or
                  (lv_dateinactive < lv_rec_erp_i_inactivate_customer.lost_date and
                  w.dateinactive = lv_dateinactive));
            gv_text := 'make wearer inventory inactive';
            update wearerinventory wi
            set    wi.dateinactive = lv_rec_erp_i_inactivate_customer.lost_date,
                   wi.systemuser_id = gv_erp_systemuserid, wi.timestamp = sysdate
            where  ((wi.dateinactive > lv_rec_erp_i_inactivate_customer.lost_date) or
                   (lv_dateinactive < lv_rec_erp_i_inactivate_customer.lost_date and
                   wi.dateinactive = lv_dateinactive))
            and    exists (select 1
                    from   wearer w
                    join   weareremployment we
                    on     we.wearer_id = w.wearer_id
                    where  we.weareremployment_id = wi.weareremployment_id
                    and    w.customer_id = lv_customerid);
          end;
        end if;
      end markwearersinactiv;
    
      procedure add_uniqueitemflag is
        lv_flagid flag.flag_id%type;
      
        procedure get_autoflag is
        begin
          --get automatic flag customer no long active
          select af.flag_id
          into   lv_flagid
          from   automaticflag af
          where  af.event = 'Customer no longer active';
        exception
          when no_data_found then
            begin
              lv_flagid := null;
            end;
        end get_autoflag;
      begin
        --add_UniqueItemFlag
        gv_text := 'add uniqueItem flag';
        get_autoflag;
        if (lv_rec_erp_i_inactivate_customer.flagitemscustomer_yn = 'Y' and lv_flagid is not null) then
          begin
            if lv_rec_erp_i_inactivate_customer.lost_date >= to_date('31-12-2099', 'dd-mm-yyyy') then
              begin
                --only removing it from the same date inactive flag start date
                delete from uniqueitemflag uf
                where  uf.startdate = lv_dateinactive
                and    uf.flag_id = lv_flagid
                and    exists (select 1
                        from   uniqueitemnonpool un
                        join   weareremployment we
                        on     we.weareremployment_id = un.weareremployment_id
                        join   wearer w
                        on     w.wearer_id = we.wearer_id
                        where  w.customer_id = lv_customerid
                        and    un.uniqueitem_id = uf.uniqueitem_id);
              end;
            else
              begin
                insert into uniqueitemflag
                  (uniqueitem_id, flag_id, startdate, freetextitem, systemuser_id, timestamp)
                  select u.uniqueitem_id, lv_flagid, lv_rec_erp_i_inactivate_customer.lost_date,
                         null, gv_erp_systemuserid, sysdate
                  from   uniqueitem u
                  join   uniqueitemnonpool un
                  on     un.uniqueitem_id = u.uniqueitem_id
                  join   weareremployment we
                  on     we.weareremployment_id = un.weareremployment_id
                  join   wearer w
                  on     w.wearer_id = we.wearer_id
                  where  w.customer_id = lv_customerid;
              end;
            end if;
          end;
        end if;
      end add_uniqueitemflag;
    begin
      --get customer id
      lv_customerid   := get_customerid(lv_rec_erp_i_inactivate_customer.lost_customernumber, 0,
                                        lv_dateactive, lv_dateinactive, lv_businessunitid);
      lv_lostreasonid := get_gainlostreasonid(lv_rec_erp_i_inactivate_customer.lost_reason,
                                              lv_rec_erp_i_inactivate_customer.lost_reason);
      lv_competitorid := get_competitorid(lv_rec_erp_i_inactivate_customer.lost_competitorcode,
                                          lv_rec_erp_i_inactivate_customer.lost_competitorcode);
      --update customer
      gv_text := 'update customer to lost customer';
      update customer c
      set    c.lostdate = lv_rec_erp_i_inactivate_customer.lost_date,
             c.dateinactive = lv_rec_erp_i_inactivate_customer.lost_date,
             c.competitor_id = lv_competitorid, c.systemuser_id = gv_erp_systemuserid,
             c.timestamp = sysdate,
             c.active = case
                          when lv_rec_erp_i_inactivate_customer.lost_date >=
                               to_date('31-12-2099', 'dd-mm-yyyy') then
                           'Y'
                          else
                           'N'
                        end
      where  c.customer_id = lv_customerid;
      --make plpc inactive
      makeplpcinactive;
      --make wearer(inv) inactive
      markwearersinactiv;
      --add_UniqueItemFlag 
      add_uniqueitemflag;
    end process_inactcust;
    -------------
  begin
    --proc_i_inactcust_one
    gv_text := 'Process erp_i_inactivate_customer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_inactcust;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_inactivate_customer_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully',
           f.timestamp = sysdate
    where  exists
     (select fi.transfer_id
            from   erp_i_inactivate_customer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.lost_customernumber = lv_rec_erp_i_inactivate_customer.lost_customernumber)
    and    f.transfer_id < lv_rec_erp_i_inactivate_customer.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_inactivate_customer_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_inactivate_customer zz
      where  zz.lost_customernumber = lv_rec_erp_i_inactivate_customer.lost_customernumber
      and    zz.transfer_id < lv_rec_erp_i_inactivate_customer.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_inactivate_customer_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For lost customer ' || lv_rec_erp_i_inactivate_customer.lost_customernumber,
              lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For lost customer ' ||
                   lv_rec_erp_i_inactivate_customer.lost_customernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For lost customer ' ||
                   lv_rec_erp_i_inactivate_customer.lost_customernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For lost customer ' ||
                   lv_rec_erp_i_inactivate_customer.lost_customernumber, 1, 0);
      end;
  end proc_i_inactcust_one;

  --process erp_i_inactivate_customer 
  procedure proc_i_inactcust(fp_transferid in erp_i_inactivate_customer.transfer_id%type,
                             fp_rerun      in number default 0) is
  begin
    for pscx in (select eic.lost_customernumber
                 from   erp_i_inactivate_customer eic
                 where  eic.transfer_id = fp_transferid
                 and    (eic.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for pscy in (select max(eic.transfer_id) transfer_id
                     from   erp_i_inactivate_customer eic
                     where  eic.lost_customernumber = pscx.lost_customernumber) loop
          begin
            if fp_transferid < pscy.transfer_id then
              begin
                update erp_i_inactivate_customer eis
                set    eis.transfer_status = 1
                where  eis.transfer_id = fp_transferid
                and    eis.transfer_status <> 1;
                commit;
              end;
            end if;
            proc_i_inactcust_one(pscy.transfer_id, fp_rerun);
          end;
        end loop; --pscy
      end;
    end loop; --pscx
  end proc_i_inactcust;

  --process proc_i_inactcust_all
  procedure proc_i_inactcust_all is
  begin
    for pce in (select l.transfer_id
                from   erp_i_inactivate_customer l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_inactcust(pce.transfer_id);
      end;
    end loop; --e
  end proc_i_inactcust_all;

  --process erp_i_routechangetransaction
  procedure proc_i_routetransaction(fp_transferid in erp_i_routechangetransaction.transfer_id%type,
                                    fp_rerun      in number default 0) is
    lv_rec_erp_i_routechgtransaction erp_i_routechangetransaction%rowtype;
    lv_log_tablename                 varchar2(32) := 'ERP_I_ROUTECHANGETRANSACT_LOG';
    lv_process_status                number := 0;
    -------------
    --internal procedure functions 
    function read_line return number is
    begin
      --read_line erp_i_routechangetransaction
      select eis.*
      into   lv_rec_erp_i_routechgtransaction
      from   erp_i_routechangetransaction eis
      where  eis.transfer_id = fp_transferid
      and    (eis.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_routechangetransaction eis
      set    eis.transfer_status = 1
      where  eis.transfer_id = fp_transferid;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    procedure process_routechngtrs is
      lv_onlineroutechange number;
      lv_deliverypointcode deliverypoint.code%type;
    
      procedure get_customer_stopnumbers is
        lv_customerid number;
      begin
        --get_customer_stopnumbers
        if lv_rec_erp_i_routechgtransaction.customernumber is not null then
          begin
            lv_customerid := get_customerid(lv_rec_erp_i_routechgtransaction.customernumber);
          end;
        end if;
        if lv_rec_erp_i_routechgtransaction.transactionnumber = 3 and
           lv_rec_erp_i_routechgtransaction.stopnumber is null then
          begin
            lv_rec_erp_i_routechgtransaction.stopnumber := 0;
          end;
        end if;
        if (lv_rec_erp_i_routechgtransaction.transactionnumber in (4, 5, 6) and
           nvl(lv_rec_erp_i_routechgtransaction.stopnumber, 0) = 0) then
          begin
            if lv_customerid is null then
              begin
                gv_text := 'Cannot find routestop because customer is null (unknown)?';
                raise ge_user___exception;
              end;
            end if;
            --check get real stopnumber
            gv_text := 'get active routestop for route ' ||
                       nvl(to_char(lv_rec_erp_i_routechgtransaction.routenumber), 'NULL') ||
                       ' customer ' || lv_rec_erp_i_routechgtransaction.customernumber || ' day ' ||
                       nvl(to_char(lv_rec_erp_i_routechgtransaction.drivingday), 'NULL');
            select rs.stopnumber,
                   (select dp.code
                     from   deliverypoint dp
                     where  dp.deliverypoint_id = rs.deliverypoint_id)
            into   lv_rec_erp_i_routechgtransaction.stopnumber, lv_deliverypointcode
            from   routestop rs
            join   route r
            on     r.route_id = rs.route_id
            where  rs.customer_id = lv_customerid
            and    r.routenumber = lv_rec_erp_i_routechgtransaction.routenumber
            and    r.drivingday_id = lv_rec_erp_i_routechgtransaction.drivingday
            and    sysdate between rs.dateactive and rs.dateinactive;
          exception
            when too_many_rows then
              begin
                gv_text := 'Error more then one active routestop found, for route ' ||
                           nvl(to_char(lv_rec_erp_i_routechgtransaction.routenumber), 'NULL') ||
                           ' customer ' || lv_rec_erp_i_routechgtransaction.customernumber ||
                           ' day ' ||
                           nvl(to_char(lv_rec_erp_i_routechgtransaction.drivingday), 'NULL') ||
                           ' cannot determine the right routestop!';
                raise ge_user___exception;
              end;
          end;
        end if;
      end get_customer_stopnumbers;
    
      procedure get_set_transactionumber is
      begin
        --get_set_transactionumber
        gv_text := 'gv_text';
        case lv_rec_erp_i_routechgtransaction.transactionnumber
          when 1 then
            begin
              ---add route; we make null what should be null
              lv_rec_erp_i_routechgtransaction.drivingday  := null;
              lv_rec_erp_i_routechgtransaction.routenumber := null;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.new_routenumber is null or
                 lv_rec_erp_i_routechgtransaction.new_drivingday is null then
                begin
                  gv_text := 'Both new routenumber and new driving day must be filled for transaction 1 new route';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 2 then
            begin
              --change depot; we make null what should be null
              lv_rec_erp_i_routechgtransaction.new_stopnumber := null;
              lv_rec_erp_i_routechgtransaction.stopnumber     := null;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.depotcode is null then
                begin
                  gv_text := 'Routenumber and driving day, depot must be filled for transaction 2 change depot';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 3 then
            begin
              --add route stop; we make null what should be null, or fill it
              lv_rec_erp_i_routechgtransaction.new_stopnumber := nvl(lv_rec_erp_i_routechgtransaction.new_stopnumber,
                                                                     lv_rec_erp_i_routechgtransaction.stopnumber);
              lv_rec_erp_i_routechgtransaction.stopnumber     := null;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.new_stopnumber is null then
                begin
                  gv_text := 'Routenumber and driving day, new stopnumber must be filled for transaction 3 add route stop';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 4 then
            begin
              --remove stop; we make null what should be null
              lv_rec_erp_i_routechgtransaction.new_stopnumber         := null;
              lv_rec_erp_i_routechgtransaction.new_deliveryschemecode := null;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.stopnumber is null then
                begin
                  gv_text := 'Routenumber and driving day, stopnumber must be filled for transaction 4 remove route stop';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 5 then
            begin
              --change stop number within route
              lv_rec_erp_i_routechgtransaction.new_drivingday  := lv_rec_erp_i_routechgtransaction.drivingday;
              lv_rec_erp_i_routechgtransaction.new_routenumber := lv_rec_erp_i_routechgtransaction.routenumber;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.stopnumber is null or
                 lv_rec_erp_i_routechgtransaction.new_stopnumber is null then
                begin
                  gv_text := 'Routenumber and driving day, (new)stopnumber must be filled for transaction 5 change stop in same route';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 6 then
            begin
              --change deliveryscheme; we make null what should be null
              lv_rec_erp_i_routechgtransaction.new_deliveryschemecode := null;
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.stopnumber is null or
                 lv_rec_erp_i_routechgtransaction.new_stopnumber is null or
                 lv_rec_erp_i_routechgtransaction.new_routenumber is null or
                 lv_rec_erp_i_routechgtransaction.new_drivingday is null then
                begin
                  gv_text := '(new)routenumber and (new)driving day, (new)stopnumber must be filled for transaction 6 move stop';
                  raise ge_user___exception;
                end;
              end if;
            end;
          when 7 then
            begin
              --we check if that is there what should be there
              if lv_rec_erp_i_routechgtransaction.routenumber is null or
                 lv_rec_erp_i_routechgtransaction.drivingday is null or
                 lv_rec_erp_i_routechgtransaction.stopnumber is null or
                 lv_rec_erp_i_routechgtransaction.new_stopnumber is null or
                 lv_rec_erp_i_routechgtransaction.new_routenumber is null or
                 lv_rec_erp_i_routechgtransaction.new_drivingday is null or
                 lv_rec_erp_i_routechgtransaction.new_deliveryschemecode is null then
                begin
                  gv_text := '(new)routenumber and (new)driving day, (new)stopnumber and new deliveryscheme must be filled for transaction 7 change deliveryscheme';
                  raise ge_user___exception;
                end;
              end if;
            end;
          else
            begin
              gv_text := 'Unknown transaction ' ||
                         lv_rec_erp_i_routechgtransaction.transactionnumber;
              raise ge_user___exception;
            end;
        end case;
      end get_set_transactionumber;
    begin
      --move data into table and process
      --get_customer_stopnumbers
      get_customer_stopnumbers;
      --get set transaction number
      get_set_transactionumber;
      --call pack_routetransaction.onlineroutechange
      pack_routetransaction.onlineroutechange(fp_changestartdate => lv_rec_erp_i_routechgtransaction.changestartdate,
                                              fp_oldroutelastdrivingdate => lv_rec_erp_i_routechgtransaction.old_routelastdrivingdate,
                                              fp_customernumber => lv_rec_erp_i_routechgtransaction.customernumber,
                                              fp_deliverypointcode => lv_deliverypointcode,
                                              fp_plantcode => lv_rec_erp_i_routechgtransaction.plantcode,
                                              fp_drivingday => lv_rec_erp_i_routechgtransaction.drivingday,
                                              fp_routenumber => lv_rec_erp_i_routechgtransaction.routenumber,
                                              fp_depotcode => lv_rec_erp_i_routechgtransaction.depotcode,
                                              fp_stopnumber => lv_rec_erp_i_routechgtransaction.stopnumber,
                                              fp_deliveryschemecode => lv_rec_erp_i_routechgtransaction.deliveryschemecode,
                                              fp_newdrivingday => lv_rec_erp_i_routechgtransaction.new_drivingday,
                                              fp_newroutenumber => lv_rec_erp_i_routechgtransaction.new_routenumber,
                                              fp_newstopnumber => lv_rec_erp_i_routechgtransaction.new_stopnumber,
                                              fp_newdeliveryscheme => lv_rec_erp_i_routechgtransaction.new_deliveryschemecode,
                                              fp_productgroupcode => null, fp_sortsequence => null,
                                              fp_errmsg => gv_text,
                                              fp_onlineroutechange => lv_onlineroutechange,
                                              fp_systemuserid => gv_erp_systemuserid);
      if lv_onlineroutechange = 1 then
        begin
          lv_process_status := 0;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
      end if;
    end process_routechngtrs;
    -------------
  begin
    --proc_i_inactcust_one
    gv_text := 'Process erp_i_routechangetransaction for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_routechngtrs;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid, 'Ok', lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid, gv_text, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid, gv_text || ' no data found!', 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid, gv_text || ' ' || sqlerrm, 1, 0);
      end;
  end proc_i_routetransaction;

  --process proc_i_routetransaction_all
  procedure proc_i_routetransaction_all is
  begin
    for pce in (select l.transfer_id
                from   erp_i_routechangetransaction l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_routetransaction(pce.transfer_id);
      end;
    end loop; --e
  end proc_i_routetransaction_all;
  ----------------------------------------------------------------------------
  --ERP O Tables
  --process erp_o_artransaction
  procedure proc_o_artransaction(fp_cleanup_afterdays in number default null) is
    -------------
    --internal procedure functions
    procedure cleanup is
    begin
      -- cleanup erp_o_artransaction
      gv_text := 'cleanup erp_o_artransaction';
      if nvl(fp_cleanup_afterdays, 0) between 2 and 128 then
        gv_cleanup_afterdays := fp_cleanup_afterdays;
      else
        gv_cleanup_afterdays := nvl(gv_cleanup_afterdays, 14); --default
      end if;
      delete from erp_o_artransaction eola
      where  eola.transfer_status <> 0 --so it was read
      and    exists (select 1
              from   erp_o_artransaction_log eolal
              where  eolal.transfer_id = eola.transfer_id
              and    eolal.process_status = 0 --so was processed ok
              and    eolal.timestamp < (sysdate - gv_cleanup_afterdays));
      --commit
      commit;
    end cleanup;
  
    procedure export_o_artransaction is
    begin
      --export_o_artransaction
      --set flag for processed
      gv_text := 'export_o_artransaction set flag for processed';
      update artransaction a
      set    a.exportstatus = -1
      where  a.exportstatus in (0, 1, 3)
      and    exists (select 1
              from   v_auj_artransactions va
              where  va.exportstatus in (0, 1, 3)
              and    va.artransaction_id = a.artransaction_id);
      --insert into erp_o_artransaction
      gv_text := 'export_o_artransaction insert into erp_o_artransaction';
      insert into erp_o_artransaction
        (transfer_id, transfer_status, businessunitcode, legalentitycode, billtobusinessunitcode,
         billtolegalentitycode, billtocustomer, billtoname, deltobusinessunitcode,
         deltolegalentitycode, deltocustomernumber, deltoname, transactiondate, invoicedate,
         invoicenumber, currencycode, amount, debitcredit, paymenttype, artransactiontype,
         artransactiontype_code, artransactiontype_desc, remitidentification, remark, turnovergroup,
         legacycode, maxaccountnumber, creditedinv, creditinv_date, credit_paymenttype,
         paymentreference)
        select seq_transfer.nextval, 0, va.businessunitcode, va.legalentitycode,
               va.bill2businessunitcode, va.bill2legalentitycode, va.billto_customer, va.billto_name,
               va.deltobusinessunitcode, va.deltolegalentitycode, va.customernumber, va.name,
               va.transactiondate, va.invoicedate, va.invoicenumber, va.currency, va.amount,
               va.debitcredit, va.paymenttype, va.artransactiontype, va.artransactiontype_code,
               va.artransactiontype_desc, va.remitidentification, va.remark, va.turnovergroup,
               va.legacycode, va.maxaccountnumber, va.creditedinv, va.creditinv_date,
               va.credit_paymenttype, va.paymentreference
        from   v_auj_artransactions va
        where  va.exportstatus = -1;
      --set to processed
      gv_text := 'export_o_artransaction set to processed';
      update artransaction a
      set    a.exportstatus = 2
      where  a.exportstatus = -1
      and    exists (select 1
              from   v_auj_artransactions va
              where  va.exportstatus = -1
              and    va.artransaction_id = a.artransaction_id);
    end export_o_artransaction;
  begin
    --export_o_artransaction
    export_o_artransaction;
    --cleanup
    cleanup;
  exception
    when no_data_found then
      begin
        rollback;
        write_o_log('proc_o_artransaction no data found ' || gv_text);
      end;
    when others then
      begin
        rollback;
        write_o_log(gv_text || ' during proc_o_artransaction ' || sqlerrm, 5);
      end;
  end proc_o_artransaction;

  --process proc_o_invoiceheader
  procedure proc_o_invoiceheader(fp_cleanup_afterdays in number default null) is
    lv_transferid            erp_transaction_log.transfer_id%type;
    lv_packingnotenumberlist erp_o_invoiceheader.packingnotenumberlist%type;
    lv_billingmethodcode     erp_o_invoiceline.billingmethodcode%type;
    lv_discountamount        erp_o_invoiceline.discountamount%type;
    lv_sizecode              sizedefinition.code%type;
    lv_productgroupcode      productgroup.code%type;
    lv_linenumber            number;
    lv_ponumber              contractspercustomer.purchaseorder%type;
    lv_poexpirationdate      contractspercustomer.purchaseorderexpirationdate%type;
    -------------
    --internal procedure functions
    function get_billingmethodcode(fp_invoicelinetypeid  in invoiceline.invoicelinetype_id%type,
                                   fp_invoicelinesubtype in invoiceline.invoicelinesubtype%type,
                                   fp_customerid         in customer.customer_id%type,
                                   fp_productid          in product.product_id%type,
                                   fp_sizedefinitionid   in sizedefinition.sizedefinition_id%type,
                                   fp_finishingmethodid  in finishingmethod.finishingmethod_id%type,
                                   fp_deliveryschemecode in invoicelineproduct.deliveryschemecode%type,
                                   fp_startdate          in invoiceheader.startdate%type,
                                   fp_enddate            in invoiceheader.enddate%type)
      return erp_o_invoiceline.billingmethodcode%type is
      lv_billingmethodcode erp_o_invoiceline.billingmethodcode%type;
      lv_priceusage        productlistpercustomer.priceusage%type;
      lv_billingmethod     productlistpercustomer.billingmethod%type;
      lv_frequency         deliveryscheme.frequency%type;
    begin
      --get_billingmethodcode
      gv_text := 'get_billingmethodcode';
      if fp_customerid is null or fp_productid is null or fp_sizedefinitionid is null or
         fp_finishingmethodid is null then
        return null;
      end if;
      --get PLPC info
      select max(l.billingmethod), max(l.priceusage)
      into   lv_billingmethod, lv_priceusage
      from   productlistpercustomer l
      where  l.customer_id = fp_customerid
      and    l.product_id = fp_productid
      and    l.sizedefinition_id = fp_sizedefinitionid
      and    l.finishingmethod_id = fp_finishingmethodid
      and    (fp_startdate between l.dateactive and l.dateinactive or
            fp_enddate between l.dateactive and l.dateinactive);
      if lv_billingmethod is null then
        begin
          select max(l.billingmethod), max(l.priceusage)
          into   lv_billingmethod, lv_priceusage
          from   productlistpercustomer l
          where  l.customer_id = fp_customerid
          and    l.product_id = fp_productid
          and    l.sizedefinition_id = gv_sizestarid
          and    l.finishingmethod_id = fp_finishingmethodid
          and    (fp_startdate between l.dateactive and l.dateinactive or
                fp_enddate between l.dateactive and l.dateinactive);
        end;
      end if;
      --get frequency from deliveryscheme
      select max(ds.frequency)
      into   lv_frequency
      from   deliveryscheme ds
      where  ds.code = fp_deliveryschemecode;
      --get data from conversiont table
      select max(tc.billingmethodcode)
      into   lv_billingmethodcode
      from   erp_c_billingmethodcode tc
      where  tc.invoicelinetype_id = fp_invoicelinetypeid
      and    tc.invoicelinesubtype = fp_invoicelinesubtype
      and    tc.billingmethod = lv_billingmethod
      and    nvl(tc.frequency, -1) = nvl(lv_frequency, -1)
      and    tc.priceusage = lv_priceusage;
      --return value
      return lv_billingmethodcode;
    exception
      when no_data_found then
        return null;
    end get_billingmethodcode;
  
    procedure fill_packingnotenumberlist(fp_invoiceheaderid in invoiceheader.invoiceheader_id%type) is
    begin
      --fill_packingnotenumberlist
      gv_text                  := 'proc_o_invoiceheader.fill_packingnotenumberlist for invoiceheader id ' ||
                                  to_char(fp_invoiceheaderid);
      lv_packingnotenumberlist := null;
      for pkx in (select pk.notenumber
                  from   packingnoteline pkl, packingnote pk
                  where  pkl.invoiceheader_id = fp_invoiceheaderid
                  and    pkl.packingnote_id = pk.packingnote_id
                  and    pk.showoninvoiceappendix = 'Y'
                  group  by pk.notenumber
                  union
                  select pk.notenumber
                  from   packingnotecontainer pkl, packingnote pk
                  where  pkl.invoiceheader_id = fp_invoiceheaderid
                  and    pkl.packingnote_id = pk.packingnote_id
                  and    pk.showoninvoiceappendix = 'Y'
                  group  by pk.notenumber
                  order  by 1 desc) loop
        begin
          lv_packingnotenumberlist := substr(pkx.notenumber || ',' || lv_packingnotenumberlist, 1,
                                             4000);
        end;
      end loop; --pkx
      lv_packingnotenumberlist := rtrim(lv_packingnotenumberlist, ',');
    end fill_packingnotenumberlist;
  
    procedure cleanup is
    begin
      -- cleanup erp_o_invoiceheader
      gv_text := 'cleanup erp_o_invoiceheader';
      if nvl(fp_cleanup_afterdays, 0) between 2 and 128 then
        gv_cleanup_afterdays := fp_cleanup_afterdays;
      else
        gv_cleanup_afterdays := nvl(gv_cleanup_afterdays, 14); --default
      end if;
      delete from erp_o_invoiceheader eoih
      where  eoih.transfer_status <> 0 --so it was read
      and    exists (select 1
              from   erp_o_invoice_log eoihl
              where  eoihl.transfer_id = eoih.transfer_id
              and    eoihl.process_status = 0 --so was processed ok
              and    eoihl.timestamp < (sysdate - gv_cleanup_afterdays));
      --commit
      commit;
    end cleanup;
  begin
    --proc_o_invoiceheader
    gv_text := 'proc_o_invoiceheader';
    --loop invoiceheader x
    for x in (select ih.invoiceheader_id, ih.invoicedate, ih.invoicenumber,
                     ihp.invoicenumber parentinvoicenumber,
                     case
                       when ihp.invoicenumber is null then
                        0 --standard invoice
                       when ihp.invoicenumber = ih.invoicenumber then
                        2 --consolidated invoice
                       else
                        1 --child invoice
                     end interfaceinvoicetype, ih.invoicetype, ih.documenttype,
                     ih.invoicefrequency_id, invbu.code invoicebusinessunitcode,
                     ih.billtocustomernumber,
                     case
                       when ihp.invoicenumber = ih.invoicenumber then
                        null
                       else
                        ih.deltocustomernumber
                     end deltocustomernumber, ih.startweek, ih.startyear, ih.startmonth, ih.endweek,
                     ih.endyear, ih.endmonth, ih.startdate, ih.enddate, ih.invoiceyear,
                     ih.invoiceweek, ih.invoicedaynumber, ih.street, ih.street2, ih.zipcode, ih.city,
                     substr(ih.emailaddress, 1, 40) emailaddress, ih.contactpersonname,
                     ih.splitupcode, ih.splitupdescription, ih.deltostreet, ih.deltostreet2,
                     ih.deltozipcode, ih.deltocity, cu.code currencycode, ih.credited,
                     ih.creditedinvoiceno, ih.totalamountexclvat, ih.totalminusadjustment,
                     ih.totalplusadjustment, ih.prebillamount, ih.paidamount, ih.roundingamount,
                     ih.paythisamount, ih.cashcollected, ih.underuseamount, ih.netpaymentdays,
                     ih.paymentdiscountdays, ih.creditsqueezeamount, ih.creditsqueezeperc,
                     ih.invoicecomments, ih.exported, ih.nextperiodstartweek, ih.nextperiodendweek,
                     ih.deltocustomer_link_id, ihei.formlayoutcode invoicelayoutcode,
                     nvl((select deltoc.signaturerequired
                          from   customer deltoc
                          where  deltoc.customer_id = ih.deltocustomer_link_id), 'N') signaturerequired,
                     ih.deltocustomername,
                     (select m.customernumber
                       from   customer c
                       join   customer m
                       on     m.customer_id = c.masteraccount_id
                       where  c.customer_id = ih.deltocustomer_link_id) masteraccountnumber,
                     ih.deltocustomer_link_id deltocustomer_id, ih.routenumber,
                     (select max(rb.batchnumber)
                       from   artransaction ar
                       join   remitbatch rb
                       on     rb.remitbatch_id = ar.remitbatch_id
                       where  ar.invoiceheader_id = ih.invoiceheader_id
                       and    ar.debitcredit = 'C') remitbatchnumber, ih.depotcode, ihei.checknumber,
                     cta.taxauthoritycode citytaxauthoritycode,
                     ctc.taxauthoritycode countytaxauthoritycode,
                     sts.taxauthoritycode statetaxauthoritycode,
                     (select sum(il.amount)
                       from   invoiceline il
                       where  il.invoiceheader_id = ih.invoiceheader_id
                       and    il.invoicelinetype_id = 18
                       and    il.code = cta.taxauthoritycode) citytax_amount,
                     (select sum(il.amount)
                       from   invoiceline il
                       where  il.invoiceheader_id = ih.invoiceheader_id
                       and    il.invoicelinetype_id = 18
                       and    il.code = ctc.taxauthoritycode) countytax_amount,
                     (select sum(il.amount)
                       from   invoiceline il
                       where  il.invoiceheader_id = ih.invoiceheader_id
                       and    il.invoicelinetype_id = 18
                       and    il.code = sts.code) statetax_amount,
                     (select count(il.invoiceline_id)
                       from   invoiceline il
                       where  il.invoiceheader_id = ih.invoiceheader_id
                       and    il.billedqty <> 0) numberoflines,
                     (select rc.drivingdate
                       from   routecontrol rc
                       where  ih.routecontrol_id = rc.routecontrol_id) rcdrivingdate,
                     ct.code contractcode,
                     (select max(r.routecode) from route r where r.route_id = ih.route_id) routecode,
                     (select max(getroutestopcode(rs.routestop_id))
                       from   routestop rs
                       where  rs.customer_id = ih.deltocustomer_link_id
                       and    rs.route_id = ih.route_id
                       and    ih.invoicedate between rs.dateactive and rs.dateinactive) routestopcode,
                     sale1.employeenumber salesperson1, sale1.name salesperson1name,
                     ct.salesemployee1percentage splitpercentage1, sale2.employeenumber salesperson2,
                     sale2.name salesperson2name, ct.salesemployee2percentage splitpercentage2,
                     ih.billtocustomername,
                     (select master.name
                       from   customer master
                       where  master.customer_id = delto.masteraccount_id) masteraccountname,
                     pt.language_id, ih.state,
                     (select stdelto.name
                       from   states stdelto
                       where  stdelto.states_id = delto.states_id) deltostate,
                     budelto.code deltobusinessunitcode, deltoregion.code deltoregioncode,
                     billtoregion.code billtoregioncode
              from   invoiceheader ih
              left   outer join invoiceheaderextrainfo ihei
              on     ihei.invoiceheader_id = ih.invoiceheader_id
              left   outer join invoiceheader ihp
              on     ihp.invoiceheader_id = ih.parentinvoiceheader_id
              join   businessunit invbu
              on     invbu.businessunit_id = ih.invoicebusinessunit_id
              join   plant pt
              on     pt.plant_id = invbu.plant_id
              join   currency cu
              on     ih.currency_id = cu.currency_id
              left   outer join(invoiceheaderus ius
              left   outer join citycounty cta
              on     cta.citycounty_id = ius.taxcity_id
              left   outer join citycounty ctc
              on     ctc.citycounty_id = ius.taxcounty_id
              left   outer join states sts
              on     sts.states_id = ius.taxstates_id) on ius.invoiceheader_id = ih.invoiceheader_id
              join   customer billto
              on     billto.customer_id = ih.billtocustomer_link_id
              join   businessunit bubillto
              on     bubillto.businessunit_id = billto.defaultbusinessunit_id
              join   region billtoregion
              on     billtoregion.region_id = bubillto.region_id
              join   customer delto
              on     delto.customer_id = ih.deltocustomer_link_id
              join   businessunit budelto
              on     budelto.businessunit_id = delto.defaultbusinessunit_id
              join   region deltoregion
              on     deltoregion.region_id = budelto.region_id
              left   outer join(contract ct
              left   outer join employee sale1
              on     sale1.employee_id = ct.salesemployee_id
              left   outer join employee sale2
              on     sale2.employee_id = ct.salesemployee2_id) on ct.code = ih.contractcode
              where  ih.exported = 'N'
              and    exists (select 1
                      from   status st
                      where  st.statustype = 'IN'
                      and    st.code = '2'
                      and    st.status_id = ih.status_id)
              and    ih.documenttype = 1
              and    (ih.parentinvoiceheader_id = ih.invoiceheader_id or
                    ih.parentinvoiceheader_id is null)) loop
      begin
        --get next id
        select seq_transfer.nextval into lv_transferid from dual;
        --get po info
        get_contract_purchaseorder(x.deltocustomer_id, lv_ponumber, lv_poexpirationdate);
        --fill_packingnotenumberlist
        fill_packingnotenumberlist(x.invoiceheader_id);
        --insert into erp_o_invoiceheader
        gv_text := 'proc_o_invoiceheader insert into erp_o_invoiceheader';
        insert into erp_o_invoiceheader
          (transfer_id, transfer_status, invoicedate, invoiceheader_id, parentinvoicenumber,
           interfaceinvoicetype, invoicenumber, invoicetype, documenttype, invoicefrequency_id,
           invoicebusinessunitcode, billtocustomernumber, deltocustomernumber, startweek, endweek,
           startmonth, endmonth, startyear, endyear, startdate, enddate, invoiceyear, invoiceweek,
           invoicedaynumber, street, street2, zipcode, city, emailaddress, contactpersonname,
           splitupcode, splitupdescription, deltostreet, deltostreet2, deltozipcode, deltocity,
           currencycode, credited, creditedinvoiceno, totalamountexclvat, totalminusadjustment,
           totalplusadjustment, prebillamount, paidamount, roundingamount, paythisamount,
           cashcollected, underuseamount, netpaymentdays, paymentdiscountdays, creditsqueezeamount,
           creditsqueezeperc, invoicecomments, exported, nextperiodstartweek, nextperiodendweek,
           packingnotenumberlist, masteraccountnumber, purchase_order, po_expiration_date,
           routenumber, remitbatchnumber, depotcode, checknumber, statetax_authcode, statetax_amount,
           citytax_authcode, citytax_amount, countytax_authcode, countytax_amount, line_count,
           invoicelayoutcode, signaturerequired, drivingdate, contract, routecode, routestopcode,
           salesperson1, salesperson1name, splitpercentage1, salesperson2, salesperson2name,
           splitpercentage2, deltocustomername, billtocustomername, masteraccountname, state,
           deltostate, deltobusinessunitcode, deltoregioncode, billtoregioncode)
        values
          (lv_transferid, 0, x.invoicedate, x.invoiceheader_id, x.parentinvoicenumber,
           x.interfaceinvoicetype, x.invoicenumber, x.invoicetype, x.documenttype,
           x.invoicefrequency_id, x.invoicebusinessunitcode, x.billtocustomernumber,
           x.deltocustomernumber, x.startweek, x.endweek, x.startmonth, x.endmonth, x.startyear,
           x.endyear, x.startdate, x.enddate, x.invoiceyear, x.invoiceweek, x.invoicedaynumber,
           x.street, x.street2, x.zipcode, x.city, x.emailaddress, x.contactpersonname,
           x.splitupcode, x.splitupdescription, x.deltostreet, x.deltostreet2, x.deltozipcode,
           x.deltocity, x.currencycode, x.credited, x.creditedinvoiceno, x.totalamountexclvat,
           x.totalminusadjustment, x.totalplusadjustment, x.prebillamount, x.paidamount,
           x.roundingamount, x.paythisamount, x.cashcollected, x.underuseamount, x.netpaymentdays,
           x.paymentdiscountdays, x.creditsqueezeamount, x.creditsqueezeperc, x.invoicecomments,
           x.exported, x.nextperiodstartweek, x.nextperiodendweek, lv_packingnotenumberlist,
           x.masteraccountnumber, lv_ponumber, lv_poexpirationdate, x.routenumber,
           x.remitbatchnumber, x.depotcode, x.checknumber, x.statetaxauthoritycode,
           x.statetax_amount, x.citytaxauthoritycode, x.citytax_amount, x.countytaxauthoritycode,
           x.countytax_amount, x.numberoflines, x.invoicelayoutcode, x.signaturerequired,
           x.rcdrivingdate, x.contractcode, x.routecode, x.routestopcode, x.salesperson1,
           x.salesperson1name, x.splitpercentage1, x.salesperson2, x.salesperson2name,
           x.splitpercentage2, x.deltocustomername, x.billtocustomername, x.masteraccountname,
           x.state, x.deltostate, x.deltobusinessunitcode, x.deltoregioncode, x.billtoregioncode);
        lv_linenumber := 0;
        --loop the invoice lines
        for y in (select il.invoiceline_id, il.linenumber, il.invoicelinetype_id,
                         il.invoicelinesubtype, il.code, il.description, il.price, il.billedqty,
                         il.amount, il.discountpercentage, il.taxtype, il.taxgroupcode, il.remark,
                         il.generated, il.credit, il.subjecttominimum, il.adjustedamount,
                         il.adjustedprice, il.adjustmentbilledqty,
                         (select rs.code
                           from   reasoncode rs
                           where  rs.reasoncode_id = il.adjustmentreason_id) adjustmentreasoncode,
                         'N' adjustmentpermited, p.code productcode, s.code sizecode,
                         fi.code finishingmethodcode, w.wearernumber, w.fullname wearername,
                         fi.pricefactor, nvl(tg.code, 'XXXX') turnovergroupcode,
                         wgc.code weighingcategorycode, p.typeofmerchandise, p.productgroup_id,
                         p.product_id, s.sizedefinition_id, ilp.finishingmethod_id,
                         ilp.deliveryschemecode,
                         (select xh.deltocustomernumber
                           from   invoiceheader xh
                           where  xh.invoiceheader_id = il.invoiceheader_id) deltocustomernumber,
                         ilp.billingmethod, ilp.wearerlocker lockernumber,
                         w.firstname wearerfirstname,
                         (select max(la.accountnumber)
                           from   ledgeracctsperturnovergroup latg
                           join   ledgeraccounts la
                           on     la.ledgeraccounts_id = latg.ledgeraccounts_id
                           where  latg.turnovergroup_id = il.turnovergroup_id) ledgeraccountcode,
                         (select tgd.description
                           from   turnovergroup_desc tgd
                           where  tgd.turnovergroup_id = il.turnovergroup_id
                           and    tgd.language_id = x.language_id) turnovergroupdesc,
                         ilp.deliveredqty deliverquantity, il.extend
                  from   invoiceline il
                  left   outer join invoicelineproduct ilp
                  on     ilp.invoiceline_id = il.invoiceline_id
                  left   outer join product p
                  on     p.product_id = ilp.product_link_id
                  left   outer join sizedefinition s
                  on     s.sizedefinition_id = ilp.sizedefinition_link_id
                  left   outer join finishingmethod fi
                  on     fi.finishingmethod_id = ilp.finishingmethod_id
                  left   outer join weighingcategory wgc
                  on     wgc.weighingcategory_id = ilp.weighingcategory_link_id
                  left   outer join turnovergroup tg
                  on     tg.turnovergroup_id = il.turnovergroup_id
                  left   outer join(weareremployment we
                  join   wearer w
                  on     we.wearer_id = w.wearer_id) on we.weareremployment_id = ilp.weareremployment_link_id
                  where  il.invoiceheader_id in
                         (select ih.invoiceheader_id
                          from   invoiceheader ih
                          where  ih.invoiceheader_id = x.invoiceheader_id
                          or     ih.parentinvoiceheader_id = x.invoiceheader_id)
                  order  by il.invoiceline_id) loop
          begin
            lv_linenumber := lv_linenumber + 1;
            gv_text       := 'proc_o_invoiceheader.before insert invoiceline discount amount';
            if y.discountpercentage > 0 then
              begin
                if y.billedqty * y.price > 0 then
                  lv_discountamount := y.billedqty * y.price - y.amount;
                else
                  lv_discountamount := null;
                end if;
              end;
            else
              begin
                lv_discountamount := null;
              end;
            end if;
            if y.productcode is not null and y.sizecode is null then
              begin
                select pg.code
                into   lv_productgroupcode
                from   productgroup pg
                where  pg.productgroup_id = y.productgroup_id;
                case y.typeofmerchandise
                  when 2 then
                    lv_sizecode := '*';
                  else
                    lv_sizecode := '-';
                end case;
              end;
            else
              begin
                lv_sizecode := null;
              end;
            end if;
            gv_text := 'proc_o_invoiceheader.insert into erp_o_invoiceline';
            insert into erp_o_invoiceline
              (transfer_id, transfer_status, invoiceheader_id, invoiceline_id, invoicenumber,
               linenumber, invoicelinetype_id, invoicelinesubtype, code, description, price,
               billedqty, amount, discountpercentage, taxtype, taxgroupcode, remark, generated,
               credit, subjecttominimum, adjustmentpermited, adjustmentreasoncode, adjustedprice,
               adjustmentbilledqty, adjustedamount, productcode, sizecode, finishingmethodcode,
               wearernumber, wearername, turnovergroupcode, pricefactor, discountamount,
               weighingcategorycode, billingmethodcode, deltocustomernumber, lockernumber,
               wearerfirstname, ledgeraccountcode, turnovergroupdesc, deliverquantity, extend)
            values
              (lv_transferid, 0, x.invoiceheader_id, y.invoiceline_id, x.invoicenumber,
               lv_linenumber, y.invoicelinetype_id, y.invoicelinesubtype, y.code, y.description,
               y.price, y.billedqty, y.amount, y.discountpercentage, y.taxtype, y.taxgroupcode,
               y.remark, y.generated, y.credit, y.subjecttominimum, y.adjustmentpermited,
               y.adjustmentreasoncode, y.adjustedprice, y.adjustmentbilledqty, y.adjustedamount,
               y.productcode, nvl(lv_sizecode, y.sizecode), y.finishingmethodcode, y.wearernumber,
               y.wearername, y.turnovergroupcode, y.pricefactor, lv_discountamount,
               y.weighingcategorycode, y.billingmethod,
               nvl(y.deltocustomernumber, x.deltocustomernumber), y.lockernumber, y.wearerfirstname,
               y.ledgeraccountcode, y.turnovergroupdesc, y.deliverquantity, y.extend);
          end;
        end loop; --y invoiceline
        --set invoiceheader to exported
        gv_text := 'proc_o_invoiceheader update invoiceheader as exported';
        update invoiceheader st
        set    st.exported = 'Y'
        where  st.invoiceheader_id = x.invoiceheader_id
        or     st.parentinvoiceheader_id = x.invoiceheader_id;
        commit;
      end;
    end loop; --x
    --cleanup
    cleanup;
  exception
    when no_data_found then
      begin
        rollback;
        write_o_log('proc_o_invoiceheader.no data found ' || gv_text);
      end;
    when others then
      begin
        rollback;
        write_o_log(gv_text || ' during proc_o_invoiceheader ' || sqlerrm, 5);
      end;
  end proc_o_invoiceheader;
  ----------------------------------------------------------------------------
-- Initialization
begin
  --get size star
  if gv_sizestarid is null then
    begin
      select s.sizedefinition_id into gv_sizestarid from sizedefinition s where s.code = '*';
    end;
  end if;
  if gv_erp_systemuserid is null then
    begin
      --get ERP systemuser
      select sy.systemuser_id
      into   gv_erp_systemuserid
      from   systemuser sy
      where  sy.username = 'ERP';
    exception
      when no_data_found then
        begin
          --not found take first one
          select min(sy.systemuser_id) into gv_erp_systemuserid from systemuser sy;
        end;
    end;
  end if;
  if nvl(gv_invoicecolumn, 0) = 0 then
    begin
      --get product invoicecolumn value from system setting
      select max(st.value)
      into   gv_invoicecolumn
      from   systemsetting st
      where  st.name = 'GARMENTRENTCOLUMN1';
      if gv_invoicecolumn is null then
        gv_invoicecolumn := 1;
      end if;
    exception
      when others then
        gv_invoicecolumn := 1;
    end;
  end if;
end auj_erp_interface;
/

create or replace package auj_erp_miroku is
  /***************************************************************************\
  *  Author  : ABS                                                            *
  *  Created : 03-12-2019                                                     *
  *  Purpose : Interface for ERP_* tables to and from ABSSolute               *
  *              to rerun for a certain transferid then the parameter         *
  *              fp_rerun>0 and corresponding log record must be there then!  *
  *  Version : 0.11                                                           *
  *  Revision: ABS-97809 Remake Miroku interface adding ERP_O_Miroku          *
  \***************************************************************************/
  --ERP I Tables
  --None  
  ----------------------------------------------------------------------------
  --ERP O Tables
  --process erp_o_miroku
  procedure proc_o_miroku(fp_monthyear         in varchar2, --Format mm/yyyy
                          fp_cleanup_afterdays in number default null);
end auj_erp_miroku;
/
/
create or replace package body auj_erp_miroku is
  ----------------------------------------------------------------------------
  --internal variables:
  ge_user___exception exception;
  gv_cleanup_afterdays number := 33;
  gv_text              abslog.message%type := null;
  gv_erp_systemuserid  systemuser.systemuser_id%type;
  gv_sizestarid        sizedefinition.sizedefinition_id%type;
  gv_startdate         date;
  gv_enddate           date;
  ----------------------------------------------------------------------------
  --process erp_o_miroku
  procedure proc_o_miroku(fp_monthyear         in varchar2, --Format mm/yyyy
                          fp_cleanup_afterdays in number default null) is
    -------------
    --internal procedure functions
    procedure initialize is
    begin
      --initialize
      if fp_monthyear is null then
        begin
          gv_startdate := last_day(add_months(trunc(sysdate), -2)) + 1;
          gv_enddate   := last_day(gv_startdate);
        end;
      else
        begin
          --get first and last day of month for fp_monthyear
          gv_text      := 'get first and last day of month for ' || fp_monthyear ||
                          ' (format must be mm/yyyy)';
          gv_startdate := to_date('1/' || fp_monthyear, 'dd/mm/yyyy');
          gv_enddate   := last_day(gv_startdate);
        end;
      end if;
    end initialize;
    procedure fill_erp_o_miroku is
    begin
      --fill_erp_o_miroku
      insert into erp_o_miroku
        (transfer_id, transfer_status, artransactiondate, slip_number, journal_input_format,
         debit_subject_code, debit_subject_name, debit_division_code, debit_division_name,
         subject_code, subject_name, debit_business_partner_code, debit_business_partner_name,
         debit_auxiliary_code, debit_auxiliary_name, credit_item_code, credit_item_name,
         credit_department_code, credit_department_name, credit_subject_code, credit_subject_name,
         credit_business_partner_code, credit_business_partner_name, credit_auxiliary_code,
         credit_auxiliary_name, consumption_tax_code, consumption_tax_rate, amount, description,
         due_date, record_category)
        select seq_transfer.nextval, 0, artransactiondate, slip_number, journal_input_format,
               debit_subject_code, debit_subject_name, debit_division_code, debit_division_name,
               subject_code, subject_name, debit_business_partner_code, debit_business_partner_name,
               debit_auxiliary_code, debit_auxiliary_name, credit_item_code, credit_item_name,
               credit_department_code, credit_department_name, credit_subject_code,
               credit_subject_name, credit_business_partner_code, credit_business_partner_name,
               credit_auxiliary_code, credit_auxiliary_name, consumption_tax_code,
               consumption_tax_rate, amount, description, due_date, record_category
        from   v_miroko_export_new
        where  artransactiondate between gv_startdate and gv_enddate;
    end fill_erp_o_miroku;
    procedure cleanup is
    begin
      -- cleanup erp_o_miroku
      gv_text := 'cleanup erp_o_miroku';
      if nvl(fp_cleanup_afterdays, 0) between 2 and 128 then
        gv_cleanup_afterdays := fp_cleanup_afterdays;
      else
        gv_cleanup_afterdays := nvl(gv_cleanup_afterdays, 14); --default
      end if;
      delete from erp_o_miroku eost
      where  eost.transfer_status <> 0 --so it was read
      and    exists (select 1
              from   erp_o_miroku_log eostl
              where  eostl.transfer_id = eost.transfer_id
              and    eostl.process_status = 0 --so was processed ok
              and    eostl.timestamp < (sysdate - gv_cleanup_afterdays));
      --commit
      commit;
    end cleanup;
  begin
    --proc_o_miroku
    gv_text := 'proc_o_miroku';
    --initialize
    initialize;
    --fill_erp_o_miroku
    fill_erp_o_miroku;
    --cleanup
    cleanup;
  end proc_o_miroku;
  ----------------------------------------------------------------------------
begin
  --get size star
  if gv_sizestarid is null then
    begin
      select s.sizedefinition_id into gv_sizestarid from sizedefinition s where s.code = '*';
    end;
  end if;
  if gv_erp_systemuserid is null then
    begin
      --get ERP systemuser
      select sy.systemuser_id
      into   gv_erp_systemuserid
      from   systemuser sy
      where  sy.username = 'ERP';
    exception
      when no_data_found then
        begin
          --not found take first one
          select min(sy.systemuser_id) into gv_erp_systemuserid from systemuser sy;
        end;
    end;
  end if;
end auj_erp_miroku;
/

create or replace package auj_erp_wearer is
  /***************************************************************************\
  *  Author  : ABS                                                            *
  *  Created : 10-03-2020                                                     *
  *  Purpose : Interface for ERP_Wearer tables to ABSSolute                   *
  *              to rerun for a certain transferid then the parameter         *
  *              fp_rerun>0 and corresponding log record must be there then!  *
  *            Special AUJ version to be tested on 8.03.11 and higher         *
  *  Version : 0.04                                                           *
  *  Created                                                                  *
  *  10-03-2020 ABS-72415 ERP Wearer interface                                *
  *  30-07-2021 ABS-122785 check on active PLPC needs adjustment              *
  *  07-09-2021 ABS-122785 updated PLPC check back again to include = signs   *
  *  14-09-2022 ABS-140379 ERP_I_WEARER do not update remark to NULL when send*
  \***************************************************************************/
  -- I Tables
  --ERP I Tables
  --process erp_i_wearer
  procedure proc_i_wearer(fp_transferid in erp_i_wearer.transfer_id%type,
                          fp_rerun      in number default 0);
  procedure proc_i_wearer_all;
end auj_erp_wearer;
/
/
create or replace package body auj_erp_wearer is
  ----------------------------------------------------------------------------
  --internal variables:
  ge_user___exception exception;
  gv_text             abslog.message%type := null;
  gv_erp_systemuserid systemuser.systemuser_id%type;
  gv_languageid       languages.language_id%type := 2;
  ----------------------------------------------------------------------------
  --internal functions:
  procedure write_o_log(fp_text     in abslog.message%type,
                        fp_priority in abslog.priority%type default 3) is
  begin
    --write_o_log
    abslogwrite.abslog_write(5, 'ERP_Interface', null, fp_priority, fp_text || ' ' || sqlerrm,
                             gv_erp_systemuserid);
  end write_o_log;

  procedure write_log(fp_logtablename    in varchar2,
                      fp_transferid      in number,
                      fp_text            in abslog.message%type,
                      fp_process_status  in number,
                      fp_transfer_status in number default 0) is
    lv_exec_sql_string varchar2(512);
  begin
    begin
      --build insert log string
      lv_exec_sql_string := 'INSERT INTO ' || upper(fp_logtablename) ||
                            '(transfer_id, transfer_status, text, process_status ) VALUES(:fp_transferid, :fp_transfer_status, :fp_text, :fp_process_status)';
      --execute insert log string
      execute immediate lv_exec_sql_string
        using fp_transferid, fp_transfer_status, fp_text, fp_process_status;
    exception
      when dup_val_on_index then
        begin
          --build update log string
          lv_exec_sql_string := 'UPDATE ' || upper(fp_logtablename) ||
                                '   SET transfer_status = :fp_transfer_status,' ||
                                '       text            = :fp_text,' ||
                                '       process_status  = :fp_process_status,' ||
                                '       timestamp       = sysdate' ||
                                ' WHERE transfer_id     = :fp_transferid';
          --execute insert log string
          execute immediate lv_exec_sql_string
            using fp_transfer_status, fp_text, fp_process_status, fp_transferid;
        end;
    end;
    commit;
  exception
    when others then
      begin
        --Write message in ABSLOG with debug info when something went wrong!
        rollback;
        write_o_log(fp_text || ' ' || sqlerrm, 3);
      end;
  end write_log;

  function get_customerid(fp_customernumber in customer.customernumber%type)
    return customer.customer_id%type is
    fp_customerid customer.customer_id%type;
  begin
    --get_customerid
    gv_text := ' get customer id for number ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      begin
        return null;
      end;
    else
      select c.customer_id
      into   fp_customerid
      from   customer c
      where  c.customernumber = fp_customernumber;
      return fp_customerid;
    end if;
  end get_customerid;

  function get_departmentid(fp_departmentnumber in department.departmentnumber%type,
                            fp_customerid       in customer.customer_id%type)
    return department.department_id%type is
    lv_departmentid department.department_id%type;
  begin
    --get_departmentid
    gv_text := ' department id for ' || nvl(to_char(fp_departmentnumber), 'NULL') ||
               ' for customer id ' || nvl(to_char(fp_customerid), 'NULL');
    select t.department_id
    into   lv_departmentid
    from   department t
    where  t.departmentnumber = fp_departmentnumber
    and    t.customer_id = fp_customerid;
    return lv_departmentid;
  end get_departmentid;

  function get_finishingmethodid(fp_finishingmethodcode in finishingmethod.code%type)
    return finishingmethod.finishingmethod_id%type is
    lv_finishingmethodid finishingmethod.finishingmethod_id%type;
  begin
    --get_finishingmethodid
    if fp_finishingmethodcode is null then
      begin
        return null;
      end;
    end if;
    gv_text := ' get finishingmethod id for code ' || fp_finishingmethodcode;
    select rg.finishingmethod_id
    into   lv_finishingmethodid
    from   finishingmethod rg
    where  rg.code = fp_finishingmethodcode;
    return lv_finishingmethodid;
  end get_finishingmethodid;

  function get_distributionpointid(fp_distributionpointnumber in distributionpoint.distributionpointnumber%type,
                                   fp_departmentid            in distributionpoint.department_id%type,
                                   fp_delpointid              out distributionpoint.deliverypoint_id%type)
    return distributionpoint.distributionpoint_id%type is
    lv_distributionpointid distributionpoint.distributionpoint_id%type;
  begin
    --get_distributionpointid
    gv_text := ' consumptionpoint id for ' || nvl(to_char(fp_distributionpointnumber), 'NULL') ||
               ' for department id ' || nvl(to_char(fp_departmentid), 'NULL');
    select dp.distributionpoint_id, dp.deliverypoint_id
    into   lv_distributionpointid, fp_delpointid
    from   distributionpoint dp
    where  dp.distributionpointnumber = fp_distributionpointnumber
    and    dp.department_id = fp_departmentid;
    return lv_distributionpointid;
  end get_distributionpointid;

  function get_flagid(fp_flagcode in flag.code%type, fp_flagtype in flag.flagtype%type)
    return flag.flag_id%type is
    lv_flagid flag.flag_id%type;
  begin
    --get_flagid
    if fp_flagcode is null then
      return null;
    else
      begin
        gv_text := ' get flag id for code ' || nvl(fp_flagcode, 'NULL') || ' flag type ' ||
                   nvl(to_char(fp_flagtype), 'NULL');
        select f.flag_id
        into   lv_flagid
        from   flag f
        where  f.code = fp_flagcode
        and    f.flagtype = fp_flagtype;
        return lv_flagid;
      end;
    end if;
  end get_flagid;

  function get_productid(fp_productcode       in product.code%type,
                         fp_rec_passive_stock in product.recordpassivestock%type default null,
                         fp_tom_product       in number default 0) return product.product_id%type is
    lv_productid   product.product_id%type;
    lv_tom_product product.typeofmerchandise%type;
  begin
    --get_productid
    if fp_productcode is null then
      begin
        return null;
      end;
    end if;
    if fp_rec_passive_stock is null then
      begin
        gv_text := ' get_product id for code ' || nvl(fp_productcode, 'NULL');
        select s.product_id, s.typeofmerchandise
        into   lv_productid, lv_tom_product
        from   product s
        where  s.code = fp_productcode;
      end;
    else
      begin
        gv_text := ' get_product id for code ' || nvl(fp_productcode, 'NULL') ||
                   ' with record passive stock is ' || fp_rec_passive_stock;
        select s.product_id, s.typeofmerchandise
        into   lv_productid, lv_tom_product
        from   product s
        where  s.code = fp_productcode
        and    s.recordpassivestock = fp_rec_passive_stock;
      end;
    end if;
    if fp_tom_product <> 0 and fp_tom_product <> lv_tom_product then
      begin
        gv_text := ' product ' || nvl(fp_productcode, 'NULL') || ' has TOM ' ||
                   to_char(lv_tom_product) || ' required is ' || fp_tom_product;
        raise ge_user___exception;
      end;
    end if;
    return lv_productid;
  end get_productid;

  function get_qualitygradeid(fp_qualitygradecode in qualitygrade.code%type)
    return qualitygrade.qualitygrade_id%type is
    lv_qualitygradeid qualitygrade.qualitygrade_id%type;
  begin
    --get_qualitygradeid
    gv_text := ' get qualitygrade id for code ' || fp_qualitygradecode;
    if fp_qualitygradecode is null then
      return null;
    end if;
    select pg.qualitygrade_id
    into   lv_qualitygradeid
    from   qualitygrade pg
    where  pg.code = fp_qualitygradecode;
    return lv_qualitygradeid;
  end get_qualitygradeid;

  function get_sizeid(fp_sizecode in sizedefinition.code%type)
    return sizedefinition.sizedefinition_id%type is
    lv_sizeid sizedefinition.sizedefinition_id%type;
  begin
    --get_sizeid
    gv_text := ' get_size id for code ' || nvl(fp_sizecode, 'NULL');
    select s.sizedefinition_id into lv_sizeid from sizedefinition s where s.code = fp_sizecode;
    return lv_sizeid;
  exception
    when no_data_found then
      begin
        --insert size id
        gv_text := ' get_size. insert size id for code ' || nvl(fp_sizecode, 'NULL');
        select seq_sizedefinition.nextval into lv_sizeid from dual;
        --insert into size tables
        insert into sizedefinition
          (sizedefinition_id, code, systemuser_id, unfinishedlength, legacysizecode, width,
           timestamp, length, usedforemblem, unfinishedsizedefinition_id, reservealternativesize)
        values
          (lv_sizeid, fp_sizecode, gv_erp_systemuserid, 'N', null, null, sysdate, null, 'N', null,
           'N');
        insert into sizedefinition_desc
          (sizedefinition_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_sizeid, gv_languageid, fp_sizecode, gv_erp_systemuserid, sysdate);
        insert into sizedefinition_link
          (sizedefinition_link_id, sizedefinition_id, code, systemuser_id, legacysizecode,
           timestamp)
        values
          (lv_sizeid, lv_sizeid, fp_sizecode, gv_erp_systemuserid, null, sysdate);
        insert into sizedefinition_link_desc
          (sizedefinition_link_id, language_id, description, systemuser_id, timestamp)
        values
          (lv_sizeid, gv_languageid, fp_sizecode, gv_erp_systemuserid, sysdate);
        return lv_sizeid;
      end;
  end get_sizeid;

  --process erp_i_wearer
  procedure proc_i_wearer_one(fp_transferid in erp_i_wearer.transfer_id%type,
                              fp_rerun      in number default 0) is
    lv_rec_erp_i_wearer          erp_i_wearer%rowtype;
    lv_rec_wearerinventory       wearerinventory%rowtype;
    lv_rec_erp_i_wearerinventory erp_i_wearerinventory%rowtype;
    lv_rec_wearer                wearer%rowtype;
    lv_rec_weareremployment      weareremployment%rowtype;
    lv_departmentid              department.department_id%type;
    lv_log_tablename             varchar2(32) := 'ERP_I_WEARER_LOG';
    lv_process_status            number := 0;
    -------------
    --internal procedure functions
    function read_line return number is
    begin
      --read_line erp_i_wearer
      select eip.*
      into   lv_rec_erp_i_wearer
      from   erp_i_wearer eip
      where  eip.transfer_id = fp_transferid
      and    (eip.transfer_status = 0 or fp_rerun > 0);
      --update line as read
      update erp_i_wearer eip
      set    eip.transfer_status = 1
      where  eip.transfer_id <= fp_transferid
      and    eip.transfer_status = 0
      and    eip.customernumber = lv_rec_erp_i_wearer.customernumber
      and    eip.wearernumber = lv_rec_erp_i_wearer.wearernumber
      and    eip.weareremploymentnumber = lv_rec_erp_i_wearer.weareremploymentnumber;
      commit;
      return 0;
    exception
      when no_data_found then
        begin
          gv_text := gv_text || ' nothing found to process';
          return 1;
        end;
    end read_line;
  
    function get_modificationid(fp_modificationcode in modification.code%type)
      return modification.modification_id%type is
      lv_modificationid modification.modification_id%type;
    begin
      --get_modificationid
      if fp_modificationcode is null then
        return null;
      else
        gv_text := ' get modification id for code ' || nvl(fp_modificationcode, 'NULL');
        select md.modification_id
        into   lv_modificationid
        from   modification md
        where  md.code = fp_modificationcode;
        return lv_modificationid;
      end if;
    end get_modificationid;
  
    procedure process_wearer is
      -------------
      --internal procedure functions from process_wearer
      procedure init_wearer is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_wearer';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'WEARER'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_wearer;
        close rcur_typ;
        --get id
        select seq_wearer.nextval into lv_rec_wearer.wearer_id from dual;
        --set default that CANNOT and MAY NOT be updated
        lv_rec_wearer.wearernumber := lv_rec_erp_i_wearer.wearernumber;
        lv_rec_wearer.customer_id  := get_customerid(lv_rec_erp_i_wearer.customernumber);
        --set missing defaults
        lv_rec_wearer.dummyforpool := 'N';
      end init_wearer;
    
      procedure update_rec_wearer is
      begin
        --update_rec_wearer
        gv_text                              := 'update_rec_wearer';
        lv_rec_wearer.fullname               := lv_rec_erp_i_wearer.fullname;
        lv_rec_wearer.searchname             := lv_rec_erp_i_wearer.searchname;
        lv_rec_wearer.emblemname             := lv_rec_erp_i_wearer.emblemname;
        lv_rec_wearer.firstname              := lv_rec_erp_i_wearer.firstname;
        lv_rec_wearer.customeremployeenumber := lv_rec_erp_i_wearer.customeremployeenumber;
        lv_rec_wearer.sex                    := coalesce(lv_rec_erp_i_wearer.sex, lv_rec_wearer.sex,
                                                         'M');
        lv_rec_wearer.dateactive             := coalesce(lv_rec_erp_i_wearer.dateactive,
                                                         lv_rec_wearer.dateactive, trunc(sysdate) - 1);
        lv_rec_wearer.dateinactive           := coalesce(lv_rec_erp_i_wearer.dateinactive,
                                                         lv_rec_wearer.dateinactive,
                                                         to_date('31-12-2099', 'DD-MM-YYYY'));
        lv_rec_wearer.remark                 := nvl(lv_rec_erp_i_wearer.remark, lv_rec_wearer.remark);
        lv_rec_wearer.flag_id                := get_flagid(lv_rec_erp_i_wearer.wearerflagcode, 1);
        if lv_rec_wearer.flag_id is null then
          lv_rec_wearer.flagstartdate := null;
        else
          lv_rec_wearer.flagstartdate := coalesce(lv_rec_erp_i_wearer.wearerflagstartdate,
                                                  lv_rec_wearer.flagstartdate, trunc(sysdate) - 1);
        end if;
        lv_rec_wearer.systemuser_id := gv_erp_systemuserid;
        lv_rec_wearer.timestamp     := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_wearer;
      -------------
    begin
      --process_wearer select
      gv_text                   := 'proc_i_wearer.process_wearer';
      lv_rec_wearer.customer_id := get_customerid(lv_rec_erp_i_wearer.customernumber);
      select w.*
      into   lv_rec_wearer
      from   wearer w
      where  w.wearernumber = lv_rec_erp_i_wearer.wearernumber
      and    w.customer_id = lv_rec_wearer.customer_id;
      --update_rec_wearer
      update_rec_wearer;
      --update wearer
      gv_text := 'proc_i_wearer.process_wearer update';
      update wearer w set row = lv_rec_wearer where w.wearer_id = lv_rec_wearer.wearer_id;
    exception
      when no_data_found then
        begin
          --process_wearer insert
          init_wearer;
          --update_rec_wearer
          update_rec_wearer;
          --insert record
          gv_text := 'proc_i_wearer.process_wearer insert';
          insert into wearer values lv_rec_wearer;
        end;
    end process_wearer;
  
    procedure process_weareremployment is
      -------------
      --internal procedure functions from process_weareremployment
      procedure init_weareremployement is
      begin
        --init_weareremployement
        gv_text := 'init_weareremployement';
        select seq_weareremployment.nextval
        into   lv_rec_weareremployment.weareremployment_id
        from   dual;
        lv_rec_weareremployment.wearer_id      := lv_rec_wearer.wearer_id;
        lv_rec_weareremployment.sequencenumber := lv_rec_erp_i_wearer.weareremploymentnumber;
        lv_rec_weareremployment.dispensecredit := 0;
      end init_weareremployement;
    
      procedure update_rec_weareremployement is
      begin
        --update_rec_weareremployement
        gv_text         := 'update_rec_weareremployement';
        lv_departmentid := get_departmentid(lv_rec_erp_i_wearer.departmentnumber,
                                            lv_rec_wearer.customer_id);
        --remark BANK/LOCKER and GARMENTDISPENSER are NOT used, only DELIVERYPOINT retrieved below
        lv_rec_weareremployment.distributionpoint_id := get_distributionpointid(lv_rec_erp_i_wearer.consumptionnumber,
                                                                                lv_departmentid,
                                                                                lv_rec_weareremployment.deliverypoint_id);
        lv_rec_weareremployment.flag_id              := get_flagid(lv_rec_erp_i_wearer.employmentflagcode,
                                                                   1);
        if lv_rec_weareremployment.flag_id is null then
          lv_rec_weareremployment.flagstartdate := null;
        else
          lv_rec_weareremployment.flagstartdate := coalesce(lv_rec_erp_i_wearer.employmentflagstartdate,
                                                            lv_rec_weareremployment.flagstartdate,
                                                            trunc(sysdate) - 1);
        end if;
        lv_rec_weareremployment.embroideryletteringline1 := lv_rec_erp_i_wearer.embroideryletteringline1;
        lv_rec_weareremployment.embroideryletteringline2 := lv_rec_erp_i_wearer.embroideryletteringline2;
        lv_rec_weareremployment.embroideryletteringline3 := lv_rec_erp_i_wearer.embroideryletteringline3;
        lv_rec_weareremployment.systemuser_id            := gv_erp_systemuserid;
        lv_rec_weareremployment.timestamp                := sysdate;
      end update_rec_weareremployement;
      -------------
    begin
      --process_weareremployment
      gv_text := 'proc_i_wearer.process_weareremployment';
      select we.*
      into   lv_rec_weareremployment
      from   weareremployment we
      where  we.wearer_id = lv_rec_wearer.wearer_id
      and    we.sequencenumber = lv_rec_erp_i_wearer.weareremploymentnumber;
      --update_rec_weareremployement
      update_rec_weareremployement;
      --update wearer
      gv_text := 'proc_i_wearer.process_weareremployement update';
      update weareremployment we
      set    row = lv_rec_weareremployment
      where  we.wearer_id = lv_rec_weareremployment.wearer_id
      and    we.sequencenumber = lv_rec_weareremployment.sequencenumber;
    exception
      when no_data_found then
        begin
          --process_weareremployement insert
          init_weareremployement;
          --update_rec_weareremployement
          update_rec_weareremployement;
          --insert record
          gv_text := 'proc_i_wearer.process_weareremployment insert';
          insert into weareremployment values lv_rec_weareremployment;
        end;
    end process_weareremployment;
  
    procedure process_weareremp_links is
    begin
      --process_weareremp_links
      gv_text := 'process_weareremp_links';
      update weareremployment_link wl
      set    wl.distributionpoint_link_id = lv_rec_weareremployment.distributionpoint_id,
             wl.wearersearchname = lv_rec_erp_i_wearer.searchname,
             wl.wearername = lv_rec_erp_i_wearer.fullname, wl.systemuser_id = gv_erp_systemuserid,
             wl.timestamp = sysdate
      where  wl.weareremployment_id = lv_rec_weareremployment.weareremployment_id;
      if sql%rowcount < 1 then
        raise no_data_found;
      end if;
    exception
      when no_data_found then
        begin
          --create link record
          insert into weareremployment_link
            (weareremployment_link_id, weareremployment_id, distributionpoint_link_id,
             wearersearchname, wearername, wearernumber, systemuser_id, timestamp, sequencenumber)
          values
            (lv_rec_weareremployment.weareremployment_id,
             lv_rec_weareremployment.weareremployment_id,
             lv_rec_weareremployment.distributionpoint_id, lv_rec_erp_i_wearer.searchname,
             lv_rec_erp_i_wearer.fullname, lv_rec_erp_i_wearer.wearernumber, gv_erp_systemuserid,
             sysdate, lv_rec_weareremployment.sequencenumber);
        end;
    end process_weareremp_links;
  
    procedure process_wearerinventory is
      -------------
      --internal procedure functions from process_wearerinventory
      procedure process_wearerinvmodification is
        lv_modificationid modification.modification_id%type;
      begin
        --process_wearerinvmodification
        gv_text := 'process_wearerinvmodification';
        if lv_rec_erp_i_wearerinventory.modificationcode1 is not null then
          begin
            lv_modificationid := get_modificationid(lv_rec_erp_i_wearerinventory.modificationcode1);
            begin
              insert into wearerinventorymodification
                (wearerinventory_id, modification_id, sequencenumber, systemuser_id, timestamp)
              values
                (lv_rec_wearerinventory.wearerinventory_id, lv_modificationid, 1,
                 gv_erp_systemuserid, sysdate);
            exception
              when dup_val_on_index then
                begin
                  --WEARERINVENTORY_ID, SEQUENCENUMBER
                  update wearerinventorymodification wim
                  set    wim.modification_id = lv_modificationid
                  where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id
                  and    wim.sequencenumber = 1;
                end;
            end;
            if lv_rec_erp_i_wearerinventory.modificationcode2 is not null then
              begin
                begin
                  lv_modificationid := get_modificationid(lv_rec_erp_i_wearerinventory.modificationcode2);
                  insert into wearerinventorymodification
                    (wearerinventory_id, modification_id, sequencenumber, systemuser_id, timestamp)
                  values
                    (lv_rec_wearerinventory.wearerinventory_id, lv_modificationid, 2,
                     gv_erp_systemuserid, sysdate);
                exception
                  when dup_val_on_index then
                    begin
                      --WEARERINVENTORY_ID, SEQUENCENUMBER
                      update wearerinventorymodification wim
                      set    wim.modification_id = lv_modificationid
                      where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id
                      and    wim.sequencenumber = 2;
                    end;
                end;
                if lv_rec_erp_i_wearerinventory.modificationcode3 is not null then
                  begin
                    begin
                      lv_modificationid := get_modificationid(lv_rec_erp_i_wearerinventory.modificationcode2);
                      insert into wearerinventorymodification
                        (wearerinventory_id, modification_id, sequencenumber, systemuser_id,
                         timestamp)
                      values
                        (lv_rec_wearerinventory.wearerinventory_id, lv_modificationid, 3,
                         gv_erp_systemuserid, sysdate);
                    exception
                      when dup_val_on_index then
                        begin
                          --WEARERINVENTORY_ID, SEQUENCENUMBER
                          update wearerinventorymodification wim
                          set    wim.modification_id = lv_modificationid
                          where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id
                          and    wim.sequencenumber = 3;
                        end;
                    end;
                  end;
                else
                  begin
                    delete from wearerinventorymodification wim
                    where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id
                    and    wim.sequencenumber = 3;
                  end;
                end if;
              end;
            else
              begin
                delete from wearerinventorymodification wim
                where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id
                and    wim.sequencenumber in (2, 3);
              end;
            end if;
          end;
        else
          begin
            delete from wearerinventorymodification wim
            where  wim.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id;
          end;
        end if;
      end process_wearerinvmodification;
    
      procedure check_plpc is
        lv_countplpc number;
      begin
        --check_plpc
        gv_text := 'check_plpc';
        select count(1)
        into   lv_countplpc
        from   productlistpercustomer l
        where  l.customer_id = lv_rec_wearer.customer_id
        and    l.product_id = lv_rec_wearerinventory.product_id
        and    (l.sizedefinition_id = lv_rec_wearerinventory.sizedefinition_id or
              l.sizedefinition_id =
              (select s.sizedefinition_id from sizedefinition s where s.code = '*'))
        and    l.dateactive <= lv_rec_erp_i_wearerinventory.startdate
        and    l.dateinactive >= lv_rec_erp_i_wearerinventory.enddate;
        if lv_countplpc = 0 then
          begin
            gv_text := 'No active PLPC line found for this wearer inventory line! Customer ' ||
                       to_char(lv_rec_erp_i_wearer.customernumber) || ' product ' ||
                       lv_rec_erp_i_wearerinventory.productcode || ' size ' ||
                       lv_rec_erp_i_wearerinventory.sizecode;
            raise ge_user___exception;
          end;
        end if;
      end check_plpc;
    
      function get_emblemtemplateid(fp_customerid         in customer.customer_id%type,
                                    fp_emblemtemplatecode in emblemtemplate.code%type)
        return emblemtemplate.emblemtemplate_id%type is
        lv_emblemtemplateid emblemtemplate.emblemtemplate_id%type;
      begin
        --get_emblemtemplateid
        if fp_emblemtemplatecode is null then
          return null;
        else
          begin
            gv_text := 'get emblemtemplate id for coded ' || nvl(fp_emblemtemplatecode, 'NULL') ||
                       ' for customer id ' || nvl(to_char(fp_customerid), 'NULL');
            select emt.emblemtemplate_id
            into   lv_emblemtemplateid
            from   emblemtemplate emt
            where  emt.code = fp_emblemtemplatecode
            and    emt.customer_id = fp_customerid;
            return lv_emblemtemplateid;
          end;
        end if;
      end get_emblemtemplateid;
    
      procedure init_wearerinventory is
        lv_query varchar2(1000);
        type cur_typ is ref cursor;
        rcur_typ cur_typ;
      begin
        --init fill the record with all default values
        gv_text := 'init_wearerinventory';
        for rec in (select data_default, data_type
                    from   user_tab_columns
                    where  table_name = 'WEARERINVENTORY'
                    order  by column_id) loop
          if rec.data_default is null then
            lv_query := lv_query || ', null';
          else
            lv_query := lv_query || ', ' || rec.data_default;
          end if;
        end loop;
        lv_query := 'SELECT' || substr(lv_query, 2) || ' FROM DUAL';
        open rcur_typ for lv_query;
        fetch rcur_typ
          into lv_rec_wearerinventory;
        close rcur_typ;
        --set default that CANNOT and MAY NOT be updated
        select seq_wearerinventory.nextval
        into   lv_rec_wearerinventory.wearerinventory_id
        from   dual;
        lv_rec_wearerinventory.weareremployment_id        := lv_rec_weareremployment.weareremployment_id;
        lv_rec_wearerinventory.product_id                 := get_productid(lv_rec_erp_i_wearerinventory.productcode);
        lv_rec_wearerinventory.sizedefinition_id          := get_sizeid(lv_rec_erp_i_wearerinventory.sizecode);
        lv_rec_wearerinventory.circinventory              := 0;
        lv_rec_wearerinventory.swingsuitstatus            := 0;
        lv_rec_wearerinventory.returnedqty                := 0;
        lv_rec_wearerinventory.qtytobereturnedreplacement := 0;
        lv_rec_wearerinventory.qtytobereturneddecreasemax := 0;
        lv_rec_wearerinventory.dispensecredit             := 0;
        lv_rec_wearerinventory.personalizedgarment        := 'Y';
      end init_wearerinventory;
    
      procedure update_rec_wearerinventory is
      begin
        --update_rec_wearerinventory
        gv_text                                   := 'update_rec_wearerinventory';
        lv_rec_wearerinventory.finishingmethod_id := get_finishingmethodid(lv_rec_erp_i_wearerinventory.finishingmethodcode);
        lv_rec_wearerinventory.specialgrade_id    := get_qualitygradeid(lv_rec_erp_i_wearerinventory.specialqualitygrade);
        lv_rec_wearerinventory.maxinventory       := lv_rec_erp_i_wearerinventory.maxinventory;
        lv_rec_wearerinventory.changesperweek     := lv_rec_erp_i_wearerinventory.changesperweek;
        lv_rec_wearerinventory.freeofchargeqty    := lv_rec_erp_i_wearerinventory.freeofchargeqty;
        lv_rec_wearerinventory.maxfreeofcharge    := lv_rec_erp_i_wearerinventory.maxfreeofcharge;
        lv_rec_wearerinventory.dateactive         := lv_rec_erp_i_wearerinventory.startdate;
        lv_rec_wearerinventory.dateinactive       := lv_rec_erp_i_wearerinventory.enddate;
        lv_rec_wearerinventory.emblemtemplate_id  := get_emblemtemplateid(lv_rec_wearer.customer_id,
                                                                          lv_rec_erp_i_wearerinventory.emblemtemplate);
        lv_rec_wearerinventory.remark             := lv_rec_erp_i_wearerinventory.remark;
        lv_rec_wearerinventory.systemuser_id      := gv_erp_systemuserid;
        lv_rec_wearerinventory.timestamp          := sysdate;
      exception
        when no_data_found then
          begin
            gv_text := gv_text || ' no data found!';
            raise ge_user___exception;
          end;
      end update_rec_wearerinventory;
    begin
      --process_wearerinventory
      gv_text := 'proc_i_prod.process_wearerinventory';
      for x in (select s.rowid
                from   erp_i_wearerinventory s
                where  s.transfer_id = fp_transferid
                and    (s.transfer_status = 0 or fp_rerun > 0)) loop
        begin
          --update status
          update erp_i_wearerinventory eis
          set    eis.transfer_status = 1
          where  eis.transfer_id = fp_transferid
          and    eis.rowid = x.rowid;
          --select record
          select eis.*
          into   lv_rec_erp_i_wearerinventory
          from   erp_i_wearerinventory eis
          where  eis.transfer_id = fp_transferid
          and    eis.rowid = x.rowid;
          lv_rec_wearerinventory.product_id        := get_productid(lv_rec_erp_i_wearerinventory.productcode);
          lv_rec_wearerinventory.sizedefinition_id := get_sizeid(lv_rec_erp_i_wearerinventory.sizecode);
          begin
            --insert/update wearerinventory
            select ps.*
            into   lv_rec_wearerinventory
            from   wearerinventory ps
            where  ps.weareremployment_id = lv_rec_weareremployment.weareremployment_id
            and    ps.product_id = lv_rec_wearerinventory.product_id
            and    ps.sizedefinition_id = lv_rec_wearerinventory.sizedefinition_id;
            --update_rec_wearerinventory
            update_rec_wearerinventory;
            --update wearerinventory
            gv_text := 'proc_i_prod.process_wearerinventory.update';
            update wearerinventory ps
            set    row = lv_rec_wearerinventory
            where  ps.wearerinventory_id = lv_rec_wearerinventory.wearerinventory_id;
          exception
            when no_data_found then
              begin
                --process_wearerinventory insert
                init_wearerinventory;
                --update_rec_wearerinventory
                update_rec_wearerinventory;
                --insert record
                gv_text := 'proc_i_wearer.wearerinventory.insert';
                insert into wearerinventory values lv_rec_wearerinventory;
              end;
          end;
          --check PLPC
          check_plpc;
          --process_wearerinvmodification
          process_wearerinvmodification;
        end;
      end loop; --x
    end process_wearerinventory;
    -------------
  begin
    --proc_i_wearer
    gv_text := 'proc_i_wearer process erp_i_wearer for fp_transferid ' ||
               nvl(to_char(fp_transferid), 'NULL') || ' rerun ' || nvl(to_char(fp_rerun), 'NULL');
    case read_line
      when 0 then
        begin
          process_wearer;
          process_weareremployment;
          process_weareremp_links;
          process_wearerinventory;
          gv_text := null;
        end;
      else
        begin
          lv_process_status := 1;
          raise ge_user___exception;
        end;
    end case;
    --update might exist older records for the same key
    update erp_i_wearer_log f
    set    f.process_status = 0, f.text = 'Newer record processed succesfully'
    where  exists (select fi.transfer_id
            from   erp_i_wearer fi
            where  fi.transfer_id = f.transfer_id
            and    fi.customernumber = lv_rec_erp_i_wearer.customernumber
            and    fi.wearernumber = lv_rec_erp_i_wearer.wearernumber
            and    fi.weareremploymentnumber = lv_rec_erp_i_wearer.weareremploymentnumber)
    and    f.transfer_id < lv_rec_erp_i_wearer.transfer_id
    and    f.process_status <> 0;
    --insert existing
    insert into erp_i_wearer_log
      (transfer_id, text, process_status, timestamp)
      select zz.transfer_id, 'Newer record processed succesfully', 0, sysdate
      from   erp_i_wearer zz
      where  zz.customernumber = lv_rec_erp_i_wearer.customernumber
      and    zz.wearernumber = lv_rec_erp_i_wearer.wearernumber
      and    zz.weareremploymentnumber = lv_rec_erp_i_wearer.weareremploymentnumber
      and    zz.transfer_id < lv_rec_erp_i_wearer.transfer_id
      and    zz.transfer_status = 1
      and    not exists
       (select 1 from erp_i_wearer_log zl where zl.transfer_id = zz.transfer_id);
    --all ok commit
    commit;
    write_log(lv_log_tablename, fp_transferid,
              'For customer ' || lv_rec_erp_i_wearer.customernumber || ' wearer ' ||
               lv_rec_erp_i_wearer.wearernumber, lv_process_status, 0);
  exception
    when ge_user___exception then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' For customer ' || lv_rec_erp_i_wearer.customernumber || ' wearer ' ||
                   lv_rec_erp_i_wearer.wearernumber, 1, 0);
      end;
    when no_data_found then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' no data found! For customer ' || lv_rec_erp_i_wearer.customernumber ||
                   ' wearer ' || lv_rec_erp_i_wearer.wearernumber, 1, 0);
      end;
    when others then
      begin
        rollback;
        write_log(lv_log_tablename, fp_transferid,
                  gv_text || ' ' || sqlerrm || ' For customer ' ||
                   lv_rec_erp_i_wearer.customernumber || ' wearer ' ||
                   lv_rec_erp_i_wearer.wearernumber, 1, 0);
      end;
  end proc_i_wearer_one;

  --process proc_i_wearer
  procedure proc_i_wearer(fp_transferid in erp_i_wearer.transfer_id%type,
                          fp_rerun      in number default 0) is
  begin
    for x in (select eiw.customernumber, eiw.wearernumber, eiw.weareremploymentnumber
              from   erp_i_wearer eiw
              where  eiw.transfer_id = fp_transferid
              and    (eiw.transfer_status = 0 or fp_rerun > 0)) loop
      begin
        for y in (select max(eipw.transfer_id) transfer_id
                  from   erp_i_wearer eipw
                  where  eipw.customernumber = x.customernumber
                  and    eipw.wearernumber = x.wearernumber
                  and    eipw.weareremploymentnumber = x.weareremploymentnumber) loop
          proc_i_wearer_one(y.transfer_id, fp_rerun);
        end loop; --y
      end;
    end loop; --x
  end proc_i_wearer;

  --process proc_i_wearer_all
  procedure proc_i_wearer_all is
  begin
    for ewr in (select l.transfer_id
                from   erp_i_wearer l
                where  l.transfer_status = 0
                order  by l.transfer_id) loop
      begin
        proc_i_wearer_one(ewr.transfer_id);
      end;
    end loop; --ewr
  end proc_i_wearer_all;
  ----------------------------------------------------------------------------
-- Initialization
begin
  if gv_erp_systemuserid is null then
    begin
      --get ERP systemuser
      select sy.systemuser_id
      into   gv_erp_systemuserid
      from   systemuser sy
      where  sy.username = 'ERP';
    exception
      when no_data_found then
        begin
          --not found take first one
          select min(sy.systemuser_id) into gv_erp_systemuserid from systemuser sy;
        end;
    end;
  end if;
end auj_erp_wearer;
/

create or replace procedure auj_upd_customer_ranking(fp_systemuserid in number default 1,
                                                     fp_processtype  in number default 23) is
  --auj_upd_customer_ranking version 0.3
  --data must be loaded into i_miscellaneous, that data will be processed.
  --Goal is to update the deliveryscheme FROM-TO
  --TABLE I_MISCELLANEOUS
  --NUMBERVALUE1  -> CUSTOMERNUMBER
  --STRINGVALUE1  -> REMARK
  --NUMBERVALUE2  -> PRIORITY (CUSTOMERRANKING)
  --NUMBERVALUE3  -> SYSTEMUSER_ID if empty we take fp_systemuserid or 1
  --BOOLEANVALUE1 -> N=NOT PROCESSED, Y=PROCESSED

  --global variables
  gv_user__exception exception;
  gv_message  abslog.message%type;
  gv_plantid  plant.plant_id%type; --LEFT EMPTY
  gv_rowcount number;

  ---internal procedures/functions
  procedure write_log(fp_message in varchar2 default null, fp_priority in number) is
  begin
    abslogwrite.abslog_write(5, 'auj_upd_customer_ranking', gv_plantid, fp_priority, fp_message,
                             fp_systemuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --no problem cannot show output, read abslog
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    write_log('Start the process for system user id ' || to_char(fp_systemuserid) ||
              ' fp_processtype used (normally 23) ' || to_char(nvl(fp_processtype, 23)), 1);
    --gv_rowcount reset
    gv_rowcount := 0;
  end initialize;

  procedure process is
    lv_customerid        customer.customer_id%type;
    lv_remark            customer.remark%type;
    lv_systemuserid      systemuser.systemuser_id%type;
    lv_customerrankingid customerranking.customerranking_id%type;
  
    procedure update_customerdata(fp_customernumber in number) is
    begin
      --update customer
      gv_message := 'update customer ' || to_char(fp_customernumber);
      update customer c
      set    c.remark = lv_remark, c.customerranking_id = lv_customerrankingid,
             c.timestamp = sysdate, c.systemuser_id = lv_systemuserid
      where  c.customer_id = lv_customerid;
    end update_customerdata;
  begin
    --process i_miscellaneous
    gv_message := 'process i_miscellaneous';
    for x in (select im.*, rowid
              from   i_miscellaneous im
              where  im.processtype = nvl(fp_processtype, 23) --default value 23
              and    im.tablename = 'CUSTOMER'
              and    im.booleanvalue1 = 'N') loop
      begin
        --NUMBERVALUE1 -> CUSTOMERNUMBER
        gv_message := 'NUMBERVALUE1 -> CUSTOMERNUMBER ' || to_char(x.numbervalue1);
        select c.customer_id
        into   lv_customerid
        from   customer c
        where  c.customernumber = x.numbervalue1;
        --STRINGVALUE1 -> REMARK
        gv_message := 'STRINGVALUE1 -> REMARK ' || x.stringvalue1;
        lv_remark  := x.stringvalue1;
        --NUMBERVALUE2 -> PRIORITY (CUSTOMERRANKING)
        gv_message := 'NUMBERVALUE2 -> PRIORITY (CUSTOMERRANKING) ' ||
                      nvl(to_char(x.numbervalue2), 'NULL');
        select cr.customerranking_id
        into   lv_customerrankingid
        from   customerranking cr
        where  cr.priority = x.numbervalue2;
        --NUMBERVALUE3 -> SYSTEMUSER_ID if empty we take fp_systemuserid
        gv_message      := 'NUMBERVALUE3 -> SYSTEMUSER_ID ' || to_char(x.numbervalue3);
        lv_systemuserid := coalesce(x.numbervalue3, fp_systemuserid, 1);
        --update_customerdata
        update_customerdata(x.numbervalue1);
        --processed ok
        update i_miscellaneous im
        set    im.booleanvalue1 = 'Y', im.stringvalue6 = 'Processed ok'
        where  im.rowid = x.rowid;
        commit;
      exception
        --processed NOT ok
        when gv_user__exception then
          begin
            rollback;
            update i_miscellaneous im
            set    im.booleanvalue1 = 'Y', im.stringvalue6 = gv_message
            where  im.rowid = x.rowid;
            commit;
          end;
        when no_data_found then
          begin
            rollback;
            update i_miscellaneous im
            set    im.booleanvalue1 = 'Y', im.stringvalue6 = 'No data found ' || gv_message
            where  im.rowid = x.rowid;
            commit;
          end;
        when others then
          begin
            rollback;
            gv_message := sqlerrm;
            update i_miscellaneous im
            set    im.booleanvalue1 = 'Y', im.stringvalue6 = gv_message
            where  im.rowid = x.rowid;
            commit;
          end;
      end;
    end loop;
  end process;

  procedure finalize is
  begin
    --finalize
    commit;
    write_log('Process ran successfully ' || to_char(gv_rowcount) || ' customer rows updated', 1);
  end finalize;
begin
  --Main process
  --initialize
  initialize;
  --process
  process;
  --finalize
  finalize;
exception
  --Exception handling
  when gv_user__exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(gv_message || ' ' || sqlerrm, 3);
    end;
end auj_upd_customer_ranking;
/

create or replace procedure change_masteraccount(fp_filename     in varchar2,
                                                 fp_directory    in varchar2,
                                                 fp_seperator    in varchar2 default ';',
                                                 fp_systemuserid in number default 0) is
  /*procedure change_masteraccount version 1.0*/
  -- ABS-121099
  --1-Oct-2021 we started to use enddate 31-12-2099 on contract(customer) and pricelists

  --Global variables
  gv_userexception exception;
  gv_counter      number := 0;
  gv_errors       number := 0;
  gv_message      varchar2(1000);
  gv_endddate     date := to_date('31-12-2099', 'dd-mm-yyyy');
  gv_org_masterid number;
  gv_new_masterid number;

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'change_masteraccount', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --cannot produce output but its in ABSLOG as well
    end;
  end write_log;

  procedure import_u_masteraccount is
    --global variables
    gv_filehandle utl_file.file_type;
    gv_separator  varchar2(1);
  
    ---internal procedure(s)
    procedure initialize is
    begin
      --initialize
      gv_message := 'initialize';
      if fp_filename is null then
        begin
          gv_message := 'parameter fp_filename cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_directory is null then
        begin
          gv_message := 'parameter fp_directory cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_seperator is null then
        begin
          gv_separator := ';';
        end;
      else
        begin
          gv_message   := 'check separator';
          gv_separator := fp_seperator;
        end;
      end if;
      execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
      execute immediate 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''';
    end initialize;
  
    procedure read_file is
    begin
      --open the file
      gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
      gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
    exception
      when utl_file.invalid_path then
        begin
          gv_message := gv_message || ' Invalid Path';
          raise gv_userexception;
        end;
      when utl_file.invalid_mode then
        begin
          gv_message := gv_message || ' Invalid Mode';
          raise gv_userexception;
        end;
      when utl_file.invalid_operation then
        begin
          gv_message := gv_message || ' Invalid Operation';
          raise gv_userexception;
        end;
      when utl_file.invalid_filehandle then
        begin
          gv_message := gv_message || ' Invalid Filehandle';
          raise gv_userexception;
        end;
      when utl_file.write_error then
        begin
          gv_message := gv_message || ' Write Error';
          raise gv_userexception;
        end;
      when utl_file.read_error then
        begin
          gv_message := gv_message || ' Read Error';
          raise gv_userexception;
        end;
      when utl_file.internal_error then
        begin
          gv_message := gv_message || ' Internal Error';
          raise gv_userexception;
        end;
    end read_file;
  
    procedure process_file is
      lv_readline        varchar2(4000);
      lv_line_counter    number := 0;
      lv_u_masteraccount u_masteraccount%rowtype;
    
      ----process_file internal procedures
      procedure process_line(fp_readline in varchar2) is
      
        ---process_file.process_line internal procedures
        procedure read_line(fp_readline in varchar2) is
          lv_currentposition number := 0;
          lv_nextposition    number := 0;
          lv_laststring      boolean := false;
        
          ---process_file.process_line.read_line internal function
          function get_nextvalue(fp_message in varchar2) return varchar2 is
          
            --process_file.process_line.read_line.get_nextvalue internal function
            function get_position(fp_startpos in number) return number is
            begin
              --get_position
              return instr(substr(fp_readline, fp_startpos + 1), gv_separator) + fp_startpos;
            end get_position;
          begin
            --get_nextvalue
            lv_currentposition := lv_nextposition;
            lv_nextposition    := get_position(lv_currentposition);
            gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                  to_char(lv_nextposition) || ' ' || fp_message;
            if lv_nextposition = lv_currentposition then
              begin
                --separator not found, so last field
                --last string, repeat it, if nothing else...
                if not lv_laststring then
                  begin
                    lv_laststring := true;
                    --read last value
                    return substr(fp_readline, lv_currentposition + 1);
                  end;
                else
                  begin
                    --no new values found!
                    return null;
                  end;
                end if;
              end;
            else
              --read value
              return trim(substr(fp_readline, lv_currentposition + 1,
                                 lv_nextposition - lv_currentposition - 1));
            end if;
          end get_nextvalue;
        begin
          --read_line
          lv_laststring                := false;
          lv_u_masteraccount.timestamp := sysdate;
          lv_u_masteraccount.processed := 0;
          --read values
          lv_u_masteraccount.orignal_masteraccount  := to_number(get_nextvalue('orignal_masteraccount'));
          lv_u_masteraccount.original_contractcode  := get_nextvalue('original_contractcode');
          lv_u_masteraccount.original_pricelistcode := get_nextvalue('original_pricelistcode');
          lv_u_masteraccount.pricetype              := to_number(get_nextvalue('pricetype'));
          lv_u_masteraccount.new_masteraccount      := to_number(get_nextvalue('new_masteraccount'));
          lv_u_masteraccount.new_contractcode       := get_nextvalue('new_contractcode');
          lv_u_masteraccount.new_pricelistcode      := get_nextvalue('new_pricelistcode');
        end read_line;
      
        procedure insert_line is
        begin
          --insert_line
          gv_message := 'insert_line';
          insert into u_masteraccount values lv_u_masteraccount;
          commit;
        end insert_line;
      begin
        --read
        read_line(fp_readline);
        --insert
        insert_line;
      exception
        when others then
          begin
            write_log('Line# ' || to_char(lv_line_counter) || ' error ' || sqlerrm || ' ' ||
                      gv_message || ' file ' || fp_filename, 3);
          end;
      end process_line;
    begin
      --process_file
      gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                    nvl(fp_directory, '<Empty>');
      --loop go through lines
      loop
        begin
          begin
            -- get line from file.
            utl_file.get_line(gv_filehandle, lv_readline);
            lv_line_counter := lv_line_counter + 1;
          exception
            when no_data_found then
              exit;
          end;
          --process_line
          gv_message := 'Linenumber ' || lv_line_counter;
          --process lines
          if substr(lv_readline, 1, 3) <> (gv_separator || gv_separator || gv_separator) then
            begin
              process_line(lv_readline);
            end;
          end if;
        end;
      end loop;
      --commit
      commit;
    end process_file;
  
    procedure close_file is
    begin
      --close file(s)
      gv_message := 'close files';
      if utl_file.is_open(gv_filehandle) = true then
        utl_file.fclose(gv_filehandle);
      end if;
      utl_file.fclose_all;
    end close_file;
  
    procedure finalize is
    begin
      --write log
      write_log('Successfully processed file ' || fp_filename || ' in directory ' || fp_directory,
                1);
    end finalize;
    --start main procedure
  begin
    --initialize
    initialize;
    --read_file
    read_file;
    --process_file
    process_file;
    --close file
    close_file;
    --finalize
    finalize;
  exception
    --exception handling global
    when gv_userexception then
      begin
        raise gv_userexception;
      end;
    when others then
      begin
        rollback;
        write_log('Error Others ' || sqlerrm || ' ' || gv_message, 3);
        close_file;
        gv_message := 'error processing file';
        raise gv_userexception;
      end;
  end import_u_masteraccount;

  function get_customerid(fp_customernumber in customer.customernumber%type)
    return customer.customer_id%type is
    fp_customerid customer.customer_id%type;
  begin
    --get_customerid
    gv_message := ' customer ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      return null;
    else
      select c.customer_id
      into   fp_customerid
      from   customer c
      where  c.customernumber = fp_customernumber;
      return fp_customerid;
    end if;
  end get_customerid;

  procedure create_new_contract(fp_original_contractcode in varchar2,
                                fp_new_contractcode      in varchar2) is
    lv_rowcount        number;
    lv_con_customer_id number;
  begin
    --create_new_contract
    gv_message := 'create_new_contract';
    select cc.customer_link_id
    into   lv_con_customer_id
    from   contract cc
    where  cc.code = fp_new_contractcode;
    if lv_con_customer_id <> gv_new_masterid then
      begin
        gv_message := 'new contractcode ' || fp_new_contractcode ||
                      ' already linked to another customer';
        raise no_data_found;
      end;
    end if;
  exception
    when no_data_found then
      begin
        insert into contract
          (contract_id, code, description, contracttype_id, contractdocument, salesemployee_id,
           commisionpayablesales, accountmanager_id, commisionpayableaccmgr, customer_link_id, owner,
           address_id, country_id, cvrnumber, phonenumber, signdate, startdate, enddate, duration,
           termofnotice, terminationdate, autextensionperiod, contactperson_id, contactpersonname,
           gainreason_id, gaincompetitor_id, lostreason_id, lostcompetitor_id,
           startdatepriceincrease, updateevery, previouspriceincrease, nextschedulepriceincrease,
           agreedpriceindex_id, notagreedpriceindex_id, allownotagreedpricelists, purchaseorder,
           purchaseordervalue, purchaseorderexpirationdate, estimatedweeklysales, remark,
           systemuser_id, timestamp) --,status_id)
          select seq_contract.nextval, fp_new_contractcode, description, contracttype_id,
                 contractdocument, salesemployee_id, commisionpayablesales, accountmanager_id,
                 commisionpayableaccmgr, gv_new_masterid, owner, address_id, country_id, cvrnumber,
                 phonenumber, signdate, startdate, gv_endddate, duration, termofnotice,
                 terminationdate, autextensionperiod, contactperson_id, contactpersonname,
                 gainreason_id, gaincompetitor_id, lostreason_id, lostcompetitor_id,
                 startdatepriceincrease, updateevery, previouspriceincrease,
                 nextschedulepriceincrease, agreedpriceindex_id, notagreedpriceindex_id,
                 allownotagreedpricelists, purchaseorder, purchaseordervalue,
                 purchaseorderexpirationdate, estimatedweeklysales, remark, nvl(fp_systemuserid, 0),
                 sysdate --, status_id
          from   contract cc
          where  cc.code = fp_original_contractcode
          and    cc.customer_link_id = gv_org_masterid;
        lv_rowcount := sql%rowcount;
        if lv_rowcount = 0 then
          begin
            gv_message := 'original_contractcode ' || fp_original_contractcode;
            raise no_data_found;
          end;
        end if;
      end;
  end create_new_contract;

  procedure copy_pricelists(fp_original_pricelistcode in varchar2,
                            fp_pricetype              in number,
                            fp_new_pricelistcode      varchar2) is
    lv_rowcount number;
  
    procedure insert_generalpricelist is
      lv_genpriceid number;
    begin
      begin
        --check if it already exists
        select g.generalpricelist_id
        into   lv_genpriceid
        from   generalpricelist g
        where  g.code = fp_new_pricelistcode
        and    g.pricetype = fp_pricetype;
      exception
        when no_data_found then
          begin
            --did not yet exist, we create it
            --unique key PRICETYPE, CODE
            select seq_generalpricelist.nextval into lv_genpriceid from dual;
            --
            insert into generalpricelist
              (priceindexcode, autopriceupdate, active, description, code, pricetype,
               generalpricelist_id, currency_id, timestamp, systemuser_id, usage)
              select gl.priceindexcode, gl.autopriceupdate, gl.active, gl.description,
                     fp_new_pricelistcode, gl.pricetype, lv_genpriceid, gl.currency_id, sysdate,
                     nvl(fp_systemuserid, 0), gl.usage
              from   generalpricelist gl
              where  gl.code = fp_original_pricelistcode
              and    gl.pricetype = fp_pricetype;
            lv_rowcount := sql%rowcount;
            if lv_rowcount = 0 then
              begin
                gv_message := 'original pricelist ' || fp_original_pricelistcode || ' pricetype ' ||
                              to_char(fp_pricetype);
                raise no_data_found;
              end;
            end if;
          end;
      end;
      insert into pricelistpercustomer
        (pricelistpercustomer_id, customer_id, pricetype, priority, generalpricelist_id, dateactive,
         dateinactive, systemuser_id, timestamp)
        select seq_pricelistpercustomer.nextval, gv_new_masterid, gl.pricetype, 16,
               gl.generalpricelist_id, trunc(sysdate - 1), gv_endddate, nvl(fp_systemuserid, 0),
               sysdate
        from   generalpricelist gl
        where  gl.generalpricelist_id = lv_genpriceid;
    exception
      when dup_val_on_index then
        begin
          --warning
          write_log('new pricelist ' || fp_new_pricelistcode || ' type ' || to_char(fp_pricetype) ||
                    ' did already exists', 2);
        end;
    end insert_generalpricelist;
  begin
    --copy_pricelist
    gv_message := 'copy generalpricelist';
    --insert_generalpricelist
    insert_generalpricelist;
    --copy the different general price lists, copy them to the new pricelist
    case fp_pricetype
      when 1 then
        begin
          --wash
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, STARTDATE, PRICETYPE
          insert into generalwashprice
            (generalwashprice_id, generalpricelist_id, product_id, sizedefinition_id,
             finishingmethod_id, timestamp, systemuser_id, price, startdate, pricetype)
            select seq_generalwashprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id,
                   finishingmethod_id, sysdate, nvl(fp_systemuserid, 0), price, startdate, pricetype
            from   generalwashprice gwp
            where  gwp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalwashprice wx
                    where  wx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    wx.product_id = gwp.product_id
                    and    wx.sizedefinition_id = gwp.sizedefinition_id
                    and    wx.finishingmethod_id = gwp.finishingmethod_id
                    and    wx.startdate = gwp.startdate
                    and    wx.pricetype = gwp.pricetype);
        end;
      when 2 then
        begin
          --rent
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, TYPEOFRENT, STARTDATE, CHANGESPERWEEK
          insert into generalrentprice
            (generalrentprice_id, generalpricelist_id, product_id, sizedefinition_id,
             finishingmethod_id, timestamp, systemuser_id, price, startdate, changesperweek,
             typeofrent, invoicefrequencynumber)
            select seq_generalrentprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id,
                   finishingmethod_id, sysdate, nvl(fp_systemuserid, 0), price, startdate,
                   changesperweek, typeofrent, invoicefrequencynumber
            from   generalrentprice gr
            where  gr.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalrentprice rx
                    where  rx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    rx.product_id = gr.product_id
                    and    rx.sizedefinition_id = gr.sizedefinition_id
                    and    rx.finishingmethod_id = gr.finishingmethod_id
                    and    rx.typeofrent = gr.typeofrent
                    and    rx.startdate = gr.startdate
                    and    rx.changesperweek = gr.changesperweek);
        end;
      when 3 then
        begin
          --replacement
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
          insert into generalreplacementprice
            (generalreplacementprice_id, generalpricelist_id, product_id, sizedefinition_id,
             timestamp, systemuser_id, price, startdate)
            select seq_generalreplacementprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id, sysdate,
                   nvl(fp_systemuserid, 0), price, startdate
            from   generalreplacementprice grp
            where  grp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalreplacementprice mx
                    where  mx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    mx.product_id = grp.product_id
                    and    mx.sizedefinition_id = grp.sizedefinition_id
                    and    mx.startdate = grp.startdate);
        end;
      when 4 then
        begin
          --sales
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
          insert into generalsalesprice
            (generalsalesprice_id, generalpricelist_id, product_id, sizedefinition_id, timestamp,
             systemuser_id, price, startdate)
            select seq_generalsalesprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id, sysdate,
                   nvl(fp_systemuserid, 0), price, startdate
            from   generalsalesprice gsp
            where  gsp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalsalesprice cx
                    where  cx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    cx.product_id = gsp.product_id
                    and    cx.sizedefinition_id = gsp.sizedefinition_id
                    and    cx.startdate = gsp.startdate);
        end;
      when 6 then
        begin
          --repair
          --GENERALPRICELIST_ID, REPAIRTYPE_ID, STARTDATE
          insert into generalrepairprice
            (generalrepairprice_id, generalpricelist_id, repairtype_id, price, startdate,
             priceperminute, systemuser_id, timestamp)
            select seq_generalrepairprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), repairtype_id, price, startdate,
                   priceperminute, nvl(fp_systemuserid, 0), sysdate
            from   generalrepairprice gf
            where  gf.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalrepairprice lx
                    where  lx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    lx.repairtype_id = gf.repairtype_id
                    and    lx.startdate = gf.startdate);
        end;
      else
        begin
          gv_message := 'Error no prices copied for pricetype ' || to_char(fp_pricetype);
          raise gv_userexception;
        end;
    end case;
  end copy_pricelists;

  procedure link_pricelists(fp_original_contractcode  in varchar2,
                            fp_new_contractcode       in varchar2,
                            fp_original_pricelistcode in varchar2,
                            fp_pricetype              in number,
                            fp_new_pricelistcode      varchar2) is
  begin
    --link_pricelists
    --CONTRACT_ID, GENERALPRICELIST_ID--, PRICETYPE
    gv_message := 'link_pricelists';
    insert into contractpricelist
      (contractpricelist_id, contract_id, generalpricelist_id, startdate, enddate, agreed,
       systemuser_id, timestamp)
      select seq_contractpricelist.nextval,
             (select cc.contract_id from contract cc where cc.code = fp_new_contractcode),
             (select glx.generalpricelist_id
               from   generalpricelist glx
               where  glx.code = fp_new_pricelistcode
               and    glx.pricetype = fp_pricetype), startdate, enddate, agreed,
             nvl(fp_systemuserid, 0), sysdate
      from   contractpricelist ccl
      where  ccl.contract_id =
             (select cc.contract_id from contract cc where cc.code = fp_original_contractcode)
      and    ccl.generalpricelist_id =
             (select gl.generalpricelist_id
               from   generalpricelist gl
               where  gl.code = fp_original_pricelistcode
               and    gl.pricetype = fp_pricetype)
      and    not exists
       (select 1
              from   contractpricelist cp
              where  cp.contract_id =
                     (select cc.contract_id from contract cc where cc.code = fp_new_contractcode)
              and    cp.generalpricelist_id =
                     (select glx.generalpricelist_id
                       from   generalpricelist glx
                       where  glx.code = fp_new_pricelistcode
                       and    glx.pricetype = fp_pricetype));
  end link_pricelists;

  procedure create_contractcustomer(fp_new_contractcode in varchar2) is
    lv_contractcustomerid number;
  begin
    --create_contractcustomer
    gv_message := 'create_contractcustomer';
    select cc.contractcustomer_id
    into   lv_contractcustomerid
    from   contractcustomer cc
    where  cc.contract_id =
           (select cc.contract_id from contract cc where cc.code = fp_new_contractcode)
    and    cc.customer_link_id = gv_new_masterid;
  exception
    when no_data_found then
      begin
        insert into contractcustomer
          (contractcustomer_id, contract_id, customer_link_id, startdate, enddate, systemuser_id,
           timestamp)
          select seq_contractcustomer.nextval, c.contract_id, gv_new_masterid, c.startdate,
                 gv_endddate, nvl(fp_systemuserid, 0), sysdate
          from   contract c
          where  c.code = fp_new_contractcode;
      exception
        when dup_val_on_index then
          null;
      end;
  end create_contractcustomer;
begin
  write_log('Start', 1);
  --import_u_masteraccount load file
  import_u_masteraccount;
  --process data from file
  for x in (select u.*, rowid from u_masteraccount u where u.processed = 0) loop
    begin
      gv_counter := gv_counter + 1;
      --start loop x
      --get customer numbers
      gv_org_masterid := get_customerid(x.orignal_masteraccount);
      gv_new_masterid := get_customerid(x.new_masteraccount);
      --create new contract
      create_new_contract(x.original_contractcode, x.new_contractcode);
      --create_contractcustomer
      create_contractcustomer(x.new_contractcode);
      --copy_pricelists
      copy_pricelists(x.original_pricelistcode, x.pricetype, x.new_pricelistcode);
      --link_pricelists
      link_pricelists(x.original_contractcode, x.new_contractcode, x.original_pricelistcode,
                      x.pricetype, x.new_pricelistcode);
      --set flag
      update u_masteraccount u set u.processed = 1 where u.rowid = x.rowid;
      --commit all ok and count number of succesfully processed records
      commit;
    exception
      --Exception handling, and count errors
      when gv_userexception then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End.' || gv_message, 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
      when no_data_found then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End. Error, No Data Found ' || gv_message || ' ORIGNAL_MASTERACCOUNT ' ||
                    to_char(x.orignal_masteraccount) || ' ORIGINAL_CONTRACTCODE ' ||
                    x.original_contractcode || ' ORIGINAL_PRICELISTCODE ' ||
                    x.original_pricelistcode || ' PRICETYPE ' || to_char(x.pricetype), 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
      when others then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End. Error ' || sqlerrm || ' ' || gv_message || ' ORIGNAL_MASTERACCOUNT ' ||
                    to_char(x.orignal_masteraccount) || ' ORIGINAL_CONTRACTCODE ' ||
                    x.original_contractcode || ' ORIGINAL_PRICELISTCODE ' ||
                    x.original_pricelistcode || ' PRICETYPE ' || to_char(x.pricetype), 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
    end;
  end loop; --x
  commit;
  write_log(' file ' || fp_filename || ' in directory ' || fp_directory || ' processed', 1);
  if gv_errors > 0 then
    begin
      write_log(' warning ' || to_char(gv_errors) || ' errors', 1);
      write_log('End processed ' || to_char(gv_counter) || ' rows', 1);
    end;
  else
    write_log('End processed ' || to_char(gv_counter) || ' rows', 1);
  end if;
exception
  --Exception handling
  when gv_userexception then
    begin
      rollback;
      write_log(gv_message || chr(10) || 'End.', 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error, No Data Found ' || gv_message || chr(10) || 'End.', 3);
    end;
  when others then
    begin
      rollback;
      write_log('Error ' || sqlerrm || ' ' || gv_message || ' file ' || fp_filename ||
                ' in directory ' || fp_directory || chr(10) || 'End.', 3);
    end;
end change_masteraccount;
/

create or replace procedure cleanup_inactiveroutestops(fp_systemuserid in number default 1) is
  --cleanup_inactiveroutestops version 0.7
  -----
  --Cleanup inactive routes
  -- Cleanup all inactive routestops if customer has at least 1 active routestop
  -- If customer has no active routestop, then keep last inactive routestop
  gv_message varchar2(1000);
  gv_counter number;
  gv_date    date;

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'Cleanup Inactive Routestops', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --ok no output to screen
    end;
  end write_log;

  procedure fix_bugs is
  begin
    --remove invalid customerdeliveryscheme records
    delete from customerdeliveryscheme cds
    where  not exists (select 1
            from   customerdeliveryday cd
            where  cd.customer_id = cds.customer_id
            and    cd.day_id = cds.day_id);
    gv_counter := sql%rowcount;
    commit;
    if gv_counter > 0 then
      begin
        write_log('Removed a total of ' || gv_counter ||
                  ' customerdeliveryscheme without a customerdeliveryday', 1);
      end;
    end if;
  end fix_bugs;

  procedure cleanup_days_no_routestop is
    procedure cleanup_days(fp_dayid in number, fp_customerid in number) is
    begin
      --delete customer days in related tables see condition above why
      gv_message := 'delete from customer days, customer id ' || to_char(fp_customerid) || ' day ' ||
                    to_char(fp_dayid);
      delete from customerdeliveryday cdd
      where  cdd.day_id = fp_dayid
      and    cdd.customer_id = fp_customerid;
      --delete productdeliveryday
      delete from productdeliveryday pdd
      where  pdd.day_id = fp_dayid
      and    pdd.productlistpercustomer_id in
             (select l.productlistpercustomer_id
               from   productlistpercustomer l
               where  l.customer_id = fp_customerid);
      --delete customerdeliveryscheme
      delete from customerdeliveryscheme cds
      where  cds.day_id = fp_dayid
      and    cds.customer_id = fp_customerid;
      --delete deliveryday
      delete from deliveryday du
      where  du.day_id = fp_dayid
      and    exists (select 1
              from   department t
              where  t.department_id = du.department_id
              and    t.customer_id = fp_customerid);
      --update customer timestamp
      update customer c
      set    c.timestamp = sysdate, c.systemuser_id = nvl(fp_systemuserid, 1)
      where  c.customer_id = fp_customerid;
      --commit, to be able to count
      commit;
      --count routestops cleaned up
      gv_counter := gv_counter + 1;
    end cleanup_days;
  begin
    --cleanup_days_no_routestop
    gv_counter := 0;
    for y in (select cdd.day_id, cdd.customer_id
              from   customerdeliveryday cdd
              where  not exists (select 1
                      from   routestop rs
                      join   route r
                      on     r.route_id = rs.route_id
                      where  rs.customer_id = cdd.customer_id
                      and    r.drivingday_id = cdd.day_id)
              group  by cdd.day_id, cdd.customer_id) loop
      begin
        --cleanup_days
        cleanup_days(y.day_id, y.customer_id);
      end;
    end loop; --y
    commit;
    write_log('Removed a total of ' || gv_counter ||
              ' customer deliverydays with no routestop linked', 1);
  end cleanup_days_no_routestop;

  procedure remove_inactive_routestops is
    procedure remove_stop(fp_routestopid in number, fp_customerid in number) is
    begin
      --remove_stop
      gv_message := 'Remove stop for routestop id ' || to_char(fp_routestopid);
      --delete straightevenreturn
      delete from straightevenreturn ste
      where  exists (select 1
              from   stop st
              where  st.stop_id = ste.stop_id
              and    st.routestop_id = fp_routestopid);
      --delete stop
      delete from stop st where st.routestop_id = fp_routestopid;
      --routestop
      delete from routestop rs
      where  rs.routestop_id = fp_routestopid
      and    rs.dateactive < sysdate;
      --update customer timestamp
      update customer c
      set    c.timestamp = sysdate, c.systemuser_id = nvl(fp_systemuserid, 1)
      where  c.customer_id = fp_customerid;
      --commit, to be able to count
      commit;
      --count routestops cleaned up
      gv_counter := gv_counter + 1;
    end remove_stop;
  begin
    gv_counter := 0;
    for x in (select c.customernumber, c.name customername, r.routenumber, r.drivingday_id,
                     rs.stopnumber, rs.routestop_id, c.customer_id, rs.dateinactive,
                     nvl((select min(cdd.deliverytype)
                          from   customerdeliveryday cdd
                          where  cdd.customer_id = rs.customer_id
                          and    cdd.day_id = r.drivingday_id
                          and    cdd.deliverytype = 'B'), 'X') deliverytype,
                     (select count(distinct ars.routestop_id)
                       from   routestop ars
                       join   route ar
                       on     ar.route_id = ars.route_id
                       join   customerdeliveryday cdd
                       on     cdd.customer_id = ars.customer_id
                       and    cdd.day_id = ar.drivingday_id
                       where  ars.customer_id = rs.customer_id
                       and    cdd.deliverytype = 'B'
                       and    sysdate between ars.dateactive and ars.dateinactive) active_b_routestop
              from   routestop rs
              join   customer c
              on     c.customer_id = rs.customer_id
              join   route r
              on     r.route_id = rs.route_id
              where  rs.dateinactive < sysdate) loop
      begin
        gv_message := 'delete routestop id ' || to_char(x.routestop_id);
        if nvl(x.deliverytype, 'X') = 'B' and x.active_b_routestop = 0 then
          begin
            --lookup most recent B routestop, to optionally keep
            select max(rs.dateinactive)
            into   gv_date
            from   routestop rs
            join   route r
            on     r.route_id = rs.route_id
            join   customerdeliveryday cdd
            on     cdd.customer_id = rs.customer_id
            and    cdd.day_id = r.drivingday_id
            where  rs.customer_id = x.customer_id
            and    cdd.deliverytype = 'B'
            and    rs.dateinactive < sysdate;
            if gv_date <> x.dateinactive then
              begin
                --stop
                remove_stop(x.routestop_id, x.customer_id);
                --write cleanup info
                write_log('Removed routestop for route ' || to_char(x.routenumber) || ' day ' ||
                          to_char(x.drivingday_id) || ' stop ' || to_char(x.stopnumber) ||
                          ' cust# ' || to_char(x.customernumber) || ' ' || x.customername, 1);
              end;
            end if;
          end;
        else
          begin
            --stop
            remove_stop(x.routestop_id, x.customer_id);
            --write cleanup info
            write_log('Removed routestop for route ' || to_char(x.routenumber) || ' day ' ||
                      to_char(x.drivingday_id) || ' stop ' || to_char(x.stopnumber) || ' cust# ' ||
                      to_char(x.customernumber) || ' ' || x.customername, 1);
          end;
        end if;
      end;
    end loop; --x
    commit;
    write_log('Removed a total of ' || gv_counter || ' inactive routestops', 1);
  end remove_inactive_routestops;
begin
  --fix bugs
  fix_bugs;
  --main code
  cleanup_days_no_routestop;
  --remove_inactive_routestops
  remove_inactive_routestops;
  --cleanup_days_no_routestop;
  cleanup_days_no_routestop;
exception
  when others then
    begin
      rollback;
      write_log(gv_message || ' ' || sqlerrm, 3);
    end;
end cleanup_inactiveroutestops;
/

create or replace procedure copy_supplier(fp_from_suppliernumber    in supplier.suppliernumber%type,
                                          fp_to_suppliernumber      in supplier.suppliernumber%type,
                                          fp_move_stockroomsupplier in varchar2 default 'N') is
  --version 1.11
  gv_message           abslog.message%type;
  gv_to_supplierid     supplier.supplier_id%type;
  gv_from_supplierid   supplier.supplier_id%type := null;
  gv_supplierproductid supplierproduct.supplierproduct_id%type;
  gv_counter           number := 0;

  procedure write_log(fp_priority in number default 1) is
  begin
    --write_log
    abslogwrite.abslog_write(5,
                             'copy_supplier',
                             null,
                             fp_priority,
                             gv_message);
  end write_log;

  procedure update_stockdefinitionperitem is
    lv_counter number;
  begin
    if fp_move_stockroomsupplier = 'Y' and gv_from_supplierid is not null then
      begin
        --move_stockroomsupplier
        gv_message := 'update_stockdefinitionperitem from supplier ' ||
                      coalesce(to_char(fp_from_suppliernumber), 'NULL') ||
                      ' to supplier ' ||
                      coalesce(to_char(fp_to_suppliernumber), 'NULL');
      
        update stockdefinitionperitem sti
           set sti.defaultsupplier_id = gv_to_supplierid,
               sti.timestamp          = sysdate
         where sti.defaultsupplier_id = gv_from_supplierid;
        lv_counter := sql%rowcount;
        if lv_counter > 0 then
          begin
            gv_message := 'updated ' || to_char(lv_counter) ||
                          ' stockdefinitionperitem records, from default supplier ' ||
                          coalesce(to_char(fp_from_suppliernumber), 'NULL') ||
                          ' to default supplier ' ||
                          coalesce(to_char(fp_to_suppliernumber), 'NULL');
            write_log;
          end;
        end if;
      end;
    end if;
  end update_stockdefinitionperitem;
  
  procedure update_product is
  begin
    update product p
    set p.supplier_id = gv_to_supplierid, p.timestamp  = sysdate
    where p.supplier_id = gv_from_supplierid;
  end update_product;
begin
  --copy_supplier
  gv_message := 'select to supplier number ' ||
                coalesce(to_char(fp_to_suppliernumber), 'NULL');
  select s.supplier_id
    into gv_to_supplierid
    from supplier s
   where s.suppliernumber = fp_to_suppliernumber;
  --loop suppliers 241 lines
  gv_message := 'loop from supplier number ' ||
                coalesce(to_char(fp_from_suppliernumber), 'NULL') ||
                ' lines';
  --loop x supplierproduct
  for x in (select sp.*
              from supplierproduct sp
             where sp.supplier_id =
                   (select s.supplier_id
                      from supplier s
                     where s.suppliernumber = fp_from_suppliernumber)) loop
    begin
      gv_message         := 'insert into supplierproduct for supplier ' ||
                            to_char(fp_to_suppliernumber) ||
                            ' SUPPLIERPRODUCTCODE ' ||
                            x.supplierproductcode || ' SUPPLIERSIZECODE ' ||
                            x.suppliersizecode;
      gv_counter         := gv_counter + 1;
      gv_from_supplierid := x.supplier_id;
      select seq_supplierproduct.nextval
        into gv_supplierproductid
        from dual;
      insert into supplierproduct
        (supplierproduct_id,
         supplier_id,
         supplierproductcode,
         supplierproductdescription,
         suppliersizecode,
         deliverydays,
         minorderqty,
         boxquantity,
         uniqueitem,
         active,
         remark,
         systemuser_id,
         timestamp,
         turnovergroup_id,
         packing,
         transportchargepercentage)
      values
        (gv_supplierproductid,
         gv_to_supplierid,
         x.supplierproductcode,
         x.supplierproductdescription,
         x.suppliersizecode,
         x.deliverydays,
         x.minorderqty,
         x.boxquantity,
         x.uniqueitem,
         x.active,
         x.remark,
         x.systemuser_id,
         sysdate,
         x.turnovergroup_id,
         x.packing,
         x.transportchargepercentage);
      --loop y productsizepersupproduct
      for y in (select psp.*
                  from productsizepersupproduct psp
                 where psp.supplierproduct_id = x.supplierproduct_id) loop
        begin
          gv_message := 'insert into productsizepersupproduct for supplier ' ||
                        to_char(fp_to_suppliernumber) ||
                        ' SUPPLIERPRODUCTCODE ' || x.supplierproductcode ||
                        ' SUPPLIERSIZECODE ' || x.suppliersizecode;
          insert into productsizepersupproduct
            (productsizepersupproduct_id,
             supplierproduct_id,
             product_id,
             sizedefinition_id,
             systemuser_id,
             timestamp)
          values
            (seq_productsizepersupproduct.nextval,
             gv_supplierproductid,
             y.product_id,
             y.sizedefinition_id,
             y.systemuser_id,
             sysdate);
        end;
      end loop; --y
      --loop z supplierproductprice
      for z in (select spp.*
                  from supplierproductprice spp
                 where spp.supplierproduct_id = x.supplierproduct_id) loop
        begin
          gv_message := 'insert into supplierproductprice for supplier ' ||
                        to_char(fp_to_suppliernumber) ||
                        ' SUPPLIERPRODUCTCODE ' || x.supplierproductcode ||
                        ' SUPPLIERSIZECODE ' || x.suppliersizecode;
          insert into supplierproductprice
            (supplierproductprice_id,
             supplierproduct_id,
             startdate,
             purchaseprice,
             systemuser_id,
             timestamp)
          values
            (seq_supplierproductprice.nextval,
             gv_supplierproductid,
             z.startdate,
             z.purchaseprice,
             z.systemuser_id,
             sysdate);
        end;
      end loop; --z
    end;
  end loop; --x
  --update_stockdefinitionperitem
  update_stockdefinitionperitem;
  --update_product
  update_product;
  --commit
  commit;
  gv_message := 'copied ' || to_char(gv_counter) ||
                ' supplier products from supplier ' ||
                to_char(fp_from_suppliernumber) || '  to supplier ' ||
                to_char(fp_to_suppliernumber);
  write_log;
exception
  when others then
    begin
      rollback;
      gv_message := gv_message || ' ' || sqlerrm;
      write_log(3);
    end;
end copy_supplier;
/

create or replace view drsum_ar_transactions as
select /*+parallel(8)*/
 /*drsum_ar_transactions version 1.12*/
 ad.artransaction_id source_id,
 to_number(to_char(ad.artransactiondate, 'YYYYMMDD')) transaction_date,
 ad.businessunit_id business_unit_id,
 nvl((select r.plant_id * 1000000 + r.routenumber from route r where r.route_id = ad.route_id),
      nvl((select min(r.plant_id * 1000000 + r.routenumber)
           from   routestop rs, route r
           where  r.route_id = rs.route_id
           and    rs.customer_id = ad.billtocustomer_link_id), bu.plant_id * -1000000)) route_number_id,
 ad.billtocustomer_link_id bill_to_customer_id,
 nvl(ad.deltocustomer_link_id, ad.billtocustomer_link_id) del_to_customer_id, ad.currency_id,
 ad.artransactiontype_id ar_transaction_type_id,
 /*--amount*/
 case
   when ca.cashapplication_id = capx.cashapplication_id then
    ad.amount
   when ca.cashapplication_id is null then
    ad.amount
   else
    0
 end amount,
 /*--applied_amount*/
 case
   when ad.debitcredit = 'D' then
    nvl(ca.amount, 0)
   else
    ad.totalappliedamount
 end applied_amount,
 /*--total_applied_amount*/
 case
   when ca.cashapplication_id = capx.cashapplication_id and ad.debitcredit = 'D' then
    ad.totalappliedamount
   when ad.debitcredit = 'C' then
    ad.totalappliedamount
   when ca.cashapplication_id is null and ad.debitcredit = 'D' then
    ad.totalappliedamount
   else
    0
 end total_applied_amount,
 /*--invoice_number*/
 case
   when ad.invoicenumber = 0 then
    null
   else
    ad.invoicenumber
 end invoice_number,
 /*--due_date*/
 case
   when ad.debitcredit = 'D' then
    case
      when ad.invoiceheader_id is not null then
       (select he.paymenttermsduedate
        from   invoiceheaderextrainfo he
        where  he.invoiceheader_id = ad.invoiceheader_id)
      else
       ad.artransactiondate
    end
   else
    null
 end due_date, ca.applydate application_date,
 /*--open*/
 case
   when ad.isopen_yn = 'Y' then
    dwh_str(1)
   else
    dwh_str(2)
 end open, /*--remit_identification*/
 nvl(ac.remitidentification, ad.remitidentification) remit_identification,
 /*--remit_batch_number*/
 case
   when ca.cashapplication_id is null and ad.debitcredit = 'D' then
    null
   else
    (select rb.batchnumber
     from   remitbatch rb
     where  rb.remitbatch_id = nvl(ac.remitbatch_id, ad.remitbatch_id))
 end remit_batch_number,
 /*payment_transaction_id*/
 case
   when ad.debitcredit = 'D' then
    ca.creditartransaction_id
   else
    ad.artransaction_id
 end payment_transaction_id,
 /*payment_date*/
 case
   when ac.artransactiondate is null and ad.debitcredit = 'D' then
    null
   else
    nvl(ac.artransactiondate, ad.artransactiondate)
 end payment_date,
 /*payment_amount*/
 case
   when ad.debitcredit = 'D' and ca.cashapplication_id is not null then
    ac.amount
   when ad.debitcredit = 'C' then
    ad.amount
   else
    null
 end payment_amount,
 /*total_payment_amount*/
 case
   when ad.debitcredit = 'D' and ca.cashapplication_id is not null then
    ac.totalappliedamount
   when ad.debitcredit = 'C' then
    ad.totalappliedamount
   else
    null
 end total_payment_amount,
 /*payment_type*/
 case
   when
   /*--1 Open Payment Credit*/
    ad.debitcredit = 'C' and ad.artransactiontype_id = 9 and ca.cashapplication_id is null then
           case when ad.paymenttype=0 then 'Cash'
            when ad.paymenttype=1 then 'Check'
            when ad.paymenttype=2 then 'Credit Card'
            when ad.paymenttype=3 then 'Electronic Fund Transfer'
            when ad.paymenttype=4 then 'EDI'
            when ad.paymenttype=5 then 'Accept Giro'
            when ad.paymenttype=6 then 'Automatic Collection'
            when ad.paymenttype=7 then 'Pay By Customer'
            when ad.paymenttype=9 then 'Not applicable'
           end
 /*--2 Open Debit*/
    when ad.debitcredit = 'D' and ca.cashapplication_id is null then
    null
 /*--4 Credit Card Credit from Misc. transactions on CA*/
   when ad.debitcredit = 'C' and ad.paymenttype = 9 then
    'Not applicable'
 /*--5 Write off credit*/
   when ad.debitcredit = 'C' and ad.artransaction_id = ad.originaltransaction_id and
        ad.artransactiontype_id >= 21 then
    'Not applicable'
 /*--6 Write off Credit or Close Open Difference Credit*/
   when ad.debitcredit = 'C' and ad.originaltransaction_id <> ad.artransaction_id and
        ad.remitbatch_id is not null then
           case when xa_remb_ad.paymenttype=0 then 'Cash'
            when xa_remb_ad.paymenttype=1 then 'Check'
            when xa_remb_ad.paymenttype=2 then 'Credit Card'
            when xa_remb_ad.paymenttype=3 then 'Electronic Fund Transfer'
            when xa_remb_ad.paymenttype=4 then 'EDI'
            when xa_remb_ad.paymenttype=5 then 'Accept Giro'
            when xa_remb_ad.paymenttype=6 then 'Automatic Collection'
            when xa_remb_ad.paymenttype=7 then 'Pay By Customer'
            when xa_remb_ad.paymenttype=9 then 'Not applicable'
           end
 /*--7 Apply credit to debit amount (Credit is created from Miscellaneous Transaction on Cash Application screen).*/
   when ad.debitcredit = 'D' and ac.artransactiontype_id >= 21 and ac.paymenttype = 9 then
    'Not applicable'
 /*--8 Debit record to reconcile with writeoff credit when unapplying*/
   else
    case
      when ad.debitcredit = 'D' and ac.artransactiontype_id < 21 then
          case when ac.paymenttype=0 then 'Cash'
            when ac.paymenttype=1 then 'Check'
            when ac.paymenttype=2 then 'Credit Card'
            when ac.paymenttype=3 then 'Electronic Fund Transfer'
            when ac.paymenttype=4 then 'EDI'
            when ac.paymenttype=5 then 'Accept Giro'
            when ac.paymenttype=6 then 'Automatic Collection'
            when ac.paymenttype=7 then 'Pay By Customer'
            when ac.paymenttype=9 then 'Not applicable'
           end
      when ad.debitcredit = 'D'  and ac.artransaction_id = ac.originaltransaction_id and
        ac.artransactiontype_id >= 21 then 'Not applicable'
      when ad.debitcredit = 'D' then
           case when xa_remb_ac.paymenttype=0 then 'Cash'
            when xa_remb_ac.paymenttype=1 then 'Check'
            when xa_remb_ac.paymenttype=2 then 'Credit Card'
            when xa_remb_ac.paymenttype=3 then 'Electronic Fund Transfer'
            when xa_remb_ac.paymenttype=4 then 'EDI'
            when xa_remb_ac.paymenttype=5 then 'Accept Giro'
            when xa_remb_ac.paymenttype=6 then 'Automatic Collection'
            when xa_remb_ac.paymenttype=7 then 'Pay By Customer'
            when xa_remb_ac.paymenttype=9 then 'Not applicable'
           end
      when ad.debitcredit = 'C' then
           case when ad.paymenttype=0 then 'Cash'
            when ad.paymenttype=1 then 'Check'
            when ad.paymenttype=2 then 'Credit Card'
            when ad.paymenttype=3 then 'Electronic Fund Transfer'
            when ad.paymenttype=4 then 'EDI'
            when ad.paymenttype=5 then 'Accept Giro'
            when ad.paymenttype=6 then 'Automatic Collection'
            when ad.paymenttype=7 then 'Pay By Customer'
            when ad.paymenttype=9 then 'Not applicable'
           end
       else
       'case not foreseen'
    end
 end payment_type, nvl(ac.remark, ad.remark) payment_remark,
 case
   when ac.artransactiondate is null and ad.debitcredit = 'D' then
    null
   else
    nvl(ac.artransactiontype_id, ad.artransactiontype_id)
 end payment_transaction_type,
 case
   when at.typenumber = 1 /*--invoice*/
    then
    ac.artransactiondate - ad.artransactiondate
   else
    null
 end days_to_pay, ad.timestamp time_stamp,
 case
   when (ca.cashapplication_id = capx.cashapplication_id or ca.cashapplication_id is null) and
        ad.debitcredit = 'D' then
    nvl((select ih2.paythisamount - ih2.totalamountexclvat
     from   invoiceheader ih2
     where  ad.invoiceheader_id = ih2.invoiceheader_id),0)
   else
    0
 end taxamount, b.customernumber bill_to_customernumber,
 nvl(d.customernumber, b.customernumber) del_to_customernumber,
 (select max(ih3.invoicedate) ih3
   from   invoiceheader ih3, statementline sl
   where  sl.artransaction_id = ad.artransaction_id
   and    ih3.invoiceheader_id = sl.invoiceheader_id) statementdate,
 nvl(nvl((select max(pc.customernumber)
          from   invoiceheaderextrainfo he1, customer pc
          where  he1.invoiceheader_id = ad.invoiceheader_id
          and    he1.paybycustomer_link_id = pc.customer_id),
          (select max(pb2.customernumber)
            from   customerbillinginfo cbi2, customer pb2
            where  cbi2.paybycustomer_link_id = pb2.customer_id
            and    cbi2.customer_id = b.customer_id)), b.customernumber) pay_by_customernumber,
 (select max(ih3.invoicenumber)
   from   invoiceheader ih3, statementline sl
   where  sl.artransaction_id = ad.artransaction_id
   and    ih3.invoiceheader_id = sl.invoiceheader_id) statementnumber,
 (select max(ihei3.paymenttermsduedate)
   from   invoiceheaderextrainfo ihei3, invoiceheader ih3, statementline sl
   where  sl.artransaction_id = ad.artransaction_id
   and    ih3.invoiceheader_id = sl.invoiceheader_id
   and    ih3.invoiceheader_id = ihei3.invoiceheader_id) statementduedate, ad.debitcredit,
 ad.systemuser_id,
 case
   when ad.debitcredit = 'D' then
    case
      when ca.cashapplication_id = capx.cashapplication_id then
       11
      when ca.cashapplication_id is null then
       21
      else
       12
    end
   else
    31
 end division,
  (select max(ih3.timestamp)
   from   invoiceheader ih3, statementline sl
   where  sl.artransaction_id = ad.artransaction_id
   and    ih3.invoiceheader_id = sl.invoiceheader_id) statement_time_stamp
from   artransaction ad
left   outer join(cashapplication ca
join   artransaction ac
on     ca.creditartransaction_id = ac.artransaction_id) on (ca.debitartransaction_id = ad.artransaction_id and ca.unapplied_yn = 'N')
left   outer join (select cap.debitartransaction_id, cap.unapplied_yn,
                          min(cap.cashapplication_id) cashapplication_id
                   from   cashapplication cap
                   group  by cap.debitartransaction_id, cap.unapplied_yn) capx
on     (capx.debitartransaction_id = ad.artransaction_id and capx.unapplied_yn = 'N')
left   outer join customer d
on     ad.deltocustomer_link_id = d.customer_id
join   artransactiontype at
on     (ad.artransactiontype_id = at.artransactiontype_id and at.typenumber <> 2)
join   businessunit bu
on     (bu.businessunit_id = ad.businessunit_id)
join   customer b
on     (ad.billtocustomer_link_id = b.customer_id)
left outer join (select xa.remitbatch_id, max(xa.paymenttype) paymenttype
                      from   artransaction xa
                      where  xa.debitcredit='C'
                      and    xa.artransactiontype_id=9
                      group by xa.remitbatch_id) xa_remb_ad on xa_remb_ad.remitbatch_id=ad.remitbatch_id
left outer join (select xa.remitbatch_id, max(xa.paymenttype) paymenttype
                      from   artransaction xa
                      where  xa.debitcredit='C'
                      and    xa.artransactiontype_id=9
                      group by xa.remitbatch_id) xa_remb_ac on xa_remb_ac.remitbatch_id=ac.remitbatch_id
where  (ad.parentartransaction_id is null or ad.parentartransaction_id = ad.artransaction_id)
and    ad.artransactiondate >= (trunc(sysdate)-610)
/

create or replace view drsum_cancelfee_calc as
select /*+parallel(4)*/
 /*view drsum_cancelfee_calc version 0.5*/
 c.customer_id, c.customernumber, p.code productcode, sd.code sizecode,
 (select qg.code from qualitygrade qg where qg.qualitygrade_id = uif.qualitygrade_id) qualitygrade,
 (select rc.code from reasoncode rc where rc.reasoncode_id = uif.reasoncode_id) reasoncode,
 w.wearernumber, ui.primaryid idorseqnumber, uif.lastissuedate issuedate,
 case
   when (select max(pol.purchaseprice)
         from   purchaseorderline pol, purchaseorderstocktransaction pss
         where  pol.product_link_id = wi.product_id
         and    pol.sizedefinition_link_id = wi.sizedefinition_id
         and    pol.purchaseorderline_id = pss.purchaseorderline_id
         and    pss.timestamp = (select max(pss2.timestamp)
                                 from   purchaseorderline pol2, purchaseorderstocktransaction pss2
                                 where  pol2.product_link_id = pol.product_link_id
                                 and    pol2.sizedefinition_link_id = pol.sizedefinition_link_id
                                 and    pol2.purchaseorderline_id = pss2.purchaseorderline_id
                                 and    trunc(pss2.timestamp) <= uif.firstissuedate)) is not null then
    (select max(pol.purchaseprice)
     from   purchaseorderline pol, purchaseorderstocktransaction pss
     where  pol.product_link_id = wi.product_id
     and    pol.sizedefinition_link_id = wi.sizedefinition_id
     and    pol.purchaseorderline_id = pss.purchaseorderline_id
     and    pss.timestamp = (select max(pss2.timestamp)
                             from   purchaseorderline pol2, purchaseorderstocktransaction pss2
                             where  pol2.product_link_id = pol.product_link_id
                             and    pol2.sizedefinition_link_id = pol.sizedefinition_link_id
                             and    pol2.purchaseorderline_id = pss2.purchaseorderline_id
                             and    trunc(pss2.timestamp) <= uif.firstissuedate))
   else
    case
      when (select max(spp1.purchaseprice)
            from   supplierproductprice spp1
            join   productsizepersupproduct pss1
            on     pss1.supplierproduct_id = spp1.supplierproduct_id
            where  spp1.startdate = (select max(spp.startdate)
                                     from   supplierproductprice spp
                                     where  pss1.supplierproduct_id = spp.supplierproduct_id
                                     and    spp.startdate <= uif.firstissuedate)
            and    pss1.product_id = wi.product_id
            and    pss1.sizedefinition_id = wi.sizedefinition_id) is null then
       (select max(spp1.purchaseprice)
        from   supplierproductprice spp1
        join   productsizepersupproduct pss1
        on     pss1.supplierproduct_id = spp1.supplierproduct_id
        where  spp1.startdate = (select min(spp.startdate)
                                 from   supplierproductprice spp
                                 where  pss1.supplierproduct_id = spp.supplierproduct_id
                                 and    spp.startdate > uif.firstissuedate)
        and    pss1.product_id = wi.product_id
        and    pss1.sizedefinition_id = wi.sizedefinition_id)
      else
       (select max(spp1.purchaseprice)
        from   supplierproductprice spp1
        join   productsizepersupproduct pss1
        on     pss1.supplierproduct_id = spp1.supplierproduct_id
        where  spp1.startdate = (select max(spp.startdate)
                                 from   supplierproductprice spp
                                 where  pss1.supplierproduct_id = spp.supplierproduct_id
                                 and    spp.startdate <= uif.firstissuedate)
        and    pss1.product_id = wi.product_id
        and    pss1.sizedefinition_id = wi.sizedefinition_id)
    end
 end currentpoprice, uif.purchasedate purchasedatenunique, uif.purchaseprice purchasepriceunique,
 wi.finishingmethod_id,
 (select fm.code from finishingmethod fm where fm.finishingmethod_id = wi.finishingmethod_id) finishingmethodcode,
 we.weareremployment_id, we.sequencenumber weareremploymentnr
from   customer c, wearer w, weareremployment we, wearerinventory wi, uniqueitemnonpool unp,
       uniqueitem ui, uniqueitemfixedinfo uif, product p, sizedefinition sd
where  c.customer_id = w.customer_id
and    w.wearer_id = we.wearer_id
and    we.weareremployment_id = wi.weareremployment_id
and    wi.wearerinventory_id = unp.wearerinventory_id
and    unp.uniqueitem_id = ui.uniqueitem_id
and    ui.uniqueitem_id = uif.uniqueitem_id
and    wi.product_id = p.product_id
and    wi.sizedefinition_id = sd.sizedefinition_id
union all
-- non unique inventory
select /*+parallel(4)*/
       c.customer_id, c.customernumber, p.code productcode, sd.code sizecode,
       nvl((select max(qg.code)
            from   issuehistory ih, qualitygrade qg
            where  ih.issuegrade_id = qg.qualitygrade_id
            and    ih.product_link_id = wi.product_id
            and    ih.sizedefinition_link_id = wi.sizedefinition_id
            and    trunc(ih.assigndate) = nui.issuedate
            and    ih.weareremployment_link_id = we.weareremployment_id), 'U') qualitygrade,
       (select rc.code from reasoncode rc where rc.reasoncode_id = nui.reasoncode_id) reasoncode,
       w.wearernumber, to_char(nui.sequencenumber) idorseqnumber, nui.issuedate,
       case
          when (select max(pol.purchaseprice)
                from   purchaseorderline pol, purchaseorderstocktransaction pss
                where  pol.product_link_id = wi.product_id
                and    pol.sizedefinition_link_id = wi.sizedefinition_id
                and    pol.purchaseorderline_id = pss.purchaseorderline_id
                and    pss.timestamp =
                       (select max(pss2.timestamp)
                         from   purchaseorderline pol2, purchaseorderstocktransaction pss2
                         where  pol2.product_link_id = pol.product_link_id
                         and    pol2.sizedefinition_link_id = pol.sizedefinition_link_id
                         and    pol2.purchaseorderline_id = pss2.purchaseorderline_id
                         and    trunc(pss2.timestamp) <= nui.issuedate)) is not null then
           (select max(pol.purchaseprice)
            from   purchaseorderline pol, purchaseorderstocktransaction pss
            where  pol.product_link_id = wi.product_id
            and    pol.sizedefinition_link_id = wi.sizedefinition_id
            and    pol.purchaseorderline_id = pss.purchaseorderline_id
            and    pss.timestamp = (select max(pss2.timestamp)
                                    from   purchaseorderline pol2, purchaseorderstocktransaction pss2
                                    where  pol2.product_link_id = pol.product_link_id
                                    and    pol2.sizedefinition_link_id = pol.sizedefinition_link_id
                                    and    pol2.purchaseorderline_id = pss2.purchaseorderline_id
                                    and    trunc(pss2.timestamp) <= nui.issuedate))
          else
           case
             when (select max(spp1.purchaseprice)
                   from   supplierproductprice spp1
                   join   productsizepersupproduct pss1
                   on     pss1.supplierproduct_id = spp1.supplierproduct_id
                   where  spp1.startdate = (select max(spp.startdate)
                                            from   supplierproductprice spp
                                            where  pss1.supplierproduct_id = spp.supplierproduct_id
                                            and    spp.startdate <= nui.issuedate)
                   and    pss1.product_id = wi.product_id
                   and    pss1.sizedefinition_id = wi.sizedefinition_id) is null then
              (select max(spp1.purchaseprice)
               from   supplierproductprice spp1
               join   productsizepersupproduct pss1
               on     pss1.supplierproduct_id = spp1.supplierproduct_id
               where  spp1.startdate = (select min(spp.startdate)
                                        from   supplierproductprice spp
                                        where  pss1.supplierproduct_id = spp.supplierproduct_id
                                        and    spp.startdate > nui.issuedate)
               and    pss1.product_id = wi.product_id
               and    pss1.sizedefinition_id = wi.sizedefinition_id)
             else
              (select max(spp1.purchaseprice)
               from   supplierproductprice spp1
               join   productsizepersupproduct pss1
               on     pss1.supplierproduct_id = spp1.supplierproduct_id
               where  spp1.startdate = (select max(spp.startdate)
                                        from   supplierproductprice spp
                                        where  pss1.supplierproduct_id = spp.supplierproduct_id
                                        and    spp.startdate <= nui.issuedate)
               and    pss1.product_id = wi.product_id
               and    pss1.sizedefinition_id = wi.sizedefinition_id)
           end
        end currentpoprice, null purchasedatenunique, null purchasepriceunique,
       wi.finishingmethod_id,
       (select fm.code from finishingmethod fm where fm.finishingmethod_id = wi.finishingmethod_id) finishingmethodcode,
       we.weareremployment_id, we.sequencenumber weareremploymentnr
from   customer c, wearer w, weareremployment we, wearerinventory wi, nonuniqueitem nui, product p,
       sizedefinition sd
where  c.customer_id = w.customer_id
and    w.wearer_id = we.wearer_id
and    we.weareremployment_id = wi.weareremployment_id
and    wi.wearerinventory_id = nui.wearerinventory_id
and    wi.product_id = p.product_id
and    wi.sizedefinition_id = sd.sizedefinition_id 
/

create or replace view drsum_cashapplication as
select /*+parallel(8)*/
/*view drsum_cashapplication version 1*/
cashapplication_id,
debitartransaction_id,
creditartransaction_id,
applydate,
applytimestamp,
applysystemuser_id,
amount,
unapplied_yn,
unapplydate,
unapplytimestamp,
unapplysystemuser_id,
origin
from cashapplication
/

create or replace view drsum_customer_contractinfo as
select /*+parallel(8)*/
/*view drsum_customer_contractinfo version 1.0*/
  cu.customer_id, cu.customernumber, cu.name customername, cu.dateactive, cu.dateinactive,
  cu.phoneno, ad.city,
   cu.paymentmethod,
   (select co.code  from competitor co  where co.competitor_id=plpc.lostcompetitor_id)competitorcode,
   (select co.name  from competitor co  where co.competitor_id=plpc.lostcompetitor_id)competitorname,
   (select  gr.code from gainlostreason gr where gr.gainlostreason_id = plpc.lostreason_id) lostreasoncode,
   (select grd.description from gainlostreason_desc grd,gainlostreason gr where  gr.gainlostreason_id = plpc.lostreason_id and grd.gainlostreason_id = gr.gainlostreason_id
   and grd.language_id = l.language_id) lostreasondesc,
  buc.code businessunitcode,
  ms.code marketsegmentcode,
  sa.code salesareacode,
  ch.code chaincode,
  cu.remark,
  (select es.employeenumber from employee es where cu.serviceemployee_id=es.employee_id) serviceemployeenumber,
  (select es.name from employee es where cu.serviceemployee_id=es.employee_id) serviceemployeename
  ,cu.dateactive startdate
  ,cu.dateinactive enddate
  ,r.routenumber
  ,r.drivingday_id drivingday
  ,rs.dateactive routestartdate
  ,rs.dateinactive routeenddate
  ,(select cdd.deliverytype from customerdeliveryday cdd where cdd.customer_id=cu.customer_id and cdd.day_id=r.drivingday_id and cdd.typeofmerchadise=1) BorDtype
from
  customer cu,
  --contractcustomer cpc,
  -- contract contr
 --employee em ,
  routestop rs, route r,
  chain ch ,
  address ad,
  businessunit buc,
  marketsegment ms, salesarea sa,
  languages l
  , productlistpercustomer plpc
  --,(select distinct plpc.lostreason_id, plpc.lostcompetitor_id, plpc.customer_id from ) losb
where --cpc.customer_link_id (+)=cu.customer_id
--and contr.contract_id(+)=cpc.contract_id
--contr.customer_link_id (+)=cu.masteraccount_id
  --and cpc.dateactive = (select max(cpc2.dateactive) from contractspercustomer cpc2 where cpc2.customer_id = cu.customer_id)
   plpc.customer_id=cu.customer_id
   and ch.chain_id(+) = cu.chain_id
  and cu.visitaddress_id = ad.address_id
  and cu.defaultbusinessunit_id = buc.businessunit_id
  and cu.marketsegment_id = ms.marketsegment_id
  and cu.salesarea_id = sa.salesarea_id
and rs.route_id=r.route_id
and rs.customer_id=cu.customer_id
and rs.customer_id=plpc.customer_id
and l.language_id=2
group by
cu.customer_id, cu.customernumber, cu.name , cu.dateactive, cu.dateinactive,
  cu.phoneno, ad.city,
   cu.paymentmethod,
 --  co.code ,
  --co.name ,
  --gr.code ,
  buc.code,
  ms.code ,
  sa.code ,
  ch.code ,
  cu.remark,
  cu.dateactive
  ,cu.dateinactive
  ,r.routenumber
  ,r.drivingday_id
  ,rs.dateactive
  ,rs.dateinactive
  --,gr.gainlostreason_id
  ,l.language_id
  ,plpc.lostcompetitor_id
  ,cu.serviceemployee_id
  ,plpc.lostreason_id
/

create or replace view drsum_directsalesdetails as
select /*+parallel(8)*/
/*view drsum_directsalesdetails version 1.0*/
c.customernumber,
p.code productcode,
fm.code finishingmethod
,sdef.code sizecode
,plpc.dateactive plpcstartdate
,plpc.dateinactive plpcenddate
,pack_price.Sales_Price(c.customer_id,plpc.product_id,plpc.sizedefinition_id,sysdate) price
,
(select max(sp.supplierproductcode) from productsizepersupproduct sps, supplierproduct sp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id) suppprodccode
,
(select max(sp.suppliersizecode) from productsizepersupproduct sps, supplierproduct sp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id) suppsizecode
,
(select max(spp.purchaseprice) from productsizepersupproduct sps, supplierproduct sp, supplierproductprice spp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id
and spp.supplierproduct_id=sp.supplierproduct_id and spp.startdate=(select max(spp2.startdate) from supplierproductprice spp2 where sp.supplierproduct_id=spp2.supplierproduct_id and spp2.startdate<=sysdate)
) suppprice
from
productlistpercustomer plpc
,product p
,finishingmethod fm
,customer c
,sizedefinition sdef
where c.customer_id=plpc.customer_id
and plpc.sizedefinition_id=sdef.sizedefinition_id
and p.product_id=plpc.product_id
and fm.finishingmethod_id=plpc.finishingmethod_id
and fm.code='DS'
group by c.customernumber,
p.code, fm.code
,plpc.dateactive
,plpc.dateinactive
,sdef.code
,c.customer_id,plpc.product_id,plpc.sizedefinition_id,plpc.finishingmethod_id
,p.supplier_id,p.product_id,sdef.sizedefinition_id
/

CREATE OR REPLACE VIEW DRSUM_DIRECTSALESREVENUE AS
select /*+parallel(8)*/
/*version 2.1*/
 ih.invoicenumber, (select b.code from businessunit b where b.businessunit_id=ih.invoicebusinessunit_id) bucode, wo.workordernumber,
ih.deltocustomernumber
,wol.completiondate issuedate
,wo.completiondate salesordercompleteddate
,ih.invoicedate invoicedate
,(select p.code from product p where p.product_id=wol.product_link_id) productcode
,(select sd.code from sizedefinition sd where sd.sizedefinition_id=wol.sizedefinition_link_id) sizecode
,case when il.adjustedprice>0 then il.adjustedprice else il.price end price
, (select max(pol.purchaseprice)
                    from purchaseorderline pol
                        ,purchaseorderstocktransaction pss
                   where
                   pol.product_link_id=wol.product_link_id
                   and pol.sizedefinition_link_id=wol.sizedefinition_link_id
                   and pol.purchaseorderline_id = pss.purchaseorderline_id
                     and pss.timestamp=(select max( pss2.timestamp) from
                         purchaseorderline pol2
                        ,purchaseorderstocktransaction pss2
                   where
                   pol2.product_link_id=pol.product_link_id
                   and pol2.sizedefinition_link_id=pol.sizedefinition_link_id
                   and pol2.purchaseorderline_id = pss2.purchaseorderline_id
                   and trunc(pss2.timestamp)<=wol.completiondate)) latestpoprice
               ,   (select spp1.purchaseprice from supplierproductprice spp1
                   where spp1.supplierproductprice_id= (select max(spp.supplierproductprice_id)
                 from supplierproduct sp, productsizepersupproduct pss, supplierproductprice spp
                  where sp.supplierproduct_id = pss.supplierproduct_id and
                      sp.supplierproduct_id = spp.supplierproduct_id and
                          pss.product_id=wol.product_link_id
                          and wol.sizedefinition_link_id= pss.sizedefinition_id and
                      spp.startdate= (select max(spp2.startdate)
                 from supplierproduct sp2, productsizepersupproduct pss2, supplierproductprice spp2
                  where sp2.supplierproduct_id = pss2.supplierproduct_id and
                      sp2.supplierproduct_id = spp2.supplierproduct_id and
                          pss2.product_id=wol.product_link_id
                          and wol.sizedefinition_link_id= pss2.sizedefinition_id
                      and spp2.startdate <= wol.completiondate)
                )) supplierprice
,nvl(( select sv.avgpurchaseprice from stockvalueavgpp sv where sv.stockvalueavgpp_id=(SELECT  MAX(s.stockvalueavgpp_id)
                            FROM StockValueAVGPP s
                            WHERE
                            s.stockroom_id=wo.processingstockroom_id
                            and  s.product_link_id = wol.product_link_id
                            and s.sizedefinition_link_id = wol.sizedefinition_link_id
                            and s.qualitygrade_id = wol.requestedgrade_id  ---needs to be changed to issuedgrade
                            and  s.transactiondate <= wol.completiondate--ih.assigndate
                            and ((s.customer_link_id = wo.customer_link_id)
                                 or s.customer_link_id is null))),nvl(
             ( select sv2.avgpurchaseprice from stockvalueavgpp sv2 where sv2.stockvalueavgpp_id=(SELECT  MIN(s2.stockvalueavgpp_id)
                            FROM StockValueAVGPP s2
                            WHERE
                            s2.stockroom_id=wo.processingstockroom_id
                            and  s2.product_link_id = wol.product_link_id
                            and s2.sizedefinition_link_id = wol.sizedefinition_link_id
                            and s2.qualitygrade_id = wol.requestedgrade_id  ---needs to be changed to issuedgrade
                            and  s2.transactiondate >= wol.completiondate--ih.assigndate
                            and ((s2.customer_link_id = wo.customer_link_id)
                                 or s2.customer_link_id is null))),
                        (select spp1.purchaseprice from supplierproductprice spp1 where spp1.supplierproductprice_id= (select max(spp.supplierproductprice_id)
                from supplierproduct sp, productsizepersupproduct pss, supplierproductprice spp
                  where sp.supplierproduct_id = pss.supplierproduct_id and
                      sp.supplierproduct_id = spp.supplierproduct_id and
    pss.product_id=wol.product_link_id and wol.sizedefinition_link_id= pss.sizedefinition_id and
                      spp.startdate <= wol.completiondate
                                 )))) AveragePurchasePrice
,il.billedqty
,case when il.adjustedamount >0 then il.adjustedamount
  else il.amount end amount
,wo.entrydate
,(select e.employeenumber from employee e where e.employee_id=wo.salesemployee1_id) employee
,(select e.name from employee e where e.employee_id=wo.salesemployee1_id) employeename
,(select rc.code from reasoncode rc where rc.reasoncode_id=wo.reasoncode_id) reasoncode
from invoiceheader ih,
invoiceline il,
invoicelineproduct ilp,
workorderline wol, workorder wo
where ih.invoiceheader_id=wo.invoiceheader_id
and ih.invoiceheader_id=il.invoiceheader_id
and il.invoiceline_id=ilp.invoiceline_id
and wo.workorder_id=wol.workorder_id
and wo.origin=6
and ilp.product_link_id=wol.product_link_id
and ilp.finishingmethod_id=wol.finishingmethod_id
and ilp.sizedefinition_link_id=wol.sizedefinition_link_id
and il.invoicelinetype_id=(select ilt.invoicelinetype_id from invoicelinetype ilt where ilt.type=5)
and wol.quantityfilled=ilp.deliveredqty
group by
ih.deltocustomernumber
,wol.completiondate
,wo.completiondate
,ih.invoicedate
,wol.product_link_id
,wol.sizedefinition_link_id
,il.price
,il.billedqty
,il.adjustedamount
,il.amount
,wo.entrydate
,wo.salesemployee1_id
,il.adjustedprice
, ih.invoicenumber
, wol.quantityfilled
, wo.workordernumber
, ih.invoicebusinessunit_id
,wo.processingstockroom_id
,wol.requestedgrade_id
,wo.customer_link_id
,wo.reasoncode_id
/

create or replace view drsum_endedroutes as
select /*+parallel(8)*/
/*view drsum_endedroutes version 1.0*/
cu.customer_id, cu.customernumber,r.routenumber,rs.stopnumber,rs.dateactive,rs.dateinactive
,r.drivingday_id drivingday
,(select cdd.deliverytype from customerdeliveryday cdd where cdd.customer_id=cu.customer_id and cdd.day_id=r.drivingday_id and cdd.typeofmerchadise=1) BorDtype
from
route r, routestop rs, customer cu
where r.route_id=rs.route_id
and cu.customer_id=rs.customer_id
and rs.dateinactive<> to_date('31-12-2099','dd-mm-yyyy')
/

CREATE OR REPLACE VIEW DRSUM_INVOICELINE_AUJ AS
select /*version 1.2*/
       /*+parallel(8) index(f XIE3INVOICEHEADER) index(a XIF934INVOICELINE) index(b XPKINVOICELINEPRODUCT) index(c XPKINVOICELINEVARIOUS)*/
       f.invoicedate,
       f.invoicenumber,
       f.deltocustomernumber,
       a.linenumber,
       (CASE
         WHEN e.TYPE = 1 AND a.invoicelinesubtype = 13 THEN
          1.6
         ELSE
          e.TYPE
       END) invoicelinetype,
       (SELECT DESCRIPTION
          FROM invoicelinetype_DESC z
         WHERE z.invoicelinetype_id = a.invoicelinetype_id
           AND z.LANGUAGE_ID = LANGUAGES.LANGUAGE_ID) invoicelinetypedesc,
       a.code,
       a.description,
       case when a.adjustmentreason_id is null then
        sum(a.amount)
       else
       sum(a.adjustedamount) end amount,
       a.adjustedprice,
       sum(a.adjustmentbilledqty)+sum(a.billedqty) billedqty,
       a.extend,
       a.price,
       a.taxgroupcode,
       a.taxtype,
       d.code turnovergroupcode,
       (SELECT DESCRIPTION
          FROM TURNOVERGROUP_DESC T
         WHERE T.TURNOVERGROUP_ID = A.TURNOVERGROUP_ID
           AND T.LANGUAGE_ID = LANGUAGES.LANGUAGE_ID) turnovergroupdescription,
       b.productgroupcode,
       b.productgroupdescription,
       b.sizecode,
       b.sizedescription,
       b.finishingmethodcode,
       b.finishingmethoddescription,
       b.inventoryqty,
       sum(b.deliveredqty)+ sum(b.adjustmentdeliveredqty) deliveredqty,
       b.billingmethod,
       count(b.weareremployment_link_id) numberofwearers,
       c.transactiontype,
       (select rs.drivingdate from routecontrol rs where f.routecontrol_id=rs.routecontrol_id) drivingdate,
       a.remark,
       b.replacementprice,
       Case when e.TYPE in (12,15,16) then
        (SELECT DESCRIPTION
          FROM invoicelinetype_DESC z
         WHERE z.invoicelinetype_id = a.invoicelinetype_id
           AND z.LANGUAGE_ID = LANGUAGES.LANGUAGE_ID)
       else
       (SELECT PD.DESCRIPTION
          FROM PRODUCT_LINK_DESC pd
         WHERE pd.product_link_id = b.product_link_id
           AND pd.language_id = LANGUAGES.LANGUAGE_ID) end PRODUCTDESCRIPTION,
       (SELECT PD.REGISTRATIONUNITDESCRIPTION
          FROM PRODUCT_LINK_DESC pd
         WHERE pd.product_link_id = b.product_link_id
           AND pd.language_id = LANGUAGES.LANGUAGE_ID) REGISTRATIONUNITDESCRIPTION,
       (SELECT rc.code
          FROM reasoncode rc
         WHERE rc.reasoncode_id = a.adjustmentreason_id) ADJUSTMENTREASON_CODE,
       (SELECT pilt.sequencenumber
          from plantinvoicelinetype pilt
         where pilt.plant_id =bu.plant_id
           and pilt.invoicelinetype_id = a.invoicelinetype_id) InvoiceLine_SequenceNumber,
       (SELECT pilt.suppressprinting
          from plantinvoicelinetype pilt
         where pilt.plant_id =bu.plant_id
           and pilt.invoicelinetype_id = a.invoicelinetype_id) supressprinting,
           coalesce(b.deliveryschemecode, (select min(ds.code)
                                           from customerdeliveryscheme cds
                                           join deliveryscheme ds on ds.deliveryscheme_id = cds.deliveryscheme_id
                                           where cds.customer_id = f.deltocustomer_link_id)) deliveryschemecode,
        coalesce((SELECT pr.typeofmerchandise
                  FROM PRODUCT pr
                  WHERE pr.product_id = b.product_link_id), 0) typeofmerchandise,
        f.routenumber
from invoiceheader f
  JOIN invoiceline a on a.invoiceheader_id = f.invoiceheader_id
  JOIN invoicelinetype e on e.invoicelinetype_id = a.invoicelinetype_id
  JOIN businessunit bu on bu.businessunit_id = f.invoicebusinessunit_id
  LEFT OUTER JOIN invoicelineproduct b ON (a.invoiceline_id = b.invoiceline_id)
  LEFT OUTER JOIN invoicelinevarious c ON (a.invoiceline_id = c.invoiceline_id)
  LEFT OUTER JOIN turnovergroup d ON (a.turnovergroup_id = d.turnovergroup_id),
  LANGUAGES
where f.invoicedate>=sysdate-20
   and f.documenttype = 1
   AND a.extend='Y'
   and f.status_id=(select st.status_id from status st where st.code=2 and st.statustype='IN')
   and LANGUAGES.CODE='JA_JP'
group by f.invoicedate,
       f.invoicenumber,
       a.linenumber,
       a.code,
       a.description,
       a.adjustedprice,
       a.extend,
       a.price,
       a.taxgroupcode,
       a.taxtype,
       d.code,
       a.invoicelinesubtype,
       b.productgroupcode,
       b.productgroupdescription,
       b.productshortdescription,
       b.sizecode,
       b.sizedescription,
       b.finishingmethodcode,
       b.finishingmethoddescription,
       b.invoiceqtycolumn,
       b.inventoryqty,
       b.deliveredqty,
       b.billingmethod,
       c.transactiontype,
       c.transactiondate,
       a.remark,
       b.replacementprice,
       b.adjustmentdeliveredqty,
       b.product_link_id,
       e.TYPE,
       a.invoicelinetype_id,
       LANGUAGES.LANGUAGE_ID,
       A.TURNOVERGROUP_ID,
       a.adjustmentreason_id,
       bu.plant_id,
       b.deliveryschemecode,
       f.deltocustomer_link_id,
       f.deltocustomernumber,
       f.routenumber,
       f.routecontrol_id
/

create or replace view drsum_invoicelinedetail as
select /*+parallel(8)*/
/*view drsum_invoicelinedetail version 0.3*/
ih.invoiceheader_id,
ih.invoicenumber,
ih.invoicedate,
ih.creationtimestamp,
ih.finalizationtimestamp,
ih.invoicetype,
ih.documenttype,
invbu.code invoicebusinessunitcode,
ih.billtocustomernumber,
ih.billtocustomername,
abil.customernumber ar_billtocustomernumber,
abil.name ar_billtocustomername,
ih.deltocustomernumber,
ih.deltocustomername,
ih.routenumber,
il.invoiceline_id,
il.linenumber,
il.invoicelinetype_id,
il.invoicelinesubtype,
il.code,
il.description,
il.price,
il.billedqty,
case when il.extend = 'N' then 0 
else il.amount
end amount,
il.taxtype,
il.taxgroupcode,
(select rs.code
 from   reasoncode rs
 where  rs.reasoncode_id = il.adjustmentreason_id) adjustmentreasoncode,
il.adjustedprice,
il.adjustmentbilledqty,
case when il.extend = 'N' then 0 
else il.adjustedamount
end adjustedamount,
p.code productcode,
(select pd.description
 from   product_desc pd
 where  pd.product_id = p.product_id
 and    pd.language_id = c.language_id) productcodedescription,
s.code sizecode,
fi.code finishingmethodcode,
nvl(ilp.wearernumber, wrl.wearernumber) wearernumber,
coalesce(ilp.wearername, wrl.wearername, w.fullname) wearername,
nvl(tg.code, 'XXXX') turnovergroupcode,
l.billingmethod billingmethodcode,
il.timestamp,
il.extend,
il.generated,
(select std.description
 from status_desc std
 where std.status_id = ih.status_id
 and std.language_id = c.language_id) status_desc,
wrl.wearersearchname wearersearchname,
ilp.weareremployment_link_id weareremployment_id,
w.wearer_id,
 (select wi.wearerinventory_id
   from   wearerinventory wi
   where  wi.weareremployment_id = ilp.weareremployment_link_id
   and    wi.product_id = ilp.product_link_id
   and    wi.sizedefinition_id = ilp.sizedefinition_link_id) wearerinventory_id,
 pg.code productgroup_code,
 (select pgd.description
   from   productgroup_desc pgd
   where  pgd.productgroup_id = p.productgroup_id
   and    pgd.language_id = c.language_id) productgroup_description
from   invoiceheader ih
join   businessunit invbu
on     invbu.businessunit_id = ih.invoicebusinessunit_id
left   outer join((select ax.invoiceheader_id, min(ax.billtocustomer_link_id) billtocustomer_link_id
                   from   artransaction ax
                   group  by ax.invoiceheader_id) a
join   customer abil
on     abil.customer_id = a.billtocustomer_link_id) on a.invoiceheader_id = ih.invoiceheader_id
join   customer c 
on     c.customer_id = ih.billtocustomer_link_id
join   invoiceline il
on     il.invoiceheader_id = ih.invoiceheader_id
left   outer join invoicelineproduct ilp
on     ilp.invoiceline_id = il.invoiceline_id
left   outer join productlistpercustomer l
on     l.productlistpercustomer_id = ilp.productlistpercustomer_id
left   outer join(product p
join   productgroup pg
on     pg.productgroup_id = p.productgroup_id) on p.product_id = nvl(ilp.product_link_id, l.product_id)
left   outer join sizedefinition s
on     s.sizedefinition_id = nvl(ilp.sizedefinition_link_id, l.sizedefinition_id)
left   outer join finishingmethod fi
on     fi.finishingmethod_id = nvl(ilp.finishingmethod_id, l.finishingmethod_id)
left   outer join turnovergroup tg
on     tg.turnovergroup_id = il.turnovergroup_id
left outer join(weareremployment we
join wearer w
on we.wearer_id = w.wearer_id) on we.weareremployment_id = ilp.weareremployment_link_id
left outer join weareremployment_link wrl
on wrl.weareremployment_link_id = ilp.weareremployment_link_id
where  ih.documenttype = 1
and    (ih.parentinvoiceheader_id = ih.invoiceheader_id or ih.parentinvoiceheader_id is null)
/

create or replace view drsum_nongarmentdetails as
select /*+parallel(8)*/
--version 1.2
c.customernumber,
p.code productcode,
fm.code finishingmethod
,sdef.code sizecode
,sdl.fixedrentquantity
,sdl.dateactive
,sdl.dateinactive
,plpc.dateactive plpcstartdate
,plpc.dateinactive plpcenddate
,ds.code
,ds.frequency
,(select sum(rqt.quantity) from rentalqtyadjustment rqt where rqt.adjustmentdate<sysdate and rqt.productlistperdistribpoint_id=plpd.productlistperdistribpoint_id) rentalqty
,sum(sda.amount) deliverqty
,pack_price.Rent_Price(c.customer_id,plpc.product_id,plpc.sizedefinition_id,plpc.finishingmethod_id,sysdate,ds.frequency) price
,(select max(sp.supplierproductcode) from productsizepersupproduct sps, supplierproduct sp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id) suppprodccode
,(select max(sp.suppliersizecode) from productsizepersupproduct sps, supplierproduct sp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id) suppsizecode
,(select max(spp.purchaseprice) from productsizepersupproduct sps, supplierproduct sp, supplierproductprice spp
where sp.supplier_id=p.supplier_id and sps.supplierproduct_id=sp.supplierproduct_id and sps.product_id=p.product_id and sps.sizedefinition_id=sdef.sizedefinition_id
and spp.supplierproduct_id=sp.supplierproduct_id and spp.startdate=(select max(spp2.startdate) from supplierproductprice spp2 where sp.supplierproduct_id=spp2.supplierproduct_id and spp2.startdate<=sysdate)
) suppprice
from
productlistpercustomer plpc
,productlistperdistribpoint plpd
--,standarddelivery sd
,standarddeliveryline sdl
,standarddeliveryamount sda
,product p
,finishingmethod fm
,deliveryscheme ds
,customer c
,sizedefinition sdef
where c.customer_id=plpc.customer_id
and plpc.productlistpercustomer_id=sdl.productlistpercustomer_id
and plpd.productlistperdistribpoint_id=sdl.productlistperdistribpoint_id
and plpd.sizedefinition_id=sdef.sizedefinition_id
and sda.standarddeliveryline_id=sdl.standarddeliveryline_id
and sdl.deliveryscheme_id=ds.deliveryscheme_id
and p.product_id=plpc.product_id
and fm.finishingmethod_id=plpc.finishingmethod_id
and sdl.dateinactive>sysdate
and sdl.dateactive<=sysdate
and p.typeofmerchandise<>2
group by c.customernumber,
p.code, fm.code
,sdl.fixedrentquantity
,sdl.dateactive
,sdl.dateinactive
,plpc.dateactive
,plpc.dateinactive
,ds.code
,plpd.productlistperdistribpoint_id
,ds.frequency
,sdef.code
,c.customer_id,plpc.product_id,plpc.sizedefinition_id,plpc.finishingmethod_id
,p.supplier_id,p.product_id,sdef.sizedefinition_id
/

create or replace view drsum_raggeditem as
select /*+parallel(8)*/ 
      /*view drsum_raggeditem version 0.5*/
      ri.primaryid primary_id                        
      ,ri.garmsequencenumber garm_sequence_number                        
      ,bu2.code bu_code                       
      ,bu.code cust_bu_code                       
      ,c.customernumber customer_number                       
      ,w.wearernumber wearer_number                       
      ,w.fullname wearer_name                       
      ,w.searchname wearer_search_name                        
      ,null stockroom_code                       
      ,null stockroom_name                       
      ,null row_code                        
      ,null location_code                        
      ,p.code product_code                        
      ,pd.description product_name                        
      ,sd.code product_size_code                        
      ,fm.code finishingmethod_code                       
      ,fmd.description finishingmethod_name                       
      ,qg.code qualitygrade_code                        
      ,std2.description prev_status                       
      ,null status                        
      ,ri.ragtimestamp status_change_date                       
      ,syd2.description prev_stay                       
      ,null stay                        
      ,ri.ragtimestamp stay_change_date                       
      ,rc.code reason_code                        
      ,rd.description reason_name                       
      ,ri.enddatefullrent end_date_fullrent                        
      ,ri.firstissuedate first_issue_date                        
      ,ri.lastissuedate last_issue_date                        
      ,null last_inscan_date                       
      ,null last_outscan_date                       
      ,ri.ragtimestamp last_scan_date                       
      ,ri.lastonstockdate last_on_stock_date                       
      ,ri.numberofissues number_of_issues                        
      ,0 now_days_in_circ                       
      ,ri.daysincirculation days_in_circ_previssue                       
      ,ri.daysincirculation all_days_in_circ
      ,ri.daysinstock all_days_in_stock                        
      ,0 washes_this_issue                       
      ,ri.washestotal washes_total                        
      ,0 rewash_this_issue                       
      ,ri.rewashtotal rewash_total                        
      ,0 repairs_this_issue                       
      ,ri.repairstotal repairs_total                        
      ,sp.suppliernumber supplier_number                        
      ,sp.name supplier_name                        
      ,w.customeremployeenumber admin_number, w.firstname first_name,                        
       we.sequencenumber wearer_employment_number, wi.dateactive wearer_inventory_start_date,                       
       wi.dateinactive wearer_inventory_end_date, wi.maxinventory max_inventory,                        
       wi.changesperweek changes_per_week, wi.circinventory circ_inventory,                       
       pr.priority product_ranking,  
       pr.ranking product_ranking_description, col.code color_code,                       
       cold.description color_code_description, pg.code product_group,                        
       pgd.description product_group_description, sp2.suppliernumber preferred_supplier_number,                       
       sp2.name preferred_supplier_name,
       ri.secondaryid secondaryid,
       ri.ragtimestamp,
       rg.code ragreason_id,
       rgd.description ragreason_name,
       ri.replacementworkorder_id,
      (select wo.workordernumber from workorder wo where wo.workorder_id = ri.replacementworkorder_id) replacementworkordernumber,
       ri.resvaluecharged,
       round(ri.residualvaluepercentage,3) residualvaluepercentage,
       case when ri.residualvaluepercentage > 0 then
         round(ri.residualvalue / ri.residualvaluepercentage * 100)
       else
         ri.residualvalue
       end residualvalue,
       ri.residualvalue residualvalue_amount
from   raggeditem ri
join   businessunit bu
on     bu.businessunit_id = ri.businessunit_id
join   ragreason rg
on     rg.ragreason_id = ri.ragreason_id
left   outer join ragreason_desc rgd
on     rgd.ragreason_id = ri.ragreason_id
and    rgd.language_id = 2
left   outer join(wearerinventory wi
join   weareremployment we
on     we.weareremployment_id = wi.weareremployment_id
join   wearer w
on     w.wearer_id = we.wearer_id
join   customer c
on     c.customer_id = w.customer_id) on wi.weareremployment_id = ri.weareremployment_link_id and wi.product_id = ri.product_link_id and wi.sizedefinition_id = ri.sizedefinition_link_id
join   product p
on     p.product_id = ri.product_link_id
join   product_desc pd
on     p.product_id = pd.product_id
and    pd.language_id = 2
join   color col
on     col.color_id = p.color_id
join   color_desc cold
on     cold.color_id = p.color_id
and    cold.language_id = 2
left   outer join productranking pr
on     pr.productranking_id = p.productranking_id
join   productgroup pg
on     pg.productgroup_id = p.productgroup_id
join   productgroup_desc pgd
on     pgd.productgroup_id = p.productgroup_id
and    pgd.language_id = 2
join   supplier sp2
on     sp2.supplier_id = p.supplier_id
join   sizedefinition sd
on     sd.sizedefinition_id = ri.sizedefinition_link_id
left   outer join(finishingmethod fm
join   finishingmethod_desc fmd
on     fmd.finishingmethod_id = fm.finishingmethod_id
and    fmd.language_id = 2) on fm.finishingmethod_id = ri.finishingmethod_id
join   businessunit bu2
on     bu2.businessunit_id = ri.businessunit_id
left   outer join(status_desc std2)
on     std2.status_id = ri.prevstatus_id
and    std2.language_id = 2
left   outer join(stay_desc syd2)
on     syd2.stay_id = ri.prevstay_id
and    syd2.language_id = 2
join   reasoncode rc
on     rc.reasoncode_id = ri.reasoncode_id
join   reasoncode_desc rd
on     rd.reasoncode_id = rc.reasoncode_id
and    rd.language_id = 2
left   outer join qualitygrade qg
on     qg.qualitygrade_id = ri.qualitygrade_id
join   supplier sp
on     sp.supplier_id = ri.supplier_id
/

create or replace view drsum_rentalgarments as
select /*view drsum_rentalgarments version 3.0*/
 *
from   drsum_rentalgarments_original
union all
select *
from   drsum_rentalgarments_extra
/

create or replace view drsum_rentalgarments_extra as
select /*+parallel(x, 8)*/
/*view drsum_rentalgarments_extra version 1.1*/
x.customernumber,
x.product_id,
x.productcode,
x.sizedefinition_id,
s.code sizecode,
x.finishingmethod_id,
f.code finishingmethod,
x.price,
x.changesperweek,
x.typeofrent,
x.billingmethod,
x.timestamp,
zz.suppprodccode,
zz.suppsizecode,
zz.suppprice
from   (select y.customernumber, y.product_id, max(y.productcode) productcode, y.sizedefinition_id,
                y.finishingmethod_id, trim(substr(y.rent_price_string, 1, 12)) price,
                trim(substr(y.rent_price_string, 22, 10)) changesperweek,
                max(trim(substr(y.rent_price_string, 21, 1))) typeofrent, max(y.timestamp) timestamp,
                max(y.supplier_id) supplier_id, max(y.billingmethod) billingmethod
         from   (select c.customernumber, l.product_id, p.code productcode, l.sizedefinition_id,
                         l.finishingmethod_id, l.billingmethod, l.timestamp,
                         f_rentprice_string(l.customer_id, l.product_id, l.sizedefinition_id,
                                             l.finishingmethod_id, trunc(sysdate), wc.chgwk) rent_price_string,
                         p.supplier_id
                  from   productlistpercustomer l
                  join   customer c
                  on     c.customer_id = l.customer_id
                  join   product p
                  on     p.product_id = l.product_id
                  cross  join (select n.chgwk
                              from   (select rownum chgwk from department chgwk where rownum <= 15) n
                              where  n.chgwk between 7 and 15) wc
                  where  p.typeofmerchandise = 2
                  and    c.customer_id <> c.debtor_id
                  and    c.masteraccount = 3
                  and    l.billingmethod <> 4
                  and    trunc(sysdate) between l.dateactive and l.dateinactive) y
         where  trim(rent_price_string) is not null
         and    trim(substr(y.rent_price_string, 22, 10)) >= 7
         group  by y.customernumber, y.product_id, y.sizedefinition_id, y.finishingmethod_id,
                   trim(substr(y.rent_price_string, 1, 12)), trim(substr(y.rent_price_string, 22, 10))) x
join   finishingmethod f
on     f.finishingmethod_id = x.finishingmethod_id
join   sizedefinition s
on     s.sizedefinition_id = x.sizedefinition_id
left   outer join (select spy.supplier_id, psy.product_id, psy.sizedefinition_id,
                          spy.supplierproductcode suppprodccode, spy.suppliersizecode suppsizecode,
                          (select spp.purchaseprice
                            from   supplierproductprice spp
                            where  spp.supplierproduct_id = spy.supplierproduct_id
                            and    spp.startdate =
                                   (select max(pz.startdate)
                                     from   supplierproductprice pz
                                     where  pz.supplierproduct_id = spp.supplierproduct_id
                                     and    pz.startdate <= trunc(sysdate))) suppprice
                   from   productsizepersupproduct psy
                   join   supplierproduct spy
                   on     spy.supplierproduct_id = psy.supplierproduct_id
                   where  spy.active = 'Y') zz
on     zz.supplier_id = x.supplier_id
and    zz.product_id = x.product_id
and    zz.sizedefinition_id = x.sizedefinition_id
/

create or replace view drsum_rentalgarments_original as
select /*+parallel(x, 8)*/ 
/*view drsum_rentalgarments_original version 1.1*/
x.customernumber,
x.product_id,
x.productcode,
x.sizedefinition_id,
s.code sizecode,
x.finishingmethod_id,
f.code finishingmethod,
x.price,
x.changesperweek,
x.typeofrent,
x.billingmethod,
x.timestamp,
zz.suppprodccode,
zz.suppsizecode,
zz.suppprice
from   (select y.customernumber, y.product_id, max(y.productcode) productcode, y.sizedefinition_id,
                y.finishingmethod_id, trim(substr(y.rent_price_string, 1, 12)) price,
                trim(substr(y.rent_price_string, 22, 10)) changesperweek,
                max(trim(substr(y.rent_price_string, 21, 1))) typeofrent, max(y.timestamp) timestamp,
                max(y.supplier_id) supplier_id, max(y.billingmethod) billingmethod
         from   (select c.customernumber, l.product_id, p.code productcode, l.sizedefinition_id,
                         l.finishingmethod_id, l.billingmethod, l.timestamp,
                         f_rentprice_string(l.customer_id, l.product_id, l.sizedefinition_id,
                                             l.finishingmethod_id, trunc(sysdate), wc.chgwk) rent_price_string,
                         p.supplier_id
                  from   productlistpercustomer l
                  join   customer c
                  on     c.customer_id = l.customer_id
                  join   product p
                  on     p.product_id = l.product_id
                  cross  join (select rownum chgwk
                              from   department chgwk
                              where  rownum <= 6
                              union all
                              select -1 chgwk
                              from   dual) wc
                  where  p.typeofmerchandise = 2
                  and    c.customer_id <> c.debtor_id
                  and    c.masteraccount = 3
                  and    l.billingmethod <> 4
                  and    trunc(sysdate) between l.dateactive and l.dateinactive) y
         where  trim(rent_price_string) is not null
         group  by y.customernumber, y.product_id, y.sizedefinition_id, y.finishingmethod_id,
                   trim(substr(y.rent_price_string, 1, 12)), trim(substr(y.rent_price_string, 22, 10))) x
join   finishingmethod f
on     f.finishingmethod_id = x.finishingmethod_id
join   sizedefinition s
on     s.sizedefinition_id = x.sizedefinition_id
left   outer join (select spy.supplier_id, psy.product_id, psy.sizedefinition_id,
                          spy.supplierproductcode suppprodccode, spy.suppliersizecode suppsizecode,
                          (select spp.purchaseprice
                            from   supplierproductprice spp
                            where  spp.supplierproduct_id = spy.supplierproduct_id
                            and    spp.startdate =
                                   (select max(pz.startdate)
                                     from   supplierproductprice pz
                                     where  pz.supplierproduct_id = spp.supplierproduct_id
                                     and    pz.startdate <= trunc(sysdate))) suppprice
                   from   productsizepersupproduct psy
                   join   supplierproduct spy
                   on     spy.supplierproduct_id = psy.supplierproduct_id
                   where  spy.active = 'Y') zz
on     zz.supplier_id = x.supplier_id
and    zz.product_id = x.product_id
and    zz.sizedefinition_id = x.sizedefinition_id
/

create or replace view drsum_stockquantities as
select /*+parallel(8)*/
 /*view drsum_stockquantities  version 1.5*/
 sr.stockroom_id stockroom_id, sr.code stockroomcode, sr.name stockroomname, sl.rowcode rowcode,
 sl.locationcode locationcode, lt.locationtype_id locationtype_id, lt.code locationtypecode,
 p.code productcode, sd.code sizecode,
 coalesce((select prd.description
           from   product_desc prd
           where  prd.product_id = sdi.product_id
           and    prd.language_id = 2), '') product_desc,
 coalesce((select sdd.description
           from   sizedefinition_desc sdd
           where  sdd.sizedefinition_id = sd.sizedefinition_id
           and    sdd.language_id = 2), '') size_desc,
 coalesce((select ltd.description
           from   locationtype_desc ltd
           where  ltd.locationtype_id = lt.locationtype_id
           and    ltd.language_id = 2), '') lt_desc, cus.customer_id customer_id,
 coalesce(cus.customernumber, -2) customernumber, cus.name customername,
 sdi.customerowned customerowned, (sq.qtyunique + sq.qtyuniquewithmodifications) qtyunique,
 (sq.qtynonunique + srg.qtynonunique) qtynonunique, q.code gradecode, q.newgarment newgarment,
 q.defectitem defectitem, 1 usergroup_id, 'JA_JP' languagecode,
 nvl((select sv.avgpurchaseprice
      from   stockvalueavgpp sv
      where  sv.product_link_id = sdi.product_id
      and    sv.sizedefinition_link_id = sdi.sizedefinition_id
      and    sv.qualitygrade_id = srg.qualitygrade_id
      and    sv.stockvalueavgpp_id =
             (select max(s.stockvalueavgpp_id)
               from   stockvalueavgpp s
               where  s.stockroom_id in (select sro.stockroom_id
                                         from   stockroom sro
                                         where  sro.code = '999'
                                         or     sro.code = 'NEW')
               and    sv.avgpurchaseprice > 0
               and    s.product_link_id = sdi.product_id
               and    s.sizedefinition_link_id = sdi.sizedefinition_id
               and    s.qualitygrade_id = srg.qualitygrade_id
               and    s.transactiondate <= sysdate
               and    ((s.customer_link_id = sdi.customer_id) or s.customer_link_id is null))),
      nvl((select sv2.avgpurchaseprice
           from   stockvalueavgpp sv2
           where  sv2.product_link_id = sdi.product_id
           and    sv2.sizedefinition_link_id = sdi.sizedefinition_id
           and    sv2.qualitygrade_id = srg.qualitygrade_id
           and    sv2.stockvalueavgpp_id =
                  (select min(s2.stockvalueavgpp_id)
                    from   stockvalueavgpp s2
                    where  s2.stockroom_id in (select sro.stockroom_id
                                               from   stockroom sro
                                               where  sro.code = '999'
                                               or     sro.code = 'NEW')
                    and    sv2.avgpurchaseprice > 0
                    and    s2.product_link_id = sdi.product_id
                    and    s2.sizedefinition_link_id = sdi.sizedefinition_id
                    and    s2.qualitygrade_id = srg.qualitygrade_id
                    and    s2.transactiondate >= sysdate
                    and    ((s2.customer_link_id = sdi.customer_id) or s2.customer_link_id is null))),
           (select spp1.purchaseprice
             from   supplierproductprice spp1
             where  spp1.supplierproductprice_id =
                    (select max(spp.supplierproductprice_id)
                     from   productsizepersupproduct pss, supplierproductprice spp
                     where  pss.supplierproduct_id = spp.supplierproduct_id
                     and    pss.product_id = sdi.product_id
                     and    sdi.sizedefinition_id = pss.sizedefinition_id
                     and    spp.startdate <= sysdate)))) avgprice,
 nvl((select sv.avgpurchaseprice
      from   stockvalueavgpp sv
      where  sv.product_link_id = sdi.product_id
      and    sv.sizedefinition_link_id = sdi.sizedefinition_id
      and    sv.qualitygrade_id = srg.qualitygrade_id
      and    sv.stockvalueavgpp_id =
             (select max(s.stockvalueavgpp_id)
               from   stockvalueavgpp s
               where  s.stockroom_id in (select sro.stockroom_id
                                         from   stockroom sro
                                         where  sro.code = '999'
                                         or     sro.code = 'NEW')
               and    sv.avgpurchaseprice > 0
               and    s.product_link_id = sdi.product_id
               and    s.sizedefinition_link_id = sdi.sizedefinition_id
               and    s.qualitygrade_id = srg.qualitygrade_id
               and    s.transactiondate <= sysdate
               and    ((s.customer_link_id = sdi.customer_id) or s.customer_link_id is null))),
      nvl((select sv2.avgpurchaseprice
           from   stockvalueavgpp sv2
           where  sv2.product_link_id = sdi.product_id
           and    sv2.sizedefinition_link_id = sdi.sizedefinition_id
           and    sv2.qualitygrade_id = srg.qualitygrade_id
           and    sv2.stockvalueavgpp_id =
                  (select min(s2.stockvalueavgpp_id)
                    from   stockvalueavgpp s2
                    where  s2.stockroom_id in (select sro.stockroom_id
                                               from   stockroom sro
                                               where  sro.code = '999'
                                               or     sro.code = 'NEW')
                    and    sv2.avgpurchaseprice > 0
                    and    s2.product_link_id = sdi.product_id
                    and    s2.sizedefinition_link_id = sdi.sizedefinition_id
                    and    s2.qualitygrade_id = srg.qualitygrade_id
                    and    s2.transactiondate >= sysdate
                    and    ((s2.customer_link_id = sdi.customer_id) or s2.customer_link_id is null))),
           (select spp1.purchaseprice
             from   supplierproductprice spp1
             where  spp1.supplierproductprice_id =
                    (select max(spp.supplierproductprice_id)
                     from   productsizepersupproduct pss, supplierproductprice spp
                     where  pss.supplierproduct_id = spp.supplierproduct_id
                     and    pss.product_id = sdi.product_id
                     and    sdi.sizedefinition_id = pss.sizedefinition_id
                     and    spp.startdate <= sysdate)))) *
  ((sq.qtyunique + sq.qtyuniquewithmodifications) + (sq.qtynonunique + srg.qtynonunique)) qtyvalue,
 nvl((select max(pol.purchaseprice)
      from   purchaseorderline pol, purchaseorderstocktransaction pss
      where  pol.product_link_id = sdi.product_id
      and    pol.sizedefinition_link_id = sdi.sizedefinition_id
      and    pol.purchaseorderline_id = pss.purchaseorderline_id
      and    pol.purchaseprice > 0
      and    pss.timestamp = (select max(pss2.timestamp)
                              from   purchaseorderline pol2, purchaseorderstocktransaction pss2,
                                     purchaseorderheader poh
                              where  pol2.product_link_id = sdi.product_id
                              and    pol2.purchaseorderheader_id = poh.purchaseorderheader_id
                              and    poh.purchaseordertype = 0
                              and    pol2.sizedefinition_link_id = sdi.sizedefinition_id
                              and    pol2.purchaseorderline_id = pss2.purchaseorderline_id
                              and    pss2.timestamp <= sysdate)),
      (select spp1.purchaseprice
        from   supplierproductprice spp1
        where  spp1.supplierproductprice_id =
               (select max(spp.supplierproductprice_id)
                from   productsizepersupproduct pss, supplierproductprice spp
                where  pss.supplierproduct_id = spp.supplierproduct_id
                and    pss.product_id = sdi.product_id
                and    sdi.sizedefinition_id = pss.sizedefinition_id
                and    spp.startdate <= sysdate))) purchaseprice,
 case
   when q.newgarment = 'Y' then
    (srg.qtynonuniquereserved + srg.qtyuniquereserved + srg.qtyuniquewiithmodifreserved)
   else
    0
 end qtyreserved_new,
 case
   when q.newgarment = 'N' and q.defectitem = 'N' then
    (srg.qtynonuniquereserved + srg.qtyuniquereserved + srg.qtyuniquewiithmodifreserved)
   else
    0
 end qtyreserved_used,
 case
   when q.newgarment = 'Y' then
    (srg.qtynonuniqueordered + srg.qtyuniqueordered - srg.qtynonuniqueordereddirectissue -
    srg.qtyuniqueordereddirectissue)
   else
    0
 end qtyordered_new,
 case
   when q.newgarment = 'N' and q.defectitem = 'N' then
    (srg.qtynonuniqueordered + srg.qtyuniqueordered - srg.qtynonuniqueordereddirectissue -
    srg.qtyuniqueordereddirectissue)
   else
    0
 end qtyordered_used,
 case
   when q.newgarment = 'Y' and lt.code = 'BLOCK' then
    (sq.qtynonunique + sq.qtyunique + sq.qtyuniquewithmodifications)
   else
    0
 end qtyblocked_new,
 case
   when q.newgarment = 'N' and q.defectitem = 'N' and lt.code = 'BLOCK' then
    (sq.qtynonunique + sq.qtyunique + sq.qtyuniquewithmodifications)
   else
    0
 end qtyblocked_used,
 case
   when q.newgarment = 'Y' and lt.code <> 'BLOCK' then
    (sq.qtynonunique + sq.qtyunique + sq.qtyuniquewithmodifications + srg.qtynonunique) -
    (srg.qtynonuniquereserved + srg.qtyuniquereserved + srg.qtyuniquewiithmodifreserved)
   else
    0
 end qtyavailable_new,
 case
   when q.newgarment = 'N' and q.defectitem = 'N' and lt.code <> 'BLOCK' then
    (sq.qtynonunique + sq.qtyunique + sq.qtyuniquewithmodifications + srg.qtynonunique) -
    (srg.qtynonuniquereserved + srg.qtyuniquereserved + srg.qtyuniquewiithmodifreserved)
   else
    0
 end qtyavailable_used, 0 qtypicked_new, 0 qtypicked_used,
 sdi.minqtynew qtyminimum_new, sdi.minqtyused qtyminimum_used
from   stockroom sr
join   stockroomlocation sl
on     sl.stockroom_id = sr.stockroom_id
join   locationtype lt
on     lt.locationtype_id = sl.locationtype_id
join   stockquantity sq
on     sq.stockroomlocation_id = sl.stockroomlocation_id
join   stockreservationpergrade srg
on     srg.stockreservationpergrade_id = sq.stockreservationpergrade_id
join   stockdefinitionperitem sdi
on     sdi.stockdefinitionperitem_id = srg.stockdefinitionperitem_id
and    sdi.stockroom_id = sr.stockroom_id
left   outer join customer cus
on     sdi.customer_id = cus.customer_id
join   product p
on     p.product_id = sdi.product_id
join   sizedefinition sd
on     sd.sizedefinition_id = sdi.sizedefinition_id
join   qualitygrade q
on     q.qualitygrade_id = srg.qualitygrade_id
/

CREATE OR REPLACE VIEW DRSUM_STOCKTRANSACTIONS AS
select /*+parallel(x, 8)*/
       /*version 3.0*/
x.stocktransaction_source_id, 
x.transaction_date, 
x.business_unit_id, 
x.stock_room_id, 
x.product_id, 
x.size_id, 
x.qualitygrade_id, 
x.reason_id, 
x.transaction_type_id, 
x.related_customer_id, 
x.customer_owned, 
x.unique_stock, 
x.quantity, 
x.price, 
x.purchase_price, 
x.stockvalue, 
x.source_stock_room_code, 
x.destination_stock_room_code, 
x.document_type, 
x.document_number, 
x.workordernumber, 
x.customernumber, 
x.origin, 
x.time_stamp, 
x.custnumber
from (
 select
 --'norm' transtype,
 st.stocktransaction_id stocktransaction_source_id,
 st.transactiondate transaction_date,
 sr.managedbybu_id business_unit_id,
 sdi.stockroom_id stock_room_id,
 sdi.product_id,
 sdi.sizedefinition_id size_id,
 srg.qualitygrade_id,
 st.reasoncode_id reason_id,
 st.transactiontype_id transaction_type_id,
 nvl(sdi.customer_id, 0) related_customer_id,
 sdi.customerowned Customer_Owned,
 st.uniquestock Unique_Stock,
 st.quantity,
 st.calculationprice Price,
 case
   when st.documenttype = 2 --External PO
    then
    nvl((select max(pol.purchaseprice)
          from purchaseorderline pol, purchaseorderstocktransaction pss
         where pol.purchaseorderline_id = pss.purchaseorderline_id
           and pss.stocktransaction_id = st.stocktransaction_id),
        0)
   else
     nvl((select max(spp.purchaseprice)
       from supplierproduct sp
       join productsizepersupproduct pss on sp.supplierproduct_id =
                                            pss.supplierproduct_id
       join supplierproductprice spp on sp.supplierproduct_id =
                                        spp.supplierproduct_id
      where pss.product_id = sdi.product_id
        and pss.sizedefinition_id = sdi.sizedefinition_id
        and spp.startdate =
            (select max(spp2.startdate)
               from supplierproductprice spp2
              where spp2.supplierproduct_id = spp.supplierproduct_id
                and spp2.startdate <= st.timestamp)),
     (select max(pol.purchaseprice)
        from purchaseorderline pol
        join purchaseorderstocktransaction pss on pol.purchaseorderline_id =
                                                  pss.purchaseorderline_id
       where pol.product_link_id = sdi.product_id
         and pol.sizedefinition_link_id = sdi.sizedefinition_id
         and pss.timestamp =
             (select max(pss2.timestamp)
                from purchaseorderstocktransaction pss2
               where pss2.purchaseorderline_id = pol.purchaseorderline_id
                 and pss2.timestamp <= st.timestamp)))
 end Purchase_Price,
 nvl((select max(sv.avgpurchaseprice)
       from stockvalueavgpp sv
      where sv.product_link_id = sdi.product_id
        and sv.sizedefinition_link_id = sdi.sizedefinition_id
        and sv.qualitygrade_id = srg.qualitygrade_id
        and sv.stockvalueavgpp_id =
            (SELECT MAX(s.stockvalueavgpp_id)
               FROM StockValueAVGPP s
              WHERE s.stockroom_id in
                    (select sro.stockroom_id
                       from stockroom sro
                      where sro.code = '999'
                         or sro.code = 'NEW') --link to central stockroom temp solution--sdi.stockroom_id
                and sv.avgpurchaseprice > 0 --added to remove 0 value  ---change 09042012
                and s.product_link_id = sdi.product_id
                and s.sizedefinition_link_id = sdi.sizedefinition_id
                and s.qualitygrade_id = srg.qualitygrade_id --ih.issuegrade_id
                and s.transactiondate <= st.timestamp --ih.assigndate
                and ((s.customer_link_id = sdi.customer_id) or
                    s.customer_link_id is null))),
     nvl((select max(sv2.avgpurchaseprice)
           from stockvalueavgpp sv2
          where sv2.product_link_id = sdi.product_id
            and sv2.sizedefinition_link_id = sdi.sizedefinition_id
            and sv2.qualitygrade_id = srg.qualitygrade_id
            and sv2.stockvalueavgpp_id =
                (SELECT MIN(s2.stockvalueavgpp_id)
                   FROM StockValueAVGPP s2
                  WHERE s2.stockroom_id in
                        (select sro.stockroom_id
                           from stockroom sro
                          where sro.code = '999'
                             or sro.code = 'NEW') --link to central stockroom temp solution--sdi.stockroom_id
                    and sv2.avgpurchaseprice > 0 --added to remove 0 value  ---change 09042012
                    and s2.product_link_id = sdi.product_id
                    and s2.sizedefinition_link_id = sdi.sizedefinition_id
                    and s2.qualitygrade_id = srg.qualitygrade_id --ih.issuegrade_id
                    and s2.transactiondate >= st.timestamp --ih.assigndate
                    and ((s2.customer_link_id = sdi.customer_id) or
                        s2.customer_link_id is null))),
         (select max(spp1.purchaseprice)
            from supplierproductprice spp1
           where spp1.supplierproductprice_id =
                 (select max(spp.supplierproductprice_id)
                    from supplierproduct          sp,
                         productsizepersupproduct pss,
                         supplierproductprice     spp
                   where sp.supplierproduct_id = pss.supplierproduct_id
                     and sp.supplierproduct_id = spp.supplierproduct_id
                     and pss.product_id = sdi.product_id
                     and sdi.sizedefinition_id = pss.sizedefinition_id
                     and spp.startdate <= sysdate)))) StockValue,
 (select max(sr.code)
    from stockroomlocation srl, stockroom sr
   where sr.stockroom_id = srl.stockroom_id
     and srl.stockroomlocation_id = st.fromstockroomlocation_id) Source_Stock_Room_Code,
 (select max(sr.code)
    from stockroomlocation srl, stockroom sr
   where sr.stockroom_id = srl.stockroom_id
     and srl.stockroomlocation_id = st.tostockroomlocation_id) Destination_Stock_Room_Code,
 st.documenttype Document_Type,
 case
   when st.documentnumber = 0 then
    st.stocktransaction_id
   else
    st.documentnumber
 end Document_Number,
 nvl(wte.workordernumber, 0) workordernumber,
 nvl(wte.customernumber, 0) customernumber,
 nvl(wte.origin, 0) origin,
 st.timestamp Time_stamp,
 nvl((select max(cu.customernumber)
       from customer cu, outofcirculationhistory och
      where och.customer_link_id = cu.customer_id
        and och.outofcirculationhistory_id =
            (select max(och2.outofcirculationhistory_id)
               from outofcirculationhistory och2
              where och2.outofcircdate <= st.transactiontimestamp
                and och2.product_link_id = sdi.product_id
                and och2.sizedefinition_link_id = sdi.sizedefinition_id
                and och2.stockroom_id = sdi.stockroom_id
                and st.transactiontype_id in (15, 16))),
     0) custnumber
  from stocktransaction st
  join stockreservationpergrade srg
    on srg.stockreservationpergrade_id = st.stockreservationpergrade_id
  join stockdefinitionperitem sdi
    on sdi.stockdefinitionperitem_id = srg.stockdefinitionperitem_id
  join stockroom sr
    on sr.stockroom_id = sdi.stockroom_id
  left outer join stockvalueavgpp stav
    on stav.stockvalueavgpp_id = st.stocktransaction_id
  left outer join (select /*+index(wost XIF1WORKORDERSTOCKTRANSACTION) index(wl XPKWORKORDERLINE) index(w XPKWORKORDR)*/
                    w.workordernumber,
                    c.customernumber,
                    w.origin,
                    wost.stocktransaction_id
                     from workorderstocktransaction wost,
                          workorder                 w,
                          workorderline             wl,
                          customer                  c
                    where wost.workorderline_id = wl.workorderline_id
                      and wl.workorder_id = w.workorder_id
                      and w.customer_link_id = c.customer_id) wte
    on wte.stocktransaction_id = st.stocktransaction_id
 where st.transactiondate > (trunc(sysdate)-33)
  Union all
select
--'di' transtype,
999 stocktransaction_source_id
, ih.assigndate transaction_date
, ih.processbusinessunit_id
, (select wos.processingstockroom_id from workorder wos where ih.workorder_id=wos.workorder_id) stockroom_id
, ih.product_link_id product_id
, ih.sizedefinition_link_id size_id
, ih.issuegrade_id qualitygrade_id
, ih.reasoncode_id
, 0 transaction_id
, 0 related_customer_id
, '-' Customer_Owned
, '-' Unique_Stock
, sum(ih.quantity) countqty
, 0 price
,  nvl((select max(spp.purchaseprice)
       from supplierproduct sp
       join productsizepersupproduct pss on sp.supplierproduct_id =
                                            pss.supplierproduct_id
       join supplierproductprice spp on sp.supplierproduct_id =
                                        spp.supplierproduct_id
      where pss.product_id = ih.product_link_id
        and pss.sizedefinition_id = ih.sizedefinition_link_id
        and spp.startdate =
            (select max(spp2.startdate)
               from supplierproductprice spp2
              where spp2.supplierproduct_id = spp.supplierproduct_id
                and spp2.startdate <= ih.assigndate)),
     (select max(pol.purchaseprice)
        from purchaseorderline pol
        join purchaseorderstocktransaction pss on pol.purchaseorderline_id =
                                                  pss.purchaseorderline_id
       where pol.product_link_id = ih.product_link_id
         and pol.sizedefinition_link_id = ih.sizedefinition_link_id
         and pss.timestamp =
             (select max(pss2.timestamp)
                from purchaseorderstocktransaction pss2
               where pss2.purchaseorderline_id = pol.purchaseorderline_id
                 and pss2.timestamp <= ih.assigndate))) purchaseprice,
 ( select max(sv.avgpurchaseprice) from stockvalueavgpp sv where
                                      sv.product_link_id=ih.product_link_id
                                      and sv.sizedefinition_link_id=ih.sizedefinition_link_id
                                      and sv.qualitygrade_id=ih.issuegrade_id
                                      and sv.stockvalueavgpp_id=(SELECT  MIN(s.stockvalueavgpp_id)
                            FROM StockValueAVGPP s
                            WHERE
                            s.stockroom_id=wo.processingstockroom_id
                            and  s.product_link_id = ih.product_link_id
                            and s.sizedefinition_link_id = ih.sizedefinition_link_id
                            and s.qualitygrade_id = ih.issuegrade_id
                            and  s.transactiondate >= ih.assigndate
                            and ((s.customer_link_id = ih.customer_link_id)
                                 or s.customer_link_id is null))) StockValue
, (select sr.code from stockroom sr where sr.stockroom_id=ih.stockroom_id) Source_Stock_Room_Code
, null Destination_Stock_Room_Code
, 91 Document_Type
, (select wo.workordernumber from workorder wo where wo.workorder_id=ih.workorder_id) DocumentNr
, wo.workordernumber
, (select c.customernumber from customer c where ih.customer_link_id=c.customer_id) customernumber
, wo.origin
,ih.assigndate timestamp
, 0 custnumber
from
  issuehistory ih, workorder wo
  where ih.workorder_id=wo.workorder_id
  and wo.deliverfrom=1
and ih.assigndate >(trunc(sysdate)-33)
group by
ih.processbusinessunit_id
, ih.product_link_id
, ih.sizedefinition_link_id
,ih.stockroom_id
, ih.issuegrade_id
, ih.reasoncode_id
, ih.assigndate
, ih.customer_link_id
,ih.workorder_id
, wo.workordernumber
, wo.origin
, wo.processingstockroom_id
Union all
select
--'rd' transtype,
999 stocktransaction_source_id
, ih.assigndate transaction_date
, ih.processbusinessunit_id
, (select wos.processingstockroom_id from workorder wos where ih.workorder_id=wos.workorder_id) stockroom_id
, ih.product_link_id product_id
, ih.sizedefinition_link_id size_id
, ih.issuegrade_id qualitygrade_id
, ih.reasoncode_id
, 0 transaction_id
, 0 related_customer_id
, '-' Customer_Owned
, '-' Unique_Stock
, - sum(ih.quantity) countqty
, 0 price
,  nvl((select max(spp.purchaseprice)
       from supplierproduct sp
       join productsizepersupproduct pss on sp.supplierproduct_id =
                                            pss.supplierproduct_id
       join supplierproductprice spp on sp.supplierproduct_id =
                                        spp.supplierproduct_id
      where pss.product_id = ih.product_link_id
        and pss.sizedefinition_id = ih.sizedefinition_link_id
        and spp.startdate =
            (select max(spp2.startdate)
               from supplierproductprice spp2
              where spp2.supplierproduct_id = spp.supplierproduct_id
                and spp2.startdate <= ih.assigndate)),
     (select max(pol.purchaseprice)
        from purchaseorderline pol
        join purchaseorderstocktransaction pss on pol.purchaseorderline_id =
                                                  pss.purchaseorderline_id
       where pol.product_link_id = ih.product_link_id
         and pol.sizedefinition_link_id = ih.sizedefinition_link_id
         and pss.timestamp =
             (select max(pss2.timestamp)
                from purchaseorderstocktransaction pss2
               where pss2.purchaseorderline_id = pol.purchaseorderline_id
                 and pss2.timestamp <= ih.assigndate))) purchaseprice,
 ( select max(sv.avgpurchaseprice) from stockvalueavgpp sv where
                                      sv.product_link_id=ih.product_link_id
                                      and sv.sizedefinition_link_id=ih.sizedefinition_link_id
                                      and sv.qualitygrade_id=ih.issuegrade_id
                                      and sv.stockvalueavgpp_id=(SELECT  MIN(s.stockvalueavgpp_id)
                            FROM StockValueAVGPP s
                            WHERE
                            s.stockroom_id=wo.processingstockroom_id
                            and  s.product_link_id = ih.product_link_id
                            and s.sizedefinition_link_id = ih.sizedefinition_link_id
                            and s.qualitygrade_id = ih.issuegrade_id
                            and  s.transactiondate >= ih.assigndate
                            and ((s.customer_link_id = ih.customer_link_id)
                                 or s.customer_link_id is null))) StockValue
, (select sr.code from stockroom sr where sr.stockroom_id=ih.stockroom_id) Source_Stock_Room_Code
, null Destination_Stock_Room_Code
, 92 Document_Type
, 0  DocumentNr
, 0 workordernumber
, 0 customernumber
, wo.origin
,ih.assigndate timestamp
, 0 custnumber
from
  issuehistory ih, workorder wo
  where ih.workorder_id=wo.workorder_id
  and wo.deliverfrom=1
and ih.assigndate>(trunc(sysdate)-33)
group by
ih.processbusinessunit_id
, ih.product_link_id
, ih.sizedefinition_link_id
,ih.stockroom_id
, ih.issuegrade_id
, ih.reasoncode_id
, ih.assigndate
, ih.customer_link_id
,ih.workorder_id
, wo.workordernumber
, wo.origin
, wo.processingstockroom_id
-- added for direct sales issues
Union all
select
--'dis' transtype,
 999 stocktransaction_source_id,
 gsh.salesdate transaction_date,
 gsh.processbusinessunit_id,
 (select max(wos.processingstockroom_id)
    from workorder wos, workorderline wols
   where gsh.workorderline_id = wols.workorderline_id
     and wols.workorder_id = wos.workorder_id) stockroom_id,
 gsh.product_link_id,
 gsh.sizedefinition_link_id size_id,
 gsh.qualitygrade_id qualitygrade_id,
 gsh.reasoncode_id,
 0 transaction_id,
 0 related_customer_id,
 '-' Customer_Owned,
 '-' Unique_Stock,
 sum(gsh.quantity) countqty,
 0 price,
 nvl((select max(spp.purchaseprice)
       from supplierproduct sp
       join productsizepersupproduct pss on sp.supplierproduct_id =
                                            pss.supplierproduct_id
       join supplierproductprice spp on sp.supplierproduct_id =
                                        spp.supplierproduct_id
      where pss.product_id = gsh.product_link_id
        and pss.sizedefinition_id = gsh.sizedefinition_link_id
        and spp.startdate =
            (select max(spp2.startdate)
               from supplierproductprice spp2
              where spp2.supplierproduct_id = spp.supplierproduct_id
                and spp2.startdate <= gsh.salesdate)),
     (select max(pol.purchaseprice)
        from purchaseorderline pol
        join purchaseorderstocktransaction pss on pol.purchaseorderline_id =
                                                  pss.purchaseorderline_id
       where pol.product_link_id = gsh.product_link_id
         and pol.sizedefinition_link_id = gsh.sizedefinition_link_id
         and pss.timestamp =
             (select max(pss2.timestamp)
                from purchaseorderstocktransaction pss2
               where pss2.purchaseorderline_id = pol.purchaseorderline_id
                 and pss2.timestamp <= gsh.salesdate))) purchaseprice,
 (select max(sv.avgpurchaseprice)
    from stockvalueavgpp sv
   where sv.product_link_id = gsh.product_link_id
     and sv.sizedefinition_link_id = gsh.sizedefinition_link_id
     and sv.qualitygrade_id = gsh.qualitygrade_id
     and sv.stockvalueavgpp_id =
         (SELECT MIN(s.stockvalueavgpp_id)
            FROM StockValueAVGPP s
           WHERE s.stockroom_id = wo.processingstockroom_id
             and s.product_link_id = gsh.product_link_id
             and s.sizedefinition_link_id = gsh.sizedefinition_link_id
             and s.qualitygrade_id = gsh.qualitygrade_id
             and s.transactiondate >= gsh.salesdate
             and ((s.customer_link_id = gsh.customer_link_id) or
                 s.customer_link_id is null))) StockValue,
 (select sr.code from stockroom sr where sr.stockroom_id = gsh.stockroom_id) Source_Stock_Room_Code,
 null Destination_Stock_Room_Code,
 91 Document_Type,
 (select max(wo.workordernumber)
    from workorder wo, workorderline wol2
   where wo.workorder_id = wol2.workorder_id
     and wol2.workorderline_id = gsh.workorderline_id) DocumentNr,
 wo.workordernumber,
 (select c.customernumber
    from customer c
   where gsh.customer_link_id = c.customer_id) customernumber,
 wo.origin,
 gsh.salesdate timestamp,
 0 custnumber
  from garmentsaleshistory gsh, workorder wo, workorderline wol
 where wo.workorder_id = wol.workorder_id
   and wo.deliverfrom = 1
   and wol.workorderline_id = gsh.workorderline_id
   and gsh.salesdate > (trunc(sysdate) - 33)
   and not exists
 (select 1
          from reasoncode rc, workorder wo, workorderline wol
         where rc.reasoncode_id = gsh.reasoncode_id
           and rc.inventorytrigger = 9
           and wol.workorderline_id = gsh.workorderline_id
           and wo.workorder_id = wol.workorder_id
           and wo.origin = 1)
 group by gsh.processbusinessunit_id,
          gsh.product_link_id,
          gsh.sizedefinition_link_id,
          gsh.stockroom_id,
          gsh.qualitygrade_id,
          gsh.reasoncode_id,
          gsh.salesdate,
          gsh.customer_link_id,
          gsh.workorderline_id,
          wo.workordernumber,
          wo.origin,
          wo.processingstockroom_id
Union all
select
--'rds' transtype,
 999 stocktransaction_source_id,
 gsh.salesdate transaction_date,
 gsh.processbusinessunit_id,
 (select max(wos.processingstockroom_id)
    from workorder wos, workorderline wols
   where gsh.workorderline_id = wols.workorderline_id
     and wols.workorder_id = wos.workorder_id) stockroom_id,
 gsh.product_link_id,
 gsh.sizedefinition_link_id size_id,
 gsh.qualitygrade_id qualitygrade_id,
 gsh.reasoncode_id,
 0 transaction_id,
 0 related_customer_id,
 '-' Customer_Owned,
 '-' Unique_Stock,
 -sum(gsh.quantity) countqty,
 0 price,
 nvl((select max(spp.purchaseprice)
       from supplierproduct sp
       join productsizepersupproduct pss on sp.supplierproduct_id =
                                            pss.supplierproduct_id
       join supplierproductprice spp on sp.supplierproduct_id =
                                        spp.supplierproduct_id
      where pss.product_id = gsh.product_link_id
        and pss.sizedefinition_id = gsh.sizedefinition_link_id
        and spp.startdate =
            (select max(spp2.startdate)
               from supplierproductprice spp2
              where spp2.supplierproduct_id = spp.supplierproduct_id
                and spp2.startdate <= gsh.salesdate)),
     (select max(pol.purchaseprice)
        from purchaseorderline pol
        join purchaseorderstocktransaction pss on pol.purchaseorderline_id =
                                                  pss.purchaseorderline_id
       where pol.product_link_id = gsh.product_link_id
         and pol.sizedefinition_link_id = gsh.sizedefinition_link_id
         and pss.timestamp =
             (select max(pss2.timestamp)
                from purchaseorderstocktransaction pss2
               where pss2.purchaseorderline_id = pol.purchaseorderline_id
                 and pss2.timestamp <= gsh.salesdate))) purchaseprice,
 (select max(sv.avgpurchaseprice)
    from stockvalueavgpp sv
   where sv.product_link_id = gsh.product_link_id
     and sv.sizedefinition_link_id = gsh.sizedefinition_link_id
     and sv.qualitygrade_id = gsh.qualitygrade_id
     and sv.stockvalueavgpp_id =
         (SELECT MIN(s.stockvalueavgpp_id)
            FROM StockValueAVGPP s
           WHERE s.stockroom_id = wo.processingstockroom_id
             and s.product_link_id = gsh.product_link_id
             and s.sizedefinition_link_id = gsh.sizedefinition_link_id
             and s.qualitygrade_id = gsh.qualitygrade_id
             and s.transactiondate >= gsh.salesdate
             and ((s.customer_link_id = gsh.customer_link_id) or
                 s.customer_link_id is null))) StockValue,
 (select sr.code from stockroom sr where sr.stockroom_id = gsh.stockroom_id) Source_Stock_Room_Code,
 null Destination_Stock_Room_Code,
 92 Document_Type,
 (select max(wo.workordernumber)
    from workorder wo, workorderline wol2
   where wo.workorder_id = wol2.workorder_id
     and wol2.workorderline_id = gsh.workorderline_id) DocumentNr,
 wo.workordernumber,
 (select c.customernumber
    from customer c
   where gsh.customer_link_id = c.customer_id) customernumber,
 wo.origin,
 gsh.salesdate timestamp,
 0 custnumber
  from garmentsaleshistory gsh, workorder wo, workorderline wol
 where wo.workorder_id = wol.workorder_id
   and wo.deliverfrom = 1
   and wol.workorderline_id = gsh.workorderline_id
   and not exists
 (select 1
          from reasoncode rc, workorder wo, workorderline wol
         where rc.reasoncode_id = gsh.reasoncode_id
           and rc.inventorytrigger = 9
           and wol.workorderline_id = gsh.workorderline_id
           and wo.workorder_id = wol.workorder_id
           and wo.origin = 1)
   and gsh.salesdate > (trunc(sysdate) - 33)
 group by gsh.processbusinessunit_id,
          gsh.product_link_id,
          gsh.sizedefinition_link_id,
          gsh.stockroom_id,
          gsh.qualitygrade_id,
          gsh.reasoncode_id,
          gsh.salesdate,
          gsh.customer_link_id,
          gsh.workorderline_id,
          wo.workordernumber,
          wo.origin,
          wo.processingstockroom_id
) x
/

create or replace view drsum_uniqueitem as
select /*+parallel(8)*/
      /*view drsum_uniqueitem version 0.4*/
      ui.primaryid primary_id                        
      ,uinp.garmentsequencenumber garm_sequence_number                        
      ,bu2.code bu_code                       
      ,bu.code cust_bu_code                       
      ,c.customernumber customer_number                       
      ,w.wearernumber wearer_number                       
      ,w.fullname wearer_name                       
      ,w.searchname wearer_search_name                        
      ,sr.code stockroom_code                       
      ,sr.name stockroom_name                       
      ,sl.rowcode row_code                        
      ,sl.locationcode location_code                        
      ,p.code product_code                        
      ,pd.description product_name                        
      ,sd.code product_size_code                        
      ,fm.code finishingmethod_code                       
      ,fmd.description finishingmethod_name                       
      ,qg.code qualitygrade_code                        
      ,std2.description prev_status                       
      ,std1.description status                        
      ,ui.statuschangedate status_change_date                       
      ,syd2.description prev_stay                       
      ,syd1.description stay                        
      ,ui.staychangedate stay_change_date                       
      ,rc.code reason_code                        
      ,rd.description reason_name                       
      ,uif.enddatefullrent end_date_fullrent                        
      ,uif.firstissuedate first_issue_date                        
      ,uif.lastissuedate last_issue_date                        
      ,ui.lastinscandate last_inscan_date                       
      ,ui.lastoutscandate last_outscan_date                       
      ,ui.lastscandate last_scan_date                       
      ,uif.lastonstockdate last_on_stock_date                       
      ,uif.numberofissues number_of_issues                        
      ,case                       
        when ui.status_id = 26 then                       
         trunc(sysdate) - trunc(uif.lastissuedate)                        
        else                        
         0                        
       end now_days_in_circ                       
      ,uif.daysincircprevissue days_in_circ_previssue                       
      ,case                       
        when uif.firstissuedate is null then                        
         0                        
        when ui.status_id = 26 then                       
         trunc(sysdate) - trunc(uif.lastissuedate) + uif.daysincircprevissue                        
        when ui.status_id in (25,31) then                       
         uif.daysincircprevissue                        
        else                        
         null                       
       end all_days_in_circ                       
       ,case                        
        when uif.firstissuedate is null then                        
         case                       
          when ui.status_id = 25 then                       
           trunc(sysdate) - trunc(uif.lastonstockdate)                        
          when ui.status_id = 31 then                       
           trunc(ui.statuschangedate) - trunc(uif.lastonstockdate)                        
          else                        
           null                       
         end                        
        when ui.status_id = 26 then                       
         (trunc(sysdate) - trunc(uif.firstissuedate)) - ((trunc(sysdate) - trunc(uif.lastissuedate)) + uif.daysincircprevissue)                       
        when ui.status_id = 25 then                       
         (trunc(sysdate) - trunc(uif.firstissuedate)) - uif.daysincircprevissue                       
        when ui.status_id = 31 then                       
         (trunc(ui.statuschangedate) - trunc(uif.firstissuedate)) - uif.daysincircprevissue                       
        else                        
         null                       
       end all_days_in_stock                        
      ,uinp.washesthisissue washes_this_issue                       
      ,ui.washestotal washes_total                        
      ,uinp.rewashthisissue rewash_this_issue                       
      ,ui.rewashtotal rewash_total                        
      ,uinp.repairsthisissue repairs_this_issue                       
      ,ui.repairstotal repairs_total                        
      ,sp.suppliernumber supplier_number                        
      ,sp.name supplier_name                        
      ,w.customeremployeenumber admin_number
      ,w.firstname first_name
      ,we.sequencenumber wearer_employment_number
      ,wi.dateactive wearer_inventory_start_date
      ,wi.dateinactive wearer_inventory_end_date
      ,wi.maxinventory max_inventory
      ,wi.changesperweek changes_per_week
      ,wi.circinventory circ_inventory
      ,pr.priority product_ranking
      ,pr.ranking product_ranking_description
      ,col.code color_code
      ,cold.description color_code_description
      ,pg.code product_group
      ,pgd.description product_group_description
      ,sp2.suppliernumber preferred_supplier_number
      ,sp2.name preferred_supplier_name
      ,(select sa.secondaryid
        from secondaryuniqueitem sa
        where sa.uniqueitem_id = ui.uniqueitem_id) secondaryid
      ,cl.customernumber last_customer_number
      ,wl.wearernumber last_wearer_number
from   uniqueitem ui
left   outer join(uniqueitemnonpool uinp
join   wearerinventory wi
on     uinp.wearerinventory_id = wi.wearerinventory_id
join   weareremployment we
on     uinp.weareremployment_id = we.weareremployment_id
join   wearer w
on     we.wearer_id = w.wearer_id
join   customer c
on     w.customer_id = c.customer_id
join   businessunit bu
on     c.defaultbusinessunit_id = bu.businessunit_id) on ui.uniqueitem_id = uinp.uniqueitem_id
join   product p
on     ui.product_id = p.product_id
join   product_desc pd
on     p.product_id = pd.product_id
join   languages l
on     l.language_id = pd.language_id
join   color col
on     p.color_id = col.color_id
join   color_desc cold
on     p.color_id = cold.color_id
and    cold.language_id = l.language_id
left   outer join productranking pr
on     p.productranking_id = pr.productranking_id
join   productgroup pg
on     p.productgroup_id = pg.productgroup_id
join   productgroup_desc pgd
on     p.productgroup_id = pgd.productgroup_id
and    pgd.language_id = l.language_id
join   supplier sp2
on     p.supplier_id = sp2.supplier_id
join   sizedefinition sd
on     ui.sizedefinition_id = sd.sizedefinition_id
left   outer join(finishingmethod fm
join   finishingmethod_desc fmd
on     fm.finishingmethod_id = fmd.finishingmethod_id) on ui.finishingmethod_id = fm.finishingmethod_id and fmd.language_id = l.language_id
join   businessunit bu2
on     ui.businessunit_id = bu2.businessunit_id
join   status st1
on     ui.status_id = st1.status_id
and    st1.statustype = 'UI'
join   status_desc std1
on     st1.status_id = std1.status_id
and    std1.language_id = l.language_id
left   outer join(status st2
join   status_desc std2
on     st2.status_id = std2.status_id) on ui.prevstatus_id = st2.status_id and std2.language_id = l.language_id and st2.statustype = 'UI'
join   stay sy1
on     ui.stay_id = sy1.stay_id
join   stay_desc syd1
on     sy1.stay_id = syd1.stay_id
and    syd1.language_id = l.language_id
left   outer join(stay sy2
join   stay_desc syd2
on     sy2.stay_id = syd2.stay_id) on ui.prevstay_id = sy2.stay_id and syd2.language_id = l.language_id
join   uniqueitemfixedinfo uif
on     ui.uniqueitem_id = uif.uniqueitem_id
join   reasoncode rc
on     uif.reasoncode_id = rc.reasoncode_id
join   reasoncode_desc rd
on     rc.reasoncode_id = rd.reasoncode_id
and    rd.language_id = l.language_id
left   outer join qualitygrade qg
on     uif.qualitygrade_id = qg.qualitygrade_id
join   supplier sp
on     uif.supplier_id = sp.supplier_id
left   outer join(stockroomlocation sl
join   stockroom sr
on     sl.stockroom_id = sr.stockroom_id) on uif.stockroomlocation_id = sl.stockroomlocation_id
left   join(weareremployment wel
join   wearer wl
on     wl.wearer_id = wel.wearer_id
join   customer cl
on     cl.customer_id = wl.customer_id) on wel.weareremployment_id = ui.lastweareremployment_link_id
where  l.language_id = 2
and    ui.status_id <> 31
/

create or replace view drsum_wearer_inventory as
select  /*+parallel(8)*/
        /*view drsum_wearer_inventory version 1.0*/
        wi.wearerinventory_id  Source_ID,
        (select w.customer_id from weareremployment wer, wearer w where wer.weareremployment_id=wi.weareremployment_id and wer.wearer_id=w.wearer_id) customer,
        wi.weareremployment_id Wearer_Employment,
        wi.product_id Product,
        --wi.sizedefinition_id Size_ID,
        wi.finishingmethod_id Finishing_Method,
        et.code Emblem_Template_Code,
        et.description Emblem_Template,
        qg.code Special_Grade_Code,
        sz.code Season_Code,
        wi.maxinventory Max_Inventory,
        wi.circinventory Circulating_Inventory,
        wi.changesperweek Changes_Per_Week,
        wi.maxfreeofcharge Max_Free_of_Charge,
        wi.freeofchargeqty Free_Of_Charge_In_Circ,
        wi.dateactive Date_Active,
        case when to_char(wi.dateinactive,'YYYYMMDD') <> '20991231'
         then wi.dateinactive
         else null
        end Date_Inactive,
        wi.returnedqty Returned_Qty,
        wi.qtytobereturnedreplacement To_Be_Returned_Replacement,
        wi.qtytobereturneddecreasemax To_Be_Returned_Decrease_Max,
        case when to_char(wi.temporaryrentstopstartdate,'YYYYMMDD') <> '20991231'
         then wi.temporaryrentstopstartdate
         else null
        end Temporary_Stop_Start_Date,
        case when to_char(wi.temporaryrentstopenddate,'YYYYMMDD') <> '20991231'
         then wi.temporaryrentstopenddate
         else null
        end Temporary_Stop_End_Date,
        wi.remark Remark,
        wi.dispensecredit Dispense_Credit,
        case when wi.personalizedgarment='Y'
             then dwh_str(1)
             else dwh_str(2)
        end Is_Personalized_Garments,
        case when to_char(wi.losschargedate,'YYYYMMDD') <> '20991231'
         then wi.losschargedate
         else null
        end Loss_Charge_Date,
        (select m.code
           from wearerinventorymodification wid, modification m
          where wid.wearerinventory_id = wi.wearerinventory_id
            and m.modification_id = wid.modification_id
            and wid.sequencenumber = 1) Modification_Code_1,
        (select m.code
           from wearerinventorymodification wid, modification m
          where wid.wearerinventory_id = wi.wearerinventory_id
            and m.modification_id = wid.modification_id
            and wid.sequencenumber = 2) Modification_Code_2,
        (select m.code
           from wearerinventorymodification wid, modification m
          where wid.wearerinventory_id = wi.wearerinventory_id
            and m.modification_id = wid.modification_id
            and wid.sequencenumber = 3) Modification_Code_3,
        greatest(wi.timestamp,
                 coalesce(et.timestamp,to_date('01-01-1900', 'dd-mm-yyyy')),
                 coalesce(qg.timestamp,to_date('01-01-1900', 'dd-mm-yyyy')),
                 coalesce(sz.timestamp,to_date('01-01-1900', 'dd-mm-yyyy')),
                 coalesce((select max(m.timestamp)
                             from wearerinventorymodification wid, modification m
                            where wid.wearerinventory_id = wi.wearerinventory_id
                              and m.modification_id = wid.modification_id),to_date('01-01-1900', 'dd-mm-yyyy'))
                 ) Time_Stamp
from  wearerinventory wi
      left outer join emblemtemplate et on (et.emblemtemplate_id=wi.emblemtemplate_id)
      left outer join qualitygrade qg on (qg.qualitygrade_id = wi.specialgrade_id)
      left outer join season sz on (sz.season_id = wi.season_id)
      and wi.dateinactive>=sysdate
/

create or replace procedure erp_cleanup is
  --procedure erp_cleanup version 0.1
  ----------locale variables
  lv_cursornum integer;
  lv_ignore    integer;
  lv_count     number;
  i            integer;
  lv_sql_stmnt varchar2(4000);
  lv_message   varchar2(1000);

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'erp_cleanup', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --ok no output does not matter
    end;
  end write_log;

  procedure finalize(fp_days in number default 2, fp_rowcount in number, fp_tablename in varchar2) is
  begin
    --finalize
    commit;
    if fp_rowcount = 0 then
      write_log('Successfull cleanup of ' || fp_tablename || ' data older then ' ||
                to_char(fp_days) || ' days, nothing deleted', 1);
    else
      write_log('Successfull cleanup of ' || fp_tablename || ' data older then ' ||
                to_char(fp_days) || ' days ' || to_char(fp_rowcount) || ' rows deleted', 1);
    end if;
  end finalize;

begin
  --erp_cleanup
  for x in (select es.* from erp_cleanup_selection es) loop
    begin
      lv_count := 0;
      --max clean in chuncks of 5000, msx 200 times..
      if x.extra_where_clause is not null then
        begin
          if x.logtablename is not null then
            begin
              lv_sql_stmnt := 'delete from ' || x.tablename || ' e where e.' || x.datefieldname ||
                              ' < trunc(sysdate-' || to_char(x.days_to_keep) || ' ) and (' ||
                              x.extra_where_clause ||
                              ') and rownum <= 5000 and exists (select 1 from ' || x.logtablename ||
                              ' el where el.transfer_id = e.transfer_id and el.process_status = 0)';
            end;
          else
            begin
              lv_sql_stmnt := 'delete from ' || x.tablename || ' e where e.' || x.datefieldname ||
                              ' < trunc(sysdate-' || to_char(x.days_to_keep) || ' ) and (' ||
                              x.extra_where_clause || ') and rownum <= 5000';
            end;
          end if;
        end;
      else
        begin
          if x.logtablename is not null then
            begin
              lv_sql_stmnt := 'delete from ' || x.tablename || ' e where e.' || x.datefieldname ||
                              ' < trunc(sysdate-' || to_char(x.days_to_keep) || ' )' ||
                              ' and rownum <= 5000 and exists (select 1 from ' || x.logtablename ||
                              ' el where el.transfer_id = e.transfer_id and el.process_status = 0)';
            end;
          else
            begin
              lv_sql_stmnt := 'delete from ' || x.tablename || ' e where e.' || x.datefieldname ||
                              ' < trunc(sysdate-' || to_char(x.days_to_keep) ||
                              ' ) and rownum <= 5000';
            end;
          end if;
        end;
      end if;
      --max 200 loops
      for i in 1 .. 200 loop
        begin
          lv_message   := 'Deleting for ' || x.description || ' chunk ' || i;
          lv_cursornum := dbms_sql.open_cursor;
          dbms_sql.parse(lv_cursornum, lv_sql_stmnt, dbms_sql.v7);
          lv_ignore := dbms_sql.execute(lv_cursornum);
          lv_count  := lv_count + lv_ignore;
          dbms_sql.close_cursor(lv_cursornum);
          commit;
          --nothing deleted exit
          if lv_ignore = 0 then
            exit;
          end if;
        end;
      end loop; -- for i in 1 .. lv_numchunks
      finalize(x.days_to_keep, lv_count, x.tablename);
    exception
      when others then
        begin
          write_log('Delete from ' || x.tablename || ' ' || lv_message || ' Error: ' || sqlerrm, 3);
        end;
    end;
  end loop; --x
exception
  when others then
    begin
      rollback;
      lv_message := 'Error ' || sqlerrm || ' ' || lv_message;
      write_log(lv_message, 3);
    end;
end erp_cleanup;
/

create or replace procedure erp_o_miroku_export(fp_monthyear in varchar2, --Format mm/yyyy
                                                fp_filename  in varchar2,
                                                fp_separator in varchar2 default ',') is
  gv_userexception exception;
  gv_message       varchar2(1000);
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_dir           systemsetting.value%type;
  gv_filehandle    utl_file.file_type;
  gv_filename      varchar2(255);
  gv_separator     varchar2(1);

  --procedure erp_o_miroku_export version 0.5
  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'erp_o_miroku_export', null, fp_priority, fp_message,
                             gv_defaultuserid);
    if fp_priority = 3 then
      write_log('erp_o_miroku_export finished with errors!', 1);
    end if;
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null;
    end;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_filename := fp_filename || '_' || to_char(sysdate, 'yyyymmdd') || '.csv';
    gv_message  := 'erp_o_miroku_export.open_file ' || gv_dir || ' filename ' || fp_filename;
    return utl_file.fopen(gv_dir, gv_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
    procedure clear_old_erp_data is
    begin
      gv_message := 'clear_old_erp_data';
      --clear_old_data, flag old data as read, we want this new data now only
      update erp_o_miroku e set e.transfer_status = 1 where e.transfer_status = 0;
      --create log, flagged as ok so it can be cleared
      insert into erp_o_miroku_log
        (transfer_id, transfer_status, text, process_status)
        select x.transfer_id, 0, 'not processed previously', 0
        from   erp_o_miroku x
        where  x.transfer_status = 0
        and    not exists
         (select 1 from erp_o_miroku_log y where y.transfer_id = x.transfer_id);
    end clear_old_erp_data;
  begin
    --initialize
    gv_message := 'initialize';
    --clear old erp data
    clear_old_erp_data;
    --get directory
    select nvl(max(ss.value), max(ss.factorydefault))
    into   gv_dir
    from   systemsetting ss
    where  ss.name = 'FINEXPORTDIRECTORY';
    --set date format
    execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "YYYY/MM/DD"';
    --write log
    write_log('Start export to file ' || gv_dir || ' filename ' || fp_filename);
    --check parameter
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    if fp_separator is null then
      gv_separator := ',';
    else
      gv_separator := substr(trim(fp_separator), 1, 1);
    end if;
    --open file
    gv_filehandle := open_file;
    --auj_erp_miroku.proc_o_miroku;
    auj_erp_miroku.proc_o_miroku(fp_monthyear);
  end initialize;

  procedure finalize is
  begin
    --finalize
    close_file;
    commit;
    gv_message := 'Exported data into directory ' || gv_dir || ' filename ' || fp_filename;
    write_log(gv_message);
  end finalize;

  procedure export_data is
    procedure upd_transstatus(fp_transferid in number) is
    begin
      update erp_o_miroku e set e.transfer_status = 1 where e.transfer_id = fp_transferid;
    end upd_transstatus;
    procedure write_line(fp_line in varchar2) is
    begin
      utl_file.put(gv_filehandle, convert(fp_line, 'JA16SJIS', 'UTF8'));
      utl_file.new_line(gv_filehandle);
    end write_line;
    procedure write_erp_log(fp_transferid      in number,
                            fp_transfer_status in number,
                            fp_text            in varchar2,
                            fp_process_status  in number) is
    begin
      insert into erp_o_miroku_log
        (transfer_id, transfer_status, text, process_status)
      values
        (fp_transferid, fp_transfer_status, fp_text, fp_process_status);
    exception
      when dup_val_on_index then
        begin
          --build update log string
          update erp_o_miroku_log
          set    transfer_status = fp_transfer_status, text = fp_text,
                 process_status = fp_process_status
          where  transfer_id = fp_transferid;
        end;
    end write_erp_log;
  begin
    --export_data
    gv_message := 'export_data';
    for x in (select e.*
              from   erp_o_miroku e
              where  e.transfer_status = 0
              order  by e.artransactiondate, e.credit_item_code, e.credit_department_code,
                        e.consumption_tax_code) loop
      begin
        --upd_transstatus
        upd_transstatus(x.transfer_id);
        --write line with separator
        write_line(x.artransactiondate || gv_separator || x.slip_number || gv_separator ||
                   x.journal_input_format || gv_separator || x.debit_subject_code || gv_separator ||
                   x.debit_subject_name || gv_separator || x.debit_division_code || gv_separator ||
                   x.debit_division_name || gv_separator || x.subject_code || gv_separator ||
                   x.subject_name || gv_separator || x.debit_business_partner_code || gv_separator ||
                   x.debit_business_partner_name || gv_separator || x.debit_auxiliary_code ||
                   gv_separator || x.debit_auxiliary_name || gv_separator || x.credit_item_code ||
                   gv_separator || x.credit_item_name || gv_separator || x.credit_department_code ||
                   gv_separator || x.credit_department_name || gv_separator ||
                   x.credit_subject_code || gv_separator || x.credit_subject_name || gv_separator ||
                   x.credit_business_partner_code || gv_separator ||
                   x.credit_business_partner_name || gv_separator || x.credit_auxiliary_code ||
                   gv_separator || x.credit_auxiliary_name || gv_separator ||
                   x.consumption_tax_code || gv_separator || x.consumption_tax_rate ||
                   gv_separator || x.amount || gv_separator || x.description || gv_separator ||
                   x.due_date || gv_separator || x.record_category || gv_separator || '1' ||
                   gv_separator);
        --write_erp_log
        write_erp_log(x.transfer_id, 0, 'Ok', 0);
      exception
        when others then
          begin
            --write_erp_log
            write_erp_log(x.transfer_id, 0, 'Error ' || sqlerrm, 1);
          end;
      end;
    end loop; --x
  end export_data;

begin
  initialize;
  export_data;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
      rollback;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
      rollback;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
      rollback;
    end;
end erp_o_miroku_export;
/

create or replace procedure export_aim(fp_filename in varchar2, fp_statementdate in date) is
  gv_userexception exception;
  gv_message       varchar2(1000);
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_dir           systemsetting.value%type;
  gv_filehandle    utl_file.file_type;
  gv_separator     varchar2(1) := ',';
  --Version 17
  --06-02-2018    version based on request document 
  --06-06-2019    ABS-81503 AIM Interface tax rate changes
  --04-06-2019    Adjustments based on test results
  --20-12-2024    ABSN-780 Name change
  --13-02-2025    ABSN-2210 Please add a new account code to AIM

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'export_aim', null, fp_priority, fp_message, gv_defaultuserid);
    if fp_priority = 3 then
      write_log('export_aim finished with errors!', 1);
    end if;
    if fp_priority > 2 then
      dbms_output.put_line(fp_message);
    end if;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_message := 'open_file directory ' || nvl(gv_dir, 'NULL') || ' filename ' ||
                  nvl(fp_filename, 'NULL');
    return utl_file.fopen(gv_dir, fp_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
  begin
    --intitialize
    gv_message := 'initialize';
    --get directory
    select nvl(max(ss.value), max(ss.factorydefault))
    into   gv_dir
    from   systemsetting ss
    where  ss.name = 'FINEXPORTDIRECTORY';
    --check parameter
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    if fp_statementdate is null then
      begin
        gv_message := 'the date parameter fp_statementdate cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    --write log
    write_log('Start export_aim for statement date (YYYYMMDD) ' ||
              to_char(fp_statementdate, 'YYYYMMDD') || ' to directory ' || nvl(gv_dir, 'NULL') ||
              ' filename ' || nvl(fp_filename, 'NULL'));
    --open file
    gv_filehandle := open_file;
  end initialize;

  procedure export_data is
    lv_counter      number := 0;
    lv_linenumber   number := 0;
    lv_debit_total  number := 0;
    lv_credit_total number := 0;
  
    procedure write_line(fp_export_string in varchar2) is
    begin
      --write_line
      utl_file.put(gv_filehandle, convert(fp_export_string, 'JA16SJIS', 'UTF8'));
      utl_file.new_line(gv_filehandle);
      lv_linenumber := lv_linenumber + 1; --for now just a line number..
    end write_line;
  
    procedure write_header is
    begin
      --write_header
      gv_message := 'export_data.write_header';
      /*write_line('0' || gv_separator || 'Year' || gv_separator || 'Month' || gv_separator ||
      'Account Code' || gv_separator || 'Account Name' || gv_separator ||
      'Component Code' || gv_separator || 'Component Name' || gv_separator || 'Debit' ||
      gv_separator || 'Credit' || gv_separator || 'Abstract' || gv_separator ||
      'Line Number' || gv_separator || 'D/N No.' || gv_separator || 'Delivery Date' ||
      gv_separator || 'Invoiced Date' || gv_separator || 'Amount without tax' ||
      gv_separator || 'Sales Tax' || gv_separator || 'Customer No.' || gv_separator);*/
      write_line('0' || gv_separator || '年' || gv_separator || '月' || gv_separator || '科目コード' ||
                 gv_separator || '科目名' || gv_separator || 'コンポコード' || gv_separator || 'コンポ名' ||
                 gv_separator || '借方' || gv_separator || '貸方' || gv_separator || '摘要' ||
                 gv_separator || '行番' || gv_separator || '伝票No' || gv_separator || '納品日' ||
                 gv_separator || '請求日' || gv_separator || '税抜金額' || gv_separator || '税率' ||
                 gv_separator || '消費税' || gv_separator || '顧客No' || gv_separator);
    end write_header;
  
    procedure write_footer is
    begin
      --write_footer
      gv_message := 'export_data.write_footer';
      write_line('10' || gv_separator || to_char(add_months(fp_statementdate, -1), 'YYYY') ||
                 gv_separator || to_char(add_months(fp_statementdate, -1), 'MM') || gv_separator ||
                 '84200' || gv_separator || '未払費用' || gv_separator || '9990' || gv_separator ||
                 'ゼネラル' || gv_separator || '0' || gv_separator || to_char(lv_debit_total) ||
                 gv_separator || gv_separator || lv_linenumber || gv_separator || '0' ||
                 gv_separator || gv_separator || gv_separator || '0' || gv_separator || '0' ||
                 gv_separator || '0' || gv_separator || '0' || gv_separator);
      write_line('20' || gv_separator || to_char(add_months(fp_statementdate, -1), 'YYYY') ||
                 gv_separator || to_char(add_months(fp_statementdate, -1), 'MM') || gv_separator ||
                 gv_separator || gv_separator || gv_separator || gv_separator ||
                 to_char(lv_debit_total) || gv_separator || to_char(lv_debit_total) ||
                 gv_separator || gv_separator || '0' || gv_separator || '0' || gv_separator ||
                 gv_separator || gv_separator || '0' || gv_separator || '0' || gv_separator || '0' ||
                 gv_separator || '0' || gv_separator);
    end write_footer;
  begin
    --export_data
    write_header;
    gv_message := 'export_data.write lines';
    for x in (select case il.code
                        when '111111' then
                         4
                        when 'EXPORT' then
                         5
                        else
                         case (select ilv.percentage
                           from   invoicelinevarious ilv
                           where  ilv.invoiceline_id = il.invoiceline_id)
                           when 5 then
                            1
                           when 8 then
                            2
                           when 10 then
                            3
                           else
                            6
                         end
                      end volgorde, '10' recordtype,
                     to_char(add_months(ih.invoicedate, -1), 'YYYY') start_year,
                     to_char(add_months(ih.invoicedate, -1), 'MM') start_month,
                     delto.legacycustomernumber accountcode,
                     case delto.legacycustomernumber
                        when '31316' then
                         '制服・衛生業務委託費（WEARA)'
                        when '31310' then
                         '衛生清掃費'
                        when '31312' then
                         '清掃業務委託費'
                        when '26106' then
                         '商品仕入（WEARA)'
                        when '33220' then
                         '販売促進費'
                        when '35501' then
                         '消耗品'
                        when '84200' then
                         '未払費用'
                        when '35956' then
                         '(エーム負担)制服・洗濯費'
                        when '28201' then
                         '標）商品仕入（売）'
                        else
                         'name'
                      end accountname, lpad(nvl(to_char(delto.pnnumber), '0'), 4, '0') componentcode,
                     delto.legalname conponentname,
                     case
                       when delto.taxable = 'Y' then
                        (nvl((select ilv.overamount
                             from   invoicelinevarious ilv
                             where  ilv.invoiceline_id = il.invoiceline_id), 0) +
                        nvl(case
                               when il.adjustmentreason_id is null then
                                il.amount
                               else
                                il.adjustedamount
                             end, 0))
                       else
                        iha.paythisamount
                     end debit, 0 credit, null abstract, iha.invoicenumber,
                     to_char(iha.invoicedate, 'YYYY/MM/DD') deliverydate,
                     to_char(iha.invoicedate, 'YYYY/MM/DD') invoicedate,
                     case
                       when delto.taxable = 'Y' then
                        (select ilv.overamount
                         from   invoicelinevarious ilv
                         where  ilv.invoiceline_id = il.invoiceline_id)
                       else
                        iha.paythisamount
                     end totalamountextax,
                     case il.code
                       when '111111' then
                        '不課税'
                       when 'EXPORT' then
                        '輸出免税'
                       else
                        case
                          when delto.taxable = 'Y' then
                           (select to_char(ilv.percentage) || '%'
                            from   invoicelinevarious ilv
                            where  ilv.invoiceline_id = il.invoiceline_id)
                          else
                           '輸出免税'
                        end
                     end taxpercentage,
                     case
                       when delto.taxable = 'Y' then
                        case
                          when il.adjustmentreason_id is null then
                           il.amount
                          else
                           il.adjustedamount
                        end
                       else
                        0
                     end tax, iha.deltocustomernumber
              from   invoiceheader ih
              join   customer billto
              on     billto.customer_id = ih.billtocustomer_link_id
              join   statementline stl
              on     stl.invoiceheader_id = ih.invoiceheader_id
              join   artransaction ar
              on     ar.artransaction_id = stl.artransaction_id
              join   invoiceheader iha
              on     iha.invoiceheader_id = ar.invoiceheader_id
              left   outer join invoiceline il
              on     (il.invoiceheader_id = iha.invoiceheader_id and il.invoicelinetype_id = 18)
              join   customer delto
              on     delto.customer_id = iha.deltocustomer_link_id
              where  ih.invoicedate = fp_statementdate
              and    ih.documenttype = 2 --statement
              and    iha.paythisamount <> 0
              and    delto.debtor_id in
                     (select cbi.customer_id
                       from   customerbillinginfo cbi
                       where  cbi.paybycustomer_link_id =
                              (select pb.customer_id from customer pb where pb.customernumber = 700999))
              order  by lpad(nvl(to_char(delto.pnnumber), '0'), 4, '0'), iha.deltocustomernumber,
                        iha.invoicenumber, volgorde) loop
      begin
        write_line(x.recordtype || gv_separator || x.start_year || gv_separator || x.start_month ||
                   gv_separator || x.accountcode || gv_separator || x.accountname || gv_separator ||
                   x.componentcode || gv_separator || x.conponentname || gv_separator || x.debit ||
                   gv_separator || x.credit || gv_separator || x.abstract || gv_separator ||
                   lv_linenumber || gv_separator || x.invoicenumber || gv_separator ||
                   x.deliverydate || gv_separator || x.invoicedate || gv_separator ||
                   x.totalamountextax || gv_separator || x.taxpercentage || gv_separator || x.tax ||
                   gv_separator || x.deltocustomernumber || gv_separator);
        --get totals
        lv_debit_total  := x.debit + lv_debit_total;
        lv_credit_total := x.credit + lv_credit_total;
        --count records
        lv_counter := lv_counter + 1;
      end;
    end loop;
    write_footer;
    write_log('Exported ' || to_char(lv_counter + 2) || ' lines.');
  end export_data;

  procedure finalize is
  begin
    --finalize
    close_file;
  end finalize;
  ---main procedure start export_aim
begin
  initialize;
  export_data;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
    end;
end export_aim;
/

create or replace procedure export_ministop(fp_filename in varchar2,
                                            fp_from_statementdate in date
                                            ) is
  gv_userexception exception;
  gv_message       varchar2(1000);
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_dir           systemsetting.value%type;
  gv_filehandle    utl_file.file_type;

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'export_ministop', null, fp_priority, fp_message, gv_defaultuserid);
    if fp_priority = 3 then
      write_log('export_ministop finished with errors!', 1);
    end if;
    if fp_priority > 2 then
      dbms_output.put_line(fp_message);
    end if;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_message := 'open_file directory ' || nvl(gv_dir, 'NULL') || ' filename ' ||
                  nvl(fp_filename, 'NULL');
    return utl_file.fopen(gv_dir, fp_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
  begin
    --intitialize
    gv_message := 'initialize';
    --get directory
    select nvl(max(ss.value), max(ss.factorydefault))
    into   gv_dir
    from   systemsetting ss
    where  ss.name = 'FINEXPORTDIRECTORY';
    --check parameter
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    --if fp_from_statementdate is null or fp_to_statementdate is null then --wbo date only
    if fp_from_statementdate is null then
      begin
        gv_message := 'the date parameters fp_from_statementdate and fp_to_statementdate cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    --write log
    write_log('Start export_ministop from statement date (YYYYMMDD) ' ||
              to_char(fp_from_statementdate, 'YYYYMMDD') || ' to statement date (YYYYMMDD) ' ||
             -- to_char(fp_to_statementdate, 'YYYYMMDD') ||
              ' to directory ' || nvl(gv_dir, 'NULL') ||
              ' filename ' || nvl(fp_filename, 'NULL'));
    --open file
    gv_filehandle := open_file;
  end initialize;

  procedure export_data is
    lv_counter   number := 0;
    lv_first     boolean := true;
    lv_prevpayno varchar2(5) := '';
    lv_seqnr     number := 0;
    lv_countseq  number := 0;

    procedure write_line(fp_export_string in varchar2) is
    begin
      --write_line
      utl_file.put(gv_filehandle, convert(fp_export_string, 'JA16SJIS', 'UTF8'));
      if lv_first then
        begin
          lv_first := false;
        end;
      else
        begin
          --new line every other line
          utl_file.new_line(gv_filehandle);
          lv_first := true;
        end;
      end if;
    end write_line;
  begin
    --export_data
    gv_message  := 'export_data';
    lv_countseq := 1;
    for x in
    (select
    invh.po_date_year,
    invh.po_date_month,
    invh.po_date_day,
    invh.delivery_date_year,
    invh.delivery_date_month,
    invh.delivery_date_day,
    invh.masteraccountcode,
    invh.branch_code,
    invh.large_class,
    invh.middle_class,
    invh.small_class,
    invh.code,
    invh.prodname,
    invh.spec,
    invh.order_piec,
    invh.purch_price,
    invh.selling_pr,
    invh.fill19
    from
     (select to_char(last_day(ih.invoicedate), 'YY') po_date_year,
                     --to_char(last_day(ih.invoicedate), 'MM') po_date_month,
                     case when ih.invoicedate>=to_date('01-10-2019','dd-mm-yyyy') and iha.invoicedate<to_date('01-10-2019','dd-mm-yyyy')
                      then  to_char(last_day(iha.invoicedate), 'MM')
                      else
                       to_char(last_day(ih.invoicedate), 'MM')
                      end po_date_month,
                     case when ih.invoicedate>=to_date('01-10-2019','dd-mm-yyyy') and iha.invoicedate<to_date('01-10-2019','dd-mm-yyyy')
                      then  to_char(last_day(iha.invoicedate), 'DD')
                      else
                       to_char(last_day(ih.invoicedate), 'DD')
                      end  po_date_day,
                     --to_char(last_day(ih.invoicedate), 'DD')
                     to_char(last_day(ih.invoicedate), 'YY') delivery_date_year,
                     --to_char(last_day(ih.invoicedate), 'MM') delivery_date_month,
                     --to_char(last_day(ih.invoicedate), 'DD') delivery_date_day,
                     case when ih.invoicedate>=to_date('01-10-2019','dd-mm-yyyy') and iha.invoicedate<to_date('01-10-2019','dd-mm-yyyy')
                      then  to_char(last_day(iha.invoicedate), 'MM')
                      else
                       to_char(last_day(ih.invoicedate), 'MM')
                      end delivery_date_month,
                     case when ih.invoicedate>=to_date('01-10-2019','dd-mm-yyyy') and iha.invoicedate<to_date('01-10-2019','dd-mm-yyyy')
                      then  to_char(last_day(iha.invoicedate), 'DD')
                      else
                       to_char(last_day(ih.invoicedate), 'DD')
                      end delivery_date_day,
                    lpad(to_char(billto.pnnumber), 8, '0') masteraccountcode,
                    -- lpad(substr(delto.legalname, 0, 5), 5, '0') branch_code, --wbo25-01-2011
                    --lpad(substr(billto.legalname, 0, 5), 5, '0') branch_code,
                    Case when delto.debtor_id<>billto.customer_id then
                    lpad(substr(billto.legalname, 0, 5), 5, '0')
                    else
                    lpad(substr(delto.legalname, 0, 5), 5, '0')
                    end branch_code,

                     '098' large_class,
                     '001' middle_class, '00' small_class, '996349' code,
                     to_char(iha.invoicedate, 'YYYY/MM/DD') ||  ' ﾉｳﾋﾝﾌﾞﾝ  'prodname,
                     '                    ' spec, '000001' order_piec,
                    /* lpad(to_char((iha.paythisamount -
                                   sum(nvl((select sum(ila.amount)
                                            from   invoiceline ila
                                            where  iha.invoiceheader_id = ila.invoiceheader_id
                                            and    ila.invoicelinetype_id = 18), 0)))), 6, '0') purch_price,*/ --wbo 21-02-2012
                    lpad(to_char(iha.totalamountexclvat), 6, '0') purch_price,
                     '0000000' selling_pr, '                   ' fill19
                     ,billto.legacycustomernumber
                     ,delto.customernumber
                     ,iha.invoiceheader_id
              from   invoiceheader ih, customer billto, customerbillinginfo cbi, statementline stl,
                     artransaction ar, invoiceheader iha, customer delto
              where  ih.invoicedate = fp_from_statementdate --and fp_to_statementdate
              and    ih.documenttype = 2 --statement
              and    ih.billtocustomer_link_id = billto.customer_id
              and    ih.invoiceheader_id = stl.invoiceheader_id
              and    stl.artransaction_id = ar.artransaction_id
              and    ar.invoiceheader_id = iha.invoiceheader_id
              and    iha.deltocustomer_link_id = delto.customer_id
              and    billto.customer_id = cbi.customer_id
              and    cbi.paybycustomer_link_id =
                     (select c.customer_id from customer c where c.customernumber = 710377)
              and    not exists
               /*(select 1
                      from   invoiceheader z
                      where  z.invoicedate = fp_from_statementdate --and fp_to_statementdate
                      and    z.deltocustomer_link_id = iha.deltocustomer_link_id
                      --and    z.paythisamount
                      and     z.totalamountexclvat< 0)*/
               (select 1
                      from   invoiceheader ih2, artransaction ar2, statementline stl2
                      where  ih2.invoiceheader_id=ar2.invoiceheader_id
                      and ar2.artransaction_id=stl2.artransaction_id
                      and stl2.invoiceheader_id=ih.invoiceheader_id
                      and     ih2.totalamountexclvat< 0)

              )invh


              group  by
               invh.po_date_year,
               invh.po_date_month,
               invh.po_date_day,
               invh.delivery_date_year,
               invh.delivery_date_month,
               invh.delivery_date_day,
               invh.masteraccountcode,
               invh.branch_code,
               invh.large_class,
               invh.middle_class,
               invh.small_class,
               invh.code,
               invh.prodname,
               invh.spec,
               invh.order_piec,
               invh.purch_price,
               invh.selling_pr,
               invh.fill19
               ,invh.legacycustomernumber
               ,invh.customernumber
               ,invh.invoiceheader_id
              order  by  invh.branch_code,
              invh.masteraccountcode,  invh.po_date_year,
               invh.po_date_month,
               invh.po_date_day, invh.legacycustomernumber,
                        invh.customernumber, invh.invoiceheader_id  ) loop  --wbo 2404
      begin
        x.purch_price := x.purch_price || '00';
        if lv_prevpayno <> x.branch_code then
          begin
            lv_seqnr    := 1;
            lv_countseq := lv_countseq + 1;
          end;
        else
          lv_seqnr := lv_seqnr + 1;
        end if;
        write_line(x.po_date_year || x.po_date_month || x.po_date_day || x.delivery_date_year ||
                   x.delivery_date_month || x.delivery_date_day || x.masteraccountcode ||
                   x.branch_code || substr(lpad(to_char(lv_countseq), 7, '0'), 1, 7) ||
                   substr(lpad(to_char(lv_seqnr), 2, '0'), 1, 2) || x.large_class ||
                   x.middle_class || x.small_class || x.code || x.prodname || x.spec ||
                   x.order_piec || x.purch_price || x.selling_pr || x.fill19);
        lv_prevpayno := x.branch_code;
        lv_counter   := lv_counter + 1;
      end;
    end loop;
    if not lv_first then -- WBO 1.2
      write_line(lpad(' ',128));
    end if;
    write_log('Exported ' || lv_counter || ' lines.');
  end export_data;

  procedure finalize is
  begin
    --finalize
    close_file;
  end finalize;
  ---main procedure start export_ministop
begin
  initialize;
  export_data;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
    end;
end export_ministop;
/

create or replace procedure export_nichii(fp_filename           in varchar2,
                                          fp_from_statementdate in varchar2) is --,
                                        --  fp_to_statementdate   in date default to_date('31-12-2099',
                                                                                     --   'dd-mm-yyyy')) is
  gv_userexception exception;
  gv_message       varchar2(1000);
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_dir           systemsetting.value%type;
  gv_filehandle    utl_file.file_type;
  gv_separator     varchar2(1) := ',';

--WBO 1.1 22-09-2011
--WBO 1.2 22-09-2011
--WBO 1.3 22-09-2011
--WBO 1.4 26-10-2011
--WBO 1.5 07-11-2011
--WBO 2.0 01-08-2012
--WBO 2.1 change 8.3.04
  ---internal procedure(s)
  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'export_nichii', null, fp_priority, fp_message, gv_defaultuserid);
    if fp_priority = 3 then
      write_log('export_nichii finished with errors!', 1);
    end if;
    if fp_priority > 2 then
      dbms_output.put_line(fp_message);
    end if;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_message := 'open_file directory ' || nvl(gv_dir, 'NULL') || ' filename ' ||
                  nvl(fp_filename, 'NULL');
    return utl_file.fopen(gv_dir, fp_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
  begin
    --intitialize
    gv_message := 'initialize';
    --get directory
    select nvl(max(ss.value), max(ss.factorydefault))
    into   gv_dir
    from   systemsetting ss
    where  ss.name = 'FINEXPORTDIRECTORY';
    --check parameter
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    if fp_from_statementdate is null then -- or fp_to_statementdate is null then
      begin
        gv_message := 'the date parameters fp_from_statementdate and fp_to_statementdate cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    --write log
    write_log('Start export_nichii from statement date (MMDDYYYY)) ' ||
            --  to_char(fp_from_statementdate, 'YYYYMMDD') || ' to statement date (YYYYMMDD) ' ||
            --  to_char(fp_to_statementdate, 'YYYYMMDD') || ' to directory ' || nvl(gv_dir, 'NULL') ||
             fp_from_statementdate || ' to statement date (MMDDYYYY) ' ||
              --fp_to_statementdate || 
              ' to directory ' || nvl(gv_dir, 'NULL') ||
              
              ' filename ' || nvl(fp_filename, 'NULL'));
    --open file
    gv_filehandle := open_file;
  end initialize;

  procedure export_data is
    lv_counter number := 0;
  
    procedure write_line(fp_export_string in varchar2) is
    begin
      --write_line
      utl_file.put(gv_filehandle, convert(fp_export_string, 'JA16SJIS', 'UTF8'));
      utl_file.new_line(gv_filehandle);
    end write_line;
  begin
    --export_data
    gv_message := 'export_data';
    
    write_line('計上月'||gv_separator  ||'経費タイトル'||gv_separator  ||
    '支店コード'||gv_separator  ||
       '支店名'||gv_separator  ||--1.4 added column header
    '課名'||gv_separator  || 
     '課コード'||gv_separator  ||--1.5 changed the order of the columns
       '商品コード'||gv_separator  ||'ユーザー名'|| gv_separator  ||'人数'||gv_separator  ||'税込金額の合計'||gv_separator  ||'売上額のみ'||gv_separator  ||
    '税額のみ'||gv_separator  ||'摘要'||gv_separator  ||'ロス'||gv_separator  ||'ダメージ'||gv_separator  ||'その他'||
    gv_separator  ||'請求明細No'||gv_separator  ||'納品先#');
    --1.2 WBO added header
    for x in (select to_char(ih.invoicedate,'YYYY/MM/DD') statementdate, '医事制服レンタル代' costtitle,
                     substr(billto.legacycustomernumber, 1, 3) billtolegacycustomernumber,
                     to_char(delto.pnnumber)--to_char(common.pnnumber)
                     division, --1.3 WBO removed pnumber, 1.4 added again and changed order
                     substr(max(billto.legalname), 1, 20) billtolegalname, 
                     case to_char(delto.pnnumber)--to_char(common.pnnumber)
                        when '1' then
                         '病院課'
                        when '2' then
                         'ｸﾘﾆｯｸ課'
                        else
                         to_char(delto.pnnumber)--to_char(common.pnnumber)
                      end divisionname,
                     case to_char(delto.pnnumber)--to_char(common.pnnumber)
                        when '1' then
                         '1110'
                        when '2' then
                         '1210'
                        else
                         to_char(delto.pnnumber)--to_char(common.pnnumber)
                      end productcode, common.legalname commonlegalname,
                     sum(iha.paythisamount) totalamount,
                     sum(nvl((select sum(ila.amount)
                              from   invoiceline ila
                              where  iha.invoiceheader_id = ila.invoiceheader_id
                              and    ila.invoicelinetype_id = 1), 0)) totalrent,
                     sum(round(nvl((select sum(ila.amount)
                                    from   invoiceline ila
                                    where  iha.invoiceheader_id = ila.invoiceheader_id
                                    and    ila.invoicelinetype_id = 1), 0) / 680)) appwearer,
                     sum(nvl((select sum(ila.amount)
                              from   invoiceline ila
                              where  iha.invoiceheader_id = ila.invoiceheader_id
                              and    ila.invoicelinetype_id = 18), 0)) salestax,
                     sum(nvl((select sum(ila.amount)
                              from   invoiceline ila
                              where  iha.invoiceheader_id = ila.invoiceheader_id
                              and    ila.extend = 'Y'
                              and    ila.invoicelinetype_id = 9), 0)) losscharge,
                     sum(nvl((select sum(ila.amount)
                              from   invoiceline ila
                              where  iha.invoiceheader_id = ila.invoiceheader_id
                              and    ila.invoicelinetype_id = 10), 0)) residualvaluecharge,
                     sum(nvl((select sum(ila.amount)
                              from   invoiceline ila
                              where  iha.invoiceheader_id = ila.invoiceheader_id
                              and    ila.invoicelinetype_id not in (10,9,18,1)), 0)) othercharge,         -- 1.1 added wbo
                    /* '(' || sum(round(nvl((select sum(ila.amount)
                                    from   invoiceline ila
                                    where  iha.invoiceheader_id = ila.invoiceheader_id
                                    and    ila.invoicelinetype_id = 1), 0) / 680))|| */
                     --max(delto.name) || '人分)' deltoname                            -- 1.1 added wbo sum and (              
                     max(delto.name) deltoname
                     , common.customernumber commoncustomernumber, delto.customernumber deltocustomernumber
              from   invoiceheader ih, customer billto, customerbillinginfo cbi, statementline stl,
                     artransaction ar, invoiceheader iha, customer delto
              left   outer join customer common
              on     common.customer_id = delto.commoncustomer_id
              --where  ih.invoicedate between fp_from_statementdate and fp_to_statementdate
              where  ih.invoicedate=to_date(fp_from_statementdate,' MM/DD/YYYY') --and fp_to_statementdate
              and    ih.documenttype = 2 --statement
              and    ih.billtocustomer_link_id = billto.customer_id
              and    ih.invoiceheader_id = stl.invoiceheader_id
              and    stl.artransaction_id = ar.artransaction_id
              and    ar.invoiceheader_id = iha.invoiceheader_id
              and    iha.deltocustomer_link_id = delto.customer_id
              and    billto.customer_id = cbi.customer_id
              and    cbi.paybycustomer_link_id =
                     (select c.customer_id from customer c where c.customernumber = 712480)  -- in other environment 612480
              group  by ih.invoicedate, billto.legacycustomernumber, common.pnnumber,
                        case to_char(delto.pnnumber)
                          when '1' then
                           '病院課'
                          when '2' then
                           'ｸﾘﾆｯｸ課'
                          else
                           to_char(delto.pnnumber)
                        end,
                        case to_char(delto.pnnumber)
                          when '1' then
                           '1110'
                          when '2' then
                           '1210'
                          else
                           to_char(delto.pnnumber)
                        end, common.legalname, delto.customernumber, delto.pnnumber,common.customernumber,delto.name
              order  by ih.invoicedate, billto.legacycustomernumber, common.legalname, delto.pnnumber,delto.name,
                        delto.customernumber) loop
      begin
        write_line(x.statementdate || gv_separator || x.costtitle || gv_separator ||
                   x.billtolegacycustomernumber || gv_separator ||
                  
                   x.billtolegalname || gv_separator || 
                   x.divisionname || gv_separator ||  
                   x.division || gv_separator ||  --1.3 WBO Removed, 1.4 added again and changed order with billtolegalname 1.5 changed column order
                   x.productcode || gv_separator || x.commonlegalname || gv_separator || x.appwearer || gv_separator ||
                   x.totalamount || gv_separator || x.totalrent || gv_separator 
                   || x.salestax || gv_separator || x.deltoname || '('||x.appwearer||'人分)'  || gv_separator || x.losscharge || gv_separator ||
                   x.residualvaluecharge || gv_separator  || x.othercharge || gv_separator  ||
                   x.commoncustomernumber || gv_separator || x.deltocustomernumber); -- 1.1 changed order as SR
        lv_counter := lv_counter + 1;
      end;
    end loop;
    write_log('Exported ' || lv_counter || ' lines.');
  end export_data;

  procedure finalize is
  begin
    --finalize
    close_file;
  end finalize;
  ---main procedure start export_nichii
begin
  initialize;
  export_data;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
    end;
end export_nichii;
/

create or replace procedure exportinvoices_auj_m11(fp_statementdate in char) is
  --ExportInvoices_AUJ_M11 XEROX Version 5.41
  --default values
  default_k1_15_value      varchar2(100) := 'ウェアラ株式会社';
  default_k1_16_value      varchar2(80) := '103-0007';
  default_k1_17_value      varchar2(80) := '東京都中央区日本橋浜町3-3-2';
  default_k1_18_value      varchar2(100) := 'トルナーレ日本橋浜町　8階';
  default_k1_19_value      varchar2(40) := 'TEL03-6732-0253';
  default_k1_26_value      varchar2(120) := '三井住友銀行';
  default_k1_27_value      varchar2(100) := '浅草橋支店';
  default_k1_28_value      varchar2(40) := '（当）6550238';
  default_k2_5per_value    varchar2(40) := '5％';
  default_k2_8per_value    varchar2(40) := '8％';
  default_k2_10per_value   varchar2(40) := '10％';
  default_k2_011111_value  varchar2(40) := '不課税';
  default_k2_0export_value varchar2(40) := '輸出免税';
  default_k3_5per_value    varchar2(40) := '5％税率計';
  default_k3_8per_value    varchar2(40) := '8％税率計';
  default_k3_10per_value   varchar2(40) := '10％税率計';
  default_k3_011111_value  varchar2(40) := '不課税計';
  default_k3_0export_value varchar2(40) := '輸出免税計';
  default_m1_12_value      varchar2(80) := default_k1_15_value;
  default_m2_5_value       varchar2(80) := '納品先#';
  default_m2_7_value       varchar2(80) := '納品伝票＃';
  default_m5_4b_value      varchar2(40) := '-------伝票計　（税別）-------';
  default_m5_4c_value      varchar2(40) := '-------日付計　（税別）-------';
  default_m9_5b_value      varchar2(40) := '不課税';
  default_m9_5a_value      varchar2(40) := '調整';
  default_year_value       varchar2(4) := '年';
  default_month_value      varchar2(4) := '月';
  default_day_value        varchar2(10) := '日発行';
  ---WBO Version 1. 12-09-2011
  ---WBO Version 1.1 14-09-2011
  ---WBO Version 1.2 14-09-2011
  ---WBO Version 1.3 15-09-2011
  ---WBO Version 1.4 15-09-2011
  ---WBO Version 1.5 16-09-2011
  ---PVD/WBO Version 1.6 16-09-2011
  ---WBO version 1.7 19-09-2011
  ---PVD version 1.8 19-09.2011
  ---PVD version 2.0 20-12-2011
  ---WBO version 2.1 21-12-2011
  ---PVD version 2.2 22-12-2011
  ---WBO version 2.3 27-12-2011
  ---WBO/HVH version 2.4 09-01-2012
  ---WBO version 2.5 12-01-2012
  ---WBO version 2.6 19-01-2012
  ---EBO version 3.0 27-01-2012
  --WBO version 3.1 09-02-2012
  -- WBO Version 3.2 09-02-2012
  --wbo bersion 3.3 23-02-2012
  --wb0 version 4.0 18-04-2012
  --wbo version 4.1 19-04-2012
  --wbo version 4.2  20-04-2012
  --wbo version 4.3 23-04-2012
  --pvd version 4.4 06-06-2012
  --wbo version 4.5 03-07-2012
  --wbo version 4.6 and 4.7 13-07-2012 adjusments during visit during user acceptance
  --wbo version 4.8 17-07-2012  adjustments for rent amounts (changed setup and allow neg invoices for subtotals)
  --wbo/pvd version 4.9 grouping on max(taxgroup) , max(taxtype)
  --WBO/PVD version 4.10 27-03-2014 adjustments for TAX lines
  --PVD Version 4.11 03-02-2016 ABS-21844 New address for AUJ headquarter+ABS-19285 Issue on Comment on Statement
  --date default, today's date
  --01-06-2019 version 5.01 ABS-81503 Enhancement on Xerox Interface related to tax rate changes and their display
  --21-12-2022 ABS-144663 Add customer chain code 002 and keep 000 and remove 008 in exportinvoices_auj_m11 procedure
  --13-05-2024 ABS-164339 Xerox Interface sorting logic changes
  --18-11-2024 ABS-171430 Xerox FM desc missing
  --06-01-2025 ABSN-792 AUJ Name change - Database
  --27-03-2025 ABSN-4488 Adjustment not shown on Xerox Export
  --global variables
  gv_message             varchar2(1000 char);
  gv_defaultuserid       systemuser.systemuser_id%type := 0;
  gv_dir                 systemsetting.value%type;
  gv_filename            varchar2(128);
  gv_filehandle          utl_file.file_type;
  gv_tab                 varchar2(1) := chr(9);
  gv_pageno              number := 0;
  gv_rows_count          number := 0;
  gv_m_counter           number := 0;
  gv_k_counter           number := 0;
  gv_totalamountexported number := 0;
  gv_aragingmethod       integer; --system setting ARAGINGMETHOD values are 1,2 or 3
  --exception
  gv_userexception exception;
  --main cursor for statement
  cursor gv_cur_statement is
    select h.invoiceheader_id, h.invoicedate, h.startdate, h.startyear, h.startweek, h.startmonth,
           h.invoicenumber, h.invoicebusinessunit_id, h.billtocustomer_link_id, h.billtocustomername,
           h.billtocustomernumber, h.extraname1, h.extraname2, h.zipcode, h.street, h.street2,
           h.contactpersonname,
           (select sum(x.amountexclvat) + round(sum(x.taxrate * x.amountexclvat / 100)) prebillamount
             from   v_statementline_auj x
             where  x.statementheader_id = h.invoiceheader_id
             and    x.invoicelinetype <> 18) prebillamount, he.paymenttermsduedate, h.endyear,
           h.endmonth, billto.legalname billto_legalname,
           (select max(cbc.description)
             from   customerbillingcomment cbc
             where  cbc.customer_id = h.billtocustomer_link_id
             and    cbc.type = 2
             and    to_date(fp_statementdate, 'mm/dd/yyyy') between cbc.startdate and cbc.enddate) billtocomment,
           (select sa.code from salesarea sa where sa.salesarea_id = billto.salesarea_id) salesarea,
           billto.commoncustomer_id,
           (select comc.legalname
             from   customer comc
             where  comc.customer_id = billto.commoncustomer_id) commonlegalname
    from   invoiceheader h, invoiceheaderextrainfo he, customer billto
    where  h.documenttype = 2
    and    h.invoiceheader_id = he.invoiceheader_id
    and    h.billtocustomer_link_id = billto.customer_id
    and    h.invoicedate = to_date(fp_statementdate, 'mm/dd/yyyy')
    and    billto.chain_id in
           (select ch.chain_id from chain ch where substr(ch.code, -3, 3) in ('000', '002'))
    order  by billto.customernumber, h.invoicenumber desc;
  --record for main statement cursor
  gv_rec_statement gv_cur_statement%rowtype;

  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'exportinvoices_auj', null, fp_priority, fp_message,
                             gv_defaultuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; ---no problem if we cannot show output
    end;
    if fp_priority = 3 then
      write_log('exportinvoices_auj finished with errors!', 1);
    end if;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_message := 'exportinvoices_auj.open_file ' || gv_dir || gv_filename;
    return utl_file.fopen(gv_dir, gv_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
  begin
    --initialize
    --get directory
    gv_message := 'initialize get systemsetting FINEXPORTDIRECTORY';
    select nvl(nvl(max(ss.value), max(ss.factorydefault)), 'NULL')
    into   gv_dir
    from   systemsetting ss
    where  ss.name = 'FINEXPORTDIRECTORY';
    --get gv_aragingmethod
    gv_message := 'initialize get systemsetting ARAGINGMETHOD';
    select nvl(nvl(max(ss.value), max(ss.factorydefault)), 'NULL')
    into   gv_aragingmethod
    from   systemsetting ss
    where  ss.name = 'ARAGINGMETHOD';
    --get file name
    gv_message  := 'initialize get todays date';
    gv_filename := to_char(to_date(fp_statementdate, 'mm/dd/yyyy'), 'DD') || '_S_INV.csv';
    --write log
    write_log('Start export to file ' || gv_dir || gv_filename || ' for date ' || fp_statementdate,
              1);
    --open file
    gv_filehandle := open_file;
  end initialize;

  procedure write_line(fp_line in varchar2, fp_linetype in varchar2) is
  begin
    --write_line
    utl_file.put_line(gv_filehandle, convert(fp_line, 'JA16SJIS', 'UTF8'));
    gv_rows_count := gv_rows_count + 1;
    case fp_linetype
      when 'M' then
        begin
          gv_m_counter := nvl(gv_m_counter, 0) + 1;
          if mod(gv_m_counter, 46) = 0 then
            begin
              --page count
              gv_pageno := gv_pageno + 1;
            end;
          end if;
        end;
      when 'K' then
        begin
          gv_k_counter := nvl(gv_k_counter, 0) + 1;
          if mod(gv_k_counter, 43) = 0 then
            begin
              --page count
              gv_pageno := gv_pageno + 1;
            end;
          end if;
        end;
      else
        null;
    end case;
  end write_line;

  procedure export_print_header is
  begin
    --export_header
    --field RH 1  , 1 and 2
    gv_message := 'export_print_header';
    write_line('A' || gv_tab || to_char(to_date(fp_statementdate, 'mm/dd/yyyy'), 'YYYYMMDD'), 'A');
  end export_print_header;

  procedure export_one_statement is
    lv_k_tab                varchar2(2) := 'K' || gv_tab;
    lv_m_tab                varchar2(2) := 'M' || gv_tab;
    lv_inv_tab              varchar2(64) := to_char(gv_rec_statement.invoicenumber) || gv_tab;
    lv_string               varchar2(1024);
    lv_arrayerror           varchar2(64) := ' is too high!';
    lv_collectresponsible   employee.employeenumber%type;
    lv_money_received_month number;
    lv_plant_name           plant.name%type;
    type assoc_array is table of number index by binary_integer;
    customer_k2_9_array assoc_array;
  
    function get_money_received_month(fp_invoicedate            in invoiceheader.invoicedate%type,
                                      fp_billtocustomer_link_id in invoiceheader.billtocustomer_link_id%type)
      return number is
      lv_money_received_month artransaction.amount%type;
    begin
      --get_money_received_month this month
      gv_message := 'get_money_received_month this month';
      --artransactiontype_id = 5 credit, over all BU's!
      select sum(a.amount)
      into   lv_money_received_month
      from   artransaction a
      where  a.artransactiontype_id = 5
      and    a.debitcredit = 'C'
      and    a.billtocustomer_link_id = fp_billtocustomer_link_id
      and    a.artransactiondate < fp_invoicedate
      and    a.artransactiondate >= (select max(xh.invoicedate)
                                     from   invoiceheader xh
                                     where  xh.documenttype = 2
                                     and    xh.billtocustomer_link_id = fp_billtocustomer_link_id
                                     and    xh.invoicedate < fp_invoicedate);
      return nvl(lv_money_received_month, 0);
    exception
      when no_data_found then
        return 0;
    end get_money_received_month;
  
    procedure export_frontpage is
      lv_k2_7_total    number := 0;
      lv_k2_8_total    number := 0;
      lv_k2_9_total    number := 0;
      lv_plant_street  address.street%type;
      lv_plant_street2 address.street2%type;
      lv_plant_zipcode address.zipcode%type;
      lv_plant_city    address.city%type;
      lv_plant_phoneno plant.phoneno%type;
    
      procedure get_collectresponsible_empl(fp_customerid in customer.customer_id%type) is
      begin
        --get_collectresponsible_empl
        gv_message := 'get_collectresponsible_empl for customer id ' || fp_customerid;
        select min(e.employeenumber)
        into   lv_collectresponsible
        from   customerbillinginfo cb, employee e
        where  cb.collectionresponsible_id = e.employee_id
        and    cb.customer_id = fp_customerid;
      exception
        when no_data_found then
          lv_collectresponsible := null;
      end get_collectresponsible_empl;
    
      procedure get_bu_plant_info(fp_businessunitid in businessunit.businessunit_id %type,
                                  fp_street         out address.street%type,
                                  fp_street2        out address.street%type,
                                  fp_zipcode        out address.zipcode%type,
                                  fp_city           out address.city%type,
                                  fp_plant_phoneno  out plant.phoneno%type,
                                  fp_plant_name     out plant.name%type) is
      begin
        --get_bu_plant_info
        select a.street, a.street2, a.zipcode, a.city, pt.phoneno, pt.name
        into   fp_street, fp_street2, fp_zipcode, fp_city, fp_plant_phoneno, fp_plant_name
        from   businessunit bu, plant pt, address a
        where  bu.businessunit_id = fp_businessunitid
        and    bu.plant_id = pt.plant_id
        and    pt.address_id = a.address_id;
      exception
        when others then
          begin
            gv_message := 'Error get_bu_plant_info get_address_bu_plant for bu id ' ||
                          fp_businessunitid;
            raise;
          end;
      end get_bu_plant_info;
    
      procedure write_k1 is
      begin
        --write_k1
        gv_message := 'write_k1';
        lv_string  := null;
        gv_pageno  := 1;
        for lv_pos in 1 .. 32 loop
          begin
            gv_message := 'write_k1 position = ' || to_char(lv_pos);
            case lv_pos
              when 1 then
                lv_string := lv_k_tab;
              when 2 then
                lv_string := lv_string || '1' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                lv_string := lv_string || to_char(gv_rec_statement.endyear) || gv_tab;
              when 5 then
                lv_string := lv_string || to_char(gv_rec_statement.endmonth) || gv_tab;
              when 6 then
                lv_string := lv_string || to_char(gv_rec_statement.invoicedate, 'YYYY') ||
                             default_year_value || to_char(gv_rec_statement.invoicedate, 'MM') ||
                             default_month_value || to_char(gv_rec_statement.invoicedate, 'DD') ||
                             default_day_value || gv_tab;
              
              when 7 then
                lv_string := lv_string || to_char(gv_rec_statement.invoicenumber) || gv_tab;
              when 8 then
                lv_string := lv_string || gv_rec_statement.zipcode || gv_tab;
              when 9 then
                lv_string := lv_string || gv_rec_statement.street || gv_tab;
              when 10 then
                lv_string := lv_string || gv_rec_statement.street2 || gv_tab;
              when 11 then
                lv_string := lv_string || gv_rec_statement.billto_legalname || gv_tab;
              when 12 then
                null;
              when 13 then
                null;
              when 14 then
                if (gv_rec_statement.contactpersonname = '-') or
                   (gv_rec_statement.contactpersonname = '0') then
                  lv_string := lv_string || ' ' || gv_tab;
                else
                  lv_string := lv_string || gv_rec_statement.contactpersonname || gv_tab;
                end if;
              when 15 then
                lv_string := lv_string || default_k1_15_value || gv_tab;
              when 16 then
                lv_string := lv_string || default_k1_16_value || gv_tab;
              when 17 then
                lv_string := lv_string || default_k1_17_value || gv_tab;
              when 18 then
                lv_string := lv_string || default_k1_18_value || gv_tab;
              when 19 then
                lv_string := lv_string || default_k1_19_value || gv_tab;
              when 20 then
                null;
              when 21 then
                null;
              when 22 then
                null;
              when 23 then
                lv_string := lv_string ||
                             trim(to_char(gv_rec_statement.prebillamount, '999,999,999,999,999')) ||
                             gv_tab;
              when 24 then
                null;
              when 25 then
                lv_string := lv_string ||
                             to_char(gv_rec_statement.paymenttermsduedate, 'YYYY/MM/DD') || gv_tab;
              when 26 then
                lv_string := lv_string || default_k1_26_value || gv_tab;
              when 27 then
                lv_string := lv_string || default_k1_27_value || gv_tab;
              when 28 then
                lv_string := lv_string || default_k1_28_value || gv_tab;
              when 29 then
                lv_string := lv_string || replace(gv_rec_statement.billtocomment, chr(10), ' ') ||
                             gv_tab;
              when 30 then
                lv_string := lv_string || 'page ' || to_char(gv_pageno) || gv_tab;
              when 31 then
                lv_string := lv_string || 'C#' || gv_rec_statement.salesarea || gv_tab;
              when 32 then
                lv_string := lv_string || gv_rec_statement.billtocustomernumber;
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'K');
      end write_k1;
    
      procedure write_k1_condensed is
      begin
        --write_k1
        gv_message := 'write_k1_condensed';
        lv_string  := null;
        for lv_pos in 1 .. 32 loop
          begin
            gv_message := 'write_k1 position = ' || to_char(lv_pos);
            case lv_pos
              when 1 then
                lv_string := lv_k_tab;
              when 2 then
                lv_string := lv_string || '1' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                lv_string := lv_string || to_char(gv_rec_statement.endyear) || gv_tab;
              when 5 then
                lv_string := lv_string || to_char(gv_rec_statement.endmonth) || gv_tab;
              when 6 then
                lv_string := lv_string || to_char(gv_rec_statement.invoicedate, 'YYYY') ||
                             default_year_value || to_char(gv_rec_statement.invoicedate, 'MM') ||
                             default_month_value || to_char(gv_rec_statement.invoicedate, 'DD') ||
                             default_day_value || gv_tab;
              when 7 then
                lv_string := lv_string || to_char(gv_rec_statement.invoicenumber) || gv_tab;
              when 8 then
                lv_string := lv_string || gv_rec_statement.zipcode || gv_tab;
              when 9 then
                lv_string := lv_string || gv_rec_statement.street || gv_tab;
              when 10 then
                lv_string := lv_string || gv_rec_statement.street2 || gv_tab;
              when 11 then
                lv_string := lv_string || gv_rec_statement.billto_legalname || gv_tab;
              when 12 then
                null;
              when 13 then
                null;
              when 14 then
                if (gv_rec_statement.contactpersonname = '-') or
                   (gv_rec_statement.contactpersonname = '0') then
                  lv_string := lv_string || ' ' || gv_tab;
                else
                  lv_string := lv_string || gv_rec_statement.contactpersonname || gv_tab;
                end if;
              when 15 then
                lv_string := lv_string || default_k1_15_value || gv_tab;
              when 16 then
                lv_string := lv_string || gv_tab;
              when 17 then
                lv_string := lv_string || gv_tab;
              when 18 then
                lv_string := lv_string || gv_tab;
              when 19 then
                lv_string := lv_string || gv_tab;
              when 20 then
                null;
              when 21 then
                null;
              when 22 then
                null;
              when 23 then
                lv_string := lv_string || gv_tab;
              when 24 then
                lv_string := lv_string || gv_tab;
              when 25 then
                lv_string := lv_string || gv_tab;
              when 26 then
                lv_string := lv_string || gv_tab;
              when 27 then
                lv_string := lv_string || gv_tab;
              when 28 then
                lv_string := lv_string || gv_tab;
              when 29 then
                null;
              when 30 then
                lv_string := lv_string || 'page ' || to_char(gv_pageno) || gv_tab;
              when 31 then
                lv_string := lv_string || 'C#' || gv_rec_statement.salesarea || gv_tab;
              when 32 then
                lv_string := lv_string || gv_rec_statement.billtocustomernumber;
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'K');
      end write_k1_condensed;
    
      procedure write_k2 is
        lv_taxcode varchar2(40);
      
        procedure write_k2_line(k2_5     in varchar2,
                                k2_6     in varchar2,
                                k2_7     in number,
                                pnnumber in varchar2) is
        
        begin
          --write_k2
          gv_message := 'write_k2';
          lv_string  := null;
          for lv_pos in 1 .. 8 loop
            begin
              gv_message := 'write_k2 position = ' || to_char(lv_pos);
              case lv_pos
                when 1 then
                  lv_string := lv_k_tab;
                when 2 then
                  lv_string := lv_string || '2' || gv_tab;
                when 3 then
                  lv_string := lv_string || lv_inv_tab;
                when 4 then
                  null;
                when 5 then
                  -- field 5 constists of field 5 and field 5_1, thats in k2_5!
                  lv_string := lv_string || k2_5 || gv_tab || pnnumber || gv_tab;
                when 6 then
                  lv_string := lv_string || k2_6 || gv_tab;
                when 7 then
                  lv_string     := lv_string || trim(to_char(k2_7, '999,999,999,999,999')) ||
                                   gv_tab;
                  lv_k2_7_total := lv_k2_7_total + k2_7;
                when 8 then
                  lv_string := lv_string || lv_taxcode || gv_tab || gv_tab;
                else
                  gv_message := gv_message || lv_arrayerror;
                  raise gv_userexception;
              end case;
            end;
          end loop; --lv_pos
          write_line(lv_string, 'K');
          if (mod(gv_k_counter, 43) = 0) then
            begin
              write_k1_condensed;
            end;
          end if;
        end write_k2_line;
      
        function get_k2_value(fp_customer in number) return number is
        begin
          return customer_k2_9_array(fp_customer);
        exception
          when others then
            return 0;
        end get_k2_value;
      begin
        --write_k2_loop
        for sh in (select x.commoncustomer_number, x.commoncustomer_name,
                          case
                            when x.pnnumber = 0 then
                             null
                            else
                             x.pnnumber
                          end pnnumber,
                          case x.taxgroupcode
                             when 'YZ08' then
                              'XXX'
                             else
                              x.taxgroupcode
                           end taxgroupcode, x.taxrate, sum(x.amountexclvat) amountexclvat,
                          sum(x.vatamount) vatamount, sum(x.amount) amount,
                          case (case x.taxgroupcode
                              when 'YZ08' then
                               'XXX'
                              else
                               x.taxgroupcode
                            end)
                             when null then
                              x.taxrate
                             when 'EXPORT' then
                              99
                             when '111111' then
                              98
                             else
                              x.taxrate
                           end sortingorder
                   from   v_statementline_auj x
                   where  x.statementheader_id = gv_rec_statement.invoiceheader_id
                   and    x.invoicelinetype <> 18
                   group  by x.commoncustomer_number, x.commoncustomer_name, x.pnnumber,
                             case x.taxgroupcode
                               when 'YZ08' then
                                'XXX'
                               else
                                x.taxgroupcode
                             end, x.taxrate
                   order  by lpad(x.pnnumber, 20, '0'), x.commoncustomer_number,
                             x.commoncustomer_name,
                             case (case x.taxgroupcode
                                when 'YZ08' then
                                 'XXX'
                                else
                                 x.taxgroupcode
                              end)
                               when null then
                                x.taxrate
                               when 'EXPORT' then
                                99
                               when '111111' then
                                98
                               else
                                x.taxrate
                             end) loop
          begin
            lv_taxcode := (case
                            when sh.taxgroupcode = '111111' then
                             default_k2_011111_value
                            when nvl(sh.taxgroupcode, 'EXPORT') = 'EXPORT' then
                             default_k2_0export_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 8 then
                             default_k2_8per_value
                            when sh.taxrate = 5 then
                             default_k2_5per_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 10 then
                             default_k2_10per_value
                            else
                             null
                          end);
            customer_k2_9_array(sh.commoncustomer_number) := sh.amountexclvat +
                                                             get_k2_value(sh.commoncustomer_number);
            write_k2_line(sh.commoncustomer_number, sh.commoncustomer_name, sh.amountexclvat,
                          sh.pnnumber);
          end;
        end loop; --sh
      end write_k2;
    
      procedure write_k3 is
        lv_taxcode  varchar2(40);
        lv_taxdesc  varchar2(40);
        lv_k2_7_sum number := 0;
        lv_k2_8_sum number := 0;
        lv_k2_9_sum number := 0;
      
        procedure write_k3_line is
        begin
          --write_k3_line
          gv_message := 'write_k3';
          lv_string  := null;
          for lv_pos in 1 .. 8 loop
            begin
              gv_message := 'write_k3 position = ' || to_char(lv_pos);
              case lv_pos
                when 1 then
                  lv_string := lv_k_tab;
                when 2 then
                  lv_string := lv_string || '3' || gv_tab;
                when 3 then
                  lv_string := lv_string || lv_inv_tab;
                when 4 then
                  lv_string := lv_string || lv_taxdesc || gv_tab;
                when 5 then
                  lv_string := lv_string || trim(to_char(lv_k2_7_total, '999,999,999,999,999')) ||
                               gv_tab;
                when 6 then
                  lv_string := lv_string || lv_taxcode || gv_tab;
                when 7 then
                  lv_string := lv_string || trim(to_char(lv_k2_8_total, '999,999,999,999,999')) ||
                               gv_tab;
                when 8 then
                  lv_string := lv_string || trim(to_char(lv_k2_9_total, '999,999,999,999,999'));
                else
                  gv_message := gv_message || lv_arrayerror;
                  raise gv_userexception;
              end case;
            end;
          end loop; --lv_pos
          write_line(lv_string, 'K');
          if (mod(gv_k_counter, 43) = 0) then
            begin
              write_k1_condensed;
            end;
          end if;
        end write_k3_line;
      
      begin
        --write_k3
        for sh in (select case nvl(x.taxgroupcode, 'EXPORT')
                             when 'YZ08' then
                              'XXX'
                             else
                              nvl(x.taxgroupcode, 'EXPORT')
                           end taxgroupcode, x.taxrate, sum(x.amountexclvat) amountexclvat,
                          sum(x.vatamount) vatamount, sum(x.amount) amount,
                          case (case nvl(x.taxgroupcode, 'EXPORT')
                              when 'YZ08' then
                               'XXX'
                              else
                               nvl(x.taxgroupcode, 'EXPORT')
                            end)
                             when null then
                              x.taxrate
                             when 'EXPORT' then
                              99
                             when '111111' then
                              98
                             else
                              x.taxrate
                           end sortingorder
                   from   v_statementline_auj x
                   where  x.statementheader_id = gv_rec_statement.invoiceheader_id
                   group  by case nvl(x.taxgroupcode, 'EXPORT')
                               when 'YZ08' then
                                'XXX'
                               else
                                nvl(x.taxgroupcode, 'EXPORT')
                             end, x.taxrate
                   order  by case (case nvl(x.taxgroupcode, 'EXPORT')
                                when 'YZ08' then
                                 'XXX'
                                else
                                 nvl(x.taxgroupcode, 'EXPORT')
                              end)
                               when null then
                                x.taxrate
                               when 'EXPORT' then
                                99
                               when '111111' then
                                98
                               else
                                x.taxrate
                             end) loop
          begin
            lv_k2_7_total := sh.amountexclvat;
            lv_k2_8_total := round(sh.taxrate * sh.amountexclvat / 100);
            lv_k2_9_total := lv_k2_8_total + sh.amountexclvat;
            lv_k2_7_sum   := lv_k2_7_sum + lv_k2_7_total;
            lv_k2_8_sum   := lv_k2_8_sum + lv_k2_8_total;
            lv_k2_9_sum   := lv_k2_8_sum + lv_k2_7_sum;
            lv_taxcode := (case
                            when sh.taxgroupcode = '111111' then
                             default_k2_011111_value
                            when nvl(sh.taxgroupcode, 'EXPORT') = 'EXPORT' then
                             default_k2_0export_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 8 then
                             default_k2_8per_value
                            when sh.taxrate = 5 then
                             default_k2_5per_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 10 then
                             default_k2_10per_value
                            else
                             null
                          end);
            lv_taxdesc := (case
                            when sh.taxgroupcode = '111111' then
                             default_k3_011111_value
                            when nvl(sh.taxgroupcode, 'EXPORT') = 'EXPORT' then
                             default_k3_0export_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 8 then
                             default_k3_8per_value
                            when sh.taxrate = 5 then
                             default_k3_5per_value
                            when sh.taxgroupcode = 'XXX' and sh.taxrate = 10 then
                             default_k3_10per_value
                            else
                             null
                          end);
            write_k3_line;
          end;
        end loop; --sh
        --write k3 total line
        lv_k2_7_total          := lv_k2_7_sum;
        lv_k2_8_total          := lv_k2_8_sum;
        lv_k2_9_total          := lv_k2_9_sum;
        gv_totalamountexported := gv_totalamountexported + lv_k2_9_total;
        lv_taxdesc             := '合計';
        lv_taxcode             := null;
        write_k3_line;
      end write_k3;
    
      procedure write_k4 is
      begin
        --write_k4
        gv_message := 'write_k4';
        while mod(gv_k_counter, 43) <> 0 loop
          begin
            gv_message := 'write_k4 counter = ' || to_char(gv_k_counter);
            write_line(lv_k_tab || '4' || gv_tab || gv_rec_statement.invoicenumber, 'K');
          end;
        end loop; --gv_k_counter
      end write_k4;
    begin
      --clear array
      for i in 1 .. customer_k2_9_array.count loop
        customer_k2_9_array.delete(i);
      end loop;
      --export_statementheader
      gv_message := 'export_frontpage invoice number ' || gv_rec_statement.invoicenumber;
      get_bu_plant_info(gv_rec_statement.invoicebusinessunit_id, lv_plant_street, lv_plant_street2,
                        lv_plant_zipcode, lv_plant_city, lv_plant_phoneno, lv_plant_name);
      write_k1;
      write_k2;
      write_k3;
      write_k4;
    end export_frontpage;
  
    procedure export_invoicelines is
      lv_tax_count          number := 0;
      lv_totalamountexclvat number := 0; --for one statements invoice
      lv_paythisamount      number := 0; --for one statments invoice
    
      --cursor for detail invoices of statement
      cursor lv_cur_detailinv is
        select a.invoiceheader_id, a.artransactiondate, a.invoicenumber artrans_invoiceno,
               h.invoicenumber, h.deltocustomernumber, h.deltocustomername, h.routenumber,
               h.prebillamount, h.contactpersonname, h.extraname1,
               h.totalamountexclvat paythisamount, h.totalamountexclvat,
               common.customernumber commoncustomernumber, common.pnnumber commonpnnumber,
               h.billtocustomernumber, h.invoicedate, common.legalname common_legalname
        from   statementline l
        join   artransaction a
        on     l.artransaction_id = a.artransaction_id
        join   customer delto
        inner  join customer common
        on     coalesce(delto.commoncustomer_id, delto.debtor_id) = common.customer_id on
         coalesce(a.deltocustomer_link_id, a.billtocustomer_link_id) = delto.customer_id
        join   invoiceheader h
        on     a.invoiceheader_id = h.invoiceheader_id
        where  l.invoiceheader_id = gv_rec_statement.invoiceheader_id
        order  by lpad(common.pnnumber, 20, '0'), common.customernumber, h.billtocustomernumber, 13,
                  h.invoicedate, delto.customernumber, a.invoicenumber asc;
      --record definition of above cursor
      lv_rec_detailinv lv_cur_detailinv%rowtype;
      --cursor for invoice lines of detail invoices of statement
      cursor lv_cur_x is
      --record definition of above cursor
      -- rent garments
      -- WBO CHange 4.6 to remove not charged amounts during delivery days
        select sorto, deltocustomer_link_id, cast(invlinecode as varchar2(30)) invlinecode,
               invlinedesc, price, sum(amount) amount, typeofmerchandise, max(sizecode) sizecode,
               max(finishingmethoddescription) finishingmethoddescription, sum(billedqty) billedqty,
               sum(deliveredqty) deliveredqty, max(ilp_timestamp) ilp_timestamp, invoicelinetype_id,
               product_id, sizedefinition_id, finishingmethod_id, taxgroupcode, taxtype, delscheme,
               sum(numberofwearers) numberofwearers, invlinetype_desc, reasoncode, null overamount,
               taxrate, max(nvl(rensum.sequencenumber, 99999)) sizesequencenumber
        from   (select 1 sorto, ih.deltocustomer_link_id, il.code invlinecode,
                        il.description invlinedesc, il.price,
                        sum(case
                              when il.extend = 'Y' then
                               case
                                 when il.adjustmentreason_id is null then
                                  il.amount
                                 else
                                  il.adjustedamount
                               end
                              else
                               0
                            end) amount,
                        (select p.typeofmerchandise
                          from   product p
                          where  p.product_id = ilp.product_link_id) typeofmerchandise, null sizecode,
                        max(coalesce(trim(ilp.finishingmethoddescription),
                                      (select fd.description
                                        from   finishingmethod_desc fd
                                        where  fd.finishingmethod_id = ilp.finishingmethod_id
                                        and    fd.language_id = billto.language_id),
                                      ilp.finishingmethodcode)) finishingmethoddescription,
                        (il.billedqty + il.adjustmentbilledqty) billedqty, null deliveredqty,
                        max(ilp.timestamp) ilp_timestamp, il.invoicelinetype_id,
                        ilp.product_link_id product_id, null sizedefinition_id, ilp.finishingmethod_id,
                        il.taxgroupcode, il.taxtype,
                        coalesce(substr(ilp.deliveryschemecode, 1, 2),
                                  (select min(substr(s.code, 1, 2))
                                    from   customerdeliveryscheme ds, deliveryscheme s
                                    where  ds.customer_id = ih.deltocustomer_link_id
                                    and    ds.deliveryscheme_id = s.deliveryscheme_id)) delscheme,
                        count(distinct ilp.wearernumber) numberofwearers,
                        max((select ilvd.description
                             from   invoicelinetype_desc ilvd
                             where  ilvd.invoicelinetype_id = il.invoicelinetype_id
                             and    ilvd.language_id = billto.language_id)) invlinetype_desc,
                        max((select rd.description
                             from   reasoncode_desc rd
                             where  rd.reasoncode_id = il.adjustmentreason_id
                             and    rd.language_id = billto.language_id)) reasoncode,
                        coalesce(ilv.percentage, 0) taxrate, max(ps.sequencenumber) sequencenumber
                 from   invoiceheader ih
                 join   invoiceline il
                 on     il.invoiceheader_id = ih.invoiceheader_id
                 left   outer join invoicelineproduct ilp
                 on     ilp.invoiceline_id = il.invoiceline_id
                 left   join productsize ps
                 on     ps.product_id = ilp.product_link_id
                 and    ps.sizedefinition_id = ilp.sizedefinition_link_id
                 left   outer join invoicelinevarious ilv
                 on     ilv.invoiceline_id = il.invoiceline_id
                 join   customer billto
                 on     billto.customer_id = ih.billtocustomer_link_id
                 where  ih.invoiceheader_id = lv_rec_detailinv.invoiceheader_id
                 and    il.invoicelinetype_id = 1
                 and    exists (select p.typeofmerchandise
                         from   product p
                         where  p.product_id = ilp.product_link_id
                         and    p.typeofmerchandise = 2)
                 group  by ih.deltocustomer_link_id, il.code, il.description, il.price,
                           il.invoicelinetype_id, ilp.product_link_id, ilp.finishingmethod_id,
                           il.taxgroupcode, il.taxtype, ilp.deliveryschemecode, il.extend,
                           ilv.percentage, (il.billedqty + il.adjustmentbilledqty),
                           ps.sizedefinition_id) rensum
        group  by sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, typeofmerchandise,
                  invoicelinetype_id, product_id, sizedefinition_id, finishingmethod_id,
                  taxgroupcode, taxtype, delscheme, invlinetype_desc, reasoncode, taxrate
        union all
        --rent non garments
        select sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, sum(amount) amount,
               typeofmerchandise, sizecode,
               max(finishingmethoddescription) finishingmethoddescription, sum(billedqty) billedqty,
               sum(deliveredqty) deliveredqty, ilp_timestamp, invoicelinetype_id, product_id,
               sizedefinition_id, finishingmethod_id, taxgroupcode, taxtype, delscheme,
               count(wearernumber) numberofwearers, max(invlinetype_desc) invlinetype_desc,
               max(reasoncode) reasoncode, null overamount, taxrate,
               max(nvl(x.sequencenumber, 99999)) sizesequencenumber
        from   (select 2 sorto, ih.deltocustomer_link_id, il.code invlinecode,
                        il.description invlinedesc, il.price,
                        case
                          when il.extend = 'Y' then
                           case
                             when il.adjustmentreason_id is null then
                              il.amount
                             else
                              il.adjustedamount
                           end
                          else
                           0
                        end amount,
                        (select p.typeofmerchandise
                          from   product p
                          where  p.product_id = ilp.product_link_id) typeofmerchandise, ilp.sizecode,
                        coalesce(trim(ilp.finishingmethoddescription),
                                  (select fd.description
                                    from   finishingmethod_desc fd
                                    where  fd.finishingmethod_id = ilp.finishingmethod_id
                                    and    fd.language_id = billto.language_id), ilp.finishingmethodcode) finishingmethoddescription,
                        null billedqty,
                        case
                          when il.adjustmentreason_id is null then
                           il.billedqty
                          else
                           il.adjustmentbilledqty + il.billedqty
                        end deliveredqty, ilp.timestamp ilp_timestamp, il.invoicelinetype_id,
                        ilp.product_link_id product_id, ilp.sizedefinition_link_id sizedefinition_id,
                        ilp.finishingmethod_id, il.taxgroupcode, il.taxtype,
                        coalesce(substr(ilp.deliveryschemecode, 1, 2),
                                  (select min(substr(s.code, 1, 2))
                                    from   customerdeliveryscheme ds, deliveryscheme s
                                    where  ds.customer_id = ih.deltocustomer_link_id
                                    and    ds.deliveryscheme_id = s.deliveryscheme_id)) delscheme,
                        ilp.wearernumber,
                        (select ilvd.description
                          from   invoicelinetype_desc ilvd
                          where  ilvd.invoicelinetype_id = il.invoicelinetype_id
                          and    ilvd.language_id = billto.language_id) invlinetype_desc,
                        (select rd.description
                          from   reasoncode_desc rd
                          where  rd.reasoncode_id = il.adjustmentreason_id
                          and    rd.language_id = billto.language_id) reasoncode,
                        coalesce(ilv.percentage, 0) taxrate, ps.sequencenumber
                 from   invoiceheader ih
                 join   invoiceline il
                 on     il.invoiceheader_id = ih.invoiceheader_id
                 left   outer join invoicelineproduct ilp
                 on     ilp.invoiceline_id = il.invoiceline_id
                 left   join productsize ps
                 on     ps.product_id = ilp.product_link_id
                 and    ps.sizedefinition_id = ilp.sizedefinition_link_id
                 left   outer join invoicelinevarious ilv
                 on     ilv.invoiceline_id = il.invoiceline_id
                 join   customer billto
                 on     billto.customer_id = ih.billtocustomer_link_id
                 where  ih.invoiceheader_id = lv_rec_detailinv.invoiceheader_id
                 and    il.invoicelinetype_id = 1
                 and    il.extend = 'Y'
                 and    not exists (select p.typeofmerchandise
                         from   product p
                         where  p.product_id = ilp.product_link_id
                         and    p.typeofmerchandise = 2)) x
        -- 09-01-2012 wbo added supress rule rental non garment
        where  x.delscheme = '01'
        or     (x.delscheme <> '01' and x.amount > 0)
        or     (x.delscheme <> '01' and x.amount = 0 and x.deliveredqty > 0)
        group  by sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, typeofmerchandise,
                  sizecode, ilp_timestamp, invoicelinetype_id, product_id, sizedefinition_id,
                  finishingmethod_id, taxgroupcode, taxtype, delscheme, taxrate
        union all
        --others
        select sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, sum(amount) amount,
               typeofmerchandise, sizecode,
               max(finishingmethoddescription) finishingmethoddescription, sum(billedqty) billedqty,
               sum(deliveredqty) deliveredqty, ilp_timestamp, invoicelinetype_id, product_id,
               sizedefinition_id, finishingmethod_id, taxgroupcode, taxtype, delscheme,
               count(wearernumber) numberofwearers, max(invlinetype_desc) invlinetype_desc,
               max(reasoncode) reasoncode, sum(x.overamount) overamount, taxrate,
               max(nvl(x.sequencenumber, 99999)) sizesequencenumber
        from   (select 3 + invoicelinetype_id + case
                          when invoicelinetype_id in (15, 18) then
                           (case (case nvl(il.code, 'EXPORT')
                               when 'YZ08' then
                                'XXX'
                               else
                                nvl(il.code, 'EXPORT')
                             end)
                             when null then
                              coalesce(ilv.percentage, 0)
                             when 'EXPORT' then
                              99
                             when '111111' then
                              98
                             else
                              coalesce(ilv.percentage, 0)
                           end)
                          else
                           0
                        end sorto, ih.deltocustomer_link_id, il.code invlinecode,
                        il.description invlinedesc, il.price,
                        case
                          when il.adjustmentreason_id is null then
                           il.amount
                          else
                           il.adjustedamount
                        end amount,
                        (select p.typeofmerchandise
                          from   product p
                          where  p.product_id = ilp.product_link_id) typeofmerchandise, ilp.sizecode,
                        coalesce(trim(ilp.finishingmethoddescription),
                                  (select fd.description
                                    from   finishingmethod_desc fd
                                    where  fd.finishingmethod_id = ilp.finishingmethod_id
                                    and    fd.language_id = billto.language_id), ilp.finishingmethodcode) finishingmethoddescription,
                        null billedqty,
                        case
                          when il.adjustmentreason_id is null then
                           il.billedqty
                          else
                           il.adjustmentbilledqty + il.billedqty
                        end deliveredqty, ilp.timestamp ilp_timestamp, il.invoicelinetype_id,
                        ilp.product_link_id product_id, ilp.sizedefinition_link_id sizedefinition_id,
                        ilp.finishingmethod_id,
                        case
                          when il.invoicelinetype_id = 18 then
                           il.code
                          else
                           il.taxgroupcode
                        end taxgroupcode, il.taxtype,
                        coalesce(substr(ilp.deliveryschemecode, 1, 2),
                                  (select min(substr(s.code, 1, 2))
                                    from   customerdeliveryscheme ds, deliveryscheme s
                                    where  ds.customer_id = ih.deltocustomer_link_id
                                    and    ds.deliveryscheme_id = s.deliveryscheme_id)) delscheme,
                        ilp.wearernumber,
                        (select ilvd.description
                          from   invoicelinetype_desc ilvd
                          where  ilvd.invoicelinetype_id = il.invoicelinetype_id
                          and    ilvd.language_id = billto.language_id) invlinetype_desc,
                        (select rd.description
                          from   reasoncode_desc rd
                          where  rd.reasoncode_id = il.adjustmentreason_id
                          and    rd.language_id = billto.language_id) reasoncode, ilv.overamount,
                        coalesce(ilv.percentage, 0) taxrate, ps.sequencenumber
                 from   invoiceheader ih
                 join   invoiceline il
                 on     il.invoiceheader_id = ih.invoiceheader_id
                 left   outer join invoicelineproduct ilp
                 on     ilp.invoiceline_id = il.invoiceline_id
                 left   join productsize ps
                 on     ps.product_id = ilp.product_link_id
                 and    ps.sizedefinition_id = ilp.sizedefinition_link_id
                 left   outer join invoicelinevarious ilv
                 on     ilv.invoiceline_id = il.invoiceline_id
                 join   customer billto
                 on     billto.customer_id = ih.billtocustomer_link_id
                 where  ih.invoiceheader_id = lv_rec_detailinv.invoiceheader_id
                 and    il.extend = 'Y'
                 and    il.invoicelinetype_id <> 1
                 and    not (il.invoicelinetype_id = 9 and il.invoicelinesubtype = 16) --skip 16=Loss Credit
                 and    ((il.amount <> 0 or il.adjustedamount <> 0) or
                       ilp.finishingmethod_id =
                       (select fim.finishingmethod_id
                          from   finishingmethod fim
                          where  fim.code = 'COG') or il.invoicelinetype_id = 18)) x
        group  by sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, typeofmerchandise,
                  sizecode, ilp_timestamp, invoicelinetype_id, product_id, sizedefinition_id,
                  finishingmethod_id, taxgroupcode, taxtype, delscheme, taxrate
        union all
        --16=Loss Credit
        select sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, sum(amount) amount,
               typeofmerchandise, sizecode,
               max(finishingmethoddescription) finishingmethoddescription, sum(billedqty) billedqty,
               sum(deliveredqty) deliveredqty, ilp_timestamp, invoicelinetype_id, product_id,
               sizedefinition_id, max(finishingmethod_id) finishingmethod_id, taxgroupcode, taxtype,
               delscheme, count(wearernumber) numberofwearers,
               max(invlinetype_desc) invlinetype_desc, max(reasoncode) reasoncode,
               sum(x.overamount) overamount, taxrate,
               max(nvl(x.sequencenumber, 99999)) sizesequencenumber
        from   (select (3 + il.invoicelinetype_id) sorto, ih.deltocustomer_link_id,
                        to_char((select max(ihc.invoicedate)
                                 from   wearerinventorycredit wic
                                 join   wearerinventory wi
                                 on     wi.wearerinventory_id = wic.wearerinventory_id
                                 join   invoiceline ilc
                                 on     ilc.invoiceline_id = wic.losschargeinvoiceline_id
                                 join   invoiceheader ihc
                                 on     ihc.invoiceheader_id = ilc.invoiceheader_id
                                 where  wic.invoiceheader_id = ih.invoiceheader_id
                                 and    wi.weareremployment_id = ilp.weareremployment_link_id
                                 and    wi.product_id = ilp.product_link_id
                                 and    wi.sizedefinition_id = ilp.sizedefinition_link_id), 'YYYYMMDD ') ||
                         il.code invlinecode, il.description invlinedesc, il.price,
                        case
                          when il.adjustmentreason_id is null then
                           il.amount
                          else
                           il.adjustedamount
                        end amount,
                        (select p.typeofmerchandise
                          from   product p
                          where  p.product_id = ilp.product_link_id) typeofmerchandise, ilp.sizecode,
                        coalesce(trim(ilp.finishingmethoddescription),
                                  (select fd.description
                                    from   finishingmethod_desc fd
                                    where  fd.finishingmethod_id = ilp.finishingmethod_id
                                    and    fd.language_id = billto.language_id), ilp.finishingmethodcode) finishingmethoddescription,
                        null billedqty, abs(ilp.deliveredqty) deliveredqty,
                        ilp.timestamp ilp_timestamp, il.invoicelinetype_id,
                        ilp.product_link_id product_id, ilp.sizedefinition_link_id sizedefinition_id,
                        ilp.finishingmethod_id,
                        case
                          when il.invoicelinetype_id = 18 then
                           il.code
                          else
                           il.taxgroupcode
                        end taxgroupcode, il.taxtype,
                        coalesce(substr(ilp.deliveryschemecode, 1, 2),
                                  (select min(substr(s.code, 1, 2))
                                    from   customerdeliveryscheme ds, deliveryscheme s
                                    where  ds.customer_id = ih.deltocustomer_link_id
                                    and    ds.deliveryscheme_id = s.deliveryscheme_id)) delscheme,
                        ilp.wearernumber,
                        (select ilvd.description
                          from   invoicelinetype_desc ilvd
                          where  ilvd.invoicelinetype_id = il.invoicelinetype_id
                          and    ilvd.language_id = billto.language_id) invlinetype_desc,
                        (select rd.description
                          from   reasoncode_desc rd
                          where  rd.reasoncode_id = il.adjustmentreason_id
                          and    rd.language_id = billto.language_id) reasoncode, ilv.overamount,
                        coalesce(ilv.percentage, 0) taxrate, ilp.weareremployment_link_id,
                        ps.sequencenumber
                 from   invoiceline il
                 join   invoiceheader ih
                 on     ih.invoiceheader_id = il.invoiceheader_id
                 left   outer join invoicelineproduct ilp
                 on     ilp.invoiceline_id = il.invoiceline_id
                 left   join productsize ps
                 on     ps.product_id = ilp.product_link_id
                 and    ps.sizedefinition_id = ilp.sizedefinition_link_id
                 left   outer join invoicelinevarious ilv
                 on     ilv.invoiceline_id = il.invoiceline_id
                 join   customer billto
                 on     billto.customer_id = ih.billtocustomer_link_id
                 where  ih.invoiceheader_id = lv_rec_detailinv.invoiceheader_id
                 and    il.invoicelinetype_id = 9
                 and    il.invoicelinesubtype = 16
                 and    il.extend = 'Y'
                 and    (il.amount <> 0 or il.adjustedamount <> 0)) x
        group  by sorto, deltocustomer_link_id, invlinecode, invlinedesc, price, typeofmerchandise,
                  sizecode, ilp_timestamp, invoicelinetype_id, product_id, sizedefinition_id,
                  taxgroupcode, taxtype, delscheme, taxrate, weareremployment_link_id
        order  by 1, 2, 3, 9, 25, 10, 13 asc;
      --other local variables
      lv_rec_x            lv_cur_x%rowtype;
      lv_sum_inv          number := 0;
      lv_sum_payta        number := 0;
      lv_sum_taxa         number := 0;
      lv_sum_totant       number := 0;
      lv_old_billtonumber customer.customernumber%type := null;
      lv_old_commonnumber customer.customernumber%type := null;
      lv_old_invoicedate  invoiceheader.invoicedate%type := null;
      lv_invoicenumber    invoiceheader.invoicenumber%type;
      lv_old_m1_string    varchar2(1024);
      lv_print_old_m1_str boolean;
      lv_overamount       number := 0;
      lv_amount           number := 0;
    
      procedure write_m1 is
      begin
        --write_m1
        gv_message := 'write_m1';
        lv_string  := null;
        for lv_pos in 1 .. 18 loop
          begin
            gv_message := 'write_m1 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '1' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                lv_string := lv_string || to_char(gv_rec_statement.endyear) || gv_tab;
              when 5 then
                lv_string := lv_string || to_char(gv_rec_statement.endmonth) || gv_tab;
              when 6 then
                lv_string := lv_string || to_char(gv_rec_statement.invoicedate, 'YYYY') ||
                             default_year_value || to_char(gv_rec_statement.invoicedate, 'MM') ||
                             default_month_value || to_char(gv_rec_statement.invoicedate, 'DD') ||
                             default_day_value || gv_tab;
              
              when 7 then
                lv_string := lv_string || lv_inv_tab;
              when 8 then
                lv_string := lv_string || case
                               when lv_rec_detailinv.commoncustomernumber <> -1 then
                                case
                                  when lv_rec_detailinv.commoncustomernumber = gv_rec_statement.billtocustomernumber then
                                   gv_rec_statement.billto_legalname
                                  else
                                   lv_rec_detailinv.common_legalname
                                end
                               else
                                gv_rec_statement.billto_legalname
                             end || gv_tab;
              when 9 then
                null;
              when 10 then
                null;
              when 11 then
                if (lv_rec_detailinv.contactpersonname = '-') or
                   (lv_rec_detailinv.contactpersonname = '0') then
                  lv_string := lv_string || ' ' || gv_tab;
                else
                  lv_string := lv_string || lv_rec_detailinv.contactpersonname || gv_tab;
                end if;
              when 12 then
                lv_string := lv_string || default_m1_12_value || gv_tab;
              when 13 then
                null;
              when 14 then
                null;
              when 15 then
                null;
              when 16 then
                lv_string := lv_string || gv_rec_statement.billtocustomernumber || gv_tab || case
                               when lv_rec_detailinv.commoncustomernumber <> -1 then
                                lv_rec_detailinv.commoncustomernumber || gv_tab || case
                                  when lv_rec_detailinv.commonpnnumber = 0 then
                                   null
                                  else
                                   lv_rec_detailinv.commonpnnumber
                                end
                               else
                                gv_tab
                             end || gv_tab;
              when 17 then
                begin
                  --4.4 change to accept field when no data in array
                  if lv_rec_detailinv.commoncustomernumber <> -1 then
                    lv_string := lv_string || trim(to_char(customer_k2_9_array(lv_rec_detailinv.commoncustomernumber),
                                                           '999,999,999,999,999')) || gv_tab;
                  else
                    lv_string := lv_string || trim(to_char(customer_k2_9_array(lv_rec_detailinv.billtocustomernumber),
                                                           '999,999,999,999,999')) || gv_tab;
                  end if;
                exception
                  when no_data_found then
                    gv_message := 'Error, check customer setup for invoice ' ||
                                  to_char(lv_invoicenumber) || ' for debtor ' ||
                                  to_char(lv_rec_detailinv.billtocustomernumber) ||
                                  ' delto customer ' ||
                                  to_char(lv_rec_detailinv.deltocustomernumber) ||
                                  ' comon customer ' ||
                                  to_char(lv_rec_detailinv.commoncustomernumber);
                    raise gv_userexception;
                end;
              when 18 then
                lv_string := lv_string || 'page ' || gv_pageno;
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        if lv_print_old_m1_str then
          write_line(substr(lv_old_m1_string, 1, instr(lv_old_m1_string, 'page ') - 1) || 'page ' ||
                     gv_pageno, 'M');
        else
          write_line(lv_string, 'M');
        end if;
        lv_old_m1_string := lv_string;
      end write_m1;
    
      procedure write_last_m11_line is
      begin
        --last_m11_line
        gv_message := 'write_last_m11_line';
        write_line(lv_m_tab || '11' || gv_tab || gv_rec_statement.invoicenumber || gv_tab || ' ' ||
                   gv_tab || ' ' || gv_tab || ' ' || gv_tab || ' ', 'M');
        write_m1;
      end write_last_m11_line;
    
      procedure pre_count_m_lines is
      begin
        --pre_count_m_lines
        gv_message := 'pre_count_m_lines';
        if mod(gv_m_counter, 46) = 45 then
          write_last_m11_line;
        end if;
      end pre_count_m_lines;
    
      procedure write_m10 is
      begin
        pre_count_m_lines;
        --write_m10
        gv_message := 'write_m10 counter = ' || to_char(gv_m_counter) || ' invoice ' ||
                      to_char(lv_invoicenumber);
        write_line(lv_m_tab || '10' || gv_tab || gv_rec_statement.invoicenumber, 'M');
      end write_m10;
    
      procedure write_m11(fp_multiple in boolean, fp_vatgroup_desc in varchar2 default null) is
      
        procedure prep_vat_m11_write is
          --prep_vat_m11_write, write the 5 tax lines or less
          lv_taxdesc varchar2(64);
        
          procedure fill_m11vat_withm10 is
            lv_linecount number;
            lv_counter   number := 0;
          begin
            --fill_m11vat_withm10
            --same select, count number of lines
            select count(1)
            into   lv_linecount
            from   (select case nvl(x.taxgroupcode, 'EXPORT')
                               when 'YZ08' then
                                'XXX'
                               else
                                nvl(x.taxgroupcode, 'EXPORT')
                             end taxgroupcode, x.taxrate, sum(x.amountexclvat) amountexclvat,
                            sum(x.vatamount) vatamount, sum(x.amount) amount,
                            case (case nvl(x.taxgroupcode, 'EXPORT')
                                when 'YZ08' then
                                 'XXX'
                                else
                                 nvl(x.taxgroupcode, 'EXPORT')
                              end)
                               when null then
                                x.taxrate
                               when 'EXPORT' then
                                99
                               when '111111' then
                                98
                               else
                                x.taxrate
                             end sortingorder
                     from   v_statementline_auj x
                     where  x.statementheader_id = gv_rec_statement.invoiceheader_id
                     and    x.commoncustomer_number = lv_old_commonnumber
                     group  by case nvl(x.taxgroupcode, 'EXPORT')
                                 when 'YZ08' then
                                  'XXX'
                                 else
                                  nvl(x.taxgroupcode, 'EXPORT')
                               end, x.taxrate
                     order  by case (case nvl(x.taxgroupcode, 'EXPORT')
                                  when 'YZ08' then
                                   'XXX'
                                  else
                                   nvl(x.taxgroupcode, 'EXPORT')
                                end)
                                 when null then
                                  x.taxrate
                                 when 'EXPORT' then
                                  99
                                 when '111111' then
                                  98
                                 else
                                  x.taxrate
                               end);
            --fill with M10
            while lv_counter < (5 - lv_linecount) loop
              begin
                write_m10;
                lv_counter := lv_counter + 1;
              end;
            end loop;
          end fill_m11vat_withm10;
        begin
          --fill_m11vat_withm10
          fill_m11vat_withm10;
          --prep_vat_m11_write, write the 5 tax lines or less
          for x in (select case nvl(x.taxgroupcode, 'EXPORT')
                              when 'YZ08' then
                               'XXX'
                              else
                               nvl(x.taxgroupcode, 'EXPORT')
                            end taxgroupcode, x.taxrate, sum(x.amountexclvat) amountexclvat,
                           sum(x.vatamount) vatamount, sum(x.amount) amount,
                           case (case nvl(x.taxgroupcode, 'EXPORT')
                               when 'YZ08' then
                                'XXX'
                               else
                                nvl(x.taxgroupcode, 'EXPORT')
                             end)
                              when null then
                               x.taxrate
                              when 'EXPORT' then
                               99
                              when '111111' then
                               98
                              else
                               x.taxrate
                            end sortingorder
                    from   v_statementline_auj x
                    where  x.statementheader_id = gv_rec_statement.invoiceheader_id
                    and    x.commoncustomer_number = lv_old_commonnumber
                    group  by case nvl(x.taxgroupcode, 'EXPORT')
                                when 'YZ08' then
                                 'XXX'
                                else
                                 nvl(x.taxgroupcode, 'EXPORT')
                              end, x.taxrate
                    order  by case (case nvl(x.taxgroupcode, 'EXPORT')
                                 when 'YZ08' then
                                  'XXX'
                                 else
                                  nvl(x.taxgroupcode, 'EXPORT')
                               end)
                                when null then
                                 x.taxrate
                                when 'EXPORT' then
                                 99
                                when '111111' then
                                 98
                                else
                                 x.taxrate
                              end) loop
            begin
              lv_overamount := x.amountexclvat;
              lv_amount     := x.vatamount;
              lv_taxdesc := (case
                              when x.taxgroupcode = '111111' then
                               default_k3_011111_value
                              when nvl(x.taxgroupcode, 'EXPORT') = 'EXPORT' then
                               default_k3_0export_value
                              when x.taxgroupcode = 'XXX' and x.taxrate = 8 then
                               default_k3_8per_value
                              when x.taxrate = 5 then
                               default_k3_5per_value
                              when x.taxgroupcode = 'XXX' and x.taxrate = 10 then
                               default_k3_10per_value
                              else
                               null
                            end);
              write_m11(true, lv_taxdesc);
            end;
          end loop;
        end prep_vat_m11_write;
      begin
        --write_m11
        gv_message := 'write_m11';
        lv_string  := null;
        if fp_multiple then
          begin
            for lv_pos in 1 .. 5 loop
              begin
                gv_message := 'write_m11 position = ' || to_char(lv_pos) || ' invoice ' ||
                              to_char(lv_invoicenumber);
                case lv_pos
                  when 1 then
                    lv_string := lv_m_tab;
                  when 2 then
                    lv_string := lv_string || '11' || gv_tab;
                  when 3 then
                    lv_string := lv_string || lv_inv_tab;
                  when 4 then
                    lv_string := lv_string || fp_vatgroup_desc || gv_tab;
                  when 5 then
                    lv_string := lv_string || trim(to_char(lv_overamount, '999,999,999,999,999')) ||
                                 gv_tab || gv_tab;
                  else
                    gv_message := gv_message || lv_arrayerror;
                    raise gv_userexception;
                end case;
              end;
            end loop; --lv_pos
            write_line(lv_string, 'M');
          end;
        else
          begin
            --prep_vat_m11_write, write the 5 tax lines or less
            prep_vat_m11_write;
            --write total M11 line
            lv_overamount := lv_totalamountexclvat;
            lv_amount     := lv_paythisamount - lv_totalamountexclvat;
            write_m11(true, '合計');
          end;
        end if;
      end write_m11;
    
      procedure write_m2 is
      begin
        pre_count_m_lines;
        --write_m2
        gv_message := 'write_m2';
        lv_string  := null;
        for lv_pos in 1 .. 9 loop
          begin
            gv_message := 'write_m2 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '2' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                lv_string := lv_string || to_char(lv_rec_detailinv.artransactiondate, 'MM/DD') ||
                             gv_tab;
              when 5 then
                lv_string := lv_string || default_m2_5_value || gv_tab;
              when 6 then
                lv_string := lv_string || to_char(lv_rec_detailinv.deltocustomernumber) || gv_tab;
              when 7 then
                lv_string := lv_string || default_m2_7_value || gv_tab;
              when 8 then
                lv_string := lv_string || to_char(lv_rec_detailinv.artrans_invoiceno) || gv_tab;
              when 9 then
                lv_string := lv_string || lv_rec_detailinv.deltocustomername;
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m2;
    
      procedure write_m3 is
      begin
        pre_count_m_lines;
        --write_m3
        gv_message := 'write_m3';
        lv_string  := null;
        for lv_pos in 1 .. 14 loop
          begin
            gv_message := 'write_m3 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '3' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                lv_string := lv_string || lv_rec_x.delscheme || gv_tab;
              when 5 then
                null;
              when 6 then
                if lv_rec_x.invoicelinetype_id = 16 then
                  lv_string := lv_string || lv_rec_x.invlinetype_desc || gv_tab;
                else
                  lv_string := lv_string || lv_rec_x.finishingmethoddescription || gv_tab;
                end if;
              when 7 then
                lv_string := lv_string || lv_rec_x.invlinedesc || gv_tab;
              when 8 then
                lv_string := lv_string || lv_rec_x.invlinecode || gv_tab;
              when 9 then
                lv_string := lv_string || lv_rec_x.sizecode || gv_tab;
              when 10 then
                lv_string := lv_string || case
                               when lv_rec_x.typeofmerchandise <> 2 then
                                null
                               else
                                lv_rec_x.numberofwearers
                             end || gv_tab;
              when 11 then
                lv_string := lv_string || to_char(lv_rec_x.billedqty) || gv_tab;
              when 12 then
                lv_string := lv_string || trim(to_char(lv_rec_x.price, '999,999,999,999,990.00')) ||
                             gv_tab;
              when 13 then
                lv_string := lv_string || trim(to_char(lv_rec_x.amount, '999,999,999,999,999')) ||
                             gv_tab;
              when 14 then
                lv_string := lv_string || to_char(lv_rec_x.deliveredqty);
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m3;
    
      procedure write_m5(fp_letter in varchar2, fp_amount in number) is
      begin
        pre_count_m_lines;
        --write_m5
        gv_message := 'write_m5';
        lv_string  := null;
        if upper(fp_letter) = 'A' then
          begin
            --write lines, skip for now because we do not export this anymore
            write_line(lv_string, 'M');
          end;
        else
          begin
            for lv_pos in 1 .. 5 loop
              begin
                gv_message := 'write_m5 position = ' || to_char(lv_pos) || ' invoice ' ||
                              to_char(lv_invoicenumber);
                case lv_pos
                  when 1 then
                    lv_string := lv_m_tab;
                  when 2 then
                    lv_string := lv_string || '5' || gv_tab;
                  when 3 then
                    lv_string := lv_string || lv_inv_tab;
                  when 4 then
                    lv_string := lv_string || case upper(fp_letter)
                                   when 'B' then
                                    default_m5_4b_value
                                   when 'C' then
                                    default_m5_4c_value
                                 end || gv_tab;
                  when 5 then
                    lv_string := lv_string || trim(to_char(fp_amount, '999,999,999,999,999'));
                  else
                    gv_message := gv_message || lv_arrayerror;
                    raise gv_userexception;
                end case;
              end;
            end loop; --lv_pos
            write_line(lv_string, 'M');
          end;
        end if;
      end write_m5;
    
      procedure write_m6 is
      begin
        pre_count_m_lines;
        --write_m6
        gv_message := 'write_m6';
        lv_string  := null;
        for lv_pos in 1 .. 14 loop
          begin
            gv_message := 'write_m6 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '6' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                null;
              when 5 then
                null;
              when 6 then
                lv_string := lv_string || lv_rec_x.invlinetype_desc || gv_tab;
              when 7 then
                lv_string := lv_string || lv_rec_x.invlinedesc || gv_tab;
              when 8 then
                lv_string := lv_string || lv_rec_x.invlinecode || gv_tab;
              when 9 then
                lv_string := lv_string || lv_rec_x.sizecode || gv_tab;
              when 10 then
                null;
              when 11 then
                null;
              when 12 then
                if lv_rec_x.billedqty > 0 then
                  lv_string := lv_string || trim(to_char(abs(lv_rec_x.amount / lv_rec_x.billedqty),
                                                         '999,999,999,999,999.00')) || gv_tab;
                else
                  lv_string := lv_string ||
                               trim(to_char(abs(lv_rec_x.amount / lv_rec_x.deliveredqty),
                                            '999,999,999,999,999.00')) || gv_tab;
                end if;
              when 13 then
                lv_string := lv_string || trim(to_char(lv_rec_x.amount, '999,999,999,999,999')) ||
                             gv_tab;
              when 14 then
                lv_string := lv_string || to_char(lv_rec_x.deliveredqty);
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m6;
    
      procedure write_m7 is
      begin
        pre_count_m_lines;
        --write_m7
        gv_message := 'write_m7';
        lv_string  := null;
        for lv_pos in 1 .. 14 loop
          begin
            gv_message := 'write_m7 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '7' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                null;
              when 5 then
                null;
              when 6 then
                lv_string := lv_string || lv_rec_x.finishingmethoddescription || gv_tab;
              when 7 then
                lv_string := lv_string || lv_rec_x.invlinedesc || gv_tab;
              when 8 then
                --8 becomes 7_1 now
                lv_string := lv_string || lv_rec_x.invlinecode || gv_tab;
              when 9 then
                null;
              when 10 then
                null;
              when 11 then
                null;
              when 12 then
                lv_string := lv_string || trim(to_char(lv_rec_x.price, '999,999,999,999,999.00')) ||
                             gv_tab;
              when 13 then
                lv_string := lv_string || trim(to_char(lv_rec_x.amount, '999,999,999,999,999')) ||
                             gv_tab;
              when 14 then
                lv_string := lv_string || to_char(lv_rec_x.deliveredqty);
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m7;
    
      procedure write_m8 is
      begin
        pre_count_m_lines;
        --write_m8
        gv_message := 'write_m8';
        lv_string  := null;
        for lv_pos in 1 .. 13 loop
          begin
            gv_message := 'write_m8 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '8' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                null;
              when 5 then
                null;
              when 6 then
                lv_string := lv_string || lv_rec_x.finishingmethoddescription || gv_tab;
              when 7 then
                lv_string := lv_string || lv_rec_x.invlinedesc || gv_tab || lv_rec_x.invlinecode ||
                             gv_tab;
              when 8 then
                lv_string := lv_string || lv_rec_x.sizecode || gv_tab;
              when 9 then
                null;
              when 10 then
                null;
              when 11 then
                lv_string := lv_string || trim(to_char(lv_rec_x.price, '999,999,999,999,999.00')) ||
                             gv_tab;
              when 12 then
                lv_string := lv_string || trim(to_char(lv_rec_x.amount, '999,999,999,999,999')) ||
                             gv_tab;
              when 13 then
                lv_string := lv_string || to_char(lv_rec_x.deliveredqty);
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m8;
    
      procedure write_m9 is
      begin
        pre_count_m_lines;
        --write_m9
        gv_message := 'write_m9';
        lv_string  := null;
        for lv_pos in 1 .. 11 loop
          begin
            gv_message := 'write_m9 position = ' || to_char(lv_pos) || ' invoice ' ||
                          to_char(lv_invoicenumber);
            case lv_pos
              when 1 then
                lv_string := lv_m_tab;
              when 2 then
                lv_string := lv_string || '9' || gv_tab;
              when 3 then
                lv_string := lv_string || lv_inv_tab;
              when 4 then
                null;
              when 5 then
                lv_string := lv_string || default_m9_5a_value || gv_tab;
              when 6 then
                lv_string := lv_string || lv_rec_x.invlinedesc || gv_tab;
              when 7 then
                if (lv_rec_x.taxgroupcode is null) and (lv_rec_x.taxtype = 0) then
                  lv_string := lv_string || default_m9_5b_value || gv_tab;
                else
                  lv_string := lv_string || gv_tab;
                end if;
              when 8 then
                null;
              when 9 then
                if lv_rec_x.deliveredqty <> 0 and lv_rec_x.price <> 0 then
                  lv_string := lv_string || trim(to_char(lv_rec_x.price, '999,999,999,999,999.00')) ||
                               gv_tab;
                else
                  lv_string := lv_string ||
                               trim(to_char(abs(lv_rec_x.amount), '999,999,999,999,999.00')) ||
                               gv_tab;
                end if;
              when 10 then
                lv_string := lv_string || trim(to_char(lv_rec_x.amount, '999,999,999,999,999')) ||
                             gv_tab;
              when 11 then
                case
                  when lv_rec_x.deliveredqty <> 0 then
                    lv_string := lv_string || lv_rec_x.deliveredqty;
                  when lv_rec_x.price = 0 and lv_rec_x.deliveredqty = 0 then
                    lv_string := lv_string || lv_rec_x.amount;
                  else
                    lv_string := lv_string || lv_rec_x.amount / lv_rec_x.price;
                end case;
              else
                gv_message := gv_message || lv_arrayerror;
                raise gv_userexception;
            end case;
          end;
        end loop; --lv_pos
        write_line(lv_string, 'M');
      end write_m9;
    
      procedure write_m10_to_fill is
      begin
        --write_m10
        gv_message := 'write_m10_to_fill';
        while mod(gv_m_counter, 46) <> 40 loop
          begin
            write_m10;
          end;
        end loop; --gv_m_counter
        write_m11(false);
      end write_m10_to_fill;
    
    begin
      --page count new m-lines is a new page
      gv_pageno := 1;
      --export_invoicelines
      gv_message := 'export_invoicelines';
      open lv_cur_detailinv;
      loop
        begin
          --getnewline --------
          fetch lv_cur_detailinv
            into lv_rec_detailinv;
          --fill old-----------
          lv_invoicenumber    := lv_rec_detailinv.invoicenumber;
          lv_print_old_m1_str := false;
          --check for M5 C
          if (lv_sum_inv <> 0 and lv_old_invoicedate <> lv_rec_detailinv.invoicedate) or
             (lv_sum_inv <> 0 and lv_cur_detailinv%notfound and gv_m_counter > 0) or
             (lv_sum_inv <> 0 and lv_old_commonnumber <> lv_rec_detailinv.commoncustomernumber and
             gv_m_counter > 0) then
            begin
              lv_print_old_m1_str := true;
              write_m5('C', lv_sum_inv);
              if mod(gv_m_counter, 46) <> 45 then
                write_m10;
              end if;
              lv_sum_inv          := 0;
              lv_print_old_m1_str := false;
            end;
          end if;
          -- check m11 line
          if (lv_old_commonnumber <> lv_rec_detailinv.commoncustomernumber) or
             (lv_cur_detailinv%notfound and gv_m_counter > 0) then
            begin
              lv_print_old_m1_str := true;
              write_m10_to_fill;
              lv_print_old_m1_str   := false;
              lv_totalamountexclvat := 0;
              lv_paythisamount      := 0;
            end;
          end if;
          lv_totalamountexclvat := lv_totalamountexclvat + lv_rec_detailinv.totalamountexclvat;
          lv_paythisamount      := lv_paythisamount + lv_rec_detailinv.paythisamount;
          --exit when not found
          exit when lv_cur_detailinv%notfound;
          --or new-------------
          if (lv_old_commonnumber <> lv_rec_detailinv.commoncustomernumber or
             lv_old_commonnumber is null) then
            begin
              write_m1;
            end;
          end if;
          --write lines
          write_m2;
          lv_tax_count := 0;
          open lv_cur_x;
          loop
            begin
              fetch lv_cur_x
                into lv_rec_x;
              exit when lv_cur_x%notfound;
              --!!!not sure about when to export what line!!!
              case
                when lv_rec_x.invoicelinetype_id in (1, 8, 16) then
                  begin
                    if ((substr(lv_rec_x.delscheme, 1, 2) = '01') or (lv_rec_x.amount <> 0)) then
                      write_m3;
                    end if;
                    if ((substr(lv_rec_x.delscheme, 1, 2) <> '01') and (lv_rec_x.deliveredqty <> 0) and
                       (lv_rec_x.amount = 0)) and lv_rec_x.typeofmerchandise = 1 then
                      write_m3;
                    end if;
                  end;
                when lv_rec_x.invoicelinetype_id in (6, 7, 9, 10, 12) and lv_rec_x.amount <> 0 then
                  write_m6;
                when lv_rec_x.invoicelinetype_id = 2 and lv_rec_x.amount <> 0 then
                  write_m7;
                when lv_rec_x.invoicelinetype_id = 5 and lv_rec_x.amount <> 0 then
                  write_m8;
                when lv_rec_x.invoicelinetype_id in (15, 21) and lv_rec_x.amount <> 0 then
                  write_m9;
                when lv_rec_x.invoicelinetype_id = 18 then
                  lv_tax_count := lv_tax_count + 1;
                else
                  null;
              end case;
              --!!!not sure about when to export what line!!!
            end;
          end loop; --x
          lv_sum_inv    := lv_sum_inv + lv_rec_detailinv.paythisamount;
          lv_sum_payta  := lv_sum_payta + lv_rec_detailinv.paythisamount;
          lv_sum_taxa   := lv_sum_taxa + lv_rec_detailinv.paythisamount -
                           lv_rec_detailinv.totalamountexclvat;
          lv_sum_totant := lv_sum_totant + lv_rec_detailinv.totalamountexclvat;
          if lv_tax_count = 0 then
            begin
              write_m10;
              write_m10;
            end;
          end if;
          write_m10;
          write_m5('B', lv_rec_detailinv.paythisamount);
          write_m10;
          lv_old_billtonumber := lv_rec_detailinv.billtocustomernumber;
          lv_old_commonnumber := lv_rec_detailinv.commoncustomernumber;
          lv_old_invoicedate  := lv_rec_detailinv.invoicedate;
          close lv_cur_x;
        end;
      end loop; --invl
      close lv_cur_detailinv;
    end export_invoicelines;
  
  begin
    --export_one_statement
    gv_message := 'export_one_statement';
    --get values
    lv_money_received_month := get_money_received_month(gv_rec_statement.invoicedate,
                                                        gv_rec_statement.billtocustomer_link_id);
    --export_statementheader
    export_frontpage;
    export_invoicelines;
  end export_one_statement;

  procedure export_print_footer is
  begin
    --export_footer
    gv_message := 'export_print_footer';
    write_line('Z' || gv_tab || gv_totalamountexported || gv_tab || to_char(gv_rows_count - 1), 'Z');
  end export_print_footer;

  procedure export_print_data is
  begin
    --export_data
    gv_message := 'export_print_data';
    export_print_header;
    --export ordered by delto customer number/invoice number
    open gv_cur_statement;
    loop
      begin
        fetch gv_cur_statement
          into gv_rec_statement;
        exit when gv_cur_statement%notfound;
        export_one_statement;
      end;
    end loop; --x
    close gv_cur_statement;
    export_print_footer;
  end export_print_data;

  procedure finalize is
  begin
    --finalize
    gv_message := 'Exported ' || to_char(gv_rows_count - 2) || ' rows with a total amount of ' ||
                  gv_totalamountexported;
    write_log(gv_message, 1);
    gv_message := 'Finished export into ' || gv_dir || gv_filename;
    write_log(gv_message, 1);
    close_file;
  end finalize;

begin
  initialize;
  export_print_data;
  finalize;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
    end;
end exportinvoices_auj_m11;
/

create or replace procedure exportloginlogout_auj(fp_year      in number,
                                                  fp_month     in number,
                                                  fp_exportdir in varchar2,
                                                  fp_separator in varchar2 default ';',
                                                  fp_filename  in varchar2 default null) is
  /*****************************************************************************\
  * Version 0.7   Standard Procedure to write the output of a query to file     *
  * 11/10/2023 ABS-154790 System User log updates on reconnect                  *
  \*****************************************************************************/
  gv_message       varchar2(1000);
  gv_year          number;
  gv_month         number;
  gv_separator     varchar2(1);
  gv_exportdir     varchar2(256);
  gv_filename      varchar2(128);
  gv_counter       number := 0;
  gv_userexception exception;
  lv_desctbl       dbms_sql.desc_tab;
  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'exportloginlogout', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null;
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_message := 'initialize';
    if fp_year is not null then
      begin
        gv_year := fp_year;
      end;
    else
      begin
        gv_year := to_number(to_char(sysdate - 14), 'YYYY');
      end;
    end if;
    if fp_month is not null then
      begin
        gv_month := fp_month;
      end;
    else
      begin
        gv_month := to_number(to_char(sysdate - 14), 'MM');
      end;
    end if;
    if trim(fp_separator) is null then
      begin
        gv_separator := ';';
      end;
    else
      begin
        gv_message   := 'get separator ' || fp_separator;
        gv_separator := substr(trim(fp_separator), 1, 1);
      end;
    end if;
    if fp_exportdir is null then
      begin
        --must exist as an Oracle directory that points towards the storage place
        gv_exportdir := 'OUTPUT';
      end;
    else
      begin
        gv_exportdir := fp_exportdir;
      end;
    end if;
    --use fp_filename 
    if fp_filename is null then
      begin
        --build file name
        gv_message  := 'build file name';
        gv_filename := 'systemuserlog_' || to_char(gv_year) || '_' || to_char(gv_month) || '.CSV';
      end;
    else
      begin
        gv_filename := fp_filename;
      end;
    end if;
    --set date format
    execute immediate ('ALTER SESSION SET NLS_DATE_FORMAT = ''DD-MM-YYYY''');
    execute immediate ('ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''');
  end initialize;

  procedure exportdata is
    lv_output        utl_file.file_type;
    lv_query         clob;
    lv_thecursor     integer default dbms_sql.open_cursor;
    lv_status        integer;
    lv_colcnt        number := 0;
    lv_columnvalue   varchar2(2000);
    lv_makenull      number := 0;
    lv_curr_username varchar2(20);
    lv_prev_username varchar2(20) := 'NULL';
  
    function open_file return utl_file.file_type is
    begin
      --open file
      gv_message := 'Write file ' || gv_filename || ' in directory ' || gv_exportdir;
      return utl_file.fopen(gv_exportdir, gv_filename, 'w', 32767);
    exception
      when utl_file.invalid_path then
        raise_application_error(-20100, 'Invalid Path');
      when utl_file.invalid_mode then
        raise_application_error(-20101, 'Invalid Mode');
      when utl_file.invalid_operation then
        raise_application_error(-20102, 'Invalid Operation');
      when utl_file.invalid_filehandle then
        raise_application_error(-20103, 'Invalid FileHandle');
      when utl_file.write_error then
        raise_application_error(-20104, 'Write Error');
      when utl_file.read_error then
        raise_application_error(-20105, 'Read Error');
      when utl_file.internal_error then
        raise_application_error(-20106, 'Internal Error');
    end open_file;
    procedure write_column is
    begin
      --write_column, no separator for the last column
      utl_file.put(lv_output, lv_columnvalue || gv_separator);
    end write_column;
    procedure write_linefeed is
    begin
      --write_linefeed
      utl_file.new_line(lv_output);
      --and count lines
      gv_counter := gv_counter + 1;
    end write_linefeed;
  
    procedure close_file is
    begin
      --close file
      if utl_file.is_open(lv_output) = true then
        utl_file.fclose(lv_output);
      end if;
    end close_file;
  begin
    --initialize, create export file, open/describe cursor
    lv_output := open_file;
    lv_query  := 'select s.username, s.fullname, u.groupname, u.description, s.sysadmin,
                  to_char(l.lastlogintimestamp,''YYYY/MM/DD HH24:MI:SS'') as lastlogintimestamp, 
                  to_char(l.lastlogouttimestamp,''YYYY/MM/DD HH24:MI:SS'') as lastlogouttimestamp,
                  w.code, w.description
                  from loggingsystemuser l, systemuser s, usergroup u, workstation w
                  where l.systemuser_id = s.systemuser_id
                  and s.usergroup_id = u.usergroup_id
                  and s.lastloginatworkstation = w.workstation_id
                  and to_number(to_char(l.lastlogintimestamp,''yyyymm'')) = ' ||
                 to_char(gv_year * 100 + gv_month) || ' 
                  order by l.systemuser_id, l.lastlogintimestamp';
    --parse select
    dbms_sql.parse(lv_thecursor, lv_query, dbms_sql.native);
    --describe_columns
    dbms_sql.describe_columns(lv_thecursor, lv_colcnt, lv_desctbl);
    --gather columns to be exported in sql statement
    for i in 1 .. lv_colcnt loop
      begin
        dbms_sql.define_column(lv_thecursor, i, lv_columnvalue, 8000);
        lv_columnvalue := lv_desctbl(i).col_name;
        write_column;
      end;
    end loop;
    --write_linefeed
    write_linefeed;
    --start the cursor with sql statement for export
    lv_status := dbms_sql.execute(lv_thecursor);
    --loop through all records for export
    while (dbms_sql.fetch_rows(lv_thecursor) > 0) loop
      begin
        dbms_sql.column_value(lv_thecursor, 1, lv_curr_username);
        dbms_sql.column_value(lv_thecursor, 7, lv_columnvalue);
        if lv_curr_username <> lv_prev_username then
          begin
            lv_makenull := 0;
          end;
        end if;
        if lv_makenull = 1 and lv_columnvalue is null then
          null; -- do not export the line, there would be no login data..
        else
          for i in 1 .. lv_colcnt loop
            begin
              --we export the lines
              dbms_sql.column_value(lv_thecursor, i, lv_columnvalue);
              if i = 7 then
                if lv_columnvalue is null then
                  lv_makenull := 1;
                else
                  lv_makenull := 0;
                end if;
              end if;
              if i = 6 and lv_makenull = 1 then
                begin
                  lv_columnvalue := null;
                  lv_makenull    := 0;
                end;
              end if;
              write_column;
            end;
          end loop;
          dbms_sql.column_value(lv_thecursor, 1, lv_prev_username);
          --write_linefeed
          write_linefeed;
        end if;
      end;
    end loop;
    --finalize close cursor
    dbms_sql.close_cursor(lv_thecursor);
    --close_file
    close_file;
  exception
    when others then
      begin
        --close_file
        close_file;
        --create message for info
        gv_message := 'Error during export ' || gv_filename || ' in directory ' || gv_exportdir ||
                      chr(10) || substr(sqlerrm, 1, 200) || chr(10) || 'Export line: ' || lv_query ||
                      chr(10) || 'sql-status ' || nvl(to_char(lv_status), 'NULL');
        --raise error to main part
        raise gv_userexception;
      end;
  end exportdata;

  procedure finalize is
  begin
    --finalize
    write_log('Successfully exported into directory ' || gv_exportdir || ' filename ' ||
              gv_filename || ' ' || to_char(gv_counter) || ' lines', 1);
  end finalize;
begin
  initialize;
  exportdata;
  finalize;
exception
  --Exception handling
  when gv_userexception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      gv_message := 'Error, No Data Found ' || gv_message;
      write_log(gv_message, 3);
    end;
  when others then
    begin
      rollback;
      gv_message := 'Error ' || sqlerrm || ' ' || gv_message;
      write_log(gv_message, 3);
    end;
end exportloginlogout_auj;
/

create or replace procedure exportlogonoff is
  gv_userexception exception;
  gv_message       varchar2(1000);
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_dir           systemsetting.value%type;
  gv_filehandle    utl_file.file_type;
  fp_filename      varchar2(100);
  gv_seperator     varchar2(1) := ',';

  procedure write_log(fp_message  in varchar2,
                      fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5,
                             'exportlogonoff',
                             null,
                             fp_priority,
                             fp_message,
                             gv_defaultuserid);
    if fp_priority = 3 then
      write_log('exportlogonoff finished with errors!', 1);
    end if;
    if fp_priority > 2 then
      dbms_output.put_line(fp_message);
    end if;
  end write_log;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  function open_file return utl_file.file_type is
  begin
    --open file
    gv_message := 'exportlogonoff.open_file ' || gv_dir || fp_filename;
    return utl_file.fopen(gv_dir, fp_filename, 'w', 32767);
  exception
    when utl_file.invalid_path then
      raise_application_error(-20100, 'Invalid Path');
    when utl_file.invalid_mode then
      raise_application_error(-20101, 'Invalid Mode');
    when utl_file.invalid_operation then
      raise_application_error(-20102, 'Invalid Operation');
    when utl_file.invalid_filehandle then
      raise_application_error(-20103, 'Invalid FileHandle');
    when utl_file.write_error then
      raise_application_error(-20104, 'Write Error');
    when utl_file.read_error then
      raise_application_error(-20105, 'Read Error');
    when utl_file.internal_error then
      raise_application_error(-20106, 'Internal Error');
  end open_file;

  procedure initialize is
 lv_YearMonth    varchar2(6) := '';
  begin
    --initialize
    gv_message := 'initialize';
    --get directory
    select nvl(max(ss.value), max(ss.factorydefault))
      into gv_dir
      from systemsetting ss
     where ss.name = 'DATABASELOGDIR';
    gv_dir := 'AUDITDIR';
    --write log
    write_log('Start export to file ' || gv_dir || fp_filename);
    --check parameter
    select to_char(sysdate, 'yyyymm') into lv_YearMonth from dual;
    
    fp_filename := 'audit_' || lv_YearMonth || '.csv';
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_userexception;
      end;
    end if;
    --open file
    gv_filehandle := open_file;
  end initialize;

  procedure finalize is
  begin
    --finalize
    gv_message := 'Exported ' || ' into ' || gv_dir || fp_filename;
    write_log(gv_message);
    dbms_output.put_line(gv_message);
    close_file;
  end finalize;

  procedure write_line(fp_IP_ADDRESS   in varchar2,
                       fp_SESSION_USER in varchar2,
                       fp_OS_USER      in varchar2,
                       fp_ISDBA        in varchar2,
                       fp_MODULE       in varchar2,
                       fp_LOGON_DATE   in varchar2,
                       fp_LOGOFF_DATE  in varchar2,
                       fp_HOST         in varchar2,
                       fp_TERMINAL     in varchar2) is
  begin
    --write_line
    gv_message := 'write_line date ' || fp_LOGON_DATE || fp_LOGOFF_DATE;
    utl_file.put(gv_filehandle,
                 convert((fp_IP_ADDRESS || gv_seperator || fp_SESSION_USER ||
                         gv_seperator || fp_OS_USER || gv_seperator ||
                         fp_ISDBA || gv_seperator || fp_MODULE ||
                         gv_seperator || fp_LOGON_DATE || gv_seperator ||
                         fp_LOGOFF_DATE || gv_seperator || fp_HOST ||
                         gv_seperator || fp_TERMINAL),
                         'JA16SJIS',
                         'UTF8'));
    utl_file.new_line(gv_filehandle);
  end write_line;

  procedure export_data is
  begin
    --export_data
    gv_message := 'export_data';
    utl_file.put(gv_filehandle,
                 convert('IP_ADDRESS,SESSION_USER,OS_USER,ISDBA,MODULE,LOGON_DATE,LOGOFF_DATE,HOST,TERMINAL',
                         'JA16SJIS',
                         'UTF8'));
    utl_file.new_line(gv_filehandle);

    for y in (select IP_ADDRESS,
                     SESSION_USER,
                     OS_USER,
                     ISDBA,
                     MODULE,
                     LOGON_DATE,
                     LOGOFF_DATE,
                     HOST,
                     TERMINAL
                from SYS_AUDIT
               where (substr(LOGON_DATE, 6, 2) = to_char(sysdate, 'mm') and
                     substr(LOGON_DATE, 1, 4) = to_char(sysdate, 'yyyy'))
                  or (substr(LOGOFF_DATE, 6, 2) = to_char(sysdate, 'mm') and
                     substr(LOGOFF_DATE, 1, 4) = to_char(sysdate, 'yyyy'))
               order by nvl(LOGON_DATE, LOGOFF_DATE)) loop
      begin
        write_line(y.ip_address,
                   y.session_user,
                   y.os_user,
                   y.ISDBA,
                   y.MODULE,
                   y.LOGON_DATE,
                   y.LOGOFF_DATE,
                   y.HOST,
                   y.TERMINAL);
      exception
        when gv_userexception then
          begin
            write_log(gv_message, 2);
          end;
      end;
    end loop; --Y
  
  end export_data;

begin
  initialize;
  export_data;
  finalize;
  commit;
  --rollback;
exception
  --exception handling
  when gv_userexception then
    begin
      write_log(gv_message, 3);
      close_file;
      rollback;
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3);
      close_file;
      rollback;
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message, 3);
      close_file;
      rollback;
    end;
end exportlogonoff;
/

create or replace function f_rentprice_string(customerid        in customer.customer_id%type,
                                              productid         in product.product_id%type,
                                              sizedefinitionid  in sizedefinition.sizedefinition_id%type,
                                              finishingmethodid in finishingmethod.finishingmethod_id%type,
                                              pricedate         in pricelistpercustomer.dateactive%type default null,
                                              chgperwk_or_freq  in generalrentprice.changesperweek%type default 0)
  return varchar2 is
  price                  customerrentprice.price%type;
  price_found_yn         varchar2(1);
  price_start_date       customerrentprice.startdate%type;
  result_code            number;
  result_desc            varchar2(80);
  price_list_type        varchar2(1);
  price_list_code        generalpricelist.code%type;
  price_list_desc        generalpricelist.description%type;
  changesperwkfoundprice customerrentprice.changesperweek%type;
  price_type_code        customerrentprice.typeofrent%type;
  price_type_desc        varchar2(30);
  inv_freq_code          customerrentprice.invoicefrequencynumber%type;
  inv_freq_desc          varchar2(10);
  customerrentpriceid    customerrentprice.customerrentprice_id%type;
begin
  /*function f_rentprice_string version 0.1*/

  /*
  The return string is composed of the following elements:
  pos  1 -  12  (12): price  format: 99999.99999 ,  spaces when no price found.
  pos  13 - 20  ( 8): price start date format YYYYMMDD, spaces when no price found.
  pos  21       ( 1): price type code
  pos  22 - 32  (10): found price is defined for this number of changes per week
  */
  pack_price.get_rent_price_details(customerid, productid, sizedefinitionid, finishingmethodid,
                                    pricedate, nvl(chgperwk_or_freq, 0), price, price_found_yn,
                                    price_start_date, result_code, result_desc, price_list_type,
                                    price_list_code, price_list_desc, changesperwkfoundprice,
                                    price_type_code, price_type_desc, inv_freq_code, inv_freq_desc,
                                    customerrentpriceid);
  return(rpad(nvl(to_char(price, '999999D9999'), ' '), 12) || 
         rpad(nvl(to_char(price_start_date, 'YYYYMMDD'), ' '), 8) ||
         rpad(nvl(to_char(price_type_code), ' '), 1) ||
         lpad(nvl(to_char(changesperwkfoundprice), ' '), 10));
end f_rentprice_string;
/

create or replace function get_accountheading(fp_billtonumber         in customer.customernumber%type,
                                              fp_ledgeraccount        in accountmapping.ledgeraccount%type,
                                              fp_customerrankpriority in accountmapping.customerrankpriority%type)
  return accountmapping.accountheading%type is
  lvf_accountheading accountmapping.accountheading%type;

  /***
  function get_accountheading version 1.0
  
  ----Please first Create table ACCOUNTMAPPING and fill this table!
  create table ACCOUNTMAPPING
  (
    LEDGERACCOUNT       NUMBER not null,
    CUSTOMERRANKING     VARCHAR2(10) not null,
    CUSTOMERNAME        VARCHAR2(40),
    ACCOUNTHEADING      NUMBER not null,
    BILLTOCUSTOMERNUMER NUMBER
  );
  -- Add comments to the columns
  comment on column ACCOUNTMAPPING.CUSTOMERNAME
    is 'Reference only not used!';
  -- Create/Recreate primary, unique and foreign key constraints
  alter table ACCOUNTMAPPING
    add constraint FK_ACCOUNTMAPPING_BILLTO foreign key (BILLTOCUSTOMERNUMER)
    references CUSTOMER (CUSTOMERNUMBER);
  -- Create/Recreate indexes
  create unique index PK_ACCOUNTMAPPING on ACCOUNTMAPPING (LEDGERACCOUNT, CUSTOMERRANKING, BILLTOCUSTOMERNUMER);
  --ABS-153200
  CREATE INDEX PK1_ACCOUNTMAPPING ON ACCOUNTMAPPING (LEDGERACCOUNT, CUSTOMERRANKPRIORITY, BILLTOCUSTOMERNUMER);  
  ***/

begin
  --get_accountheading accountheading
  select max(ac.accountheading)
  into   lvf_accountheading
  from   accountmapping ac
  where  ac.billtocustomernumer = fp_billtonumber
  and    ac.customerrankpriority = fp_customerrankpriority
  and    ac.ledgeraccount = fp_ledgeraccount;
  if lvf_accountheading is null then
    begin
      select ac.accountheading --added wbo
      into   lvf_accountheading
      from   accountmapping ac
      where  ac.ledgeraccount = fp_ledgeraccount
      and    ac.customerrankpriority = fp_customerrankpriority
      and    ac.billtocustomernumer is null;
    end;
  end if;
  return lvf_accountheading;
exception
  when no_data_found then
    return 0; --fp_ledgeraccount;
end get_accountheading;
/

create or replace procedure import_erp_wearer(fp_filename  in varchar2,
                                              fp_directory in varchar2,
                                              fp_seperator in varchar2 default ';') is
  --import_erp_wearer version 0.3
  --global variables
  gv_user__exception exception;
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_filehandle    utl_file.file_type;
  gv_message       abslog.message%type;
  gv_plantid       plant.plant_id%type;
  gv_separator     varchar2(1);

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2 default null, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'import_erp_wearer', gv_plantid, nvl(fp_priority, 1), fp_message,
                             gv_defaultuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --cannot produce output but its in ABSLOG as well
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_message := 'initialize';
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
    if fp_directory is null then
      begin
        gv_message := 'parameter fp_directory cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
    if fp_seperator is null then
      begin
        gv_separator := ';';
      end;
    else
      begin
        gv_message   := 'check separator';
        gv_separator := fp_seperator;
      end;
    end if;
    execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
    execute immediate 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''';
  end initialize;

  procedure read_file is
  begin
    --open the file
    gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
    gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
  exception
    when utl_file.invalid_path then
      begin
        gv_message := gv_message || ' Invalid Path';
        raise gv_user__exception;
      end;
    when utl_file.invalid_mode then
      begin
        gv_message := gv_message || ' Invalid Mode';
        raise gv_user__exception;
      end;
    when utl_file.invalid_operation then
      begin
        gv_message := gv_message || ' Invalid Operation';
        raise gv_user__exception;
      end;
    when utl_file.invalid_filehandle then
      begin
        gv_message := gv_message || ' Invalid Filehandle';
        raise gv_user__exception;
      end;
    when utl_file.write_error then
      begin
        gv_message := gv_message || ' Write Error';
        raise gv_user__exception;
      end;
    when utl_file.read_error then
      begin
        gv_message := gv_message || ' Read Error';
        raise gv_user__exception;
      end;
    when utl_file.internal_error then
      begin
        gv_message := gv_message || ' Internal Error';
        raise gv_user__exception;
      end;
  end read_file;

  procedure process_file is
    lv_readline     varchar2(4000);
    lv_line_counter number := 0;
    lv_erp_i_wearer erp_i_wearer%rowtype;
  
    ----process_file internal procedures
    procedure process_line(fp_readline in varchar2) is
    
      ---process_file.process_line internal procedures
      procedure read_line(fp_readline in varchar2) is
        lv_currentposition number := 0;
        lv_nextposition    number := 0;
        lv_laststring      boolean := false;
      
        ---process_file.process_line.read_line internal function
        function get_nextvalue(fp_message in varchar2) return varchar2 is
        
          --process_file.process_line.read_line.get_nextvalue internal function
          function get_position(fp_startpos in number) return number is
          begin
            --get_position
            return instr(substr(fp_readline, fp_startpos + 1), gv_separator) + fp_startpos;
          end get_position;
        begin
          --get_nextvalue
          lv_currentposition := lv_nextposition;
          lv_nextposition    := get_position(lv_currentposition);
          gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                to_char(lv_nextposition) || ' ' || fp_message;
          if lv_nextposition = lv_currentposition then
            begin
              --separator not found, so last field
              --last string, repeat it, if nothing else...
              if not lv_laststring then
                begin
                  lv_laststring := true;
                  --read last value
                  return substr(fp_readline, lv_currentposition + 1);
                end;
              else
                begin
                  --no new values found!
                  return null;
                end;
              end if;
            end;
          else
            --read value
            return trim(substr(fp_readline, lv_currentposition + 1,
                               lv_nextposition - lv_currentposition - 1));
          end if;
        end get_nextvalue;
      begin
        --read_line
        lv_laststring             := false;
        lv_erp_i_wearer.timestamp := sysdate;
        --read values
        lv_erp_i_wearer.transfer_id              := to_number(get_nextvalue('Transfer_id'));
        lv_erp_i_wearer.transfer_status          := nvl(to_number(get_nextvalue('Transfer_Status')),
                                                        0);
        lv_erp_i_wearer.customernumber           := to_number(get_nextvalue('Customer number'));
        lv_erp_i_wearer.departmentnumber         := to_number(get_nextvalue('Department number'));
        lv_erp_i_wearer.consumptionnumber        := to_number(get_nextvalue('Consumption number'));
        lv_erp_i_wearer.wearernumber             := to_number(get_nextvalue('Wearer number'));
        lv_erp_i_wearer.weareremploymentnumber   := to_number(get_nextvalue('Wearer Employment number'));
        lv_erp_i_wearer.fullname                 := get_nextvalue('Fullname');
        lv_erp_i_wearer.searchname               := get_nextvalue('Searchname');
        lv_erp_i_wearer.emblemname               := get_nextvalue('Emblemname');
        lv_erp_i_wearer.firstname                := get_nextvalue('Firstname');
        lv_erp_i_wearer.customeremployeenumber   := get_nextvalue('Customer Employee number');
        lv_erp_i_wearer.sex                      := get_nextvalue('Sex');
        lv_erp_i_wearer.wearerfunctioncode       := get_nextvalue('Wearer functioncode');
        lv_erp_i_wearer.bank                     := get_nextvalue('Bank');
        lv_erp_i_wearer.locker                   := get_nextvalue('Locker');
        lv_erp_i_wearer.garmentdispensercode     := get_nextvalue('Garment Dispensercode');
        lv_erp_i_wearer.dateactive               := to_date(get_nextvalue('Dateactive'),
                                                            'DD-MM-YYYY');
        lv_erp_i_wearer.dateinactive             := to_date(nvl(get_nextvalue('Dateinactive'),
                                                                '31-12-2099'), 'DD-MM-YYYY');
        lv_erp_i_wearer.remark                   := get_nextvalue('Remark');
        lv_erp_i_wearer.wearerflagcode           := get_nextvalue('Wearer flagcode');
        lv_erp_i_wearer.wearerflagstartdate      := get_nextvalue('Wearer flagstartdate');
        lv_erp_i_wearer.employmentflagcode       := get_nextvalue('Employment flagcode');
        lv_erp_i_wearer.employmentflagstartdate  := get_nextvalue('Employment flagstartdate');
        lv_erp_i_wearer.embroideryletteringline1 := get_nextvalue('Embroidery letteringline 1');
        lv_erp_i_wearer.embroideryletteringline2 := get_nextvalue('Embroidery letteringline 2');
        lv_erp_i_wearer.embroideryletteringline3 := get_nextvalue('Embroidery letteringline 3');
      end read_line;
    
      procedure insert_line is
      begin
        --insert_line
        gv_message := 'insert_line';
        insert into erp_i_wearer values lv_erp_i_wearer;
        commit;
      end insert_line;
    begin
      --read
      read_line(fp_readline);
      --insert
      insert_line;
    exception
      when others then
        begin
          write_log('Line# ' || to_char(lv_line_counter) || ' error ' || sqlerrm || ' customer ' ||
                    nvl(to_char(lv_erp_i_wearer.customernumber), ' unknown ') || ' wearer ' ||
                    nvl(to_char(lv_erp_i_wearer.wearernumber), ' unknown') || ' ' || gv_message ||
                    ' file ' || fp_filename);
        end;
    end process_line;
  begin
    --process_file
    gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                  nvl(fp_directory, '<Empty>');
    --loop go through lines
    loop
      begin
        begin
          -- get line from file.
          utl_file.get_line(gv_filehandle, lv_readline);
          lv_line_counter := lv_line_counter + 1;
        exception
          when no_data_found then
            exit;
        end;
        --process_line
        gv_message := 'Linenumber ' || lv_line_counter;
        --process lines
        if substr(lv_readline, 1, 3) <> (gv_separator || gv_separator || gv_separator) then
          begin
            process_line(lv_readline);
          end;
        end if;
      end;
    end loop;
    --commit
    commit;
  end process_file;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  procedure finalize is
  begin
    --write log
    write_log('Successfully processed file ' || fp_filename || ' in directory ' || fp_directory);
  end finalize;
  --start main procedure
begin
  --initialize
  initialize;
  --read_file
  read_file;
  --process_file
  process_file;
  --close file
  close_file;
  --finalize
  finalize;
exception
  --exception handling global
  when gv_user__exception then
    begin
      rollback;
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error No Data Found ' || gv_message || ' file ' || fp_filename ||
                ' in directory ' || fp_directory, 3);
      close_file;
    end;
  when others then
    begin
      rollback;
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message || ' file ' || fp_filename || ' in directory ' ||
                fp_directory, 3);
      close_file;
    end;
end import_erp_wearer;
/

create or replace procedure import_erp_wearerinv(fp_filename  in varchar2,
                                                 fp_directory in varchar2,
                                                 fp_seperator in varchar2 default ';') is
  --import_erp_wearerinv version 0.3
  --global variables
  gv_user__exception exception;
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_filehandle    utl_file.file_type;
  gv_message       abslog.message%type;
  gv_plantid       plant.plant_id%type;
  gv_separator     varchar2(1);

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2 default null, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'import_erp_wearerinv', gv_plantid, nvl(fp_priority, 1), fp_message,
                             gv_defaultuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --cannot produce output but its in ABSLOG as well
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_message := 'initialize';
    if fp_filename is null then
      begin
        gv_message := 'parameter fp_filename cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
    if fp_directory is null then
      begin
        gv_message := 'parameter fp_directory cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
    if fp_seperator is null then
      begin
        gv_separator := ';';
      end;
    else
      begin
        gv_message   := 'check separator';
        gv_separator := fp_seperator;
      end;
    end if;
    execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
    execute immediate 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''';
  end initialize;

  procedure read_file is
  begin
    --open the file
    gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
    gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
  exception
    when utl_file.invalid_path then
      begin
        gv_message := gv_message || ' Invalid Path';
        raise gv_user__exception;
      end;
    when utl_file.invalid_mode then
      begin
        gv_message := gv_message || ' Invalid Mode';
        raise gv_user__exception;
      end;
    when utl_file.invalid_operation then
      begin
        gv_message := gv_message || ' Invalid Operation';
        raise gv_user__exception;
      end;
    when utl_file.invalid_filehandle then
      begin
        gv_message := gv_message || ' Invalid Filehandle';
        raise gv_user__exception;
      end;
    when utl_file.write_error then
      begin
        gv_message := gv_message || ' Write Error';
        raise gv_user__exception;
      end;
    when utl_file.read_error then
      begin
        gv_message := gv_message || ' Read Error';
        raise gv_user__exception;
      end;
    when utl_file.internal_error then
      begin
        gv_message := gv_message || ' Internal Error';
        raise gv_user__exception;
      end;
  end read_file;

  procedure process_file is
    lv_readline        varchar2(4000);
    lv_line_counter    number := 0;
    lv_erp_i_wearerinv erp_i_wearerinventory%rowtype;
  
    ----process_file internal procedures
    procedure process_line(fp_readline in varchar2) is
    
      ---process_file.process_line internal procedures
      procedure read_line(fp_readline in varchar2) is
        lv_currentposition number := 0;
        lv_nextposition    number := 0;
        lv_laststring      boolean := false;
      
        ---process_file.process_line.read_line internal function
        function get_nextvalue(fp_message in varchar2) return varchar2 is
        
          --process_file.process_line.read_line.get_nextvalue internal function
          function get_position(fp_startpos in number) return number is
          begin
            --get_position
            return instr(substr(fp_readline, fp_startpos + 1), gv_separator) + fp_startpos;
          end get_position;
        begin
          --get_nextvalue
          lv_currentposition := lv_nextposition;
          lv_nextposition    := get_position(lv_currentposition);
          gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                to_char(lv_nextposition) || ' ' || fp_message;
          if lv_nextposition = lv_currentposition then
            begin
              --separator not found, so last field
              --last string, repeat it, if nothing else...
              if not lv_laststring then
                begin
                  lv_laststring := true;
                  --read last value
                  return substr(fp_readline, lv_currentposition + 1);
                end;
              else
                begin
                  --no new values found!
                  return null;
                end;
              end if;
            end;
          else
            --read value
            return trim(substr(fp_readline, lv_currentposition + 1,
                               lv_nextposition - lv_currentposition - 1));
          end if;
        end get_nextvalue;
      begin
        --read_line
        lv_laststring                := false;
        lv_erp_i_wearerinv.timestamp := sysdate;
        --read values
        lv_erp_i_wearerinv.transfer_id            := get_nextvalue('Transfer_Id');
        lv_erp_i_wearerinv.transfer_status        := nvl(to_number(get_nextvalue('Transfer_Status')),
                                                         0);
        lv_erp_i_wearerinv.customernumber         := to_number(get_nextvalue('Customer number'));
        lv_erp_i_wearerinv.wearernumber           := to_number(get_nextvalue('Wearer number'));
        lv_erp_i_wearerinv.weareremploymentnumber := to_number(get_nextvalue('Weareremployment number'));
        lv_erp_i_wearerinv.productcode            := get_nextvalue('Product code');
        lv_erp_i_wearerinv.sizecode               := get_nextvalue('Size code');
        lv_erp_i_wearerinv.finishingmethodcode    := get_nextvalue('Finishingmethod code');
        lv_erp_i_wearerinv.specialqualitygrade    := get_nextvalue('Specialqualitygrade');
        lv_erp_i_wearerinv.maxinventory           := get_nextvalue('Maxinventory');
        lv_erp_i_wearerinv.changesperweek         := get_nextvalue('Changes per week');
        lv_erp_i_wearerinv.freeofchargeqty        := get_nextvalue('Free of charge qty');
        lv_erp_i_wearerinv.maxfreeofcharge        := get_nextvalue('Max free of charge');
        lv_erp_i_wearerinv.startdate              := to_date(get_nextvalue('Startdate'),
                                                             'DD-MM-YYYY');
        lv_erp_i_wearerinv.enddate                := to_date(nvl(get_nextvalue('Enddate'),
                                                                 '31-12-2099'), 'DD-MM-YYYY');
        lv_erp_i_wearerinv.emblemtemplate         := get_nextvalue('Emblemtemplate');
        lv_erp_i_wearerinv.modificationcode1      := get_nextvalue('Modification code 1');
        lv_erp_i_wearerinv.modificationcode2      := get_nextvalue('Modification code 2');
        lv_erp_i_wearerinv.modificationcode3      := get_nextvalue('Modification code 3');
        lv_erp_i_wearerinv.remark                 := get_nextvalue('Remark');
      end read_line;
    
      procedure insert_line is
      begin
        --insert_line
        gv_message := 'insert_line';
        insert into erp_i_wearerinventory values lv_erp_i_wearerinv;
        commit;
      end insert_line;
    begin
      --read
      read_line(fp_readline);
      --insert
      insert_line;
    exception
      when others then
        begin
          write_log('Line# ' || to_char(lv_line_counter) || ' error ' || sqlerrm || ' customer ' ||
                    nvl(to_char(lv_erp_i_wearerinv.customernumber), ' unknown ') || ' wearer ' ||
                    nvl(to_char(lv_erp_i_wearerinv.wearernumber), ' unknown') || ' ' || gv_message ||
                    ' file ' || fp_filename);
        end;
    end process_line;
  begin
    --process_file
    gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                  nvl(fp_directory, '<Empty>');
    --loop go through lines
    loop
      begin
        begin
          -- get line from file.
          utl_file.get_line(gv_filehandle, lv_readline);
          lv_line_counter := lv_line_counter + 1;
        exception
          when no_data_found then
            exit;
        end;
        --process_line
        gv_message := 'Linenumber ' || lv_line_counter;
        --process lines
        if substr(lv_readline, 1, 3) <> (gv_separator || gv_separator || gv_separator) then
          begin
            process_line(lv_readline);
          end;
        end if;
      end;
    end loop;
    --commit
    commit;
  end process_file;

  procedure close_file is
  begin
    --close file(s)
    gv_message := 'close files';
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  procedure finalize is
  begin
    --write log
    write_log('Successfully processed file ' || fp_filename || ' in directory ' || fp_directory);
  end finalize;
  --start main procedure
begin
  --initialize
  initialize;
  --read_file
  read_file;
  --process_file
  process_file;
  --close file
  close_file;
  --finalize
  finalize;
exception
  --exception handling global
  when gv_user__exception then
    begin
      rollback;
      write_log(gv_message, 3);
      close_file;
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error No Data Found ' || gv_message || ' file ' || fp_filename ||
                ' in directory ' || fp_directory, 3);
      close_file;
    end;
  when others then
    begin
      rollback;
      write_log(sqlerrm, 5);
      write_log('Error Others ' || gv_message || ' file ' || fp_filename || ' in directory ' ||
                fp_directory, 3);
      close_file;
    end;
end import_erp_wearerinv;
/

create or replace procedure import_supplierprice is
  /*version  1.0b*/
  gv_user__exception exception;
  gv_defaultuserid     systemuser.systemuser_id%type := 1;
  gv_message           varchar2(1000);
  gv_supplierid        supplier.supplier_id%type;
  gv_productid         product.product_id%type;
  gv_sizeid            sizedefinition.sizedefinition_id%type;
  gv_supplierproductid supplierproduct.supplierproduct_id%type;
  gv_counter_sp        number := 0;
  gv_counter_ssp       number := 0;
  gv_counter_spp       number := 0;

  procedure write_log(fp_message in varchar2, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'import_supplierprice', null, fp_priority, fp_message,
                             gv_defaultuserid);
    dbms_output.put_line(fp_message);
  end write_log;
begin
  for x in (select * from i_supplierproduct i) loop
    begin
      -- determine the supplier
      gv_message := 'Supplier ' || to_char(x.suppliernumber); 
      select s.supplier_id
      into   gv_supplierid
      from   supplier s
      where  s.suppliernumber = x.suppliernumber;
      begin
        -- determine product and size
        if x.laundryproductcode is not null then
          gv_message := 'Laundry Product code ' || x.laundryproductcode;  --Product code
          select p.product_id
          into   gv_productid
          from   product p
          where  p.code = trim(x.laundryproductcode);
          if x.laundrysizecode is not null then
            begin
              gv_message := 'Laundry Size code ' || x.laundrysizecode;  --Size code
              select s.sizedefinition_id
              into   gv_sizeid
              from   sizedefinition s
              where  s.code = trim(x.laundrysizecode);
            end;
          else
            begin
              gv_sizeid := null;
            end;
          end if;
        else
          begin
            gv_productid := null;
            gv_sizeid    := null;
          end;
        end if;
      exception
        when no_data_found then
          begin
            gv_productid := null;
            gv_sizeid    := null;
          end;
      end;
      begin
        gv_message := 'Supplier product for supplierproductcode ' || x.supplierproductcode ||
                      ' suppliersizecode ' || x.suppliersizecode;
        select min(s.supplierproduct_id)
        into   gv_supplierproductid
        from   supplierproduct s
        where  s.supplier_id = gv_supplierid
        and    s.supplierproductcode = x.supplierproductcode
        and    s.suppliersizecode = x.suppliersizecode;
        if gv_supplierproductid is null then
          -- create supplier product
          gv_message := 'Insert Supplier product for supplierproductcode ' || x.supplierproductcode ||
                        ' suppliersizecode ' || x.suppliersizecode;
          insert into supplierproduct
            (supplierproduct_id, supplier_id, supplierproductcode, supplierproductdescription,
             suppliersizecode, deliverydays, minorderqty, boxquantity, uniqueitem, active, remark,
             systemuser_id, timestamp)
          values
            (seq_supplierproduct.nextval, gv_supplierid, x.supplierproductcode,
             x.supplierproductdescription, x.suppliersizecode, x.deliverydays, x.minorderqty,
             x.boxquantity, x.uniqueitem, x.active, x.remark, gv_defaultuserid, sysdate)
          returning supplierproduct_id into gv_supplierproductid;
          gv_counter_sp := gv_counter_sp + 1;
        end if;
        if gv_productid is not null and gv_sizeid is not null then
          begin
            -- create productsizepersupproduct
            gv_message := 'Insert ProductSizePerSupProduct for Supplier supplierproductcode ' ||
                          x.supplierproductcode || ' suppliersizecode ' || x.suppliersizecode;
            insert into productsizepersupproduct
              (productsizepersupproduct_id, supplierproduct_id, product_id, sizedefinition_id,
               systemuser_id, timestamp)
            values
              (seq_productsizepersupproduct.nextval, gv_supplierproductid, gv_productid, gv_sizeid,
               gv_defaultuserid, sysdate);
            gv_counter_ssp := gv_counter_ssp + 1;
          exception
            when dup_val_on_index then
              null; -- no problem.
          end;
        end if;
        if gv_supplierproductid is not null then
          begin
            -- create supplier product price
            gv_message := 'Insert SupplierProductPrice for Supplier supplierproductcode ' ||
                          x.supplierproductcode || ' suppliersizecode ' || x.suppliersizecode;
            insert into supplierproductprice
              (supplierproductprice_id, supplierproduct_id, startdate, purchaseprice, systemuser_id,
               timestamp)
            values
              (seq_supplierproductprice.nextval, gv_supplierproductid,
               x.supplierproductprice_startdate, x.supplierproductprice, gv_defaultuserid, sysdate);
            gv_counter_spp := gv_counter_spp + 1;
          exception
            when dup_val_on_index then
              null; -- no problem.
          end;
        end if;
      exception
        when dup_val_on_index then
          null; -- no problem.
      end;
    end;
  end loop;
  if gv_counter_sp > 0 then
    write_log('Inserted ' || to_char(gv_counter_sp) || ' supplier product records');
  end if;
  if gv_counter_ssp > 0 then
    write_log('Inserted ' || to_char(gv_counter_ssp) ||
              ' product size per supplier product records');
  end if;
  if gv_counter_spp > 0 then
    write_log('Inserted ' || to_char(gv_counter_spp) || ' supplier product price records');
  end if;
exception
  --exception handling
  when gv_user__exception then
    begin
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      write_log('Error No Data Found ' || gv_message, 3); 
    end;
  when others then
    begin
      write_log(sqlerrm, 5);
      write_log('Error Others, see debug info, ' || gv_message, 3); 
    end;
end import_supplierprice;
/

create or replace procedure import_supplierproduct(fp_directory    in varchar2,
                                                   fp_seperator    in varchar2 default ',',
                                                   fp_systemuserid in number default 0) is
  --import_supplierproduct version 1.0
  --global variables
  gv_user__exception exception;
  gv_skip_line       exception;
  gv_defaultuserid   systemuser.systemuser_id%type := 0;
  gv_filehandle      utl_file.file_type;
  gv_message         abslog.message%type;
  gv_recordcountfile number;

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2 default null, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'import_supplierproduct', null, nvl(fp_priority, 1), fp_message,
                             gv_defaultuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --no problem
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_message       := 'initialize';
    gv_defaultuserid := nvl(fp_systemuserid, 0);
    if fp_directory is null then
      begin
        gv_message := 'parameter fp_directory cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
    if fp_seperator is null then
      begin
        gv_message := 'parameter fp_separator cannot be left empty!';
        raise gv_user__exception;
      end;
    end if;
  end initialize;

  procedure read_file(fp_filename in varchar2) is
  begin
    --open the file
    gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
    gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
  exception
    when utl_file.invalid_path then
      begin
        gv_message := gv_message || ' Invalid Path';
        raise gv_user__exception;
      end;
    when utl_file.invalid_mode then
      begin
        gv_message := gv_message || ' Invalid Mode';
        raise gv_user__exception;
      end;
    when utl_file.invalid_operation then
      begin
        gv_message := gv_message || ' Invalid Operation';
        raise gv_user__exception;
      end;
    when utl_file.invalid_filehandle then
      begin
        gv_message := gv_message || ' Invalid Filehandle';
        raise gv_user__exception;
      end;
    when utl_file.write_error then
      begin
        gv_message := gv_message || ' Write Error';
        raise gv_user__exception;
      end;
    when utl_file.read_error then
      begin
        gv_message := gv_message || ' Read Error';
        raise gv_user__exception;
      end;
    when utl_file.internal_error then
      begin
        gv_message := gv_message || ' Internal Error';
        raise gv_user__exception;
      end;
  end read_file;

  procedure process_file(fp_filename in varchar2) is
    lv_readline     varchar2(4000);
    lv_line_counter number := 0;
  
    ----process_file internal procedures
    procedure process_line(fp_readline in varchar2) is
      lv_suppliernumber      supplier.suppliernumber%type;
      lv_supplierproductcode supplierproduct.supplierproductcode%type;
      lv_supplierproductdesc supplierproduct.supplierproductdescription%type;
      lv_supplierid          supplier.supplier_id%type;
    
      ---process_file.process_line internal procedures
      procedure read_line(fp_readline in varchar2) is
        lv_currentposition number := 0;
        lv_nextposition    number := 0;
        lv_laststring      boolean := false;
      
        ---process_file.process_line.read_line internal function
        function get_nextvalue(fp_message in varchar2) return varchar2 is
        
          --process_file.process_line.read_line.get_nextvalue internal function
          function get_position(fp_startpos in number) return number is
          begin
            --get_position
            return instr(substr(fp_readline, fp_startpos + 1), fp_seperator) + fp_startpos;
          end get_position;
        begin
          --get_nextvalue
          lv_currentposition := lv_nextposition;
          lv_nextposition    := get_position(lv_currentposition);
          gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                to_char(lv_nextposition) || ' ' || fp_message;
          if lv_nextposition = lv_currentposition then
            begin
              --separator not found, so last field
              --last string, repeat it, if nothing else...
              if not lv_laststring then
                begin
                  lv_laststring := true;
                  --read last value
                  return trim(substr(fp_readline, lv_currentposition + 1));
                end;
              else
                begin
                  --no new values found!
                  return null;
                end;
              end if;
            end;
          else
            --read value
            return trim(substr(fp_readline, lv_currentposition + 1,
                               lv_nextposition - lv_currentposition - 1));
          end if;
        end get_nextvalue;
      begin
        --read_line
        lv_laststring := false;
        --read values
        lv_suppliernumber      := get_nextvalue('supplier number');
        lv_supplierproductcode := get_nextvalue('supplier product code');
        lv_supplierproductdesc := get_nextvalue('supplier product description');
      end read_line;
    
      procedure update_supplierproduct is
      begin
        --update_supplierproduct
        gv_message := 'get supplier number ' || to_char(lv_suppliernumber);
        select s.supplier_id
        into   lv_supplierid
        from   supplier s
        where  s.suppliernumber = lv_suppliernumber;
        --
        update supplierproduct spp
        set    spp.supplierproductdescription = lv_supplierproductdesc, spp.timestamp = sysdate,
               spp.systemuser_id = gv_defaultuserid
        where  spp.supplier_id = lv_supplierid
        and    spp.supplierproductcode = lv_supplierproductcode;
        gv_recordcountfile := sql%rowcount + gv_recordcountfile;
      end update_supplierproduct;
    begin
      --read
      read_line(fp_readline);
      --process
      update_supplierproduct;
    exception
      when gv_skip_line then
        begin
          write_log('Line# ' || to_char(lv_line_counter) || ' skipped', 1); --just skip this line, from check_line
        end;
      when gv_user__exception then
        begin
          write_log(gv_message, 3);
        end;
      when others then
        begin
          write_log('Line# ' || to_char(lv_line_counter) || sqlerrm || ' ' || gv_message, 3); --just skip this line, from check_line
        end;
    end process_line;
  begin
    --process_file
    gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                  nvl(fp_directory, '<Empty>');
    --loop go through lines
    loop
      begin
        begin
          -- get line from file.
          utl_file.get_line(gv_filehandle, lv_readline);
          lv_line_counter := lv_line_counter + 1;
        exception
          when no_data_found then
            exit;
        end;
        --process_line
        gv_message := 'Linenumber ' || lv_line_counter;
        process_line(lv_readline);
      end;
    end loop;
  end process_file;

  procedure close_file(fp_filename in varchar2 default null) is
  begin
    --close file(s)
    gv_message := 'close files ' || fp_filename;
    if utl_file.is_open(gv_filehandle) = true then
      utl_file.fclose(gv_filehandle);
    end if;
    utl_file.fclose_all;
  end close_file;

  procedure rename_file(fp_filename in varchar2) is
  begin
    --rename_file
    if gv_recordcountfile > 0 then
      begin
        gv_message := 'rename_file ' || fp_filename;
        utl_file.frename(fp_directory, fp_filename, fp_directory,
                         substr(fp_filename, 1, instr(fp_filename, '.')) || 'OLD', true);
      end;
    end if;
  end rename_file;

  procedure finalize_file(fp_filename in varchar2) is
  begin
    --finalize_file
    --commit
    commit;
    --write log
    write_log('Successfully processed file ' || fp_filename || ' ' || to_char(gv_recordcountfile) ||
              ' rows updated', 1);
  end finalize_file;
begin
  --start main procedure
  --initialize
  initialize;
  --open directory
  sys.abs_show_files(fp_directory);
  --loop to read the files
  gv_message := 'loop to read the files';
  for x in (select flt.file_name
            from   sys.abs_filelist flt
            where  upper(flt.file_name) like 'SUPPLIER%.CSV'
            and    flt.directory_name = fp_directory
            order  by flt.file_name) loop
    begin
      gv_recordcountfile := 0;
      --read_file
      read_file(x.file_name);
      --process_file
      process_file(x.file_name);
      --close file
      close_file(x.file_name);
      --rename file
      rename_file(x.file_name);
      --finalize_file
      finalize_file(x.file_name);
    exception
      when gv_user__exception then
        begin
          rollback;
          write_log(gv_message, 3);
          close_file;
        end;
      when no_data_found then
        begin
          rollback;
          write_log('Error No Data Found ' || gv_message || ' file ' || x.file_name ||
                    ' in directory ' || fp_directory, 3);
          close_file;
        end;
      when others then
        begin
          rollback;
          write_log('Error Others ' || gv_message || ' file ' || x.file_name || ' in directory ' ||
                    fp_directory || ' ' || sqlerrm, 3);
          close_file;
        end;
    end;
  end loop;
  --log procedure ran
  write_log('Ran for directory ' || fp_directory, 1);
exception
  --exception handling global
  when others then
    begin
      rollback;
      write_log('Error Others ' || gv_message || ' parameter directory ' || fp_directory ||
                ' parameter seperator ' || fp_seperator || ' ' || sqlerrm, 3);
      close_file;
    end;
end import_supplierproduct;
/

create or replace package importpaymentsauj is
  /**************************************************************************************************\
  * -- Author  : PVD/WBO version 3.02                                                                *
  * -- Created : 09-7-2010                                                                           *
  * -- Updated : 11-4-2010 for order 20011240 automatic write of differences in reconsiliation file  *
  * --           19-6-2012 latest version WBO                                                        *
  * --           23-7-2012 latest version WBO/PVD                                                    *
  * --           02-7-2014 latest version WBO/PVD use cash application instead of closing transaction*
  * --           10-7-2014 updated for remitbatch                                                    *
  * --           16-7-2015 updated for link to original artransaction                                *
  * --           17-7-2015 updated for remit batch id on artransaction                               *
  * --           07-12-2015 start using the new table AUJ_IMPORTRECONCILIATIONFILE                   *
  *              07-09-2021 removed use of AUJ_IMPORTRECONCILIATIONFILE                              *
  * -- Purpose : This package contains a number of database procedures and functions for             *
  *    importing payments from external files into ABSsolute and automatically apply these payments. *
  *    These procedures are used from the ABSsolute client itself,                                   *
  *    but they can also be used in scripts that can be scheduled via the script scheduler.          *
  \**************************************************************************************************/

  --import procedures use FINIMPORTDIRECTORY directory from systemsetting table
  procedure importreconciliationfile(fp_remark        in varchar2,
                                     fp_systemuserid  in systemuser.systemuser_id%type,
                                     fp_plantid       in plant.plant_id%type,
                                     fp_dialogid      in dialogs.dialog_id%type,
                                     fp_workstationid in workstation.workstation_id%type);

  procedure importnotreconciliatedpayments(fp_remark        in varchar2,
                                           fp_systemuserid  in systemuser.systemuser_id%type,
                                           fp_plantid       in plant.plant_id%type,
                                           fp_dialogid      in dialogs.dialog_id%type,
                                           fp_workstationid in workstation.workstation_id%type);

  --export procedures use FINEXPORTDIRECTORY directory from systemsetting table
  procedure exportcustomerdata(fp_plantid            in plant.plant_id%type,
                               fp_workstationid      in workstation.workstation_id%type,
                               fp_systemuserid       in systemuser.systemuser_id%type,
                               fp_dialogid           in dialogs.dialog_id%type,
                               fp_notexported        in number,
                               fp_minbucode          in businessunit.code%type,
                               fp_maxbucode          in businessunit.code%type,
                               fp_mincustomer        in customer.customernumber%type,
                               fp_maxcustomer        in customer.customernumber%type,
                               fp_mindate            in date,
                               fp_maxdate            in date,
                               fp_abslogprocessjobid out abslogprocessjob.abslogprocessjob_id%type);

  procedure exportinvoicedata(fp_abslogprocessjobid in abslogprocessjob.abslogprocessjob_id%type,
                              fp_systemuserid       in systemuser.systemuser_id%type,
                              fp_notexported        in number,
                              fp_minbucode          in businessunit.code%type,
                              fp_maxbucode          in businessunit.code%type,
                              fp_mincustomer        in customer.customernumber%type,
                              fp_maxcustomer        in customer.customernumber%type,
                              fp_mindate            in date,
                              fp_maxdate            in date);

end importpaymentsauj;
/
/
create or replace package body importpaymentsauj is
  e_user_exception_error exception;
  gv_abslogprocessjobid      abslogprocessjob.abslogprocessjob_id%type;
  gv_abslogprocessjobpartid  abslogprocessjobpart.abslogprocessjobpart_id%type;
  gv_processname             abslogprocessjobpart.processname%type;
  gv_plantid                 plant.plant_id%type;
  gv_plantprocessid          plantprocess.plantprocess_id%type;
  gv_systemuserid            systemuser.systemuser_id%type;
  gv_dialogid                dialogs.dialog_id%type;
  gv_workstationid           workstation.workstation_id%type;
  gv_message                 abslogprocessjobline.message%type;
  gv_remitbatchstatus_1      status.status_id%type;
  gv_remitbatchstatus_2      status.status_id%type;
  gv_separator               varchar2(1);
  gv_databaselogdir          systemsetting.value%type;
  gv_d_banktransferfeetypeid artransactiontype.artransactiontype_id%type;
  gv_c_banktransferfeetypeid artransactiontype.artransactiontype_id%type;
  gv_d_awdid                 artransactiontype.artransactiontype_id%type;

  procedure initialize is
  begin
    --initialize
    gv_processname            := 'package importpaymentsauj';
    gv_message                := 'initialize';
    gv_abslogprocessjobid     := null;
    gv_abslogprocessjobpartid := null;
    gv_processname            := null;
    gv_plantid                := null;
    gv_plantprocessid         := null;
    gv_systemuserid           := 0;
    gv_dialogid               := null;
    gv_workstationid          := null;
    --get default values
    gv_message := 'initialize getting remitbatch status 1';
    select st.status_id
    into   gv_remitbatchstatus_1
    from   status st
    where  st.statustype = 'RB'
    and    st.code = '1';
    gv_message := 'initialize getting remitbatch status 1';
    select st.status_id
    into   gv_remitbatchstatus_2
    from   status st
    where  st.statustype = 'RB'
    and    st.code = '2';
    -- Determine BankTransferFeeTypeID
    gv_message := 'initialize getting the Debit BankTransferFeeType which is artransactiontype with code BTF';
    select at.artransactiontype_id
    into   gv_d_banktransferfeetypeid
    from   artransactiontype at
    where  at.debitcredit = 'D'
    and    at.predefined = 'N'
    and    at.code = 'BTF';
    -- Determine BankTransferFeeTypeID
    gv_message := 'initialize getting the BANKING FEE (previous Automatic Writeoff discount which is artransactiontype with code AWD)';
    select at.artransactiontype_id
    into   gv_d_awdid
    from   artransactiontype at
    where  at.debitcredit = 'C'
    and    at.predefined = 'N'
          --and    at.code = 'AWD'
    and    at.typenumber = 6; --wbo changes 6-7-2012
    -- Determine BankTransferFeeTypeID
    gv_message := 'initialize getting the Credit BankTransferFeeType which is artransactiontype with code BTF';
    select at.artransactiontype_id
    into   gv_c_banktransferfeetypeid
    from   artransactiontype at
    where  at.debitcredit = 'C'
    and    at.predefined = 'N'
    and    at.code = 'BTF';
  end initialize;

  procedure end_log is
  begin
    if gv_abslogprocessjobid is not null then
      --end_log
      abslogwrite.abslogprocessjob_update(gv_abslogprocessjobid, sysdate, gv_systemuserid);
    else
      --write_log
      abslogwrite.abslog_write(5, nvl(substr(gv_processname, 1, 30), 'importpaymentsauj'), null, 3,
                               gv_message || ' ' || sqlerrm, gv_systemuserid);
    end if;
  exception
    when others then
      begin
        dbms_output.put_line(gv_message);
        dbms_output.put_line(sqlerrm);
      end;
  end end_log;

  procedure write_log(fp_priority abslogprocessjobline.priority%type default 1) is
  begin
    --write_log
    if gv_abslogprocessjobid is null and gv_abslogprocessjobpartid is null then
      gv_abslogprocessjobid := abslogwrite.abslogprocessjob_write(gv_plantid, sysdate,
                                                                  gv_workstationid, gv_dialogid,
                                                                  gv_plantprocessid, gv_systemuserid);
    end if;
    --write_log part
    if gv_abslogprocessjobpartid is null and gv_abslogprocessjobid is not null then
      gv_abslogprocessjobpartid := abslogwrite.abslogprocessjobpart_write(gv_abslogprocessjobid,
                                                                          gv_processname,
                                                                          gv_systemuserid);
    end if;
    abslogwrite.abslogprocessjobline_write(gv_abslogprocessjobpartid, fp_priority, gv_message,
                                           gv_systemuserid);
  exception
    when others then
      begin
        dbms_output.put_line(gv_message);
        dbms_output.put_line(sqlerrm);
      end;
  end write_log;

  function open_file(fp_filename in varchar2, fp_openmode in varchar2 default 'a')
    return utl_file.file_type is
    lp_filehandle utl_file.file_type;
  begin
    --open file, open mode ('r', 'w', 'a' 'rb', 'wb', 'ab')
    gv_message    := 'open file ' || gv_databaselogdir || fp_filename;
    lp_filehandle := utl_file.fopen(gv_databaselogdir, fp_filename, fp_openmode, 32767);
    return lp_filehandle;
  exception
    when utl_file.invalid_path then
      gv_message := gv_message || ' Invalid Path';
      raise;
    when utl_file.invalid_mode then
      gv_message := gv_message || ' Invalid Mode';
      raise;
    when utl_file.invalid_operation then
      gv_message := gv_message || ' Invalid Operation, check if directory exists';
      raise;
    when utl_file.invalid_filehandle then
      gv_message := gv_message || ' Invalid FileHandle';
      raise;
    when utl_file.write_error then
      gv_message := gv_message || ' Write Error';
      raise;
    when utl_file.read_error then
      gv_message := gv_message || ' Read Error';
      raise;
    when utl_file.internal_error then
      gv_message := gv_message || ' Internal Error';
      raise;
    when others then
      raise;
  end open_file;

  procedure close_file(fp_filehandle in out utl_file.file_type) is
  begin
    --close file
    gv_message := 'close file';
    if utl_file.is_open(fp_filehandle) = true then
      utl_file.fclose(fp_filehandle);
    end if;
  end close_file;

  procedure delete_file(fp_filename in varchar2) is
  begin
    --delete_file
    gv_message := 'delete_file';
    utl_file.fremove(gv_databaselogdir, fp_filename);
    -- if file is not there no problem its already gone.
    -- only try to delete if possible.
  exception
    when others then
      null;
  end delete_file;

  procedure write_line(fp_filehandle in utl_file.file_type, fp_text in varchar2) is
  begin
    --write xml block or line
    utl_file.put_line(fp_filehandle, convert(fp_text, 'JA16SJIS', 'UTF8'));
  end write_line;

  function get_separators(lv_number in number) return varchar2 is
    lv_separators varchar2(1000);
  begin
    if lv_number > 0 then
      for i in 1 .. lv_number loop
        begin
          lv_separators := lv_separators || gv_separator;
          if i = 1000 then
            exit;
          end if;
        end;
      end loop;
    end if;
    return lv_separators;
  end get_separators;

  procedure get_csv_systemsettings(fp_import boolean default true) is
  begin
    --get_csv_systemsetting CSVGRIDEXPORTSEPARATOR
    gv_message := 'get_csv_systemsettings CSVGRIDEXPORTSEPARATOR for plant id ' || gv_plantid;
    select s.value
    into   gv_separator
    from   systemsetting s
    where  s.name = 'CSVGRIDEXPORTSEPARATOR'
    and    s.plant_id = gv_plantid;
    if gv_separator = '1' then
      gv_separator := ',';
    else
      gv_separator := ';';
    end if;
    if fp_import then
      begin
        --get_csv_systemsetting FINIMPORTDIRECTORY
        gv_message := 'get_csv_systemsettings FINIMPORTDIRECTORY for plant id ' || gv_plantid;
        select s.value
        into   gv_databaselogdir
        from   systemsetting s
        where  s.name = 'FINIMPORTDIRECTORY'
        and    s.plant_id = gv_plantid;
      end;
    else
      begin
        --get_csv_systemsetting FINEXPORTDIRECTORY
        gv_message := 'get_csv_systemsettings FINEXPORTDIRECTORY for plant id ' || gv_plantid;
        select s.value
        into   gv_databaselogdir
        from   systemsetting s
        where  s.name = 'FINEXPORTDIRECTORY'
        and    s.plant_id = gv_plantid;
      end;
    end if;
  end get_csv_systemsettings;

  function get_cust_currency(fp_customerid in customer.customer_id%type) return number is
    lv_currencyid currency.currency_id%type;
  begin
    --get_cust_currency
    gv_message := ' get_cust_currency for customer id ' || fp_customerid;
    select c.currency_id into lv_currencyid from customer c where c.customer_id = fp_customerid;
    return lv_currencyid;
  end get_cust_currency;

  function create_paymenttransaction(fp_rec_paymenttransaction in out paymenttransaction%rowtype,
                                     fp_refence_cust           in number default 0,
                                     fp_customerid             in number default null) return boolean is
  begin
    --create_paymenttransaction
    gv_message := 'create_paymenttransaction';
    --get paymenttransaction_id
    select seq_paymenttransaction.nextval
    into   fp_rec_paymenttransaction.paymenttransaction_id
    from   dual;
    --get other values
    fp_rec_paymenttransaction.paymenttype         := 3;
    fp_rec_paymenttransaction.importtimestamp     := sysdate;
    fp_rec_paymenttransaction.processingtimestamp := null;
    fp_rec_paymenttransaction.processinguser_id   := null;
    fp_rec_paymenttransaction.artransaction_id    := null;
    fp_rec_paymenttransaction.systemuser_id       := gv_systemuserid;
    fp_rec_paymenttransaction.timestamp           := sysdate;
    --get extra info
    case fp_refence_cust
      when 0 then
        begin
          --get customer link id
          gv_message := 'get customer link id for customer,payment reference ' ||
                        fp_rec_paymenttransaction.reference;
          select c.customer_id, c.defaultbusinessunit_id
          into   fp_rec_paymenttransaction.customer_link_id,
                 fp_rec_paymenttransaction.businessunit_id
          from   customer c
          where  c.customernumber = to_number(fp_rec_paymenttransaction.reference);
          --fill status
          fp_rec_paymenttransaction.status        := 0;
          fp_rec_paymenttransaction.messagenumber := 0;
          fp_rec_paymenttransaction.currency_id   := get_cust_currency(fp_rec_paymenttransaction.customer_link_id);
        exception
          when others then
            begin
              --errors fill with error=status 2
              fp_rec_paymenttransaction.customer_link_id := null;
              fp_rec_paymenttransaction.businessunit_id  := null;
              fp_rec_paymenttransaction.status           := 2;
              fp_rec_paymenttransaction.messagenumber    := 1;
              fp_rec_paymenttransaction.currency_id      := null;
              --write log
              write_log(2);
              raise;
            end;
        end;
      when 1 then
        begin
          --get customer link id
          gv_message := 'get customer link id for invoice number, payment reference ' ||
                        fp_rec_paymenttransaction.reference;
          select a.billtocustomer_link_id, c.defaultbusinessunit_id
          into   fp_rec_paymenttransaction.customer_link_id,
                 fp_rec_paymenttransaction.businessunit_id
          from   artransaction a, customer c
          where  a.invoicenumber = to_number(fp_rec_paymenttransaction.reference)
          and    a.billtocustomer_link_id = c.customer_id
          and    rownum = 1
          order  by a.artransaction_id desc;
          --fill status
          fp_rec_paymenttransaction.status        := 0;
          fp_rec_paymenttransaction.messagenumber := 0;
          fp_rec_paymenttransaction.currency_id   := get_cust_currency(fp_rec_paymenttransaction.customer_link_id);
        exception
          when others then
            begin
              --errors fill with error=status 2
              fp_rec_paymenttransaction.customer_link_id := null;
              fp_rec_paymenttransaction.businessunit_id  := null;
              fp_rec_paymenttransaction.status           := 2;
              fp_rec_paymenttransaction.messagenumber    := 1;
              fp_rec_paymenttransaction.currency_id      := null;
              --write log
              write_log(2);
              raise;
            end;
        end;
      when 2 then
        begin
          --get customer link id
          gv_message := 'get customer link id for invoice number, customer id ' ||
                        nvl(to_char(fp_customerid), 'NULL');
          select c.customer_id, c.defaultbusinessunit_id
          into   fp_rec_paymenttransaction.customer_link_id,
                 fp_rec_paymenttransaction.businessunit_id
          from   customer c
          where  c.customer_id = fp_customerid;
          --fill status
          fp_rec_paymenttransaction.status        := 0;
          fp_rec_paymenttransaction.messagenumber := 0;
          fp_rec_paymenttransaction.currency_id   := get_cust_currency(fp_rec_paymenttransaction.customer_link_id);
        exception
          when others then
            begin
              --errors fill with error=status 2
              fp_rec_paymenttransaction.customer_link_id := null;
              fp_rec_paymenttransaction.businessunit_id  := null;
              fp_rec_paymenttransaction.status           := 2;
              fp_rec_paymenttransaction.messagenumber    := 1;
              fp_rec_paymenttransaction.currency_id      := null;
              --write log
              write_log(2);
              raise;
            end;
        end;
    end case; --fp_refence_cust
    --create paymenttransaction
    gv_message := 'insert into paymenttransaction payment reference ' ||
                  fp_rec_paymenttransaction.reference;
    insert into paymenttransaction values fp_rec_paymenttransaction;
    return true;
  exception
    when others then
      begin
        gv_message := 'error during payment ' || fp_rec_paymenttransaction.reference || ' ' ||
                      sqlerrm;
        write_log(3);
        return false;
      end;
  end create_paymenttransaction;

  function create_paymenttransactdetail(fp_rec_paymenttransaction in paymenttransaction%rowtype,
                                        fp_banktransferfee        in number,
                                        fp_artransactionid        in artransaction.artransaction_id%type,
                                        fp_invoicenumber          in artransaction.invoicenumber%type,
                                        fp_discountamount         in paymenttransactiondetail.discountamount%type)
    return boolean is
    lv_rec_paymenttransdetail paymenttransactiondetail%rowtype;
  begin
    --create_paymenttransactiondetail
    gv_message := 'create_paymenttransactdetail';
    --get paymenttransactiondetail id
    select seq_paymenttransactiondetail.nextval
    into   lv_rec_paymenttransdetail.paymenttransactiondetail_id
    from   dual;
    --fill invoicenumber
    gv_message                              := gv_message || ' fill invoice number ' ||
                                               fp_rec_paymenttransaction.reference;
    lv_rec_paymenttransdetail.invoicenumber := nvl(fp_invoicenumber,
                                                   to_number(fp_rec_paymenttransaction.reference));
    gv_message                              := 'create_paymenttransactdetail';
    --fill other fields
    lv_rec_paymenttransdetail.paymenttransaction_id := fp_rec_paymenttransaction.paymenttransaction_id;
    lv_rec_paymenttransdetail.detailreference := case
                                                   when fp_banktransferfee is not null then
                                                    fp_invoicenumber
                                                   else
                                                    fp_rec_paymenttransaction.reference
                                                 end;
    lv_rec_paymenttransdetail.grossamount := case
                                               when fp_banktransferfee is not null then
                                                fp_banktransferfee
                                               else
                                                fp_rec_paymenttransaction.amount
                                             end;
    lv_rec_paymenttransdetail.discountamount        := fp_discountamount;
    lv_rec_paymenttransdetail.systemuser_id         := gv_systemuserid;
    lv_rec_paymenttransdetail.timestamp             := sysdate;
    lv_rec_paymenttransdetail.artransaction_id      := fp_artransactionid;
    lv_rec_paymenttransdetail.messagenumber         := 0;
    --create record
    insert into paymenttransactiondetail values lv_rec_paymenttransdetail;
    return true;
  exception
    when others then
      begin
        gv_message := 'create_paymenttransactdetail, error during payment ' ||
                      fp_rec_paymenttransaction.reference || ' ' || sqlerrm;
        write_log(3);
        return false;
      end;
  end create_paymenttransactdetail;

  function get_field(fp_position in number, fp_line in varchar2) return varchar2 is
    x              number := 0; --get position
    y              number := 0; --go to field number
    lv_returnvalue varchar2(1000);
  begin
    --get_field
    gv_message := 'get_field position ' || fp_position;
    while y < fp_position loop
      begin
        x := instr(fp_line, gv_separator, x);
        x := x + 1;
        y := y + 1;
      end;
    end loop;
    lv_returnvalue := substr(fp_line, x, instr(fp_line, gv_separator, x + 1) - x);
    if lv_returnvalue = ',' then
      return null;
    else
      return lv_returnvalue;
    end if;
  end get_field;

  procedure importreconciliationfile(fp_remark        in varchar2,
                                     fp_systemuserid  in systemuser.systemuser_id%type,
                                     fp_plantid       in plant.plant_id%type,
                                     fp_dialogid      in dialogs.dialog_id%type,
                                     fp_workstationid in workstation.workstation_id%type) is
    lv_filename              varchar2(64) := 'match.csv';
    lv_filehandle            utl_file.file_type;
    lv_line                  varchar2(4000);
    lv_counter               number := 0;
    lv_remitbatchid          remitbatch.remitbatch_id%type := null;
    lv_plantcode             plant.code%type;
    lv_previouscustomerid    customer.customer_id%type := null;
    lv_remaining_amount      artransaction.amount%type;
    lv_paymentdate           date;
    lv_rec_paymentransaction paymenttransaction%rowtype;
    lv_continue              boolean;
    lv_newcustomerid         number;
    lv_artransactionid_o     artransaction.artransaction_id%type := null;
    lv_total_invoice         number := 0;
    lv_total_paid            number := 0;

    procedure check_parameters is
    begin
      if fp_plantid is null then
        begin
          gv_message := 'parameter fp_plantid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
      if fp_systemuserid is null then
        begin
          gv_message := 'parameter fp_systemuserid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
      select pt.code into lv_plantcode from plant pt where pt.plant_id = fp_plantid;
    exception
      when no_data_found then
        begin
          gv_message := 'parameter fp_plantid ' || fp_plantid || ' could not be found';
          raise e_user_exception_error;
        end;
    end check_parameters;

    function get_customer_id(fp_customernumber in customer.customernumber%type)
      return customer.customer_id%type is
      lv_customerid customer.customer_id%type;
    begin
      gv_message := 'Get customer id for customer number  ' || fp_customernumber;
      select c.customer_id
      into   lv_customerid
      from   customer c
      where  c.customernumber = fp_customernumber;
      return lv_customerid;
    exception
      when no_data_found then
        begin
          return null;
        end;
    end get_customer_id;

    procedure process_payment is
    begin
      --process_payment
      gv_message := 'process_payment';
      --Making sure there is no Open difference!
      lv_rec_paymentransaction.amount := lv_total_invoice - lv_total_paid;
      if lv_rec_paymentransaction.amount > 0 then
        begin
          lv_artransactionid_o := importpayments.create_artransaction(lv_rec_paymentransaction,
                                                                      fp_remark, lv_remitbatchid, 7,
                                                                      'C',
                                                                      --wbo change 6-7
                                                                      gv_d_awdid,
                                                                      lv_rec_paymentransaction.reference);
        end;
      else
        lv_artransactionid_o := null;
      end if;
      if lv_continue then
        begin
          --step 3
          if lv_rec_paymentransaction.status = 0 then
            begin
              --step 4 process payment
              lv_rec_paymentransaction.amount := lv_total_paid;
              importpayments.processpaymenttransaction(lv_rec_paymentransaction.paymenttransaction_id,
                                                       lv_remitbatchid, gv_abslogprocessjobpartid,
                                                       fp_remark, fp_systemuserid, 0, true,
                                                       lv_rec_paymentransaction.reference, true,
                                                       lv_artransactionid_o);
            end;
          end if; --lv_rec_paymentransaction.status = 0
          if lv_artransactionid_o is not null then
            begin
              update artransaction a
              set    a.invoicenumber =
                      (select art.invoicenumber
                       from   artransaction art
                       where  art.artransaction_id = a.originaltransaction_id),
                     a.invoiceheader_id =
                      (select art.invoiceheader_id
                       from   artransaction art
                       where  art.artransaction_id = a.originaltransaction_id),
                     a.billtocustomer_link_id =
                      (select art.billtocustomer_link_id
                       from   artransaction art
                       where  art.artransaction_id = a.originaltransaction_id),
                     a.deltocustomer_link_id =
                      (select art.deltocustomer_link_id
                       from   artransaction art
                       where  art.artransaction_id = a.originaltransaction_id),
                     a.remitbatch_id = coalesce(a.remitbatch_id, lv_remitbatchid)
              where  a.artransaction_id = lv_artransactionid_o;
            end;
          end if;
          --processpaymenttransaction;
          lv_counter := lv_counter + 1;
        end;
      end if; --if lv_continue
    end process_payment;

    procedure process_line is
      lv_paid_amount    number;
      lv_invoiceamount  number;
      lv_discountamount number;

      procedure check_paid_amount is
      begin
        if lv_paid_amount > lv_invoiceamount then
          begin
            lv_remaining_amount := lv_paid_amount - lv_invoiceamount;
            lv_paid_amount      := lv_invoiceamount;
          end;
        else
          lv_remaining_amount := 0;
        end if;
      end check_paid_amount;
    begin
      --process_line
      gv_message := 'importreconciliationfile.process_line';
      --get field values
      lv_continue      := true;
      lv_newcustomerid := get_customer_id(replace(get_field(3, lv_line), 'Z', 0));
      if lv_newcustomerid <> lv_previouscustomerid then
        begin
          process_payment;
          lv_total_invoice := 0;
          lv_total_paid    := 0;
        end;
      end if;
      gv_message                                := 'paid_amount field 53';
      lv_paid_amount                            := get_field(53, lv_line);
      lv_total_paid                             := nvl(lv_paid_amount, 0) + lv_total_paid;
      gv_message                                := 'invoiceamount field 15';
      lv_invoiceamount                          := get_field(15, lv_line);
      lv_total_invoice                          := nvl(lv_invoiceamount, 0) + lv_total_invoice;
      gv_message                                := 'batchnumber field 5';
      lv_rec_paymentransaction.batchnumber      := get_field(5, lv_line);
      gv_message                                := 'reference field 6';
      lv_rec_paymentransaction.reference        := get_field(6, lv_line);
      gv_message                                := 'paymentdate field 52';
      lv_rec_paymentransaction.paymentdate      := to_date(get_field(52, lv_line), 'YYYYMMDD');
      gv_message                                := 'origin field 55';
      lv_rec_paymentransaction.origin           := get_field(55, lv_line);
      gv_message                                := 'process line';
      lv_rec_paymentransaction.customer_link_id := lv_newcustomerid;
      --payment for same customer..?
      if nvl(lv_previouscustomerid, 0) = lv_rec_paymentransaction.customer_link_id and
         lv_paid_amount is null and lv_rec_paymentransaction.paymentdate is null then
        begin
          lv_paid_amount                       := lv_remaining_amount;
          lv_rec_paymentransaction.paymentdate := lv_paymentdate;
          check_paid_amount;
        end;
      else
        begin
          lv_previouscustomerid := lv_rec_paymentransaction.customer_link_id;
          lv_paymentdate        := lv_rec_paymentransaction.paymentdate;
          --Step 2 create_paymenttransaction/detail
          lv_rec_paymentransaction.amount := lv_paid_amount;
          lv_continue                     := create_paymenttransaction(lv_rec_paymentransaction, 2,
                                                                       lv_rec_paymentransaction.customer_link_id);
          check_paid_amount;
        end;
      end if;
      if lv_continue then
        begin
          lv_rec_paymentransaction.amount := lv_paid_amount;
          if lv_total_invoice - lv_total_paid > 0 then
            lv_discountamount := lv_total_invoice - lv_total_paid;
          else
            lv_discountamount := 0;
          end if;
          lv_continue := create_paymenttransactdetail(lv_rec_paymentransaction, null, null,
                                                      lv_rec_paymentransaction.reference,
                                                      lv_discountamount);
        end;
      end if;
    end process_line;

    procedure read_file is
      lv_remitamount      number := 0;
      lv_paymentransbu_id number := 141;
      lv_businessunitcode businessunit.code%type := null;
    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.read_file';
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          if lv_businessunitcode is null and lv_remitbatchid is null then
            lv_remitbatchid := importpayments.create_remitbatch(lv_paymentransbu_id,
                                                                lv_businessunitcode,
                                                                to_date(get_field(52, lv_line),
                                                                         'YYYYMMDD'), 1);
          end if;
          process_line;
        end;
      end loop;
      process_payment;
      lv_remitamount := importpayments.update_remitbatch(lv_remitbatchid);
      --step 5 messages in log
      gv_message := 'Businessunit ' || lv_businessunitcode || ' total remit batch ' ||
                    lv_remitamount;
      write_log(1);
    end read_file;

    procedure check_file_struc is
      -- added WBO 28-2-2013 to check if the lines in the file are formatted well
      lv_statementcounter       number := 0;
      lv_statementcounter_error number := 0;
      lv_invoiceamount          number := 0;
      lv_paid_amount            number := 0;
      lv_previouscustomerid_2   number := 0;
    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.check_file_struc';
      write_log(1);
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          --process_line
          -- gv_message := 'importreconciliationfile.check statements';
          -- write_log(1);
          --get field values
          lv_newcustomerid := get_customer_id(replace(get_field(3, lv_line), 'Z', 0));
          gv_message       := 'get paid amount field 53';
          lv_paid_amount   := get_field(53, lv_line);
          ---WBO -->lv_total_paid := nvl(lv_paid_amount, 0) + lv_total_paid;
          gv_message                           := 'get lv_invoiceamount field 15';
          lv_invoiceamount                     := get_field(15, lv_line);
          gv_message                           := 'get batchnumber field 5';
          lv_rec_paymentransaction.batchnumber := get_field(5, lv_line);
          gv_message                           := 'get reference field 6';
          lv_rec_paymentransaction.reference   := get_field(6, lv_line);
          gv_message                           := 'get paymentdate field 52';
          lv_rec_paymentransaction.paymentdate := to_date(get_field(52, lv_line), 'YYYYMMDD');
          gv_message                           := 'check_file_struc';
          lv_statementcounter                  := lv_statementcounter + 1;
          if ((lv_newcustomerid is null or lv_rec_paymentransaction.batchnumber is null or
             lv_rec_paymentransaction.reference is null or lv_invoiceamount is null or
             lv_paid_amount is null or lv_rec_paymentransaction.paymentdate is null) and
             lv_newcustomerid <> lv_previouscustomerid_2) or
             ((lv_newcustomerid is null or lv_rec_paymentransaction.batchnumber is null or
             lv_rec_paymentransaction.reference is null or lv_invoiceamount is null) and
             lv_newcustomerid = lv_previouscustomerid_2) then
            begin
              lv_statementcounter_error := lv_statementcounter_error + 1;
              gv_message                := 'File line nr ' || lv_statementcounter ||
                                           ' does not contain right formatted data';
              write_log(1);
            end;
          end if;
        end;
        lv_previouscustomerid_2 := lv_newcustomerid;
      end loop;
      --step 5 messages in log
      if lv_statementcounter_error > 0 then
        gv_message := 'Number of lines not formatted well: ' || lv_statementcounter ||
                      ' Please check the match file';
        write_log(1);
        end_log;
        --   close_file(lv_filehandle);
        raise e_user_exception_error;
      else
        gv_message := 'data file is ok';
        write_log(1);
        end_log;
        --  close_file(lv_filehandle);
      end if;

    end check_file_struc;

    procedure check_file is
      -- added WBO 19-7-2012 to check if there are already statements which are already imported
      lv_statementcounter number := 0;
      lv_paymentnr        number := 0;
      --   lv_detailinvoicenr number :=0;
    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.check_file';
      write_log(1);
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          --process_line
          -- gv_message := 'importreconciliationfile.check statements';
          -- write_log(1);
          --get field values
          lv_rec_paymentransaction.reference := get_field(6, lv_line);
          select max(pta.paymenttransaction_id)
          into   lv_paymentnr
          from   paymenttransaction pta
          where  pta.reference = lv_rec_paymentransaction.reference;
          if lv_paymentnr is not null then
            begin
              lv_statementcounter := lv_statementcounter + 1;
              gv_message          := 'Statement ' || lv_rec_paymentransaction.reference ||
                                     ' already imported';
              write_log(1);
            end;
          end if;
        end;
      end loop;
      --step 5 messages in log
      if lv_statementcounter > 0 then
        gv_message := 'Already ' || lv_statementcounter || ' statements imported';
        write_log(1);
        end_log;
        --   close_file(lv_filehandle);
        raise e_user_exception_error;

      else
        gv_message := 'no already imported statements';
        write_log(1);
        end_log;
        --  close_file(lv_filehandle);
      end if;

    end check_file;

    procedure check_file_man is
      -- added WBO 19-7-2012 to check if there are already statements which are manual applied
      lv_statementcounter number := 0;
      lv_statementnr      number := 0;
    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.check_file';
      write_log(1);
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          --process_line
          -- gv_message := 'importreconciliationfile.check statements';
          -- write_log(1);
          --get field values
          lv_rec_paymentransaction.reference := get_field(6, lv_line);
          select max(st.invoicenumber)
          into   lv_statementnr
          from   invoiceheader st, statementline sl, artransaction a
          where  st.invoicenumber = lv_rec_paymentransaction.reference
          and    st.invoiceheader_id = sl.invoiceheader_id
          and    sl.artransaction_id = a.artransaction_id
          and    a.remitbatch_id is null;
          if lv_statementnr is null then
            begin
              lv_statementcounter := lv_statementcounter + 1;
              gv_message          := 'Statement ' || lv_rec_paymentransaction.reference ||
                                     ' already manual applied for ' ||
                                     nvl(lv_rec_paymentransaction.reference, 'NULL');
              write_log(1);
            end;
          end if;
        end;
      end loop;
      --step 5 messages in log
      if lv_statementcounter > 0 then
        gv_message := 'Already ' || lv_statementcounter || ' statements manual applied';
        write_log(1);
        end_log;
        --   close_file(lv_filehandle);
        raise e_user_exception_error;

      else
        gv_message := 'no already applied statements';
        write_log(1);
        end_log;
        --  close_file(lv_filehandle);
      end if;
    end check_file_man;

    procedure check_file_partly_apl is
      -- added WBO 03-02-2013 to check if there are already detail invoices applied
      lv_statementcounter number := 0;
      --lv_paymentnr number :=0;
      lv_detailinvoicenr number := 0;

    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.check_file';
      write_log(1);
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          --process_line
          -- gv_message := 'importreconciliationfile.check statements';
          -- write_log(1);
          --get field values
          lv_rec_paymentransaction.reference := get_field(6, lv_line);
          select min(ihd.invoicenumber)
          into   lv_detailinvoicenr
          from   invoiceheader ih, statementline sl, artransaction ar, invoiceheader ihd
          where  ih.documenttype = 2
          and    ih.invoiceheader_id = sl.invoiceheader_id
          and    ar.artransaction_id = sl.artransaction_id
          and    ihd.invoiceheader_id = ar.invoiceheader_id
          and    ih.invoicenumber = lv_rec_paymentransaction.reference
          and    exists (select 1
                  from   cashapplication ca
                  where  ca.debitartransaction_id = ar.artransaction_id);
          if lv_detailinvoicenr is not null then
            begin
              lv_statementcounter := lv_statementcounter + 1;
              gv_message          := 'At least one detail invoice ' || lv_detailinvoicenr ||
                                     ' connected to statement ' ||
                                     lv_rec_paymentransaction.reference || ' is already applied';
              write_log(1);
            end;
          end if;
        end;
      end loop;
      --step 5 messages in log
      if lv_statementcounter > 0 then
        gv_message := 'Already ' || lv_statementcounter || ' statements already (partly) applied ';
        write_log(1);
        end_log;
        --   close_file(lv_filehandle);
        raise e_user_exception_error;

      else
        gv_message := 'no already applied detail invices invoices';
        write_log(1);
        end_log;
        --  close_file(lv_filehandle);
      end if;
      --- check invoices with amounts < banking fee
      -- end;

    end check_file_partly_apl;

    procedure check_file_bf is
      -- added WBO 03-02-2013 to check if there are already detail invoices applied
      lv_statementcounter number := 0;
      lv_detailamount     number := 0;
      lv_btf              number := 0;
    begin
      -- read the file in loop
      gv_message := gv_message || ' importreconciliationfile.check_file';
      write_log(1);
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          --process_line
          --get field values
          lv_rec_paymentransaction.reference := get_field(6, lv_line);
          lv_btf                             := get_field(36, lv_line);
          select max(ihd.paythisamount)
          into   lv_detailamount
          from   invoiceheader ih, statementline sl, artransaction ar, invoiceheader ihd
          where  ih.documenttype = 2
          and    ih.invoiceheader_id = sl.invoiceheader_id
          and    ar.artransaction_id = sl.artransaction_id
          and    ihd.invoiceheader_id = ar.invoiceheader_id
          and    ih.invoicenumber = lv_rec_paymentransaction.reference;
          if lv_detailamount < lv_btf then
            begin
              lv_statementcounter := lv_statementcounter + 1;
              gv_message          := 'Detail invoices connected to statement ' ||
                                     lv_rec_paymentransaction.reference ||
                                     ' have all total amount smaller then bf';
              write_log(1);
            end;
          end if;
        end;
      end loop;
      --step 5 messages in log
      if lv_statementcounter > 0 then
        gv_message := 'All ' || lv_statementcounter ||
                      ' detail invoices have amount < banking fee ';
        write_log(1);
        end_log;
        raise e_user_exception_error;
      else
        gv_message := 'not all invoices with amount < btf of statement';
        write_log(1);
        end_log;
      end if;
    end check_file_bf;

  begin
    --importreconciliationfile
    gv_message                := 'importreconciliationfile';
    gv_abslogprocessjobid     := null;
    gv_abslogprocessjobpartid := null;
    gv_plantid                := null;
    --set variables
    gv_processname   := 'importpaymentsauj.' || gv_message;
    gv_systemuserid  := fp_systemuserid;
    gv_plantid       := fp_plantid;
    gv_dialogid      := fp_dialogid;
    gv_workstationid := fp_workstationid;
    check_parameters;
    --step 1 create log
    gv_message := gv_message || ' ' || lv_plantcode;
    write_log(1);
    get_csv_systemsettings(true);
    lv_filehandle := open_file(lv_filename, 'r');
    check_file_struc; --check if the file is formated ok
    close_file(lv_filehandle);
    lv_filehandle := open_file(lv_filename, 'r');
    check_file; -- check if no records are imported already WBO added
    close_file(lv_filehandle);
    lv_filehandle := open_file(lv_filename, 'r');
    check_file_man; -- check if no records are applied already WBO added
    close_file(lv_filehandle);
    lv_filehandle := open_file(lv_filename, 'r');
    check_file_partly_apl; -- check if no detail records are applied already WBO added
    close_file(lv_filehandle);
    lv_filehandle := open_file(lv_filename, 'r');
    check_file_bf; -- check if not all invoices have amount < btf already WBO added
    close_file(lv_filehandle);
    lv_filehandle := open_file(lv_filename, 'r');
    read_file;
    close_file(lv_filehandle);
    --step 6 close log
    commit;
    gv_message := lv_counter || ' lines processed';
    write_log(1);
    end_log;
  exception
    when e_user_exception_error then
      begin
        rollback;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when no_data_found then
      begin
        rollback;
        gv_message := 'No data found ' || gv_message;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when others then
      begin
        rollback;
        write_log(3);
        gv_message := sqlerrm;
        write_log(5);
        end_log;
        close_file(lv_filehandle);
      end;
  end importreconciliationfile;

  procedure importnotreconciliatedpayments(fp_remark        in varchar2,
                                           fp_systemuserid  in systemuser.systemuser_id%type,
                                           fp_plantid       in plant.plant_id%type,
                                           fp_dialogid      in dialogs.dialog_id%type,
                                           fp_workstationid in workstation.workstation_id%type) is
    lv_filename         varchar2(64) := 'reciept_return.csv';
    lv_filehandle       utl_file.file_type;
    lv_line             varchar2(4000);
    lv_counter          number := 0;
    lv_remitbatchid     remitbatch.remitbatch_id%type;
    lv_businessunitcode businessunit.code%type;

    procedure check_parameters is
    begin
      if fp_plantid is null then
        begin
          gv_message := 'parameter fp_plantid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
      if fp_systemuserid is null then
        begin
          gv_message := 'parameter fp_systemuserid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
    end check_parameters;

    procedure process_line is
      lv_rec_paymentransaction paymenttransaction%rowtype;
      lv_remitamount           number;
      lv_continue              boolean;
    begin
      --process_line
      gv_message := 'importnotreconciliatedpayments.process_line';
      --get field values
      lv_rec_paymentransaction.batchnumber := get_field(40, lv_line);
      lv_rec_paymentransaction.reference   := get_field(4, lv_line);
      lv_rec_paymentransaction.paymentdate := to_date(get_field(9, lv_line), 'YYYYMMDD');
      lv_rec_paymentransaction.amount      := get_field(10, lv_line);
      lv_rec_paymentransaction.origin      := get_field(12, lv_line);
      --Step 2 create_paymenttransaction ( no detail to be created! )
      lv_continue := create_paymenttransaction(lv_rec_paymentransaction, 1);
      --step 3
      if lv_continue then
        begin
          if lv_rec_paymentransaction.status = 0 then
            begin
              --step 4 process payment
              lv_remitbatchid := importpayments.create_remitbatch(lv_rec_paymentransaction.businessunit_id,
                                                                  lv_businessunitcode,
                                                                  lv_rec_paymentransaction.paymentdate,
                                                                  1);
              importpayments.processopencredit(lv_rec_paymentransaction.paymenttransaction_id,
                                               lv_remitbatchid, gv_abslogprocessjobpartid, fp_remark,
                                               fp_systemuserid, 0, true);
              lv_remitamount := importpayments.update_remitbatch(lv_remitbatchid);
              --step 5 messages in log
              gv_message := 'Businessunit ' || lv_businessunitcode || ' total remit batch ' ||
                            lv_remitamount;
              write_log(1);
            end;
          end if; --lv_rec_paymentransaction.status = 0
          --processpaymenttransaction;
          lv_counter := lv_counter + 1;
        end;
      end if; --if lv_continue
    end process_line;

    procedure read_file is
    begin
      -- read the file in loop
      gv_message := gv_message || ' importnotreconciliatedpayments.read_file';
      -- first line do not proces/read it!
      utl_file.get_line(lv_filehandle, lv_line);
      loop
        begin
          lv_line := null;
          utl_file.get_line(lv_filehandle, lv_line);
        exception
          when no_data_found then
            exit;
        end;
        begin
          process_line;
        end;
      end loop;
    end read_file;

  begin
    --importnotreconciliatedpayments
    gv_message := 'importnotreconciliatedpayments';
    --set variables
    gv_processname   := 'importpaymentsauj.' || gv_message;
    gv_systemuserid  := fp_systemuserid;
    gv_plantid       := fp_plantid;
    gv_dialogid      := fp_dialogid;
    gv_workstationid := fp_workstationid;
    check_parameters;
    --step 1 create log
    write_log(1);
    get_csv_systemsettings(true);
    lv_filehandle := open_file(lv_filename, 'r');
    read_file;
    close_file(lv_filehandle);
    --step 6 close log
    commit;
    gv_message := lv_counter || ' lines processed';
    write_log(1);
    end_log;
  exception
    when e_user_exception_error then
      begin
        rollback;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when no_data_found then
      begin
        rollback;
        gv_message := 'No data found ' || gv_message;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when others then
      begin
        rollback;
        write_log(3);
        gv_message := sqlerrm;
        write_log(5);
        end_log;
        close_file(lv_filehandle);
      end;
  end importnotreconciliatedpayments;

  procedure exportcustomerdata(fp_plantid            in plant.plant_id%type,
                               fp_workstationid      in workstation.workstation_id%type,
                               fp_systemuserid       in systemuser.systemuser_id%type,
                               fp_dialogid           in dialogs.dialog_id%type,
                               fp_notexported        in number,
                               fp_minbucode          in businessunit.code%type,
                               fp_maxbucode          in businessunit.code%type,
                               fp_mincustomer        in customer.customernumber%type,
                               fp_maxcustomer        in customer.customernumber%type,
                               fp_mindate            in date,
                               fp_maxdate            in date,
                               fp_abslogprocessjobid out abslogprocessjob.abslogprocessjob_id%type) is
    lv_filename   varchar2(64) := 'Torihikisaki-soushin data.csv';
    lv_filehandle utl_file.file_type;
    lv_counter    number := 0;

    procedure check_parameters is
    begin
      if fp_plantid is null then
        begin
          gv_message := 'parameter fp_plantid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
      if fp_systemuserid is null then
        begin
          gv_message := 'parameter fp_systemuserid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
    end check_parameters;

    procedure export_line(fp_customernumber      in customer.customernumber%type,
                          fp_customerlegalname   in customer.legalname%type,
                          fp_paybycustomernumber in customer.customernumber%type) is
      lv_paybycustomerexport varchar2(13);
      lv_paybysearchname     customer.searchname%type;
      lv_ispayby             boolean;
    begin
      --export line
      gv_message := 'exportcustomerdata.export_file.export line';
      begin
        select 'Z' || lpad(c.customernumber, 12, '0'), c.searchname
        into   lv_paybycustomerexport, lv_paybysearchname
        from   customer c
        where  c.customernumber = fp_paybycustomernumber;
      exception
        when no_data_found then
          begin
            lv_paybysearchname     := null;
            lv_paybycustomerexport := null;
          end;
      end;
      if fp_paybycustomernumber = fp_customernumber then
        lv_ispayby := true;
      else
        lv_ispayby := false;
      end if;
      write_line(lv_filehandle,
                 case when lv_ispayby then 'Z'
                  end || lpad(to_char(fp_customernumber), 12, '0') || gv_separator ||
                  lv_paybycustomerexport || gv_separator || lv_paybysearchname || gv_separator ||
                  substr(fp_customerlegalname, 1, 60) || gv_separator || '1' || gv_separator ||
                  replace('14;14;2;1;900;0;0;;;;', ';', gv_separator)); --ADD WBO 2505
      lv_counter := lv_counter + 1;
    end export_line;

    procedure export_file is
    begin
      --export_file
      gv_message := 'exportcustomerdata.export_file';
      --get customers
      if fp_notexported = 1 then
        begin
          --export all not exported invoices with exportpaymentstimestamp is null
          for x in (select i.billtocustomernumber,
                           (select c.customernumber
                             from   customer c
                             where  c.customer_id = ihe.paybycustomer_link_id) paybycustomernumber,
                           max(c.legalname) legalname
                    from   invoiceheader i, invoiceheaderextrainfo ihe, customer c
                    where  i.exportpaymentstimestamp is null
                    and    i.billtocustomer_link_id = c.customer_id
                    and    i.documenttype = 2
                    and    i.invoiceheader_id = ihe.invoiceheader_id
                    group  by i.billtocustomernumber, ihe.paybycustomer_link_id
                    union
                    select (select c.customernumber
                             from   customer c
                             where  c.customer_id = ihe.paybycustomer_link_id) billtocustomernumber,
                           (select c.customernumber
                             from   customer c
                             where  c.customer_id = ihe.paybycustomer_link_id) paybycustomernumber,
                           max(c.legalname) legalname
                    from   invoiceheader i, invoiceheaderextrainfo ihe, customer c
                    where  i.exportpaymentstimestamp is null
                    and    i.billtocustomer_link_id = c.customer_id
                    and    i.documenttype = 2
                    and    i.invoiceheader_id = ihe.invoiceheader_id
                    group  by i.billtocustomernumber, ihe.paybycustomer_link_id
                    order  by 2 desc, 1 desc) loop
            begin
              export_line(x.billtocustomernumber, x.legalname, x.paybycustomernumber);
              gv_message := x.billtocustomernumber || gv_separator || x.legalname;
              write_log(1);
            end;
          end loop; --x
        end;
      else
        begin
          --export selected customers from invoices
          for y in (select x.customernumber,
                           (select c.customernumber
                             from   customer c
                             where  c.customer_id = x.paybycustomer_link_id) paybycustomernumber,
                           max(x.name) name
                    from   (select i.billtocustomernumber customernumber, max(c.legalname) name,
                                    ihe.paybycustomer_link_id
                             from   invoiceheader i, invoiceheaderextrainfo ihe, businessunit bu,
                                    customer c
                             where  i.documenttype = 2
                             and    i.invoiceheader_id = ihe.invoiceheader_id
                             and    i.billtocustomer_link_id = c.customer_id
                             and    i.invoicebusinessunit_id = bu.businessunit_id
                             and    ((bu.code between fp_minbucode and fp_maxbucode) or
                                   (fp_minbucode is null and fp_maxbucode is null))
                             and    ((i.billtocustomernumber between fp_mincustomer and
                                   fp_maxcustomer) or
                                   (fp_mincustomer is null and fp_maxcustomer is null))
                             and    ((fp_mindate is null and fp_maxdate is null) or
                                   i.invoicedate between fp_mindate and fp_maxdate)
                             group  by i.billtocustomernumber, ihe.paybycustomer_link_id
                             union
                             select pbc.customernumber, max(pbc.legalname) name,
                                    ih.paybycustomer_link_id
                             from   invoiceheader i, invoiceheaderextrainfo ih, customer pbc,
                                    businessunit bu
                             where  i.documenttype = 2
                             and    i.invoiceheader_id = ih.invoiceheader_id
                             and    ih.paybycustomer_link_id = pbc.customer_id
                             and    i.invoicebusinessunit_id = bu.businessunit_id
                             and    ((bu.code between fp_minbucode and fp_maxbucode) or
                                   (fp_minbucode is null and fp_maxbucode is null))
                             and    ((pbc.customernumber between fp_mincustomer and fp_maxcustomer) or
                                   (fp_mincustomer is null and fp_maxcustomer is null))
                             and    ((fp_mindate is null and fp_maxdate is null) or
                                   i.invoicedate between fp_mindate and fp_maxdate)
                             group  by pbc.customernumber, ih.paybycustomer_link_id) x
                    group  by x.customernumber, x.paybycustomer_link_id
                    order  by 2 desc, x.customernumber desc) loop
            begin
              export_line(y.customernumber, y.name, y.paybycustomernumber);
              gv_message := y.customernumber || gv_separator || y.name;
              write_log(1);
            end;
          end loop; --y
        end;
      end if;
    end export_file;
  begin
    --exportcustomerdata
    gv_message       := 'exportcustomerdata';
    gv_processname   := 'importpaymentsauj.' || gv_message;
    gv_systemuserid  := fp_systemuserid;
    gv_plantid       := fp_plantid;
    gv_workstationid := fp_workstationid;
    gv_dialogid      := fp_dialogid;
    check_parameters;
    --step 1 create log
    write_log(1);
    fp_abslogprocessjobid := gv_abslogprocessjobid;
    get_csv_systemsettings(false);
    delete_file(lv_filename); --delete when it is already there first
    lv_filehandle := open_file(lv_filename);
    export_file;
    close_file(lv_filehandle);
    --step 6 close log
    gv_message := lv_counter || ' lines exported in ' || gv_databaselogdir || lv_filename;
    write_log(1);
    end_log;
  exception
    when e_user_exception_error then
      begin
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when no_data_found then
      begin
        gv_message := 'No data found ' || gv_message;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when others then
      begin
        write_log(3);
        gv_message := sqlerrm;
        write_log(5);
        end_log;
        close_file(lv_filehandle);
      end;
  end exportcustomerdata;

  procedure exportinvoicedata(fp_abslogprocessjobid in abslogprocessjob.abslogprocessjob_id%type,
                              fp_systemuserid       in systemuser.systemuser_id%type,
                              fp_notexported        in number,
                              fp_minbucode          in businessunit.code%type,
                              fp_maxbucode          in businessunit.code%type,
                              fp_mincustomer        in customer.customernumber%type,
                              fp_maxcustomer        in customer.customernumber%type,
                              fp_mindate            in date,
                              fp_maxdate            in date) is
    lv_filename   varchar2(64) := 'Seikyu-soushin data.csv';
    lv_filehandle utl_file.file_type;
    lv_counter    number := 0;

    procedure check_parameters is
    begin
      if fp_abslogprocessjobid is null then
        begin
          gv_message := 'parameter fp_abslogprocessjobid cannot be left empty!';
          raise e_user_exception_error;
        end;
      else
        select j.plant_id
        into   gv_plantid
        from   abslogprocessjob j
        where  j.abslogprocessjob_id = fp_abslogprocessjobid;
      end if;
      if fp_systemuserid is null then
        begin
          gv_message := 'parameter fp_systemuserid cannot be left empty!';
          raise e_user_exception_error;
        end;
      end if;
    end check_parameters;

    procedure export_line(fp_invoicenumber        invoiceheader.invoicenumber%type,
                          fp_billtocustomernumber invoiceheader.billtocustomernumber%type,
                          fp_invoicedate          varchar2,
                          fp_prebillamount        invoiceheader.prebillamount%type,
                          fp_paymenttermsduedate  varchar2,
                          fp_amount               statementline.amount%type) is
    begin
      --write header
      write_line(lv_filehandle,
                 lpad(to_char(fp_invoicenumber), 10, '0') || gv_separator ||
                  lpad(to_char(fp_billtocustomernumber), 12, '0') || gv_separator || fp_invoicedate ||
                  gv_separator || fp_prebillamount || gv_separator || fp_paymenttermsduedate ||
                  gv_separator || '001' || gv_separator || fp_amount);
      lv_counter := lv_counter + 1;
    end export_line;

    procedure update_to_exported(fp_invoiceheaderid in invoiceheader.invoiceheader_id%type) is
    begin
      update invoiceheader h
      set    h.exportpaymentstimestamp = sysdate, h.systemuser_id = gv_systemuserid,
             h.timestamp = sysdate
      where  h.invoiceheader_id = fp_invoiceheaderid
      and    h.exportpaymentstimestamp is null;
    end update_to_exported;

    procedure export_file is
    begin
      --export_file
      gv_message := 'exportcustomerdata.export_file';
      if fp_notexported = 1 then
        begin
          --export invoiceheader info for fp_notexported=true
          for x in (select h.invoicenumber, h.billtocustomernumber,
                           to_char(h.invoicedate, 'YYYYMMDD') invoicedate, h.prebillamount,
                           to_char(ih.paymenttermsduedate, 'YYYYMMDD') paymenttermsduedate,
                           h.invoiceheader_id, h.prebillamount amount --,l.amount,
                    --l.invoicelinetype_id
                    from   invoiceheader h, invoiceheaderextrainfo ih --, statementline l   --WBO 2505
                    where  h.invoiceheader_id = ih.invoiceheader_id
                          --and    h.invoiceheader_id = l.invoiceheader_id --WBO 2505
                    and    h.documenttype = 2
                    and    h.exportpaymentstimestamp is null) loop
            begin
              export_line(x.invoicenumber, x.billtocustomernumber, x.invoicedate, x.prebillamount,
                          x.paymenttermsduedate, x.amount);
              update_to_exported(x.invoiceheader_id);
            end;
          end loop; --x
        end;
      else
        begin
          --export invoices bassed on selection criteria, fp_notexported=false
          for a in (select h.invoicenumber, h.billtocustomernumber,
                           to_char(h.invoicedate, 'YYYYMMDD') invoicedate, h.prebillamount,
                           to_char(ih.paymenttermsduedate, 'YYYYMMDD') paymenttermsduedate,
                           h.invoiceheader_id, h.prebillamount amount --,l.amount, --WBO 2505
                    -- l.invoicelinetype_id
                    from   invoiceheader h, invoiceheaderextrainfo ih, businessunit bu
                    --,statementline l --WBO 2505
                    where  h.invoiceheader_id = ih.invoiceheader_id
                          --and    h.invoiceheader_id = l.invoiceheader_id --WBO 2505
                    and    h.documenttype = 2
                    and    h.invoicebusinessunit_id = bu.businessunit_id
                    and    ((bu.code between fp_minbucode and fp_maxbucode) or
                          (fp_minbucode is null and fp_maxbucode is null))
                    and    ((h.billtocustomernumber between fp_mincustomer and fp_maxcustomer) or
                          (fp_mincustomer is null and fp_maxcustomer is null))
                    and    ((fp_mindate is null and fp_maxdate is null) or
                          h.invoicedate between fp_mindate and fp_maxdate)) loop
            begin
              export_line(a.invoicenumber, a.billtocustomernumber, a.invoicedate, a.prebillamount,
                          a.paymenttermsduedate, a.amount);
              update_to_exported(a.invoiceheader_id);
            end;
          end loop; --a
        end;
      end if;
    end export_file;
  begin
    --exportinvoicedata
    gv_message            := 'exportinvoicedata';
    gv_processname        := 'importpaymentsauj.' || gv_message;
    gv_systemuserid       := fp_systemuserid;
    gv_abslogprocessjobid := fp_abslogprocessjobid;
    check_parameters;
    --step 1 create log
    write_log(1);
    get_csv_systemsettings(false);
    delete_file(lv_filename); --delete when it is already there first
    lv_filehandle := open_file(lv_filename);
    export_file;
    close_file(lv_filehandle);
    --step 6 close log
    commit;
    gv_message := lv_counter || ' lines exported in ' || gv_databaselogdir || lv_filename;
    write_log(1);
    end_log;
  exception
    when e_user_exception_error then
      begin
        rollback;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when no_data_found then
      begin
        rollback;
        gv_message := 'No data found ' || gv_message;
        write_log(3);
        end_log;
        close_file(lv_filehandle);
      end;
    when others then
      begin
        rollback;
        write_log(3);
        gv_message := sqlerrm;
        write_log(5);
        end_log;
        close_file(lv_filehandle);
      end;
  end exportinvoicedata;

begin
  initialize;
exception
  when e_user_exception_error then
    begin
      rollback;
      write_log(3);
      end_log;
    end;
  when no_data_found then
    begin
      rollback;
      gv_message := 'No data found ' || gv_message;
      write_log(3);
      end_log;
    end;
  when others then
    begin
      rollback;
      write_log(3);
      gv_message := sqlerrm;
      write_log(5);
      end_log;
    end;
end importpaymentsauj;
/

create or replace procedure link_masteraccount(fp_filename     in varchar2,
                                               fp_directory    in varchar2,
                                               fp_seperator    in varchar2 default ';',
                                               fp_systemuserid in number default 0) is
  /*procedure link_masteraccount version 1.5*/
  -- ABS-121099

  --Global variables
  gv_userexception exception;
  gv_message         varchar2(1000);
  gv_customerid      number;
  gv_debtorid        number;
  gv_paybyid         number;
  gv_commonid        number;
  gv_masteraccountid number;
  gv_endddate        date := to_date('31-12-2099', 'dd-mm-yyyy');
  gv_counter         number := 0;
  gv_errors          number := 0;

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'link_masteraccount', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --cannot produce output but its in ABSLOG as well
    end;
  end write_log;

  procedure import_customers_masteraccount is
    --global variables
    gv_filehandle utl_file.file_type;
    gv_separator  varchar2(1);
  
    ---internal procedure(s)
    procedure initialize is
    begin
      --initialize
      gv_message := 'initialize';
      if fp_filename is null then
        begin
          gv_message := 'parameter fp_filename cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_directory is null then
        begin
          gv_message := 'parameter fp_directory cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_seperator is null then
        begin
          gv_separator := ';';
        end;
      else
        begin
          gv_message   := 'check separator';
          gv_separator := fp_seperator;
        end;
      end if;
      execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
      execute immediate 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''';
    end initialize;
  
    procedure read_file is
    begin
      --open the file
      gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
      gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
    exception
      when utl_file.invalid_path then
        begin
          gv_message := gv_message || ' Invalid Path';
          raise gv_userexception;
        end;
      when utl_file.invalid_mode then
        begin
          gv_message := gv_message || ' Invalid Mode';
          raise gv_userexception;
        end;
      when utl_file.invalid_operation then
        begin
          gv_message := gv_message || ' Invalid Operation';
          raise gv_userexception;
        end;
      when utl_file.invalid_filehandle then
        begin
          gv_message := gv_message || ' Invalid Filehandle';
          raise gv_userexception;
        end;
      when utl_file.write_error then
        begin
          gv_message := gv_message || ' Write Error';
          raise gv_userexception;
        end;
      when utl_file.read_error then
        begin
          gv_message := gv_message || ' Read Error';
          raise gv_userexception;
        end;
      when utl_file.internal_error then
        begin
          gv_message := gv_message || ' Internal Error';
          raise gv_userexception;
        end;
    end read_file;
  
    procedure process_file is
      lv_readline                varchar2(4000);
      lv_line_counter            number := 0;
      lv_customers_masteraccount customers_masteraccount%rowtype;
    
      ----process_file internal procedures
      procedure process_line(fp_readline in varchar2) is
      
        ---process_file.process_line internal procedures
        procedure read_line(fp_readline in varchar2) is
          lv_currentposition number := 0;
          lv_nextposition    number := 0;
          lv_laststring      boolean := false;
        
          ---process_file.process_line.read_line internal function
          function get_nextvalue(fp_message in varchar2) return varchar2 is
          
            --process_file.process_line.read_line.get_nextvalue internal function
            function get_position(fp_startpos in number) return number is
            begin
              --get_position
              return instr(substr(fp_readline, fp_startpos + 1), gv_separator) + fp_startpos;
            end get_position;
          begin
            --get_nextvalue
            lv_currentposition := lv_nextposition;
            lv_nextposition    := get_position(lv_currentposition);
            gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                  to_char(lv_nextposition) || ' ' || fp_message;
            if lv_nextposition = lv_currentposition then
              begin
                --separator not found, so last field
                --last string, repeat it, if nothing else...
                if not lv_laststring then
                  begin
                    lv_laststring := true;
                    --read last value
                    return rtrim(rtrim(substr(fp_readline, lv_currentposition + 1), chr(10)),
                                 chr(13));
                  end;
                else
                  begin
                    --no new values found!
                    return null;
                  end;
                end if;
              end;
            else
              --read value
              return trim(substr(fp_readline, lv_currentposition + 1,
                                 lv_nextposition - lv_currentposition - 1));
            end if;
          end get_nextvalue;
        begin
          --read_line
          lv_laststring                        := false;
          lv_customers_masteraccount.timestamp := sysdate;
          lv_customers_masteraccount.processed := 0;
          --read values
          lv_customers_masteraccount.customernumber    := to_number(get_nextvalue('customernumber'));
          lv_customers_masteraccount.new_masteraccount := to_number(get_nextvalue('new_masteraccount'));
        end read_line;
      
        procedure insert_line is
        begin
          --insert_line
          gv_message := 'insert_line';
          insert into customers_masteraccount values lv_customers_masteraccount;
          commit;
        end insert_line;
      begin
        --read
        read_line(fp_readline);
        --insert
        insert_line;
      exception
        when others then
          begin
            write_log('Line# ' || to_char(lv_line_counter) || ' error ' || sqlerrm || ' ' ||
                      gv_message || ' file ' || fp_filename, 3);
          end;
      end process_line;
    begin
      --process_file
      gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                    nvl(fp_directory, '<Empty>');
      --loop go through lines
      loop
        begin
          begin
            -- get line from file.
            utl_file.get_line(gv_filehandle, lv_readline);
            lv_line_counter := lv_line_counter + 1;
          exception
            when no_data_found then
              exit;
          end;
          --process_line
          gv_message := 'Linenumber ' || lv_line_counter;
          --process lines
          if substr(lv_readline, 1, 3) <> (gv_separator || gv_separator || gv_separator) then
            begin
              process_line(lv_readline);
            end;
          end if;
        end;
      end loop;
      --commit
      commit;
    end process_file;
  
    procedure close_file is
    begin
      --close file(s)
      gv_message := 'close files';
      if utl_file.is_open(gv_filehandle) = true then
        utl_file.fclose(gv_filehandle);
      end if;
      utl_file.fclose_all;
    end close_file;
  
    procedure finalize is
    begin
      --write log
      write_log('Successfully processed file ' || fp_filename || ' in directory ' || fp_directory,
                1);
    end finalize;
    --start main procedure
  begin
    --initialize
    initialize;
    --read_file
    read_file;
    --process_file
    process_file;
    --close file
    close_file;
    --finalize
    finalize;
  exception
    --exception handling global
    when gv_userexception then
      begin
        raise gv_userexception;
      end;
    when others then
      begin
        rollback;
        write_log('Error Others ' || sqlerrm || ' ' || gv_message, 3);
        close_file;
        gv_message := 'error processing file';
        raise gv_userexception;
      end;
  end import_customers_masteraccount;

  function get_customerid(fp_customernumber in customer.customernumber%type)
    return customer.customer_id%type is
    fp_customerid customer.customer_id%type;
  begin
    --get_customerid
    gv_message := ' customer ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      begin
        gv_debtorid := null;
        gv_paybyid  := null;
        gv_commonid := null;
        return null;
      end;
    else
      begin
        select c.customer_id, c.debtor_id, cbi.paybycustomer_link_id,
               (select max(c.customer_id) from customer x where x.commoncustomer_id = c.customer_id)
        into   fp_customerid, gv_debtorid, gv_paybyid, gv_commonid
        from   customer c
        left   outer join customerbillinginfo cbi
        on     cbi.customer_id = c.customer_id
        where  c.customernumber = fp_customernumber;
        return fp_customerid;
      end;
    end if;
  end get_customerid;

  procedure update_masteraccount(fp_customernumber   in customers_masteraccount.customernumber%type,
                                 fp_newmasteraccount in customers_masteraccount.new_masteraccount%type) is
  begin
    gv_message := 'update_masteraccount';
    --
    update customer c
    set    c.masteraccount_id =
            (select m.customer_id
             from   customer m
             where  m.customernumber = fp_newmasteraccount
             and    m.masteraccount = 2), c.timestamp = sysdate,
           c.systemuser_id = nvl(fp_systemuserid, 0), c.masteraccount = 3
    where  c.customernumber = fp_customernumber
    and    exists (select m.customer_id
            from   customer m
            where  m.customernumber = fp_newmasteraccount
            and    m.masteraccount = 2);
    if sql%rowcount = 0 then
      begin
        gv_message := 'error : customer could not be updated';
        raise gv_userexception;
      end;
    end if;
  end update_masteraccount;

  procedure copy_contractcustomer is
  begin
    --copy_contractcustomer
    gv_message := 'copy_contractcustomer';
    if (nvl(gv_debtorid, -1) <> gv_customerid and nvl(gv_paybyid, -1) <> gv_customerid and
       nvl(gv_commonid, -1) <> gv_customerid) then
      begin
        insert into contractcustomer
          (contractcustomer_id, contract_id, customer_link_id, startdate, enddate, systemuser_id,
           timestamp)
          select seq_contractcustomer.nextval, cc.contract_id, gv_customerid, cc.startdate,
                 cc.enddate, nvl(fp_systemuserid, 0), sysdate
          from   contractcustomer cc
          where  cc.customer_link_id = gv_masteraccountid
          and    cc.enddate >= trunc(sysdate)
          and    not exists (select 1
                  from   contractcustomer x
                  where  x.contract_id = cc.contract_id
                  and    x.customer_link_id = gv_customerid);
      end;
    end if;
  end copy_contractcustomer;

  procedure copy_pricelistspercustomer is
    lv_priority       number := 0;
    lv_prev_pricetype number := 0;
  begin
    if (nvl(gv_debtorid, -1) <> gv_customerid and nvl(gv_paybyid, -1) <> gv_customerid and
       nvl(gv_commonid, -1) <> gv_customerid) then
      begin
        --copy_pricelistspercustomer
        gv_message := 'copy_pricelistspercustomer customer id ' || to_char(gv_customerid);
        for s in (select plc.pricetype,
                         nvl((select min(lx.priority) - 1
                              from   pricelistpercustomer lx
                              where  lx.customer_id = gv_customerid
                              and    lx.pricetype = plc.pricetype
                              and    lx.generalpricelist_id is not null), plc.priority) priority,
                         plc.generalpricelist_id
                  from   pricelistpercustomer plc
                  join   generalpricelist gp
                  on     gp.generalpricelist_id = plc.generalpricelist_id
                  where  plc.customer_id = gv_masteraccountid
                  and    not exists (select 1
                          from   pricelistpercustomer l
                          where  l.generalpricelist_id = plc.generalpricelist_id
                          and    l.pricetype = plc.pricetype
                          and    l.customer_id = gv_customerid)
                  order  by plc.pricetype, plc.dateactive desc, gp.code asc) loop
          begin
            if (lv_priority = 0 or lv_prev_pricetype <> s.pricetype) then
              begin
                lv_priority       := s.priority;
                lv_prev_pricetype := s.pricetype;
              end;
            else
              lv_priority := lv_priority - 1;
            end if;
            --insert into pricelistpercustomer
            insert into pricelistpercustomer
              (pricelistpercustomer_id, customer_id, pricetype, priority, generalpricelist_id,
               dateactive, dateinactive, systemuser_id, timestamp)
            values
              (seq_pricelistpercustomer.nextval, gv_customerid, s.pricetype, lv_priority,
               s.generalpricelist_id, trunc(sysdate), gv_endddate, nvl(fp_systemuserid, 0), sysdate);
          end;
        end loop; --s
      end;
    end if;
  end copy_pricelistspercustomer;
begin
  write_log('Start', 1);
  --import_customers_masteraccount load file
  import_customers_masteraccount;
  --process data from file
  for y in (select * from customers_masteraccount cm where cm.processed = 0) loop
    begin
      gv_counter := gv_counter + 1;
      --check customer numbers
      gv_masteraccountid := get_customerid(y.new_masteraccount);
      gv_customerid      := get_customerid(y.customernumber);
      --update_masteraccount
      update_masteraccount(y.customernumber, y.new_masteraccount);
      --copy contract customer
      copy_contractcustomer;
      --copy_pricelistspercustomer
      copy_pricelistspercustomer;
      --set flag as processed ok 
      update customers_masteraccount cm
      set    cm.processed = 1
      where  cm.customernumber = y.customernumber
      and    cm.new_masteraccount = y.new_masteraccount;
      commit;
    exception
      --Exception handling, and count errors
      when gv_userexception then
        begin
          rollback;
          gv_errors := gv_errors + 1;
          write_log(' ' || gv_message, 3);
          --set flag
          update customers_masteraccount cm
          set    cm.processed = -1
          where  cm.customernumber = y.customernumber
          and    cm.new_masteraccount = y.new_masteraccount;
          commit;
        end;
      when no_data_found then
        begin
          rollback;
          gv_errors := gv_errors + 1;
          write_log(' Error, No Data Found ' || gv_message || ' CUSTOMERNUMBER ' ||
                    to_char(y.customernumber) || ' NEW_MASTERACCOUNT ' || y.new_masteraccount, 3);
          update customers_masteraccount cm
          set    cm.processed = -2
          where  cm.customernumber = y.customernumber
          and    cm.new_masteraccount = y.new_masteraccount;
          commit;
        end;
      when others then
        begin
          rollback;
          gv_errors := gv_errors + 1;
          write_log(' Error ' || sqlerrm || ' ' || gv_message || ' CUSTOMERNUMBER ' ||
                    to_char(y.customernumber) || ' NEW_MASTERACCOUNT ' || y.new_masteraccount, 3);
          --set flag
          update customers_masteraccount cm
          set    cm.processed = -3
          where  cm.customernumber = y.customernumber
          and    cm.new_masteraccount = y.new_masteraccount;
          commit;
        end;
    end;
  end loop; --y
  commit;
  write_log(' file ' || fp_filename || ' in directory ' || fp_directory || ' processed', 1);
  if gv_errors > 0 then
    begin
      write_log(' warning ' || to_char(gv_errors) || ' errors', 1);
      write_log('End processed ' || to_char(gv_counter) || ' rows', 1);
    end;
  else
    write_log('End processed ' || to_char(gv_counter) || ' rows', 1);
  end if;
exception
  --Exception handling
  when gv_userexception then
    begin
      rollback;
      write_log(gv_message || chr(10) || 'End.', 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error, No Data Found ' || gv_message || chr(10) || 'End.', 3);
    end;
  when others then
    begin
      rollback;
      write_log('Error ' || sqlerrm || ' ' || gv_message || chr(10) || 'End.', 3);
    end;
end link_masteraccount;
/
CREATE OR REPLACE NONEDITIONABLE TRIGGER logoff_check
  BEFORE LOGOFF ON DATABASE
BEGIN
  /* Log all unauthorised logofs for read /write access to ABSSOLUTE schema, by check:
   -  ABSSOLUTE database schema used, and
   -  Not coming from valid application servers or BI server, and
   -  Not coming from specific OS user used */
IF SYS_CONTEXT('USERENV','HOST')  NOT  IN  ('rabsap1', 'pabsap1', 'pabsap2', 'pabsbi1', 'pabsdb1', 'pabspx1') THEN
    execute immediate 'INSERT INTO ABSSOLUTE.SYS_AUDIT  (SESSION_USER,
                        OS_USER,
                        CURRENT_USER,
                        CURRENT_SCHEMA,
                        ACTION,
                        CLIENT_IDENTIFIER,
                        CLIENT_INFO,
                        HOST,
                        IP_ADDRESS,
                        ISDBA,
                        MODULE,
                        TERMINAL,
                        LOGOFF_DATE)
             VALUES    (SYS_CONTEXT (''USERENV'', ''SESSION_USER'') ,
                SYS_CONTEXT (''USERENV'', ''OS_USER''),
                SYS_CONTEXT (''USERENV'', ''CURRENT_USER''),
                SYS_CONTEXT (''USERENV'', ''CURRENT_SCHEMA''),
                SYS_CONTEXT (''USERENV'', ''ACTION'') ,
                SYS_CONTEXT (''USERENV'', ''CLIENT_IDENTIFIER''),
                SYS_CONTEXT (''USERENV'', ''CLIENT_INFO''),
                SYS_CONTEXT (''USERENV'', ''HOST''),
                SYS_CONTEXT (''USERENV'', ''IP_ADDRESS''),
                SYS_CONTEXT (''USERENV'', ''ISDBA''),
                SYS_CONTEXT (''USERENV'', ''MODULE''),
                SYS_CONTEXT (''USERENV'', ''TERMINAL''),
                TO_CHAR(SYSDATE, ''YYYY.MM.DD HH24:MI:SS''))';
        execute immediate 'commit';
  END IF;

END;
/

CREATE OR REPLACE NONEDITIONABLE TRIGGER logon_check
  AFTER LOGON ON DATABASE
BEGIN
  /* Log all unauthorised logons for read /write access to ABSSOLUTE schema, by check:
   -  ABSSOLUTE database schema used, and
   -  Not coming from valid application servers or BI server, and
   -  Not coming from specific OS user used */
IF SYS_CONTEXT('USERENV','HOST') NOT IN ('rabsap1', 'pabsap1', 'pabsap2', 'pabsbi1', 'pabsdb1', 'pabspx1')
THEN execute immediate 'INSERT INTO ABSSOLUTE.SYS_AUDIT  (SESSION_USER,
                        OS_USER,
                        CURRENT_USER,
                        CURRENT_SCHEMA,
                        ACTION,
                        CLIENT_IDENTIFIER,
                        CLIENT_INFO,
                        HOST,
                        IP_ADDRESS,
                        ISDBA,
                        MODULE,
                        TERMINAL,
                        LOGON_DATE)
             VALUES    (SYS_CONTEXT (''USERENV'', ''SESSION_USER'') ,
                SYS_CONTEXT (''USERENV'', ''OS_USER''),
                SYS_CONTEXT (''USERENV'', ''CURRENT_USER''),
                SYS_CONTEXT (''USERENV'', ''CURRENT_SCHEMA''),
                SYS_CONTEXT (''USERENV'', ''ACTION'') ,
                SYS_CONTEXT (''USERENV'', ''CLIENT_IDENTIFIER''),
                SYS_CONTEXT (''USERENV'', ''CLIENT_INFO''),
                SYS_CONTEXT (''USERENV'', ''HOST''),
                SYS_CONTEXT (''USERENV'', ''IP_ADDRESS''),
                SYS_CONTEXT (''USERENV'', ''ISDBA''),
                SYS_CONTEXT (''USERENV'', ''MODULE''),
                SYS_CONTEXT (''USERENV'', ''TERMINAL''),
                TO_CHAR(SYSDATE, ''YYYY.MM.DD HH24:MI:SS''))';
        execute immediate 'commit';
END IF;
END;
/

create or replace procedure move_supplierproducts(fp_from_supplier in supplier.suppliernumber%type,
                                                  fp_to_supplier   in supplier.suppliernumber%type) is
  gv_from_supplierid supplier.supplier_id%type;
  gv_to_supplierid   supplier.supplier_id%type;
  gv_text            varchar2(1000);
  ---move_supplierproducts version 0.2
  ---ABS-111839 Merge supplier products from one supplier to another supplier
  --------Internal procedures/functions
  procedure write_log(fp_message in abslog.message%type, fp_priority in abslog.priority%type) is
  begin
    abslogwrite.abslog_write(5, 'move_supplierproducts', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null;
    end;
  end write_log;
begin
  ---move_supplierproducts---
  --get from supplier id
  gv_text := 'fp_from_supplier ' || to_char(fp_from_supplier);
  select s.supplier_id
  into   gv_from_supplierid
  from   supplier s
  where  s.suppliernumber = fp_from_supplier;
  --get to supplier id
  gv_text := 'fp_to_supplier ' || to_char(fp_from_supplier);
  select s.supplier_id
  into   gv_to_supplierid
  from   supplier s
  where  s.suppliernumber = fp_to_supplier;
  --update supplierproduct
  gv_text := 'update supplierproduct';
  update supplierproduct ps
  set    ps.supplier_id = gv_to_supplierid, ps.timestamp = sysdate
  where  ps.supplier_id = gv_from_supplierid
  and    not exists (select 1
          from   supplierproduct psx
          where  psx.supplier_id = gv_to_supplierid
          and    psx.supplierproductcode = ps.supplierproductcode
          and    psx.suppliersizecode = ps.suppliersizecode);
  --delete from supplierproduct
  gv_text := 'delete from supplierproduct';
  delete from productsizepersupproduct pss
  where  exists (select 1
          from   supplierproduct sp
          where  sp.supplierproduct_id = pss.supplierproduct_id
          and    sp.supplier_id = gv_from_supplierid);
  delete from supplierproduct ps where ps.supplier_id = gv_from_supplierid;
  --Also preferred supplier on product level and stockroom level 
  gv_text := 'update stockroomsupplier';
  update stockroomsupplier ssp
  set    ssp.supplier_id = gv_to_supplierid
  where  ssp.supplier_id = gv_from_supplierid
  and    not exists (select 1
          from   stockroomsupplier sspx
          where  sspx.stockroom_id = ssp.stockroom_id
          and    sspx.supplier_id = gv_to_supplierid);
  ---delete from stockroomsupplier
  gv_text := 'delete from stockroomsupplier ps';
  delete from stockroomsupplier ps where ps.supplier_id = gv_from_supplierid;
  --update product
  gv_text := 'update product';
  update product p
  set    p.supplier_id = gv_to_supplierid, p.timestamp = sysdate
  where  p.supplier_id = gv_from_supplierid;
  --update stockdefinitionperitem
  gv_text := 'update stockdefinitionperitem';
  update stockdefinitionperitem sti
  set    sti.defaultsupplier_id = gv_to_supplierid, sti.timestamp = sysdate
  where  sti.defaultsupplier_id = gv_from_supplierid;
  --update productlistpercustomer
  gv_text := 'update productlistpercustomer';
  update productlistpercustomer l
  set    l.defaultsupplier_id = gv_to_supplierid, l.timestamp = sysdate
  where  l.defaultsupplier_id = gv_from_supplierid;
  --commit
  commit;
  --log
  write_log('fp_from_supplier ' || to_char(fp_from_supplier) || 'fp_to_supplier ' ||
            to_char(fp_to_supplier), 1);
exception
  --exception handling
  when no_data_found then
    begin
      rollback;
      write_log('Error No Data Found ' || gv_text, 3);
    end;
  when others then
    begin
      rollback;
      write_log(sqlerrm || ' ' || gv_text, 5);
    end;
end move_supplierproducts;
/

create or replace procedure new_masteraccount(fp_filename     in varchar2,
                                              fp_directory    in varchar2,
                                              fp_seperator    in varchar2 default ';',
                                              fp_systemuserid in number default 0) is
  /*procedure new_masteraccount version 0.4*/
  -- ABS-121099

  --Global variables
  gv_userexception exception;
  gv_counter number := 0;
  gv_errors  number := 0;
  gv_message varchar2(1000);

  gv_org_masterid number;
  gv_new_masterid number;

  --Internal procedures
  procedure write_log(fp_message in varchar2, fp_priority in number) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'new_masteraccount', null, fp_priority, fp_message);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --cannot produce output but its in ABSLOG as well
    end;
  end write_log;

  procedure import_u_masteraccount is
    --global variables
    gv_filehandle utl_file.file_type;
    gv_separator  varchar2(1);
  
    ---internal procedure(s)
    procedure initialize is
    begin
      --initialize
      gv_message := 'initialize';
      if fp_filename is null then
        begin
          gv_message := 'parameter fp_filename cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_directory is null then
        begin
          gv_message := 'parameter fp_directory cannot be left empty!';
          raise gv_userexception;
        end;
      end if;
      if fp_seperator is null then
        begin
          gv_separator := ';';
        end;
      else
        begin
          gv_message   := 'check separator';
          gv_separator := fp_seperator;
        end;
      end if;
      execute immediate 'ALTER SESSION SET NLS_DATE_FORMAT = "DD-MM-YYYY"';
      execute immediate 'ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '', ''';
    end initialize;
  
    procedure read_file is
    begin
      --open the file
      gv_message    := 'read file ' || fp_filename || ' in directory ' || fp_directory;
      gv_filehandle := utl_file.fopen(fp_directory, fp_filename, 'r');
    exception
      when utl_file.invalid_path then
        begin
          gv_message := gv_message || ' Invalid Path';
          raise gv_userexception;
        end;
      when utl_file.invalid_mode then
        begin
          gv_message := gv_message || ' Invalid Mode';
          raise gv_userexception;
        end;
      when utl_file.invalid_operation then
        begin
          gv_message := gv_message || ' Invalid Operation';
          raise gv_userexception;
        end;
      when utl_file.invalid_filehandle then
        begin
          gv_message := gv_message || ' Invalid Filehandle';
          raise gv_userexception;
        end;
      when utl_file.write_error then
        begin
          gv_message := gv_message || ' Write Error';
          raise gv_userexception;
        end;
      when utl_file.read_error then
        begin
          gv_message := gv_message || ' Read Error';
          raise gv_userexception;
        end;
      when utl_file.internal_error then
        begin
          gv_message := gv_message || ' Internal Error';
          raise gv_userexception;
        end;
    end read_file;
  
    procedure process_file is
      lv_readline        varchar2(4000);
      lv_line_counter    number := 0;
      lv_u_masteraccount u_masteraccount%rowtype;
    
      ----process_file internal procedures
      procedure process_line(fp_readline in varchar2) is
      
        ---process_file.process_line internal procedures
        procedure read_line(fp_readline in varchar2) is
          lv_currentposition number := 0;
          lv_nextposition    number := 0;
          lv_laststring      boolean := false;
        
          ---process_file.process_line.read_line internal function
          function get_nextvalue(fp_message in varchar2) return varchar2 is
          
            --process_file.process_line.read_line.get_nextvalue internal function
            function get_position(fp_startpos in number) return number is
            begin
              --get_position
              return instr(substr(fp_readline, fp_startpos + 1), gv_separator) + fp_startpos;
            end get_position;
          begin
            --get_nextvalue
            lv_currentposition := lv_nextposition;
            lv_nextposition    := get_position(lv_currentposition);
            gv_message         := 'read_line ' || to_char(lv_line_counter) || ' from pos ' ||
                                  to_char(lv_nextposition) || ' ' || fp_message;
            if lv_nextposition = lv_currentposition then
              begin
                --separator not found, so last field
                --last string, repeat it, if nothing else...
                if not lv_laststring then
                  begin
                    lv_laststring := true;
                    --read last value
                    return substr(fp_readline, lv_currentposition + 1);
                  end;
                else
                  begin
                    --no new values found!
                    return null;
                  end;
                end if;
              end;
            else
              --read value
              return trim(substr(fp_readline, lv_currentposition + 1,
                                 lv_nextposition - lv_currentposition - 1));
            end if;
          end get_nextvalue;
        begin
          --read_line
          lv_laststring                := false;
          lv_u_masteraccount.timestamp := sysdate;
          lv_u_masteraccount.processed := 0;
          --read values
          lv_u_masteraccount.orignal_masteraccount  := to_number(get_nextvalue('orignal_masteraccount'));
          lv_u_masteraccount.original_contractcode  := get_nextvalue('original_contractcode');
          lv_u_masteraccount.original_pricelistcode := get_nextvalue('original_pricelistcode');
          lv_u_masteraccount.pricetype              := to_number(get_nextvalue('pricetype'));
          lv_u_masteraccount.new_masteraccount      := to_number(get_nextvalue('new_masteraccount'));
          lv_u_masteraccount.new_contractcode       := get_nextvalue('new_contractcode');
          lv_u_masteraccount.new_pricelistcode      := get_nextvalue('new_pricelistcode');
        end read_line;
      
        procedure insert_line is
        begin
          --insert_line
          gv_message := 'insert_line';
          insert into u_masteraccount values lv_u_masteraccount;
          commit;
        end insert_line;
      begin
        --read
        read_line(fp_readline);
        --insert
        insert_line;
      exception
        when others then
          begin
            write_log('Line# ' || to_char(lv_line_counter) || ' error ' || sqlerrm || ' ' ||
                      gv_message || ' file ' || fp_filename, 3);
          end;
      end process_line;
    begin
      --process_file
      gv_message := 'process_file ' || nvl(fp_filename, '<Empty>') || ' directory ' ||
                    nvl(fp_directory, '<Empty>');
      --loop go through lines
      loop
        begin
          begin
            -- get line from file.
            utl_file.get_line(gv_filehandle, lv_readline);
            lv_line_counter := lv_line_counter + 1;
          exception
            when no_data_found then
              exit;
          end;
          --process_line
          gv_message := 'Linenumber ' || lv_line_counter;
          --process lines
          if substr(lv_readline, 1, 3) <> (gv_separator || gv_separator || gv_separator) then
            begin
              process_line(lv_readline);
            end;
          end if;
        end;
      end loop;
      --commit
      commit;
    end process_file;
  
    procedure close_file is
    begin
      --close file(s)
      gv_message := 'close files';
      if utl_file.is_open(gv_filehandle) = true then
        utl_file.fclose(gv_filehandle);
      end if;
      utl_file.fclose_all;
    end close_file;
  
    procedure finalize is
    begin
      --write log
      write_log('Successfully processed file ' || fp_filename || ' in directory ' || fp_directory,
                1);
    end finalize;
    --start main procedure
  begin
    --initialize
    initialize;
    --read_file
    read_file;
    --process_file
    process_file;
    --close file
    close_file;
    --finalize
    finalize;
  exception
    --exception handling global
    when gv_userexception then
      begin
        raise gv_userexception;
      end;
    when others then
      begin
        rollback;
        write_log('Error Others ' || sqlerrm || ' ' || gv_message, 3);
        close_file;
        gv_message := 'error processing file';
        raise gv_userexception;
      end;
  end import_u_masteraccount;

  function get_customerid(fp_customernumber in customer.customernumber%type)
    return customer.customer_id%type is
    fp_customerid customer.customer_id%type;
  begin
    --get_customerid
    gv_message := ' customer ' || nvl(to_char(fp_customernumber), 'NULL');
    if fp_customernumber is null then
      return null;
    else
      select c.customer_id
      into   fp_customerid
      from   customer c
      where  c.customernumber = fp_customernumber;
      return fp_customerid;
    end if;
  end get_customerid;

  procedure create_new_contract(fp_original_contractcode in varchar2,
                                fp_new_contractcode      in varchar2) is
    lv_rowcount        number;
    lv_con_customer_id number;
  begin
    --create_new_contract
    gv_message := 'create_new_contract';
    select cc.customer_link_id
    into   lv_con_customer_id
    from   contract cc
    where  cc.code = fp_new_contractcode;
    if lv_con_customer_id <> gv_new_masterid then
      begin
        gv_message := 'new contractcode ' || fp_new_contractcode ||
                      ' already linked to another customer';
        raise no_data_found;
      end;
    end if;
  exception
    when no_data_found then
      begin
        insert into contract
          (contract_id, code, description, contracttype_id, contractdocument, salesemployee_id,
           commisionpayablesales, accountmanager_id, commisionpayableaccmgr, customer_link_id, owner,
           address_id, country_id, cvrnumber, phonenumber, signdate, startdate, enddate, duration,
           termofnotice, terminationdate, autextensionperiod, contactperson_id, contactpersonname,
           gainreason_id, gaincompetitor_id, lostreason_id, lostcompetitor_id,
           startdatepriceincrease, updateevery, previouspriceincrease, nextschedulepriceincrease,
           agreedpriceindex_id, notagreedpriceindex_id, allownotagreedpricelists, purchaseorder,
           purchaseordervalue, purchaseorderexpirationdate, estimatedweeklysales, remark,
           systemuser_id, timestamp /*,status_id*/)
          select seq_contract.nextval, fp_new_contractcode, description, contracttype_id,
                 contractdocument, salesemployee_id, commisionpayablesales, accountmanager_id,
                 commisionpayableaccmgr, gv_new_masterid, owner, address_id, country_id, cvrnumber,
                 phonenumber, signdate, startdate, enddate, duration, termofnotice, terminationdate,
                 autextensionperiod, contactperson_id, contactpersonname, gainreason_id,
                 gaincompetitor_id, lostreason_id, lostcompetitor_id, startdatepriceincrease,
                 updateevery, previouspriceincrease, nextschedulepriceincrease, agreedpriceindex_id,
                 notagreedpriceindex_id, allownotagreedpricelists, purchaseorder, purchaseordervalue,
                 purchaseorderexpirationdate, estimatedweeklysales, remark, nvl(fp_systemuserid, 0),
                 sysdate --, status_id
          from   contract cc
          where  cc.code = fp_original_contractcode
          and    cc.customer_link_id = gv_org_masterid;
        lv_rowcount := sql%rowcount;
        if lv_rowcount = 0 then
          begin
            gv_message := 'original_contractcode ' || fp_original_contractcode;
            raise no_data_found;
          end;
        end if;
      end;
  end create_new_contract;

  procedure create_contractcustomer(fp_new_contractcode in varchar2) is
    lv_contractcustomerid number;
  begin
    --create_contractcustomer
    gv_message := 'create_contractcustomer';
    select cc.contractcustomer_id
    into   lv_contractcustomerid
    from   contractcustomer cc
    where  cc.contract_id =
           (select cc.contract_id from contract cc where cc.code = fp_new_contractcode)
    and    cc.customer_link_id = gv_new_masterid;
  exception
    when no_data_found then
      begin
        insert into contractcustomer
          (contractcustomer_id, contract_id, customer_link_id, startdate, enddate, systemuser_id,
           timestamp)
          select seq_contractcustomer.nextval, c.contract_id, gv_new_masterid, c.startdate,
                 c.enddate, nvl(fp_systemuserid, 0), sysdate
          from   contract c
          where  c.code = fp_new_contractcode;
      exception
        when dup_val_on_index then
          null;
      end;
  end create_contractcustomer;

  procedure copy_contractcustomers(fp_original_contractcode in varchar2,
                                   fp_new_contractcode      in varchar2) is
  begin
    --create_contractcustomers
    --CONTRACT_ID, CUSTOMER_LINK_ID
    gv_message := 'create_contractcustomers';
    insert into contractcustomer
      (contractcustomer_id, contract_id, customer_link_id, startdate, enddate, systemuser_id,
       timestamp)
      select seq_contractcustomer.nextval,
             (select cc.contract_id from contract cc where cc.code = fp_new_contractcode),
             cc.customer_link_id, cc.startdate, cc.enddate, nvl(fp_systemuserid, 0), sysdate
      from   contractcustomer cc
      where  cc.customer_link_id <> gv_org_masterid
      and    cc.contract_id =
             (select cc.contract_id from contract cc where cc.code = fp_original_contractcode)
      and    not exists
       (select 1
              from   contractcustomer xx
              where  xx.contract_id =
                     (select cc.contract_id from contract cc where cc.code = fp_new_contractcode)
              and    xx.customer_link_id = cc.customer_link_id);
  end copy_contractcustomers;

  procedure copy_pricelists(fp_original_pricelistcode in varchar2,
                            fp_pricetype              in number,
                            fp_new_pricelistcode      varchar2) is
    lv_rowcount number;
  
    procedure insert_generalpricelist is
    begin
      --unique key PRICETYPE, CODE
      insert into generalpricelist
        (priceindexcode, autopriceupdate, active, description, code, pricetype, generalpricelist_id,
         currency_id, timestamp, systemuser_id)
        select priceindexcode, autopriceupdate, active, description, fp_new_pricelistcode, pricetype,
               seq_generalpricelist.nextval, currency_id, sysdate, nvl(fp_systemuserid, 0)
        from   generalpricelist gl
        where  gl.code = fp_original_pricelistcode
        and    gl.pricetype = fp_pricetype;
      lv_rowcount := sql%rowcount;
      if lv_rowcount = 0 then
        begin
          gv_message := 'original_pricelistcode ' || fp_original_pricelistcode || ' pricetype ' ||
                        to_char(fp_pricetype);
          raise no_data_found;
        end;
      end if;
    exception
      when dup_val_on_index then
        begin
          --warning
          write_log('original pricelist ' || fp_original_pricelistcode || ' type ' ||
                    to_char(fp_pricetype) || ' did already exists', 2);
        end;
    end insert_generalpricelist;
  begin
    --copy_pricelist
    gv_message := 'copy generalpricelist';
    --insert_generalpricelist
    insert_generalpricelist;
    --copy the different general price lists, copy them to the new pricelist
    case fp_pricetype
      when 1 then
        begin
          --wash
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, STARTDATE, PRICETYPE
          insert into generalwashprice
            (generalwashprice_id, generalpricelist_id, product_id, sizedefinition_id,
             finishingmethod_id, timestamp, systemuser_id, price, startdate, pricetype)
            select seq_generalwashprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id,
                   finishingmethod_id, sysdate, nvl(fp_systemuserid, 0), price, startdate, pricetype
            from   generalwashprice gwp
            where  gwp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalwashprice wx
                    where  wx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    wx.product_id = gwp.product_id
                    and    wx.sizedefinition_id = gwp.sizedefinition_id
                    and    wx.finishingmethod_id = gwp.finishingmethod_id
                    and    wx.startdate = gwp.startdate
                    and    wx.pricetype = gwp.pricetype);
        end;
      when 2 then
        begin
          --rent
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, FINISHINGMETHOD_ID, TYPEOFRENT, STARTDATE, CHANGESPERWEEK
          insert into generalrentprice
            (generalrentprice_id, generalpricelist_id, product_id, sizedefinition_id,
             finishingmethod_id, timestamp, systemuser_id, price, startdate, changesperweek,
             typeofrent, invoicefrequencynumber)
            select seq_generalrentprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id,
                   finishingmethod_id, sysdate, nvl(fp_systemuserid, 0), price, startdate,
                   changesperweek, typeofrent, invoicefrequencynumber
            from   generalrentprice gr
            where  gr.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalrentprice rx
                    where  rx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    rx.product_id = gr.product_id
                    and    rx.sizedefinition_id = gr.sizedefinition_id
                    and    rx.finishingmethod_id = gr.finishingmethod_id
                    and    rx.typeofrent = gr.typeofrent
                    and    rx.startdate = gr.startdate
                    and    rx.changesperweek = gr.changesperweek);
        end;
      when 3 then
        begin
          --replacement
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
          insert into generalreplacementprice
            (generalreplacementprice_id, generalpricelist_id, product_id, sizedefinition_id,
             timestamp, systemuser_id, price, startdate)
            select seq_generalreplacementprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id, sysdate,
                   nvl(fp_systemuserid, 0), price, startdate
            from   generalreplacementprice grp
            where  grp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalreplacementprice mx
                    where  mx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    mx.product_id = grp.product_id
                    and    mx.sizedefinition_id = grp.sizedefinition_id
                    and    mx.startdate = grp.startdate);
        end;
      when 4 then
        begin
          --sales
          --GENERALPRICELIST_ID, PRODUCT_ID, SIZEDEFINITION_ID, STARTDATE
          insert into generalsalesprice
            (generalsalesprice_id, generalpricelist_id, product_id, sizedefinition_id, timestamp,
             systemuser_id, price, startdate)
            select seq_generalsalesprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), product_id, sizedefinition_id, sysdate,
                   nvl(fp_systemuserid, 0), price, startdate
            from   generalsalesprice gsp
            where  gsp.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalsalesprice cx
                    where  cx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    cx.product_id = gsp.product_id
                    and    cx.sizedefinition_id = gsp.sizedefinition_id
                    and    cx.startdate = gsp.startdate);
        end;
      when 6 then
        begin
          --repair
          --GENERALPRICELIST_ID, REPAIRTYPE_ID, STARTDATE
          insert into generalrepairprice
            (generalrepairprice_id, generalpricelist_id, repairtype_id, price, startdate,
             priceperminute, systemuser_id, timestamp)
            select seq_generalrepairprice.nextval,
                   (select glx.generalpricelist_id
                     from   generalpricelist glx
                     where  glx.code = fp_new_pricelistcode
                     and    glx.pricetype = fp_pricetype), repairtype_id, price, startdate,
                   priceperminute, nvl(fp_systemuserid, 0), sysdate
            from   generalrepairprice gf
            where  gf.generalpricelist_id =
                   (select gl.generalpricelist_id
                    from   generalpricelist gl
                    where  gl.code = fp_original_pricelistcode
                    and    gl.pricetype = fp_pricetype)
            and    not exists (select 1
                    from   generalrepairprice lx
                    where  lx.generalpricelist_id =
                           (select glx.generalpricelist_id
                            from   generalpricelist glx
                            where  glx.code = fp_new_pricelistcode
                            and    glx.pricetype = fp_pricetype)
                    and    lx.repairtype_id = gf.repairtype_id
                    and    lx.startdate = gf.startdate);
        end;
      else
        begin
          gv_message := 'Error no prices copied for pricetype ' || to_char(fp_pricetype);
          raise gv_userexception;
        end;
    end case;
  end copy_pricelists;

  procedure link_pricelists(fp_original_contractcode  in varchar2,
                            fp_new_contractcode       in varchar2,
                            fp_original_pricelistcode in varchar2,
                            fp_pricetype              in number,
                            fp_new_pricelistcode      varchar2) is
  begin
    --link_pricelists
    --CONTRACT_ID, GENERALPRICELIST_ID--, PRICETYPE
    gv_message := 'link_pricelists';
    insert into contractpricelist
      (contractpricelist_id, contract_id, generalpricelist_id, startdate, enddate, agreed,
       systemuser_id, timestamp)
      select seq_contractpricelist.nextval,
             (select cc.contract_id from contract cc where cc.code = fp_new_contractcode),
             (select glx.generalpricelist_id
               from   generalpricelist glx
               where  glx.code = fp_new_pricelistcode
               and    glx.pricetype = fp_pricetype), startdate, enddate, agreed,
             nvl(fp_systemuserid, 0), sysdate
      from   contractpricelist ccl
      where  ccl.contract_id =
             (select cc.contract_id from contract cc where cc.code = fp_original_contractcode)
      and    ccl.generalpricelist_id =
             (select gl.generalpricelist_id
               from   generalpricelist gl
               where  gl.code = fp_original_pricelistcode
               and    gl.pricetype = fp_pricetype)
      and    not exists
       (select 1
              from   contractpricelist cp
              where  cp.contract_id =
                     (select cc.contract_id from contract cc where cc.code = fp_new_contractcode)
              and    cp.generalpricelist_id =
                     (select glx.generalpricelist_id
                       from   generalpricelist glx
                       where  glx.code = fp_new_pricelistcode
                       and    glx.pricetype = fp_pricetype));
  end link_pricelists;

  procedure update_customers is
  begin
    --update_customers
    gv_message := 'update_customers';
    update customer c
    set    c.masteraccount_id = gv_new_masterid, c.timestamp = sysdate,
           c.systemuser_id = nvl(fp_systemuserid, 0)
    where  c.masteraccount_id = gv_org_masterid
    and    c.customer_id <> gv_org_masterid;
  end update_customers;
begin
  write_log('Start', 1);
  --import_u_masteraccount load file
  import_u_masteraccount;
  --process data from file
  for x in (select u.*, rowid from u_masteraccount u where u.processed = 0) loop
    begin
      --start loop x
      --get customer numbers
      gv_org_masterid := get_customerid(x.orignal_masteraccount);
      gv_new_masterid := get_customerid(x.new_masteraccount);
      --create new contract
      create_new_contract(x.original_contractcode, x.new_contractcode);
      --create_contractcustomer
      create_contractcustomer(x.new_contractcode);
      --copy contract customers
      copy_contractcustomers(x.original_contractcode, x.new_contractcode);
      --copy_pricelists
      copy_pricelists(x.original_pricelistcode, x.pricetype, x.new_pricelistcode);
      --link_pricelists
      link_pricelists(x.original_contractcode, x.new_contractcode, x.original_pricelistcode,
                      x.pricetype, x.new_pricelistcode);
      --update customers
      update_customers;
      --set flag
      update u_masteraccount u set u.processed = 1 where u.rowid = x.rowid;
      --commit all ok and count number of succesfully processed records
      commit;
      gv_counter := gv_counter + 1;
    exception
      --Exception handling, and count errors
      when gv_userexception then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End.' || gv_message, 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
      when no_data_found then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End. Error, No Data Found ' || gv_message || ' ORIGNAL_MASTERACCOUNT ' ||
                    to_char(x.orignal_masteraccount) || ' ORIGINAL_CONTRACTCODE ' ||
                    x.original_contractcode || ' ORIGINAL_PRICELISTCODE ' ||
                    x.original_pricelistcode || ' PRICETYPE ' || to_char(x.pricetype), 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
      when others then
        begin
          gv_errors := gv_errors + 1;
          rollback;
          write_log('End. Error ' || sqlerrm || ' ' || gv_message || ' ORIGNAL_MASTERACCOUNT ' ||
                    to_char(x.orignal_masteraccount) || ' ORIGINAL_CONTRACTCODE ' ||
                    x.original_contractcode || ' ORIGINAL_PRICELISTCODE ' ||
                    x.original_pricelistcode || ' PRICETYPE ' || to_char(x.pricetype), 3);
          --set flag
          update u_masteraccount u set u.processed = -1 where u.rowid = x.rowid;
          commit;
        end;
    end;
  end loop; --x
  commit;
  write_log(' file ' || fp_filename || ' in directory ' || fp_directory || ' processed', 1);
  write_log('End', 1);
exception
  --Exception handling
  when gv_userexception then
    begin
      rollback;
      write_log(gv_message || chr(10) || 'End.', 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error, No Data Found ' || gv_message || chr(10) || 'End.', 3);
    end;
  when others then
    begin
      rollback;
      write_log('Error ' || sqlerrm || ' ' || gv_message || ' file ' || fp_filename ||
                ' in directory ' || fp_directory || chr(10) || 'End.', 3);
    end;
end new_masteraccount;
/

create or replace procedure process_productsizesequence is
  gv_new_sequencenumber number;
begin
  --process_productsizesequence 1.0
  update productsize ps set ps.sequencenumber = ps.sequencenumber * -1;
  --update sequence sorted by sizecode
  for psy in (select p.product_id from product p where p.active = 'Y') loop
    begin
      gv_new_sequencenumber := 0;
      for psx in (select nvl((select x.sequencenumber
                              from   auj_sizepriority x
                              where  x.sizecode = s.code), 9999) sequencenumber, s.code,
                         ps.product_id, ps.sizedefinition_id
                  from   productsize ps
                  join   sizedefinition s
                  on     s.sizedefinition_id = ps.sizedefinition_id
                  where  ps.product_id = psy.product_id
                  order  by 1, 2) loop
        begin
          gv_new_sequencenumber := gv_new_sequencenumber + 1;
          update productsize ps
          set    ps.sequencenumber = gv_new_sequencenumber
          where  ps.product_id = psx.product_id
          and    ps.sizedefinition_id = psx.sizedefinition_id;
        end;
      end loop; --psx
    end;
  end loop; --psy
  --we skipped inactive products
  update productsize ps set ps.sequencenumber = ps.sequencenumber * -1 where ps.sequencenumber < 0;
  commit;
exception
  when others then
    rollback;
    raise;
end process_productsizesequence;
/

create or replace procedure rag_noneunique_2correct_stock(fp_ragreasoncode in ragreason.code%type,
                                                          fp_reasoncode    in reasoncode.code%type,
                                                          fp_stockroomcode in stockroom.code%type default '000RTS',
                                                          fp_systemuserid  in number default 0) is
  --rag_noneunique_2correct_stock Version 0.1
  --For version 8.03.11
  --global variables
  gv_user_exception exception;
  gv_counter                    number := 0;
  gv_message                    abslog.message%type;
  gv_systemuserid               systemuser.systemuser_id%type := 0;
  gv_businessunitid             businessunit.businessunit_id%type;
  gv_plantid                    plant.plant_id%type;
  gv_stockroomid                stockroom.stockroom_id%type;
  gv_stockroomlocationid        stockroomlocation.stockroomlocation_id%type;
  gv_ragreasonid                ragreason.ragreason_id%type;
  gv_reasoncodeid               reasoncode.reasoncode_id%type;
  gv_transactiontypeid          transactiontype.transactiontype_id%type;
  gv_stockreservationpergradeid stockreservationpergrade.stockreservationpergrade_id%type;

  --internal procedures
  procedure write_log(lfp_message  in abslog.message%type,
                      lfp_priority in abslog.priority%type default 1) is
  begin
    /*
    Write message in ABSLOG with these priorities
    1 = Message
    2 = Warning
    3 = Error
    4 = Stack trace
    5 = Debug info
    */
    dbms_output.put_line(lfp_message);
    abslogwrite.abslog_write(5, 'rag_noneunique_2correct_stock', gv_plantid, lfp_priority,
                             lfp_message, fp_systemuserid);
  end write_log;

  procedure initialize is
  begin
    --initialize
    --check fp_stockroomcode parameter
    if fp_stockroomcode is null then
      begin
        gv_message := 'parameter fp_stockroomcode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_stockroomcode ''' || nvl(fp_stockroomcode, 'NULL') || '''';
        select st.stockroom_id, st.managedbybu_id, bu.plant_id
        into   gv_stockroomid, gv_businessunitid, gv_plantid
        from   stockroom st
        join   businessunit bu
        on     bu.businessunit_id = st.managedbybu_id
        where  st.code = fp_stockroomcode;
      end;
    end if;
    --check fp_ragreasoncode
    if fp_ragreasoncode is null then
      begin
        gv_message := 'parameter fp_ragreasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_ragreasoncode ' || nvl(fp_ragreasoncode, 'NULL');
        select rg.ragreason_id
        into   gv_ragreasonid
        from   ragreason rg
        where  rg.code = fp_ragreasoncode;
      end;
    end if;
    --check fp_reasoncode
    if fp_reasoncode is null then
      begin
        gv_message := 'parameter fp_reasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_reasoncode ' || nvl(fp_reasoncode, 'NULL');
        select rs.reasoncode_id
        into   gv_reasoncodeid
        from   reasoncode rs
        where  rs.code = fp_reasoncode;
      end;
    end if;
    --get transaction type
    select min(td.transactiontype_id)
    into   gv_transactiontypeid
    from   transactiontype_desc td
    where  td.description = 'Ragged from Stock';
    if gv_transactiontypeid is null then
      begin
        gv_message := 'transaction type ''Ragged from Stock'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --get gv_systemuserid
    if fp_systemuserid is null then
      begin
        select st.systemuser_id
        into   gv_systemuserid
        from   systemuser st
        where  st.username = 'SYSDAM';
      exception
        when no_data_found then
          begin
            select nvl(min(st.systemuser_id), 0) into gv_systemuserid from systemuser st;
          end;
      end;
    else
      begin
        gv_systemuserid := fp_systemuserid;
      end;
    end if;
  end initialize;

  procedure ragnoneuniqueitemstock is
    lv_real_desc_qty number;
  
    --begin internal procedures for ragnoneuniqueitemstock
    procedure update_stockquantity is
    begin
      --update_stockquantity
      gv_message := 'update stockquantity fp_stockroomcode ' || fp_stockroomcode;
      update stockquantity q
      set    q.qtynonunique = 0, q.systemuser_id = gv_systemuserid, q.timestamp = sysdate
      where  q.stockreservationpergrade_id = gv_stockreservationpergradeid
      and    q.stockroomlocation_id = gv_stockroomlocationid;
    end update_stockquantity;
  
    procedure create_stocktransaction(fp_decrease_qty in stockquantity.qtynonunique%type) is
    begin
      --create_stocktransaction
      --key STOCKRESERVATIONPERGRADE_ID, TRANSACTIONDATE, REASONCODE_ID, TRANSACTIONTYPE_ID, UNIQUESTOCK
      gv_message := 'create stocktransaction fp_stockroomcode ' || fp_stockroomcode ||
                    to_char(fp_decrease_qty);
      begin
        insert into stocktransaction
          (stocktransaction_id, stockreservationpergrade_id, transactiondate, reasoncode_id,
           transactiontype_id, uniquestock, quantity, systemuser_id, timestamp, exported, delayed,
           transactiontimestamp, fromstockroomlocation_id)
        values
          (seq_stocktransaction.nextval, gv_stockreservationpergradeid, trunc(sysdate),
           gv_reasoncodeid, gv_transactiontypeid, 'N', fp_decrease_qty * -1, gv_systemuserid,
           sysdate, 'N', 'N', sysdate, gv_stockroomlocationid);
      exception
        when dup_val_on_index then
          begin
            update stocktransaction st
            set    st.quantity = st.quantity - fp_decrease_qty, st.systemuser_id = gv_systemuserid,
                   st.timestamp = sysdate
            where  st.stockreservationpergrade_id = gv_stockreservationpergradeid
            and    st.transactiondate = trunc(sysdate)
            and    st.reasoncode_id = gv_reasoncodeid
            and    st.transactiontype_id = gv_transactiontypeid
            and    st.uniquestock = 'N';
          end;
      end;
    end create_stocktransaction;
    --end internal procedures for ragnoneuniqueitemstock
  begin
    --ragnoneuniqueitemstock
    gv_message := 'ragnoneuniqueitemstock';
    for x in (select *
              from   v_nonunique_stockqty_actions v
              where  v.stockroomcode = fp_stockroomcode
              and    v.qty_stocktransactions < 0) loop
      begin
        --we correct negative amount
        gv_stockreservationpergradeid := x.stockreservationpergrade_id;
        gv_stockroomlocationid        := x.stockroomlocation_id;
        lv_real_desc_qty              := x.qty_stocktransactions;
        --create stocktransaction 
        create_stocktransaction(lv_real_desc_qty);
        --update_stockquantity
        update_stockquantity;
        --counter
        gv_counter := gv_counter + (lv_real_desc_qty * -1);
      end;
    end loop; --x ragnoneuniqueitemstock loop
  end ragnoneuniqueitemstock;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    commit;
    if gv_counter > 0 then
      begin
        write_log(to_char(gv_counter) ||
                  ' noneunique stocktransactions corrected from stockroomcode ' ||
                  fp_stockroomcode);
      end;
    else
      begin
        write_log('No items were corrected from fp_stockroomcode ' || fp_stockroomcode);
      end;
    end if;
  end finalize;

  --Main program block
begin
  --initialize
  initialize;
  --ragnoneuniqueitemstock
  ragnoneuniqueitemstock;
  --finalize
  finalize;
exception
  when gv_user_exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('No data found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(gv_message, 3);
      write_log(sqlerrm, 5);
    end;
end rag_noneunique_2correct_stock;
/

create or replace procedure rag_noneunique_from_stock(fp_ragreasoncode          in ragreason.code%type,
                                                      fp_reasoncode             in reasoncode.code%type,
                                                      fp_stockroomcode          in stockroom.code%type,
                                                      fp_rowcode                in stockroomlocation.rowcode%type,
                                                      fp_locationcode           in stockroomlocation.locationcode%type,
                                                      fp_productcode            in product.code%type,
                                                      fp_before_lastonstockdate in date default (trunc(sysdate) - 32),
                                                      fp_systemuserid           in number default 0) is
  --rag_noneunique_from_stock Version 0.7
  --22-dec-2021 ABS-129185 Adjust scripts to rag specified products in 000RTS stockroom (block location)
  --global variables
  gv_user_exception exception;
  gv_counter                    number := 0;
  gv_message                    abslog.message%type;
  gv_systemuserid               systemuser.systemuser_id%type := 0;
  gv_businessunitid             businessunit.businessunit_id%type;
  gv_plantid                    plant.plant_id%type;
  gv_stockroomid                stockroom.stockroom_id%type;
  gv_stockroomlocationid        stockroomlocation.stockroomlocation_id%type;
  gv_ragreasonid                ragreason.ragreason_id%type;
  gv_reasoncodeid               reasoncode.reasoncode_id%type;
  gv_transactiontypeid          transactiontype.transactiontype_id%type;
  gv_stockreservationpergradeid stockreservationpergrade.stockreservationpergrade_id%type;
  gv_productid                  product.product_id%type;

  --internal procedures
  procedure write_log(lfp_message  in abslog.message%type,
                      lfp_priority in abslog.priority%type default 1) is
  begin
    /*
    Write message in ABSLOG with these priorities
    1 = Message
    2 = Warning
    3 = Error
    4 = Stack trace
    5 = Debug info
    */
    dbms_output.put_line(lfp_message);
    abslogwrite.abslog_write(5, 'rag_noneunique_from_stock', gv_plantid, lfp_priority, lfp_message,
                             fp_systemuserid);
  end write_log;

  procedure initialize is
    lv_locationtypeid      locationtype.locationtype_id%type;
    lv_locationtypeblockid locationtype.locationtype_id%type;
    lv_tom                 product.typeofmerchandise%type;
  begin
    --initialize
    --get location type block
    select min(lct.locationtype_id)
    into   lv_locationtypeblockid
    from   locationtype lct
    where  lct.code = 'BLOCK';
    if lv_locationtypeblockid is null then
      begin
        gv_message := 'location type ''BLOCK'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_stockroomcode parameter
    if fp_stockroomcode is null then
      begin
        gv_message := 'parameter fp_stockroomcode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_stockroomcode ''' || nvl(fp_stockroomcode, 'NULL') || '''';
        select st.stockroom_id, st.managedbybu_id, bu.plant_id
        into   gv_stockroomid, gv_businessunitid, gv_plantid
        from   stockroom st
        join   businessunit bu
        on     bu.businessunit_id = st.managedbybu_id
        where  st.code = fp_stockroomcode;
      end;
    end if;
    --check fp_locationcode
    begin
      if fp_locationcode is null then
        begin
          gv_message := 'parameter fp_locationcode cannot be left blank';
          raise gv_user_exception;
        end;
      else
        begin
          if fp_rowcode is null then
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode left blank';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode is null
              and    srl.locationcode = fp_locationcode;
            end;
          else
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode ''' || fp_rowcode || '''';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode = fp_rowcode
              and    srl.locationcode = fp_locationcode;
            end;
          end if;
        end;
      end if;
    exception
      when too_many_rows then
        begin
          gv_message := 'There is more then 1 stockroomlocation because of different areacodes for the stockroomcode ''' ||
                        fp_stockroomcode || ''' location code ''' || fp_locationcode ||
                        ''' row code ''' || nvl(fp_rowcode, 'NULL') || '''';
          raise gv_user_exception;
        end;
    end;
    --check is location type is BLOCK
    if lv_locationtypeid <> lv_locationtypeblockid then
      begin
        gv_message := 'The stockroomlocation for the stockroomcode ''' || fp_stockroomcode ||
                      ''' location code ''' || fp_locationcode || ''' row code ''' ||
                      nvl(fp_rowcode, 'NULL') || ''' does NOT have the location type ''BLOCK'' !?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_before_lastonstockdate parameter
    if fp_before_lastonstockdate is null then
      begin
        gv_message := 'parameter fp_before_lastonstockdate cannot be left empty';
        raise gv_user_exception;
      end;
    else
      begin
        if fp_before_lastonstockdate > (trunc(sysdate) - 32) then
          begin
            gv_message := 'parameter fp_before_lastonstockdate should be <= ' ||
                          to_date(trunc(sysdate) - 32, 'DD-MM-YYYY');
            raise gv_user_exception;
          end;
        end if;
      end;
    end if;
    --check fp_ragreasoncode
    if fp_ragreasoncode is null then
      begin
        gv_message := 'parameter fp_ragreasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_ragreasoncode ' || nvl(fp_ragreasoncode, 'NULL');
        select rg.ragreason_id
        into   gv_ragreasonid
        from   ragreason rg
        where  rg.code = fp_ragreasoncode;
      end;
    end if;
    --check fp_reasoncode
    if fp_reasoncode is null then
      begin
        gv_message := 'parameter fp_reasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_reasoncode ' || nvl(fp_reasoncode, 'NULL');
        select rs.reasoncode_id
        into   gv_reasoncodeid
        from   reasoncode rs
        where  rs.code = fp_reasoncode;
      end;
    end if;
    --get transaction type
    select min(td.transactiontype_id)
    into   gv_transactiontypeid
    from   transactiontype_desc td
    where  td.description = 'Ragged from Stock';
    if gv_transactiontypeid is null then
      begin
        gv_message := 'transaction type ''Ragged from Stock'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --get gv_systemuserid
    if fp_systemuserid is null then
      begin
        select st.systemuser_id
        into   gv_systemuserid
        from   systemuser st
        where  st.username = 'SYSDAM';
      exception
        when no_data_found then
          begin
            select nvl(min(st.systemuser_id), 0) into gv_systemuserid from systemuser st;
          end;
      end;
    else
      begin
        gv_systemuserid := fp_systemuserid;
      end;
    end if;
    --get product id
    if fp_productcode is null then
      gv_productid := null;
    else
      begin
        --get the product id of the uniqueitem
        gv_message := 'Product code ' || fp_productcode;
        select p.product_id, p.typeofmerchandise
        into   gv_productid, lv_tom
        from   product p
        where  p.code = fp_productcode;
        if lv_tom = 2 then
          begin
            gv_productid := null;
            gv_message   := 'Product ' || fp_productcode || ' cannot be TOM=2 (uniqueitem)';
            raise gv_user_exception;
          end;
        end if;
      end;
    end if;
  end initialize;

  procedure ragnoneuniqueitemstock is
    lv_real_desc_qty number;
  
    --begin internal procedures for ragnoneuniqueitemstock
    procedure update_stockquantity is
    begin
      --update_stockquantity
      gv_message := 'update stockquantity fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY');
      update stockquantity q
      set    q.qtynonunique =
              (select sum(st.quantity)
               from   stocktransaction st
               where  (q.stockroomlocation_id = st.tostockroomlocation_id or
                      q.stockroomlocation_id = st.fromstockroomlocation_id)
               and    q.stockreservationpergrade_id = st.stockreservationpergrade_id
               and    st.uniquestock = 'N'), q.systemuser_id = gv_systemuserid,
             q.timestamp = sysdate
      where  q.stockreservationpergrade_id = gv_stockreservationpergradeid
      and    q.stockroomlocation_id = gv_stockroomlocationid;
    end update_stockquantity;
  
    procedure create_stocktransaction(fp_decrease_qty in stockquantity.qtynonunique%type) is
    begin
      --create_stocktransaction
      --key STOCKRESERVATIONPERGRADE_ID, TRANSACTIONDATE, REASONCODE_ID, TRANSACTIONTYPE_ID, UNIQUESTOCK
      gv_message := 'create stocktransaction fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' quantity ' ||
                    to_char(fp_decrease_qty);
      begin
        insert into stocktransaction
          (stocktransaction_id, stockreservationpergrade_id, transactiondate, reasoncode_id,
           transactiontype_id, uniquestock, quantity, systemuser_id, timestamp, exported, delayed,
           transactiontimestamp, fromstockroomlocation_id)
        values
          (seq_stocktransaction.nextval, gv_stockreservationpergradeid, trunc(sysdate),
           gv_reasoncodeid, gv_transactiontypeid, 'N', fp_decrease_qty * -1, gv_systemuserid,
           sysdate, 'N', 'N', sysdate, gv_stockroomlocationid);
      exception
        when dup_val_on_index then
          begin
            update stocktransaction st
            set    st.quantity = st.quantity - fp_decrease_qty, st.systemuser_id = gv_systemuserid,
                   st.timestamp = sysdate
            where  st.stockreservationpergrade_id = gv_stockreservationpergradeid
            and    st.transactiondate = trunc(sysdate)
            and    st.reasoncode_id = gv_reasoncodeid
            and    st.transactiontype_id = gv_transactiontypeid
            and    st.uniquestock = 'N';
          end;
      end;
    end create_stocktransaction;
    --end internal procedures for ragnoneuniqueitemstock
  begin
    --ragnoneuniqueitemstock
    gv_message := 'ragnoneuniqueitemstock';
    for x in (select (select sum(st.quantity)
                       from   stocktransaction st
                       where  (q.stockroomlocation_id = st.tostockroomlocation_id or
                              q.stockroomlocation_id = st.fromstockroomlocation_id)
                       and    q.stockreservationpergrade_id = st.stockreservationpergrade_id
                       and    st.uniquestock = 'N'
                       and    st.transactiondate < fp_before_lastonstockdate) decrease_qty,
                     (select sum(st.quantity)
                       from   stocktransaction st
                       where  (q.stockroomlocation_id = st.tostockroomlocation_id or
                              q.stockroomlocation_id = st.fromstockroomlocation_id)
                       and    q.stockreservationpergrade_id = st.stockreservationpergrade_id
                       and    st.uniquestock = 'N') max_decrease_qty, q.qtynonunique,
                     q.stockreservationpergrade_id, q.stockroomlocation_id, sg.qualitygrade_id,
                     q.timestamp, si.product_id, si.sizedefinition_id, si.customer_id,
                     si.customerowned
              from   stockquantity q
              join   stockreservationpergrade sg
              on     sg.stockreservationpergrade_id = q.stockreservationpergrade_id
              join   stockdefinitionperitem si
              on     si.stockdefinitionperitem_id = sg.stockdefinitionperitem_id
              where  q.qtynonunique > 0
              and    (si.product_id = gv_productid or gv_productid is null)
              and    q.stockroomlocation_id = gv_stockroomlocationid
              and    (select sum(st.quantity)
                      from   stocktransaction st
                      where  (q.stockroomlocation_id = st.tostockroomlocation_id or
                             q.stockroomlocation_id = st.fromstockroomlocation_id)
                      and    q.stockreservationpergrade_id = st.stockreservationpergrade_id
                      and    st.uniquestock = 'N'
                      and    st.transactiondate < fp_before_lastonstockdate) > 0) loop
      begin
        --max descrease is the max the stock quantity can go down.
        if x.max_decrease_qty < x.decrease_qty then
          begin
            --because the decrease is more then the max, we must take the max.
            lv_real_desc_qty := x.max_decrease_qty;
          end;
        else
          begin
            --decrease is less then the max, so we can use this qty
            lv_real_desc_qty := x.decrease_qty;
          end;
        end if;
        gv_stockreservationpergradeid := x.stockreservationpergrade_id;
        --create stocktransaction 
        create_stocktransaction(lv_real_desc_qty);
        --update_stockquantity
        update_stockquantity;
        --create_outofstockhistory
        gv_message := 'create outofstockhistory fp_stockroomcode ' || fp_stockroomcode ||
                      ' fp_before_lastonstockdate ' ||
                      to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' quantity ' ||
                      to_char(lv_real_desc_qty);
        insert into outofstockhistory
          (outofstockhistory_id, processbusinessunit_id, stockroom_id, uniqueitem_link_id,
           outofstockdate, reasoncode_id, quantity, product_link_id, sizedefinition_link_id,
           qualitygrade_id, customerowned, relatedcustomer_link_id, outofstockyear, outofstockweek,
           outofstockday, ragreason_id, supplier_id, primaryid, systemuser_id, timestamp)
        values
          (seq_outofstockhistory.nextval, gv_businessunitid, gv_stockroomid, null /*uniqueitem_id*/,
           trunc(sysdate), gv_reasoncodeid, lv_real_desc_qty, x.product_id, x.sizedefinition_id,
           x.qualitygrade_id, x.customerowned, null /*relatedcustomer_id*/, to_char(sysdate, 'IYYY'),
           to_char(sysdate, 'IW'), getabsdaynumber(sysdate), gv_ragreasonid, null /*supplier_id*/,
           null /*primaryid*/, gv_systemuserid, sysdate /*timestamp*/);
        --counter
        gv_counter := gv_counter + x.qtynonunique;
      end;
    end loop; --x ragnoneuniqueitemstock loop
  end ragnoneuniqueitemstock;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    commit;
    if gv_counter > 0 then
      begin
        write_log(to_char(gv_counter) || ' noneunique (ragged) removed from stock');
      end;
    else
      begin
        write_log('No items were (ragged) removed from stock!');
      end;
    end if;
  end finalize;

  --Main program block
begin
  --initialize
  initialize;
  --ragnoneuniqueitemstock
  ragnoneuniqueitemstock;
  --finalize
  finalize;
exception
  when gv_user_exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('No data found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(gv_message, 3);
      write_log(sqlerrm, 5);
    end;
end rag_noneunique_from_stock;
/

create or replace procedure rag_noneunique_from_stockrts(fp_ragreasoncode in ragreason.code%type,
                                                         fp_reasoncode    in reasoncode.code%type,
                                                         fp_systemuserid  in number default 0) is
  --rag_noneunique_from_stock Version 0.4
  --For version 8.03.11
  --global variables
  --FIXED values
  fp_stockroomcode stockroom.code%type := '000RTS';
  fp_rowcode       stockroomlocation.rowcode%type := 'RTS';
  fp_locationcode  stockroomlocation.locationcode%type := '-';
  --Variables
  gv_user_exception exception;
  gv_counter                    number := 0;
  gv_message                    abslog.message%type;
  gv_systemuserid               systemuser.systemuser_id%type := 0;
  gv_businessunitid             businessunit.businessunit_id%type;
  gv_plantid                    plant.plant_id%type;
  gv_stockroomid                stockroom.stockroom_id%type;
  gv_stockroomlocationid        stockroomlocation.stockroomlocation_id%type;
  gv_ragreasonid                ragreason.ragreason_id%type;
  gv_reasoncodeid               reasoncode.reasoncode_id%type;
  gv_transactiontypeid          transactiontype.transactiontype_id%type;
  gv_stockreservationpergradeid stockreservationpergrade.stockreservationpergrade_id%type;

  --internal procedures
  procedure write_log(lfp_message  in abslog.message%type,
                      lfp_priority in abslog.priority%type default 1) is
  begin
    /*
    Write message in ABSLOG with these priorities
    1 = Message
    2 = Warning
    3 = Error
    4 = Stack trace
    5 = Debug info
    */
    dbms_output.put_line(lfp_message);
    abslogwrite.abslog_write(5, 'rag_noneunique_from_stockrts', gv_plantid, lfp_priority,
                             lfp_message, fp_systemuserid);
  end write_log;

  procedure initialize is
    lv_locationtypeid      locationtype.locationtype_id%type;
    lv_locationtypeblockid locationtype.locationtype_id%type;
  begin
    --initialize
    --get location type block
    select min(lct.locationtype_id)
    into   lv_locationtypeblockid
    from   locationtype lct
    where  lct.code = 'BLOCK';
    if lv_locationtypeblockid is null then
      begin
        gv_message := 'location type ''BLOCK'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_stockroomcode parameter
    if fp_stockroomcode is null then
      begin
        gv_message := 'parameter fp_stockroomcode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_stockroomcode ''' || nvl(fp_stockroomcode, 'NULL') || '''';
        select st.stockroom_id, st.managedbybu_id, bu.plant_id
        into   gv_stockroomid, gv_businessunitid, gv_plantid
        from   stockroom st
        join   businessunit bu
        on     bu.businessunit_id = st.managedbybu_id
        where  st.code = fp_stockroomcode;
      end;
    end if;
    --check fp_locationcode
    begin
      if fp_locationcode is null then
        begin
          gv_message := 'parameter fp_locationcode cannot be left blank';
          raise gv_user_exception;
        end;
      else
        begin
          if fp_rowcode is null then
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode left blank';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode is null
              and    srl.locationcode = fp_locationcode;
            end;
          else
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode ''' || fp_rowcode || '''';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode = fp_rowcode
              and    srl.locationcode = fp_locationcode;
            end;
          end if;
        end;
      end if;
    exception
      when too_many_rows then
        begin
          gv_message := 'There is more then 1 stockroomlocation because of different areacodes for the stockroomcode ''' ||
                        fp_stockroomcode || ''' location code ''' || fp_locationcode ||
                        ''' row code ''' || nvl(fp_rowcode, 'NULL') || '''';
          raise gv_user_exception;
        end;
    end;
    --check is location type is BLOCK
    if lv_locationtypeid <> lv_locationtypeblockid then
      begin
        gv_message := 'The stockroomlocation for the stockroomcode ''' || fp_stockroomcode ||
                      ''' location code ''' || fp_locationcode || ''' row code ''' ||
                      nvl(fp_rowcode, 'NULL') || ''' does NOT have the location type ''BLOCK'' !?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_ragreasoncode
    if fp_ragreasoncode is null then
      begin
        gv_message := 'parameter fp_ragreasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_ragreasoncode ' || nvl(fp_ragreasoncode, 'NULL');
        select rg.ragreason_id
        into   gv_ragreasonid
        from   ragreason rg
        where  rg.code = fp_ragreasoncode;
      end;
    end if;
    --check fp_reasoncode
    if fp_reasoncode is null then
      begin
        gv_message := 'parameter fp_reasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_reasoncode ' || nvl(fp_reasoncode, 'NULL');
        select rs.reasoncode_id
        into   gv_reasoncodeid
        from   reasoncode rs
        where  rs.code = fp_reasoncode;
      end;
    end if;
    --get transaction type
    select min(td.transactiontype_id)
    into   gv_transactiontypeid
    from   transactiontype_desc td
    where  td.description = 'Ragged from Stock';
    if gv_transactiontypeid is null then
      begin
        gv_message := 'transaction type ''Ragged from Stock'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --get gv_systemuserid
    if fp_systemuserid is null then
      begin
        select st.systemuser_id
        into   gv_systemuserid
        from   systemuser st
        where  st.username = 'SYSDAM';
      exception
        when no_data_found then
          begin
            select nvl(min(st.systemuser_id), 0) into gv_systemuserid from systemuser st;
          end;
      end;
    else
      begin
        gv_systemuserid := fp_systemuserid;
      end;
    end if;
  end initialize;

  procedure ragnoneuniqueitemstock is
    --begin internal procedures for ragnoneuniqueitemstock
    procedure update_stockquantity is
    begin
      --update_stockquantity
      gv_message := 'update stockquantity fp_stockroomcode ' || fp_stockroomcode;
      update stockquantity q
      set    q.qtynonunique = 0, q.systemuser_id = gv_systemuserid, q.timestamp = sysdate
      where  q.stockreservationpergrade_id = gv_stockreservationpergradeid
      and    q.stockroomlocation_id = gv_stockroomlocationid;
    end update_stockquantity;
  
    procedure create_stocktransaction(fp_decrease_qty in stockquantity.qtynonunique%type) is
    begin
      --create_stocktransaction
      --key STOCKRESERVATIONPERGRADE_ID, TRANSACTIONDATE, REASONCODE_ID, TRANSACTIONTYPE_ID, UNIQUESTOCK
      gv_message := 'create stocktransaction fp_stockroomcode ' || fp_stockroomcode || ' quantity ' ||
                    to_char(fp_decrease_qty);
      begin
        insert into stocktransaction
          (stocktransaction_id, stockreservationpergrade_id, transactiondate, reasoncode_id,
           transactiontype_id, uniquestock, quantity, systemuser_id, timestamp, exported, delayed,
           transactiontimestamp, fromstockroomlocation_id)
        values
          (seq_stocktransaction.nextval, gv_stockreservationpergradeid, trunc(sysdate),
           gv_reasoncodeid, gv_transactiontypeid, 'N', fp_decrease_qty * -1, gv_systemuserid,
           sysdate, 'N', 'N', sysdate, gv_stockroomlocationid);
      exception
        when dup_val_on_index then
          begin
            update stocktransaction st
            set    st.quantity = st.quantity - fp_decrease_qty, st.systemuser_id = gv_systemuserid,
                   st.timestamp = sysdate
            where  st.stockreservationpergrade_id = gv_stockreservationpergradeid
            and    st.transactiondate = trunc(sysdate)
            and    st.reasoncode_id = gv_reasoncodeid
            and    st.transactiontype_id = gv_transactiontypeid
            and    st.uniquestock = 'N';
          end;
      end;
    end create_stocktransaction;
    --end internal procedures for ragnoneuniqueitemstock
  begin
    --ragnoneuniqueitemstock
    gv_message := 'ragnoneuniqueitemstock';
    for x in (select q.qtynonunique decrease_qty, q.qtynonunique max_decrease_qty, q.qtynonunique,
                     q.stockreservationpergrade_id, q.stockroomlocation_id, sg.qualitygrade_id,
                     q.timestamp, si.product_id, si.sizedefinition_id, si.customer_id,
                     si.customerowned
              from   stockquantity q
              join   stockreservationpergrade sg
              on     sg.stockreservationpergrade_id = q.stockreservationpergrade_id
              join   stockdefinitionperitem si
              on     si.stockdefinitionperitem_id = sg.stockdefinitionperitem_id
              where  q.qtynonunique > 0
              and    q.stockroomlocation_id = gv_stockroomlocationid) loop
      begin
        gv_stockreservationpergradeid := x.stockreservationpergrade_id;
        --create stocktransaction 
        create_stocktransaction(x.qtynonunique);
        --update_stockquantity
        update_stockquantity;
        --create_outofstockhistory
        gv_message := 'create outofstockhistory fp_stockroomcode ' || fp_stockroomcode ||
                      ' quantity ' || to_char(x.qtynonunique);
        insert into outofstockhistory
          (outofstockhistory_id, processbusinessunit_id, stockroom_id, uniqueitem_link_id,
           outofstockdate, reasoncode_id, quantity, product_link_id, sizedefinition_link_id,
           qualitygrade_id, customerowned, relatedcustomer_link_id, outofstockyear, outofstockweek,
           outofstockday, ragreason_id, supplier_id, primaryid, systemuser_id, timestamp)
        values
          (seq_outofstockhistory.nextval, gv_businessunitid, gv_stockroomid, null /*uniqueitem_id*/,
           trunc(sysdate), gv_reasoncodeid, x.qtynonunique, x.product_id, x.sizedefinition_id,
           x.qualitygrade_id, x.customerowned, null /*relatedcustomer_id*/, to_char(sysdate, 'IYYY'),
           to_char(sysdate, 'IW'), getabsdaynumber(sysdate), gv_ragreasonid, null /*supplier_id*/,
           null /*primaryid*/, gv_systemuserid, sysdate /*timestamp*/);
        --counter
        gv_counter := gv_counter + x.qtynonunique;
      end;
    end loop; --x ragnoneuniqueitemstock loop
  end ragnoneuniqueitemstock;

  procedure correct_negativeamounts is
    procedure create_negstocktransaction(fp_decrease_qty in stockquantity.qtynonunique%type) is
    begin
      --create_stocktransaction
      --key STOCKRESERVATIONPERGRADE_ID, TRANSACTIONDATE, REASONCODE_ID, TRANSACTIONTYPE_ID, UNIQUESTOCK
      gv_message := 'create stocktransaction fp_stockroomcode ' || fp_stockroomcode || ' quantity ' ||
                    to_char(fp_decrease_qty);
      begin
        insert into stocktransaction
          (stocktransaction_id, stockreservationpergrade_id, transactiondate, reasoncode_id,
           transactiontype_id, uniquestock, quantity, systemuser_id, timestamp, exported, delayed,
           transactiontimestamp, fromstockroomlocation_id)
        values
          (seq_stocktransaction.nextval, gv_stockreservationpergradeid, trunc(sysdate),
           gv_reasoncodeid, gv_transactiontypeid, 'N', fp_decrease_qty, gv_systemuserid, sysdate,
           'N', 'N', sysdate, gv_stockroomlocationid);
      exception
        when dup_val_on_index then
          begin
            update stocktransaction st
            set    st.quantity = st.quantity + fp_decrease_qty, st.systemuser_id = gv_systemuserid,
                   st.timestamp = sysdate
            where  st.stockreservationpergrade_id = gv_stockreservationpergradeid
            and    st.transactiondate = trunc(sysdate)
            and    st.reasoncode_id = gv_reasoncodeid
            and    st.transactiontype_id = gv_transactiontypeid
            and    st.uniquestock = 'N';
          end;
      end;
    end create_negstocktransaction;
  begin
    for y in (select q.qtynonunique decrease_qty, q.qtynonunique max_decrease_qty, q.qtynonunique,
                     q.stockreservationpergrade_id, q.stockroomlocation_id, sg.qualitygrade_id,
                     q.timestamp, si.product_id, si.sizedefinition_id, si.customer_id,
                     si.customerowned
              from   stockquantity q
              join   stockreservationpergrade sg
              on     sg.stockreservationpergrade_id = q.stockreservationpergrade_id
              join   stockdefinitionperitem si
              on     si.stockdefinitionperitem_id = sg.stockdefinitionperitem_id
              where  q.qtynonunique < 0
              and    q.stockroomlocation_id = gv_stockroomlocationid) loop
      begin
        gv_stockreservationpergradeid := y.stockreservationpergrade_id;
        --create stocktransaction 
        create_negstocktransaction(y.qtynonunique);
        --update stockquantity
        update stockquantity q
        set    q.qtynonunique = 0
        where  q.stockreservationpergrade_id = y.stockreservationpergrade_id
        and    q.stockroomlocation_id = y.stockroomlocation_id;
      end;
    end loop;
  end correct_negativeamounts;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    commit;
    if gv_counter > 0 then
      begin
        write_log(to_char(gv_counter) || ' noneunique (ragged) removed from stock');
      end;
    else
      begin
        write_log('No items were (ragged) removed from stock!');
      end;
    end if;
  end finalize;
  --Main program block
begin
  --initialize
  initialize;
  --ragnoneuniqueitemstock
  ragnoneuniqueitemstock;
  --correct negative amounts
  correct_negativeamounts;
  --finalize
  finalize;
exception
  when gv_user_exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('No data found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(gv_message, 3);
      write_log(sqlerrm, 5);
    end;
end rag_noneunique_from_stockrts;
/

create or replace procedure rag_uniqueitems_on_stock(fp_ragreasoncode          in ragreason.code%type,
                                                     fp_reasoncode             in reasoncode.code%type,
                                                     fp_stockroomcode          in stockroom.code%type,
                                                     fp_rowcode                in stockroomlocation.rowcode%type,
                                                     fp_locationcode           in stockroomlocation.locationcode%type,
                                                     fp_productcode            in product.code%type,
                                                     fp_before_lastonstockdate in date default (trunc(sysdate) - 60),
                                                     fp_systemuserid           in number default 0) is
  --RAG_Uniqueitems_On_Stock Version 0.8
  --22-dec-2021 ABS-129185 Adjust scripts to rag specified products in 000RTS stockroom (block location)
  --global variables
  gv_user_exception exception;
  gv_counter                    number := 0;
  gv_message                    abslog.message%type;
  gv_systemuserid               systemuser.systemuser_id%type := 0;
  gv_businessunitid             businessunit.businessunit_id%type;
  gv_plantid                    plant.plant_id%type;
  gv_stockroomid                stockroom.stockroom_id%type;
  gv_stockroomlocationid        stockroomlocation.stockroomlocation_id%type;
  gv_ragreasonid                ragreason.ragreason_id%type;
  gv_reasoncodeid               reasoncode.reasoncode_id%type;
  gv_transactiontypeid          transactiontype.transactiontype_id%type;
  gv_stockreservationpergradeid stockreservationpergrade.stockreservationpergrade_id%type;
  gv_productid                  product.product_id%type;

  --internal procedures
  procedure write_log(lfp_message  in abslog.message%type,
                      lfp_priority in abslog.priority%type default 1) is
  begin
    /*
    Write message in ABSLOG with these priorities
    1 = Message
    2 = Warning
    3 = Error
    4 = Stack trace
    5 = Debug info
    */
    dbms_output.put_line(lfp_message);
    abslogwrite.abslog_write(5, 'rag_uniqueitems_on_stock', gv_plantid, lfp_priority, lfp_message,
                             fp_systemuserid);
  end write_log;

  procedure initialize is
    lv_locationtypeid      locationtype.locationtype_id%type;
    lv_locationtypeblockid locationtype.locationtype_id%type;
    lv_tom                 product.typeofmerchandise%type;
  begin
    --initialize
    --get location type block
    select min(lct.locationtype_id)
    into   lv_locationtypeblockid
    from   locationtype lct
    where  lct.code = 'BLOCK';
    if lv_locationtypeblockid is null then
      begin
        gv_message := 'location type ''BLOCK'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_stockroomcode parameter
    if fp_stockroomcode is null then
      begin
        gv_message := 'parameter fp_stockroomcode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_stockroomcode ''' || nvl(fp_stockroomcode, 'NULL') || '''';
        select st.stockroom_id, st.managedbybu_id, bu.plant_id
        into   gv_stockroomid, gv_businessunitid, gv_plantid
        from   stockroom st
        join   businessunit bu
        on     bu.businessunit_id = st.managedbybu_id
        where  st.code = fp_stockroomcode;
      end;
    end if;
    --check fp_locationcode
    begin
      if fp_locationcode is null then
        begin
          gv_message := 'parameter fp_locationcode cannot be left blank';
          raise gv_user_exception;
        end;
      else
        begin
          if fp_rowcode is null then
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode left blank';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode is null
              and    srl.locationcode = fp_locationcode;
            end;
          else
            begin
              --key STOCKROOM_ID, ROWCODE, LOCATIONCODE, AREACODE
              gv_message := 'stockroomlocation, for fp_stockroomcode ''' ||
                            nvl(fp_stockroomcode, 'NULL') || ''' fp_locationcode ''' ||
                            fp_locationcode || ''' and fp_rowcode ''' || fp_rowcode || '''';
              select srl.stockroomlocation_id, srl.locationtype_id
              into   gv_stockroomlocationid, lv_locationtypeid
              from   stockroomlocation srl
              where  srl.stockroom_id = gv_stockroomid
              and    srl.rowcode = fp_rowcode
              and    srl.locationcode = fp_locationcode;
            end;
          end if;
        end;
      end if;
    exception
      when too_many_rows then
        begin
          gv_message := 'There is more then 1 stockroomlocation because of different areacodes for the stockroomcode ''' ||
                        fp_stockroomcode || ''' location code ''' || fp_locationcode ||
                        ''' row code ''' || nvl(fp_rowcode, 'NULL') || '''';
          raise gv_user_exception;
        end;
    end;
    --check is location type is BLOCK
    if lv_locationtypeid <> lv_locationtypeblockid then
      begin
        gv_message := 'The stockroomlocation for the stockroomcode ''' || fp_stockroomcode ||
                      ''' location code ''' || fp_locationcode || ''' row code ''' ||
                      nvl(fp_rowcode, 'NULL') || ''' does NOT have the location type ''BLOCK'' !?';
        raise gv_user_exception;
      end;
    end if;
    --check fp_before_lastonstockdate parameter
    if fp_before_lastonstockdate is null then
      begin
        gv_message := 'parameter fp_before_lastonstockdate cannot be left empty';
        raise gv_user_exception;
      end;
    else
      begin
        if fp_before_lastonstockdate > (trunc(sysdate) - 32) then
          begin
            gv_message := 'parameter fp_before_lastonstockdate should be <= ' ||
                          to_date(trunc(sysdate) - 32, 'DD-MM-YYYY');
            raise gv_user_exception;
          end;
        end if;
      end;
    end if;
    --check fp_ragreasoncode
    if fp_ragreasoncode is null then
      begin
        gv_message := 'parameter fp_ragreasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_ragreasoncode ' || nvl(fp_ragreasoncode, 'NULL');
        select rg.ragreason_id
        into   gv_ragreasonid
        from   ragreason rg
        where  rg.code = fp_ragreasoncode;
      end;
    end if;
    --check fp_reasoncode
    if fp_reasoncode is null then
      begin
        gv_message := 'parameter fp_reasoncode cannot be left blank';
        raise gv_user_exception;
      end;
    else
      begin
        gv_message := 'parameter fp_reasoncode ' || nvl(fp_reasoncode, 'NULL');
        select rs.reasoncode_id
        into   gv_reasoncodeid
        from   reasoncode rs
        where  rs.code = fp_reasoncode;
      end;
    end if;
    --get transaction type
    select min(td.transactiontype_id)
    into   gv_transactiontypeid
    from   transactiontype_desc td
    where  td.description = 'Ragged from Stock';
    if gv_transactiontypeid is null then
      begin
        gv_message := 'transaction type ''Ragged from Stock'' does not exist!?';
        raise gv_user_exception;
      end;
    end if;
    --get gv_systemuserid
    if fp_systemuserid is null then
      begin
        select st.systemuser_id
        into   gv_systemuserid
        from   systemuser st
        where  st.username = 'SYSDAM';
      exception
        when no_data_found then
          begin
            select nvl(min(st.systemuser_id), 0) into gv_systemuserid from systemuser st;
          end;
      end;
    else
      begin
        gv_systemuserid := fp_systemuserid;
      end;
    end if;
    --get product id
    if fp_productcode is null then
      gv_productid := null;
    else
      begin
        --get the product id of the uniqueitem
        gv_message := 'Product code ' || fp_productcode;
        select p.product_id, p.typeofmerchandise
        into   gv_productid, lv_tom
        from   product p
        where  p.code = fp_productcode;
        if lv_tom <> 2 then
          begin
            gv_productid := null;
            gv_message   := 'Product ' || fp_productcode || ' is not an TOM=2 (uniqueitem)';
            raise gv_user_exception;
          end;
        end if;
      end;
    end if;
  end initialize;

  procedure raguniqueitemstock is
    --begin internal procedures for raguniqueitemstock
    procedure delete_uniqueitem(fp_primaryid in varchar2, fp_uniqueitemid in number) is
    begin
      --delete_uniqueitem
      gv_message := 'delete from uniqueitem/update uniqueitem_link for fp_stockroomcode ' ||
                    fp_stockroomcode || ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                    fp_primaryid;
      update uniqueitem_link l set l.uniqueitem_id = null where l.uniqueitem_id = fp_uniqueitemid;
      delete from uniqueitem u where u.uniqueitem_id = fp_uniqueitemid;
    end delete_uniqueitem;
  
    procedure get_stockreservationpergrade(fp_primaryid         in varchar2,
                                           fp_productid         in number,
                                           fp_sizeid            in number,
                                           fp_relatedcustomerid in number,
                                           fp_customerowned     in varchar2,
                                           fp_qualitygradeid    in number) is
      lv_stockdefinitionperitemid stockdefinitionperitem.stockdefinitionperitem_id%type;
    begin
      ---get stock definition per item STOCKROOM_ID, PRODUCT_ID, SIZEDEFINITION_ID, CUSTOMER_ID, CUSTOMEROWNED
      gv_message := 'get stockdefinitionperitem for fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                    fp_primaryid;
      select stdp.stockdefinitionperitem_id
      into   lv_stockdefinitionperitemid
      from   stockdefinitionperitem stdp, stockroomlocation stl
      where  stl.stockroom_id = stdp.stockroom_id
      and    stl.stockroomlocation_id = gv_stockroomlocationid
      and    stdp.product_id = fp_productid
      and    stdp.sizedefinition_id = fp_sizeid
      and    (stdp.customer_id = fp_relatedcustomerid or
            stdp.customer_id is null and fp_relatedcustomerid is null)
      and    stdp.customerowned = fp_customerowned;
      --get stock reservation per grade STOCKDEFINITIONPERITEM_ID, QUALITYGRADE_ID
      gv_message := 'get stockreservationpergrade for fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                    fp_primaryid;
      select stg.stockreservationpergrade_id
      into   gv_stockreservationpergradeid
      from   stockreservationpergrade stg
      where  stg.stockdefinitionperitem_id = lv_stockdefinitionperitemid
      and    stg.qualitygrade_id = fp_qualitygradeid;
    end get_stockreservationpergrade;
  
    procedure update_stockquantity(fp_primaryid in varchar2, fp_uniqueitemmod_yn in varchar2) is
    begin
      --update_stockquantity
      gv_message := 'update stockquantity for fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                    fp_primaryid;
      if fp_uniqueitemmod_yn = 'Y' then
        begin
          update stockquantity q
          set    q.qtyuniquewithmodifications = q.qtyuniquewithmodifications - 1,
                 q.systemuser_id = gv_systemuserid, q.timestamp = sysdate
          where  q.stockreservationpergrade_id = gv_stockreservationpergradeid
          and    q.stockroomlocation_id = gv_stockroomlocationid;
        end;
      else
        begin
          update stockquantity q
          set    q.qtyunique = q.qtyunique - 1, q.systemuser_id = gv_systemuserid,
                 q.timestamp = sysdate
          where  q.stockreservationpergrade_id = gv_stockreservationpergradeid
          and    q.stockroomlocation_id = gv_stockroomlocationid;
        end;
      end if;
    end update_stockquantity;
  
    procedure create_stocktransaction(fp_primaryid in varchar2) is
    begin
      --create_stocktransaction
      --key STOCKRESERVATIONPERGRADE_ID, TRANSACTIONDATE, REASONCODE_ID, TRANSACTIONTYPE_ID, UNIQUESTOCK
      gv_message := 'create stocktransaction fp_stockroomcode ' || fp_stockroomcode ||
                    ' fp_before_lastonstockdate ' ||
                    to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                    fp_primaryid;
      begin
        insert into stocktransaction
          (stocktransaction_id, stockreservationpergrade_id, transactiondate, reasoncode_id,
           transactiontype_id, uniquestock, quantity, systemuser_id, timestamp, exported, delayed,
           transactiontimestamp, fromstockroomlocation_id)
        values
          (seq_stocktransaction.nextval, gv_stockreservationpergradeid, trunc(sysdate),
           gv_reasoncodeid, gv_transactiontypeid, 'Y', -1, gv_systemuserid, sysdate, 'N', 'N',
           sysdate, gv_stockroomlocationid);
      exception
        when dup_val_on_index then
          begin
            update stocktransaction st
            set    st.quantity = st.quantity - 1, st.systemuser_id = gv_systemuserid,
                   st.timestamp = sysdate
            where  st.stockreservationpergrade_id = gv_stockreservationpergradeid
            and    st.transactiondate = trunc(sysdate)
            and    st.reasoncode_id = gv_reasoncodeid
            and    st.transactiontype_id = gv_transactiontypeid
            and    st.uniquestock = 'Y';
          end;
      end;
    end create_stocktransaction;
    --end internal procedures for raguniqueitemstock
  begin
    --raguniqueitemstock
    gv_message := 'raguniqueitemstock';
    for x in (select u.uniqueitem_id, u.primaryid, u.product_id, u.sizedefinition_id, u.poolitem,
                     u.distributionpoint_id, u.businessunit_id, un.weareremployment_id,
                     u.lastdistributionpoint_link_id, u.repairstotal, u.rewashtotal,
                     uf.daysincircprevissue, uf.daysinstockprevious, uf.supplier_id, uf.purchaseprice,
                     uf.purchasedate, u.customerowned, u.relatedcustomer_id, uf.firstissuedate,
                     uf.lastonstockdate, nvl(un.garmentsequencenumber, 0) garmentsequencenumber,
                     u.lastweareremployment_link_id, u.washestotal, uf.qualitygrade_id,
                     u.residualvalue, uf.enddatefullrent, uf.numberofissues, uf.lastissuedate,
                     (select su.secondaryid
                       from   secondaryuniqueitem su
                       where  su.uniqueitem_id = u.uniqueitem_id) secondaryid, u.status_id, u.stay_id,
                     u.prevstay_id,
                     case
                       when (select count(1)
                             from   uniqueitemmodification um
                             where  um.uniqueitem_id = u.uniqueitem_id) > 0 then
                        'Y'
                       else
                        'N'
                     end uniqueitemmod_yn
              from   uniqueitem u
              join   uniqueitemfixedinfo uf
              on     uf.uniqueitem_id = u.uniqueitem_id
              left   outer join uniqueitemnonpool un
              on     un.uniqueitem_id = u.uniqueitem_id
              where  uf.stockroomlocation_id = gv_stockroomlocationid
              and    (u.product_id = gv_productid or gv_productid is null)
              and    uf.lastonstockdate <= fp_before_lastonstockdate
              and    u.poolitem = 0
              and    u.status_id = (select st.status_id
                                    from   status st
                                    where  st.code = '10'
                                    and    st.statustype = 'UI')) loop
      begin
        --insert into raggeditem
        gv_message := 'insert into raggeditem for fp_stockroomcode ' || fp_stockroomcode ||
                      ' fp_before_lastonstockdate ' ||
                      to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                      x.primaryid;
        insert into raggeditem
          (raggeditem_id, primaryid, secondaryid, ragtimestamp, ragreason_id, garmsequencenumber,
           prevstatus_id, prevstay_id, product_link_id, sizedefinition_link_id, purchasedate,
           lastonstockdate, firstissuedate, lastissuedate, numberofissues, enddatefullrent,
           qualitygrade_id, washestotal, repairstotal, rewashtotal, daysincirculation, daysinstock,
           supplier_id, purchaseprice, customerowned, relatedcustomerlink_id,
           lastweareremployment_link_id, reasoncode_id, residualvalue, lastdistributionpoint_link_id,
           systemuser_id, businessunit_id, timestamp, weareremployment_link_id,
           distributionpoint_link_id, poolitem, losschargeinvoiceline_id, wearerinventorycredit_id)
        values
          (x.uniqueitem_id, x.primaryid, x.secondaryid, sysdate /*ragtimestamp*/, gv_ragreasonid,
           x.garmentsequencenumber, x.status_id, x.stay_id, x.product_id, x.sizedefinition_id,
           x.purchasedate, x.lastonstockdate, x.firstissuedate, x.lastissuedate, x.numberofissues,
           x.enddatefullrent, x.qualitygrade_id, x.washestotal, x.repairstotal, x.rewashtotal,
           x.daysincircprevissue, x.daysinstockprevious, x.supplier_id, x.purchaseprice,
           x.customerowned, x.relatedcustomer_id, x.lastweareremployment_link_id, gv_reasoncodeid,
           x.residualvalue, x.lastdistributionpoint_link_id, gv_systemuserid, x.businessunit_id,
           sysdate /*timestamp*/, x.weareremployment_id, x.distributionpoint_id, x.poolitem, 0
           /*losschargeinvoiceline_id*/, 0 /*wearerinventorycredit_id*/);
        -- delete_uniqueitem
        delete_uniqueitem(x.primaryid, x.uniqueitem_id);
        --create_scanrecord, register ragged scan
        gv_message := 'insert into scan for fp_stockroomcode ' || fp_stockroomcode ||
                      ' fp_before_lastonstockdate ' ||
                      to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                      x.primaryid;
        insert into scan
          (scan_id, businessunit_id, scantimestamp, primaryid, customer_link_id,
           weareremployment_link_id, distributionpoint_link_id, product_link_id,
           sizedefinition_link_id, stay_id, status_id, scanstation, issuedate, route_id,
           reasoncode_id, customerowned, year, week, dayno, qualitygrade_id, systemuser_id,
           timestamp, prevstay_id, transactiontype_id, dayslate, uniqueitem_link_id, secondaryid,
           batchnumber, scandateoffset, qualitytesttype_id)
        values
          (seq_scan.nextval, x.businessunit_id, sysdate, x.primaryid, x.relatedcustomer_id
           /*customer_link_id*/, x.weareremployment_id, x.distributionpoint_id, x.product_id,
           x.sizedefinition_id, x.stay_id, x.status_id, null /*scanstation*/, null /*issuedate*/,
           null /*route_id*/, gv_reasoncodeid, x.customerowned, getyearofweek(sysdate) /*year*/,
           getisoweek(sysdate) /*week*/, getabsdaynumber(sysdate) /*dayno*/, x.qualitygrade_id,
           gv_systemuserid, sysdate /*timestamp*/, x.prevstay_id, gv_transactiontypeid, 0
           /*dayslate*/, x.uniqueitem_id, x.secondaryid, null /*batchnumber*/, 0 /*scandateoffset*/,
           null /*qualitytesttype_id*/);
        --get_stockreservationpergrade
        get_stockreservationpergrade(x.primaryid, x.product_id, x.sizedefinition_id,
                                     x.relatedcustomer_id, x.customerowned, x.qualitygrade_id);
        --update_stockquantity
        update_stockquantity(x.primaryid, x.uniqueitemmod_yn);
        --create stocktransaction 
        create_stocktransaction(x.primaryid);
        --create_outofstockhistory
        gv_message := 'create_outofstockhistory for fp_stockroomcode ' || fp_stockroomcode ||
                      ' fp_before_lastonstockdate ' ||
                      to_char(fp_before_lastonstockdate, 'DD-MM-YYYY') || ' primary id ' ||
                      x.primaryid;
        insert into outofstockhistory
          (outofstockhistory_id, processbusinessunit_id, stockroom_id, uniqueitem_link_id,
           outofstockdate, reasoncode_id, quantity, product_link_id, sizedefinition_link_id,
           qualitygrade_id, customerowned, relatedcustomer_link_id, outofstockyear, outofstockweek,
           outofstockday, ragreason_id, supplier_id, primaryid, systemuser_id, timestamp)
        values
          (seq_outofstockhistory.nextval, x.businessunit_id, gv_stockroomid, x.uniqueitem_id,
           trunc(sysdate), gv_reasoncodeid, 1, x.product_id, x.sizedefinition_id, x.qualitygrade_id,
           x.customerowned, x.relatedcustomer_id, to_char(sysdate, 'IYYY'), to_char(sysdate, 'IW'),
           getabsdaynumber(sysdate), gv_ragreasonid, x.supplier_id, x.primaryid, gv_systemuserid,
           sysdate);
        --remark create_residualvaluehistory, not yet for this version 8.03.11!!
        --counter
        gv_counter := gv_counter + 1;
      end;
    end loop; --x uniqueitem rag loop
  end raguniqueitemstock;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    commit;
    if gv_counter > 0 then
      begin
        write_log(to_char(gv_counter) || ' uniqueitems ragged from stock');
      end;
    else
      begin
        write_log('No uniqueitems were ragged!');
      end;
    end if;
  end finalize;

  --Main program block
begin
  --initialize
  initialize;
  --raguniqueitemstock
  raguniqueitemstock;
  --finalize
  finalize;
exception
  when gv_user_exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('No data found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(gv_message, 3);
      write_log(sqlerrm, 5);
    end;
end rag_uniqueitems_on_stock;
/

create or replace procedure remove_supplierproduct(fp_suppliernumber in number,
                                                   fp_productcode    in varchar2 default null) is
  --remove_supplierproduct version 0.2 
  --global variables
  gv_user__exception exception;
  gv_defaultuserid systemuser.systemuser_id%type := 0;
  gv_message       abslog.message%type;
  gv_plantid       plant.plant_id%type := null;
  gv_supplierid    supplier.supplier_id%type;
  gv_productid     product.product_id%type;
  gv_counter       number;

  ---internal procedure(s)
  procedure write_log(fp_message in varchar2 default null, fp_priority in number default 1) is
  begin
    /* Logging: write message in ABSLOG with these priorities:
    1 = Message
    2 = Warning
    3 = Error */
    abslogwrite.abslog_write(5, 'import_packingnote', gv_plantid, nvl(fp_priority, 1), fp_message,
                             gv_defaultuserid);
    begin
      dbms_output.put_line(fp_message);
    exception
      when others then
        null; --no problem if we could not show log in output
    end;
  end write_log;

  procedure initialize is
  begin
    --initialize
    gv_message := 'initialize';
    gv_counter := 0;
    --check supplier parameter
    if fp_suppliernumber is null then
      begin
        gv_message := 'parameter fp_suppliernumber cannot be left blank!';
        raise gv_user__exception;
      end;
    else
      begin
        --get supplier
        gv_message := 'parameter fp_suppliernumber ' || to_char(fp_suppliernumber);
        select s.supplier_id
        into   gv_supplierid
        from   supplier s
        where  s.suppliernumber = fp_suppliernumber;
      end;
    end if;
    --check product parameter
    if fp_productcode is null then
      begin
        gv_productid := null;
      end;
    else
      begin
        --get product
        gv_message := 'parameter fp_productcode ' || fp_productcode;
        select p.product_id into gv_productid from product p where p.code = fp_productcode;
      end;
    end if;
  end initialize;

  procedure del_supplierproduct is
  begin
    --del_supplierproduct
    gv_message := 'del_supplierproduct product ' || fp_productcode || ' from supplier number ' ||
                  to_char(fp_suppliernumber);
    delete from productsizepersupproduct pspp
    where  (pspp.product_id = gv_productid or gv_productid is null)
    and    exists (select 1
            from   supplierproduct sp
            where  sp.supplier_id = gv_supplierid
            and    sp.supplierproduct_id = pspp.supplierproduct_id)
    returning count(1) into gv_counter;
  end del_supplierproduct;

  procedure finalize is
  begin
    --finalize
    gv_message := 'finalize';
    --commit
    commit;
    --write log
    write_log('Successfully removed ' || to_char(gv_counter) ||
              ' product supplier size records for product ' || fp_productcode ||
              ' from supplier number ' || to_char(fp_suppliernumber));
  
  end finalize;
  --start main procedure
begin
  --initialize
  initialize;
  --del_supplierproduct
  del_supplierproduct;
  --finalize
  finalize;
exception
  --exception handling global
  when gv_user__exception then
    begin
      rollback;
      write_log(gv_message, 3);
    end;
  when no_data_found then
    begin
      rollback;
      write_log('Error No Data Found ' || gv_message, 3);
    end;
  when others then
    begin
      rollback;
      write_log(sqlerrm || ' product ' || fp_productcode || ' from supplier number ' ||
                to_char(fp_suppliernumber), 5);
      write_log('Error Others ' || gv_message, 3);
    end;
end remove_supplierproduct;
/

--Workaround for ABS-41554 Settlement status could not be updated to Completed, scheduled script (AUJ)
insert into abslog
  (abslog_id, logtype, logsource, plant_id, priority, timestamp, systemuser_id, message)
  select seq_abslog.nextval, 8, 'Check routecontrol', null, 3, sysdate, rc.systemuser_id,
         'routecontrol_id ' || to_char(rc.routecontrol_id) || ' driving date ' ||
          to_char(originaldrivingdate, 'dd-mon-yyyy') || ' routenumber ' ||
          (select to_char(r.routenumber) from route r where r.route_id = rc.route_id)
  from   routecontrol rc
  where  rc.settlementstatus = 2
  and    rc.originaldrivingdate between trunc(sysdate) - 3 and trunc(sysdate)
  and    not exists (select ih.invoiceheader_id
          from   invoiceheader ih
          where  ih.routecontrol_id = rc.routecontrol_id
          and    ih.status_id in (select st.status_id
                                  from   status st
                                  where  st.statustype = 'IN'
                                  and    st.code = '1'))
  and    exists (select ih.invoiceheader_id
          from   invoiceheader ih
          where  ih.routecontrol_id = rc.routecontrol_id
          and    ih.status_id in (select st.status_id
                                  from   status st
                                  where  st.statustype = 'IN'
                                  and    st.code in ('2', '3')));
commit;


update routecontrol rc
set    rc.settlementstatus = 3, rc.timestamp = sysdate, rc.systemuser_id = 1
where  rc.settlementstatus = 2
and    rc.originaldrivingdate between trunc(sysdate) - 3 and trunc(sysdate)
and    not exists (select ih.invoiceheader_id
        from   invoiceheader ih
        where  ih.routecontrol_id = rc.routecontrol_id
        and    ih.status_id in (select st.status_id
                                from   status st
                                where  st.statustype = 'IN'
                                and    st.code = '1'))
and    exists (select ih.invoiceheader_id
        from   invoiceheader ih
        where  ih.routecontrol_id = rc.routecontrol_id
        and    ih.status_id in (select st.status_id
                                from   status st
                                where  st.statustype = 'IN'
                                and    st.code in ('2', '3')));
commit;
/

CREATE OR REPLACE TRIGGER trg_change_customer_addr
  before INSERT OR UPDATE on address
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  lv_customerid           customer.customer_id%type;
  lv_addresstype          number;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    ---ADDRESS_TYPE   1=mail, 2=visit and 3=invoice!
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'ADDRESS', fp_fieldname, lv_insert_update_delete, 'ADDRESS_ID',
           :new.address_id, 'ADDRESS_TYPE', lv_addresstype, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'ADDRESS', fp_fieldname, lv_insert_update_delete, 'ADDRESS_ID',
           :old.address_id, 'ADDRESS_TYPE', lv_addresstype, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  begin
    --get customer id
    select max(c.customer_id),
           case
             when max(c.mailaddress_id) = :new.address_id then
              1
             when max(c.visitaddress_id) = :new.address_id then
              2
             when max(c.invoiceaddress_id) = :new.address_id then
              3
             else
              null
           end
    into   lv_customerid, lv_addresstype
    from   customer c
    where  c.mailaddress_id = :new.address_id
    or     c.visitaddress_id = :new.address_id
    or     c.invoiceaddress_id = :new.address_id;
  exception
    when no_data_found then
      begin
        lv_customerid  := null;
        lv_addresstype := null;
      end;
  end;
  --determine lv_insert_update_delete value
  if (updating or inserting) and lv_customerid is not null then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.address_id), 'NULL') <> nvl(to_char(:old.address_id), 'NULL') then
        begin
          insert_changes('ADDRESS_ID', :old.address_id, :new.address_id);
        end;
      end if;
      if nvl(to_char(:new.street), 'NULL') <> nvl(to_char(:old.street), 'NULL') then
        begin
          insert_changes('STREET', :old.street, :new.street);
        end;
      end if;
      if nvl(to_char(:new.zipcode), 'NULL') <> nvl(to_char(:old.zipcode), 'NULL') then
        begin
          insert_changes('ZIPCODE', :old.zipcode, :new.zipcode);
        end;
      end if;
      if nvl(to_char(:new.city), 'NULL') <> nvl(to_char(:old.city), 'NULL') then
        begin
          insert_changes('CITY', :old.city, :new.city);
        end;
      end if;
      if nvl(to_char(:new.state), 'NULL') <> nvl(to_char(:old.state), 'NULL') then
        begin
          insert_changes('STATE', :old.state, :new.state);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.county), 'NULL') <> nvl(to_char(:old.county), 'NULL') then
        begin
          insert_changes('COUNTY', :old.county, :new.county);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', to_char(:old.timestamp,'DD-MON-YYYY HH24:MI:SS'), to_char(:new.timestamp,'DD-MON-YYYY HH24:MI:SS'));
        end;
      end if;
      if nvl(to_char(:new.street2), 'NULL') <> nvl(to_char(:old.street2), 'NULL') then
        begin
          insert_changes('STREET2', :old.street2, :new.street2);
        end;
      end if;
      if nvl(to_char(:new.housenumber), 'NULL') <> nvl(to_char(:old.housenumber), 'NULL') then
        begin
          insert_changes('HOUSENUMBER', :old.housenumber, :new.housenumber);
        end;
      end if;
      if nvl(to_char(:new.housenumberext), 'NULL') <> nvl(to_char(:old.housenumberext), 'NULL') then
        begin
          insert_changes('HOUSENUMBEREXT', :old.housenumberext, :new.housenumberext);
        end;
      end if;
    end;
  elsif deleting and lv_customerid is not null then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('ADDRESS_ID', :old.address_id, :new.address_id);
    end;
  end if;
end trg_change_customer_addr;
/

CREATE OR REPLACE TRIGGER trg_change_customer_billto
  before INSERT OR UPDATE OR DELETE on customerbillinginfo
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('U', 'I') then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, old_value, new_value)
        values
          (:new.customer_id, :new.systemuser_id, sysdate, 'CUSTOMERBILLINGINFO', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :new.customer_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'));
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, old_value, new_value)
        values
          (:old.customer_id, :old.systemuser_id, sysdate, 'CUSTOMERBILLINGINFO', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :old.customer_id, nvl(fp_old_value, 'NULL'),
           'NULL');
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if; --check for changes
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.delinquentmarkafter), 'NULL') <>
         nvl(to_char(:old.delinquentmarkafter), 'NULL') then
        begin
          insert_changes('DELINQUENTMARKAFTER', :old.delinquentmarkafter, :new.delinquentmarkafter);
        end;
      end if;
      if nvl(to_char(:new.creditlimit), 'NULL') <> nvl(to_char(:old.creditlimit), 'NULL') then
        begin
          insert_changes('CREDITLIMIT', :old.creditlimit, :new.creditlimit);
        end;
      end if;
      if nvl(to_char(:new.financechargeputon), 'NULL') <>
         nvl(to_char(:old.financechargeputon), 'NULL') then
        begin
          insert_changes('FINANCECHARGEPUTON', :old.financechargeputon, :new.financechargeputon);
        end;
      end if;
      if nvl(to_char(:new.financechargedays), 'NULL') <>
         nvl(to_char(:old.financechargedays), 'NULL') then
        begin
          insert_changes('FINANCECHARGEDAYS', :old.financechargedays, :new.financechargedays);
        end;
      end if;
      if nvl(to_char(:new.statementcopies), 'NULL') <> nvl(to_char(:old.statementcopies), 'NULL') then
        begin
          insert_changes('STATEMENTCOPIES', :old.statementcopies, :new.statementcopies);
        end;
      end if;
      if nvl(to_char(:new.statementpercustomer), 'NULL') <>
         nvl(to_char(:old.statementpercustomer), 'NULL') then
        begin
          insert_changes('STATEMENTPERCUSTOMER', :old.statementpercustomer,
                         :new.statementpercustomer);
        end;
      end if;
      if nvl(to_char(:new.attachinvoicecopies), 'NULL') <>
         nvl(to_char(:old.attachinvoicecopies), 'NULL') then
        begin
          insert_changes('ATTACHINVOICECOPIES', :old.attachinvoicecopies, :new.attachinvoicecopies);
        end;
      end if;
      if nvl(to_char(:new.sendstatement), 'NULL') <> nvl(to_char(:old.sendstatement), 'NULL') then
        begin
          insert_changes('SENDSTATEMENT', :old.sendstatement, :new.sendstatement);
        end;
      end if;
      if nvl(to_char(:new.sendstatementbyemail), 'NULL') <>
         nvl(to_char(:old.sendstatementbyemail), 'NULL') then
        begin
          insert_changes('SENDSTATEMENTBYEMAIL', :old.sendstatementbyemail,
                         :new.sendstatementbyemail);
        end;
      end if;
      if nvl(to_char(:new.collectionresponsible_id), 'NULL') <>
         nvl(to_char(:old.collectionresponsible_id), 'NULL') then
        begin
          insert_changes('COLLECTIONRESPONSIBLE_ID', :old.collectionresponsible_id,
                         :new.collectionresponsible_id);
        end;
      end if;
      if nvl(to_char(:new.paymentterms_id), 'NULL') <> nvl(to_char(:old.paymentterms_id), 'NULL') then
        begin
          insert_changes('PAYMENTTERMS_ID', :old.paymentterms_id, :new.paymentterms_id);
        end;
      end if;
      if nvl(to_char(:new.statementlayout_id), 'NULL') <>
         nvl(to_char(:old.statementlayout_id), 'NULL') then
        begin
          insert_changes('STATEMENTLAYOUT_ID', :old.statementlayout_id, :new.statementlayout_id);
        end;
      end if;
      if nvl(to_char(:new.statementfrequency_id), 'NULL') <>
         nvl(to_char(:old.statementfrequency_id), 'NULL') then
        begin
          insert_changes('STATEMENTFREQUENCY_ID', :old.statementfrequency_id,
                         :new.statementfrequency_id);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', to_char(:old.timestamp,'dd-MON-YY HH24:MI:SS'), to_char(:new.timestamp,'dd-MON-YY HH24:MI:SS'));
        end;
      end if;
      if nvl(to_char(:new.highestbalance), 'NULL') <> nvl(to_char(:old.highestbalance), 'NULL') then
        begin
          insert_changes('HIGHESTBALANCE', :old.highestbalance, :new.highestbalance);
        end;
      end if;
      if nvl(to_char(:new.highestbalancedate), 'NULL') <>
         nvl(to_char(:old.highestbalancedate), 'NULL') then
        begin
          insert_changes('HIGHESTBALANCEDATE', :old.highestbalancedate, :new.highestbalancedate);
        end;
      end if;
      if nvl(to_char(:new.consolidatedinvoice), 'NULL') <>
         nvl(to_char(:old.consolidatedinvoice), 'NULL') then
        begin
          insert_changes('CONSOLIDATEDINVOICE', :old.consolidatedinvoice, :new.consolidatedinvoice);
        end;
      end if;
      if nvl(to_char(:new.bankaccount), 'NULL') <> nvl(to_char(:old.bankaccount), 'NULL') then
        begin
          insert_changes('BANKACCOUNT', :old.bankaccount, :new.bankaccount);
        end;
      end if;
      if nvl(to_char(:new.creditsqueezeperc), 'NULL') <>
         nvl(to_char(:old.creditsqueezeperc), 'NULL') then
        begin
          insert_changes('CREDITSQUEEZEPERC', :old.creditsqueezeperc, :new.creditsqueezeperc);
        end;
      end if;
      if nvl(to_char(:new.bankinstitution_id), 'NULL') <>
         nvl(to_char(:old.bankinstitution_id), 'NULL') then
        begin
          insert_changes('BANKINSTITUTION_ID', :old.bankinstitution_id, :new.bankinstitution_id);
        end;
      end if;
      if nvl(to_char(:new.consolidatedreportinv), 'NULL') <>
         nvl(to_char(:old.consolidatedreportinv), 'NULL') then
        begin
          insert_changes('CONSOLIDATEDREPORTINV', :old.consolidatedreportinv,
                         :new.consolidatedreportinv);
        end;
      end if;
      if nvl(to_char(:new.laundrybankinstitution_id), 'NULL') <>
         nvl(to_char(:old.laundrybankinstitution_id), 'NULL') then
        begin
          insert_changes('LAUNDRYBANKINSTITUTION_ID', :old.laundrybankinstitution_id,
                         :new.laundrybankinstitution_id);
        end;
      end if;
      if nvl(to_char(:new.ibanno), 'NULL') <> nvl(to_char(:old.ibanno), 'NULL') then
        begin
          insert_changes('IBANNO', :old.ibanno, :new.ibanno);
        end;
      end if;
      /***
      if nvl(to_char(:new.creditcardtype), 'NULL') <> nvl(to_char(:old.creditcardtype), 'NULL') then
        begin
          insert_changes('CREDITCARDTYPE', :old.creditcardtype, :new.creditcardtype);
        end;
      end if;
      if nvl(to_char(:new.creditcardnumber), 'NULL') <> nvl(to_char(:old.creditcardnumber), 'NULL') then
        begin
          insert_changes('CREDITCARDNUMBER', :old.creditcardnumber, :new.creditcardnumber);
        end;
      end if;
      if nvl(to_char(:new.expirationyear), 'NULL') <> nvl(to_char(:old.expirationyear), 'NULL') then
        begin
          insert_changes('EXPIRATIONYEAR', :old.expirationyear, :new.expirationyear);
        end;
      end if;
      if nvl(to_char(:new.expirationmonth), 'NULL') <> nvl(to_char(:old.expirationmonth), 'NULL') then
        begin
          insert_changes('EXPIRATIONMONTH', :old.expirationmonth, :new.expirationmonth);
        end;
      end if;
      if nvl(to_char(:new.verificationvalue), 'NULL') <>
         nvl(to_char(:old.verificationvalue), 'NULL') then
        begin
          insert_changes('VERIFICATIONVALUE', :old.verificationvalue, :new.verificationvalue);
        end;
      end if;
      if nvl(to_char(:new.creditcardname), 'NULL') <> nvl(to_char(:old.creditcardname), 'NULL') then
        begin
          insert_changes('CREDITCARDNAME', :old.creditcardname, :new.creditcardname);
        end;
      end if;
      if nvl(to_char(:new.createtransactionfromstatement), 'NULL') <>
         nvl(to_char(:old.createtransactionfromstatement), 'NULL') then
        begin
          insert_changes('CREATETRANSACTIONFROMSTATEMENT', :old.createtransactionfromstatement,
                         :new.createtransactionfromstatement);
        end;
      end if;
      ***/
      if nvl(to_char(:new.sendinvoicebyemail), 'NULL') <>
         nvl(to_char(:old.sendinvoicebyemail), 'NULL') then
        begin
          insert_changes('SENDINVOICEBYEMAIL', :old.sendinvoicebyemail, :new.sendinvoicebyemail);
        end;
      end if;
      if nvl(to_char(:new.senddirectinvoicebyemail), 'NULL') <>
         nvl(to_char(:old.senddirectinvoicebyemail), 'NULL') then
        begin
          insert_changes('SENDDIRECTINVOICEBYEMAIL', :old.senddirectinvoicebyemail,
                         :new.senddirectinvoicebyemail);
        end;
      end if;
      if nvl(to_char(:new.sendstatementbyfax), 'NULL') <>
         nvl(to_char(:old.sendstatementbyfax), 'NULL') then
        begin
          insert_changes('SENDSTATEMENTBYFAX', :old.sendstatementbyfax, :new.sendstatementbyfax);
        end;
      end if;
      if nvl(to_char(:new.sendinvoicebyfax), 'NULL') <> nvl(to_char(:old.sendinvoicebyfax), 'NULL') then
        begin
          insert_changes('SENDINVOICEBYFAX', :old.sendinvoicebyfax, :new.sendinvoicebyfax);
        end;
      end if;
      if nvl(to_char(:new.senddirectinvoicebyfax), 'NULL') <>
         nvl(to_char(:old.senddirectinvoicebyfax), 'NULL') then
        begin
          insert_changes('SENDDIRECTINVOICEBYFAX', :old.senddirectinvoicebyfax,
                         :new.senddirectinvoicebyfax);
        end;
      end if;
      if nvl(to_char(:new.consolidatedinvoicelayout_id), 'NULL') <>
         nvl(to_char(:old.consolidatedinvoicelayout_id), 'NULL') then
        begin
          insert_changes('CONSOLIDATEDINVOICELAYOUT_ID', :old.consolidatedinvoicelayout_id,
                         :new.consolidatedinvoicelayout_id);
        end;
      end if;
      if nvl(to_char(:new.paybycustomer), 'NULL') <> nvl(to_char(:old.paybycustomer), 'NULL') then
        begin
          insert_changes('PAYBYCUSTOMER', :old.paybycustomer, :new.paybycustomer);
        end;
      end if;
      if nvl(to_char(:new.printinvoice), 'NULL') <> nvl(to_char(:old.printinvoice), 'NULL') then
        begin
          insert_changes('PRINTINVOICE', :old.printinvoice, :new.printinvoice);
        end;
      end if;
      if nvl(to_char(:new.paybycustomer_link_id), 'NULL') <>
         nvl(to_char(:old.paybycustomer_link_id), 'NULL') then
        begin
          insert_changes('PAYBYCUSTOMER_LINK_ID', :old.paybycustomer_link_id,
                         :new.paybycustomer_link_id);
        end;
      end if;
      if nvl(to_char(:new.sendinvoiceby), 'NULL') <> nvl(to_char(:old.sendinvoiceby), 'NULL') then
        begin
          insert_changes('SENDINVOICEBY', :old.sendinvoiceby, :new.sendinvoiceby);
        end;
      end if;
      if nvl(to_char(:new.district), 'NULL') <> nvl(to_char(:old.district), 'NULL') then
        begin
          insert_changes('DISTRICT', :old.district, :new.district);
        end;
      end if;
      if nvl(to_char(:new.statementflagcode), 'NULL') <>
         nvl(to_char(:old.statementflagcode), 'NULL') then
        begin
          insert_changes('STATEMENTFLAGCODE', :old.statementflagcode, :new.statementflagcode);
        end;
      end if;
      if nvl(to_char(:new.statementcutoffdate), 'NULL') <>
         nvl(to_char(:old.statementcutoffdate), 'NULL') then
        begin
          insert_changes('STATEMENTCUTOFFDATE', to_char(:old.statementcutoffdate,'dd-mm-yyyy'), to_char(:new.statementcutoffdate,'dd-mm-yyyy'));
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_billto;
/

CREATE OR REPLACE TRIGGER trg_change_customer_contract
  before INSERT OR UPDATE OR DELETE on contract
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('U', 'I') then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, old_value, new_value)
        values
          (:new.customer_link_id, :new.systemuser_id, sysdate, 'CONTRACT', fp_fieldname,
           lv_insert_update_delete, 'CONTRACT_ID', :new.contract_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'));
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, old_value, new_value)
        values
          (:old.customer_link_id, :old.systemuser_id, sysdate, 'CONTRACT', fp_fieldname,
           lv_insert_update_delete, 'CONTRACT_ID', :old.contract_id, nvl(fp_old_value, 'NULL'),
           'NULL');
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if; --check for changes
      if nvl(to_char(:new.contract_id), 'NULL') <> nvl(to_char(:old.contract_id), 'NULL') then
        begin
          insert_changes('CONTRACT_ID', :old.contract_id, :new.contract_id);
        end;
      end if;
      if nvl(to_char(:new.code), 'NULL') <> nvl(to_char(:old.code), 'NULL') then
        begin
          insert_changes('CODE', :old.code, :new.code);
        end;
      end if;
      if nvl(to_char(:new.description), 'NULL') <> nvl(to_char(:old.description), 'NULL') then
        begin
          insert_changes('DESCRIPTION', :old.description, :new.description);
        end;
      end if;
      if nvl(to_char(:new.contracttype_id), 'NULL') <> nvl(to_char(:old.contracttype_id), 'NULL') then
        begin
          insert_changes('CONTRACTTYPE_ID', :old.contracttype_id, :new.contracttype_id);
        end;
      end if;
      /*
      if nvl(to_char(:new.usergroup_id), 'NULL') <> nvl(to_char(:old.usergroup_id), 'NULL') then
        begin
          insert_changes('USERGROUP_ID', :old.usergroup_id, :new.usergroup_id);
        end;
      end if;
      */
      if nvl(to_char(:new.contractdocument), 'NULL') <> nvl(to_char(:old.contractdocument), 'NULL') then
        begin
          insert_changes('CONTRACTDOCUMENT', :old.contractdocument, :new.contractdocument);
        end;
      end if;
      if nvl(to_char(:new.salesemployee_id), 'NULL') <> nvl(to_char(:old.salesemployee_id), 'NULL') then
        begin
          insert_changes('SALESEMPLOYEE_ID', :old.salesemployee_id, :new.salesemployee_id);
        end;
      end if;
      if nvl(to_char(:new.commisionpayablesales), 'NULL') <>
         nvl(to_char(:old.commisionpayablesales), 'NULL') then
        begin
          insert_changes('COMMISIONPAYABLESALES', :old.commisionpayablesales,
                         :new.commisionpayablesales);
        end;
      end if;
      if nvl(to_char(:new.accountmanager_id), 'NULL') <>
         nvl(to_char(:old.accountmanager_id), 'NULL') then
        begin
          insert_changes('ACCOUNTMANAGER_ID', :old.accountmanager_id, :new.accountmanager_id);
        end;
      end if;
      if nvl(to_char(:new.commisionpayableaccmgr), 'NULL') <>
         nvl(to_char(:old.commisionpayableaccmgr), 'NULL') then
        begin
          insert_changes('COMMISIONPAYABLEACCMGR', :old.commisionpayableaccmgr,
                         :new.commisionpayableaccmgr);
        end;
      end if;
      if nvl(to_char(:new.customer_link_id), 'NULL') <> nvl(to_char(:old.customer_link_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_LINK_ID', :old.customer_link_id, :new.customer_link_id);
        end;
      end if;
      if nvl(to_char(:new.owner), 'NULL') <> nvl(to_char(:old.owner), 'NULL') then
        begin
          insert_changes('OWNER', :old.owner, :new.owner);
        end;
      end if;
      if nvl(to_char(:new.address_id), 'NULL') <> nvl(to_char(:old.address_id), 'NULL') then
        begin
          insert_changes('ADDRESS_ID', :old.address_id, :new.address_id);
        end;
      end if;
      if nvl(to_char(:new.country_id), 'NULL') <> nvl(to_char(:old.country_id), 'NULL') then
        begin
          insert_changes('COUNTRY_ID', :old.country_id, :new.country_id);
        end;
      end if;
      if nvl(to_char(:new.cvrnumber), 'NULL') <> nvl(to_char(:old.cvrnumber), 'NULL') then
        begin
          insert_changes('CVRNUMBER', :old.cvrnumber, :new.cvrnumber);
        end;
      end if;
      if nvl(to_char(:new.phonenumber), 'NULL') <> nvl(to_char(:old.phonenumber), 'NULL') then
        begin
          insert_changes('PHONENUMBER', :old.phonenumber, :new.phonenumber);
        end;
      end if;
      if nvl(to_char(:new.signdate), 'NULL') <> nvl(to_char(:old.signdate), 'NULL') then
        begin
          insert_changes('SIGNDATE', to_char(:old.signdate,'dd-mm-yyyy'), to_char(:new.signdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.startdate), 'NULL') <> nvl(to_char(:old.startdate), 'NULL') then
        begin
          insert_changes('STARTDATE', to_char(:old.startdate,'dd-mm-yyyy'), to_char(:new.startdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.enddate), 'NULL') <> nvl(to_char(:old.enddate), 'NULL') then
        begin
          insert_changes('ENDDATE', to_char(:old.enddate,'dd-mm-yyyy'), to_char(:new.enddate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.duration), 'NULL') <> nvl(to_char(:old.duration), 'NULL') then
        begin
          insert_changes('DURATION', :old.duration, :new.duration);
        end;
      end if;
      if nvl(to_char(:new.termofnotice), 'NULL') <> nvl(to_char(:old.termofnotice), 'NULL') then
        begin
          insert_changes('TERMOFNOTICE', :old.termofnotice, :new.termofnotice);
        end;
      end if;
      if nvl(to_char(:new.terminationdate), 'NULL') <> nvl(to_char(:old.terminationdate), 'NULL') then
        begin
          insert_changes('TERMINATIONDATE', to_char(:old.terminationdate,'dd-mm-yyyy'), to_char(:new.terminationdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.autextensionperiod), 'NULL') <>
         nvl(to_char(:old.autextensionperiod), 'NULL') then
        begin
          insert_changes('AUTEXTENSIONPERIOD', :old.autextensionperiod, :new.autextensionperiod);
        end;
      end if;
      if nvl(to_char(:new.contactperson_id), 'NULL') <> nvl(to_char(:old.contactperson_id), 'NULL') then
        begin
          insert_changes('CONTACTPERSON_ID', :old.contactperson_id, :new.contactperson_id);
        end;
      end if;
      if nvl(to_char(:new.contactpersonname), 'NULL') <>
         nvl(to_char(:old.contactpersonname), 'NULL') then
        begin
          insert_changes('CONTACTPERSONNAME', :old.contactpersonname, :new.contactpersonname);
        end;
      end if;
      if nvl(to_char(:new.gainreason_id), 'NULL') <> nvl(to_char(:old.gainreason_id), 'NULL') then
        begin
          insert_changes('GAINREASON_ID', :old.gainreason_id, :new.gainreason_id);
        end;
      end if;
      if nvl(to_char(:new.gaincompetitor_id), 'NULL') <>
         nvl(to_char(:old.gaincompetitor_id), 'NULL') then
        begin
          insert_changes('GAINCOMPETITOR_ID', :old.gaincompetitor_id, :new.gaincompetitor_id);
        end;
      end if;
      if nvl(to_char(:new.lostreason_id), 'NULL') <> nvl(to_char(:old.lostreason_id), 'NULL') then
        begin
          insert_changes('LOSTREASON_ID', :old.lostreason_id, :new.lostreason_id);
        end;
      end if;
      if nvl(to_char(:new.lostcompetitor_id), 'NULL') <>
         nvl(to_char(:old.lostcompetitor_id), 'NULL') then
        begin
          insert_changes('LOSTCOMPETITOR_ID', :old.lostcompetitor_id, :new.lostcompetitor_id);
        end;
      end if;
      if nvl(to_char(:new.startdatepriceincrease), 'NULL') <>
         nvl(to_char(:old.startdatepriceincrease), 'NULL') then
        begin
          insert_changes('STARTDATEPRICEINCREASE', to_char(:old.startdatepriceincrease,'dd-mm-yyyy'),
                         to_char(:new.startdatepriceincrease,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.updateevery), 'NULL') <> nvl(to_char(:old.updateevery), 'NULL') then
        begin
          insert_changes('UPDATEEVERY', :old.updateevery, :new.updateevery);
        end;
      end if;
      if nvl(to_char(:new.previouspriceincrease), 'NULL') <>
         nvl(to_char(:old.previouspriceincrease), 'NULL') then
        begin
          insert_changes('PREVIOUSPRICEINCREASE', :old.previouspriceincrease,
                         :new.previouspriceincrease);
        end;
      end if;
      if nvl(to_char(:new.nextschedulepriceincrease), 'NULL') <>
         nvl(to_char(:old.nextschedulepriceincrease), 'NULL') then
        begin
          insert_changes('NEXTSCHEDULEPRICEINCREASE', :old.nextschedulepriceincrease,
                         :new.nextschedulepriceincrease);
        end;
      end if;
      if nvl(to_char(:new.agreedpriceindex_id), 'NULL') <>
         nvl(to_char(:old.agreedpriceindex_id), 'NULL') then
        begin
          insert_changes('AGREEDPRICEINDEX_ID', :old.agreedpriceindex_id, :new.agreedpriceindex_id);
        end;
      end if;
      if nvl(to_char(:new.notagreedpriceindex_id), 'NULL') <>
         nvl(to_char(:old.notagreedpriceindex_id), 'NULL') then
        begin
          insert_changes('NOTAGREEDPRICEINDEX_ID', :old.notagreedpriceindex_id,
                         :new.notagreedpriceindex_id);
        end;
      end if;
      if nvl(to_char(:new.allownotagreedpricelists), 'NULL') <>
         nvl(to_char(:old.allownotagreedpricelists), 'NULL') then
        begin
          insert_changes('ALLOWNOTAGREEDPRICELISTS', :old.allownotagreedpricelists,
                         :new.allownotagreedpricelists);
        end;
      end if;
      if nvl(to_char(:new.purchaseorder), 'NULL') <> nvl(to_char(:old.purchaseorder), 'NULL') then
        begin
          insert_changes('PURCHASEORDER', :old.purchaseorder, :new.purchaseorder);
        end;
      end if;
      if nvl(to_char(:new.purchaseordervalue), 'NULL') <>
         nvl(to_char(:old.purchaseordervalue), 'NULL') then
        begin
          insert_changes('PURCHASEORDERVALUE', :old.purchaseordervalue, :new.purchaseordervalue);
        end;
      end if;
      if nvl(to_char(:new.purchaseorderexpirationdate), 'NULL') <>
         nvl(to_char(:old.purchaseorderexpirationdate), 'NULL') then
        begin
          insert_changes('PURCHASEORDEREXPIRATIONDATE', to_char(:old.purchaseorderexpirationdate,'dd-mm-yyyy'),
                         to_char(:new.purchaseorderexpirationdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.estimatedweeklysales), 'NULL') <>
         nvl(to_char(:old.estimatedweeklysales), 'NULL') then
        begin
          insert_changes('ESTIMATEDWEEKLYSALES', :old.estimatedweeklysales,
                         :new.estimatedweeklysales);
        end;
      end if;
      if nvl(to_char(:new.remark), 'NULL') <> nvl(to_char(:old.remark), 'NULL') then
        begin
          insert_changes('REMARK', :old.remark, :new.remark);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', to_char(:old.timestamp,'dd-MON-YY HH24:MI:SS'), to_char(:new.timestamp,'dd-MON-YY HH24:MI:SS'));
        end;
      end if;
      if nvl(to_char(:new.renegotiationdate), 'NULL') <>
         nvl(to_char(:old.renegotiationdate), 'NULL') then
        begin
          insert_changes('RENEGOTIATIONDATE', to_char(:old.renegotiationdate,'dd-mm-yyyy'), to_char(:new.renegotiationdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.warnpriceincrease), 'NULL') <>
         nvl(to_char(:old.warnpriceincrease), 'NULL') then
        begin
          insert_changes('WARNPRICEINCREASE', :old.warnpriceincrease, :new.warnpriceincrease);
        end;
      end if;
      if nvl(to_char(:new.warndayspriceincrease), 'NULL') <>
         nvl(to_char(:old.warndayspriceincrease), 'NULL') then
        begin
          insert_changes('WARNDAYSPRICEINCREASE', :old.warndayspriceincrease,
                         :new.warndayspriceincrease);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_link_id, :new.customer_link_id);
    end;
  end if;
end trg_change_customer_contract;
/

CREATE OR REPLACE TRIGGER trg_change_customer_cust
  before INSERT OR UPDATE OR DELETE on customer
  for each row
declare
  --TRIGGER trg_change_customer_cust version 0.2
  --01-nov-2021 ABS-126876 Adjust trg_change_customer_cust not to save prep charges for AUJ
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'CUSTOMER', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :new.customer_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'CUSTOMER', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :old.customer_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      --check for changes
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.customernumber), 'NULL') <> nvl(to_char(:old.customernumber), 'NULL') then
        begin
          insert_changes('CUSTOMERNUMBER', :old.customernumber, :new.customernumber);
        end;
      end if;
      if nvl(to_char(:new.name), 'NULL') <> nvl(to_char(:old.name), 'NULL') then
        begin
          insert_changes('NAME', :old.name, :new.name);
        end;
      end if;
      if nvl(to_char(:new.phoneno), 'NULL') <> nvl(to_char(:old.phoneno), 'NULL') then
        begin
          insert_changes('PHONENO', :old.phoneno, :new.phoneno);
        end;
      end if;
      if nvl(to_char(:new.legalname), 'NULL') <> nvl(to_char(:old.legalname), 'NULL') then
        begin
          insert_changes('LEGALNAME', :old.legalname, :new.legalname);
        end;
      end if;
      if nvl(to_char(:new.faxno), 'NULL') <> nvl(to_char(:old.faxno), 'NULL') then
        begin
          insert_changes('FAXNO', :old.faxno, :new.faxno);
        end;
      end if;
      if nvl(to_char(:new.email), 'NULL') <> nvl(to_char(:old.email), 'NULL') then
        begin
          insert_changes('EMAIL', :old.email, :new.email);
        end;
      end if;
      if nvl(to_char(:new.dateactive), 'NULL') <> nvl(to_char(:old.dateactive), 'NULL') then
        begin
          insert_changes('DATEACTIVE', to_char(:old.dateactive,'dd-mm-yyyy'),to_char(:new.dateactive,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.dateinactive), 'NULL') <> nvl(to_char(:old.dateinactive), 'NULL') then
        begin
          insert_changes('DATEINACTIVE',to_char(:old.dateinactive,'dd-mm-yyyy'),to_char(:new.dateinactive,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.active), 'NULL') <> nvl(to_char(:old.active), 'NULL') then
        begin
          insert_changes('ACTIVE', :old.active, :new.active);
        end;
      end if;
      if nvl(to_char(:new.remark), 'NULL') <> nvl(to_char(:old.remark), 'NULL') then
        begin
          insert_changes('REMARK', :old.remark, :new.remark);
        end;
      end if;
      if nvl(to_char(:new.siccode), 'NULL') <> nvl(to_char(:old.siccode), 'NULL') then
        begin
          insert_changes('SICCODE', :old.siccode, :new.siccode);
        end;
      end if;
      if nvl(to_char(:new.searchname), 'NULL') <> nvl(to_char(:old.searchname), 'NULL') then
        begin
          insert_changes('SEARCHNAME', :old.searchname, :new.searchname);
        end;
      end if;
      if nvl(to_char(:new.legacycustomernumber), 'NULL') <>
         nvl(to_char(:old.legacycustomernumber), 'NULL') then
        begin
          insert_changes('LEGACYCUSTOMERNUMBER', :old.legacycustomernumber,
                         :new.legacycustomernumber);
        end;
      end if;
      if nvl(to_char(:new.occupancyfromstockcount), 'NULL') <>
         nvl(to_char(:old.occupancyfromstockcount), 'NULL') then
        begin
          insert_changes('OCCUPANCYFROMSTOCKCOUNT', :old.occupancyfromstockcount,
                         :new.occupancyfromstockcount);
        end;
      end if;
      if nvl(to_char(:new.debtor_id), 'NULL') <> nvl(to_char(:old.debtor_id), 'NULL') then
        begin
          insert_changes('DEBTOR_ID', :old.debtor_id, :new.debtor_id);
        end;
      end if;
      if nvl(to_char(:new.defaultbusinessunit_id), 'NULL') <>
         nvl(to_char(:old.defaultbusinessunit_id), 'NULL') then
        begin
          insert_changes('DEFAULTBUSINESSUNIT_ID', :old.defaultbusinessunit_id,
                         :new.defaultbusinessunit_id);
        end;
      end if;
      if nvl(to_char(:new.masteraccount_id), 'NULL') <> nvl(to_char(:old.masteraccount_id), 'NULL') then
        begin
          insert_changes('MASTERACCOUNT_ID', :old.masteraccount_id, :new.masteraccount_id);
        end;
      end if;
      if nvl(to_char(:new.marketsegment_id), 'NULL') <> nvl(to_char(:old.marketsegment_id), 'NULL') then
        begin
          insert_changes('MARKETSEGMENT_ID', :old.marketsegment_id, :new.marketsegment_id);
        end;
      end if;
      if nvl(to_char(:new.masteraccount), 'NULL') <> nvl(to_char(:old.masteraccount), 'NULL') then
        begin
          insert_changes('MASTERACCOUNT', :old.masteraccount, :new.masteraccount);
        end;
      end if;
      if nvl(to_char(:new.salesarea_id), 'NULL') <> nvl(to_char(:old.salesarea_id), 'NULL') then
        begin
          insert_changes('SALESAREA_ID', :old.salesarea_id, :new.salesarea_id);
        end;
      end if;
      if nvl(to_char(:new.country_id), 'NULL') <> nvl(to_char(:old.country_id), 'NULL') then
        begin
          insert_changes('COUNTRY_ID', :old.country_id, :new.country_id);
        end;
      end if;
      if nvl(to_char(:new.language_id), 'NULL') <> nvl(to_char(:old.language_id), 'NULL') then
        begin
          insert_changes('LANGUAGE_ID', :old.language_id, :new.language_id);
        end;
      end if;
      if nvl(to_char(:new.visitaddress_id), 'NULL') <> nvl(to_char(:old.visitaddress_id), 'NULL') then
        begin
          insert_changes('VISITADDRESS_ID', :old.visitaddress_id, :new.visitaddress_id);
        end;
      end if;
      if nvl(to_char(:new.mailaddress_id), 'NULL') <> nvl(to_char(:old.mailaddress_id), 'NULL') then
        begin
          insert_changes('MAILADDRESS_ID', :old.mailaddress_id, :new.mailaddress_id);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.communicationmethod_id), 'NULL') <>
         nvl(to_char(:old.communicationmethod_id), 'NULL') then
        begin
          insert_changes('COMMUNICATIONMETHOD_ID', :old.communicationmethod_id,
                         :new.communicationmethod_id);
        end;
      end if;
      if nvl(to_char(:new.soilcount), 'NULL') <> nvl(to_char(:old.soilcount), 'NULL') then
        begin
          insert_changes('SOILCOUNT', :old.soilcount, :new.soilcount);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.deliverynotelayout_id), 'NULL') <>
         nvl(to_char(:old.deliverynotelayout_id), 'NULL') then
        begin
          insert_changes('DELIVERYNOTELAYOUT_ID', :old.deliverynotelayout_id,
                         :new.deliverynotelayout_id);
        end;
      end if;
      if nvl(to_char(:new.consignmentnotelayout_id), 'NULL') <>
         nvl(to_char(:old.consignmentnotelayout_id), 'NULL') then
        begin
          insert_changes('CONSIGNMENTNOTELAYOUT_ID', :old.consignmentnotelayout_id,
                         :new.consignmentnotelayout_id);
        end;
      end if;
      if nvl(to_char(:new.internetordering), 'NULL') <> nvl(to_char(:old.internetordering), 'NULL') then
        begin
          insert_changes('INTERNETORDERING', :old.internetordering, :new.internetordering);
        end;
      end if;
      if nvl(to_char(:new.importoccupancyhht), 'NULL') <>
         nvl(to_char(:old.importoccupancyhht), 'NULL') then
        begin
          insert_changes('IMPORTOCCUPANCYHHT', :old.importoccupancyhht, :new.importoccupancyhht);
        end;
      end if;
      if nvl(to_char(:new.returnlinen), 'NULL') <> nvl(to_char(:old.returnlinen), 'NULL') then
        begin
          insert_changes('RETURNLINEN', :old.returnlinen, :new.returnlinen);
        end;
      end if;
      if nvl(to_char(:new.returngarments), 'NULL') <> nvl(to_char(:old.returngarments), 'NULL') then
        begin
          insert_changes('RETURNGARMENTS', :old.returngarments, :new.returngarments);
        end;
      end if;
      if nvl(to_char(:new.codegarmentsuniquely), 'NULL') <>
         nvl(to_char(:old.codegarmentsuniquely), 'NULL') then
        begin
          insert_changes('CODEGARMENTSUNIQUELY', :old.codegarmentsuniquely,
                         :new.codegarmentsuniquely);
        end;
      end if;
      if nvl(to_char(:new.daysnoprepcharge), 'NULL') <> nvl(to_char(:old.daysnoprepcharge), 'NULL') then
        begin
          insert_changes('DAYSNOPREPCHARGE', :old.daysnoprepcharge, :new.daysnoprepcharge);
        end;
      end if;
      if nvl(to_char(:new.garmentrentspecification), 'NULL') <>
         nvl(to_char(:old.garmentrentspecification), 'NULL') then
        begin
          insert_changes('GARMENTRENTSPECIFICATION', :old.garmentrentspecification,
                         :new.garmentrentspecification);
        end;
      end if;
      if nvl(to_char(:new.swingsuitdelivery), 'NULL') <>
         nvl(to_char(:old.swingsuitdelivery), 'NULL') then
        begin
          insert_changes('SWINGSUITDELIVERY', :old.swingsuitdelivery, :new.swingsuitdelivery);
        end;
      end if;
      if nvl(to_char(:new.usesgarmentdispenser), 'NULL') <>
         nvl(to_char(:old.usesgarmentdispenser), 'NULL') then
        begin
          insert_changes('USESGARMENTDISPENSER', :old.usesgarmentdispenser,
                         :new.usesgarmentdispenser);
        end;
      end if;
      if nvl(to_char(:new.lockermanagement), 'NULL') <> nvl(to_char(:old.lockermanagement), 'NULL') then
        begin
          insert_changes('LOCKERMANAGEMENT', :old.lockermanagement, :new.lockermanagement);
        end;
      end if;
      if nvl(to_char(:new.firstdaysgrade_id), 'NULL') <>
         nvl(to_char(:old.firstdaysgrade_id), 'NULL') then
        begin
          insert_changes('FIRSTDAYSGRADE_ID', :old.firstdaysgrade_id, :new.firstdaysgrade_id);
        end;
      end if;
      if nvl(to_char(:new.daysspecialgrade), 'NULL') <> nvl(to_char(:old.daysspecialgrade), 'NULL') then
        begin
          insert_changes('DAYSSPECIALGRADE', :old.daysspecialgrade, :new.daysspecialgrade);
        end;
      end if;
      if nvl(to_char(:new.firstissuegrade_id), 'NULL') <>
         nvl(to_char(:old.firstissuegrade_id), 'NULL') then
        begin
          insert_changes('FIRSTISSUEGRADE_ID', :old.firstissuegrade_id, :new.firstissuegrade_id);
        end;
      end if;
      if nvl(to_char(:new.qualitygrade_id), 'NULL') <> nvl(to_char(:old.qualitygrade_id), 'NULL') then
        begin
          insert_changes('QUALITYGRADE_ID', :old.qualitygrade_id, :new.qualitygrade_id);
        end;
      end if;
      if nvl(to_char(:new.serviceteam_id), 'NULL') <> nvl(to_char(:old.serviceteam_id), 'NULL') then
        begin
          insert_changes('SERVICETEAM_ID', :old.serviceteam_id, :new.serviceteam_id);
        end;
      end if;
      if nvl(to_char(:new.correctshortages), 'NULL') <> nvl(to_char(:old.correctshortages), 'NULL') then
        begin
          insert_changes('CORRECTSHORTAGES', :old.correctshortages, :new.correctshortages);
        end;
      end if;
      if nvl(to_char(:new.standardqtydefinition), 'NULL') <>
         nvl(to_char(:old.standardqtydefinition), 'NULL') then
        begin
          insert_changes('STANDARDQTYDEFINITION', :old.standardqtydefinition,
                         :new.standardqtydefinition);
        end;
      end if;
      if nvl(to_char(:new.correctoverdeliveries), 'NULL') <>
         nvl(to_char(:old.correctoverdeliveries), 'NULL') then
        begin
          insert_changes('CORRECTOVERDELIVERIES', :old.correctoverdeliveries,
                         :new.correctoverdeliveries);
        end;
      end if;
      if nvl(to_char(:new.invoicelayout_id), 'NULL') <> nvl(to_char(:old.invoicelayout_id), 'NULL') then
        begin
          insert_changes('INVOICELAYOUT_ID', :old.invoicelayout_id, :new.invoicelayout_id);
        end;
      end if;
      if nvl(to_char(:new.currency_id), 'NULL') <> nvl(to_char(:old.currency_id), 'NULL') then
        begin
          insert_changes('CURRENCY_ID', :old.currency_id, :new.currency_id);
        end;
      end if;
      if nvl(to_char(:new.paymenttype), 'NULL') <> nvl(to_char(:old.paymenttype), 'NULL') then
        begin
          insert_changes('PAYMENTTYPE', :old.paymenttype, :new.paymenttype);
        end;
      end if;
      if nvl(to_char(:new.paymentmethod), 'NULL') <> nvl(to_char(:old.paymentmethod), 'NULL') then
        begin
          insert_changes('PAYMENTMETHOD', :old.paymentmethod, :new.paymentmethod);
        end;
      end if;
      if nvl(to_char(:new.taxable), 'NULL') <> nvl(to_char(:old.taxable), 'NULL') then
        begin
          insert_changes('TAXABLE', :old.taxable, :new.taxable);
        end;
      end if;
      if nvl(to_char(:new.minimuminvoiceamount), 'NULL') <>
         nvl(to_char(:old.minimuminvoiceamount), 'NULL') then
        begin
          insert_changes('MINIMUMINVOICEAMOUNT', :old.minimuminvoiceamount,
                         :new.minimuminvoiceamount);
        end;
      end if;
      if nvl(to_char(:new.invoicecopies), 'NULL') <> nvl(to_char(:old.invoicecopies), 'NULL') then
        begin
          insert_changes('INVOICECOPIES', :old.invoicecopies, :new.invoicecopies);
        end;
      end if;
      if nvl(to_char(:new.states_id), 'NULL') <> nvl(to_char(:old.states_id), 'NULL') then
        begin
          insert_changes('STATES_ID', :old.states_id, :new.states_id);
        end;
      end if;
      if nvl(to_char(:new.countytaxauthority_id), 'NULL') <>
         nvl(to_char(:old.countytaxauthority_id), 'NULL') then
        begin
          insert_changes('COUNTYTAXAUTHORITY_ID', :old.countytaxauthority_id,
                         :new.countytaxauthority_id);
        end;
      end if;
      if nvl(to_char(:new.citytaxauthority_id), 'NULL') <>
         nvl(to_char(:old.citytaxauthority_id), 'NULL') then
        begin
          insert_changes('CITYTAXAUTHORITY_ID', :old.citytaxauthority_id, :new.citytaxauthority_id);
        end;
      end if;
      if nvl(to_char(:new.customermarkinggarment), 'NULL') <>
         nvl(to_char(:old.customermarkinggarment), 'NULL') then
        begin
          insert_changes('CUSTOMERMARKINGGARMENT', :old.customermarkinggarment,
                         :new.customermarkinggarment);
        end;
      end if;
      if nvl(to_char(:new.invoicefrequency_id), 'NULL') <>
         nvl(to_char(:old.invoicefrequency_id), 'NULL') then
        begin
          insert_changes('INVOICEFREQUENCY_ID', :old.invoicefrequency_id, :new.invoicefrequency_id);
        end;
      end if;
      if nvl(to_char(:new.codelabellayout_id), 'NULL') <>
         nvl(to_char(:old.codelabellayout_id), 'NULL') then
        begin
          insert_changes('CODELABELLAYOUT_ID', :old.codelabellayout_id, :new.codelabellayout_id);
        end;
      end if;
      if nvl(to_char(:new.namelabellayout_id), 'NULL') <>
         nvl(to_char(:old.namelabellayout_id), 'NULL') then
        begin
          insert_changes('NAMELABELLAYOUT_ID', :old.namelabellayout_id, :new.namelabellayout_id);
        end;
      end if;
      if nvl(to_char(:new.allowprepchargepertemplate), 'NULL') <>
         nvl(to_char(:old.allowprepchargepertemplate), 'NULL') then
        begin
          insert_changes('ALLOWPREPCHARGEPERTEMPLATE', :old.allowprepchargepertemplate,
                         :new.allowprepchargepertemplate);
        end;
      end if;
      if nvl(to_char(:new.emblemspecification), 'NULL') <>
         nvl(to_char(:old.emblemspecification), 'NULL') then
        begin
          insert_changes('EMBLEMSPECIFICATION', :old.emblemspecification, :new.emblemspecification);
        end;
      end if;
      if nvl(to_char(:new.allownegativestockcount), 'NULL') <>
         nvl(to_char(:old.allownegativestockcount), 'NULL') then
        begin
          insert_changes('ALLOWNEGATIVESTOCKCOUNT', :old.allownegativestockcount,
                         :new.allownegativestockcount);
        end;
      end if;
      if nvl(to_char(:new.outscansort), 'NULL') <> nvl(to_char(:old.outscansort), 'NULL') then
        begin
          insert_changes('OUTSCANSORT', :old.outscansort, :new.outscansort);
        end;
      end if;
      if nvl(to_char(:new.chargerepairs), 'NULL') <> nvl(to_char(:old.chargerepairs), 'NULL') then
        begin
          insert_changes('CHARGEREPAIRS', :old.chargerepairs, :new.chargerepairs);
        end;
      end if;
      if nvl(to_char(:new.chargewashfirstissue), 'NULL') <>
         nvl(to_char(:old.chargewashfirstissue), 'NULL') then
        begin
          insert_changes('CHARGEWASHFIRSTISSUE', :old.chargewashfirstissue,
                         :new.chargewashfirstissue);
        end;
      end if;
      if nvl(to_char(:new.allowautomaticsales), 'NULL') <>
         nvl(to_char(:old.allowautomaticsales), 'NULL') then
        begin
          insert_changes('ALLOWAUTOMATICSALES', :old.allowautomaticsales, :new.allowautomaticsales);
        end;
      end if;
      if nvl(to_char(:new.customerrelated), 'NULL') <> nvl(to_char(:old.customerrelated), 'NULL') then
        begin
          insert_changes('CUSTOMERRELATED', :old.customerrelated, :new.customerrelated);
        end;
      end if;
      if nvl(to_char(:new.chargeresidualvalue), 'NULL') <>
         nvl(to_char(:old.chargeresidualvalue), 'NULL') then
        begin
          insert_changes('CHARGERESIDUALVALUE', :old.chargeresidualvalue, :new.chargeresidualvalue);
        end;
      end if;
      /***
      if nvl(to_char(:new.oldcluster_id), 'NULL') <> nvl(to_char(:old.oldcluster_id), 'NULL') then
        begin
          insert_changes('OLDCLUSTER_ID', :old.oldcluster_id, :new.oldcluster_id);
        end;
      end if;
      ***/
      if nvl(to_char(:new.rentperiod), 'NULL') <> nvl(to_char(:old.rentperiod), 'NULL') then
        begin
          insert_changes('RENTPERIOD', :old.rentperiod, :new.rentperiod);
        end;
      end if;
      if nvl(to_char(:new.splitinvoices), 'NULL') <> nvl(to_char(:old.splitinvoices), 'NULL') then
        begin
          insert_changes('SPLITINVOICES', :old.splitinvoices, :new.splitinvoices);
        end;
      end if;
      if nvl(to_char(:new.vatnumber), 'NULL') <> nvl(to_char(:old.vatnumber), 'NULL') then
        begin
          insert_changes('VATNUMBER', :old.vatnumber, :new.vatnumber);
        end;
      end if;
      if nvl(to_char(:new.chain_id), 'NULL') <> nvl(to_char(:old.chain_id), 'NULL') then
        begin
          insert_changes('CHAIN_ID', :old.chain_id, :new.chain_id);
        end;
      end if;
      if nvl(to_char(:new.garmentinsurance), 'NULL') <> nvl(to_char(:old.garmentinsurance), 'NULL') then
        begin
          insert_changes('GARMENTINSURANCE', :old.garmentinsurance, :new.garmentinsurance);
        end;
      end if;
      if nvl(to_char(:new.invoiceaddress_id), 'NULL') <>
         nvl(to_char(:old.invoiceaddress_id), 'NULL') then
        begin
          insert_changes('INVOICEADDRESS_ID', :old.invoiceaddress_id, :new.invoiceaddress_id);
        end;
      end if;
      if nvl(to_char(:new.ilnnumber), 'NULL') <> nvl(to_char(:old.ilnnumber), 'NULL') then
        begin
          insert_changes('ILNNUMBER', :old.ilnnumber, :new.ilnnumber);
        end;
      end if;
      if nvl(to_char(:new.usesbundles), 'NULL') <> nvl(to_char(:old.usesbundles), 'NULL') then
        begin
          insert_changes('USESBUNDLES', :old.usesbundles, :new.usesbundles);
        end;
      end if;
      if nvl(to_char(:new.extraname1), 'NULL') <> nvl(to_char(:old.extraname1), 'NULL') then
        begin
          insert_changes('EXTRANAME1', :old.extraname1, :new.extraname1);
        end;
      end if;
      if nvl(to_char(:new.extraname2), 'NULL') <> nvl(to_char(:old.extraname2), 'NULL') then
        begin
          insert_changes('EXTRANAME2', :old.extraname2, :new.extraname2);
        end;
      end if;
      if nvl(to_char(:new.scansondeliverynote), 'NULL') <>
         nvl(to_char(:old.scansondeliverynote), 'NULL') then
        begin
          insert_changes('SCANSONDELIVERYNOTE', :old.scansondeliverynote, :new.scansondeliverynote);
        end;
      end if;
      if nvl(to_char(:new.directinvdeliveries), 'NULL') <>
         nvl(to_char(:old.directinvdeliveries), 'NULL') then
        begin
          insert_changes('DIRECTINVDELIVERIES', :old.directinvdeliveries, :new.directinvdeliveries);
        end;
      end if;
      if nvl(to_char(:new.directinvcleanweights), 'NULL') <>
         nvl(to_char(:old.directinvcleanweights), 'NULL') then
        begin
          insert_changes('DIRECTINVCLEANWEIGHTS', :old.directinvcleanweights,
                         :new.directinvcleanweights);
        end;
      end if;
      if nvl(to_char(:new.directinvsoilweights), 'NULL') <>
         nvl(to_char(:old.directinvsoilweights), 'NULL') then
        begin
          insert_changes('DIRECTINVSOILWEIGHTS', :old.directinvsoilweights,
                         :new.directinvsoilweights);
        end;
      end if;
      if nvl(to_char(:new.directinvminimumamount), 'NULL') <>
         nvl(to_char(:old.directinvminimumamount), 'NULL') then
        begin
          insert_changes('DIRECTINVMINIMUMAMOUNT', :old.directinvminimumamount,
                         :new.directinvminimumamount);
        end;
      end if;
      if nvl(to_char(:new.associationtype), 'NULL') <> nvl(to_char(:old.associationtype), 'NULL') then
        begin
          insert_changes('ASSOCIATIONTYPE', :old.associationtype, :new.associationtype);
        end;
      end if;
      if nvl(to_char(:new.usecoverpage), 'NULL') <> nvl(to_char(:old.usecoverpage), 'NULL') then
        begin
          insert_changes('USECOVERPAGE', :old.usecoverpage, :new.usecoverpage);
        end;
      end if;
      if nvl(to_char(:new.bulkpacking), 'NULL') <> nvl(to_char(:old.bulkpacking), 'NULL') then
        begin
          insert_changes('BULKPACKING', :old.bulkpacking, :new.bulkpacking);
        end;
      end if;
      if nvl(to_char(:new.ownedcontainer), 'NULL') <> nvl(to_char(:old.ownedcontainer), 'NULL') then
        begin
          insert_changes('OWNEDCONTAINER', :old.ownedcontainer, :new.ownedcontainer);
        end;
      end if;
      if nvl(to_char(:new.edimethod), 'NULL') <> nvl(to_char(:old.edimethod), 'NULL') then
        begin
          insert_changes('EDIMETHOD', :old.edimethod, :new.edimethod);
        end;
      end if;
      if nvl(to_char(:new.insurancepricetype), 'NULL') <>
         nvl(to_char(:old.insurancepricetype), 'NULL') then
        begin
          insert_changes('INSURANCEPRICETYPE', :old.insurancepricetype, :new.insurancepricetype);
        end;
      end if;
      if nvl(to_char(:new.delnoteforbulkputupitems), 'NULL') <>
         nvl(to_char(:old.delnoteforbulkputupitems), 'NULL') then
        begin
          insert_changes('DELNOTEFORBULKPUTUPITEMS', :old.delnoteforbulkputupitems,
                         :new.delnoteforbulkputupitems);
        end;
      end if;
      if nvl(to_char(:new.passerbycustomer), 'NULL') <> nvl(to_char(:old.passerbycustomer), 'NULL') then
        begin
          insert_changes('PASSERBYCUSTOMER', :old.passerbycustomer, :new.passerbycustomer);
        end;
      end if;
      if nvl(to_char(:new.misturnoversegment_id), 'NULL') <>
         nvl(to_char(:old.misturnoversegment_id), 'NULL') then
        begin
          insert_changes('MISTURNOVERSEGMENT_ID', :old.misturnoversegment_id,
                         :new.misturnoversegment_id);
        end;
      end if;
      if nvl(to_char(:new.signaturerequired), 'NULL') <>
         nvl(to_char(:old.signaturerequired), 'NULL') then
        begin
          insert_changes('SIGNATUREREQUIRED', :old.signaturerequired, :new.signaturerequired);
        end;
      end if;
      if nvl(to_char(:new.depositstockallowed), 'NULL') <>
         nvl(to_char(:old.depositstockallowed), 'NULL') then
        begin
          insert_changes('DEPOSITSTOCKALLOWED', :old.depositstockallowed, :new.depositstockallowed);
        end;
      end if;
      if nvl(to_char(:new.seasonautoflagallowed), 'NULL') <>
         nvl(to_char(:old.seasonautoflagallowed), 'NULL') then
        begin
          insert_changes('SEASONAUTOFLAGALLOWED', :old.seasonautoflagallowed,
                         :new.seasonautoflagallowed);
        end;
      end if;
      if nvl(to_char(:new.weeklymininvamount), 'NULL') <>
         nvl(to_char(:old.weeklymininvamount), 'NULL') then
        begin
          insert_changes('WEEKLYMININVAMOUNT', :old.weeklymininvamount, :new.weeklymininvamount);
        end;
      end if;
      if nvl(to_char(:new.outscanconfirmwearerchng), 'NULL') <>
         nvl(to_char(:old.outscanconfirmwearerchng), 'NULL') then
        begin
          insert_changes('OUTSCANCONFIRMWEARERCHNG', :old.outscanconfirmwearerchng,
                         :new.outscanconfirmwearerchng);
        end;
      end if;
      if nvl(to_char(:new.flatratedtypecharge), 'NULL') <>
         nvl(to_char(:old.flatratedtypecharge), 'NULL') then
        begin
          insert_changes('FLATRATEDTYPECHARGE', :old.flatratedtypecharge, :new.flatratedtypecharge);
        end;
      end if;
      if nvl(to_char(:new.inscanbasedforecast), 'NULL') <>
         nvl(to_char(:old.inscanbasedforecast), 'NULL') then
        begin
          insert_changes('INSCANBASEDFORECAST', :old.inscanbasedforecast, :new.inscanbasedforecast);
        end;
      end if;
      if nvl(to_char(:new.loadingprogram), 'NULL') <> nvl(to_char(:old.loadingprogram), 'NULL') then
        begin
          insert_changes('LOADINGPROGRAM', :old.loadingprogram, :new.loadingprogram);
        end;
      end if;
      if nvl(to_char(:new.consignmentnotelevel), 'NULL') <>
         nvl(to_char(:old.consignmentnotelevel), 'NULL') then
        begin
          insert_changes('CONSIGNMENTNOTELEVEL', :old.consignmentnotelevel,
                         :new.consignmentnotelevel);
        end;
      end if;
      if nvl(to_char(:new.directinvsalesnotes), 'NULL') <>
         nvl(to_char(:old.directinvsalesnotes), 'NULL') then
        begin
          insert_changes('DIRECTINVSALESNOTES', :old.directinvsalesnotes, :new.directinvsalesnotes);
        end;
      end if;
      if nvl(to_char(:new.deliverynotewithprices), 'NULL') <>
         nvl(to_char(:old.deliverynotewithprices), 'NULL') then
        begin
          insert_changes('DELIVERYNOTEWITHPRICES', :old.deliverynotewithprices,
                         :new.deliverynotewithprices);
        end;
      end if;
      if nvl(to_char(:new.autoloadpacking), 'NULL') <> nvl(to_char(:old.autoloadpacking), 'NULL') then
        begin
          insert_changes('AUTOLOADPACKING', :old.autoloadpacking, :new.autoloadpacking);
        end;
      end if;
      if nvl(to_char(:new.chargerestockingfee), 'NULL') <>
         nvl(to_char(:old.chargerestockingfee), 'NULL') then
        begin
          insert_changes('CHARGERESTOCKINGFEE', :old.chargerestockingfee, :new.chargerestockingfee);
        end;
      end if;
      if nvl(to_char(:new.chargestockcharge), 'NULL') <>
         nvl(to_char(:old.chargestockcharge), 'NULL') then
        begin
          insert_changes('CHARGESTOCKCHARGE', :old.chargestockcharge, :new.chargestockcharge);
        end;
      end if;
      if nvl(to_char(:new.plantdepartment_id), 'NULL') <>
         nvl(to_char(:old.plantdepartment_id), 'NULL') then
        begin
          insert_changes('PLANTDEPARTMENT_ID', :old.plantdepartment_id, :new.plantdepartment_id);
        end;
      end if;
      if nvl(to_char(:new.chargelosscharge), 'NULL') <> nvl(to_char(:old.chargelosscharge), 'NULL') then
        begin
          insert_changes('CHARGELOSSCHARGE', :old.chargelosscharge, :new.chargelosscharge);
        end;
      end if;
      if nvl(to_char(:new.nationalaccount_id), 'NULL') <>
         nvl(to_char(:old.nationalaccount_id), 'NULL') then
        begin
          insert_changes('NATIONALACCOUNT_ID', :old.nationalaccount_id, :new.nationalaccount_id);
        end;
      end if;
      if nvl(to_char(:new.alternatesorting), 'NULL') <> nvl(to_char(:old.alternatesorting), 'NULL') then
        begin
          insert_changes('ALTERNATESORTING', :old.alternatesorting, :new.alternatesorting);
        end;
      end if;
      if nvl(to_char(:new.lostdate), 'NULL') <> nvl(to_char(:old.lostdate), 'NULL') then
        begin
          insert_changes('LOSTDATE', to_char(:old.lostdate,'dd-mm-yyyy'),  to_char(:new.lostdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.contractweeksleft), 'NULL') <>
         nvl(to_char(:old.contractweeksleft), 'NULL') then
        begin
          insert_changes('CONTRACTWEEKSLEFT', :old.contractweeksleft, :new.contractweeksleft);
        end;
      end if;
      if nvl(to_char(:new.lostrevenueamount), 'NULL') <>
         nvl(to_char(:old.lostrevenueamount), 'NULL') then
        begin
          insert_changes('LOSTREVENUEAMOUNT', :old.lostrevenueamount, :new.lostrevenueamount);
        end;
      end if;
      if nvl(to_char(:new.inheritmapricelist), 'NULL') <>
         nvl(to_char(:old.inheritmapricelist), 'NULL') then
        begin
          insert_changes('INHERITMAPRICELIST', :old.inheritmapricelist, :new.inheritmapricelist);
        end;
      end if;
      if nvl(to_char(:new.restrictonmaproducts), 'NULL') <>
         nvl(to_char(:old.restrictonmaproducts), 'NULL') then
        begin
          insert_changes('RESTRICTONMAPRODUCTS', :old.restrictonmaproducts,
                         :new.restrictonmaproducts);
        end;
      end if;
      if nvl(to_char(:new.completnesscheckcontainer), 'NULL') <>
         nvl(to_char(:old.completnesscheckcontainer), 'NULL') then
        begin
          insert_changes('COMPLETNESSCHECKCONTAINER', :old.completnesscheckcontainer,
                         :new.completnesscheckcontainer);
        end;
      end if;
      if nvl(to_char(:new.chargerepaircog), 'NULL') <> nvl(to_char(:old.chargerepaircog), 'NULL') then
        begin
          insert_changes('CHARGEREPAIRCOG', :old.chargerepaircog, :new.chargerepaircog);
        end;
      end if;
      if nvl(to_char(:new.cogallowedonlyplpc), 'NULL') <>
         nvl(to_char(:old.cogallowedonlyplpc), 'NULL') then
        begin
          insert_changes('COGALLOWEDONLYPLPC', :old.cogallowedonlyplpc, :new.cogallowedonlyplpc);
        end;
      end if;
      if nvl(to_char(:new.allocationmethod), 'NULL') <> nvl(to_char(:old.allocationmethod), 'NULL') then
        begin
          insert_changes('ALLOCATIONMETHOD', :old.allocationmethod, :new.allocationmethod);
        end;
      end if;
      if nvl(to_char(:new.standardsbasedon), 'NULL') <> nvl(to_char(:old.standardsbasedon), 'NULL') then
        begin
          insert_changes('STANDARDSBASEDON', :old.standardsbasedon, :new.standardsbasedon);
        end;
      end if;
      if nvl(to_char(:new.cocnumber), 'NULL') <> nvl(to_char(:old.cocnumber), 'NULL') then
        begin
          insert_changes('COCNUMBER', :old.cocnumber, :new.cocnumber);
        end;
      end if;
      if nvl(to_char(:new.pnnumber), 'NULL') <> nvl(to_char(:old.pnnumber), 'NULL') then
        begin
          insert_changes('PNNUMBER', :old.pnnumber, :new.pnnumber);
        end;
      end if;
      if nvl(to_char(:new.serviceemployee_id), 'NULL') <>
         nvl(to_char(:old.serviceemployee_id), 'NULL') then
        begin
          insert_changes('SERVICEEMPLOYEE_ID', :old.serviceemployee_id, :new.serviceemployee_id);
        end;
      end if;
      if nvl(to_char(:new.commoncustomer_id), 'NULL') <>
         nvl(to_char(:old.commoncustomer_id), 'NULL') then
        begin
          insert_changes('COMMONCUSTOMER_ID', :old.commoncustomer_id, :new.commoncustomer_id);
        end;
      end if;
      if nvl(to_char(:new.bonusagreement), 'NULL') <> nvl(to_char(:old.bonusagreement), 'NULL') then
        begin
          insert_changes('BONUSAGREEMENT', :old.bonusagreement, :new.bonusagreement);
        end;
      end if;
      if nvl(to_char(:new.acquisioncode_id), 'NULL') <> nvl(to_char(:old.acquisioncode_id), 'NULL') then
        begin
          insert_changes('ACQUISIONCODE_ID', :old.acquisioncode_id, :new.acquisioncode_id);
        end;
      end if;
      if nvl(to_char(:new.customerranking_id), 'NULL') <>
         nvl(to_char(:old.customerranking_id), 'NULL') then
        begin
          insert_changes('CUSTOMERRANKING_ID', :old.customerranking_id, :new.customerranking_id);
        end;
      end if;
      if nvl(to_char(:new.tdccode), 'NULL') <> nvl(to_char(:old.tdccode), 'NULL') then
        begin
          insert_changes('TDCCODE', :old.tdccode, :new.tdccode);
        end;
      end if;
      if nvl(to_char(:new.sendinvoiceto), 'NULL') <> nvl(to_char(:old.sendinvoiceto), 'NULL') then
        begin
          insert_changes('SENDINVOICETO', :old.sendinvoiceto, :new.sendinvoiceto);
        end;
      end if;
      if nvl(to_char(:new.usewearergarmentsbudget), 'NULL') <>
         nvl(to_char(:old.usewearergarmentsbudget), 'NULL') then
        begin
          insert_changes('USEWEARERGARMENTSBUDGET', :old.usewearergarmentsbudget,
                         :new.usewearergarmentsbudget);
        end;
      end if;
      if nvl(to_char(:new.exportdatefin), 'NULL') <> nvl(to_char(:old.exportdatefin), 'NULL') then
        begin
          insert_changes('EXPORTDATEFIN', :old.exportdatefin, :new.exportdatefin);
        end;
      end if;
      if nvl(to_char(:new.masteraccountrelation), 'NULL') <>
         nvl(to_char(:old.masteraccountrelation), 'NULL') then
        begin
          insert_changes('MASTERACCOUNTRELATION', :old.masteraccountrelation,
                         :new.masteraccountrelation);
        end;
      end if;
      if nvl(to_char(:new.allowothercontracts), 'NULL') <>
         nvl(to_char(:old.allowothercontracts), 'NULL') then
        begin
          insert_changes('ALLOWOTHERCONTRACTS', :old.allowothercontracts, :new.allowothercontracts);
        end;
      end if;
      if nvl(to_char(:new.allowotherpricelists), 'NULL') <>
         nvl(to_char(:old.allowotherpricelists), 'NULL') then
        begin
          insert_changes('ALLOWOTHERPRICELISTS', :old.allowotherpricelists,
                         :new.allowotherpricelists);
        end;
      end if;
      if nvl(to_char(:new.priceconcerncode), 'NULL') <> nvl(to_char(:old.priceconcerncode), 'NULL') then
        begin
          insert_changes('PRICECONCERNCODE', :old.priceconcerncode, :new.priceconcerncode);
        end;
      end if;
      if nvl(to_char(:new.invoicecouplingcode), 'NULL') <>
         nvl(to_char(:old.invoicecouplingcode), 'NULL') then
        begin
          insert_changes('INVOICECOUPLINGCODE', :old.invoicecouplingcode, :new.invoicecouplingcode);
        end;
      end if;
      if nvl(to_char(:new.suppressprintdelnote), 'NULL') <>
         nvl(to_char(:old.suppressprintdelnote), 'NULL') then
        begin
          insert_changes('SUPPRESSPRINTDELNOTE', :old.suppressprintdelnote,
                         :new.suppressprintdelnote);
        end;
      end if;
      if nvl(to_char(:new.suppressprintdelnotebatch), 'NULL') <>
         nvl(to_char(:old.suppressprintdelnotebatch), 'NULL') then
        begin
          insert_changes('SUPPRESSPRINTDELNOTEBATCH', :old.suppressprintdelnotebatch,
                         :new.suppressprintdelnotebatch);
        end;
      end if;
      if nvl(to_char(:new.customertype), 'NULL') <> nvl(to_char(:old.customertype), 'NULL') then
        begin
          insert_changes('CUSTOMERTYPE', :old.customertype, :new.customertype);
        end;
      end if;
      if nvl(to_char(:new.orderingstockroom_id), 'NULL') <>
         nvl(to_char(:old.orderingstockroom_id), 'NULL') then
        begin
          insert_changes('ORDERINGSTOCKROOM_ID', :old.orderingstockroom_id,
                         :new.orderingstockroom_id);
        end;
      end if;
      if nvl(to_char(:new.soldtocustomer), 'NULL') <> nvl(to_char(:old.soldtocustomer), 'NULL') then
        begin
          insert_changes('SOLDTOCUSTOMER', :old.soldtocustomer, :new.soldtocustomer);
        end;
      end if;
      if nvl(to_char(:new.billtocustomer), 'NULL') <> nvl(to_char(:old.billtocustomer), 'NULL') then
        begin
          insert_changes('BILLTOCUSTOMER', :old.billtocustomer, :new.billtocustomer);
        end;
      end if;
      if nvl(to_char(:new.mininvamounttobereached), 'NULL') <>
         nvl(to_char(:old.mininvamounttobereached), 'NULL') then
        begin
          insert_changes('MININVAMOUNTTOBEREACHED', :old.mininvamounttobereached,
                         :new.mininvamounttobereached);
        end;
      end if;
      if nvl(to_char(:new.splitinvoicesperactivity), 'NULL') <>
         nvl(to_char(:old.splitinvoicesperactivity), 'NULL') then
        begin
          insert_changes('SPLITINVOICESPERACTIVITY', :old.splitinvoicesperactivity,
                         :new.splitinvoicesperactivity);
        end;
      end if;
      if nvl(to_char(:new.contractperiod), 'NULL') <> nvl(to_char(:old.contractperiod), 'NULL') then
        begin
          insert_changes('CONTRACTPERIOD', :old.contractperiod, :new.contractperiod);
        end;
      end if;
      if nvl(to_char(:new.prolongationperiod), 'NULL') <>
         nvl(to_char(:old.prolongationperiod), 'NULL') then
        begin
          insert_changes('PROLONGATIONPERIOD', :old.prolongationperiod, :new.prolongationperiod);
        end;
      end if;
      if nvl(to_char(:new.canceladvanceperiod), 'NULL') <>
         nvl(to_char(:old.canceladvanceperiod), 'NULL') then
        begin
          insert_changes('CANCELADVANCEPERIOD', :old.canceladvanceperiod, :new.canceladvanceperiod);
        end;
      end if;
      if nvl(to_char(:new.contractusage), 'NULL') <> nvl(to_char(:old.contractusage), 'NULL') then
        begin
          insert_changes('CONTRACTUSAGE', :old.contractusage, :new.contractusage);
        end;
      end if;
      if nvl(to_char(:new.taxexemptcode), 'NULL') <> nvl(to_char(:old.taxexemptcode), 'NULL') then
        begin
          insert_changes('TAXEXEMPTCODE', :old.taxexemptcode, :new.taxexemptcode);
        end;
      end if;
      if nvl(to_char(:new.salesemployee1_id), 'NULL') <>
         nvl(to_char(:old.salesemployee1_id), 'NULL') then
        begin
          insert_changes('SALESEMPLOYEE1_ID', :old.salesemployee1_id, :new.salesemployee1_id);
        end;
      end if;
      if nvl(to_char(:new.salesemployee2_id), 'NULL') <>
         nvl(to_char(:old.salesemployee2_id), 'NULL') then
        begin
          insert_changes('SALESEMPLOYEE2_ID', :old.salesemployee2_id, :new.salesemployee2_id);
        end;
      end if;
      if nvl(to_char(:new.variableservices), 'NULL') <> nvl(to_char(:old.variableservices), 'NULL') then
        begin
          insert_changes('VARIABLESERVICES', :old.variableservices, :new.variableservices);
        end;
      end if;
      if nvl(to_char(:new.exportdelnoteinfo), 'NULL') <>
         nvl(to_char(:old.exportdelnoteinfo), 'NULL') then
        begin
          insert_changes('EXPORTDELNOTEINFO', :old.exportdelnoteinfo, :new.exportdelnoteinfo);
        end;
      end if;
      if nvl(to_char(:new.csvfileseparator), 'NULL') <> nvl(to_char(:old.csvfileseparator), 'NULL') then
        begin
          insert_changes('CSVFILESEPARATOR', :old.csvfileseparator, :new.csvfileseparator);
        end;
      end if;
      if nvl(to_char(:new.chargeservicecosts), 'NULL') <>
         nvl(to_char(:old.chargeservicecosts), 'NULL') then
        begin
          insert_changes('CHARGESERVICECOSTS', :old.chargeservicecosts, :new.chargeservicecosts);
        end;
      end if;
      if nvl(to_char(:new.labelcolor), 'NULL') <> nvl(to_char(:old.labelcolor), 'NULL') then
        begin
          insert_changes('LABELCOLOR', :old.labelcolor, :new.labelcolor);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
exception when dup_val_on_index then null; --ok no problem already registered
end trg_change_customer_cust;
/

CREATE OR REPLACE TRIGGER trg_change_customer_custdelday
  before INSERT OR UPDATE OR DELETE on customerdeliveryday
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --CUSTOMER_ID, DAY_ID, TYPEOFMERCHADISE
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'CUSTOMERDELIVERYDAY', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :new.customer_id, 'DAY_ID', :new.day_id, 'TYPEOFMERCHADISE',
           :new.typeofmerchadise, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'CUSTOMERDELIVERYDAY', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :old.customer_id, 'DAY_ID', :old.day_id, 'TYPEOFMERCHADISE',
           :old.typeofmerchadise, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.day_id), 'NULL') <> nvl(to_char(:old.day_id), 'NULL') then
        begin
          insert_changes('DAY_ID', :old.day_id, :new.day_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.deliverytype), 'NULL') <> nvl(to_char(:old.deliverytype), 'NULL') then
        begin
          insert_changes('DELIVERYTYPE', :old.deliverytype, :new.deliverytype);
        end;
      end if;
      if nvl(to_char(:new.typeofmerchadise), 'NULL') <> nvl(to_char(:old.typeofmerchadise), 'NULL') then
        begin
          insert_changes('TYPEOFMERCHADISE', :old.typeofmerchadise, :new.typeofmerchadise);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_custdelday;
/

CREATE OR REPLACE TRIGGER trg_change_customer_delpt
  before INSERT OR UPDATE OR DELETE on deliverypoint
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --Added customer_id in key for extra info.. not really part of key, thats only DELIVERYPOINT_ID
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'DELIVERYPOINT', fp_fieldname, lv_insert_update_delete,
           'DELIVERYPOINT_ID', :new.deliverypoint_id, 'CUSTOMER_ID', :new.customer_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'DELIVERYPOINT', fp_fieldname, lv_insert_update_delete,
           'DELIVERYPOINT_ID', :old.deliverypoint_id, 'CUSTOMER_ID', :old.customer_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.deliverypoint_id), 'NULL') <> nvl(to_char(:old.deliverypoint_id), 'NULL') then
        begin
          insert_changes('DELIVERYPOINT_ID', :old.deliverypoint_id, :new.deliverypoint_id);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.code), 'NULL') <> nvl(to_char(:old.code), 'NULL') then
        begin
          insert_changes('CODE', :old.code, :new.code);
        end;
      end if;
      if nvl(to_char(:new.description), 'NULL') <> nvl(to_char(:old.description), 'NULL') then
        begin
          insert_changes('DESCRIPTION', :old.description, :new.description);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.deliveryaddress_id), 'NULL') <>
         nvl(to_char(:old.deliveryaddress_id), 'NULL') then
        begin
          insert_changes('DELIVERYADDRESS_ID', :old.deliveryaddress_id, :new.deliveryaddress_id);
        end;
      end if;
      if nvl(to_char(:new.sortaddress), 'NULL') <> nvl(to_char(:old.sortaddress), 'NULL') then
        begin
          insert_changes('SORTADDRESS', :old.sortaddress, :new.sortaddress);
        end;
      end if;
      if nvl(to_char(:new.active), 'NULL') <> nvl(to_char(:old.active), 'NULL') then
        begin
          insert_changes('ACTIVE', :old.active, :new.active);
        end;
      end if;
      if nvl(to_char(:new.breakstarttime), 'NULL') <> nvl(to_char(:old.breakstarttime), 'NULL') then
        begin
          insert_changes('BREAKSTARTTIME', :old.breakstarttime, :new.breakstarttime);
        end;
      end if;
      if nvl(to_char(:new.breakendtime), 'NULL') <> nvl(to_char(:old.breakendtime), 'NULL') then
        begin
          insert_changes('BREAKENDTIME', :old.breakendtime, :new.breakendtime);
        end;
      end if;
      if nvl(to_char(:new.serviceemployee_id), 'NULL') <>
         nvl(to_char(:old.serviceemployee_id), 'NULL') then
        begin
          insert_changes('SERVICEEMPLOYEE_ID', :old.serviceemployee_id, :new.serviceemployee_id);
        end;
      end if;
      if nvl(to_char(:new.salesarea_id), 'NULL') <> nvl(to_char(:old.salesarea_id), 'NULL') then
        begin
          insert_changes('SALESAREA_ID', :old.salesarea_id, :new.salesarea_id);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CODE', :old.code, :new.code);
    end;
  end if;
end trg_change_customer_delpt;
/

CREATE OR REPLACE TRIGGER trg_change_customer_delscheme
  before INSERT OR UPDATE OR DELETE
 on customerdeliveryscheme
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --CUSTOMER_ID, DELIVERYSCHEME_ID, DAY_ID
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'CUSTOMERDELIVERYSCHEME', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :new.customer_id, 'DELIVERYSCHEME_ID',
           :new.deliveryscheme_id, 'DAY_ID', :new.day_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'CUSTOMERDELIVERYSCHEME', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :old.customer_id, 'DELIVERYSCHEME_ID',
           :old.deliveryscheme_id, 'DAY_ID', :old.day_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.deliveryscheme_id), 'NULL') <>
         nvl(to_char(:old.deliveryscheme_id), 'NULL') then
        begin
          insert_changes('DELIVERYSCHEME_ID', :old.deliveryscheme_id, :new.deliveryscheme_id);
        end;
      end if;
      if nvl(to_char(:new.day_id), 'NULL') <> nvl(to_char(:old.day_id), 'NULL') then
        begin
          insert_changes('DAY_ID', :old.day_id, :new.day_id);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_delscheme;
/

CREATE OR REPLACE TRIGGER trg_change_customer_delstop
  before INSERT OR UPDATE OR DELETE on deliveryschemesperstop
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --ROUTESTOP_ID, CUSTOMER_ID, DELIVERYSCHEME_ID, DAY_ID
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           unique_id_field4, unique_id_value4, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'DELIVERYSCHEMESPERSTOP', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :new.customer_id, 'ROUTESTOP_ID',
           :new.routestop_id, 'DELIVERYSCHEME_ID', :new.deliveryscheme_id, 'DAY_ID', :new.day_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, unique_id_field3, unique_id_value3,
           unique_id_field4, unique_id_value4, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'DELIVERYSCHEMESPERSTOP', fp_fieldname,
           lv_insert_update_delete, 'CUSTOMER_ID', :old.customer_id, 'ROUTESTOP_ID',
           :old.routestop_id, 'DELIVERYSCHEME_ID', :old.deliveryscheme_id, 'DAY_ID', :old.day_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.routestop_id), 'NULL') <> nvl(to_char(:old.routestop_id), 'NULL') then
        begin
          insert_changes('ROUTESTOP_ID', :old.routestop_id, :new.routestop_id);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.deliveryscheme_id), 'NULL') <>
         nvl(to_char(:old.deliveryscheme_id), 'NULL') then
        begin
          insert_changes('DELIVERYSCHEME_ID', :old.deliveryscheme_id, :new.deliveryscheme_id);
        end;
      end if;
      if nvl(to_char(:new.day_id), 'NULL') <> nvl(to_char(:old.day_id), 'NULL') then
        begin
          insert_changes('DAY_ID', :old.day_id, :new.day_id);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_delstop;
/

create or replace trigger trg_change_customer_prepcharge
  before insert or update or delete on customerprepcharge
  for each row
declare
  -- TRIGGER trg_change_customer_prepcharge version 0.2
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'CUSTOMERPREPCHARGE', fp_fieldname, lv_insert_update_delete,
           'CUSTOMERPREPCHARGE_ID', :new.customerprepcharge_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'CUSTOMERPREPCHARGE', fp_fieldname, lv_insert_update_delete,
           'CUSTOMERPREPCHARGE_ID', :old.customerprepcharge_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      --check for changes
      if nvl(to_char(:new.customerprepcharge_id), 'NULL') <>
         nvl(to_char(:old.customerprepcharge_id), 'NULL') then
        begin
          insert_changes('CUSTOMERPREPCHARGE_ID', :old.customerprepcharge_id,
                         :new.customerprepcharge_id);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.price), 'NULL') <> nvl(to_char(:old.price), 'NULL') then
        begin
          insert_changes('PRICE', :old.price, :new.price);
        end;
      end if;
      if nvl(to_char(:new.startdate), 'NULL') <> nvl(to_char(:old.startdate), 'NULL') then
        begin
          insert_changes('STARTDATE', to_char(:old.startdate, 'dd-mm-yyyy'),
                         to_char(:new.startdate, 'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.reasoncode_id), 'NULL') <> nvl(to_char(:old.reasoncode_id), 'NULL') then
        begin
          insert_changes('REASONCODE_ID', :old.reasoncode_id, :new.reasoncode_id);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
exception
  when dup_val_on_index then
    null; --no problem the change is already registered.
end trg_change_customer_prepcharge;
/

CREATE OR REPLACE TRIGGER trg_change_customer_routeinf
  before INSERT OR UPDATE OR DELETE on customerrouteinfo
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --Added customer_id in key for extra info.. not really part of key, thats only DELIVERYPOINT_ID
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'CUSTOMERROUTEINFO', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :new.customer_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'CUSTOMERROUTEINFO', fp_fieldname, lv_insert_update_delete,
           'CUSTOMER_ID', :old.customer_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.routedescription), 'NULL') <> nvl(to_char(:old.routedescription), 'NULL') then
        begin
          insert_changes('ROUTEDESCRIPTION', :old.routedescription, :new.routedescription);
        end;
      end if;
      ---cannot check changes to BLOB!
      ---if nvl(to_char(:new.ROUTEMAP),'NULL') <>  nvl(to_char(:old.ROUTEMAP),'NULL') then begin  insert_changes('ROUTEMAP', :old.ROUTEMAP,:new.ROUTEMAP ); end; end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :new.customer_id, :old.customer_id);
    end;
  end if;
end trg_change_customer_routeinf;
/

CREATE OR REPLACE TRIGGER trg_change_customer_routestop
  before INSERT OR UPDATE OR DELETE on routestop
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('U', 'I') then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, unique_id_field2, unique_id_value2, old_value,
           new_value)
        values
          (:new.customer_id, :new.systemuser_id, sysdate, 'ROUTESTOP', fp_fieldname,
           lv_insert_update_delete, 'ROUTESTOP_ID', :new.routestop_id, 'ROUTE_ID', :new.route_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'));
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, systemuser_id, timestamp, tablename, fieldname, insert_update_delete,
           unique_id_field1, unique_id_value1, unique_id_field2, unique_id_value2, old_value,
           new_value)
        values
          (:old.customer_id, :old.systemuser_id, sysdate, 'ROUTESTOP', fp_fieldname,
           lv_insert_update_delete, 'ROUTESTOP_ID', :old.routestop_id, 'ROUTE_ID', :old.route_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'));
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if; --check for changes
      if nvl(to_char(:new.routestop_id), 'NULL') <> nvl(to_char(:old.routestop_id), 'NULL') then
        begin
          insert_changes('ROUTESTOP_ID', :old.routestop_id, :new.routestop_id);
        end;
      end if;
      if nvl(to_char(:new.route_id), 'NULL') <> nvl(to_char(:old.route_id), 'NULL') then
        begin
          insert_changes('ROUTE_ID', :old.route_id, :new.route_id);
        end;
      end if;
      if nvl(to_char(:new.stopnumber), 'NULL') <> nvl(to_char(:old.stopnumber), 'NULL') then
        begin
          insert_changes('STOPNUMBER', :old.stopnumber, :new.stopnumber);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.contactperson_id), 'NULL') <> nvl(to_char(:old.contactperson_id), 'NULL') then
        begin
          insert_changes('CONTACTPERSON_ID', :old.contactperson_id, :new.contactperson_id);
        end;
      end if;
      if nvl(to_char(:new.deliverypoint_id), 'NULL') <> nvl(to_char(:old.deliverypoint_id), 'NULL') then
        begin
          insert_changes('DELIVERYPOINT_ID', :old.deliverypoint_id, :new.deliverypoint_id);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.soiltickets), 'NULL') <> nvl(to_char(:old.soiltickets), 'NULL') then
        begin
          insert_changes('SOILTICKETS', :old.soiltickets, :new.soiltickets);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.returnroute_id), 'NULL') <> nvl(to_char(:old.returnroute_id), 'NULL') then
        begin
          insert_changes('RETURNROUTE_ID', :old.returnroute_id, :new.returnroute_id);
        end;
      end if;
      if nvl(to_char(:new.stoptype), 'NULL') <> nvl(to_char(:old.stoptype), 'NULL') then
        begin
          insert_changes('STOPTYPE', :old.stoptype, :new.stoptype);
        end;
      end if;
      if nvl(to_char(:new.travelminutes), 'NULL') <> nvl(to_char(:old.travelminutes), 'NULL') then
        begin
          insert_changes('TRAVELMINUTES', :old.travelminutes, :new.travelminutes);
        end;
      end if;
      if nvl(to_char(:new.serviceminutes), 'NULL') <> nvl(to_char(:old.serviceminutes), 'NULL') then
        begin
          insert_changes('SERVICEMINUTES', :old.serviceminutes, :new.serviceminutes);
        end;
      end if;
      if nvl(to_char(:new.specificsortbatchdefinition_id), 'NULL') <>
         nvl(to_char(:old.specificsortbatchdefinition_id), 'NULL') then
        begin
          insert_changes('SPECIFICSORTBATCHDEFINITION_ID', :old.specificsortbatchdefinition_id,
                         :new.specificsortbatchdefinition_id);
        end;
      end if;
      if nvl(to_char(:new.expectedsortpercentage), 'NULL') <>
         nvl(to_char(:old.expectedsortpercentage), 'NULL') then
        begin
          insert_changes('EXPECTEDSORTPERCENTAGE', :old.expectedsortpercentage,
                         :new.expectedsortpercentage);
        end;
      end if;
      if nvl(to_char(:new.containerno), 'NULL') <> nvl(to_char(:old.containerno), 'NULL') then
        begin
          insert_changes('CONTAINERNO', :old.containerno, :new.containerno);
        end;
      end if;
      if nvl(to_char(:new.chargedeliveryfee), 'NULL') <>
         nvl(to_char(:old.chargedeliveryfee), 'NULL') then
        begin
          insert_changes('CHARGEDELIVERYFEE', :old.chargedeliveryfee, :new.chargedeliveryfee);
        end;
      end if;
      if nvl(to_char(:new.instructionsstartdate), 'NULL') <>
         nvl(to_char(:old.instructionsstartdate), 'NULL') then
        begin
          insert_changes('INSTRUCTIONSSTARTDATE', to_char(:old.instructionsstartdate,'dd-mm-yyyy'),
                         to_char(:new.instructionsstartdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.instructionsenddate), 'NULL') <>
         nvl(to_char(:old.instructionsenddate), 'NULL') then
        begin
          insert_changes('INSTRUCTIONSENDDATE', to_char(:old.instructionsenddate,'dd-mm-yyyy'),  to_char(:new.instructionsenddate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.dateactive), 'NULL') <> nvl(to_char(:old.dateactive), 'NULL') then
        begin
          insert_changes('DATEACTIVE', to_char(:old.dateactive,'dd-mm-yyyy'), to_char(:new.dateactive,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.dateinactive), 'NULL') <> nvl(to_char(:old.dateinactive), 'NULL') then
        begin
          insert_changes('DATEINACTIVE',to_char( :old.dateinactive,'dd-mm-yyyy'), to_char(:new.dateinactive,'dd-mm-yyyy'));
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_routestop;
/

CREATE OR REPLACE TRIGGER trg_change_customer_templ
  before INSERT OR UPDATE OR DELETE on emblemtemplate
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'EMBLEMTEMPLATE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATE_ID', :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'EMBLEMTEMPLATE', fp_fieldname, lv_insert_update_delete, 'v',
           :old.emblemtemplate_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      --check for changes
      if nvl(to_char(:new.emblemtemplate_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplate_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATE_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.code), 'NULL') <> nvl(to_char(:old.code), 'NULL') then
        begin
          insert_changes('CODE', :old.code, :new.code);
        end;
      end if;
      if nvl(to_char(:new.description), 'NULL') <> nvl(to_char(:old.description), 'NULL') then
        begin
          insert_changes('DESCRIPTION', :old.description, :new.description);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.printnamelabel), 'NULL') <> nvl(to_char(:old.printnamelabel), 'NULL') then
        begin
          insert_changes('PRINTNAMELABEL', :old.printnamelabel, :new.printnamelabel);
        end;
      end if;
      if nvl(to_char(:new.active), 'NULL') <> nvl(to_char(:old.active), 'NULL') then
        begin
          insert_changes('ACTIVE', :old.active, :new.active);
        end;
      end if;
      if nvl(to_char(:new.rentemblem), 'NULL') <> nvl(to_char(:old.rentemblem), 'NULL') then
        begin
          insert_changes('RENTEMBLEM', :old.rentemblem, :new.rentemblem);
        end;
      end if;
      if nvl(to_char(:new.embroidery), 'NULL') <> nvl(to_char(:old.embroidery), 'NULL') then
        begin
          insert_changes('EMBROIDERY', :old.embroidery, :new.embroidery);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
    end;
  end if;
end trg_change_customer_templ;
/

CREATE OR REPLACE TRIGGER trg_change_customer_templinepr
  before INSERT OR UPDATE OR DELETE on emblemtemplatelineprice
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  lv_customerid           customer.customer_id%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATELINEPRICE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATELINEPRICE_ID', :new.emblemtemplatelineprice_id, 'EMBLEMTEMPLATELINE_ID',
           :new.emblemtemplateline_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATELINEPRICE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATELINEPRICE_ID', :old.emblemtemplatelineprice_id, 'EMBLEMTEMPLATELINE_ID',
           :new.emblemtemplateline_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  begin
    select et.customer_id
    into   lv_customerid
    from   emblemtemplate et, emblemtemplateline etl
    where  et.emblemtemplate_id = etl.emblemtemplate_id
    and    etl.emblemtemplateline_id = :new.emblemtemplateline_id;
  exception
    when no_data_found then
      lv_customerid := null;
  end;
  if (updating or inserting) and lv_customerid is not null then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.emblemtemplatelineprice_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplatelineprice_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATELINEPRICE_ID', :old.emblemtemplatelineprice_id,
                         :new.emblemtemplatelineprice_id);
        end;
      end if;
      if nvl(to_char(:new.emblemtemplateline_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplateline_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATELINE_ID', :old.emblemtemplateline_id,
                         :new.emblemtemplateline_id);
        end;
      end if;
      if nvl(to_char(:new.price), 'NULL') <> nvl(to_char(:old.price), 'NULL') then
        begin
          insert_changes('PRICE', :old.price, :new.price);
        end;
      end if;
      if nvl(to_char(:new.startdate), 'NULL') <> nvl(to_char(:old.startdate), 'NULL') then
        begin
          insert_changes('STARTDATE', to_char(:old.startdate,'dd-mm-yyyy'), to_char(:new.startdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting and lv_customerid is not null then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.emblemtemplateline_id, :new.emblemtemplateline_id);
    end;
  end if;
end trg_change_customer_templinepr;
/

CREATE OR REPLACE TRIGGER trg_change_customer_templline
  before INSERT OR UPDATE OR DELETE on emblemtemplateline
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  lv_customerid           customer.customer_id%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATELINE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATELINE_ID', :new.emblemtemplateline_id, 'EMBLEMTEMPLATE_ID',
           :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATELINE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATELINE_ID', :old.emblemtemplateline_id, 'EMBLEMTEMPLATE_ID',
           :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  begin
    select et.customer_id
    into   lv_customerid
    from   emblemtemplate et
    where  et.emblemtemplate_id = :new.emblemtemplate_id;
  exception
    when no_data_found then
      lv_customerid := null;
  end;
  if (updating or inserting) and lv_customerid is not null then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.emblemtemplateline_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplateline_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATELINE_ID', :old.emblemtemplateline_id,
                         :new.emblemtemplateline_id);
        end;
      end if;
      if nvl(to_char(:new.emblemtemplate_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplate_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATE_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
        end;
      end if;
      if nvl(to_char(:new.product_id), 'NULL') <> nvl(to_char(:old.product_id), 'NULL') then
        begin
          insert_changes('PRODUCT_ID', :old.product_id, :new.product_id);
        end;
      end if;
      if nvl(to_char(:new.sizedefinition_id), 'NULL') <>
         nvl(to_char(:old.sizedefinition_id), 'NULL') then
        begin
          insert_changes('SIZEDEFINITION_ID', :old.sizedefinition_id, :new.sizedefinition_id);
        end;
      end if;
      if nvl(to_char(:new.description), 'NULL') <> nvl(to_char(:old.description), 'NULL') then
        begin
          insert_changes('DESCRIPTION', :old.description, :new.description);
        end;
      end if;
      if nvl(to_char(:new.textcolor_id), 'NULL') <> nvl(to_char(:old.textcolor_id), 'NULL') then
        begin
          insert_changes('TEXTCOLOR_ID', :old.textcolor_id, :new.textcolor_id);
        end;
      end if;
      if nvl(to_char(:new.bordercolor_id), 'NULL') <> nvl(to_char(:old.bordercolor_id), 'NULL') then
        begin
          insert_changes('BORDERCOLOR_ID', :old.bordercolor_id, :new.bordercolor_id);
        end;
      end if;
      if nvl(to_char(:new.bkgcolor_id), 'NULL') <> nvl(to_char(:old.bkgcolor_id), 'NULL') then
        begin
          insert_changes('BKGCOLOR_ID', :old.bkgcolor_id, :new.bkgcolor_id);
        end;
      end if;
      if nvl(to_char(:new.fabric_id), 'NULL') <> nvl(to_char(:old.fabric_id), 'NULL') then
        begin
          insert_changes('FABRIC_ID', :old.fabric_id, :new.fabric_id);
        end;
      end if;
      if nvl(to_char(:new.placement_id), 'NULL') <> nvl(to_char(:old.placement_id), 'NULL') then
        begin
          insert_changes('PLACEMENT_ID', :old.placement_id, :new.placement_id);
        end;
      end if;
      if nvl(to_char(:new.emblemtype), 'NULL') <> nvl(to_char(:old.emblemtype), 'NULL') then
        begin
          insert_changes('EMBLEMTYPE', :old.emblemtype, :new.emblemtype);
        end;
      end if;
      if nvl(to_char(:new.attachmentby), 'NULL') <> nvl(to_char(:old.attachmentby), 'NULL') then
        begin
          insert_changes('ATTACHMENTBY', :old.attachmentby, :new.attachmentby);
        end;
      end if;
      if nvl(to_char(:new.qtypergarment), 'NULL') <> nvl(to_char(:old.qtypergarment), 'NULL') then
        begin
          insert_changes('QTYPERGARMENT', :old.qtypergarment, :new.qtypergarment);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
      if nvl(to_char(:new.emblemimage_id), 'NULL') <> nvl(to_char(:old.emblemimage_id), 'NULL') then
        begin
          insert_changes('EMBLEMIMAGE_ID', :old.emblemimage_id, :new.emblemimage_id);
        end;
      end if;
      if nvl(to_char(:new.placementimage_id), 'NULL') <>
         nvl(to_char(:old.placementimage_id), 'NULL') then
        begin
          insert_changes('PLACEMENTIMAGE_ID', :old.placementimage_id, :new.placementimage_id);
        end;
      end if;
      if nvl(to_char(:new.emblemfont_id), 'NULL') <> nvl(to_char(:old.emblemfont_id), 'NULL') then
        begin
          insert_changes('EMBLEMFONT_ID', :old.emblemfont_id, :new.emblemfont_id);
        end;
      end if;
      if nvl(to_char(:new.fontsize), 'NULL') <> nvl(to_char(:old.fontsize), 'NULL') then
        begin
          insert_changes('FONTSIZE', :old.fontsize, :new.fontsize);
        end;
      end if;
      if nvl(to_char(:new.embroideryfilepathoriginal), 'NULL') <>
         nvl(to_char(:old.embroideryfilepathoriginal), 'NULL') then
        begin
          insert_changes('EMBROIDERYFILEPATHORIGINAL', :old.embroideryfilepathoriginal,
                         :new.embroideryfilepathoriginal);
        end;
      end if;
      if nvl(to_char(:new.embroideryfilepathproduction), 'NULL') <>
         nvl(to_char(:old.embroideryfilepathproduction), 'NULL') then
        begin
          insert_changes('EMBROIDERYFILEPATHPRODUCTION', :old.embroideryfilepathproduction,
                         :new.embroideryfilepathproduction);
        end;
      end if;
      if nvl(to_char(:new.stitchcount), 'NULL') <> nvl(to_char(:old.stitchcount), 'NULL') then
        begin
          insert_changes('STITCHCOUNT', :old.stitchcount, :new.stitchcount);
        end;
      end if;
      if nvl(to_char(:new.setupfee), 'NULL') <> nvl(to_char(:old.setupfee), 'NULL') then
        begin
          insert_changes('SETUPFEE', :old.setupfee, :new.setupfee);
        end;
      end if;
      if nvl(to_char(:new.colorpalette), 'NULL') <> nvl(to_char(:old.colorpalette), 'NULL') then
        begin
          insert_changes('COLORPALETTE', :old.colorpalette, :new.colorpalette);
        end;
      end if;
      if nvl(to_char(:new.embroiderylettering), 'NULL') <>
         nvl(to_char(:old.embroiderylettering), 'NULL') then
        begin
          insert_changes('EMBROIDERYLETTERING', :old.embroiderylettering, :new.embroiderylettering);
        end;
      end if;
      if nvl(to_char(:new.embroideryletteringline1), 'NULL') <>
         nvl(to_char(:old.embroideryletteringline1), 'NULL') then
        begin
          insert_changes('EMBROIDERYLETTERINGLINE1', :old.embroideryletteringline1,
                         :new.embroideryletteringline1);
        end;
      end if;
      if nvl(to_char(:new.embroideryletteringline2), 'NULL') <>
         nvl(to_char(:old.embroideryletteringline2), 'NULL') then
        begin
          insert_changes('EMBROIDERYLETTERINGLINE2', :old.embroideryletteringline2,
                         :new.embroideryletteringline2);
        end;
      end if;
      if nvl(to_char(:new.embroideryletteringline3), 'NULL') <>
         nvl(to_char(:old.embroideryletteringline3), 'NULL') then
        begin
          insert_changes('EMBROIDERYLETTERINGLINE3', :old.embroideryletteringline3,
                         :new.embroideryletteringline3);
        end;
      end if;
    end;
  elsif deleting and lv_customerid is not null then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.emblemtemplateline_id, :new.emblemtemplateline_id);
    end;
  end if;
end trg_change_customer_templline;
/

CREATE OR REPLACE TRIGGER trg_change_customer_templpchrg
  before INSERT OR UPDATE OR DELETE on emblemtemplateprepcharge
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  lv_customerid           customer.customer_id%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATEPREPCHARGE', fp_fieldname,
           lv_insert_update_delete, 'EMBLEMTEMPLATEPREPCHARGE_ID', :new.emblemtemplateprepcharge_id,
           'EMBLEMTEMPLATE_ID', :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATEPREPCHARGE', fp_fieldname,
           lv_insert_update_delete, 'EMBLEMTEMPLATEPREPCHARGE_ID', :old.emblemtemplateprepcharge_id,
           'EMBLEMTEMPLATE_ID', :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'),
           nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  begin
    select et.customer_id
    into   lv_customerid
    from   emblemtemplate et
    where  et.emblemtemplate_id = :new.emblemtemplate_id;
  exception
    when no_data_found then
      lv_customerid := null;
  end;
  if (updating or inserting) and lv_customerid is not null then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.emblemtemplateprepcharge_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplateprepcharge_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATEPREPCHARGE_ID', :old.emblemtemplateprepcharge_id,
                         :new.emblemtemplateprepcharge_id);
        end;
      end if;
      if nvl(to_char(:new.emblemtemplate_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplate_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATE_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
        end;
      end if;
      if nvl(to_char(:new.price), 'NULL') <> nvl(to_char(:old.price), 'NULL') then
        begin
          insert_changes('PRICE', :old.price, :new.price);
        end;
      end if;
      if nvl(to_char(:new.startdate), 'NULL') <> nvl(to_char(:old.startdate), 'NULL') then
        begin
          insert_changes('STARTDATE', to_char(:old.startdate,'dd-mm-yyyy'), to_char(:new.startdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting and lv_customerid is not null then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
    end;
  end if;
end trg_change_customer_templpchrg;
/

CREATE OR REPLACE TRIGGER trg_change_customer_templprice
  before INSERT OR UPDATE OR DELETE on emblemtemplateprice
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  lv_customerid           customer.customer_id%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATEPRICE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATEPRICE_ID', :new.emblemtemplateprice_id, 'EMBLEMTEMPLATE_ID',
           :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, unique_id_field2, unique_id_value2, old_value, new_value, systemuser_id)
        values
          (lv_customerid, sysdate, 'EMBLEMTEMPLATEPRICE', fp_fieldname, lv_insert_update_delete,
           'EMBLEMTEMPLATEPRICE_ID', :old.emblemtemplateprice_id, 'EMBLEMTEMPLATE_ID',
           :new.emblemtemplate_id, nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'),
           :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  begin
    select et.customer_id
    into   lv_customerid
    from   emblemtemplate et
    where  et.emblemtemplate_id = :new.emblemtemplate_id;
  exception
    when no_data_found then
      lv_customerid := null;
  end;
  if (updating or inserting) and lv_customerid is not null then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.emblemtemplateprice_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplateprice_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATEPRICE_ID', :old.emblemtemplateprice_id,
                         :new.emblemtemplateprice_id);
        end;
      end if;
      if nvl(to_char(:new.emblemtemplate_id), 'NULL') <>
         nvl(to_char(:old.emblemtemplate_id), 'NULL') then
        begin
          insert_changes('EMBLEMTEMPLATE_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
        end;
      end if;
      if nvl(to_char(:new.startdate), 'NULL') <> nvl(to_char(:old.startdate), 'NULL') then
        begin
          insert_changes('STARTDATE', to_char(:old.startdate,'dd-mm-yyyy'), to_char(:new.startdate,'dd-mm-yyyy'));
        end;
      end if;
      if nvl(to_char(:new.price), 'NULL') <> nvl(to_char(:old.price), 'NULL') then
        begin
          insert_changes('PRICE', :old.price, :new.price);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting and lv_customerid is not null then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :old.emblemtemplate_id, :new.emblemtemplate_id);
    end;
  end if;
end trg_change_customer_templprice;
/

CREATE OR REPLACE TRIGGER trg_change_customer_tmpgrtstp
  before INSERT OR UPDATE OR DELETE on temporarygarmentrentstop
  for each row
declare
  --internal variable
  lv_insert_update_delete changes_customer.insert_update_delete%type;
  --internal procedure
  procedure insert_changes(fp_fieldname in varchar2,
                           fp_old_value in varchar2,
                           fp_new_value in varchar2) is
  begin
    --Added customer_id in key for extra info.. not really part of key, thats only DELIVERYPOINT_ID
    if lv_insert_update_delete in ('I', 'U') then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:new.customer_id, sysdate, 'TEMPORARYGARMENTRENTSTOP', fp_fieldname,
           lv_insert_update_delete, 'TEMPORARYGARMENTRENTSTOP_ID', :new.temporarygarmentrentstop_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :new.systemuser_id);
      end;
    elsif lv_insert_update_delete = 'D' then
      begin
        insert into changes_customer
          (customer_id, timestamp, tablename, fieldname, insert_update_delete, unique_id_field1,
           unique_id_value1, old_value, new_value, systemuser_id)
        values
          (:old.customer_id, sysdate, 'TEMPORARYGARMENTRENTSTOP', fp_fieldname,
           lv_insert_update_delete, 'TEMPORARYGARMENTRENTSTOP_ID', :old.temporarygarmentrentstop_id,
           nvl(fp_old_value, 'NULL'), nvl(fp_new_value, 'NULL'), :old.systemuser_id);
      end;
    end if;
  end insert_changes;
begin
  --determine lv_insert_update_delete value
  if updating or inserting then
    begin
      if inserting then
        lv_insert_update_delete := 'I';
      else
        lv_insert_update_delete := 'U';
      end if;
      if nvl(to_char(:new.temporarygarmentrentstop_id), 'NULL') <>
         nvl(to_char(:old.temporarygarmentrentstop_id), 'NULL') then
        begin
          insert_changes('TEMPORARYGARMENTRENTSTOP_ID', :old.temporarygarmentrentstop_id,
                         :new.temporarygarmentrentstop_id);
        end;
      end if;
      if nvl(to_char(:new.customer_id), 'NULL') <> nvl(to_char(:old.customer_id), 'NULL') then
        begin
          insert_changes('CUSTOMER_ID', :old.customer_id, :new.customer_id);
        end;
      end if;
      if nvl(to_char(:new.startyear), 'NULL') <> nvl(to_char(:old.startyear), 'NULL') then
        begin
          insert_changes('STARTYEAR', :old.startyear, :new.startyear);
        end;
      end if;
      if nvl(to_char(:new.startweek), 'NULL') <> nvl(to_char(:old.startweek), 'NULL') then
        begin
          insert_changes('STARTWEEK', :old.startweek, :new.startweek);
        end;
      end if;
      if nvl(to_char(:new.endyear), 'NULL') <> nvl(to_char(:old.endyear), 'NULL') then
        begin
          insert_changes('ENDYEAR', :old.endyear, :new.endyear);
        end;
      end if;
      if nvl(to_char(:new.endweek), 'NULL') <> nvl(to_char(:old.endweek), 'NULL') then
        begin
          insert_changes('ENDWEEK', :old.endweek, :new.endweek);
        end;
      end if;
      if nvl(to_char(:new.numberweeks), 'NULL') <> nvl(to_char(:old.numberweeks), 'NULL') then
        begin
          insert_changes('NUMBERWEEKS', :old.numberweeks, :new.numberweeks);
        end;
      end if;
      if nvl(to_char(:new.systemuser_id), 'NULL') <> nvl(to_char(:old.systemuser_id), 'NULL') then
        begin
          insert_changes('SYSTEMUSER_ID', :old.systemuser_id, :new.systemuser_id);
        end;
      end if;
      if nvl(to_char(:new.timestamp), 'NULL') <> nvl(to_char(:old.timestamp), 'NULL') then
        begin
          insert_changes('TIMESTAMP', :old.timestamp, :new.timestamp);
        end;
      end if;
    end;
  elsif deleting then
    begin
      lv_insert_update_delete := 'D';
      insert_changes('CUSTOMER_ID', :new.customer_id, :old.customer_id);
    end;
  end if;
end trg_change_customer_tmpgrtstp;
/

create or replace trigger trg_invoiceline
  before update on invoiceline
  for each row
  when (nvl (old.adjustmentreason_id, 0) <> nvl (new.adjustmentreason_id, 0)
        or (old.adjustmentreason_id is not null and old.adjustedamount <> new.adjustedamount)
        or (old.adjustmentreason_id is not null and old.adjustmentbilledqty <> new.adjustmentbilledqty))
begin
  --trigger trg_invoiceline version 0.2
  insert into invoicelineadjusted
    (invoiceline_id, systemuser_id, timestamp)
  values
    (:new.invoiceline_id, :new.systemuser_id, :new.timestamp);
exception
  when dup_val_on_index then
    begin
      update invoicelineadjusted ila
      set    ila.systemuser_id = :new.systemuser_id, ila.timestamp = :new.timestamp
      where  ila.invoiceline_id = :new.invoiceline_id;
    end;
end trg_invoiceline;
/

create or replace trigger TRG_LOGGINGSYSTEMUSER_AUJ
  after insert or update on SYSTEMUSER
  for each row
begin
  if :new.LASTLOGINTIMESTAMP <> :old.LASTLOGINTIMESTAMP then
      insert into LOGGINGSYSTEMUSER
        (SYSTEMUSER_ID, USERNAME, LASTLOGINTIMESTAMP, LASTLOGOUTTIMESTAMP, timestamp)
      values
        (:new.SYSTEMUSER_ID, :new.USERNAME, :new.LASTLOGINTIMESTAMP, '' , :new.TIMESTAMP);
  end if;
  if :new.LASTLOGOUTTIMESTAMP <> :old.LASTLOGOUTTIMESTAMP then
    update LOGGINGSYSTEMUSER S
         set S.LASTLOGOUTTIMESTAMP = :NEW.LASTLOGOUTTIMESTAMP
       where S.LASTLOGINTIMESTAMP = :NEW.LASTLOGINTIMESTAMP
       and S.SYSTEMUSER_ID = :NEW.SYSTEMUSER_ID;
  end if;
end TRG_LOGGINGSYSTEMUSER_AUJ;
/

create or replace trigger trg_recalc_avg_purchaseprice
  before insert on stockvalueavgpp
  for each row
declare
  m_totalonstock number;
begin
  --Determine the current qty on stock 
  select nvl(sum(sq.qtyunique + sq.qtyuniquewithmodifications + sq.qtynonunique), 0)
  into   m_totalonstock
  from   stockreservationpergrade srg
  join   stockdefinitionperitem sdi
  on     sdi.stockdefinitionperitem_id = srg.stockdefinitionperitem_id
  join   stockquantity sq
  on     sq.stockreservationpergrade_id = srg.stockreservationpergrade_id
  where  sdi.product_id = :new.product_link_id
  and    sdi.sizedefinition_id = :new.sizedefinition_link_id
  and    (sdi.customer_id = :new.customer_link_id or
        (sdi.customer_id is null and :new.customer_link_id is null))
  and    srg.qualitygrade_id = :new.qualitygrade_id;
 case when :new.transactiontype=3 then
     if m_totalonstock > 0 then
      :new.actualstockquantity:=m_totalonstock;
      :new.prevstockqty:=m_totalonstock;
      end if;
 else
      --Calculate the new avgpurchaseprice
  if m_totalonstock > 0 then
    :new.avgpurchaseprice := ((:new.quantity * :new.piecevalue) +
                           --  (m_totalonstock * :new.avgpurchaseprice)) / m_totalonstock;
                              ((m_totalonstock-:new.quantity)  * :new.prevavgpurchaseprice)) / m_totalonstock;
  :new.actualstockquantity:=m_totalonstock;
  :new.prevstockqty:=m_totalonstock-:new.quantity;

 end if;
 end case;
end trg_recalc_avg_purchaseprice;
/

create or replace trigger trg_workstation_prefix_2n
  before insert or update on workstation
  for each row
  when (new.automaticaddprefix <> 'N')
/*trigger trg_workstation_prefix version 0.1*/
begin
  :new.automaticaddprefix := 'N';
end trg_workstation_prefix_2n;
/

create or replace view v_adjustmentverif_auj as
select '1' pr, bu.code businessunitCode, bu.description businessunitDescription
, ih.invoicedate, ro.routeNumber, ro.description routeDescription, ih.deltocustomernumber
, ih.deltocustomername, ih.invoicenumber, il.linenumber, ilp.wearernumber, ilt.type invoicelinetype
, (select iltd.description from invoicelinetype_desc iltd where iltd.invoicelinetype_id = ilt.invoicelinetype_id
  and iltd.language_id = lan.language_id) invoicelineTypeDesc
, il.description invoicelineDesc, il.code invoicelineCode, rc.code adjustmentCode
, (select rcd.description from reasoncode_desc rcd where rcd.reasoncode_id = rc.reasoncode_id
  and rcd.language_id = lan.language_id) adjustmentDesc
, il.adjustedamount, il.amount, il.adjustmentbilledqty, il.price, il.adjustedprice
, cur.code currencyCode, cur.invoiceamountdecimals, lan.code languageCode
, (select d.code from district d where ro.district_id = d.district_id) districtcode
, (select e.employeenumber from employee e where ro.routemanager_id = e.employee_id) routemanagernr
, ih.route_id, il.timestamp chtimestamp, il.taxgroupcode
, suil.username chuser
, (select tg.code from turnovergroup tg where tg.turnovergroup_id = il.turnovergroup_id) turnovergroup_code
, (select tgd.description from turnovergroup_desc tgd where tgd.turnovergroup_id = il.turnovergroup_id
   and tgd.language_id = lan.language_id) turnovergroup_desc
, trunc(coalesce(ilad.timestamp, il.timestamp)) DateInputted, coalesce(sua.username, suil.username) user_name
, coalesce(sua.fullname, suil.fullname) user_fullname, coalesce(sua.active, suil.active) user_active
, ih.billtocustomernumber, ih.billtocustomername
, (select ma.customernumber from customer ma, customer bill where bill.customer_id = ih.billtocustomer_link_id and ma.customer_id = bill.masteraccount_id) masteracctnumber
, (select pb.customernumber from customer pb, invoiceheaderextrainfo ihextr where ihextr.invoiceheader_id = ih.invoiceheader_id and pb.customer_id = ihextr.paybycustomer_link_id) paybynumber
, (select coc.customernumber from customer coc, customer del where del.customer_id = ih.deltocustomer_link_id and coc.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commonnumber
from
  invoiceline il
  left outer join invoicelineproduct ilp on il.invoiceline_id = ilp.invoiceline_id
  left outer join invoicelineadjusted ilad 
       inner join systemuser sua on ilad.systemuser_id = sua.systemuser_id
  on il.invoiceline_id = ilad.invoiceline_id
  inner join systemuser suil on il.systemuser_id = suil.systemuser_id
  inner join invoicelinetype ilt on il.invoicelinetype_id = ilt.invoicelinetype_id
  inner join reasoncode rc on il.adjustmentreason_id = rc.reasoncode_id
  inner join invoiceheader ih
        left outer join route ro on ih.route_id = ro.route_id and ro.active = 'Y'
        inner join businessunit bu on ih.invoicebusinessunit_id = bu.businessunit_id
        inner join currency cur on ih.currency_id = cur.currency_id
        inner join status sta on ih.status_id = sta.status_id and sta.statustype = 'IN'
  on il.invoiceheader_id = ih.invoiceheader_id
, languages lan
union 
select '2' pr, bu.code businessunitCode, bu.description businessunitDescription
, ih.invoicedate, ro.routeNumber, ro.description routeDescription, ih.deltocustomernumber
, ih.deltocustomername, ih.invoicenumber, il.linenumber, ilp.wearernumber, ilt.type invoicelinetype
, (select iltd.description from invoicelinetype_desc iltd where iltd.invoicelinetype_id = ilt.invoicelinetype_id
  and iltd.language_id = lan.language_id) invoicelineTypeDesc
, il.description invoicelineDesc, il.code invoicelineCode, rc.code adjustmentCode
, (select rcd.description from reasoncode_desc rcd where rcd.reasoncode_id = rc.reasoncode_id
   and rcd.language_id = lan.language_id) adjustmentDesc
, 0 adjustedamount, 0 amount, ila.quantity adjustmentbilledqty, il.price, il.adjustedprice
, cur.code currencyCode, cur.invoiceamountdecimals, lan.code languageCode
, (select d.code from district d where ro.district_id = d.district_id) districtcode
, (select e.employeenumber from employee e where ro.routemanager_id = e.employee_id) routemanagernr
, ih.route_id, ila.timestamp chtimestamp, il.taxgroupcode
, (select suil.username from systemuser suil where suil.systemuser_id = il.systemuser_id) chuser
, (select tg.code from turnovergroup tg where tg.turnovergroup_id = il.turnovergroup_id) turnovergroup_code
, (select tgd.description from turnovergroup_desc tgd where tgd.turnovergroup_id = il.turnovergroup_id
   and tgd.language_id = lan.language_id) turnovergroup_desc
, trunc(coalesce(ilad.timestamp, il.timestamp)) DateInputted, coalesce(sua.username, suila.username) user_name
, coalesce(sua.fullname, suila.fullname) user_fullname, coalesce(sua.active, suila.active) user_active
, ih.billtocustomernumber, ih.billtocustomername
, (select ma.customernumber from customer ma, customer bill where bill.customer_id = ih.billtocustomer_link_id and ma.customer_id = bill.masteraccount_id) masteracctnumber
, (select pb.customernumber from customer pb, invoiceheaderextrainfo ihextr where ihextr.invoiceheader_id = ih.invoiceheader_id and pb.customer_id = ihextr.paybycustomer_link_id) paybynumber
, (select coc.customernumber from customer coc, customer del where del.customer_id = ih.deltocustomer_link_id and coc.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commonnumber
from
  invoiceline il
  left outer join invoicelineadjusted ilad 
       inner join systemuser sua on ilad.systemuser_id = sua.systemuser_id
  on il.invoiceline_id = ilad.invoiceline_id  
  inner join invoicelineproduct ilp on il.invoiceline_id = ilp.invoiceline_id
  inner join invoicelinetype ilt on il.invoicelinetype_id = ilt.invoicelinetype_id
  inner join invoicelineadjust ila 
        inner join reasoncode rc on ila.reasoncode_id = rc.reasoncode_id 
        inner join systemuser suila on ila.systemuser_id = suila.systemuser_id
  on il.invoiceline_id = ila.invoiceline_id
  inner join invoiceheader ih
        left outer join route ro on ih.route_id = ro.route_id and ro.active = 'Y'
        inner join businessunit bu on ih.invoicebusinessunit_id = bu.businessunit_id
        inner join currency cur on ih.currency_id = cur.currency_id
        inner join status sta on ih.status_id = sta.status_id and sta.statustype = 'IN'
  on il.invoiceheader_id = ih.invoiceheader_id
, languages lan
/
create or replace view v_auj_artransactions as
select --view v_auj_artransactions version 1.00
 x.exportstatus,
 x.businessunitcode,
 x.legalentitycode,
 x.bill2businessunitcode,
 x.bill2legalentitycode,
 x.billto_customer,
 x.billto_name,
 x.deltobusinessunitcode,
 x.deltolegalentitycode,
 x.customernumber,
 x.name,
 x.artransactiondate,
 x.invoicedate,
 x.invoicenumber,
 x.currency,
 x.amount,
 x.debitcredit,
 nvl(x.original_paymenttype, x.paymenttype) paymenttype,
 x.artransactiontype,
 x.artransactiontype_code,
 x.artransactiontype_desc,
 x.remitidentification,
 x.remark,
 x.turnovergroup,
 x.legacycode,
 x.maxaccountnumber,
 x.artransaction_legacycode,
 x.creditedinv,
 x.creditinv_date,
 case
   when x.debitcredit = 'C' then
    nvl(x.original_paymenttype, x.paymenttype)
   else
    null
 end credit_paymenttype,
 case
   when x.debitcredit = 'D' then
    nvl(x.original_paymenttype, x.paymenttype)
   else
    null
 end debit_paymenttype,
 x.artransaction_id,
 x.transactiondate,
 x.origin,
 x.paymentreference
  from (select a.exportstatus,
               bu.code businessunitcode,
               le.code legalentitycode,
               bu_bil2.code bill2businessunitcode,
               le_bil2.code bill2legalentitycode,
               billto.customernumber billto_customer,
               billto.name billto_name,
               bu_delto.code deltobusinessunitcode,
               le_delto.code deltolegalentitycode,
               delto.customernumber,
               delto.name,
               a.artransactiondate,
               ih.invoicedate,
               a.invoicenumber,
               cu.code currency,
               nvl(ad.amount, a.amount) amount,
               a.debitcredit,
               case a.debitcredit
                 when 'C' then
                  case a.paymenttype
                    when 0 then
                     'Cash'
                    when 1 then
                     'Check'
                    when 2 then
                     'Credit card'
                    when 3 then
                     'EFT'
                    when 4 then
                     'EDI'
                    when 5 then
                     'Acceptgiro'
                    when 6 then
                     'Automatic collection'
                    when 7 then
                     'Pay-by customer'
                    when 8 then
                     'Credit Card Portal'
                    when 11 then
                     'Schedule Credit Card'
                    when 12 then
                     'Schedule ACH Payment'
                    when 13 then
                     'ACH Payment'
                    else
                     'Not applicable'
                  end
                 else
                  case a.paymenttype
                    when 0 then
                     'COD'
                    when 1 then
                     'Charge'
                    else
                     'Not applicable'
                  end
               end paymenttype,
               att.typenumber artransactiontype,
               att.code artransactiontype_code,
               nvl(atd.description, att.factorydescription) artransactiontype_desc,
               a.remitidentification,
               case when a.debitcredit='C' and a.origin=17
                 then nvl(a.remark,'Payment by route')
                 else a.remark
               end remark,
               tg.code turnovergroup,
               att.legacycode,
               lx.accountnumber maxaccountnumber,
               att.legacycode artransaction_legacycode,
               ihc.invoicenumber creditedinv,
               ihc.invoicedate creditinv_date,
               case oa.debitcredit
                 when 'C' then
                  case oa.paymenttype
                    when 0 then
                     'Cash'
                    when 1 then
                     'Check'
                    when 2 then
                     'Credit card'
                    when 3 then
                     'EFT'
                    when 4 then
                     'EDI'
                    when 5 then
                     'Acceptgiro'
                    when 6 then
                     'Automatic collection'
                    when 7 then
                     'Pay-by customer'
                    when 8 then
                     'Credit Card Portal'
                    when 11 then
                     'Schedule Credit Card'
                    when 12 then
                     'Schedule ACH Payment'
                    when 13 then
                     'ACH Payment'
                    else
                     'Not applicable'
                  end
                 else
                  case oa.paymenttype
                    when 0 then
                     'COD'
                    when 1 then
                     'Charge'
                    else
                     'Not applicable'
                  end
               end original_paymenttype,
               a.artransaction_id,
               case
                 when a.artransactiontype_id = 1 and ih.invoicetype <> 2 then
                  ih.invoicedate
                 when a.artransactiontype_id = 1 and ih.invoicetype = 2 then
                  ih.creationtimestamp
                 when a.artransactiontype_id = 9 and
                      a.remitidentification = 'Settlement' then
                  ih.finalizationtimestamp
                 when a.origin = 17 then
                  nvl(ih.finalizationtimestamp, a.artransactiondate)
                 when a.origin = 3 and a.remark = 'Payment by route' then
                  ih.finalizationtimestamp
                 else
                  a.artransactiondate
               end transactiondate,
               a.origin,
               a.paymentreference
          from artransaction a
          join businessunit bu
            on bu.businessunit_id = a.businessunit_id
          left outer join legalentity le
            on le.legalentity_id = bu.legalentity_id
          join customer billto
            on billto.customer_id = a.billtocustomer_link_id
          join businessunit bu_bil2
            on bu_bil2.businessunit_id = billto.defaultinvoicebusinessunit_id
          left outer join legalentity le_bil2
            on le_bil2.legalentity_id = bu.legalentity_id
          join artransactiontype att
            on att.artransactiontype_id = a.artransactiontype_id
          join currency cu
            on cu.currency_id = a.currency_id
          left outer join invoiceheader ih
            on ih.invoiceheader_id = a.invoiceheader_id
          left outer join invoiceheader ihc
            on ihc.invoiceheader_id = ih.creditedinvoiceheader_id
          left outer join artransactiontype_desc atd
            on (atd.artransactiontype_id = a.artransactiontype_id and
               atd.language_id = billto.language_id)
          left outer join(customer delto
          join businessunit bu_delto
            on bu_delto.businessunit_id = delto.defaultinvoicebusinessunit_id
          left outer join legalentity le_delto
            on le_delto.legalentity_id = bu_delto.legalentity_id) on delto.customer_id = a.deltocustomer_link_id
          left outer join(artransactiondetail ad
          join turnovergroup tg
            on tg.turnovergroup_id = ad.turnovergroup_id) on ad.artransaction_id = a.artransaction_id
          left outer join (select lag.turnovergroup_id,
                                 max(la.accountnumber) accountnumber
                            from ledgeracctsperturnovergroup lag
                            join ledgeraccounts la
                              on la.ledgeraccounts_id =
                                 lag.ledgeraccounts_id
                           group by lag.turnovergroup_id) lx
            on lx.turnovergroup_id = ad.turnovergroup_id
          left outer join artransaction oa
            on oa.artransaction_id = a.originaltransaction_id) x
/
create or replace view v_auj_scans_inout as
select /*view v_auj_scans_inout version 0.1*/
 bu.code businessunitcode, s.transactiontype_id, trunc(s.scantimestamp) scandate,
 count(1) numberofscans
from   scan s
join   businessunit bu
on     bu.businessunit_id = s.businessunit_id
where  s.transactiontype_id in (1, 2)
and    trunc(s.issuedate) <> trunc(s.scantimestamp)
group  by bu.code, s.transactiontype_id, trunc(s.scantimestamp)
/
CREATE OR REPLACE VIEW V_CUSTOMERAUDITREPORTS AS
select --customer audit version 3.0
       0 linetype, trunc(cc.timestamp) timestamp_date, cc.timestamp, cu1.customernumber, -1 wearernumber, bu.code BU_code, sa.code SalesArea_Code
, (select min(ro.routenumber) from route ro, routestop rs where rs.customer_id = cu1.customer_id and rs.route_id = ro.route_id
  and rs.dateactive <= trunc(sysdate) and rs.dateinactive > trunc(sysdate)) routenumber
 , (select rtrim (xmlagg (xmlelement (e, cdd.day_id || ',')).extract ('//text()'), ',')
--, (select ListAgg(cdd.day_id,',') WITHIN GROUP (order by cdd.day_id)
from CUSTOMERDELIVERYDAY cdd where cu1.customer_id = cdd.customer_id  and cdd.deliverytype='B')
--and cdd.typeofmerchadise = 1)--*/'InOracle11gR2'
BillingDays
, cu1.name CustomerName, cu1.cocnumber
, f_changes_description(cc.TABLENAME, cc.fieldname,lan.language_id) fieldname
, f_changes_value(cc.TABLENAME, cc.fieldname, cc.old_value) old_value
, f_changes_value(cc.TABLENAME, cc.fieldname, cc.new_value) new_value
--,cc.fieldname
--, cc.old_value
--, cc.new_value
, su.username, su.systemuser_id
, case when (select count(*) from department dep where dep.customer_id = cu1.customer_id) > 1 then -1
  else coalesce((select dep.departmentnumber from department dep where dep.customer_id = cu1.customer_id), -1)
    end departmentnumber
, cc.unique_id_field1, cc.unique_id_value1, cc.unique_id_field2, cc.unique_id_value2, cc.tablename
, ' ' reasoncode_code
, ' ' ProductRanking
, -1 AllowReturnToStock
, ' ' ProductCodeBefore
, ' ' ProductCodeAfter
, ' ' ProductDescBefore
, ' ' ProductDescAfter
, ' ' SizeCodeBefore
, ' ' SizeCodeAfter
, ' ' FinMethBefore
, ' ' FinMethAfter
, -1 Price
, -1 PriceAfter
, ' ' Modification_code
, ' ' DelSchemeCodeBefore
, ' ' DelSchemeCodeAfter
, ' ' DelSchemeDescBefore
, ' ' DelSchemeDescAfter
, ' ' ChangedBillingDay
, lan.code Language_Code, curr.systemuser_id currentuser_id
, ' ' oldFULLNAME
, ' ' newFULLNAME
, ' ' oldSEARCHNAME
,' ' newsearchname
, cr.fieldtab
, cr.fieldsort
, null searchname, null fullname, null changedate, null insert_update_delete,
null old_we_dateactive,
null new_we_dateactive,
null old_we_dateinactive,
null  new_we_dateinactive,
null  old_wi_dateactive,
null  new_wi_dateactive,
null old_wi_dateinactive,
null  new_wi_dateinactive,
null  old_wi_changesperweek,
null  new_wi_changesperweek,
null  old_wi_maxinventory,
null new_wi_maxinventory,
null we_remark,
null wo_remark,
null new_wi_temprentstop_start,
null new_wi_temprentstop_end,
'-' wi_productcode
,'-'wi_finishingmethod
,'-' wi_sizecode
, 0 maxinventory
, 0 changesperweek
, null temporaryrentstopstartdate
, null temporaryrentstopenddate
, null bm
, null oldprice
, null newprice
, null modi_before
, null modi_after
, null unval1
, null chanval
,0 old_amount
,0 new_amount
,0 old_day_id
,0 new_day_id
,' ' old_dateactive
,' ' new_dateactive
,' ' old_dateinactive
,' ' new_dateinactive
,0 old_fixedrentqty
,0 new_fixedrentqty
,0 old_freeqtyfreq
,0 new_freeqtyfreq
,0 old_qty_freeofcharge
,0 new_qty_freeofcharge
,' ' old_temp_rst_enddate
,' ' new_temp_rst_enddate
,' ' old_temp_rst_startdate
,' ' new_temp_rst_startdate
,0  old_amount_std
,0  new_amount_std
,0 old_st_freq
,0 new_st_freq
,null wo_workorder_id
, null wo_workordernumber
, null wo_reasoncode
, null wo_reasoncode_desc
, null wo_entrydate
, null wo_neededdate
, (select cl.customermarkinggarment from customer cl where cl.customer_id=cu1.customer_id) custnameonlabel
, null FinMethBeforeDesc
, null FinMethAfterDesc
, null FinMethDesc
, null ProductDesc
, null oldcustomernumber
, null oldwearernumber
, null inventorymove
, null unique_id_value4
, null newcustomernumber
, null newwearernumber
from changes_customer cc, customer cu1, businessunit bu, salesarea sa, systemuser su, languages lan, systemuser curr
,changes_reference cr
where cc.customer_id = cu1.customer_id and bu.businessunit_id = cu1.defaultbusinessunit_id
      and sa.salesarea_id = cu1.salesarea_id and su.systemuser_id = cc.systemuser_id
      AND EXISTS (SELECT * FROM businessunitsperusergroup bug WHERE bug.usergroup_id = curr.usergroup_id AND bug.businessunit_id = bu.businessunit_id)
      and cc.fieldname <> 'SYSTEMUSER_ID' and cc.fieldname <> 'TIMESTAMP'
and cr.tablename=cc.tablename
and cr.fieldname=cc.fieldname
and cr.fieldshowrep=1
union all --wearers audit
select 1 linetype, cw.change_date timestamp_date
, cw.change_timestamp timestamp, cu.customernumber,
 case when cw.change_type='WI' and cw.IUD='MI' then cw.NEW_WEARERNUMBER
 else cw.OLD_WEARERNUMBER end WEARERNUMBER
 , bu.code BU_code, sa.code SalesArea_Code
, (select min(ro.routenumber) from route ro, routestop rs where rs.customer_id = cu.customer_id and rs.route_id = ro.route_id
  and rs.dateactive <= trunc(sysdate) and rs.dateinactive > trunc(sysdate)) routenumber
 , (select rtrim (xmlagg (xmlelement (e, cdd.day_id || ',')).extract ('//text()'), ',')
--, (select ListAgg(cdd.day_id,',') WITHIN GROUP (order by cdd.day_id)
from CUSTOMERDELIVERYDAY cdd where cu.customer_id = cdd.customer_id  and cdd.deliverytype='B')--and cdd.typeofmerchadise = 1)--*/'InOracle11gR2'
BillingDays
, cu.name CustomerName, cu.cocnumber
--, cw.fieldname, cw.old_value, cw.new_value
--, f_changes_description(cw.TABLENAME, cw.fieldname)
,'-' fieldname
--, f_changes_value(cw.TABLENAME, cw.fieldname, cw.old_value)
, null old_value
--, f_changes_value(cw.TABLENAME, cw.fieldname, cw.new_value)
, null new_value
 , su.username, su.systemuser_id
, case when (select count(*) from department dep where dep.customer_id = cu.customer_id) > 1 then -1
  else coalesce((select dep.departmentnumber from department dep where dep.customer_id = cu.customer_id), -1)
    end departmentnumber
,' ' unique_id_field1, 0 unique_id_value1, ' ' unique_id_field2, 0 unique_id_value2, ' ' tablename
,' ' reasoncode_code
, (select pra.ranking from product pr, ProductRanking pra
       where pr.product_id = nvl(cw.OLD_PRODUCT_ID,cw.NEW_PRODUCT_ID) and pra.productranking_id = pr.productranking_id )
  ProductRanking
, (select max(plpc.allowreturntostock) from productlistpercustomer plpc
       where plpc.product_id = nvl(cw.OLD_PRODUCT_ID,cw.NEW_PRODUCT_ID) and plpc.customer_id = cu.customer_id and (nvl(cw.OLD_SIZEDEFINITION_ID,cw.NEW_SIZEDEFINITION_ID)=plpc.sizedefinition_id
       or plpc.sizedefinition_id=(select sd.sizedefinition_id from sizedefinition sd where sd.code='*')) and nvl(cw.OLD_FINISHINGMETHOD_ID,cw.NEW_FINISHINGMETHOD_ID)=plpc.finishingmethod_id
       )
   AllowReturnToStock
,(select p.code from product p where p.product_id=cw.OLD_PRODUCT_ID)ProductCodeBefore
,(select p.code from product p where p.product_id=cw.NEW_PRODUCT_ID)ProductCodeAfter
, (select prd.description from product_desc prd
       where prd.product_id = cw.OLD_PRODUCT_ID and prd.language_id = lan.language_id)
   ProductDescBefore
, (select prd.description from product_desc prd
       where prd.product_id = cw.NEW_PRODUCT_ID and prd.language_id = lan.language_id)
    ProductDescAfter
,(select sd.code from sizedefinition sd where sd.sizedefinition_id=cw.OLD_SIZEDEFINITION_ID) SizeCodeBefore
,(select sd.code from sizedefinition sd where sd.sizedefinition_id=cw.NEW_SIZEDEFINITION_ID) SizeCodeAfter
,(select fm.code from finishingmethod fm where fm.finishingmethod_id=cw.OLD_FINISHINGMETHOD_ID) FinMethBefore
,(select fm.code from finishingmethod fm where fm.finishingmethod_id=cw.NEW_FINISHINGMETHOD_ID)    FinMethAfter
/*,case when (select max(plpc.billingmethod) from productlistpercustomer plpc
       where plpc.product_id = wi.product_id and plpc.customer_id = cw.customer_id and (wi.sizedefinition_id=plpc.sizedefinition_id
       or plpc.sizedefinition_id=(select sd.sizedefinition_id from sizedefinition sd where sd.code='*')) and wi.finishingmethod_id=plpc.finishingmethod_id
       ) =1 then pack_price.Rent_Price(cw.customer_id, wi.product_id, wi.sizedefinition_id, wi.finishingmethod_id, cw.changedate, wi.changesperweek)
 else
   pack_price.Rent_Price(cw.customer_id, wi.product_id, wi.sizedefinition_id, wi.finishingmethod_id, cw.changedate)
end
*/
, -1 price
, -1 PriceAfter
, '-'Modification_code
, ' ' DelSchemeCodeBefore
, ' ' DelSchemeCodeAfter
, ' ' DelSchemeDescBefore
, ' ' DelSchemeDescAfter
, ' ' ChangedBillingDay
, lan.code Language_Code, curr.systemuser_id currentuser_id
,cw.OLD_FULLNAME oldfullname
,cw.NEW_FULLNAME newfullname
,cw.OLD_SEARCHNAME oldsearchname
,cw.NEW_SEARCHNAME newsearchname
, 0 fieldtab
, 0 fieldsort
--,nvl(cw.NEW_SEARCHNAME,cw.OLD_SEARCHNAME) searchname, nvl(cw.NEW_FULLNAME,cw.OLD_FULLNAME) fullname, trunc(cw.change_timestamp) changedate,cw.iud, -- cw.insert_update_delete,
,w.searchname, w.fullname, trunc(cw.change_timestamp) changedate,cw.iud,
to_char(cw.old_wearerdateactive,'mm/dd/yyyy') old_we_dateactive,
to_char(cw.new_wearerdateactive,'mm/dd/yyyy') new_we_dateactive,
to_char(cw.old_wearerdateinactive,'mm/dd/yyyy') old_we_dateinactive,
to_char(cw.new_wearerdateinactive,'mm/dd/yyyy') new_we_dateinactive,
to_char(cw.OLD_DATEACTIVE,'mm/dd/yyyy') old_wi_dateactive,
to_char(cw.NEW_DATEACTIVE,'mm/dd/yyyy') new_wi_dateactive,
to_char(cw.OLD_DATEINACTIVE,'mm/dd/yyyy') old_wi_dateinactive,
to_char(cw.NEW_DATEINACTIVE,'mm/dd/yyyy') new_wi_dateinactive,
cw.OLD_CHANGESPERWEEK old_wi_changesperweek,
cw.NEW_CHANGESPERWEEK new_wi_changesperweek,
cw.OLD_MAXINVENTORY old_wi_maxinventory,
cw.NEW_MAXINVENTORY new_wi_maxinventory,
cw.NEW_wearerREMARK we_remark,
cw.NEW_WO_REMARK wo_remark,
to_char(cw.NEW_TEMPORARYRENTSTOPSTARTDATE,'mm/dd/yyyy') new_wi_temprentstop_start,
to_char(cw.NEW_TEMPORARYRENTSTOPENDDATE,'mm/dd/yyyy') new_wi_temprentstop_end,
null wi_productcode,
null wi_finishingmethod,
null wi_sizecode
, null maxinventory
, null changesperweek
, null temporaryrentstopstartdate
, null temporaryrentstopenddate
,(select max(plpc.billingmethod) from productlistpercustomer plpc
       where plpc.product_id = nvl(cw.OLD_PRODUCT_ID,cw.NEW_PRODUCT_ID) and plpc.customer_id = cu.customer_id and (nvl(cw.OLD_SIZEDEFINITION_ID,cw.new_sizedefinition_id)=plpc.sizedefinition_id
       or plpc.sizedefinition_id=(select sd.sizedefinition_id from sizedefinition sd where sd.code='*')) and nvl(cw.OLD_FINISHINGMETHOD_ID,cw.new_finishingmethod_id)=plpc.finishingmethod_id
       ) BM
,case when (select max(plpc.billingmethod) from productlistpercustomer plpc
       where plpc.product_id = cw.OLD_PRODUCT_ID and plpc.customer_id = cu.customer_id and (cw.OLD_SIZEDEFINITION_ID=plpc.sizedefinition_id
       or plpc.sizedefinition_id=(select sd.sizedefinition_id from sizedefinition sd where sd.code='*')) and cw.OLD_FINISHINGMETHOD_ID=plpc.finishingmethod_id
       ) =1 then
   pack_price.Rent_Price(cu.customer_id, cw.OLD_PRODUCT_ID, cw.OLD_SIZEDEFINITION_ID, cw.OLD_FINISHINGMETHOD_ID, cw.change_timestamp, cw.OLD_CHANGESPERWEEK)
else
  pack_price.Rent_Price(cu.customer_id, cw.OLD_PRODUCT_ID, cw.OLD_SIZEDEFINITION_ID, cw.OLD_FINISHINGMETHOD_ID, cw.change_timestamp)
end oldprice
,case when (select max(plpc.billingmethod) from productlistpercustomer plpc
       where plpc.product_id = cw.NEW_PRODUCT_ID and plpc.customer_id = cu.customer_id and (cw.NEW_SIZEDEFINITION_ID=plpc.sizedefinition_id
       or plpc.sizedefinition_id=(select sd.sizedefinition_id from sizedefinition sd where sd.code='*')) and cw.NEW_FINISHINGMETHOD_ID=plpc.finishingmethod_id
       ) =1 then pack_price.Rent_Price(cu.customer_id, cw.NEW_PRODUCT_ID, cw.NEW_SIZEDEFINITION_ID, cw.NEW_FINISHINGMETHOD_ID, cw.change_timestamp, cw.NEW_CHANGESPERWEEK)
 else
   pack_price.Rent_Price(cu.customer_id, cw.NEW_PRODUCT_ID, cw.NEW_SIZEDEFINITION_ID, cw.NEW_FINISHINGMETHOD_ID, cw.change_timestamp)
end newprice
,(select mo.code from modification mo where mo.modification_id= nvl(replace(cw.OLD_WM_MODIFICATION_ID,'NULL',null),cw.old_wwi_modification_id)) modi_before
,(select mo.code from modification mo where mo.modification_id= nvl(replace(cw.new_wm_modification_id,'NULL',null),cw.old_wwi_modification_id)) modi_after
, null unval1 --cw.unique_id_value1 unval1
, case when cw.change_type='WE' then 1
  when cw.change_type='WI' then 2
  --when cw.tablename='WORKORDER' then 3
  when cw.change_type='WO' then 3
  else 4
  end
  chanval
,0 old_amount
,0 new_amount
,0 old_day_id
,0 new_day_id
,' ' old_dateactive
,' ' new_dateactive
,' ' old_dateinactive
,' ' new_dateinactive
,0 old_fixedrentqty
,0 new_fixedrentqty
,0 old_freeqtyfreq
,0 new_freeqtyfreq
,0 old_qty_freeofcharge
,0 new_qty_freeofcharge
,' ' old_temp_rst_enddate
,' ' new_temp_rst_enddate
,' ' old_temp_rst_startdate
,' ' new_temp_rst_startdate
,0  old_amount_std
,0  new_amount_std
,0 old_st_freq
,0 new_st_freq
,replace(cw.new_wo_workorder_id,'NULL',null) wo_workorder_id
,replace(cw.new_wo_workordernumber,'NULL',null) wo_workordernumber
, (select rc.code from reasoncode rc where rc.reasoncode_id=to_number(replace(cw.new_wo_reasoncode_id,'NULL',null))) wo_reasoncode
, (select rcd.description from reasoncode_desc rcd where rcd.reasoncode_id=to_number(replace(cw.new_wo_reasoncode_id,'NULL',null)) and rcd.language_id=lan.language_id) wo_reasoncode_desc
,replace(cw.new_wo_entrydate,'NULL',null) wo_entrydate
,replace(cw.new_wo_neededdate,'NULL',null) wo_neededdate
, (select cl.customermarkinggarment from customer cl where cl.customer_id=cu.customer_id) custnameonlabel
,(select fmd.description from finishingmethod_desc fmd where fmd.finishingmethod_id=cw.OLD_FINISHINGMETHOD_ID and fmd.language_id=lan.language_id) FinMethBeforeDesc
,(select fmd.description from finishingmethod_desc fmd where fmd.finishingmethod_id=cw.NEW_FINISHINGMETHOD_ID and fmd.language_id=lan.language_id )    FinMethAfterDesc
, null  FinMethDesc
,-- (select prd.description from product_desc prd
   --    where prd.product_id = wi.product_id and prd.language_id = lan.language_id)
  null ProductDesc
, (select co.customernumber from customer co where cw.OLD_CUSTOMER_ID=co.customer_id) oldcustomernumber
, cw.OLD_WEARERNUMBER oldwearernumber
, 9 inventorymove
, null unique_id_value4
, (select cn.customernumber from customer cn where cw.NEW_CUSTOMER_ID=cn.customer_id) newcustomernumber
, cw.NEW_WEARERNUMBER newwearernumber
from --changes_wearer cw,
businessunit bu, salesarea sa, systemuser su,languages lan, systemuser curr
,v_customerauditreports_det_pa cw
,customer cu
, wearer w
--,customer c_old, wearer w_old, weareremployment we_old
where-- cw.changedate=to_date('28-02-2012','dd-mm-yyyy')
--and  wi.wearerinventory_id=cw.wearerinventoryid
--and
bu.businessunit_id = cu.defaultbusinessunit_id
and sa.salesarea_id = cu.salesarea_id and su.systemuser_id = cw.change_user_id
AND EXISTS (SELECT * FROM businessunitsperusergroup bug WHERE bug.usergroup_id = curr.usergroup_id AND bug.businessunit_id = bu.businessunit_id)
and cu.customer_id=cw.OLD_CUSTOMER_ID
and w.wearer_id=nvl(cw.NEW_WEARER_ID,cw.OLD_WEARER_ID)
--and curr.systemuser_id=1
and not(
-- changes in inventory excluded
(cw.change_type='WI'
and cw.OLD_MAXINVENTORY=cw.NEW_MAXINVENTORY
and cw.OLD_CHANGESPERWEEK=cw.NEW_CHANGESPERWEEK
and cw.OLD_CIRCINVENTORY<>cw.NEW_CIRCINVENTORY and cw.IUD='U'
and cw.NEW_DATEACTIVE=cw.OLD_DATEACTIVE)
--exclude changes in qty to be returned
or (cw.change_type='WI'
and cw.OLD_QTYTOBERETURNEDREPLACEMENT<>cw.NEW_QTYTOBERETURNEDREPLACEMENT
and cw.OLD_QTYTOBERETURNEDREPLACEMENT is not null)
  --or cw.OLD_QTYTOBERETURNEDDECREASEMAX<>cw.NEW_QTYTOBERETURNEDDECREASEMAX
or (cw.change_type='WI'
and cw.NEW_QTYTOBERETURNEDREPLACEMENT>0
and cw.OLD_CHANGESPERWEEK>CW.NEW_CHANGESPERWEEK
AND CW.NEW_CHANGESPERWEEK=0
AND CW.OLD_DATEINACTIVE=CW.NEW_DATEINACTIVE
and cw.OLD_QTYTOBERETURNEDREPLACEMENT<>cw.NEW_QTYTOBERETURNEDREPLACEMENT)
/*or (
cw.change_type='WI' and cw.OLD_MAXINVENTORY=cw.NEW_MAXINVENTORY
and cw.IUD='U'
and cw.OLD_MAXINVENTORY=0
and cw.OLD_QTYTOBERETURNEDREPLACEMENT=cw.NEW_QTYTOBERETURNEDREPLACEMENT
and cw.OLD_QTYTOBERETURNEDREPLACEMENT=cw.OLD_CIRCINVENTORY
and cw.NEW_QTYTOBERETURNEDREPLACEMENT=cw.NEW_CIRCINVENTORY
and cw.NEW_DATEINACTIVE<cw.OLD_DATEINACTIVE
)*/
)
union all --consumption point logistics audit
select 2 linetype, cp.changedate timestamp_date, cp.changedate, cu2.customernumber, -1 wearernumber, bu.code BU_code, sa.code SalesArea_Code
, (select min(ro.routenumber) from route ro, routestop rs where rs.customer_id = cu2.customer_id and rs.route_id = ro.route_id
  and rs.dateactive <= trunc(sysdate) and rs.dateinactive > trunc(sysdate)) routenumber
 , (select rtrim (xmlagg (xmlelement (e, cdd.day_id || ',')).extract ('//text()'), ',')
--, (select ListAgg(cdd.day_id,',') WITHIN GROUP (order by cdd.day_id)
from CUSTOMERDELIVERYDAY cdd where cu2.customer_id = cdd.customer_id  and cdd.deliverytype='B'
and cdd.typeofmerchadise = 1)--*/'InOracle11gR2'
BillingDays
, cu2.name CustomerName, cu2.cocnumber
/*, f_changes_description(cp.TABLENAME, cp.fieldname,lan.language_id) fieldname
, f_changes_value(cp.TABLENAME, cp.fieldname, cp.old_value) old_value
, f_changes_value(cp.TABLENAME, cp.fieldname, cp.new_value) new_value
*/
, ' ' fieldname
, ' ' old_value
, ' ' new_value
, su.username, su.systemuser_id
, case when (select count(*) from department dep where dep.customer_id = cu2.customer_id) > 1 then -1
  else coalesce((select dep.departmentnumber from department dep where dep.customer_id = cu2.customer_id), -1)
    end departmentnumber
, ' ' unique_id_field1, 0  unique_id_value1, ' ' unique_id_field2, 0 unique_id_value2, ' ' tablename
, ' ' reasoncode_code
, ' ' ProductRanking
, -1 AllowReturnToStock
, ' 'ProductCodeBefore
, (select pr.code from product pr where pr.product_id = cp.product_id) ProductCodeAfter
, ' ' ProductDescBefore
, (select prd.description from product_desc prd
       where prd.product_id = cp.product_id and prd.language_id = lan.language_id) ProductDescAfter
, ' ' SizeCodeBefore
, (select sd.code from sizedefinition sd where sd.sizedefinition_id = cp.sizedefinition_id) SizeCodeAfter
, ' ' FinMethBefore
, (select fm.code from finishingmethod fm where fm.finishingmethod_id = cp.finishingmethod_id) FinMethAfter
, pack_price.Rent_Price(cu2.customer_id, cp.product_id, cp.sizedefinition_id, cp.finishingmethod_id, cp.changedate,
  (select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.old_st_deliveryscheme_id,'NULL', null))) Price
, pack_price.Rent_Price(cu2.customer_id, cp.product_id, cp.sizedefinition_id, cp.finishingmethod_id, cp.changedate,
(select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.new_st_deliveryscheme_id,'NULL', null))) PriceAfter
, ' ' Modification_code
, (select substr(ds.code, 0, 2) from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.old_st_deliveryscheme_id,'NULL', null)) DelSchemeCodeBefore
, (select substr(ds.code, 0, 2) from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.new_st_deliveryscheme_id,'NULL', null)) DelSchemeCodeAfter
/*
, /*case when (cp.fieldname = 'DELIVERYSCHEME_ID' and cp.old_value <> 'NULL')
       then (select coalesce(substr(dd.description, -4, 4), dd.description) from deliveryscheme_desc dd where dd.deliveryscheme_id = castVarcharAsNumber(cp.old_value) and dd.language_id = lan.language_id)
  else ' '
  end */
,  ' '  DelSchemeDescBefore
/*, case when (cp.fieldname = 'DELIVERYSCHEME_ID' and cp.new_value <> 'NULL')
       then (select coalesce(substr(dd.description, -4, 4), dd.description) from deliveryscheme_desc dd where dd.deliveryscheme_id = castVarcharAsNumber(cp.new_value) and dd.language_id = lan.language_id)
  else ' '
  end  */
,  ' ' DelSchemeDescAfter
/*, case when (cp.tablename = 'STANDARDDELIVERYAMOUNT' and cp.insert_update_delete='I' and cp.fieldname = 'DAY_ID' and cp.new_value <> 'NULL')
       then (select dad.description from day_desc dad where dad.day_id = castVarcharAsNumber(cp.new_value) and dad.language_id = lan.language_id)
  else ' '
  end */
,  ' ' ChangedBillingDay
, lan.code Language_Code, curr.systemuser_id currentuser_id
 ,' ' oldFULLNAME
, ' ' newFULLNAME
, ' ' oldSEARCHNAME
,' ' newsearchname
, 0 fieldtab
, 0 fieldsort
, null searchname, null fullname, null changedate, null insert_update_delete,
null old_we_dateactive,
null new_we_dateactive,
null old_we_dateinactive,
null  new_we_dateinactive,
null  old_wi_dateactive,
null  new_wi_dateactive,
null old_wi_dateinactive,
null  new_wi_dateinactive,
null  old_wi_changesperweek,
null  new_wi_changesperweek,
null  old_wi_maxinventory,
null new_wi_maxinventory,
null we_remark,
null wo_remark,
null new_wi_temprentstop_start,
null new_wi_temprentstop_end,
'-' wi_productcode
,'-'wi_finishingmethod
,'-' wi_sizecode
, 0 maxinventory
, 0 changesperweek
, null temporaryrentstopstartdate
, null temporaryrentstopenddate
, null bm
, null oldprice
, null newprice
, null modi_before
, null modi_after
, null unval1
, null chanval
,to_number(replace (cp.OLD_ST_AMOUNT,'NULL',null)) old_amount
,to_number(replace (cp.NEW_ST_AMOUNT,'NULL',null)) new_amount
,to_number(replace (cp.OLD_ST_DAY_ID,'NULL',null)) old_day_id
,to_number(replace (cp.NEW_ST_DAY_ID,'NULL',null)) new_day_id
,replace (cp.OLD_ST_DATEACTIVE,'NULL',null) old_dateactive
,replace (cp.NEW_ST_DATEACTIVE,'NULL',null) new_dateactive
,replace (cp.OLD_ST_DATEINACTIVE,'NULL',null) old_dateinactive
,replace (cp.NEW_ST_DATEINACTIVE,'NULL',null) new_dateinactive
,to_number(replace (cp.OLD_ST_FIXEDRENTQUANTITY,'NULL',null)) old_fixedrentqty
,to_number(replace (cp.NEW_ST_FIXEDRENTQUANTITY,'NULL',null))  new_fixedrentqty
,to_number(replace (cp.OLD_ST_FREEQTYFREQUENCY,'NULL',null)) old_freeqtyfreq
,to_number(replace (cp.NEW_ST_FREEQTYFREQUENCY,'NULL',null)) new_freeqtyfreq
,to_number(replace (cp.OLD_ST_QTYFREEOFCHARGE,'NULL',null)) old_qty_freeofcharge
,to_number(replace (cp.NEW_ST_QTYFREEOFCHARGE,'NULL',null)) new_qty_freeofcharge
,replace (cp.OLD_TE_ENDDATE,'NULL',null) old_temp_rst_enddate
,replace (cp.NEW_TE_ENDDATE,'NULL',null) new_temp_rst_enddate
,replace (cp.OLD_TE_STARTDATE,'NULL',null) old_temp_rst_startdate
,replace (cp.OLD_TE_STARTDATE,'NULL',null) new_temp_rst_startdate
,(to_number(replace (cp.OLD_ST_FIXEDRENTQUANTITY,'NULL',null)) --old_fixedrentqty
*  pack_price.Rent_Price(cu2.customer_id, cp.product_id, cp.sizedefinition_id, cp.finishingmethod_id, cp.changedate,
  (select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.old_st_deliveryscheme_id,'NULL', null)))
  --Price
  ) old_amount_std
,(to_number(replace (cp.NEW_ST_FIXEDRENTQUANTITY,'NULL',null))  --new_fixedrentqty
 * pack_price.Rent_Price(cu2.customer_id, cp.product_id, cp.sizedefinition_id, cp.finishingmethod_id, cp.changedate,
(select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.new_st_deliveryscheme_id,'NULL', null)))
--PriceAfter
) new_amount_std
,(select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.old_st_deliveryscheme_id,'NULL', null)) old_st_freq
,(select ds.frequency from deliveryscheme ds where ds.deliveryscheme_id = replace(cp.new_st_deliveryscheme_id,'NULL', null)) new_st_freq
,null wo_workorder_id
, null wo_workordernumber
, null wo_reasoncode
, null wo_reasoncode_desc
, null wo_entrydate
, null wo_neededdate
, (select cl.customermarkinggarment from customer cl where cl.customer_id=cu2.customer_id) custnameonlabel
, null FinMethBeforeDesc
, null FinMethAfterDesc
, null FinMethDesc
, null ProductDesc
, null oldcustomernumber
, null oldwearernumber
, null inventorymove
, null unique_id_value4
, null newcustomernumber
, null newwearernumber
from v_changes_plpd cp, customer cu2, businessunit bu, salesarea sa, systemuser su
, languages lan, systemuser curr
where cp.customer_id = cu2.customer_id and bu.businessunit_id = cu2.defaultbusinessunit_id
      and sa.salesarea_id = cu2.salesarea_id and su.systemuser_id = cp.systemuser_id
      AND EXISTS (SELECT * FROM businessunitsperusergroup bug WHERE bug.usergroup_id = curr.usergroup_id AND bug.businessunit_id = bu.businessunit_id)
/

create or replace view v_invoiceheader_auj as
select /*version 2.0*/
       1 linetype, rp.reportparam_id, rp.copy_number, ih.invoicedate, ih.invoiceyear, ih.invoiceweek, ih.invoicedaynumber, ih.invoicenumber,
       ih.documenttype, ibu.code invoicebusinessunitcode, ibu.description invoicebusinessunitdesc, ih.billtocustomernumber, ih.billtocustomername,
       ih.extraname1, ih.extraname2, ih.deltocustomernumber, ih.deltocustomername, ih.startweek, ih.endweek, ih.startmonth, ih.endmonth, ih.startyear,
       ih.endyear, ih.city, ih.county, ih.state, ih.zipcode, ih.street2, ih.street, ih.routenumber, ih.stopnumber, ih.depotcode, ih.contactpersonname,
       ih.contactpersonphone, ih.emailstatus, ih.emailaddress, ih.realcollectiontype, ih.originalcollectiontype, ih.invoicetype, ih.exported, ih.contractcode,
       case when ih.purchaseorder is null or ih.purchaseorder = 'Multiple' 
         then (select listagg(X.referencenumber, ', ') within group(order by X.workordernumber)
                 from (select distinct wo.workordernumber, wo.referencenumber
                         from packingnoteline pnl
                         join garmentsaleshistory gsh on pnl.packingnoteline_id = gsh.packingnoteline_id
                         join workorderline wol on gsh.workorderline_id = wol.workorderline_id
                         join workorder wo on wol.workorder_id = wo.workorder_id
                        where pnl.invoiceheader_id = ih.invoiceheader_id) X)
         else ih.purchaseorder end purchaseorder, ih.deliverinstructions, ih.invoicecomments, ih.totalminusadjustment, ih.totalplusadjustment, ih.cashcollected, ih.paythisamount,
       ih.prebillamount, ih.invoicefrequency_id invoicefrequencynumber, cur.code currencycode, cur.description currencydesc, s.statustype,
       s.code statuscode, s.factorydescription statusfactorydescription, pl.code plantcode, pl.name plantname, pad.street plantstreet,
       pad.street2 plantstreet2, pad.zipcode plantzipcode, pad.city plantcity, pad.state plantstate, pad.county plantcounty, pl.phoneno plantphone,
       pl.faxno plantfax, pl.website plantwebsite, pl.email plantemail, ih.city billto_city, ih.street billto_street, ih.street2 billto_street2,
       ih.state billto_state, ih.zipcode billto_zipcode, ih.routecontrol_id, ih.adjustmentreason_id, ih.systemuser_id, ih.timestamp, ih.invoiceheader_id,
       ih.creditsqueezeamount, cur.invoiceamountdecimals, cur.description currencydescription, ih.totalamountexclvat, cur.decimals, ih.startdate,
       ih.enddate, ihextr.billtocountrydescription, ihextr.deltocountrydescription, ihextr.deltocustvatnumber, ihextr.customermarkinggarment,
       ihextr.taxable, ihextr.siccode, ihextr.invoicecopies, cast(fsget_custdeliveryscheme(ih.route_id, ih.deltocustomer_link_id) as varchar2(6)) custdeliveryscheme,
       cast(fsget_cust_delivery_days(ih.deltocustomer_link_id) as varchar2(7)) cust_delivery_days, ihextr.attachinvoicecopies,
       ihextr.paymenttermsdescription paymentterms_desc, ihextr.formlayoutcode invoicelayoutcode, ibu.code default_bu_code,
       (select rtes.soiltickets
           from routestop rtes
          where rtes.route_id = ih.route_id
            and rtes.stopnumber = ih.stopnumber
            and rtes.customer_id = ih.deltocustomer_link_id) no_of_soiltickets, rc.code adjustment_reasoncode,
       getsortusasc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_asc,
       getsortusdesc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_desc, 
       ih.splitupcode, ih.splitupdescription, ihs.personidentification, ihs.signature,
       cast(fsget_min_5_yearweeks(ih.invoiceheader_id, ih.invoicefrequency_id) as varchar2(39)) min_year_weeks, ih.parentinvoiceheader_id,
       ih.contractstartdate, ih.contractenddate, ihextr.bankaccount, ihextr.ibanno, cbank.idcode cust_bank_idcode, cbank.description cust_bank_desc,
       cbank.internalidcode cust_bank_internid, cbank.laundrybankaccount cust_lndrybankaccount, cbank.ibanno cust_ibanno, lbank.idcode lndry_bank_idcode,
       lbank.description lndry_bank_desc, lbank.internalidcode lndry_bank_internid, lbank.laundrybankaccount lndry_bank_lndrybankaccount,
       lbank.ibanno lndry_bank_ibanno, ih.paymentdiscountdays, ih.creditsqueezeperc, ih.netpaymentdays, ih.deltostreet, ih.deltostreet2, ih.deltocounty,
       ih.deltocity, ih.deltozipcode, ih.deltostate, pco.description plantcountrydescription,
       (select ss.value
           from systemsetting ss
          where pl.plant_id = ss.plant_id
            and ss.name = 'WEIGHTUNIT') weightunit,
       (select max(ilv.percentage)
           from invoiceline il, invoicelinevarious ilv
          where il.invoiceheader_id = ih.invoiceheader_id
            and ilv.invoiceline_id = il.invoiceline_id
            and il.invoicelinetype_id = 18) max_percentage, 
       ih.roundingamount, ih.nextperiodstartdate, ih.nextperiodenddate, ih.nextperiodnoweeks,
       ihextr.discountdays, ihextr.paymentdiscount, ihextr.discountdays2, ihextr.paymentdiscount2,
       (select cast(ss1.value as numeric)
           from systemsetting ss1
          where pl.plant_id = ss1.plant_id
            and ss1.name = 'WEIGHTDECIMALSMANUALINPUT') weightdecimalsmanualinput,
       (select empl.name
           from routecontrol rcntrl, employee empl
          where rcntrl.routecontrol_id = ih.routecontrol_id
            and empl.employeenumber = rcntrl.drivernumber
            and empl.plant_id = rcntrl.plant_id) drivername,
       (case
         when (ihs.signature is null) then
          'N'
         else
          'Y'
       end) hassignature,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = pl.language_id) generalinv_remark_plant,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = del.language_id) generalinv_remark_customer, 
       pl.invoiceremarkstartdate, pl.invoiceremarkenddate, ibu.internalvatnumber, ibu.vatnumber,
       coalesce((select max(pa.packingnote_id)
                   from packingnote pa, packingnoteline pl
                  where pa.packingnote_id = pl.packingnote_id
                    and pl.invoiceheader_id = ih.invoiceheader_id
                    and ih.invoicefrequency_id = 0 and pa.origin = 5), 0) setspecial,
       (case
         when ih.cluster_id is null then
          (select max(c.code)
             from customerspercluster cpc, customercluster c
            where c.invoicefrequency_id = ih.invoicefrequency_id
              and cpc.cluster_id = c.cluster_id
              and cpc.customer_id = ih.billtocustomer_link_id)
         else
          (select cc.code from customercluster cc where cc.cluster_id = ih.cluster_id)
       end) clustercode, ihextr.paymenttermsduedate, ih.reference, ih.activityreference,
       (select com1.customernumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_nr,
       (select com1.name from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_name,
       (select com1.pnnumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_pnnumber,
       del.pnnumber delto_pnnumber, del.phoneno delto_phoneno, del.faxno delto_faxno, del.searchname delto_searchname, del.legalname delto_legalname,
       (select sa.code from salesarea sa where sa.salesarea_id = del.salesarea_id) salesarea_code,
       (select sad.description
           from salesarea_desc sad
          where sad.salesarea_id = del.salesarea_id
            and sad.language_id = pl.language_id) salesarea_desc,
       (select da.daynumber
           from route r, day da
          where ih.route_id = r.route_id
            and r.drivingday_id = da.day_id) drivingdaynr,
       (select listagg(dd.code, ',') within group(order by dd.day_id)
           from customerdeliveryday cdd, day_desc dd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.day_id = dd.day_id and cdd.typeofmerchadise = 1
            and dd.language_id = pl.language_id) drivingdaycode, del.customermarkinggarment delto_nameonlabel,
       (select ch.code
           from chain ch, customer bill
          where del.debtor_id = bill.customer_id
            and ch.chain_id = bill.chain_id) chain_code, 0 ar_balance,
       (select max(cbc.description)
           from customerbillingcomment cbc
          where cbc.customer_id = ih.billtocustomer_link_id
            and cbc.type = 1 and cbc.startdate <= ih.invoicedate
            and ih.invoicedate <= cbc.enddate) billtocomment,
       (select min(dep.departmentnumber) from department dep where dep.customer_id = del.customer_id) delto_depnr,
       (select min(cdd.day_id)
           from customerdeliveryday cdd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.typeofmerchadise = 1 and cdd.deliverytype = 'B') billingdaynr,
       (select ad.street || chr(13) || ad.street2
           from route r, depot depo join address ad on depo.address_id = ad.address_id
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depostreet,
       (select depo.phoneno
           from route r, depot depo
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depophoneno,
       (select depo2.faxno
           from route r, depot depo2
          where ih.route_id = r.route_id and r.depot_id = depo2.depot_id) depofaxno, 0 ar_balancepastdue,
       coalesce((select cpb.paymenttype from customer cpb where cpb.customer_id = ihextr.paybycustomer_link_id), ihextr.paymenttype) paymenttypepayby,
       ihextr.paymenttype
  from reportparam rp
  join invoiceheader ih on rp.number_value = ih.invoicenumber
       left join invoicesignature ihs on ih.invoiceheader_id = ihs.invoiceheader_id
       left join reasoncode rc on ih.adjustmentreason_id = rc.reasoncode_id
       left join customer del on ih.deltocustomer_link_id = del.customer_id
  join invoiceheaderextrainfo ihextr on ih.invoiceheader_id = ihextr.invoiceheader_id
       left join bankinstitution cbank on ihextr.bankinstitution_id = cbank.bankinstitution_id
       left join bankinstitution lbank on ihextr.laundrybankinstitution_id = lbank.bankinstitution_id
  join currency cur on ih.currency_id = cur.currency_id
  join businessunit ibu on ih.invoicebusinessunit_id = ibu.businessunit_id
  join status s on ih.status_id = s.status_id
  join plant pl on ibu.plant_id = pl.plant_id
  join address pad on pl.address_id = pad.address_id
  join country pco on pl.country_id = pco.country_id
 where ih.documenttype = 1
union all
select 2 linetype, rp.reportparam_id, rp.copy_number, ih.invoicedate, ih.invoiceyear, ih.invoiceweek, ih.invoicedaynumber, ih.invoicenumber,
       ih.documenttype, ibu.code invoicebusinessunitcode, ibu.description invoicebusinessunitdesc, ih.billtocustomernumber, ih.billtocustomername,
       ih.extraname1, ih.extraname2, ih.deltocustomernumber, ih.deltocustomername, ih.startweek, ih.endweek, ih.startmonth, ih.endmonth, ih.startyear,
       ih.endyear, ih.city, ih.county, ih.state, ih.zipcode, ih.street2, ih.street, ih.routenumber, ih.stopnumber, ih.depotcode, ih.contactpersonname,
       ih.contactpersonphone, ih.emailstatus, ih.emailaddress, ih.realcollectiontype, ih.originalcollectiontype, ih.invoicetype, ih.exported, ih.contractcode, 
       case when ih.purchaseorder is null or ih.purchaseorder = 'Multiple' 
         then (select listagg(X.referencenumber, ', ') within group(order by X.workordernumber)
                 from (select distinct wo.workordernumber, wo.referencenumber
                         from packingnoteline pnl
                         join garmentsaleshistory gsh on pnl.packingnoteline_id = gsh.packingnoteline_id
                         join workorderline wol on gsh.workorderline_id = wol.workorderline_id
                         join workorder wo on wol.workorder_id = wo.workorder_id
                        where pnl.invoiceheader_id = ih.invoiceheader_id) X)
         else ih.purchaseorder end purchaseorder, 
       ih.deliverinstructions, ih.invoicecomments, ih.totalminusadjustment, ih.totalplusadjustment, ih.cashcollected,
       ih.paythisamount, ih.prebillamount, ih.invoicefrequency_id invoicefrequencynumber, cur.code currencycode, cur.description currencydesc, s.statustype,
       s.code statuscode, s.factorydescription statusfactorydescription, pl.code plantcode, pl.name plantname, pad.street plantstreet,
       pad.street2 plantstreet2, pad.zipcode plantzipcode, pad.city plantcity, pad.state plantstate, pad.county plantcounty, pl.phoneno plantphone,
       pl.faxno plantfax, pl.website plantwebsite, pl.email plantemail, ih.city billto_city, ih.street billto_street, ih.street2 billto_street2,
       ih.state billto_state, ih.zipcode billto_zipcode, ih.routecontrol_id, ih.adjustmentreason_id, ih.systemuser_id, ih.timestamp, ih.invoiceheader_id,
       ih.creditsqueezeamount, cur.invoiceamountdecimals, cur.description currencydescription, ih.totalamountexclvat, cur.decimals, ih.startdate,
       ih.enddate, ihextr.billtocountrydescription, ihextr.deltocountrydescription, ihextr.deltocustvatnumber, ihextr.customermarkinggarment,
       ihextr.taxable, ihextr.siccode, ihextr.invoicecopies,
       cast(fsget_custdeliveryscheme(ih.route_id, ih.deltocustomer_link_id) as varchar2(6)) custdeliveryscheme,
       cast(fsget_cust_delivery_days(ih.deltocustomer_link_id) as varchar2(7)) cust_delivery_days, ihextr.attachinvoicecopies,
       ihextr.paymenttermsdescription paymentterms_desc, ihextr.formlayoutcode invoicelayoutcode, ibu.code default_bu_code,
       (select rtes.soiltickets
           from routestop rtes
          where rtes.route_id = ih.route_id
            and rtes.stopnumber = ih.stopnumber
            and rtes.customer_id = ih.deltocustomer_link_id) no_of_soiltickets, rc.code adjustment_reasoncode,
       getsortusasc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_asc,
       getsortusdesc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_desc, 
       ih.splitupcode, ih.splitupdescription, ihs.personidentification, ihs.signature,
       cast(fsget_min_5_yearweeks(ih.invoiceheader_id, ih.invoicefrequency_id) as varchar2(39)) min_year_weeks, ih.parentinvoiceheader_id,
       ih.contractstartdate, ih.contractenddate, ihextr.bankaccount, ihextr.ibanno, cbank.idcode cust_bank_idcode, cbank.description cust_bank_desc,
       cbank.internalidcode cust_bank_internid, cbank.laundrybankaccount cust_lndrybankaccount, cbank.ibanno cust_ibanno, lbank.idcode lndry_bank_idcode,
       lbank.description lndry_bank_desc, lbank.internalidcode lndry_bank_internid, lbank.laundrybankaccount lndry_bank_lndrybankaccount,
       lbank.ibanno lndry_bank_ibanno, ih.paymentdiscountdays, ih.creditsqueezeperc, ih.netpaymentdays, ih.deltostreet, ih.deltostreet2, ih.deltocounty,
       ih.deltocity, ih.deltozipcode, ih.deltostate, pco.description plantcountrydescription,
       (select ss.value
           from systemsetting ss
          where pl.plant_id = ss.plant_id
            and ss.name = 'WEIGHTUNIT') weightunit,
       (select max(ilv.percentage)
           from invoiceline il, invoicelinevarious ilv
          where il.invoiceheader_id = ih.invoiceheader_id
            and ilv.invoiceline_id = il.invoiceline_id
            and il.invoicelinetype_id = 18) max_percentage, 
       ih.roundingamount, ih.nextperiodstartdate, ih.nextperiodenddate, ih.nextperiodnoweeks,
       ihextr.discountdays, ihextr.paymentdiscount, ihextr.discountdays2, ihextr.paymentdiscount2,
       (select cast(ss1.value as numeric)
           from systemsetting ss1
          where pl.plant_id = ss1.plant_id
            and ss1.name = 'WEIGHTDECIMALSMANUALINPUT') weightdecimalsmanualinput,
       (select empl.name
           from routecontrol rcntrl, employee empl
          where rcntrl.routecontrol_id = ih.routecontrol_id
            and empl.employeenumber = rcntrl.drivernumber
            and empl.plant_id = rcntrl.plant_id) drivername,
       (case
          when (ihs.signature is null) then
           'N'
          else
           'Y'
        end) hassignature,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = pl.language_id) generalinv_remark_plant,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = del.language_id) generalinv_remark_customer, 
       pl.invoiceremarkstartdate, pl.invoiceremarkenddate, ibu.internalvatnumber, ibu.vatnumber,
       coalesce((select max(pa.packingnote_id)
                   from packingnote pa, packingnoteline pl
                  where pa.packingnote_id = pl.packingnote_id
                    and pl.invoiceheader_id = ih.invoiceheader_id
                    and ih.invoicefrequency_id = 0 and pa.origin = 5), 0) setspecial,
       (case
          when ih.cluster_id is null then
           (select max(c.code)
              from customerspercluster cpc, customercluster c
             where c.invoicefrequency_id = ih.invoicefrequency_id
               and cpc.cluster_id = c.cluster_id
               and cpc.customer_id = ih.billtocustomer_link_id)
          else
           (select cc.code from customercluster cc where cc.cluster_id = ih.cluster_id)
        end) clustercode, ihextr.paymenttermsduedate, ih.reference, ih.activityreference,
       (select com1.customernumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_nr,
       (select com1.name from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_name,
       (select com1.pnnumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_pnnumber,
       del.pnnumber delto_pnnumber, del.phoneno delto_phoneno, del.faxno delto_faxno, del.searchname delto_searchname, del.legalname delto_legalname,
       (select sa.code from salesarea sa where sa.salesarea_id = del.salesarea_id) salesarea_code,
       (select sad.description
           from salesarea_desc sad
          where sad.salesarea_id = del.salesarea_id
            and sad.language_id = pl.language_id) salesarea_desc,
       (select da.daynumber
           from route r, day da
          where ih.route_id = r.route_id
            and r.drivingday_id = da.day_id) drivingdaynr,
       (select listagg(dd.code, ',') within group(order by dd.day_id)
           from customerdeliveryday cdd, day_desc dd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.day_id = dd.day_id and cdd.typeofmerchadise = 1
            and dd.language_id = pl.language_id) drivingdaycode, del.customermarkinggarment delto_nameonlabel,
       (select ch.code
           from chain ch, customer bill
          where del.debtor_id = bill.customer_id
            and ch.chain_id = bill.chain_id) chain_code, 0 ar_balance,
       (select max(cbc.description)
           from customerbillingcomment cbc
          where cbc.customer_id = ih.billtocustomer_link_id
            and cbc.type = 1 and cbc.startdate <= ih.invoicedate
            and ih.invoicedate <= cbc.enddate) billtocomment,
       (select min(dep.departmentnumber) from department dep where dep.customer_id = del.customer_id) delto_depnr,
       (select min(cdd.day_id)
           from customerdeliveryday cdd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.typeofmerchadise = 1 and cdd.deliverytype = 'B') billingdaynr,
       (select ad.street || chr(13) || ad.street2
           from route r, depot depo join address ad on depo.address_id = ad.address_id
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depostreet,
       (select depo.phoneno
           from route r, depot depo
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depophoneno,
       (select depo2.faxno
           from route r, depot depo2
          where ih.route_id = r.route_id and r.depot_id = depo2.depot_id) depofaxno, 0 ar_balancepastdue,
       coalesce((select cpb.paymenttype from customer cpb where cpb.customer_id = ihextr.paybycustomer_link_id), ihextr.paymenttype) paymenttypepayby,
       ihextr.paymenttype
  from reportparam rp
  join invoiceheader ih on rp.number_value = ih.invoicenumber
       left join invoicesignature ihs on ih.invoiceheader_id = ihs.invoiceheader_id
       left join reasoncode rc on ih.adjustmentreason_id = rc.reasoncode_id
       left join customer del on ih.deltocustomer_link_id = del.customer_id
  join invoiceheaderextrainfo ihextr on ih.invoiceheader_id = ihextr.invoiceheader_id
       left join bankinstitution cbank on ihextr.bankinstitution_id = cbank.bankinstitution_id
       left join bankinstitution lbank on ihextr.laundrybankinstitution_id = lbank.bankinstitution_id
  join currency cur on ih.currency_id = cur.currency_id
  join businessunit ibu on ih.invoicebusinessunit_id = ibu.businessunit_id
  join status s on ih.status_id = s.status_id
  join plant pl on ibu.plant_id = pl.plant_id
  join address pad on pl.address_id = pad.address_id
  join country pco on pl.country_id = pco.country_id
 where ih.documenttype = 1
   and ihextr.formlayoutcode = '2' --for Layout 2 print also without prices 
union all
select 3 linetype, rp.reportparam_id, rp.copy_number, ih.invoicedate, ih.invoiceyear, ih.invoiceweek, ih.invoicedaynumber, ih.invoicenumber,
       ih.documenttype, ibu.code invoicebusinessunitcode, ibu.description invoicebusinessunitdesc, ih.billtocustomernumber, ih.billtocustomername,
       ih.extraname1, ih.extraname2, ih.deltocustomernumber, ih.deltocustomername, ih.startweek, ih.endweek, ih.startmonth, ih.endmonth, ih.startyear,
       ih.endyear, ih.city, ih.county, ih.state, ih.zipcode, ih.street2, ih.street, ih.routenumber, ih.stopnumber, ih.depotcode, ih.contactpersonname,
       ih.contactpersonphone, ih.emailstatus, ih.emailaddress, ih.realcollectiontype, ih.originalcollectiontype, ih.invoicetype, ih.exported, ih.contractcode, 
       case when ih.purchaseorder is null or ih.purchaseorder = 'Multiple' 
         then (select listagg(X.referencenumber, ', ') within group(order by X.workordernumber)
                 from (select distinct wo.workordernumber, wo.referencenumber
                         from packingnoteline pnl
                         join garmentsaleshistory gsh on pnl.packingnoteline_id = gsh.packingnoteline_id
                         join workorderline wol on gsh.workorderline_id = wol.workorderline_id
                         join workorder wo on wol.workorder_id = wo.workorder_id
                        where pnl.invoiceheader_id = ih.invoiceheader_id) X)
         else ih.purchaseorder end purchaseorder, 
       ih.deliverinstructions, ih.invoicecomments, ih.totalminusadjustment, ih.totalplusadjustment, ih.cashcollected,
       ih.paythisamount, ih.prebillamount, ih.invoicefrequency_id invoicefrequencynumber, cur.code currencycode, cur.description currencydesc, s.statustype,
       s.code statuscode, s.factorydescription statusfactorydescription, pl.code plantcode, pl.name plantname, pad.street plantstreet,
       pad.street2 plantstreet2, pad.zipcode plantzipcode, pad.city plantcity, pad.state plantstate, pad.county plantcounty, pl.phoneno plantphone,
       pl.faxno plantfax, pl.website plantwebsite, pl.email plantemail, ih.city billto_city, ih.street billto_street, ih.street2 billto_street2,
       ih.state billto_state, ih.zipcode billto_zipcode, ih.routecontrol_id, ih.adjustmentreason_id, ih.systemuser_id, ih.timestamp, ih.invoiceheader_id,
       ih.creditsqueezeamount, cur.invoiceamountdecimals, cur.description currencydescription, ih.totalamountexclvat, cur.decimals, ih.startdate,
       ih.enddate, ihextr.billtocountrydescription, ihextr.deltocountrydescription, ihextr.deltocustvatnumber, ihextr.customermarkinggarment,
       ihextr.taxable, ihextr.siccode, ihextr.invoicecopies,
       cast(fsget_custdeliveryscheme(ih.route_id, ih.deltocustomer_link_id) as varchar2(6)) custdeliveryscheme,
       cast(fsget_cust_delivery_days(ih.deltocustomer_link_id) as varchar2(7)) cust_delivery_days, ihextr.attachinvoicecopies,
       ihextr.paymenttermsdescription paymentterms_desc, ihextr.formlayoutcode invoicelayoutcode, ibu.code default_bu_code,
       (select rtes.soiltickets
           from routestop rtes
          where rtes.route_id = ih.route_id
            and rtes.stopnumber = ih.stopnumber
            and rtes.customer_id = ih.deltocustomer_link_id) no_of_soiltickets, rc.code adjustment_reasoncode,
       getsortusasc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_asc,
       getsortusdesc(ih.routenumber, ih.stopnumber, ih.deltocustomernumber, ih.invoicenumber) m_sort_us_desc, 
       ih.splitupcode, ih.splitupdescription, ihs.personidentification, ihs.signature,
       cast(fsget_min_5_yearweeks(ih.invoiceheader_id, ih.invoicefrequency_id) as varchar2(39)) min_year_weeks, ih.parentinvoiceheader_id,
       ih.contractstartdate, ih.contractenddate, ihextr.bankaccount, ihextr.ibanno, cbank.idcode cust_bank_idcode, cbank.description cust_bank_desc,
       cbank.internalidcode cust_bank_internid, cbank.laundrybankaccount cust_lndrybankaccount, cbank.ibanno cust_ibanno, lbank.idcode lndry_bank_idcode,
       lbank.description lndry_bank_desc, lbank.internalidcode lndry_bank_internid, lbank.laundrybankaccount lndry_bank_lndrybankaccount,
       lbank.ibanno lndry_bank_ibanno, ih.paymentdiscountdays, ih.creditsqueezeperc, ih.netpaymentdays, ih.deltostreet, ih.deltostreet2, ih.deltocounty,
       ih.deltocity, ih.deltozipcode, ih.deltostate, pco.description plantcountrydescription,
       (select ss.value
           from systemsetting ss
          where pl.plant_id = ss.plant_id
            and ss.name = 'WEIGHTUNIT') weightunit,
       (select max(ilv.percentage)
           from invoiceline il, invoicelinevarious ilv
          where il.invoiceheader_id = ih.invoiceheader_id
            and ilv.invoiceline_id = il.invoiceline_id
            and il.invoicelinetype_id = 18) max_percentage, 
       ih.roundingamount, ih.nextperiodstartdate, ih.nextperiodenddate, ih.nextperiodnoweeks,
       ihextr.discountdays, ihextr.paymentdiscount, ihextr.discountdays2, ihextr.paymentdiscount2,
       (select cast(ss1.value as numeric)
           from systemsetting ss1
          where pl.plant_id = ss1.plant_id
            and ss1.name = 'WEIGHTDECIMALSMANUALINPUT') weightdecimalsmanualinput,
       (select empl.name
           from routecontrol rcntrl, employee empl
          where rcntrl.routecontrol_id = ih.routecontrol_id
            and empl.employeenumber = rcntrl.drivernumber
            and empl.plant_id = rcntrl.plant_id) drivername,
       (case
          when (ihs.signature is null) then
           'N'
          else
           'Y'
        end) hassignature,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = pl.language_id) generalinv_remark_plant,
       (select pldesc.invoiceremark
           from plantinvoiceremark_desc pldesc
          where pldesc.plant_id = pl.plant_id
            and pldesc.language_id = del.language_id) generalinv_remark_customer, 
       pl.invoiceremarkstartdate, pl.invoiceremarkenddate, ibu.internalvatnumber, ibu.vatnumber,
       coalesce((select max(pa.packingnote_id)
                   from packingnote pa, packingnoteline pl
                  where pa.packingnote_id = pl.packingnote_id
                    and pl.invoiceheader_id = ih.invoiceheader_id
                    and ih.invoicefrequency_id = 0
                    and pa.origin = 5), 0) setspecial,
       (case
          when ih.cluster_id is null then
           (select max(c.code)
              from customerspercluster cpc, customercluster c
             where c.invoicefrequency_id = ih.invoicefrequency_id
               and cpc.cluster_id = c.cluster_id
               and cpc.customer_id = ih.billtocustomer_link_id)
          else
           (select cc.code from customercluster cc where cc.cluster_id = ih.cluster_id)
        end) clustercode, ihextr.paymenttermsduedate, ih.reference, ih.activityreference,
       (select com1.customernumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_nr,
       (select com1.name from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_name,
       (select com1.pnnumber from customer com1 where com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_pnnumber,
       del.pnnumber delto_pnnumber, del.phoneno delto_phoneno, del.faxno delto_faxno, del.searchname delto_searchname, del.legalname delto_legalname,
       (select sa.code from salesarea sa where sa.salesarea_id = del.salesarea_id) salesarea_code,
       (select sad.description
           from salesarea_desc sad
          where sad.salesarea_id = del.salesarea_id
            and sad.language_id = pl.language_id) salesarea_desc,
       (select da.daynumber
           from route r, day da
          where ih.route_id = r.route_id
            and r.drivingday_id = da.day_id) drivingdaynr,
       (select listagg(dd.code, ',') within group(order by dd.day_id)
           from customerdeliveryday cdd, day_desc dd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.day_id = dd.day_id and cdd.typeofmerchadise = 1
            and dd.language_id = pl.language_id) drivingdaycode, del.customermarkinggarment delto_nameonlabel,
       (select ch.code
           from chain ch, customer bill
          where del.debtor_id = bill.customer_id
            and ch.chain_id = bill.chain_id) chain_code, 0 ar_balance,
       (select max(cbc.description)
           from customerbillingcomment cbc
          where cbc.customer_id = ih.billtocustomer_link_id
            and cbc.type = 1 and cbc.startdate <= ih.invoicedate
            and ih.invoicedate <= cbc.enddate) billtocomment,
       (select min(dep.departmentnumber) from department dep where dep.customer_id = del.customer_id) delto_depnr,
       (select min(cdd.day_id)
           from customerdeliveryday cdd
          where ih.deltocustomer_link_id = cdd.customer_id
            and cdd.typeofmerchadise = 1
            and cdd.deliverytype = 'B') billingdaynr,
       (select ad.street || chr(13) || ad.street2
           from route r, depot depo join address ad on depo.address_id = ad.address_id
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depostreet,
       (select depo.phoneno
           from route r, depot depo
          where ih.route_id = r.route_id and r.depot_id = depo.depot_id) depophoneno,
       (select depo2.faxno
           from route r, depot depo2
          where ih.route_id = r.route_id and r.depot_id = depo2.depot_id) depofaxno, 0 ar_balancepastdue,
       coalesce((select cpb.paymenttype from customer cpb where cpb.customer_id = ihextr.paybycustomer_link_id), ihextr.paymenttype) paymenttypepayby,
       ihextr.paymenttype
  from reportparam rp
  join invoiceheader ih on rp.number_value = ih.invoicenumber
       left join invoicesignature ihs on ih.invoiceheader_id = ihs.invoiceheader_id
       left join reasoncode rc on ih.adjustmentreason_id = rc.reasoncode_id
       left join customer del on ih.deltocustomer_link_id = del.customer_id
  join invoiceheaderextrainfo ihextr on ih.invoiceheader_id = ihextr.invoiceheader_id
       left join bankinstitution cbank on ihextr.bankinstitution_id = cbank.bankinstitution_id
       left join bankinstitution lbank on ihextr.laundrybankinstitution_id = lbank.bankinstitution_id
  join currency cur on ih.currency_id = cur.currency_id
  join businessunit ibu on ih.invoicebusinessunit_id = ibu.businessunit_id
  join status s on ih.status_id = s.status_id
  join plant pl on ibu.plant_id = pl.plant_id
  join address pad on pl.address_id = pad.address_id
  join country pco on pl.country_id = pco.country_id
 where ih.documenttype = 1
   and ihextr.formlayoutcode = '2' --for Layout 2 print also without prices TWICE
/

create or replace view v_invoiceheader_rs_auj as
select ih.invoicedate, ih.invoiceyear, ih.invoiceweek, ih.invoicedaynumber,
       ih.invoicenumber, ih.documenttype, ibu.code invoicebusinessunitcode, ibu.description invoicebusinessunitdesc,
       ih.billtocustomernumber, ih.billtocustomername, ih.extraname1, ih.extraname2,
       ih.deltocustomernumber, ih.deltocustomername,
       ih.startweek, ih.endweek, ih.startmonth, ih.endmonth, ih.startyear, ih.endyear,
       ih.city, ih.county, ih.state, ih.zipcode, ih.street2, ih.street, ih.routenumber, ih.stopnumber, ih.depotcode,
       ih.contactpersonname, ih.contactpersonphone,
       ih.emailstatus, ih.emailaddress, ih.realcollectiontype, ih.originalcollectiontype,
       ih.invoicetype, ih.exported, ih.contractcode, ih.purchaseorder,
       ih.deliverinstructions, ih.invoicecomments, ih.totalminusadjustment, ih.totalplusadjustment, ih.cashcollected,
       ih.paythisamount, ih.prebillamount, ih.invoicefrequency_id invoicefrequencynumber,
       ih.city billto_city, ih.street billto_street,
       ih.street2 billto_Street2, ih.state billto_state, ih.zipcode billto_zipcode,
       ih.routecontrol_id, ih.adjustmentreason_id, ih.systemuser_id, ih.timestamp, ih.invoiceheader_id,
       ih.creditsqueezeamount, ih.totalamountexclvat, ih.startdate, ih.enddate,
       ihextr.billtocountrydescription, ihextr.deltocountrydescription, ihextr.deltocustvatnumber,
       ihextr.customermarkinggarment, ihextr.taxable, ihextr.siccode, ihextr.invoicecopies,
       ihextr.attachinvoicecopies, ihextr.paymenttermsdescription paymentterms_desc,
       ihextr.formlayoutcode invoicelayoutcode,
       ibu.code default_BU_code, ih.splitupcode, ih.splitupdescription,
       ih.parentinvoiceheader_id, ih.contractstartdate, ih.contractenddate,
       ihextr.bankaccount, ihextr.ibanno,
       ih.paymentdiscountdays, ih.creditsqueezeperc, ih.netpaymentdays,
       ih.deltostreet, ih.deltostreet2, ih.deltocounty, ih.deltocity, ih.deltozipcode, ih.deltostate,
       ih.roundingamount, ih.NEXTPERIODSTARTDATE, ih.NEXTPERIODENDDATE, ih.NEXTPERIODNOWEEKS,--ihextr.paymenttype,
       ihextr.discountdays, ihextr.paymentdiscount, ihextr.discountdays2, ihextr.paymentdiscount2
, ibu.internalvatnumber, ibu.vatnumber, ihextr.paymenttermsduedate, ih.reference, ih.activityreference
, del.pnnumber delto_pnnumber,del.phoneno delto_phoneno,del.faxno delto_faxno,del.searchname delto_searchname, del.legalname delto_legalname
, (select sa.code from salesarea sa where sa.salesarea_id = del.salesarea_id) salesarea_code
, (select sad.description from salesarea_desc sad where sad.salesarea_id = del.salesarea_id
          and sad.language_id = del.language_id) salesarea_desc
, del.customermarkinggarment DelTo_NameOnLabel
, (select ch.code from chain ch, customer bill where del.debtor_id = bill.customer_id and ch.chain_id = bill.chain_id) chain_code
, (select max(cbc.description) from customerbillingcomment cbc where cbc.customer_id = ih.billtocustomer_link_id and cbc.type = 1
and cbc.startdate <= ih.invoicedate and ih.invoicedate <= cbc.enddate) BillToComment
, (select max(dep.departmentnumber) from department dep where dep.customer_id = del.customer_id) delto_depnr
, (select min(cdd.day_id) from CUSTOMERDELIVERYDAY cdd where ih.deltocustomer_link_id = cdd.customer_id
and cdd.typeofmerchadise = 1 and cdd.deliverytype = 'B') BillingDayNr
, nvl((select sum(nvl(art.amount, 0) - art.totalappliedamount)
     from artransaction art, invoiceheaderextrainfo x, artransactiontype artt
    where art.invoiceheader_id = x.invoiceheader_id--and art.closingtransaction_id is null
      and x.paymenttermsduedate <= trunc(sysdate)
      and art.isopen_yn = 'Y' and art.debitcredit = 'D' 
      and art.artransactiontype_id = artt.artransactiontype_id and artt.typenumber = 1
      and art.deltocustomer_link_id = ih.deltocustomer_link_id), 0) AR_BalancePastDue
, coalesce((select cpb.paymenttype from customer cpb where cpb.customer_id=ihextr.PAYBYCUSTOMER_LINK_ID)
       , ihextr.paymenttype) paymenttypePayBy
, ihextr.paymenttype
, trunc(sysdate) - (select min(x.paymenttermsduedate) from artransaction art, invoiceheaderextrainfo x, artransactiontype artt
    where art.invoiceheader_id = x.invoiceheader_id --and art.closingtransaction_id is null
      and art.deltocustomer_link_id = ih.deltocustomer_link_id
      and x.paymenttermsduedate <= trunc(sysdate)
      and art.isopen_yn = 'Y' and art.debitcredit = 'D' 
      and art.artransactiontype_id = artt.artransactiontype_id and artt.typenumber = 1) Due_Date_Oldest_Open_Invoice
, (select count(1) from  artransaction art
    where art.invoiceheader_id = ih.invoiceheader_id
      and art.closingtransaction_id is null
      and art.isopen_yn = 'Y'
      and art.debitcredit = 'D') debitopen
, (select ma.customernumber from customer bill, customer ma where bill.customer_id = ih.billtocustomer_link_id and bill.masteraccount_id = ma.customer_id) MasterAcctNumber     
from  invoiceheader ih
      LEFT OUTER JOIN customer del ON ih.deltocustomer_link_id = del.customer_id
      inner join invoiceheaderextrainfo ihextr on ih.invoiceheader_id = ihextr.invoiceheader_id
      inner join businessunit ibu on ih.invoicebusinessunit_id = ibu.businessunit_id
where ih.documenttype = 1
/
create or replace view v_invoiceheaderstatement_auj as
select 1 linetype, a.invoicedate,
       a.invoicenumber,
       a.billtocustomernumber, a.billtocustomername,
       a.deltocustomernumber, a.invoiceheader_id, a.deltocustomername,
       a.paythisamount, a.prebillamount, a.invoicefrequency_id invoicefrequencynumber,
       b.code currencycode, b.description currencydesc,
       a.totalamountexclvat,
       com1.customernumber commoncustomer_nr,
       com1.name commoncustomer_name,
       com1.pnnumber commoncustomer_pnnumber
from  invoiceheader a
        LEFT OUTER JOIN customer del
             LEFT OUTER JOIN customer com1 ON (com1.customer_id = coalesce(del.commoncustomer_id, del.debtor_id))
        ON (del.customer_id = a.deltocustomer_link_id),
      currency b
where a.currency_id = b.currency_id
      and a.documenttype = 1
/
create or replace view v_invoiceline_auj as
select /*version 1.7*/
       ih.invoicedate, ih.invoicenumber, il.linenumber,
       (case when ilt.type = 1 and il.invoicelinesubtype = 13 then 1.6 else ilt.type end) invoicelinetype,
       (select iltd.description from invoicelinetype_desc iltd
         where iltd.invoicelinetype_id = il.invoicelinetype_id and iltd.language_id = lan.language_id) invoicelinetypedesc,
       il.code, cast(fsget_taxcode(ih.invoicenumber, il.linenumber) as varchar2(255)) taxcode,
       il.description, il.adjustedamount, il.adjustedprice, il.adjustmentbilledqty, il.extend, il.amount, il.discountpercentage,
       il.price, il.billedqty, il.taxgroupcode, il.taxtype, il.subjecttominimum, tg.code turnovergroupcode,
       (select tgd.description from turnovergroup_desc tgd
          where tgd.turnovergroup_id = il.turnovergroup_id and tgd.language_id = lan.language_id) turnovergroupdescription,
       il.invoicelinesubtype, ilp.productgroupcode, ilp.productgroupdescription, ilp.productshortdescription,
       cast(fsget_code(ih.invoicenumber, il.linenumber) as varchar2(255)) shortdescription,
       nvl((select psz.sequencenumber 
              from productsize psz 
             where psz.product_id = ilp.product_link_id
               and psz.sizedefinition_id = ilp.sizedefinition_link_id),0) productsize_sequencenumber,
       ilp.sizecode, ilp.sizedescription, ilp.finishingmethodcode, ilp.finishingmethoddescription, ilp.invoiceqtycolumn,  ilp.inventoryqty, 
       ilp.deliveredqty, ilp.abusedquantity, ilp.soilquantity, ilp.soilcountmethod, ilp.billingmethod, ilp.wearernumber, ilp.wearername, 
       ilp.weareradminnr, ilp.wearerbank, ilp.wearerlocker, ilv.transactiontype, ilv.transactiondate, ilv.percentage, il.systemuser_id, 
       il.timestamp, il.invoiceline_id, il.remark, lan.code languagecode, il.invoiceheader_id, ilv.overamount, ilp.replacementprice,
       (select pd.description from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) productdescription,
       (select pd.registrationunitdescription from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) registrationunitdescription,
       (select rc.code from reasoncode rc where rc.reasoncode_id = il.adjustmentreason_id) adjustmentreason_code,
       (select pilt.sequencenumber from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) invoiceline_sequencenumber,
       (select pilt.suppressprinting from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) supressprinting, 
       ilp.adjustmentdeliveredqty, ilp.pricefactor,
       coalesce(ilp.deliveryschemecode, 
                (select min(ds.code) from customerdeliveryscheme cds, deliveryscheme ds
                  where cds.customer_id = ih.deltocustomer_link_id and cds.deliveryscheme_id = ds.deliveryscheme_id)) deliveryschemecode,
       coalesce((select pr.typeofmerchandise from product pr where pr.product_id = ilp.product_link_id), 0) typeofmerchandise,          
       case when il.invoicelinetype_id <> 18-- ilv.percentage is null or ilv.percentage = 0
            then (select case when ih.invoicedate < tag.startdatetaxrate then tag.oldtaxrate else tag.taxrate  end
                        from customer bil, taxgroup tag where bil.customer_id = ih.billtocustomer_link_id 
                        and tag.code = il.taxgroupcode and tag.country_id = bil.country_id)
       else ilv.percentage end taxrate
  from invoiceline il
       left join invoicelineproduct ilp on il.invoiceline_id = ilp.invoiceline_id
       left join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id
       left join turnovergroup tg on il.turnovergroup_id = tg.turnovergroup_id
       join invoicelinetype ilt on il.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader ih 
            join businessunit bu on ih.invoicebusinessunit_id = bu.businessunit_id
       on il.invoiceheader_id = ih.invoiceheader_id
       cross join languages lan
 where ih.documenttype = 1
/

create or replace view v_invoiceline_st_auj as
select /*version 1.4*/
       ih.invoicedate, ih.invoicenumber, il.linenumber,
       (case when ilt.type = 1 and il.invoicelinesubtype = 13 then 1.6 else ilt.type end) invoicelinetype,
       (select iltd.description from invoicelinetype_desc iltd
         where iltd.invoicelinetype_id = il.invoicelinetype_id and iltd.language_id = lan.language_id) invoicelinetypedesc,
       il.code, cast(fsget_taxcode(ih.invoicenumber, il.linenumber) as varchar2(255)) taxcode,
       il.description, il.adjustedamount, il.adjustedprice, il.adjustmentbilledqty, il.extend, il.amount, il.discountpercentage,
       il.price, il.billedqty, il.taxgroupcode, il.taxtype, il.subjecttominimum, tg.code turnovergroupcode,
       (select tgd.description from turnovergroup_desc tgd
         where tgd.turnovergroup_id = il.turnovergroup_id and tgd.language_id = lan.language_id) turnovergroupdescription,
       il.invoicelinesubtype, ilp.productgroupcode, ilp.productgroupdescription, ilp.productshortdescription,
       cast(fsget_code(ih.invoicenumber, il.linenumber) as varchar2(255)) shortdescription,
       nvl((select psz.sequencenumber 
              from productsize psz 
             where psz.product_id = ilp.product_link_id 
               and psz.sizedefinition_id = ilp.sizedefinition_link_id),0) productsize_sequencenumber,
       ilp.sizecode, ilp.sizedescription, ilp.finishingmethodcode, ilp.invoiceqtycolumn,  ilp.inventoryqty, 
       nvl(ilp.finishingmethoddescription, 
           (select fmd.description from finishingmethod_desc fmd
             where fmd.finishingmethod_id = ilp.finishingmethod_id 
               and fmd.language_id = lan.language_id)) finishingmethoddescription, 
       ilp.deliveredqty, ilp.abusedquantity, ilp.soilquantity, ilp.soilcountmethod, ilp.billingmethod, ilp.wearernumber, ilp.wearername, 
       ilp.weareradminnr, ilp.wearerbank, ilp.wearerlocker, ilv.transactiontype, ilv.transactiondate, ilv.percentage, il.systemuser_id, 
       il.timestamp, il.invoiceline_id, il.remark, lan.code languagecode, il.invoiceheader_id, ilv.overamount, ilp.replacementprice,
       (select pd.description from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) productdescription,
       (select pd.registrationunitdescription from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) registrationunitdescription,
       (select rc.code from reasoncode rc where rc.reasoncode_id = il.adjustmentreason_id) adjustmentreason_code,
       (select pilt.sequencenumber from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) invoiceline_sequencenumber,
       (select pilt.suppressprinting from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) supressprinting, 
       ilp.adjustmentdeliveredqty, ilp.pricefactor,
       coalesce(ilp.deliveryschemecode, 
                (select min(ds.code) from customerdeliveryscheme cds, deliveryscheme ds
                  where cds.customer_id = ih.deltocustomer_link_id and cds.deliveryscheme_id = ds.deliveryscheme_id)) deliveryschemecode,
       coalesce((select pr.typeofmerchandise from product pr where pr.product_id = ilp.product_link_id), 0) typeofmerchandise,          
       case when il.invoicelinetype_id <> 18-- ilv.percentage is null or ilv.percentage = 0
            then (select case when ih.invoicedate < tag.startdatetaxrate then tag.oldtaxrate else tag.taxrate  end
                        from customer bil, taxgroup tag where bil.customer_id = ih.billtocustomer_link_id 
                        and tag.code = il.taxgroupcode and tag.country_id = bil.country_id)
       else ilv.percentage end taxrate, 
       null lossdate
  from invoiceline il
       left join invoicelineproduct ilp on il.invoiceline_id = ilp.invoiceline_id
       left join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id
       left join turnovergroup tg on il.turnovergroup_id = tg.turnovergroup_id
       join invoicelinetype ilt on il.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader ih 
            join businessunit bu on ih.invoicebusinessunit_id = bu.businessunit_id
       on il.invoiceheader_id = ih.invoiceheader_id
       cross join languages lan
 where ih.documenttype = 1
   and il.invoicelinetype_id <> 9
 union all
select ih.invoicedate, ih.invoicenumber, il.linenumber,
       (case when ilt.type = 1 and il.invoicelinesubtype = 13 then 1.6 else ilt.type end) invoicelinetype,
       (select iltd.description from invoicelinetype_desc iltd
         where iltd.invoicelinetype_id = il.invoicelinetype_id and iltd.language_id = lan.language_id) invoicelinetypedesc,
       il.code, cast(fsget_taxcode(ih.invoicenumber, il.linenumber) as varchar2(255)) taxcode,
       il.description, il.adjustedamount, il.adjustedprice, il.adjustmentbilledqty, il.extend, 
       coalesce(x.amount, il.amount) amount, il.discountpercentage, il.price, coalesce(x.quantity, il.billedqty) billedqty, 
       il.taxgroupcode, il.taxtype, il.subjecttominimum, tg.code turnovergroupcode,
       (select tgd.description from turnovergroup_desc tgd
          where tgd.turnovergroup_id = il.turnovergroup_id and tgd.language_id = lan.language_id) turnovergroupdescription,
       il.invoicelinesubtype, ilp.productgroupcode, ilp.productgroupdescription, ilp.productshortdescription,
       cast(fsget_code(ih.invoicenumber, il.linenumber) as varchar2(255)) shortdescription,
       nvl((select psz.sequencenumber 
              from productsize psz 
             where psz.product_id = ilp.invoiceline_id 
               and psz.sizedefinition_id = ilp.sizedefinition_link_id),0) productsize_sequencenumber,
       ilp.sizecode, ilp.sizedescription, ilp.finishingmethodcode, ilp.invoiceqtycolumn,  ilp.inventoryqty, 
       nvl(ilp.finishingmethoddescription, 
           (select fmd.description from finishingmethod_desc fmd
             where fmd.finishingmethod_id = ilp.finishingmethod_id 
               and fmd.language_id = lan.language_id)) finishingmethoddescription, 
       ilp.deliveredqty, ilp.abusedquantity, ilp.soilquantity, ilp.soilcountmethod, ilp.billingmethod, ilp.wearernumber, ilp.wearername, 
       ilp.weareradminnr, ilp.wearerbank, ilp.wearerlocker, ilv.transactiontype, ilv.transactiondate, ilv.percentage, il.systemuser_id, 
       il.timestamp, il.invoiceline_id, il.remark, lan.code languagecode, il.invoiceheader_id, ilv.overamount, ilp.replacementprice,
       (select pd.description from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) productdescription,
       (select pd.registrationunitdescription from product_link_desc pd
         where pd.product_link_id = ilp.product_link_id and pd.language_id = lan.language_id) registrationunitdescription,
       (select rc.code from reasoncode rc where rc.reasoncode_id = il.adjustmentreason_id) adjustmentreason_code,
       (select pilt.sequencenumber from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) invoiceline_sequencenumber,
       (select pilt.suppressprinting from plantinvoicelinetype pilt
         where pilt.plant_id = bu.plant_id and pilt.invoicelinetype_id = il.invoicelinetype_id) supressprinting, 
       ilp.adjustmentdeliveredqty, ilp.pricefactor,
       coalesce(ilp.deliveryschemecode, 
                (select min(ds.code) from customerdeliveryscheme cds, deliveryscheme ds
                  where cds.customer_id = ih.deltocustomer_link_id and cds.deliveryscheme_id = ds.deliveryscheme_id)) deliveryschemecode,
       coalesce((select pr.typeofmerchandise from product pr where pr.product_id = ilp.product_link_id), 0) typeofmerchandise,          
       case when il.invoicelinetype_id <> 18-- ilv.percentage is null or ilv.percentage = 0
            then (select case when ih.invoicedate < tag.startdatetaxrate then tag.oldtaxrate else tag.taxrate  end
                        from customer bil, taxgroup tag where bil.customer_id = ih.billtocustomer_link_id 
                        and tag.code = il.taxgroupcode and tag.country_id = bil.country_id)
       else ilv.percentage end taxrate, 
       x.lossdate
  from invoiceline il
       left join invoicelineproduct ilp on il.invoiceline_id = ilp.invoiceline_id
       left join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id
       left join turnovergroup tg on il.turnovergroup_id = tg.turnovergroup_id
       join invoicelinetype ilt on il.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader ih 
            join businessunit bu on ih.invoicebusinessunit_id = bu.businessunit_id
       on il.invoiceheader_id = ih.invoiceheader_id
       cross join languages lan
       left join (select wic.invoiceheader_id, YearMonthDay(cih.invoicedate) lossdate, 
                         cilp.weareremployment_link_id, cilp.product_link_id, 
                         cilp.sizedefinition_link_id, cilp.finishingmethod_id, 
                         wic.quantity, (-1)*wic.amount amount
                    from wearerinventorycredit wic
                         join invoiceline cil
                              left join invoicelineproduct cilp on cil.invoiceline_id = cilp.invoiceline_id
                              join invoiceheader cih on cil.invoiceheader_id = cih.invoiceheader_id
                         on wic.losschargeinvoiceline_id = cil.invoiceline_id
                   where cil.extend = 'Y' and (cil.amount <> 0 or cil.adjustedamount <> 0)) x
       on il.invoiceheader_id = x.invoiceheader_id
 where ih.documenttype = 1
   and il.invoicelinetype_id = 9
   and coalesce(x.weareremployment_link_id, ilp.weareremployment_link_id, 0) = nvl(ilp.weareremployment_link_id, 0)
   and coalesce(x.product_link_id, ilp.product_link_id, 0) = nvl(ilp.product_link_id, 0)
   and coalesce(x.sizedefinition_link_id, ilp.sizedefinition_link_id, 0) = nvl(ilp.sizedefinition_link_id, 0)
   and coalesce(x.finishingmethod_id, ilp.finishingmethod_id, 0) = nvl(ilp.finishingmethod_id, 0)
/

create or replace view v_miroko_export as
select /*view v_miroko_export version 1.0*/
       a.artransaction_id, a.artransactiondate,
       case
         when h.realcollectiontype = 1 then -- Cash
          '2  '
         when ei.paymenttype = 1 then --EFT
          '3  '
         when ei.paymenttype = 2 then -- Credit card
          '3  '
         when ei.paymenttype = 7 then -- Pay by customer
          (case
            when nvl(pbc.paymenttype, 1) = 1 then
             '3  '
            when nvl(pbc.paymenttype, 1) = 2 then
             '3  '
            else
             '1  '
          end)
         else
          '1  '
       end paymentmethod,
       nvl((select e2.employeenumber
            from   salesarea sa2, employee e2
            where  sa2.responsibleemployee_id = e2.employee_id
            and    sa2.salesarea_id =
                   (select min(to_number(ccu2.old_value))
                     from   changes_customer ccu2
                     where  ccu2.customer_id = h.deltocustomer_link_id
                     and    ccu2.tablename = 'CUSTOMER'
                     and    ccu2.fieldname = 'SALESAREA_ID'
                     and    ccu2.insert_update_delete = 'U'
                     and    ccu2.old_value <> 'NULL'
                     and    ccu2.timestamp = (select min(ccu.timestamp)
                                              from   changes_customer ccu
                                              where  ccu.customer_id = h.deltocustomer_link_id
                                              and    ccu.customer_id = ccu2.customer_id
                                              and    ccu.tablename = ccu2.tablename
                                              and    ccu.fieldname = ccu2.fieldname
                                              and    ccu.insert_update_delete = 'U'
                                              and    ccu.old_value <> 'NULL'
                                              and    ccu.timestamp >= h.creationtimestamp
                                              and    ccu.timestamp < sysdate
                                              ))), e.employeenumber) employeenumber,
       sum(ard.amount) amount,
       get_accountheading(pbc.customernumber,
                           (select max(la.accountnumber)
                             from   ledgeraccounts la, ledgeracctsperturnovergroup lts
                             where  lts.turnovergroup_id = ard.turnovergroup_id
                             and    la.ledgeraccounts_id = lts.ledgeraccounts_id), cr.priority) accountheading,
       a.exportstatus, to_char(a.artransactiondate, 'mm/yyyy') monthyear
from   invoiceheader h
join   status st
on     st.status_id = h.status_id
join   invoiceheaderextrainfo ei
on     ei.invoiceheader_id = h.invoiceheader_id
join   artransaction a
on     a.invoiceheader_id = h.invoiceheader_id
join   artransactiondetail ard
on     ard.artransaction_id = a.artransaction_id
join   customer c
on     c.customer_id = h.deltocustomer_link_id
join   customer d
on     d.customer_id = c.debtor_id
left   outer join customer pbc
on     pbc.customer_id = ei.paybycustomer_link_id
join   customerranking cr
on     cr.customerranking_id = c.customerranking_id
join   salesarea sa
on     sa.salesarea_id = c.salesarea_id
join   employee e
on     e.employee_id = sa.responsibleemployee_id
where  h.documenttype = 1
and    st.statustype = 'IN'
and    st.code = '2'
and    a.artransactiontype_id = 1
and    ard.amount <> 0
and    0 <>
       get_accountheading(d.customernumber,
                           (select max(la.accountnumber)
                             from   ledgeraccounts la, ledgeracctsperturnovergroup lts
                             where  lts.turnovergroup_id = ard.turnovergroup_id
                             and    la.ledgeraccounts_id = lts.ledgeraccounts_id), cr.priority)
group  by a.exportstatus, a.artransaction_id, a.artransactiondate,
          case
            when h.realcollectiontype = 1 then -- Cash
             '2  '
            when ei.paymenttype = 1 then --EFT
             '3  '
            when ei.paymenttype = 2 then -- Credit card
             '3  '
            when ei.paymenttype = 7 then -- Pay by customer
             (case
               when nvl(pbc.paymenttype, 1) = 1 then
                '3  '
               when nvl(pbc.paymenttype, 1) = 2 then
                '3  '
               else
                '1  '
             end)
            else
             '1  '
          end, c.name, cr.priority, employeenumber, ard.turnovergroup_id, d.customernumber,
          h.invoicebusinessunit_id, c.defaultbusinessunit_id, h.deltocustomer_link_id, h.startdate,
          h.creationtimestamp, pbc.customernumber
-->order  by employeenumber, 3, 6, a.artransactiondate
/

create or replace view v_miroko_export_new as
select /*view v_miroko_export_new version 1.0*/
x.artransactiondate,
9991 slip_number,
null journal_input_format,
1250 debit_subject_code,
null debit_subject_name,
null debit_division_code,
null debit_division_name,
1    subject_code,
null subject_name,
null debit_business_partner_code,
null debit_business_partner_name,
null debit_auxiliary_code,
null debit_auxiliary_name,
x.credit_item_code,
null credit_item_name,
x.credit_department_code,
null credit_department_name,
null credit_subject_code,
null credit_subject_name,
null credit_business_partner_code,
null credit_business_partner_name,
null credit_auxiliary_code,
null credit_auxiliary_name,
x.consumption_tax_code,
x.consumption_tax_rate,
sum(x.amount) amount,
null description,
null due_date,
199 record_category
from ( select a.artransactiondate,
get_accountheading(pbc.customernumber,
                  (select max(la.accountnumber)
                   from   ledgeraccounts la, ledgeracctsperturnovergroup lts
                   where  lts.turnovergroup_id = ard.turnovergroup_id
                   and    la.ledgeraccounts_id = lts.ledgeraccounts_id), cr.priority) credit_item_code,
to_number(substr(to_char(nvl((select e2.employeenumber
     from   salesarea sa2, employee e2
     where  sa2.responsibleemployee_id = e2.employee_id
     and    sa2.salesarea_id =
            (select min(to_number(ccu2.old_value))
             from   changes_customer ccu2
             where  ccu2.customer_id = h.deltocustomer_link_id
             and    ccu2.tablename = 'CUSTOMER'
             and    ccu2.fieldname = 'SALESAREA_ID'
             and    ccu2.insert_update_delete = 'U'
             and    ccu2.old_value <> 'NULL'
             and    ccu2.timestamp = (select min(ccu.timestamp)
                                      from   changes_customer ccu
                                      where  ccu.customer_id = h.deltocustomer_link_id
                                      and    ccu.customer_id = ccu2.customer_id
                                      and    ccu.tablename = ccu2.tablename
                                      and    ccu.fieldname = ccu2.fieldname
                                      and    ccu.insert_update_delete = 'U'
                                      and    ccu.old_value <> 'NULL'
                                      and    ccu.timestamp >= trunc(h.invoicedate) + 1 - 1/(24*60)
                                      and    ccu.timestamp < sysdate
                                      ))), e.employeenumber)),1,3)) credit_department_code,
case when ei.taxable = 'Y' then
 case nvl(tx.code,'NULL') 
  when 'NULL' then '60'
  when '111111' then '40'
  else '20'
 end 
else
  '60' 
end consumption_tax_code,
case when ei.taxable = 'Y' then
 case tx.taxrate
  when 3 then 1
  when 5 then 2
  when 8 then 3
  when 10 then 4
  else 0
 end 
else 
  0 
end consumption_tax_rate,
sum(ard.amount) amount
from   invoiceheader h
join   status st
on     st.status_id = h.status_id
join   invoiceheaderextrainfo ei
on     ei.invoiceheader_id = h.invoiceheader_id
join   artransaction a
on     a.invoiceheader_id = h.invoiceheader_id
join   artransactiondetail ard
on     ard.artransaction_id = a.artransaction_id
join   customer c
on     c.customer_id = h.deltocustomer_link_id
join   customer d
on     d.customer_id = c.debtor_id
join   turnovergroup t
on     t.turnovergroup_id = ard.turnovergroup_id
left   outer join taxgroup tx
on     tx.taxgroup_id = t.taxgroup_id
left   outer join customer pbc
on     pbc.customer_id = ei.paybycustomer_link_id
join   customerranking cr
on     cr.customerranking_id = c.customerranking_id
join   salesarea sa
on     sa.salesarea_id = c.salesarea_id
join   employee e
on     e.employee_id = sa.responsibleemployee_id
where  h.documenttype = 1
and    st.statustype = 'IN'
and    st.code = '2'
and    a.artransactiontype_id = 1
and    ard.amount <> 0
and    0 <> get_accountheading(d.customernumber,
                         (select max(la.accountnumber)
                          from   ledgeraccounts la, ledgeracctsperturnovergroup lts
                          where  lts.turnovergroup_id = ard.turnovergroup_id
                          and    la.ledgeraccounts_id = lts.ledgeraccounts_id), cr.priority)
group  by a.artransactiondate,
          case
            when h.realcollectiontype = 1 then -- Cash
             '2  '
            when ei.paymenttype = 1 then --EFT
             '3  '
            when ei.paymenttype = 2 then -- Credit card
             '3  '
            when ei.paymenttype = 7 then -- Pay by customer
             (case
               when nvl(pbc.paymenttype, 1) = 1 then
                '3  '
               when nvl(pbc.paymenttype, 1) = 2 then
                '3  '
               else
                '1  '
             end)
            else
             '1  '
          end, cr.priority, e.employeenumber, ard.turnovergroup_id, d.customernumber,
          h.deltocustomer_link_id, h.invoicedate, tx.taxrate, tx.code, ei.taxable, 
          pbc.customernumber) x
group by x.artransactiondate,
         x.credit_item_code,
         x.credit_department_code,
         x.consumption_tax_code,
         x.consumption_tax_rate
/

create or replace view v_nonunique_stockqty_actions as
select /*v_nonunique_stockqty_actionsv version 0.1*/
 sr.code stockroomcode, stl.rowcode, stl.locationcode, p.code productocode, s.code sizecode,
 q.code grade,
 (select sum(str.quantity)
   from   stocktransaction str
   where  str.stockreservationpergrade_id = sq.stockreservationpergrade_id
   and    str.uniquestock = 'N'
   and    (sq.stockroomlocation_id = str.tostockroomlocation_id or
         sq.stockroomlocation_id = str.fromstockroomlocation_id)) qty_stocktransactions,
 sq.qtynonunique qty_stockroomlocation, sti.stockdefinitionperitem_id,
 srg.stockreservationpergrade_id, sq.stockroomlocation_id
from   stockdefinitionperitem sti
join   stockreservationpergrade srg
on     srg.stockdefinitionperitem_id = sti.stockdefinitionperitem_id
join   stockquantity sq
on     sq.stockreservationpergrade_id = srg.stockreservationpergrade_id
join   stockroomlocation stl
on     stl.stockroomlocation_id = sq.stockroomlocation_id
join   stockroom sr
on     sr.stockroom_id = stl.stockroom_id
join   product p
on     p.product_id = sti.product_id
join   sizedefinition s
on     s.sizedefinition_id = sti.sizedefinition_id
join   qualitygrade q
on     q.qualitygrade_id = srg.qualitygrade_id
where  sq.qtynonunique <> 0
/
create or replace view v_purchaseorder_auj as
select 1 linetype, poh.purchaseordernumber, poh.orderamount totalamountpo, rc.code reasoncode, sup.suppliernumber suppnumber, sup.name suppname,
       poh.orderdate, poh.remark pohremark, pol.quantityordered, pol.purchaseprice, pol.remark pliremark, poh.purchaseorderheader_id,
       pol.purchaseorderline_id, pol.supplierproductcode, pol.suppliersizecode,
       coalesce((select v.supplierproductdescription 
                   from (select sp.supplierproductdescription
                           from supplierproduct sp 
                           join productsizepersupproduct psp on sp.supplierproduct_id = psp.supplierproduct_id
                           join supplierproductprice spp on sp.supplierproduct_id=spp.supplierproduct_id
                          where sp.supplier_id = poh.supplier_id
                            and pol.product_link_id = psp.product_id 
                            and pol.sizedefinition_link_id = psp.sizedefinition_id
                            and spp.startdate <= poh.orderdate 
                            and sp.active = 'Y' order by spp.startdate desc, sp.supplierproduct_id desc) v
                  where rownum = 1),
                (select prd.description
                   from product_desc prd
                  where prd.product_id = pol.product_link_id
                    and prd.language_id = lan.language_id)) supplierproductdescription,
       (select su.fullname 
          from systemuser su 
         where su.systemuser_id = poh.orderuser_id) createdby,
       (select su.fullname 
          from systemuser su 
         where su.systemuser_id = poh.approvaluser_id) approvedby, pol.quantitycancelled,
       wol.quantityordered woqtyorderd, wol.quantitycancelled woqtycancelled, wol.quantityfilled woqtyfilled, lan.code languagecode,
       sup.orderformremark, sup.creditornumber,
       (select count(1)
          from product p 
          join productranking pr on p.productranking_id = pr.productranking_id
           and pol.product_link_id = p.product_id
           and pr.priority = 2) hasprio2,
       (select count(1)
          from product p 
          join productranking pr on p.productranking_id = pr.productranking_id
           and pr.priority = 0
           and pol.product_link_id = p.product_id
           and p.color_id in (select c.color_id from color c where c.code in ('2', '4'))) hasprio0color24, sup.paymentterms,
       wol.quantityordered quantity,
       nvl((select sum(woll.quantityordered)
              from workorderline woll
             where woll.purchaseorderline_id = pol.purchaseorderline_id
               and woll.reasoncode_id = (select rcc.reasoncode_id from reasoncode rcc where rcc.code = '091')), 0) woqty1,
       nvl((select sum(woll.quantityordered)
              from workorderline woll
             where woll.purchaseorderline_id = pol.purchaseorderline_id
               and woll.reasoncode_id <> (select rcc.reasoncode_id from reasoncode rcc where rcc.code = '091')), 0) woqty2,
       (select ps.sequencenumber
          from productsize ps
         where ps.product_id = pol.product_link_id
           and ps.sizedefinition_id = pol.sizedefinition_link_id) sequencenumber
  from purchaseorderheader poh
       join purchaseorderline pol on poh.purchaseorderheader_id = pol.purchaseorderheader_id
       join sizedefinition_link szl on pol.sizedefinition_link_id = szl.sizedefinition_link_id 
       left join workorderline wol on pol.purchaseorderline_id = wol.purchaseorderline_id 
       join workorder wo on wol.workorder_id = wo.workorder_id
       join status st on (wo.status_id = st.status_id and st.statustype = 'WO' and st.code <> '05')
       join reasoncode rc on wo.reasoncode_id = rc.reasoncode_id
       join stockroom sk on wo.processingstockroom_id = sk.stockroom_id
       join supplier sup on poh.supplier_id = sup.supplier_id, languages lan
 where wo.processingstockroom_id = poh.stockroom_id
union all
select 2 linetype, poh.purchaseordernumber, poh.orderamount totalamountpo, ' ' reasoncode, sup.suppliernumber suppnumber, sup.name suppname,
       poh.orderdate, poh.remark pohremark, pol.quantityordered, pol.purchaseprice, pol.remark pliremark, poh.purchaseorderheader_id,
       pol.purchaseorderline_id, pol.supplierproductcode, pol.suppliersizecode,
       coalesce((select v.supplierproductdescription 
                   from (select sp.supplierproductdescription
                           from supplierproduct sp 
                           join productsizepersupproduct psp on sp.supplierproduct_id = psp.supplierproduct_id
                           join supplierproductprice spp on sp.supplierproduct_id=spp.supplierproduct_id
                          where sp.supplier_id = poh.supplier_id
                            and pol.product_link_id = psp.product_id 
                            and pol.sizedefinition_link_id = psp.sizedefinition_id
                            and spp.startdate <= poh.orderdate 
                            and sp.active = 'Y' order by spp.startdate desc, sp.supplierproduct_id desc) v
                  where rownum = 1),
                (select prd.description
                   from product_desc prd
                  where prd.product_id = pol.product_link_id
                    and prd.language_id = lan.language_id)) supplierproductdescription,         
       (select su.fullname 
          from systemuser su 
         where su.systemuser_id = poh.orderuser_id) createdby,
       (select su.fullname 
          from systemuser su 
         where su.systemuser_id = poh.approvaluser_id) approvedby, pol.quantitycancelled, 0 woqtyorderd,
       0 woqtycancelled, 0 woqtyfilled, lan.code languagecode, sup.orderformremark, sup.creditornumber,
       (select count(1)
          from product p 
          join productranking pr on p.productranking_id = pr.productranking_id
           and pol.product_link_id = p.product_id
           and pr.priority = 2) hasprio2,
       (select count(1)
          from product p 
          join productranking pr on p.productranking_id = pr.productranking_id
           and pr.priority = 0
           and pol.product_link_id = p.product_id
           and p.color_id in (select c.color_id from color c where c.code in ('2', '4'))) hasprio0color24, sup.paymentterms,
       (pol.quantityordered - pol.quantitycancelled) quantity, 0 woqty1, 0 woqty2,
       (select ps.sequencenumber
          from productsize ps
         where ps.product_id = pol.product_link_id
           and ps.sizedefinition_id = pol.sizedefinition_link_id) sequencenumber
  from purchaseorderheader poh
       join purchaseorderline pol on poh.purchaseorderheader_id = pol.purchaseorderheader_id
       join sizedefinition_link szl on pol.sizedefinition_link_id = szl.sizedefinition_link_id
       join stockroom sk on poh.stockroom_id = sk.stockroom_id 
       join supplier sup on poh.supplier_id = sup.supplier_id, languages lan
 where poh.businessunit_id = sk.managedbybu_id 
   and not exists (select wo.workorderline_id from workorderline wo where wo.purchaseorderline_id = pol.purchaseorderline_id)
/
create or replace view v_purchaseorderdata_auj as
select sup.suppliernumber, sup.name suppliername, poh.purchaseordernumber, poh.orderdate, poh.requesteddate, 
       poh.firstreceivingdate, poh.lastreceivingdate, pol.supplierproductcode, pol.suppliersizecode,
       (select sp.supplierproductdescription
          from supplierproduct sp
         where sp.supplier_id = sup.supplier_id
           and sp.supplierproductcode = pol.supplierproductcode
           and sp.suppliersizecode = pol.suppliersizecode) supplierproductdesc, 
       pol.purchaseprice, pol.quantityordered, pol.quantityreceived, pol.quantitycancelled, pol.quantityorderedstock, 
       pol.quantityordereddirectissue, pol.quantityreceiveddirectissue, pol.quantityconfirmed
  from purchaseorderline pol
  join purchaseorderheader poh on pol.purchaseorderheader_id = poh.purchaseorderheader_id
  join supplier sup on poh.supplier_id = sup.supplier_id
  join status st on poh.status_id = st.status_id
 where st.statustype = 'PO' and st.code not in ('05', '50')
   and pol.quantityordered - pol.quantitycancelled <> 0
/
create or replace view v_purchaseorderline_auj as
select distinct
  pli.purchaseorderheader_id, pli.purchaseorderline_id, wok.workordernumber
/*, (case when wok.weareremployment_link_id is null then (select c.customernumber from customer c where wok.customer_link_id = c.customer_id)
  else cu.customernumber end) customernumber
, (case when wok.weareremployment_link_id is null then (select c.name from customer c where wok.customer_link_id = c.customer_id)
   else cu.name end) customerName
, w.wearernumber, w.fullname, wok.neededdate, wok.workorder_id*/
, prl.code productcode, sd.code sizecode
, (select pld.description from product_link_desc pld where pld.product_link_id = wokli.product_link_id and pld.language_id = lan.language_id) productdesc
, lan.code langcode
from
  purchaseorderline pli, workorderline wokli
, workorder wok/*
left outer join (weareremployment we
                left outer join
                ( wearer w join customer cu on w.customer_id = cu.customer_id
                )on w.wearer_id = we.wearer_id)
on wok.weareremployment_link_id = we.weareremployment_id*/
, product_link prl, sizedefinition_link sd, languages lan
where
    pli.purchaseorderline_id = wokli.purchaseorderline_id
and wokli.workorder_id = wok.workorder_id
and wokli.product_link_id = prl.product_link_id
and wokli.sizedefinition_link_id = sd.sizedefinition_link_id
union
select distinct
  pli.purchaseorderheader_id, pli.purchaseorderline_id, wok.workordernumber
, prl.code productcode, sd.code sizecode
, (select pld.description from product_link_desc pld where pld.product_link_id = wokli.product_link_id and pld.language_id = lan.language_id) productdesc
, lan.code langcode
from
  purchaseorderline pli, workorderline wokli, workorderlinepurchordline wolpol
, workorder wok, product_link prl, sizedefinition_link sd, languages lan
where pli.purchaseorderline_id=wolpol.workorderlinepurchordline_id and wokli.workorderline_id=wolpol.workorderline_id
and wokli.workorder_id = wok.workorder_id
and wokli.product_link_id = prl.product_link_id
and wokli.sizedefinition_link_id = sd.sizedefinition_link_id
union
select distinct
  pli.purchaseorderheader_id, pli.purchaseorderline_id, wok.workordernumber
--, cu.customernumber, cu.name customerName
/*, (case when wok.weareremployment_link_id is null then (select c.customernumber from customer c where wok.customer_link_id = c.customer_id)
  else cu.customernumber end) customernumber
, (case when wok.weareremployment_link_id is null then (select c.name from customer c where wok.customer_link_id = c.customer_id)
   else cu.name end) customerName
, w.wearernumber, w.fullname, wok.neededdate, wok.workorder_id*/
, prl.code productcode, sd.code sizecode
, (select pld.description from product_link_desc pld where pld.product_link_id = wokem.product_id and pld.language_id = lan.language_id) productdesc
, lan.code langcode
from
  purchaseorderline pli, workorderlineemblem wokem, workorderline wokli
, workorder wok
/*left outer join (weareremployment we
                left outer join
                ( wearer w join customer cu on w.customer_id = cu.customer_id
                )on w.wearer_id = we.wearer_id)
on wok.weareremployment_link_id = we.weareremployment_id*/
, product_link prl, sizedefinition_link sd, languages lan
where
    pli.purchaseorderline_id = wokem.purchaseorderline_id
and wokem.workorderline_id = wokli.workorderline_id
and wokli.workorder_id = wok.workorder_id
and wokem.product_id = prl.product_id
and wokem.sizedefinition_id = sd.sizedefinition_id
union
select distinct
  pli.purchaseorderheader_id, pli.purchaseorderline_id, wok.workordernumber
, prl.code productcode, sd.code sizecode
, (select pld.description from product_link_desc pld where pld.product_link_id = wokem.product_id and pld.language_id = lan.language_id) productdesc
, lan.code langcode
from
  purchaseorderline pli, workorderlineemblem wokem, workorderline wokli, workorderlinepurchordline wolpol
, workorder wok, product_link prl, sizedefinition_link sd, languages lan
where pli.purchaseorderline_id=wolpol.workorderlinepurchordline_id and wokli.workorderline_id=wolpol.workorderline_id
and pli.purchaseorderline_id = wokem.purchaseorderline_id
and wokem.workorderline_id = wokli.workorderline_id
and wokli.workorder_id = wok.workorder_id
and wokem.product_id = prl.product_id
and wokem.sizedefinition_id = sd.sizedefinition_id
/
create or replace view v_raggedreturneditems_auj as
select /*version 2.0*/
       och.outofcirculationhistory_id, rp.reportparam_id, cu.customernumber, cu.name customername,
       wel.wearernumber, wel.wearername fullname, pg.code productgroupcode, pr.code productcode,
       (select pd.description
          from product_desc pd
         where pd.product_id = pr.product_id
           and pd.language_id = lan.language_id) productdesc, siz.code sizecode,
       (select sdd.description
          from sizedefinition_desc sdd
         where sdd.sizedefinition_id = siz.sizedefinition_id
           and sdd.language_id = lan.language_id) sizedesc,
       (select rc.code
          from reasoncode rc
         where rc.reasoncode_id = och.reasoncode_id) reasoncode,
       (select rcd.description
          from reasoncode_desc rcd
         where rcd.reasoncode_id = och.reasoncode_id
           and rcd.language_id = lan.language_id) reasondesc, 
       och.quantity, och.primaryid, (och.weeksinusethisissue + och.weeksinuseprevissue) weeks, 
       och.residualvalue, och.tobechargedpercentage enteredpercentage, och.amount valuecharge, 
       och.outofcircdate, trunc(och.outofcircdate) outofcircdatetrunc, och.status, 
       (select su.username 
          from systemuser su 
         where och.systemuser_id = su.systemuser_id) username,
       dep.departmentnumber, dpl.distributionpointnumber consumptionpoint,
       och.invoiceheader_id invoicedyn, och.ragreason_id raggedreturnedyn,
       lan.code languagecode, och.customer_link_id,
       coalesce((select ui.washestotal
                   from uniqueitem ui
                  where ui.uniqueitem_id = och.uniqueitem_link_id), 
                (select ri.washestotal
                   from raggeditem ri
                  where ri.raggeditem_id = och.uniqueitem_link_id), 0) washestotal
  from outofcirculationhistory och
       left join weareremployment_link wel on och.weareremployment_link_id = wel.weareremployment_link_id 
       join distributionpoint_link dpl
            join department dep 
                 join customer cu on dep.customer_id = cu.customer_id
            on dpl.department_link_id = dep.department_id
       on och.distributionpoint_link_id = dpl.distributionpoint_link_id
       join product pr
            join productgroup pg on pr.productgroup_id = pg.productgroup_id
       on och.product_link_id = pr.product_id 
       join sizedefinition siz on och.sizedefinition_link_id = siz.sizedefinition_id
       cross join reportparam rp
             join languages lan 
       on rp.string_value = lan.code
 where och.chargetype = 1 
   and och.customer_link_id = cu.customer_id
   and cu.customernumber >= rp.number_value1
   and cu.customernumber <= rp.number_value2
   and dep.departmentnumber >= rp.number_value3
   and dep.departmentnumber <= rp.number_value4
   and dpl.distributionpointnumber >= rp.number_value5
   and dpl.distributionpointnumber <= rp.number_value6
   and exists (select 1
                 from businessunitsperusergroup bus, systemuser s
                where cu.defaultbusinessunit_id = bus.businessunit_id
                  and bus.usergroup_id = s.usergroup_id
                  and s.systemuser_id = rp.number_value) 
/

create or replace view v_routecontrol_AUJ as
Select c.routenumber, c.description routedescription, a.routelistprinted, a.soilticketsprinted, a.soilcountstatus,
a.settlementstatus, a.packingstatus, a.originaldrivingdate, a.drivingdate, d.daynumber packingdaynumber, a.overageamount,
a.voucheramount, a.totalcashcollected, a.totalcoddelayed, a.totalcodpaythisamnt, a.totalcodundelivered,a.totalcodplusadj,
a.totalcodminusadj, a.totalcodprebilled, a.totalchargeplusadj, a.totalchargecollections, a.totalchargepaythisamnt,
a.totalchargeundelivered, a.totalchargeminusadj, a.totalchargeprebilled, a.returntime, a.returndate, a.starttime,
a.loadingdock, a.packingdeadline, a.truckcode, a.drivernumber, b.code plantcode, b.name plantname, a.routecontrol_id,
s.street plantstreet, s.zipcode plantzipcode, s.city plantcity, s.street2 plantstreet2, e.code depotcode,
l.code Language_Code,
(select ddd.description from day_desc ddd where ddd.day_id = GETABSDAYNUMBER(a.drivingdate) and ddd.language_id = l.language_id) Day_Description,
(select emp.name from employee emp where emp.plant_id = a.plant_id and emp.employeenumber = a.drivernumber) Employee_Name,
(select da.daynumber from day da where da.day_id = GETABSDAYNUMBER(a.drivingdate) ) Day_Nr
from routecontrol a 
           LEFT OUTER JOIN day d ON (a.packingday_id = d.day_id),
     plant b, route c 
		       left outer join depot e on c.depot_id = e.depot_id, 
		 address s, languages l
where a.plant_id = b.plant_id
and a.route_id = c.route_id
and b.address_id = s.address_id
/
create or replace view V_ScansPerWearer_AUJ as
select--+ INDEX(sc XSPEEDSCAN) INDEX(dilk XPKDISTRIBUTIONPOINT_LINK) INDEX(prdlk XPKPRODUCT_LINK)
  culk.customernumber, culk.name customerName, culk.customer_id, delk.departmentnumber, delk.description departmentDesc
, wel.wearernumber, wel.wearername, sc.primaryid
, prdlk.code ProductCode, szlk.code SizeCode
, (select product_desc.description from product_desc where product_desc.product_id = prdlk.product_id
  and product_desc.language_id = lan.language_id ) ProductDesc
, sc.year, sc.week, sc.dayno
, (select day_desc.code from day_desc where day_desc.day_id = sc.dayno
  and day_desc.language_id = lan.language_id) dayCode
, to_char(sc.scantimestamp, 'HH24.MI.SS') scantimestamp
, trunc(sc.scantimestamp) ScanDate, trt.transactiontype_id
, (select transactiontype_desc.description from transactiontype_desc where transactiontype_desc.transactiontype_id = trt.transactiontype_id
  and transactiontype_desc.language_id = lan.language_id ) transactiontypeDesc
, trt.factorydescription, lan.code languageCode
, (select rc.code from reasoncode rc where sc.reasoncode_id = rc.reasoncode_id) reason_code
, (select wi1.maxinventory+wi1.maxfreeofcharge from wearerinventory wi1 
  where wi1.weareremployment_id = wel.weareremployment_link_id
  and wi1.product_id = prdlk.product_link_id and wi1.sizedefinition_id = szlk.sizedefinition_link_id) maxinventory
, (select wi2.changesperweek from wearerinventory wi2 where wi2.weareremployment_id = wel.weareremployment_link_id
  and wi2.product_id = prdlk.product_link_id and wi2.sizedefinition_id = szlk.sizedefinition_link_id) changesperweek
from scan sc
     join weareremployment_link wel
          join distributionpoint_link dilk
               join department_link delk
                    join customer culk 
                         join businessunit bu on culk.defaultbusinessunit_id = bu.businessunit_id 
                    on delk.customer_link_id = culk.customer_id
              on dilk.department_link_id = delk.department_link_id
          on wel.distributionpoint_link_id = dilk.distributionpoint_link_id
     on sc.weareremployment_link_id = wel.weareremployment_link_id
     join product_link prdlk on sc.product_link_id = prdlk.product_link_id
     join sizedefinition_link szlk on sc.sizedefinition_link_id = szlk.sizedefinition_link_id
     join transactiontype trt on sc.transactiontype_id = trt.transactiontype_id
     , languages lan
WHERE sc.customer_link_id = culk.customer_id
   and (trt.transactiontype_id <> 0
         and trt.transactiontype_id <> 10
         and trt.transactiontype_id <> 11
         and trt.transactiontype_id <> 40
         and trt.transactiontype_id <> 41
         and trt.transactiontype_id <> 50
         and trt.transactiontype_id <> 53
         and trt.transactiontype_id <> 60
         and trt.transactiontype_id <> 70
         and trt.transactiontype_id <> 71
         and trt.transactiontype_id <> 72
         and trt.transactiontype_id <> 73
         and trt.transactiontype_id <> 99)
/
create or replace view v_statementdetails_auj as
select /*version 1.0*/
       vi.statementheader_id, coalesce(vh.commoncustomer_nr, vh.billtocustomernumber) commoncustomer_nr, 
       sum(vh.paythisamount) common_amount, sum(vh.totalamountexclvat) exclvat_amount
  from v_invoiceheaderstatement_auj vh
       join v_statementinvoices_auj vi on vh.invoiceheader_id = vi.invoiceheader_id 
 where vh.linetype = 1
 group by vi.statementheader_id, coalesce(vh.commoncustomer_nr, vh.billtocustomernumber)
/

create or replace view v_statementheader_auj as
select a.enddate statementdate, a.invoicenumber statementnumber, e.code invoicebusinessunitcode, e.description invoicebusinessunitdesc,
a.billtocustomernumber, a.billtocustomername, a.deltocustomernumber, a.deltocustomername,
a.startweek, a.endweek, a.startmonth, a.endmonth, a.startyear, a.endyear, a.city, a.county, a.state, a.zipcode,
a.street2, a.street, a.contactpersonname, a.contactpersonphone,
a.emailstatus, a.emailaddress, a.realcollectiontype, a.originalcollectiontype, a.exported,
a.invoicecomments statementcomments, a.prebillamount, a.invoicefrequency_id statementfrequencynumber,
b.code currencycode, b.description currencydesc,
s.statustype, s.code statuscode, s.factorydescription statusfactorydescription,
c.countytaxrate, c.citytaxrate, c.statestaxrate,
p.code plantcode, p.name plantname, x.street plantstreet,x.street2 plantstreet2, x.zipcode plantzipcode,
x.city plantcity, x.state plantstate, x.county plantcounty, a.purchaseorder, a.routenumber,
a.systemuser_id, a.timestamp, a.invoiceheader_id statementheader_id,
F_GetArAgingAmount(a.billtocustomer_link_id, reportparam.number_value2, 0, getdateasvarcharfixedformat(reportparam.date_value1), getdateasvarcharfixedformat(reportparam.date_value2), getdateasvarcharfixedformat(reportparam.date_value3), getdateasvarcharfixedformat(reportparam.date_value4), null, a.invoiceheader_id) days0,
F_GetArAgingAmount(a.billtocustomer_link_id, reportparam.number_value2, 1, getdateasvarcharfixedformat(reportparam.date_value1), getdateasvarcharfixedformat(reportparam.date_value2), getdateasvarcharfixedformat(reportparam.date_value3), getdateasvarcharfixedformat(reportparam.date_value4), null, a.invoiceheader_id) days30,
F_GetArAgingAmount(a.billtocustomer_link_id, reportparam.number_value2, 2, getdateasvarcharfixedformat(reportparam.date_value1), getdateasvarcharfixedformat(reportparam.date_value2), getdateasvarcharfixedformat(reportparam.date_value3), getdateasvarcharfixedformat(reportparam.date_value4), null, a.invoiceheader_id)  days60,
F_GetArAgingAmount(a.billtocustomer_link_id, reportparam.number_value2, 3, getdateasvarcharfixedformat(reportparam.date_value1), getdateasvarcharfixedformat(reportparam.date_value2), getdateasvarcharfixedformat(reportparam.date_value3), getdateasvarcharfixedformat(reportparam.date_value4), null, a.invoiceheader_id)  days90,
F_GetArAgingAmount(a.billtocustomer_link_id, reportparam.number_value2, 4, getdateasvarcharfixedformat(reportparam.date_value1), getdateasvarcharfixedformat(reportparam.date_value2), getdateasvarcharfixedformat(reportparam.date_value3), getdateasvarcharfixedformat(reportparam.date_value4), null, a.invoiceheader_id)  days120,
F_PreviousStatement(a.invoicedate, a.billtocustomernumber, a.deltocustomernumber) previousbalance,
ihe.formlayoutcode statementlayoutcode,
(select chain.code
        from chain, customer
        where chain.chain_id = customer.chain_id and
              customer.customer_id = a.billtocustomer_link_id) billto_chain
, cast(fsget_cust_delivery_days(a.billtocustomer_link_id) as varchar2(7)) custdeliveryscheme
, reportparam.reportparam_id, reportparam.copy_number, reportparam.string_value
, p.phoneno plantphoneno, p.faxno plantfax, p.email plantemail, a.netpaymentdays
, ihe.paymenttermsduedate
, (select max(v.invoicedate) from V_StatementLine_AUJ v where v.statementheader_id = a.invoiceheader_id ) Max_InvoiceDate
, (select count(1) from V_StatementInvoices_AUJ vsi where vsi.statementheader_id = a.invoiceheader_id) NrOfInvoices
, (select lan.code from languages lan where lan.language_id = p.language_id) language_plant
, (select sa.code from salesarea sa, customer bil where bil.customer_id = a.billtocustomer_link_id
          and sa.salesarea_id = bil.salesarea_id) salesarea_code
from invoiceheader a
left outer join invoiceheaderus c on (a.invoiceheader_id = c.invoiceheader_id)
, currency b, businessunit e, status s, plant p, address x
, invoiceheaderextrainfo ihe
, reportparam
where a.currency_id = b.currency_id
and a.documenttype = 2
and a.invoicebusinessunit_id = e.businessunit_id
and a.status_id = s.status_id
and e.plant_id = p.plant_id
and p.address_id = x.address_id
and a.invoiceheader_id = ihe.invoiceheader_id
and reportparam.number_value = a.invoicenumber
and reportparam.copy_number = 0
and reportparam.string_value is null
/
create or replace view v_statementheader_auj_sl as
select /*version 1.0*/
       ih.enddate statementdate, ih.invoicenumber statementnumber, bu.code invoicebusinessunitcode,
       bu.description invoicebusinessunitdesc, ih.billtocustomernumber, ih.billtocustomername,
       ih.deltocustomernumber, ih.deltocustomername, ih.startweek, ih.endweek, ih.startmonth,
       ih.endmonth, ih.startyear, ih.endyear, ih.city, ih.county, ih.state, ih.zipcode, ih.street2,
       ih.street, ih.contactpersonname, ih.contactpersonphone, ih.emailstatus, ih.emailaddress,
       ih.realcollectiontype, ih.originalcollectiontype, ih.exported,
       ih.invoicecomments statementcomments, ih.prebillamount,
       ih.invoicefrequency_id statementfrequencynumber, cur.code currencycode,
       cur.description currencydesc, s.statustype, s.code statuscode,
       s.factorydescription statusfactorydescription, ihus.countytaxrate, ihus.citytaxrate,
       ihus.statestaxrate, p.code plantcode, p.name plantname, pad.street plantstreet,
       pad.street2 plantstreet2, pad.zipcode plantzipcode, pad.city plantcity, pad.state plantstate,
       pad.county plantcounty, ih.purchaseorder, ih.routenumber, ih.systemuser_id, ih.timestamp,
       ih.invoiceheader_id statementheader_id, 0 days0, 0 days30, 0 days60, 0 days90, 0 days120,
       ihe.formlayoutcode statementlayoutcode, ih.netpaymentdays, ihe.paymenttermsduedate,
       (select chain.code from chain where chain.chain_id = billto.chain_id) billto_chain,
       cast(fsget_cust_delivery_days(ih.billtocustomer_link_id) as varchar2(7)) custdeliveryscheme,
       1 reportparam_id, 0 copy_number, p.phoneno plantphoneno, p.faxno plantfax, p.email plantemail,
       (select max(v.invoicedate)
          from v_statementline_auj_sl v
         where v.statementheader_id = ih.invoiceheader_id) max_invoicedate,
       (select count(1)
          from v_statementinvoices_auj vsi
         where vsi.statementheader_id = ih.invoiceheader_id) nrofinvoices,
       (select lan.code from languages lan where lan.language_id = p.language_id) language_plant,
       (select sa.code
          from customer bil
               join salesarea sa on bil.salesarea_id = sa.salesarea_id
         where bil.customer_id = ih.billtocustomer_link_id) salesarea_code,
       (select macc.customernumber
          from customer macc
         where macc.customer_id = billto.masteraccount_id) masteraccount,
       (select payby.customernumber
          from customerbillinginfo cbi
               join customer payby on cbi.paybycustomer_link_id = payby.customer_id
         where cbi.customer_id = ih.billtocustomer_link_id) paybycustomer
  from invoiceheader ih
       left join customer billto on ih.billtocustomer_link_id = billto.customer_id
       left join invoiceheaderus ihus on ih.invoiceheader_id = ihus.invoiceheader_id
       join invoiceheaderextrainfo ihe on ih.invoiceheader_id = ihe.invoiceheader_id
       join status s on ih.status_id = s.status_id
       join currency cur on ih.currency_id = cur.currency_id
       join businessunit bu
            join plant p
                 join address pad on p.address_id = pad.address_id 
            on bu.plant_id = p.plant_id 
       on ih.invoicebusinessunit_id = bu.businessunit_id
 where ih.documenttype = 2 
/

create or replace view v_statementheader_auj_sln as
select /*version 1.1*/
       ih.enddate statementdate, ih.invoicenumber statementnumber, bu.code invoicebusinessunitcode,
       bu.description invoicebusinessunitdesc, ih.billtocustomernumber, ih.billtocustomername,
       ih.deltocustomernumber, ih.deltocustomername, ih.startweek, ih.endweek, ih.startmonth,
       ih.endmonth, ih.startyear, ih.endyear, ih.city, ih.county, ih.state, ih.zipcode, ih.street2,
       ih.street, ih.contactpersonname, ih.contactpersonphone, ih.emailstatus, ih.emailaddress,
       ih.realcollectiontype, ih.originalcollectiontype, ih.exported,
       ih.invoicecomments statementcomments, ih.prebillamount,
       ih.invoicefrequency_id statementfrequencynumber, cur.code currencycode,
       cur.description currencydesc, s.statustype, s.code statuscode,
       s.factorydescription statusfactorydescription, ihus.countytaxrate, ihus.citytaxrate,
       ihus.statestaxrate, p.code plantcode, p.name plantname, pad.street plantstreet,
       pad.street2 plantstreet2, pad.zipcode plantzipcode, pad.city plantcity, pad.state plantstate,
       pad.county plantcounty, ih.purchaseorder, ih.routenumber, ih.systemuser_id, ih.timestamp,
       ih.invoiceheader_id statementheader_id, 0 days0, 0 days30, 0 days60, 0 days90, 0 days120,
       ihe.formlayoutcode statementlayoutcode, ih.netpaymentdays, ihe.paymenttermsduedate,
       (select chain.code from chain where chain.chain_id = billto.chain_id) billto_chain,
       cast(fsget_cust_delivery_days(ih.billtocustomer_link_id) as varchar2(7)) custdeliveryscheme,
       1 reportparam_id, 0 copy_number, p.phoneno plantphoneno, p.faxno plantfax, p.email plantemail,
       (select max(v.invoicedate)
          from v_statementline_auj_sln v
         where v.statementheader_id = ih.invoiceheader_id) max_invoicedate,
       (select count(1)
          from v_statementinvoices_auj vsi
         where vsi.statementheader_id = ih.invoiceheader_id) nrofinvoices,
       (select lan.code from languages lan where lan.language_id = p.language_id) language_plant,
       (select sa.code
          from customer bil
               join salesarea sa on bil.salesarea_id = sa.salesarea_id
         where bil.customer_id = ih.billtocustomer_link_id) salesarea_code,
       (select macc.customernumber
          from customer macc
         where macc.customer_id = billto.masteraccount_id) masteraccount,
       (select payby.customernumber
          from customerbillinginfo cbi
               join customer payby on cbi.paybycustomer_link_id = payby.customer_id
         where cbi.customer_id = ih.billtocustomer_link_id) paybycustomer,
       (select payby.name
          from customerbillinginfo cbi
               join customer payby on cbi.paybycustomer_link_id = payby.customer_id
         where cbi.customer_id = ih.billtocustomer_link_id) paybyname,
       (select payby.paymenttype
          from customerbillinginfo cbi
               join customer payby on cbi.paybycustomer_link_id = payby.customer_id
         where cbi.customer_id = ih.billtocustomer_link_id) paymenttype
  from invoiceheader ih
       left join customer billto on ih.billtocustomer_link_id = billto.customer_id
       left join invoiceheaderus ihus on ih.invoiceheader_id = ihus.invoiceheader_id
       join invoiceheaderextrainfo ihe on ih.invoiceheader_id = ihe.invoiceheader_id
       join status s on ih.status_id = s.status_id
       join currency cur on ih.currency_id = cur.currency_id
       join businessunit bu
            join plant p
                 join address pad on p.address_id = pad.address_id 
            on bu.plant_id = p.plant_id 
       on ih.invoicebusinessunit_id = bu.businessunit_id
 where ih.documenttype = 2 
/

create or replace view v_statementinvoices_auj as
select distinct sh.invoiceheader_id statementheader_id, ih.invoiceheader_id
, (select comm.customernumber from customer comm, customer del where ih.deltocustomer_link_id = del.customer_id
  and comm.customer_id = coalesce(del.commoncustomer_id, del.debtor_id)) commoncustomer_nr
, sh.invoicenumber  statementnumber
from invoiceheader sh, statementline sl, artransaction ar, invoiceheader ih, invoiceheaderextrainfo she
where sh.invoiceheader_id = sl.invoiceheader_id
and sl.artransaction_id = ar.artransaction_id
and ar.invoiceheader_id = ih.invoiceheader_id
and ih.documenttype <> 2
and sh.documenttype = 2
and she.invoiceheader_id = sh.invoiceheader_id--for the Summary layout do not select child invoices
and she.formlayoutcode <> '2'
/
create or replace view v_statementline_auj as
select /*version 2.1*/
       sh.invoicedate, sh.invoicenumber statementnumber, ilt.type invoicelinetype,
       sl.transactiontype_id, art.typenumber transactiontypenumber, art.code transactiontypecode,
       sl.transactionreference, sl.transactiondate, sl.debitcredit,
       coalesce((ilv.overamount + case when il.adjustmentreason_id is null 
                                       then il.amount else il.adjustedamount end), 
                sl.amount) amount, 
       sl.percentage, sl.systemuser_id, sl.timestamp,
       sl.statementline_id, sl.invoiceheader_id statementheader_id, sl.artransaction_id, cc.pnnumber,
       del.customernumber del_number, del.name del_name, cc.customernumber commoncustomer_number,
       cc.name commoncustomer_name, ar.invoiceheader_id ar_invoiceheader_id, ar.amount ar_amount,
       coalesce((ilv.percentage*nvl(ilv.overamount, ih.totalamountexclvat)/100),
                (case when il.adjustmentreason_id is null 
                      then il.amount else il.adjustedamount end), 
                (ar.amount * coalesce(ilv.percentage, ilvnew.percentage, 0) / 100), 0) vatamount,
       (select sa.code from salesarea sa where cc.salesarea_id = sa.salesarea_id) salesarea_code,
       nvl(il.code, ilnew.code) taxgroupcode, 
       coalesce(ilv.overamount, ih.totalamountexclvat) amountexclvat,
       coalesce(ilv.percentage, ilvnew.percentage, 0) taxrate, 
       ih.invoicenumber, ih.invoicedate childdate, ih.totalamountexclvat,
       coalesce((case when il.adjustmentreason_id is null 
                      then il.amount else il.adjustedamount end), 
                (case when ilnew.adjustmentreason_id is null 
                      then ilnew.amount else ilnew.adjustedamount end), 
                (ar.amount - ih.totalamountexclvat), 0) vatamountold
  from statementline sl
       left join artransactiontype art on sl.transactiontype_id = art.artransactiontype_id
       left join artransaction ar
            join customer del
                 join customer cc on nvl(del.commoncustomer_id, del.debtor_id) = cc.customer_id 
            on nvl(ar.deltocustomer_link_id, ar.billtocustomer_link_id) = del.customer_id
            left join invoiceheader ih
                 left join invoiceline il
                      left join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id 
                 on ih.invoiceheader_id = il.invoiceheader_id and il.invoicelinetype_id = 18 
            on ar.invoiceheader_id = ih.invoiceheader_id 
       on sl.artransaction_id = ar.artransaction_id
       join invoicelinetype ilt on sl.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader sh 
            left join invoiceline ilnew
                 left join invoicelinevarious ilvnew on ilnew.invoiceline_id = ilvnew.invoiceline_id 
            on sh.invoiceheader_id = ilnew.invoiceheader_id and ilnew.invoicelinetype_id = 18
       on sl.invoiceheader_id = sh.invoiceheader_id
 where sh.documenttype = 2 
/

create or replace view v_statementline_auj_sl as
select /*version 1.0*/
       sh.invoicedate, sh.invoicenumber statementnumber, ilt.type invoicelinetype,
       sl.transactiontype_id, art.typenumber transactiontypenumber, art.code transactiontypecode,
       sl.transactionreference, sl.transactiondate, sl.debitcredit,
       coalesce(ilv.overamount + case
                  when il.adjustmentreason_id is null 
                    then il.amount
                  else il.adjustedamount end, sl.amount) amount, 
       sl.percentage, sl.systemuser_id, sl.timestamp, sl.statementline_id, 
       sl.invoiceheader_id statementheader_id, sl.artransaction_id, cc.pnnumber,
       del.customernumber del_number, del.name del_name, cc.customernumber commoncustomer_number,
       cc.name commoncustomer_name, ar.invoiceheader_id ar_invoiceheader_id, ar.amount ar_amount,
       coalesce(case
                  when il.adjustmentreason_id is null 
                    then il.amount
                  else il.adjustedamount end, 
                (ar.amount - ih.totalamountexclvat), 0) vatamount,
       (select sa.code from salesarea sa where cc.salesarea_id = sa.salesarea_id) salesarea_code,
       il.code taxgroupcode, coalesce(ilv.overamount, ih.totalamountexclvat) amountexclvat,
       coalesce(ilv.percentage, 0) taxrate, ih.invoicenumber, ih.invoicedate childdate, ih.totalamountexclvat
  from statementline sl
       left join artransactiontype art on sl.transactiontype_id = art.artransactiontype_id
       left join artransaction ar
            left join invoiceheader ih
                 left join invoiceline il
                      join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id 
                 on ih.invoiceheader_id = il.invoiceheader_id and il.invoicelinetype_id = 18 
            on ar.invoiceheader_id = ih.invoiceheader_id 
            join customer del
                 join customer cc on coalesce(del.commoncustomer_id, del.debtor_id) = cc.customer_id 
            on coalesce(ar.deltocustomer_link_id, ar.billtocustomer_link_id) = del.customer_id       
       on sl.artransaction_id = ar.artransaction_id
       join invoicelinetype ilt on sl.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader sh on sl.invoiceheader_id = sh.invoiceheader_id
 where sh.documenttype = 2 
/

create or replace view v_statementline_auj_sln as
select /*version 1.0*/
       sh.invoicedate, sh.invoicenumber statementnumber, ilt.type invoicelinetype,
       sl.transactiontype_id, art.typenumber transactiontypenumber, art.code transactiontypecode,
       sl.transactionreference, sl.transactiondate, sl.debitcredit,
       coalesce(ilv.overamount + case when il.adjustmentreason_id is null 
                                      then il.amount else il.adjustedamount end, sl.amount) amount, 
       sl.percentage, sl.systemuser_id, sl.timestamp,
       sl.statementline_id, sl.invoiceheader_id statementheader_id, sl.artransaction_id, cc.pnnumber,
       del.customernumber del_number, del.name del_name, cc.customernumber commoncustomer_number,
       cc.name commoncustomer_name, ar.invoiceheader_id ar_invoiceheader_id, ar.amount ar_amount,
       coalesce((ilv.percentage*coalesce(ilv.overamount, ih.totalamountexclvat)/100),
                case when il.adjustmentreason_id is null 
                     then il.amount else il.adjustedamount end, 
                (ar.amount - ih.totalamountexclvat), 0) vatamount,
       (select sa.code from salesarea sa where cc.salesarea_id = sa.salesarea_id) salesarea_code,
       il.code taxgroupcode, coalesce(ilv.overamount, ih.totalamountexclvat) amountexclvat,
       coalesce(ilv.percentage, 0) taxrate, ih.invoicenumber, ih.invoicedate childdate, ih.totalamountexclvat,
       coalesce(case when il.adjustmentreason_id is null 
                     then il.amount else il.adjustedamount end, 
                (ar.amount - ih.totalamountexclvat), 0) vatamountold
  from statementline sl
       left join artransactiontype art on sl.transactiontype_id = art.artransactiontype_id
       left join artransaction ar
            join customer del
                 join customer cc on coalesce(del.commoncustomer_id, del.debtor_id) = cc.customer_id 
            on coalesce(ar.deltocustomer_link_id, ar.billtocustomer_link_id) = del.customer_id
            left join invoiceheader ih
                 left join invoiceline il
                      join invoicelinevarious ilv on il.invoiceline_id = ilv.invoiceline_id 
                 on ih.invoiceheader_id = il.invoiceheader_id and il.invoicelinetype_id = 18 
            on ar.invoiceheader_id = ih.invoiceheader_id 
       on sl.artransaction_id = ar.artransaction_id
       join invoicelinetype ilt on sl.invoicelinetype_id = ilt.invoicelinetype_id
       join invoiceheader sh on sl.invoiceheader_id = sh.invoiceheader_id
 where sh.documenttype = 2 
/

create or replace view v_stockroompicklist_auj as
select qgOrder.Code qgOrderCode, s.code stockroomCode, s.name stockroomDescription, sl.rowcode rowCode
, sl.locationcode locationCode, sl.pickingsequence, qgReserved.Newgarment UniqueYN, prd.code ProductCode
, (select product_desc.description from product_desc where product_desc.product_id = prd.product_id
  and product_desc.language_id = languages.language_id) productDescription
, sizedef.code ReservedSizeCode, qgReserved.code qgReservedCode
, (select sl.code from sizedefinition_link sl where sl.sizedefinition_link_id = wokli.sizedefinition_link_id) RequestedSizeCode
, wok.workordernumber, wokli.workorderline_id
, wok.neededdate ReqstdDelivery, wokli.quantityordered
, wokli.quantitycancelled
, sum(WRE.QUANTITY) WorkOrderLineReservationQTY
, cu.customernumber, cu.name customerName
, coalesce(we.wearernumber, d.distributionpointnumber) wearernumber
, coalesce(we.wearersearchname, d.description) wearerSearchname
, languages.code languageCode
, wokli.codeuniquely
, (sq.qtyunique + sq.qtynonunique) qtyonstock
, coalesce((select psz.sequencenumber from productsize psz where psz.product_id = prd.product_id and psz.sizedefinition_id = sizedef.sizedefinition_link_id), 0) SizeSequence
from workorderlinereservation wre
     inner join workorderline wokli
           inner join workorder wok
                 left outer join weareremployment_link we on wok.weareremployment_link_id = we.weareremployment_id
                 left outer join distributionpoint_link d on wok.distributionpoint_link_id = d.distributionpoint_link_id
                 inner join customer_link cu on wok.customer_link_id = cu.customer_id
           on wokli.workorder_id = wok.workorder_id
           inner join qualitygrade qgOrder on wokli.requestedgrade_id = qgOrder.Qualitygrade_Id
     on wre.workorderline_id = wokli.workorderline_id  
     inner join stockreservationpergrade srg
           left outer join stockquantity sq 
                inner join stockroomlocation sl on sq.stockroomlocation_id = sl.stockroomlocation_id and sl.locationtype_id <> 11
           on srg.stockreservationpergrade_id = sq.stockreservationpergrade_id
           inner join qualitygrade qgReserved on srg.qualitygrade_id = qgReserved.qualitygrade_id
           inner join stockdefinitionperitem sdi
                 inner join stockroom s on sdi.stockroom_id = s.stockroom_id
                 inner join product_link prd on sdi.product_id = prd.product_id
                 inner join sizedefinition_link sizedef on sdi.sizedefinition_id = sizedef.sizedefinition_id
           on srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
     on wre.stockreservationpergrade_id = srg.stockreservationpergrade_id
, languages
group by qgOrder.Code, s.code, s.name, sl.rowcode
, sl.locationcode , sl.pickingsequence, qgReserved.Newgarment, prd.code
, prd.product_id, languages.language_id
, sizedef.code, sizedef.sizedefinition_link_id, qgReserved.code
, wok.workordernumber ,wokli.workorderline_id
, wok.neededdate, wokli.quantityordered
, wokli.quantitycancelled
, cu.customernumber, cu.name
, coalesce(we.wearernumber, d.distributionpointnumber)
, coalesce(we.wearersearchname, d.description)
, languages.code, wokli.codeuniquely, wokli.sizedefinition_link_id, sq.qtyunique, sq.qtynonunique
/
create or replace view v_stockroompicklist_gr_auj as
select /*version 2.1*/
       wok.workorder_id, min(prd.code) pcode
  from workorder wok
       join workorderline wokli 
            join qualitygrade qgOrder on wokli.requestedgrade_id = qgOrder.Qualitygrade_Id
            join workorderlinereservation wre 
                 join stockreservationpergrade srg
                      left join stockquantity sq
                                join stockroomlocation sl on sl.stockroomlocation_id = sq.stockroomlocation_id and sl.locationtype_id <> 11
                      on srg.stockreservationpergrade_id = sq.stockreservationpergrade_id
                      join qualitygrade qgReserved on srg.qualitygrade_id = qgReserved.qualitygrade_id
                      join stockdefinitionperitem sdi 
                           join stockroom s on sdi.stockroom_id = s.stockroom_id
                           join product_link prd on sdi.product_id = prd.product_id
                           join sizedefinition_link sizedef on sdi.sizedefinition_id = sizedef.sizedefinition_id
                      on srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
                 on wre.stockreservationpergrade_id = srg.stockreservationpergrade_id
            on wokli.workorderline_id = wre.workorderline_id        
       on wok.workorder_id = wokli.workorder_id
       join weareremployment_link we on wok.weareremployment_link_id = we.weareremployment_id
       join customer_link cu on wok.customer_link_id = cu.customer_id
       cross join languages
 where (sq.qtyunique + sq.qtynonunique) > 0
 group by wok.workorder_id 
union all
select wok.workorder_id, min(prd.code) pcode
  from workorder wok
       join workorderline wokli 
            join qualitygrade qgOrder on wokli.requestedgrade_id = qgOrder.Qualitygrade_Id
            join workorderlinereservation wre on wokli.workorderline_id = wre.workorderline_id
                 join stockreservationpergrade srg
                      left join stockquantity sq
                                join stockroomlocation sl on sl.stockroomlocation_id = sq.stockroomlocation_id and sl.locationtype_id <> 11
                      on srg.stockreservationpergrade_id = sq.stockreservationpergrade_id
                      join qualitygrade qgReserved on srg.qualitygrade_id = qgReserved.qualitygrade_id
                      join stockdefinitionperitem sdi 
                           join stockroom s on sdi.stockroom_id = s.stockroom_id
                           join product_link prd on sdi.product_id = prd.product_id
                           join sizedefinition_link sizedef on sdi.sizedefinition_id = sizedef.sizedefinition_id
                      on srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
                 on wre.stockreservationpergrade_id = srg.stockreservationpergrade_id
       on wok.workorder_id = wokli.workorder_id
       cross join languages
 where wok.weareremployment_link_id is NULL
   and (sq.qtyunique + sq.qtynonunique) > 0
 group by  wok.workorder_id
 order by 2,1
/
CREATE OR REPLACE VIEW V_TURNOVERCOMPARISON_AUJ AS
select 
       rp.reportparam_id,
       art.currencycode,
       art.invoiceamountdecimals,
       art.groupcode,
       art.groupdesc,
       art.customerphoneno,
       art.customercity,
       tog.turnovergroupcode,
       tog.turnovergroupdescription,
       la.code languagecode,
       SUM(case when art.ARTRANSACTIONDATE between rp.date_value1 and rp.date_value2 
                then AD.AMOUNT
                else 0
           end) PERIOD_1_AMOUNT,
       SUM(case when art.ARTRANSACTIONDATE between rp.date_value3 and rp.date_value4
                then AD.AMOUNT
                else 0
           end) PERIOD_2_AMOUNT
  from artransactiondetail ad,
       reportparam rp, 
       languages la,
       (select tg.turnovergroup_id,
               tg.code turnovergroupcode,
               tod.description turnovergroupdescription,
               tod.language_id,
               rp.reportparam_id,
               ss.plant_id
          from turnovergroup tg, turnovergroup_desc tod, reportparam rp, systemsetting ss
         where tg.turnovergroup_id = tod.turnovergroup_id and ss.name='TAXDEFINITION'
           and ((
               case ss.value 
                 when 'US' then (select count(states_id) from states where states.turnovergroup_id = tg.turnovergroup_id) 
                 when 'EU' then (select count(taxgroup_id) from taxgroup where taxgroup.turnovergroup_id = tg.turnovergroup_id) 
                   else 0 end = 0
                ) 
                or rp.string_value = 'N')
       ) tog,
     (select -- TurnoverGr
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             '1' groupcode,
             '1' groupdesc,
             null customerphoneno,
             null customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and a.debitcredit='D'
         and rp.number_value1=1 -- TurnoverGr
      UNION ALL --=======
      select -- chain
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             cu.groupcode,
             cu.groupdesc,
             cu.customerphoneno,
             cu.customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l,
             (select c.customer_id,
                     c.customer_id GROUPID,
                     H.CODE GROUPCODE,
                     H.NAME GROUPDESC,
                     null CUSTOMERPHONENO,
                     null CUSTOMERCITY,
                     RP.REPORTPARAM_ID
                FROM CUSTOMER C
                     LEFT OUTER JOIN CHAIN H ON C.CHAIN_ID = H.CHAIN_ID,
                     REPORTPARAM RP
               WHERE H.CODE between rp.string_value7 and rp.string_value8
                 AND rp.number_value1=2 -- CHAIN
             ) cu
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and cu.customer_id = a.billtocustomer_link_id
         and cu.reportparam_id = rp.reportparam_id
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and a.debitcredit='D'
         AND rp.number_value1=2 -- CHAIN
      UNION ALL --=======
      select  -- market segment
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             cu.groupcode,
             cu.groupdesc,
             cu.customerphoneno,
             cu.customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l,
             (select c.customer_id,
                     c.customer_id GROUPID,
                     M.CODE GROUPCODE,
                     (SELECT MSD.DESCRIPTION
                        FROM MARKETSEGMENT_DESC MSD
                       WHERE MSD.MARKETSEGMENT_ID = M.MARKETSEGMENT_ID
                         AND MSD.LANGUAGE_ID = LAN.LANGUAGE_ID) GROUPDESC,
                     null CUSTOMERPHONENO,
                     null CUSTOMERCITY,
                     LAN.LANGUAGE_ID,
                     RP.REPORTPARAM_ID
                FROM CUSTOMER C,
                     MARKETSEGMENT M,
                     REPORTPARAM RP,
                     LANGUAGES LAN
               WHERE M.MARKETSEGMENT_ID = C.MARKETSEGMENT_ID
                 AND M.CODE between rp.string_value7 and rp.string_value8
                 AND rp.number_value1=3 -- MARKETSEGEMENT
             ) cu
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and cu.customer_id = a.billtocustomer_link_id
         and cu.reportparam_id = rp.reportparam_id
         and cu.language_id = l.language_id
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and a.debitcredit='D'
         AND rp.number_value1=3 -- MARKETSEGEMENT
      UNION ALL --=======
      select -- sales area
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             cu.groupcode,
             cu.groupdesc,
             cu.customerphoneno,
             cu.customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l,
             (select c.customer_id,
                     c.customer_id GROUPID,
                     S.CODE GROUPCODE,
                     (SELECT SAD.DESCRIPTION
                        FROM SALESAREA_DESC SAD
                       WHERE SAD.SALESAREA_ID = S.SALESAREA_ID
                         AND SAD.LANGUAGE_ID = LAN.LANGUAGE_ID) GROUPDESC,
                     null CUSTOMERPHONENO,
                     null CUSTOMERCITY,
                     LAN.LANGUAGE_ID,
                     RP.REPORTPARAM_ID
                FROM CUSTOMER C,
                     SALESAREA S,
                     REPORTPARAM RP,
                     LANGUAGES LAN
               WHERE S.SALESAREA_ID = C.SALESAREA_ID
                 AND S.CODE between rp.string_value7 and rp.string_value8
                 AND rp.number_value1=4 -- SALES AREA
             ) cu
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and cu.customer_id = a.deltocustomer_link_id
         and cu.reportparam_id = rp.reportparam_id
         and cu.language_id = l.language_id
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and a.debitcredit='D'
         AND rp.number_value1=4 -- SALES AREA
      UNION ALL --=======
      select -- Route
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             to_char(R.ROUTENUMBER) groupcode,
             R.description groupdesc,
             null customerphoneno,
             null customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             route r,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and A.ROUTE_ID = R.ROUTE_ID
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and r.routenumber BETWEEN rp.number_value2 and rp.number_value3
         and a.debitcredit='D'
         AND rp.number_value1=5 -- ROUTE
      UNION ALL --=======
      select -- Customer
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             cu.groupcode,
             cu.groupdesc,
             cu.customerphoneno,
             cu.customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l,
             (select c.customer_id,
                     c.customer_id GROUPID,
                     TO_CHAR(C.CUSTOMERNUMBER) GROUPCODE,
                     C.NAME GROUPDESC,
                     C.PHONENO CUSTOMERPHONENO,
                     ADR.CITY CUSTOMERCITY,
                     RP.REPORTPARAM_ID
                FROM CUSTOMER C,
                     ADDRESS ADR,
                     REPORTPARAM RP
               WHERE ADR.ADDRESS_ID = C.Visitaddress_Id
                 AND C.CUSTOMERNUMBER between rp.number_value2 and rp.number_value3
                 AND rp.number_value1=6 -- CUSTOMER
             ) cu
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and cu.customer_id = a.billtocustomer_link_id
         and cu.reportparam_id = rp.reportparam_id
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and a.debitcredit='D'
         AND rp.number_value1=6 -- CUSTOMER
      UNION ALL --=======
      select -- Depot
             a.artransaction_id,
             a.artransactiondate,
             cur.code currencycode,
             cur.invoiceamountdecimals,
             de.code groupcode,
             de.description groupdesc,
             null customerphoneno,
             null customercity,
             rp.reportparam_id,
             l.language_id, bu.plant_id
        from artransaction a,
             route r,
             depot de,
             currency cur,
             businessunit bu,
             businessunit procbu,
             reportparam rp,
             languages l
       where (
             a.artransactiondate between rp.date_value1 and rp.date_value2
          or
             a.artransactiondate between rp.date_value3 and rp.date_value4)
         and bu.businessunit_id = a.businessunit_id
         and procbu.businessunit_id = a.processbusinessunit_id
         and cur.currency_id = a.currency_id
         and A.ROUTE_ID = R.ROUTE_ID
         and R.DEPOT_ID = DE.DEPOT_ID
         and bu.code BETWEEN rp.string_value1 AND rp.string_value2
         and procbu.code BETWEEN rp.string_value3 AND rp.string_value4
         and de.code BETWEEN rp.string_value7 AND rp.string_value8
         and a.debitcredit='D'
         and rp.number_value1=7 -- DEPOT
     ) art
where ad.artransaction_id = art.artransaction_id
   and ad.turnovergroup_id = tog.turnovergroup_id
   and tog.language_id = la.language_id
   and tog.reportparam_id = rp.reportparam_id
   and art.reportparam_id = rp.reportparam_id
   and art.language_id = la.language_id
   and tog.turnovergroupcode BETWEEN rp.string_value5 AND rp.string_value6
   and tog.plant_id = art.plant_id
group by rp.reportparam_id,
         art.currencycode,
         art.invoiceamountdecimals,
         art.groupcode,
         art.groupdesc,
         tog.turnovergroupcode,
         tog.turnovergroupdescription,
         art.customerphoneno,
         art.customercity,
         la.code
/
create or replace view v_workorder_auj as
select /* version 2.2*/
       wok.workorder_id, wok.workordernumber, wok.neededdate orderdate, wok.origin origin, wok.workordernumber docket, cu.customernumber, cu.name,
       address.street, address.street2, address.zipcode, address.city, cu.phoneno, nvl(de.departmentnumber, de2.departmentnumber) departmentnumber,      
       w.searchname wearersearchname, w.fullname wearername, wok.remark wo_remark, wok.referencenumber wo_refnumber, wok.externalremark, 
       wok.customerowned notlaundryowned, su.fullname sysuser_name, bu.code bucode, bu.description budesc, cu.customermarkinggarment custnameonlabel, 
       wok.creationtimestamp, wok.approvaltimestamp, cu.legalname, ro.description routedescription, cu.name custsearchname, lan.code language_code,
       case when isnumeric(nvl(de.legacydepartmentcode, de2.legacydepartmentcode)) = 1 then to_number(nvl(de.legacydepartmentcode, de2.legacydepartmentcode))
            else 0
        end routenumber, 
       coalesce((select count(wokli.workorderline_id) 
                   from workorderline wokli 
                  where wok.workorder_id = wokli.workorder_id), 0) countworkorderline,
       coalesce((select count(wokem.workorderlineemblem_id)
                   from workorderline wokli
                   join workorderlineemblem wokem on wokli.workorderline_id = wokem.workorderline_id
                  where wok.workorder_id = wokli.workorder_id), 0) countworkorderlineemblem,
       (select ss.value
          from systemsetting ss
         where ss.plant_id = plant.plant_id
           and ss.name = 'PRINTBARCODEONWORKORDER') print_barcode, 
       (select sy.value
          from systemsetting sy
         where sy.plant_id = plant.plant_id
           and sy.name = 'PRINTREPLACEMENTSONWO') printreplacementsonwo, 
       (select rd.description
          from reasoncode rc, reasoncode_desc rd
         where rc.reasoncode_id = wok.reasoncode_id
           and rc.reasoncode_id = rd.reasoncode_id
           and rd.language_id = lan.language_id) reasoncodedesc,
       coalesce((select sa.code 
                   from salesarea sa 
                  where cu.salesarea_id = sa.salesarea_id), '') salesareacode, 
       (select min(cdd.day_id)
          from customerdeliveryday cdd
         where cdd.customer_id = cu.customer_id
           and cdd.typeofmerchadise = 2
           and cdd.deliverytype = 'B') customerbillingdays,
       (select gj.pcode from v_stockroompicklist_gr_auj gj where gj.workorder_id = wok.workorder_id) pcode,
       nvl((select sum(sq.qtyunique + sq.qtynonunique) 
              from workorderline wokli
                   join workorderlinereservation wolr
                        join stockquantity sq 
                             join stockroomlocation sl on sq.stockroomlocation_id = sl.stockroomlocation_id 
                        on wolr.stockreservationpergrade_id = sq.stockreservationpergrade_id
                   on wokli.workorderline_id = wolr.workorderline_id       
             where sl.locationtype_id <> 11
               and wokli.workorder_id = wok.workorder_id)
          , 0) totstockqtyWO
  from workorder wok
       left join weareremployment we
            join wearer w on we.wearer_id = w.wearer_id
            join distributionpoint dp 
                 join department de on dp.department_id = de.department_id
            on we.distributionpoint_id = dp.distributionpoint_id
       on wok.weareremployment_link_id = we.weareremployment_id
       left join distributionpoint dp2
            join department de2 on dp2.department_id = de2.department_id
       on wok.distributionpoint_link_id = dp2.distributionpoint_id
       left join customer cu
            join address address on cu.visitaddress_id = address.address_id
       on wok.customer_link_id = cu.customer_id
       left join route ro on wok.route_id = ro.route_id
       left join systemuser su on wok.creationuser_id = su.systemuser_id
       join status on wok.status_id = status.status_id
       join businessunit bu 
            join plant on bu.plant_id = plant.plant_id
       on wok.businessunit_id = bu.businessunit_id
       cross join languages lan
/

create or replace view v_workorderemblem_auj as
select 1 linetype, wol.workorder_id, wole.workorderline_id, wole.qtyrequested,
       wole.emblemtemplateline_id,
       castNumberAsVarchar(etl.emblemtype) emblemtype,
       (select et.code from emblemtemplate et where etl.emblemtemplate_id = et.emblemtemplate_id) emblcode,
       etl.description embltemplate_desc,
       (select p.code from placement p where p.placement_id = wole.placement_id) placementcode,
       (select pld.description from placement_desc pld where pld.placement_id = wole.placement_id and pld.language_id = lan.language_id) placementdesc,
       (select pr.code from product_link pr where pr.product_link_id = wol.product_link_id) prodcode,
       (select prd.description from product_link_desc prd where prd.product_link_id = wol.product_link_id and prd.language_id = lan.language_id) proddesc,
       lan.code languagecode
from workorderline wol, workorderlineemblem wole, emblemtemplateline etl, languages lan
where wol.workorderline_id = wole.workorderline_id
      and wole.emblemtemplateline_id = etl.emblemtemplateline_id
union all
select 2 linetype, wol.workorder_id, wole.workorderline_id, wole.qtyrequested,
       p.product_id emblemtemplateline_id,
       'Other' emblemtype,
       p.code emblcode,
       (select pd.description from product_desc pd where pd.product_id = p.product_id and pd.language_id = lan.language_id) embltemplate_desc,
       (select p.code from placement p where p.placement_id = wole.placement_id) placementcode,
       (select pld.description from placement_desc pld where pld.placement_id = wole.placement_id and pld.language_id = lan.language_id) placementdesc,
       (select pr.code from product_link pr where pr.product_link_id = wol.product_link_id) prodcode,
       (select prd.description from product_link_desc prd where prd.product_link_id = wol.product_link_id and prd.language_id = lan.language_id) proddesc,
       lan.code languagecode
from workorderline wol, workorderlineemblem wole, product p, languages lan
where wol.workorderline_id = wole.workorderline_id
      and wole.product_id = p.product_id
/
create or replace view v_workorderline_auj as
select /*version 2.3*/
       wokli.workorderline_id, wokli.workorder_id, prdlk.code prodnr, fm.code finmethcode, szlk.code sizecode, wokli.codeuniquely uniqueyn, reqg.code requestqualgradecode,
       wokli.quantityordered, wokli.quantitycancelled, (wokli.quantityordered - wokli.quantitycancelled) qorder, wokli.quantityfilled qdone, lan.code languagecode,
       (wokli.quantityordered - wokli.quantityfilled - wokli.quantitycancelled) qopen, wokli.instructions  wi_remark, ps.sequencenumber sizesequencenumber, sum(wolr.quantity) reservedqty,
       f_getrowlocation(srg.stockreservationpergrade_id, wokli.codeuniquely) rowcode,
       f_getlocationcode(srg.stockreservationpergrade_id, wokli.codeuniquely) locationcode,
       nvl(get_flexfield_string((select max(plpc.productlistpercustomer_id)
                                   from productlistpercustomer plpc 
                                        join workorder wo on plpc.customer_id = wo.customer_link_id
                                  where plpc.product_id = wokli.product_link_id 
                                   and (plpc.sizedefinition_id = wokli.sizedefinition_link_id 
                                        or plpc.sizedefinition_id = (select sd.sizedefinition_id from sizedefinition sd where sd.code = '*'))
                                   and plpc.finishingmethod_id = wokli.finishingmethod_id
                                   and wo.workorder_id = wokli.workorder_id
                                   and trunc(wo.creationtimestamp) between plpc.dateactive and plpc.dateinactive), 'ProductListPerCustomer', 'RFID'), 'N') rfid,
       (select pr.ranking
          from product p
               join productranking pr on p.productranking_id = pr.productranking_id
         where p.product_id = prdlk.product_id) prodranking,
       (select pds.description
          from product_desc pds
         where prdlk.product_id = pds.product_id
           and pds.language_id = lan.language_id) proddescription,  
       (select fd.description 
          from finishingmethod_desc fd
         where fd.finishingmethod_id = fm.finishingmethod_id 
           and fd.language_id = lan.language_id) fm_desc,    
       (select qgd.description
          from qualitygrade_desc qgd
         where qgd.qualitygrade_id = reqg.qualitygrade_id
           and qgd.language_id = lan.language_id) requestqualgradedesc,
       (select resqg.newgarment
          from qualitygrade resqg
         where srg.qualitygrade_id = resqg.qualitygrade_id) reservednewgarm,
       (select sd.code 
          from stockdefinitionperitem sdi 
               join sizedefinition sd on sdi.sizedefinition_id = sd.sizedefinition_id
         where sdi.stockdefinitionperitem_id = srg.stockdefinitionperitem_id) reservedsizecode,
       (select qg.code 
          from qualitygrade qg
         where srg.qualitygrade_id = qg.qualitygrade_id) reservedqualitycode,
       coalesce((select md.description
                   from wearerinventory wi
                        join workorder wo on wi.weareremployment_id = wo.weareremployment_link_id
                        join wearerinventorymodification wim on wi.wearerinventory_id = wim.wearerinventory_id
                        join modification m on wim.modification_id = m.modification_id
                        join modification_desc md on m.modification_id = md.modification_id
                  where wo.workorder_id = wokli.workorder_id
                    and wi.product_id = prdlk.product_id
                    and wi.sizedefinition_id = szlk.sizedefinition_link_id
                    and wi.finishingmethod_id = fm.finishingmethod_id
                    and wim.sequencenumber = 1
                    and md.language_id = lan.language_id),
                (select md.description
                   from modification_desc md 
                        join workorderlinemodification wlm on md.modification_id = wlm.modification_id
                  where wlm.workorderline_id = wokli.workorderline_id
                    and wlm.sequencenumber = 1 
                    and md.language_id = lan.language_id)) wi_modif1,
       coalesce((select md.description
                   from wearerinventory wi
                        join workorder wo on wi.weareremployment_id = wo.weareremployment_link_id
                        join wearerinventorymodification wim on wi.wearerinventory_id = wim.wearerinventory_id
                        join modification m on wim.modification_id = m.modification_id
                        join modification_desc md on m.modification_id = md.modification_id
                  where wo.workorder_id = wokli.workorder_id
                    and wi.product_id = prdlk.product_id
                    and wi.sizedefinition_id = szlk.sizedefinition_link_id
                    and wi.finishingmethod_id = fm.finishingmethod_id
                    and wim.sequencenumber = 2
                    and md.language_id = lan.language_id),
                (select md.description
                    from modification_desc md 
                         join workorderlinemodification wlm on md.modification_id = wlm.modification_id
                   where wlm.workorderline_id = wokli.workorderline_id
                     and wlm.sequencenumber = 2
                     and md.language_id = lan.language_id)) wi_modif2,
       coalesce((select md.description
                   from wearerinventory wi
                        join workorder wo on wi.weareremployment_id = wo.weareremployment_link_id
                        join wearerinventorymodification wim on wi.wearerinventory_id = wim.wearerinventory_id
                        join modification m on wim.modification_id = m.modification_id
                        join modification_desc md on m.modification_id = md.modification_id
                  where wo.workorder_id = wokli.workorder_id
                    and wi.product_id = prdlk.product_id
                    and wi.sizedefinition_id = szlk.sizedefinition_link_id
                    and wi.finishingmethod_id = fm.finishingmethod_id
                    and wim.sequencenumber = 3
                    and md.language_id = lan.language_id),
                (select md.description
                    from modification_desc md 
                         join workorderlinemodification wlm on md.modification_id = wlm.modification_id
                   where wlm.workorderline_id = wokli.workorderline_id
                     and wlm.sequencenumber = 3
                     and md.language_id = lan.language_id)) wi_modif3,
       (select sum(sq.qtyunique+sq.qtynonunique) 
          from stockquantity sq 
               join stockroomlocation sl on sq.stockroomlocation_id = sl.stockroomlocation_id
         where sl.locationtype_id <> 11
           and sq.stockreservationpergrade_id = srg.stockreservationpergrade_id ) totstockqty
  from workorderline wokli
       left join qualitygrade reqg on wokli.requestedgrade_id = reqg.qualitygrade_id
       left join finishingmethod fm on wokli.finishingmethod_id = fm.finishingmethod_id
       left join sizedefinition_link szlk on wokli.sizedefinition_link_id = szlk.sizedefinition_link_id
       left join product_link prdlk on wokli.product_link_id = prdlk.product_link_id
       left join productsize ps on prdlk.product_id = ps.product_id and szlk.sizedefinition_id = ps.sizedefinition_id
       left join workorderlinereservation wolr
                 join stockreservationpergrade srg on wolr.stockreservationpergrade_id = srg.stockreservationpergrade_id
       on wokli.workorderline_id = wolr.workorderline_id
       cross join languages lan
 group by wokli.workorder_id, wokli.workorderline_id, wolr.stockreservationpergrade_id, srg.stockreservationpergrade_id, srg.stockdefinitionperitem_id, prdlk.code, prdlk.product_id,
       fm.code, fm.finishingmethod_id, szlk.code, reqg.code, reqg.qualitygrade_id, wokli.quantityordered, wokli.quantitycancelled, srg.qualitygrade_id,wokli.quantityfilled, 
       wokli.codeuniquely, lan.code, lan.language_id, szlk.sizedefinition_link_id, ps.sequencenumber, wokli.instructions, wokli.product_link_id,
       wokli.sizedefinition_link_id, wokli.finishingmethod_id
/
CREATE OR REPLACE VIEW V_WORKORDERSPERPO_REP_AUJ AS
SELECT wo.workorder_id, wo.workordernumber, wo.requestdate, wo.neededdate
, cu.customer_id, cu.customernumber, cu.name CustomerName
, poh.purchaseordernumber
, su.suppliernumber, su.name SuppName
, lan.code Lan_code
FROM workorder wo, workorderline wol
, customer cu
, product prd, sizedefinition sd
, purchaseorderline pol, purchaseorderheader poh
, productsizepersupproduct ps, supplierproduct sp, supplier su
, languages lan
WHERE wo.workorder_id = wol.workorder_id
and wo.customer_link_id=cu.customer_id
and wol.product_link_id = prd.product_id and wol.sizedefinition_link_id = sd.sizedefinition_id
and wol.purchaseorderline_id = pol.purchaseorderline_id and pol.purchaseorderheader_id = poh.purchaseorderheader_id
and ps.product_id = wol.product_link_id and ps.sizedefinition_id = wol.sizedefinition_link_id
and sp.supplierproduct_id = ps.supplierproduct_id and sp.supplier_id = su.supplier_id
and poh.supplier_id=su.supplier_id
and lan.language_id=2
and wo.status_id<>23
and wol.quantityfilled<>wol.quantityordered
group by
wo.workorder_id, wo.workordernumber, wo.requestdate, wo.neededdate
, cu.customer_id, cu.customernumber, cu.name
, poh.purchaseordernumber
, su.suppliernumber, su.name
, lan.code
/
create or replace view v_workordersperproduct_auj as
select /*version 2.0*/
b.code bucode, c.customernumber, c.name customername
, p.code productcode
, (select pdes.description from product_desc pdes where pdes.product_id = p.product_id and pdes.language_id = lan.language_id) description
, sd.code sizecode, fm.code fmcode
, w.workordernumber, st.factorydescription
, w.entrydate, w.requestdate, w.completiondate
, wol.quantityordered, wol.quantitypendingorder
, wol.quantityfilled, wol.quantitycancelled
from workorder w
     join workorderline wol on w.workorder_id = wol.workorder_id
          join product p on wol.product_link_id = p.product_id
          join sizedefinition sd on wol.sizedefinition_link_id = sd.sizedefinition_id
          join finishingmethod fm on wol.finishingmethod_id = fm.finishingmethod_id
     join customer c on w.customer_link_id = c.customer_id
     join businessunit b on w.businessunit_id = b.businessunit_id
     join status st on w.status_id = st.status_id
     , languages lan
where wol.completiondate = to_date('31-12-2099', 'dd-mm-yyyy')
and st.code not in ('05', '30', '40')
and st.statustype = 'WO'
order by b.code, c.customernumber, w.requestdate
/
