 
/*********************************************\
*   ABSSOLUTE Oracle Objects                  *
*                                             *
*   Objects:           FUNCTIONS              *
*   Database version:  09.10.00               *
*   Date:              17-FEB-2026            *
\*********************************************/
 
set define off 
 
create or replace function abs_encrypt wrapped
a000000
369
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
253 1ad
TTq8X+MPE9wE9YQKiXU9NsqcM6gwg/D3Lq5qfHRAOj68Yvfo5dX9Dz3I8XdMCjKhiRqEAOmp
U7imNnHO/hSM9brGN3ZR2zMeemReYQlTo6FTqs6lrpbQuw8gTxp3GeU850ajFaeIzH+3zHx9
owMoZ3n79YuxtHmTHSQeeKHJMZSl/6gCE2xZw38Xfn+YibFUJsHqbl2mNcELAoFAVUTetPpC
YIQ5Y3yQSlQZMqs1eDyxJe6eLoorpfCBmJ6NS8ofcTDtb58tnOBSUCEM64mLduqvsndsdrQD
ygXo++prX9LtagQFgcXmOr3eyhFMttD0cDxCsAZYdLcOSQTviyKh2PNLNHMDMalasC9gL9lg
hFgVtStwGPzvmfdLxHs/z86ddeeu5eG2/1aHR/j9rcJg3hyw21OBEHok+Dm+ixOD
/
create or replace function base64encode(p_blob in blob) return clob is
  --function base64encode version 0.1
  l_clob clob;
  l_step number := 12000;
begin
  for i in 0 .. trunc((dbms_lob.getlength(p_blob) - 1) / l_step) loop
    begin
      l_clob := l_clob ||
                utl_raw.cast_to_varchar2(utl_encode.base64_encode(dbms_lob.substr(p_blob, l_step,
                                                                                  i * l_step + 1)));
    end;
  end loop;
  return l_clob;
exception
  when others then
    return null;
end base64encode;
/
create or replace function castNumberAsVarchar(
			FPnumber	number
) return varchar2 is
begin
	return cast(FPnumber as varchar2);
end;
/
create or replace function castNumberAsVarcharWithFormat(
			FPnumber	number,
			FPformat	varchar2
) return varchar2 is
begin
	return to_char(FPnumber, FPformat);
end;
/
create or replace function castVarcharAsNumber(
			FPstring	varchar2
) return number is
begin
	return cast(FPstring as number);
end;
/
create or replace function CASTVARCHARASNUMBERINT(FPstring varchar2)
  return number is

begin
  return cast(FPstring as INTEGER);
end CASTVARCHARASNUMBERINT;
/
create or replace FUNCTION CBD_FSGET_MIN_6_YEARWEEKS_REV (INV_HEADER_ID NUMBER,
                                                          inv_freq_id number)
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(47);
 hlpStr varchar2(47);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';

    /*select f.invoicefrequencynumber
    into hlp
    from invoicefrequency f
    where f.invoicefrequency_id = inv_freq_id;

    if (hlp = 110) or (hlp = 45) or (hlp = 10) or
       (hlp =  20) or (hlp = 30) or (hlp = 40) or (hlp = 200) then*/
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;

       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l
                    where l.invoiceheader_id = INV_HEADER_ID
                       and l.invoiceline_id = cri.invoiceline_id
                       --and rownum < 6
                       order by cri.year desc, cri.week desc) loop

           hlp := vCsr.year * 100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;

           if (cnt = 6) then
              return hlpStr;
           end if;

       end loop;

       if cnt < 6 then
          for i in (cnt+1)..6 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;

       return hlpStr;
   /* else
       return dummyStr;
    end if;*/
exception
    when no_data_found then return dummyStr;
end;
/
create or replace FUNCTION CFSGETDESC_PRODUCT (
        FPnPRODUCT_ID                             in     PRODUCT.PRODUCT_ID%type,
        FPnLANGUAGE_ID                            in     LANGUAGES.LANGUAGE_ID%TYPE) return varchar2 is
   LVnDescription                                  PRODUCT_DESC.description%TYPE;
begin
  select DESCRIPTION into LVnDescription
  from PRODUCT_DESC
  where PRODUCT_ID = FPnPRODUCT_ID and
        LANGUAGE_ID = FPnLANGUAGE_ID;
  return LVnDescription;
exception
  when others then
       return null;
end;
/
create or replace function concatenate (
       FPstr1     varchar2,
       FPstr2     varchar2
) return varchar2 is
begin
     return FPstr1 || FPstr2;
end;
/
create or replace function concatenate3 (
       FPstr1     varchar2,
       FPstr2     varchar2,
       FPstr3     varchar2
) return varchar2 is
begin
     return FPstr1 || FPstr2 || FPstr3;
end;
/
create or replace function concatenateWithBlank (
       FPstr1     varchar2,
       FPstr2     varchar2
) return varchar2 is
begin
     return FPstr1 || ' ' || FPstr2;
end;
/
create or replace function concatenateWithBlank3 (
       FPstr1     varchar2,
       FPstr2     varchar2,
       FPstr3     varchar2
) return varchar2 is
begin
     return FPstr1 || ' ' || FPstr2 || ' ' || FPstr3;
end;
/
create or replace function concatenateWithSign (
       FPstr1     varchar2,
       SIGN_i       varchar2,
       FPstr2     varchar2
) return varchar2 is
begin
     return FPstr1 || SIGN_i || FPstr2;
end;
/
create or replace function determine_delivery_date(fp_customerid           in CUSTOMER.CUSTOMER_ID%type,
                                                   fp_dayid                in DAY.DAY_ID%type,
                                                   fp_stockcountscheduleid in STOCKCOUNTSCHEDULE.STOCKCOUNTSCHEDULE_ID%type,
                                                   fp_webuserid            in WEBUSER.WEBUSER_ID%type,
                                                   fp_fromdepartmentno     in number,
                                                   fp_todepertmentno       in number,
                                                   fp_reportrunid          in number,
                                                   fp_order_date           in date,
                                                   fp_distributionpoint_id in DISTRIBUTIONPOINT.DISTRIBUTIONPOINT_ID%type,
                                                   fp_typeofmerchandise    in PRODUCT.TYPEOFMERCHANDISE%type)
  return date is
  SQL_STMT                     varchar2(1500);
  fp_daynr                     DAY.DAY_ID%type;
  fp_weeknr                    integer;
  fp_yearnr                    integer;
  fp_foundstockcountscheduleid STOCKCOUNTSCHEDULE.STOCKCOUNTSCHEDULE_ID%type;
  fp_deliverydaydetermination  STOCKCOUNTSCHEDULE.DELIVERYDAYDETERMINATION%type;
  fp_deliverydayid             STOCKCOUNTSCHEDULEDAY.DELIVERYDAY_ID%type;
  fp_deliveryday               integer;
  fp_deliverydate              date;
begin
  fp_daynr  := GETABSDAYNUMBER(fp_order_date);
  fp_weeknr := GETISOWEEK(fp_order_date);
  fp_yearnr := GETYEAROFWEEK(fp_order_date);
  if (fp_stockcountscheduleid = -1) then
    --get all active distribution points per customer
    SQL_STMT := 'select SC.STOCKCOUNTSCHEDULE_ID
                     from DEPARTMENT DEP
                     join DISTRIBUTIONPOINT DIP
                       on DIP.DEPARTMENT_ID = DEP.DEPARTMENT_ID
                     join STOCKCOUNTSCHEDULEDIST SCSDIST
                       on SCSDIST.DISTRIBUTIONPOINT_ID = DIP.DISTRIBUTIONPOINT_ID
                     join STOCKCOUNTSCHEDULE SC
                       on SC.STOCKCOUNTSCHEDULE_ID = SCSDIST.STOCKCOUNTSCHEDULE_ID
                     join STOCKCOUNTSCHEDULEDAY SCDAY
                       on (SCDAY.STOCKCOUNTSCHEDULE_ID = SC.STOCKCOUNTSCHEDULE_ID and
                          SC.CUSTOMER_ID = DEP.CUSTOMER_ID)
                    where DIP.ACTIVE = ''Y''
                      and DEP.CUSTOMER_ID = ' ||
                fp_customerid || ' and DEP.ACTIVE = ''Y''
                      and SCDAY.DAY_ID = ' || fp_dayid ||
                ' and SC.REPLENISHMENTTYPE = 0';
  else
    --get all active distribution points in stock count schedule
    SQL_STMT := 'select SC.STOCKCOUNTSCHEDULE_ID
                     from STOCKCOUNTSCHEDULEDIST SCSDIST
                     join STOCKCOUNTSCHEDULE SC
                       on SC.STOCKCOUNTSCHEDULE_ID = SCSDIST.STOCKCOUNTSCHEDULE_ID
                     join DISTRIBUTIONPOINT DIP
                       on DIP.DISTRIBUTIONPOINT_ID = SCSDIST.DISTRIBUTIONPOINT_ID
                     join DEPARTMENT DEP
                       on DEP.DEPARTMENT_ID = DIP.DEPARTMENT_ID
                    where SC.REPLENISHMENTTYPE = 0
                      and DIP.ACTIVE = ''Y''
                      and SCSDIST.STOCKCOUNTSCHEDULE_ID = ' ||
                fp_stockcountscheduleid || ' and DEP.ACTIVE = ''Y''';
  end if;
  if (fp_webuserid > -1) then
    SQL_STMT := SQL_STMT || ' and (exists
        (select 1
           from WEBUSERDEPARTMENT WDEP
           join WEBUSERCUSTOMER WCUST
             on WCUST.WEBUSERCUSTOMER_ID = WDEP.WEBUSERCUSTOMER_ID
          where WDEP.DEPARTMENT_ID = DEP.DEPARTMENT_ID
            and WCUST.WEBUSER_ID = ' || fp_webuserid ||
                ' and WCUST.CUSTOMER_ID = DEP.CUSTOMER_ID) or not exists
        (select 1
           from WEBUSERDEPARTMENT WDEP
           join WEBUSERCUSTOMER WCUST
             on WCUST.WEBUSERCUSTOMER_ID = WDEP.WEBUSERCUSTOMER_ID
          where WCUST.WEBUSER_ID = ' || fp_webuserid ||
                ' and WCUST.CUSTOMER_ID = DEP.CUSTOMER_ID)) ';
  end if;
  if (fp_fromdepartmentno > -1) then
    SQL_STMT := SQL_STMT || ' and DEP.DEPARTMENTNUMBER >= ' ||
                fp_fromdepartmentno || ' and DEP.DEPARTMENTNUMBER <= ' ||
                fp_todepertmentno;
  else
    if (fp_reportrunid > -1) then
      SQL_STMT := SQL_STMT ||
                  ' and DEP.DEPARTMENT_ID in (select T.NUMBER_VALUE from REPORTPARAM T WHERE T.REPORTPARAM_ID = ' ||
                  fp_reportrunid || ')';
    end if;
  end if;
  SQL_STMT := SQL_STMT || ' and DIP.DISTRIBUTIONPOINT_ID = ' ||
              fp_distributionpoint_id;
  execute immediate SQL_STMT
    into fp_foundstockcountscheduleid;
  select SCS.DELIVERYDAYDETERMINATION
    into fp_deliverydaydetermination
    from STOCKCOUNTSCHEDULE SCS
   where SCS.STOCKCOUNTSCHEDULE_ID = fp_foundstockcountscheduleid;
  select SCSD.DELIVERYDAY_ID
    into fp_deliverydayid
    from STOCKCOUNTSCHEDULEDAY SCSD
   where SCSD.STOCKCOUNTSCHEDULE_ID = fp_foundstockcountscheduleid
     and SCSD.DAY_ID = fp_dayid
     and exists
   (select 1
            from STOCKCOUNTSCHEDULEDIST SCSDIST
           where SCSDIST.STOCKCOUNTSCHEDULE_ID =
                 fp_foundstockcountscheduleid
             and SCSDIST.DISTRIBUTIONPOINT_ID = fp_distributionpoint_id);
  if (fp_deliverydaydetermination = 1) then
    fp_deliveryday := fp_deliverydayid;
    if (fp_deliveryday >= fp_daynr) then
      fp_deliverydate := GETDATEFORWEEKYEAR(fp_deliveryday,
                                            fp_weeknr,
                                            fp_yearnr);
    else
      fp_deliverydate := GETDATEFORWEEKYEAR(fp_deliveryday,
                                            fp_weeknr + 1,
                                            fp_yearnr);
    end if;
  else
    begin
      if (fp_typeofmerchandise = 3) then
        fp_deliverydate := PACK_SORT.GETNEXTDELIVERYDATE(fp_order_date,
                                                         fp_customerid,
                                                         1);
      else
        fp_deliverydate := PACK_SORT.GETNEXTDELIVERYDATE(fp_order_date,
                                                         fp_customerid,
                                                         fp_typeofmerchandise);
      end if;
      fp_deliveryday := GETABSDAYNUMBER(fp_deliverydate);
    exception
      when others then
        begin
          fp_deliveryday := fp_deliverydayid;
          if (fp_deliveryday >= fp_daynr) then
            fp_deliverydate := GETDATEFORWEEKYEAR(fp_deliveryday,
                                                  fp_weeknr,
                                                  fp_yearnr);
          else
            fp_deliverydate := GETDATEFORWEEKYEAR(fp_deliveryday,
                                                  fp_weeknr + 1,
                                                  fp_yearnr);
          end if;
        end;
    end;
  end if;
  return fp_deliverydate;
end determine_delivery_date;
/
create or replace function determine_max_cart_qty(fp_plant_id in number,
                                                  fp_product_id in number,
                                                  fp_size_id in number,
                                                  fp_transportarticle_id in number) return number is
/*This function returns the max cart qty for given plant,product,size,transportarticle.
  All parameters are obligated.
  It goes to 8 steps from most detailed level of definition to least detailed level.
  First 4 steps are on size level, second 4 steps on product level.
  Volume factor of transport item is taken into account when needed.
  When no max cart qty can be determined the funcion returns null
*/
  MaxCartQtyResult    number;
  lv_volumefactor     number;
  lv_use_volumefactor varchar2(1);

begin
  -- step 1: check on plant, product, size, transport article level
  begin
    select ppsta.maxcartqty
      into MaxCartQtyResult
      from plantproductsizetransparticle ppsta
     where ppsta.plant_id = fp_plant_id
       and ppsta.product_id = fp_product_id
       and ppsta.sizedefinition_id = fp_size_id
       and ppsta.transportarticle_id = fp_transportarticle_id;
    lv_use_volumefactor := 'N';
  exception
    when no_data_found then
      MaxCartQtyResult := -1;
    when others then
      MaxCartQtyResult := 0;
  end;

  -- step 2: check on plant, product, size level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select ppss.maxcartqty
        into MaxCartQtyResult
        from plantproductsizesettings ppss
       where ppss.plant_id = fp_plant_id
         and ppss.product_id = fp_product_id
         and ppss.sizedefinition_id = fp_size_id;
    lv_use_volumefactor := 'Y';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- step 3: check on product, size, transport article level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select psta.maxcartqty
        into MaxCartQtyResult
        from productsizetransparticle psta
       where psta.product_id = fp_product_id
         and psta.sizedefinition_id = fp_size_id
         and psta.transportarticle_id = fp_transportarticle_id;
    lv_use_volumefactor := 'N';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- 4 check on product, size level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select ps.maxcartqty
        into MaxCartQtyResult
        from productsize ps
       where ps.product_id = fp_product_id
         and ps.sizedefinition_id = fp_size_id;
    lv_use_volumefactor := 'Y';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- 5 check on plant, product, transport article level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select ppta.maxcartqty
        into MaxCartQtyResult
        from plantproducttransportarticle ppta
       where ppta.plant_id = fp_plant_id
         and ppta.product_id = fp_product_id
         and ppta.transportarticle_id = fp_transportarticle_id;
    lv_use_volumefactor := 'N';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- 6 check on plant, product level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select pp.maxcartqty
        into MaxCartQtyResult
        from plantproductsettings pp
       where pp.plant_id = fp_plant_id
         and pp.product_id = fp_product_id;
    lv_use_volumefactor := 'Y';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- 7 check on product, transport article level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select pta.maxcartqty
        into MaxCartQtyResult
        from producttransportarticle pta
       where pta.product_id = fp_product_id
         and pta.transportarticle_id = fp_transportarticle_id;
    lv_use_volumefactor := 'N';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  -- 8 check on product level
  if nvl(MaxCartQtyResult,0) <= 0 then
    begin
      select p.maxcartqty
        into MaxCartQtyResult
        from product p
       where p.product_id = fp_product_id;
    lv_use_volumefactor := 'Y';
    exception
      when no_data_found then
        MaxCartQtyResult := -1;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  if nvl(MaxCartQtyResult,0) > 0 and lv_use_volumefactor = 'Y' then
    begin
      select t.volumefactor
        into lv_volumefactor
        from transportarticle t
       where t.transportarticle_id = fp_transportarticle_id;
    exception
      when no_data_found then
        MaxCartQtyResult := null;
      when others then
        MaxCartQtyResult := null;
    end;
  end if;

  if lv_use_volumefactor = 'N' then
    lv_volumefactor := 1;
  end if;

  return(MaxCartQtyResult*lv_volumefactor);
end determine_max_cart_qty;
/
create or replace FUNCTION DWH_STR(FPnSTRING_ID number) return varchar2 is
  Vstring    dwh_string_desc.string%type;
  Vmaxlength dwh_string.maxstringlength%type;
begin
  select nvl(sd.string, '???'), s.maxstringlength
    into Vstring, Vmaxlength
    from dwh_string s, dwh_string_desc sd, languages l, dwh_settings dwh
   where s.dwh_string_id = FPnSTRING_ID
     and l.language_id = dwh.language_id
     and sd.dwh_string_id = s.dwh_string_id
     and sd.languagecode = l.code
     and dwh.dwh_settings_id = 1;
  return Substr(Vstring, 1, Vmaxlength);
exception
  when no_data_found then
    begin
      -- take factory description
      select nvl(s.factorydescription, '???'), s.maxstringlength
        into Vstring, Vmaxlength
        from dwh_string s
       where s.dwh_string_id = FPnSTRING_ID;
      return Substr(Vstring, 1, Vmaxlength);
    exception
      when no_data_found then
        begin
          Vstring := '???';
          return Vstring;
        end;
    end;
end;
/
create or replace function employeenumber_unique(workspot        number,
                                                 employee_number number,
                                                 employeeID      number,
                                                 plantID         number)
  return integer is
  count_empl number;
begin
  if workspot = 1 then
    select count(1)
      into count_empl
      from employee e1, employee e2
     where e2.employee_id <> employeeID
       and e2.employeenumber = employee_number;
  else
    select count(1)
      into count_empl
      from employee e1, employee e2
     where e2.employee_id <> employeeID
       and e2.employeenumber = employee_number
       and e2.plant_id = plantID;
  end if;
  if count_empl = 0 then
    return(1);--true - not exists double employeenumbers
  else
    return(0);--false - exists double employeenumbers
  end if;
end employeenumber_unique;
/
create or replace function ExistsSQItemInfoOnWearerLevel(
  customerID            customer.customer_id%type,
  startYearWeek         int,
  endYearWeek           int
) return int is

begin
  for c in (select sqi.statusquoheader_id from sqitemincirculation sqi
            where sqi.customer_link_id = customerID and
                  sqi.yearweek between startYearWeek and endYearWeek and
                  sqi.weareremployment_link_id is not null and rownum = 1) loop
    return 1;
  end loop;
  for c in (select sqi.statusquoheader_id from sqitemincirculation sqi
            where sqi.customer_link_id = customerID and
                  sqi.yearweek between startYearWeek and endYearWeek and
                  sqi.weareremployment_link_id is null and rownum = 1) loop
    return 0;
  end loop;
  return 1;
end ExistsSQItemInfoOnWearerLevel;
/
create or replace function extract_housenr(fp_address_id number, fp_country_code varchar2) return varchar2 is
/*-- HVH 27-12-2010 Newly created.
 This function returns in one formatted string for the passed address record:
 position content
 1-30     street without house#,
 31-35    house#
 36-41    house# extension
 For US and Canada (country code US and CA it will start to search the house# at the beginning of the string, else at the end
 This function uses another function: gethousenumber.
 This function is used in export to Route Assistant PDA in case Navigation module is active.
 Updated 10.11.2021 APE: ABS-126407 Route Assistant error with procedure 'extract_housenr'
*/
 lv_street address.street%type;
 lv_housenr address.housenumber%type;
 lv_housenrext address.housenumberext%type;
 lv_housenrtxt varchar2(5);
begin
 lv_street := null;
 lv_housenr := null;
 lv_housenrext := null;
 if fp_country_code in ('US','CA')
  then -- house# at beginning of string and no house# extension
   begin
    select x.streetstring,
           x.housenumber,
           null
      into lv_street,
           lv_housenr,
           lv_housenrext
    from
     (select a.street, a.address_id,
         instr(rtrim(a.street), ' ', 1) spacepos,
         substr(ltrim(a.street), instr(rtrim(a.street), ' ', 1) +1 , 30) streetstring,
         substr(ltrim(a.street), 1, instr(rtrim(a.street), ' ', 1)-1) housenumber
      from address a
     where instr(rtrim(a.street), ' ', 1) > 0
       and a.address_id = fp_address_id
       and isnumeric(substr(ltrim(a.street), 1 , instr(rtrim(a.street), ' ', 1)-1))=1
       and length(substr(ltrim(a.street), 1 , instr(rtrim(a.street), ' ', 1)-1)) <= 5) x;
    exception
    when no_data_found then
      begin
       lv_street := null;
      end;
    end;
  else -- if country_code <> US/CA, house# at the end of the string
   begin
    select x.streetstring,
           x.housenumber,
           x.houseextension
      into lv_street,
           lv_housenr,
           lv_housenrext
      from
    (select substr(ltrim(a.street), 1, instr(rtrim(a.street), ' ', -1, 2)) streetstring,
           substr(ltrim(a.street),
                  1 + instr(rtrim(a.street), ' ', -1, 2),
                  instr(ltrim(rtrim(a.street)), ' ', -1, 1) -
                  instr(rtrim(a.street), ' ', -1, 2)) housenumber,
           substr(ltrim(a.street), 1 + instr(rtrim(a.street), ' ', -1)) houseextension
      from address a
     where instr(rtrim(a.street), ' ', -1) > 0
       and a.address_id = fp_address_id
       and isnumeric(substr(ltrim(a.street),
                            1 + instr(rtrim(a.street), ' ', -1, 2),
                            instr(ltrim(rtrim(a.street)), ' ', -1, 1) -
                            instr(rtrim(a.street), ' ', -1, 2))) = 1
       and length(substr(ltrim(a.street), 1 + instr(rtrim(a.street), ' ', -1))) <= 6 --house extension enlarged to 6
       and length(substr(ltrim(a.street),
                         1 + instr(rtrim(a.street), ' ', -1, 2),
                         instr(ltrim(rtrim(a.street)), ' ', -1, 1) -
                         instr(rtrim(a.street), ' ', -1, 2))) <= 5 --house number
    union
    select substr(ltrim(a.street),
                  1,
                  length(rtrim(ltrim(a.street))) -
                  (length(rtrim(a.street)) - instr(rtrim(a.street), '.', -1))) streetstring,
           substr(ltrim(rtrim(a.street)), 1 + instr(rtrim(a.street), '.', -1)) housenumber,
           ' ' houseextension
      from address a
     where a.address_id = fp_address_id
       and instr(ltrim(rtrim(a.street)), ' ', 1) = 0
       and isnumeric(substr(ltrim(rtrim(a.street)),
                            1 + instr(rtrim(a.street), '.', -1))) = 1
       and length(substr(ltrim(rtrim(a.street)),
                         1 + instr(rtrim(a.street), '.', -1))) <= 5 --house number
    union
    select substr(ltrim(a.street),
                  1,
                  length(rtrim(ltrim(a.street))) -
                  (length(rtrim(a.street)) - instr(rtrim(a.street), ' ', -1))) streetstring,
           case isnumeric(substr(ltrim(a.street),
                             - (length(rtrim(a.street)) -
                               instr(rtrim(a.street), ' ', -1)),
                             length(rtrim(a.street)) -
                             instr(rtrim(a.street), ' ', -1)))
             when 1 then
              substr(ltrim(a.street),
                     - (length(rtrim(a.street)) - instr(rtrim(a.street), ' ', -1)),
                     length(rtrim(a.street)) - instr(rtrim(a.street), ' ', -1))
             when 0 then
              gethousenumber(substr(ltrim(a.street),
                                    - (length(rtrim(a.street)) -
                                      instr(rtrim(a.street), ' ', -1)),
                                    length(rtrim(a.street)) -
                                    instr(rtrim(a.street), ' ', -1)),
                             'l')
           end housenumber,
           case isnumeric(substr(ltrim(a.street),
                             - (length(rtrim(a.street)) -
                               instr(rtrim(a.street), ' ', -1)),
                             length(rtrim(a.street)) -
                             instr(rtrim(a.street), ' ', -1)))
             when 1 then
              ' '
             when 0 then
              substr(substr(ltrim(a.street),
                            - (length(rtrim(a.street)) -
                              instr(rtrim(a.street), ' ', -1)),
                            length(rtrim(a.street)) -
                            instr(rtrim(a.street), ' ', -1)),
                     1 +
                     length(gethousenumber(substr(ltrim(a.street),
                                                  - (length(rtrim(a.street)) -
                                                    instr(rtrim(a.street), ' ', -1)),
                                                  length(rtrim(a.street)) -
                                                  instr(rtrim(a.street), ' ', -1)),
                                           'l')))
           end houseextension
      from address a
     where instr(rtrim(a.street), ' ', -1) > 0
       and a.address_id = fp_address_id
       and length(case isnumeric(substr(ltrim(a.street),
                                   - (length(rtrim(a.street)) -
                                     instr(rtrim(a.street), ' ', -1)),
                                   length(rtrim(a.street)) -
                                   instr(rtrim(a.street), ' ', -1))) when 1 then
                  substr(ltrim(a.street),
                         - (length(rtrim(a.street)) -
                           instr(rtrim(a.street), ' ', -1)),
                         length(rtrim(a.street)) -
                         instr(rtrim(a.street), ' ', -1)) when 0 then
                  gethousenumber(substr(ltrim(a.street),
                                        - (length(rtrim(a.street)) -
                                          instr(rtrim(a.street), ' ', -1)),
                                        length(rtrim(a.street)) -
                                        instr(rtrim(a.street), ' ', -1)),
                                 'l') end) <= 5 --house number
       and length(case isnumeric(substr(ltrim(a.street),
                                   - (length(rtrim(a.street)) -
                                     instr(rtrim(a.street), ' ', -1)),
                                   length(rtrim(a.street)) -
                                   instr(rtrim(a.street), ' ', -1))) when 1 then ' ' when 0 then
                  substr(substr(ltrim(a.street),
                                - (length(rtrim(a.street)) -
                                  instr(rtrim(a.street), ' ', -1)),
                                length(rtrim(a.street)) -
                                instr(rtrim(a.street), ' ', -1)),
                         1 + length(gethousenumber(substr(ltrim(a.street),
                                                          - (length(rtrim(a.street)) -
                                                            instr(rtrim(a.street),
                                                                  ' ',
                                                                  -1)),
                                                          length(rtrim(a.street)) -
                                                          instr(rtrim(a.street),
                                                                ' ',
                                                                -1)),
                                                   'l'))) end) <= 6 -- --house extension enlarged to 6
       and not exists
     (select a2.address_id
              from address a2
             where instr(rtrim(a2.street), ' ', -1) > 0
               and a2.address_id = fp_address_id
               and isnumeric(substr(ltrim(a2.street),
                                    1 + instr(rtrim(a2.street), ' ', -1, 2),
                                    instr(ltrim(rtrim(a2.street)), ' ', -1, 1) -
                                    instr(rtrim(a2.street), ' ', -1, 2))) = 1
               and length(substr(ltrim(a2.street),
                                 1 + instr(rtrim(a2.street), ' ', -1))) <= 6
               and a2.address_id = a.address_id)) x;
    exception
    when no_data_found then
      begin
       lv_street := null;
      end;
    end;
  end if; -- if country code
 if nvl(lv_street,'-1')='-1' then
   begin
       select a.street
         into lv_street
        from address a
       where a.address_id = fp_address_id;
    exception
    when no_data_found then
      begin
       lv_street := null;
      end;
    end;
 end if;

 lv_street := substr(lv_street || '                              ',1,30);
 lv_housenrtxt := substr((TO_CHAR(lv_housenr)) || '     ',1,5);
 lv_housenrext := substr(lv_housenrext || '      ',1,6);
 return(lv_street || lv_housenrtxt || lv_housenrext);
end extract_housenr;
/
create or replace function fgetuniqueitemflags(lvnuniqueitemid uniqueitem.uniqueitem_id%type,
                                               lvplantid       plant.plant_id%type,
                                               lvwearerid      wearer.wearer_id%type,
                                               lvweareremplid  weareremployment.weareremployment_id%type)
  return varchar2 is
  lvssortaddress varchar2(10);
begin
  for x in (select sf.sortaddress, substr(sf.sortaddress, 1, 1) sortadress
            from   flag f, sortaddressperflag sf,
                   (select uf.flag_id
                     from   uniqueitemflag uf
                     where  uf.uniqueitem_id = lvnuniqueitemid
                     and    uf.startdate <= sysdate
                     union
                     select w.flag_id
                     from   wearer w
                     where  w.wearer_id = lvwearerid
                     and    w.flagstartdate <= sysdate
                     union
                     select we.flag_id
                     from   weareremployment we
                     where  we.weareremployment_id = lvweareremplid
                     and    we.flagstartdate <= sysdate) x
            where  x.flag_id = f.flag_id
            and    x.flag_id = sf.flag_id
            and    sf.plant_id = lvplantid
            and    exists (select 1
                    from   flagoptions o, dialogs dg
                    where  o.dialog_id = dg.dialog_id
                    and    f.flag_id = o.flag_id
                    and    upper(dg.code) in ('INSCAN', 'CHECKPOINTSCAN')
                    and    o.show = 'Y')
            order  by f.priority) loop
    begin
      lvssortaddress := substr(lvssortaddress || x.sortadress, 1, 10);
    end;
  end loop;
  return(lvssortaddress);
end fgetuniqueitemflags;
/
create or replace FUNCTION FGET_BDE_FRECV (deltocustomer_link_id NUMBER,
                                           product_link_id NUMBER,
                                           sizedefinition_link_id NUMBER,
                                           finishingmethod_id NUMBER,
                                           invoicedate date,
                                           deliveryschemecode varchar2)
return number is
 hlp varchar2(1);
 f number;
begin
hlp := ' ';
f := 0;
select max(plpc.rentpriceperfrequency)
into hlp
from productlistpercustomer plpc
where plpc.customer_id = deltocustomer_link_id
      and plpc.product_id = product_link_id
      and plpc.sizedefinition_id = sizedefinition_link_id
      and plpc.finishingmethod_id = finishingmethod_id
      and invoicedate >= plpc.dateactive
      and invoicedate <= plpc.dateinactive;
 if (hlp <> 'Y') then
      return -1;
   end if;
select dsc.frequency
into f
from deliveryscheme dsc
where dsc.code = deliveryschemecode;
 if (hlp = 'Y') then return f;
                else return -1;
   end if;
exception
    when no_data_found then return -1;
end;
/
create or replace function fsget_code(fp_invoicenumber integer, fp_linenumber integer)
  return varchar2 is
  lv_psd varchar2(64);
begin
  for x in (select lp.productshortdescription
            from   invoiceheader h
            join   invoiceline l
            on     l.invoiceheader_id = h.invoiceheader_id
            join   invoicelineproduct lp
            on     lp.invoiceline_id = l.invoiceline_id
            join   invoicelinetype lt
            on     lt.invoicelinetype_id = l.invoicelinetype_id
            where  lt.type = 1
            and    l.invoicelinesubtype = 2
            and    h.invoicenumber = fp_invoicenumber
            and    l.linenumber = fp_linenumber
            group  by lp.productshortdescription
            order  by lp.productshortdescription) loop
    begin
      lv_psd := lv_psd || substr(trim(x.productshortdescription), 1, 1) || '&';
    end;
  end loop;
  return(rtrim(lv_psd, '&'));
end fsget_code;
/
create or replace function FSGET_CustDeliveryScheme(routeID number, custID number) return varchar2 is
  Result varchar2(6);
  min_f  integer;
begin
  if (routeID is null) then
     return('');
  else
  begin
    min_f := 99999999;
    result := '';
    for vCursor in(SELECT ds.code, ds.frequency
                    FROM CUSTOMERDELIVERYSCHEME CDS, deliveryscheme ds, route r
                    WHERE cds.customer_id = custID AND
                    r.route_id = routeID AND
                    cds.day_id = r.drivingday_id AND
                    cds.deliveryscheme_id = ds.deliveryscheme_id
          ) loop
    if min_f > vCursor.frequency then
      min_f := vCursor.frequency;
      result := vCursor.code;
    end if;
    end loop;

  return(Result);
  end;
  end if;
end FSGET_CustDeliveryScheme;
/
create or replace function FsGet_Cust_Delivery_Days(DelToCustomerID integer) return  varchar2 is
  sir      varchar2(7);
  result   varchar2(7);
begin
  sir := '';
  result := '';
for vCursor in( select d.daynumber daynumber,
     			            (Select cdd.deliverytype
          		                from customerdeliveryday cdd
                              where cdd.typeofmerchadise = 1 and
                              cdd.day_id = d.day_id and
                              cdd.customer_id = DelToCustomerID) delivery_type
		            from day d order by daynumber
                ) loop

     if  ltrim(rtrim(Vcursor.delivery_type)) is not null then
         result:= concat(result,ltrim(rtrim(Vcursor.delivery_type)));
     else
         result:= concat(result, ' ');
     end if;
end loop;
return(Result);
end FsGet_Cust_Delivery_Days;
/
create or replace function fsget_idcodelengths(fp_plant_id number, fp_packagetype number, fp_primary_YNB varchar2 default 'Y') return varchar2 is
-- function returns a comma separated string with all allowed ID code lenghts for the passed plant and package type
-- parameter fp_primary_YNB defines if only lengths of primary ID's (Y) or only secondary ID's (N) or both (B) should be returned
  Result varchar2(100);
begin
  if (fp_plant_id is null) or (fp_packagetype is null) then
     return('');
  else
  begin
    result := '';
    for vCursor in(select distinct(i.length) len
                     from uniqueidconfiguration i,
                          businessunit b
                    where i.packagetype = fp_packagetype
                      and b.businessunit_id = i.businessunit_id
                      and b.plant_id = fp_plant_id
                      and (i.primaryid = fp_primary_YNB or fp_primary_YNB = 'B')
                    order by i.length
          ) loop
      result := result || vCursor.len || ',';
    end loop;
  result := substr(result,1,length(result)-1);
  result := substr(result,1,40);
  return(Result);
  end;
  end if;
end fsget_idcodelengths;
/
create or replace FUNCTION FSGET_MIN_5_YEARWEEKS (INV_HEADER_ID NUMBER,
                                                  inv_freq_id number)
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(39);
 hlpStr varchar2(39);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';
    select f.invoicefrequencynumber
    into hlp
    from invoicefrequency f
    where f.invoicefrequency_id = inv_freq_id;
    if (hlp = 105) or (hlp = 110) or (hlp = 45) or (hlp = 10) or
       (hlp =  20) or (hlp = 30) or (hlp = 40) or (hlp = 200) then
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;
       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l
                    where l.invoiceheader_id = INV_HEADER_ID
                       and l.invoiceline_id = cri.invoiceline_id
                       --and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year*100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;
           if (cnt = 5) then
              return hlpStr;
           end if;
       end loop;
       if cnt < 5 then
          for i in (cnt+1)..5 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;
       return hlpStr;
    else
       return dummyStr;
    end if;
exception
    when no_data_found then return dummyStr;
end
;
/
create or replace FUNCTION fsget_min_5_yearweeks_rev (INV_LINE_ID NUMBER,
                                                  inv_freq_id number)
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(39);
 hlpStr varchar2(39);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';
    select f.invoicefrequencynumber
    into hlp
    from invoicefrequency f
    where f.invoicefrequency_id = inv_freq_id;
    if (hlp = 105) or (hlp = 110) or (hlp = 45) or (hlp = 10) or
       (hlp =  20) or (hlp = 30) or (hlp = 40) or (hlp = 200) then
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;
       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri
                    where cri.invoiceline_id = INV_LINE_ID
                       and cri.quantity > 0--and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year*100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;
           if (cnt = 5) then
              return hlpStr;
           end if;
       end loop;
       if cnt < 5 then
          for i in (cnt+1)..5 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;
       return hlpStr;
    else
       return dummyStr;
    end if;
exception
    when no_data_found then return dummyStr;
end
;
/
create or replace FUNCTION FSGET_MIN_6_YEARWEEKS (INV_HEADER_ID NUMBER,
                                                  inv_freq_id number)
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(47);
 hlpStr varchar2(47);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';

    /*select f.invoicefrequencynumber
    into hlp
    from invoicefrequency f
    where f.invoicefrequency_id = inv_freq_id;

    if (hlp = 110) or (hlp = 45) or (hlp = 10) or
       (hlp =  20) or (hlp = 30) or (hlp = 40) or (hlp = 200) then*/
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;

       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l
                    where l.invoiceheader_id = INV_HEADER_ID
                       and l.invoiceline_id = cri.invoiceline_id
                       --and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year * 100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;

           if (cnt = 6) then
              return hlpStr;
           end if;

       end loop;

       if cnt < 6 then
          for i in (cnt+1)..6 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;

       return hlpStr;
   /* else
       return dummyStr;
    end if;*/
exception
    when no_data_found then return dummyStr;
end;
/
create or replace FUNCTION FSGET_MIN_6_YEARWEEKS_4RENT (INV_HEADER_ID NUMBER )
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(47);
 hlpStr varchar2(47);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;

       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l
                    where l.invoiceheader_id = INV_HEADER_ID
                       and l.invoiceline_id = cri.invoiceline_id
                       AND l.invoicelinetype_id = 1
                       --and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year * 100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;

           if (cnt = 6) then
              return hlpStr;
           end if;

       end loop;

       if cnt < 6 then
          for i in (cnt+1)..6 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;

       return hlpStr;
   /* else
       return dummyStr;
    end if;*/
exception
    when no_data_found then return dummyStr;
end;
/
create or replace FUNCTION FSGET_MIN_6_YEARWEEKS_CONS (INV_HEADER_ID NUMBER,
                                                  inv_freq_id number)
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(47);
 hlpStr varchar2(47);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';
/*
    select f.invoicefrequencynumber
    into hlp
    from invoicefrequency f
    where f.invoicefrequency_id = inv_freq_id;

    if (hlp = 110) or (hlp = 45) or (hlp = 10) or
       (hlp =  20) or (hlp = 30) or (hlp = 40) or (hlp = 200) then
       --only for MONTHLY and 4-4-5 invoices*/
       hlpStr := 'A';
       cnt := 0;

       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l, invoiceheader ih
                    where l.invoiceheader_id = ih.invoiceheader_id
                    and ih.parentinvoiceheader_id = INV_HEADER_ID
                   --and ih.parentinvoiceheader_id <> ih.invoiceheader_id
                       and l.invoiceline_id = cri.invoiceline_id
                       --and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year * 100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;

           if (cnt = 6) then
              return hlpStr;
           end if;

       end loop;

       if cnt < 6 then
          for i in (cnt+1)..6 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;

       return hlpStr;
--    else        return dummyStr;
--    end if;
exception
    when no_data_found then return dummyStr;
end;
/
create or replace FUNCTION FSGET_MIN_7_YEARWEEKS_4RENT (INV_HEADER_ID NUMBER )
                                       return varchar2 is
 hlp number;
 dummyStr varchar2(55);
 hlpStr varchar2(55);
 cnt integer;
begin
    dummyStr := ' 000000, 000000, 000000, 000000, 000000, 000000, 000000';
    hlpStr := '';
       --only for MONTHLY and 4-4-5 invoices
       hlpStr := 'A';
       cnt := 0;

       for vCsr in (select distinct cri.year, cri.week
                    from costreportinfo cri, invoiceline l
                    where l.invoiceheader_id = INV_HEADER_ID
                       and l.invoiceline_id = cri.invoiceline_id
                       AND l.invoicelinetype_id = 1
                       --and rownum < 6
                       order by cri.year asc, cri.week asc) loop

           hlp := vCsr.year * 100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
           cnt := cnt + 1;

           if (cnt = 7) then
              return hlpStr;
           end if;

       end loop;

       if cnt < 7 then
          for i in (cnt+1)..7 loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
          end loop;
       end if;

       return hlpStr;
   /* else
       return dummyStr;
    end if;*/
exception
    when no_data_found then return dummyStr;
end;
/
create or replace function FsGet_TaxCode(Vinvoicenumber integer, Vlinenumber integer) return   varchar2 is
  Result          varchar2(40) ;
  i               integer;
  result1         varchar2(40);
  result2         varchar2(80);

begin
result:='';
i:=0;
result1:='';
for vCursor in( select f.invoicenumber, a.linenumber, a.code
                from invoiceline a, invoicelinetype e, invoiceheader f
                where a.invoicelinetype_id = e.invoicelinetype_id
                and a.invoiceheader_id = f.invoiceheader_id
                and e.type = 18
                and f.invoicenumber = Vinvoicenumber
                and a.linenumber = Vlinenumber
                group by invoicenumber, linenumber, a.code
                ) loop
i:=i+1;
if i>1  then

     if  ltrim(rtrim(Vcursor.code)) is not null then
     result2:= concat(result,',');
     result2:= concat(result,ltrim(rtrim(Vcursor.code)));
     end if;

     if (length(result2) <= 40) then
          if  ltrim(rtrim(Vcursor.code)) is not null then
               result:= concat(result,',');
               result:= concat(result,ltrim(rtrim(Vcursor.code)));
          end if;
     end if;
else
     result2:= concat(result, Vcursor.code);
     if (length(result2) <= 40) then
        result:= concat(result, Vcursor.code);
     end if;

end if;
end loop;
return(Result);
end FsGet_TaxCode;
/
create or replace FUNCTION F_5_YEARWEEKS
       ( invoiceheadeid number
       , inv_freq_id number)
                       return varchar2 is
                              hlp number;
 dummyStr varchar2(39);
 hlpStr varchar2(39);
 cnt integer;
begin
dummyStr := ' 000000, 000000, 000000, 000000, 000000';
hlpStr := '';
       select f.invoicefrequencynumber
              into hlp
                   from invoicefrequency f
       where f.invoicefrequency_id = inv_freq_id;
if (hlp = 110) or (hlp = 45) or (hlp = 40)--only for MONTHLY and 4-4-5 invoices -- (todo 6980) Every 4 weeks
   then
       hlpStr := 'A';
cnt := 0;
for vCsr in ( select distinct iladd.year, iladd.week
                     from invoicelineaddition iladd, invoiceline il
                          where iladd.invoiceline_id = il.invoiceline_id
                                and il.invoiceheader_id = invoiceheadeid
                                order by iladd.year, iladd.week asc)
loop
           hlp := vCsr.year*100 + vCsr.week;
           if (hlpStr = 'A') then
              hlpStr := to_char(hlp, '999999');
           else
              hlpStr := concatenate3(hlpStr, ',', to_char(hlp,'999999'));
           end if;
cnt := cnt + 1;
           if (cnt = 5) then
              return hlpStr;
           end if;
end loop;
       if cnt < 5 then
          for i in ( cnt + 1 )..5
         loop
              if i = 1 then
                hlpStr := ' 000000';
              else
                hlpStr := concatenate3(hlpStr, ',', ' 000000');
              end if;
         end loop;
       end if;
       return hlpStr;
    else
       return dummyStr;
   end if;
exception
    when no_data_found then return dummyStr;
end;


/
create or replace function f_amountdelivered(customerid in number, productid in number, sizedefinitionid in number, finishingmethodid in number, reportparamid in number) return number is
  amountdelivered number;
begin
  select /*+ index(dh XIE16DELIVERYHISTORY)*/
        sum(dh.amountdelivered) into amountdelivered
         from   deliveryhistory dh, reportparam rp
         where  dh.customer_link_id = customerid and
                dh.product_link_id = productid and
                dh.sizedefinition_link_id = sizedefinitionid and
                dh.finishingmethod_id = finishingmethodid and
                rp.reportparam_id = reportparamid and
                dh.deliverydate between rp.date_value1 and rp.date_value2;
  return(amountdelivered);
end f_amountdelivered;
/
create or replace function F_ASSIGNEDDN(ROUTECONTR_ID in ROUTECONTROL.ROUTECONTROL_ID%type)
  return number is
  result number;
begin
  result := 0;
  select /*+index(PN XIE15PACKINGNOTE)*/ NVL(max(PN.PACKINGNOTE_ID), 0)
    into result
    from PACKINGNOTE   PN,
         STOP,
         STATUS,
         DELIVERYPOINT DP,
         CUSTOMER,
         BUSINESSUNIT  BU,
         ROUTECONTROL  RC
   where STOP.CUSTOMER_LINK_ID = CUSTOMER.CUSTOMER_ID
     and PN.DELIVERYPOINT_ID = DP.DELIVERYPOINT_ID
     and DP.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
     and NVL(STOP.DELIVERYPOINT_ID,PN.DELIVERYPOINT_ID) = PN.DELIVERYPOINT_ID
     and PN.PROCESSBUSINESSUNIT_ID = BU.BUSINESSUNIT_ID
     and BU.PLANT_ID = RC.PLANT_ID
     and STOP.ROUTECONTROL_ID = RC.ROUTECONTROL_ID
     and NVL(PN.ROUTECONTROL_ID,0) = 0
     and NVL(PN.STOP_ID,0) = 0
     and PN.INVOICESTATUS = 0
     and PN.STATUS_ID = STATUS.STATUS_ID
     and STATUS.STATUSTYPE = 'PN'
     and STATUS.CODE in ('10', '20', '30')
     and ((STOP.STATUS - 0) * (STOP.STATUS - 3) = 0)
     and RC.ROUTECONTROL_ID = ROUTECONTR_ID
     and (case when (RC.DRIVINGDATE < trunc(sysdate)) then (RC.DRIVINGDATE - PN.DELIVERYDATE) else 1 end) >= 0;
  return result;
end F_ASSIGNEDDN;
/
create or replace function f_audit_piped(fp_tablename          in varchar2 default null,
                                         fp_condensedinsert_yn in varchar2 default 'Y')
  return t_audit_tab
  pipelined is
  --function f_audit_piped version 1.3
  lv_thecursor           integer default dbms_sql.open_cursor;
  lv_desctbl             dbms_sql.desc_tab;
  lv_columnvalue         varchar2(1000);
  lv_action              varchar2(1000);
  lv_status              integer;
  lv_query               varchar2(4000);
  lv_colcnt              number := 0;
  lv_entity_id           varchar2(1000);
  lv_client_identifier   varchar2(1000);
  lv_business_unit       varchar2(6);
  lv_business_unit_desc  varchar2(40);
  lv_workstation         varchar2(40);
  lv_client_identifier_s varchar2(1000);
  lv_timestamp           varchar2(1000);
  lv_old_value           varchar2(1000);
  lv_new_value           varchar2(1000);
  lv_table_desc          varchar2(1000);
  lv_table_name          varchar2(100);
  lv_history_days        number;
  lv_extrafield1         varchar2(1000);
  lv_extrafield2         varchar2(1000);
  lv_extrafield3         varchar2(1000);
  lv_extrafield4         varchar2(1000);
  lv_extrafield5         varchar2(1000);
  lv_extrafield6         varchar2(1000);
  lv_message             varchar2(1000);
  --Split a_client_identifier into three fields and get the BU description
  procedure split(fp_split_cli_identifier varchar2) is
  begin
    if instr(fp_split_cli_identifier, 'BU:') <> 0 then
      begin
        lv_business_unit       := substr(fp_split_cli_identifier,
                                         instr(fp_split_cli_identifier, 'BU:') + 4);
        lv_workstation         := substr(fp_split_cli_identifier, 7,
                                         instr(fp_split_cli_identifier, 'STATION') - 8);
        lv_client_identifier_s := substr(fp_split_cli_identifier,
                                         instr(fp_split_cli_identifier, 'STATION') + 9,
                                         instr(fp_split_cli_identifier, 'BU:') -
                                          instr(fp_split_cli_identifier, 'STATION') - 9);
        select bu.description
        into   lv_business_unit_desc
        from   businessunit bu
        where  bu.code = lv_business_unit;
      end;
    else
      begin
        lv_business_unit       := '-';
        lv_workstation         := '-';
        lv_client_identifier_s := '# ' || fp_split_cli_identifier;
      end;
    end if;
  end split;
begin
  --Traverse all audit tables that have history_days defined
  execute immediate('ALTER SESSION SET NLS_DATE_FORMAT=''DD-MON-YYYY HH24:MI:SS''');
  for y in (select *
            from   a_tablelist x
            where  x.view_txt is not null
            and    x.history_days is not null
            and    x.processed in (1, 2, 3)
            and    (upper(x.tablename) = upper(fp_tablename) or fp_tablename is null)) loop
    begin
      lv_table_name   := y.tablename;
      lv_table_desc   := y.table_desc;
      lv_history_days := y.history_days;
      --Pick insert/delete records from the a_table. Only for inserts made by an actual user.
      lv_query   := y.view_txt;
      lv_query   := lv_query ||
                    ' where a.a_timestamp >= trunc(sysdate) - :lv_history_days order by a.a_timestamp';
      lv_message := substr(lv_query, 1, 1000);
      dbms_sql.parse(lv_thecursor, lv_query, dbms_sql.native);
      lv_message := 'describe columns ';
      dbms_sql.describe_columns(lv_thecursor, lv_colcnt, lv_desctbl);
      lv_message := 'bind history_days ';
      dbms_sql.bind_variable(lv_thecursor, ':lv_history_days', lv_history_days);
      lv_message := 'execute sql';
      lv_status  := dbms_sql.execute(lv_thecursor);
      lv_message := 'ST ' || nvl(to_char(lv_status), 'TEST');
      for i in 1 .. lv_colcnt loop
        begin
          lv_message := 'LOOP 1 ' || nvl(to_char(i), '--');
          dbms_sql.define_column(lv_thecursor, i, lv_columnvalue, 4000);
        end;
      end loop;
      while (dbms_sql.fetch_rows(lv_thecursor) > 0) loop
        begin
          --Retrieve B values from grouped a_table A last record-1 join with last record grouped B same a_table: A1A2A3A4B1B2B3B4
          for i in 1 .. lv_colcnt / 2 loop
            lv_message := 'LOOP 2 ' || nvl(to_char(i), '--');
            if lv_desctbl(i).col_name = 'A_ACTION' then
              dbms_sql.column_value(lv_thecursor, i, lv_action);
            end if;
            if lv_desctbl(i).col_name = 'A_TIMESTAMPFM' then
              dbms_sql.column_value(lv_thecursor, i, lv_timestamp);
            end if;
            if lv_desctbl(i).col_name = 'A_CLIENT_IDENTIFIER' then
              dbms_sql.column_value(lv_thecursor, i, lv_client_identifier);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD1' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield1);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD2' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield2);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD3' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield3);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD4' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield4);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD5' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield5);
            end if;
            if lv_desctbl(i).col_name = 'EXTRAFIELD6' then
              dbms_sql.column_value(lv_thecursor, i, lv_extrafield6);
            end if;
            if lv_desctbl(i).col_name = 'ENTITY_ID' then
              dbms_sql.column_value(lv_thecursor, i, lv_entity_id);
            end if;
          end loop;
          split(lv_client_identifier);
          if lv_client_identifier <> 'OLDVALUE' then
            begin
              --Compare the column value with the column value in the "preceding" record for each column except: rownum, id, additional fields and the a_ type columns
              if lv_action in ('I', 'D') and upper(nvl(fp_condensedinsert_yn, 'Y')) = 'Y' then
                begin
                  lv_message := 'pipe row insert';
                  pipe row(t_audit(nvl(lv_table_desc, lv_table_name), lv_entity_id,
                                   to_date(lv_timestamp, 'yyyymmddhh24miss'), lv_action, 'NULL',
                                   'NULL', 'NULL', lv_business_unit, lv_business_unit_desc,
                                   lv_workstation, lv_client_identifier_s, lv_extrafield1,
                                   lv_extrafield2, lv_extrafield3, lv_extrafield4, lv_extrafield5,
                                   lv_extrafield6, null));
                end;
              else
                begin
                  lv_message := 'pipe row column';
                  for j in 1 .. lv_colcnt / 2 loop
                    begin
                      dbms_sql.column_value(lv_thecursor, j, lv_new_value);
                      dbms_sql.column_value(lv_thecursor, j + (lv_colcnt / 2), lv_old_value);
                      begin
                        if (((nvl(lv_old_value, 'NULL') <> nvl(lv_new_value, 'NULL')) or
                           ((nvl(fp_condensedinsert_yn, 'Y') = 'N' and lv_action in ('I', 'D')))) and lv_desctbl(j)
                           .col_name not in
                           ('ENTITY_ID', 'ROW_NUM', 'TIMESTAMP', 'SYSTEMUSER_ID', 'A_TIMESTAMP',
                             'A_TIMESTAMPFM', 'A_CLIENT_IDENTIFIER', 'A_ACTION', 'EXTRAFIELD1',
                             'EXTRAFIELD2', 'EXTRAFIELD3', 'EXTRAFIELD4', 'EXTRAFIELD5',
                             'EXTRAFIELD6')) then
                          begin
                            pipe row(t_audit(nvl(lv_table_desc, lv_table_name), lv_entity_id,
                                             to_date(lv_timestamp, 'yyyymmddhh24miss'), lv_action,
                                             lv_desctbl(j).col_name, nvl(lv_old_value, 'NULL'),
                                             nvl(lv_new_value, 'NULL'), lv_business_unit,
                                             lv_business_unit_desc, lv_workstation,
                                             lv_client_identifier_s, lv_extrafield1, lv_extrafield2,
                                             lv_extrafield3, lv_extrafield4, lv_extrafield5,
                                             lv_extrafield6, null));
                          end;
                        end if;
                      end;
                    end;
                  end loop;
                end;
              end if;
            end;
          end if;
        end;
      end loop;
      lv_extrafield1 := '';
      lv_extrafield2 := '';
      lv_extrafield3 := '';
      lv_extrafield4 := '';
      lv_extrafield5 := '';
      lv_extrafield6 := '';
    end;
  end loop;
  dbms_sql.close_cursor(lv_thecursor);
exception
  when others then
    begin
      dbms_output.put_line(substr(sqlerrm || ' # ' || nvl(lv_message, '-'), 1, 2000));
      raise;
    end;
end f_audit_piped;
/
create or replace function F_CEIL( abc in real )
return numeric
as
begin
return CEIL(abc) ;
end;
/
create or replace function f_checkdeliverysignature
  (packingnoteid in packingnote.packingnote_id%type
  ) return  varchar2 is
   hasSignature number;
   starSign varchar2(5);
begin
  hasSignature := 0;
  starSign := null;
  begin
   select count(1)
   into hasSignature
          from packingnote pn
          join stop on (pn.stop_id = stop.stop_id)
          join deliverysignature dsig on (dsig.stop_id = pn.stop_id and dsig.stop_id = pn.deliverysignature_id)
          where pn.packingnote_id = packingnoteid;
    exception when no_data_found then
        hasSignature := 0;
  end;
  if hasSignature = 0 then
    starSign := '*';
  end if;
  return starSign;
end f_checkdeliverysignature;
/
create or replace function F_CheckForDelivery (
  plpdId  in                   productlistperdistribpoint.productlistperdistribpoint_id%type,
  customerId in                customer.customer_id%type,
  departmentId in              department.department_id%type,
  delDate in                   standarddeliveryline.dateinactive%type) return numeric is

  yearNo         number;
  weekNo         number;
  dayNo          number;

begin

  yearNo := getYearofWeek(delDate);
  weekNo := getISOWeek(delDate);

  select max(scy.deliveryday_id)
  into dayNo
  from normstockamount nsa, stockcountscheduleday scy, stockcountschedule scs, stockcountscheduledept scd
  where nsa.productlistperdistribpoint_id = plpdId
    and nsa.day_id = scy.day_id
    and scy.stockcountschedule_id = scs.stockcountschedule_id
    and scs.customer_id = customerId
    and scs.stockcountschedule_id = scd.stockcountschedule_id
    and scd.department_id = departmentId
    and scy.deliveryday_id = GETABSDAYNUMBER(delDate);

    if dayNo is null then
  select max(scy.deliveryday_id)
    into dayNo
    from normstockamount        nsa,
         stockcountscheduleday  scy,
         stockcountschedule     scs,
         stockcountscheduledist scd
   where nsa.productlistperdistribpoint_id = plpdId
     and nsa.day_id = scy.day_id
     and scy.stockcountschedule_id = scs.stockcountschedule_id
     and scs.customer_id = customerId
     and scs.stockcountschedule_id = scd.stockcountschedule_id
     and scd.distributionpoint_id = (select plpd.distributionpoint_id from productlistperdistribpoint plpd where plpd.productlistperdistribpoint_id = plpdid)
     and scy.deliveryday_id = GETABSDAYNUMBER(delDate);
     end if;

  if dayNo is null then
    select max(nsa.day_id)
    into dayNo
    from normstockamount nsa
    where nsa.productlistperdistribpoint_id = plpdId
      and nsa.day_id = GETABSDAYNUMBER(delDate);
  end if;

  if dayNo is null then return 0; end if;

  for vCursor in(
    select coalesce(ds.frequency, 1) frequency, ds.offsetweek,
      (case when sdl.season_id is null then -1
       else (select count(*) from seasonweek sw where sw.season_id = sdl.season_id and sw.weeknumber = weekNo)
       end) existsweekinseazon,
       ISTEMPORARYDELIVERYSTOP2(yearNo, weekNo, sdl.standarddeliveryline_id) + ISTEMPORARYDELIVERYSTOP_DATE(delDate, sdl.standarddeliveryline_id) is_temporarydeliverystop
    from standarddeliveryline sdl
      left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id
    where sdl.productlistperdistribpoint_id = plpdId
      and sdl.dateactive <= delDate
      and sdl.dateinactive > delDate) LOOP

      -- season check
      if vCursor.existsweekinseazon = 0 then goto x; end if;
      -- temporary stop check
      if vCursor.is_temporarydeliverystop <> 0 then goto x; end if;
      -- deliveryscheme check
      if (not IsWeekDeliveryweek(yearNo, weekNo, vCursor.frequency, vCursor.offsetweek)) then goto x; end if;

      return 1;

  <<x>> null;
  end loop;

  return 0;

  exception
    when no_data_found then return 0;
end F_CheckForDelivery;
/
create or replace function f_concat_modificationcode(fpUniqueItem_ID number)
  return varchar2 is
  modifcode1  modification.code%type;
  modifcode2  modification.code%type;
  modifcode3  modification.code%type;
  modifresult varchar2(30);
  virg        varchar2(1);
begin
  begin
    select m1.code
      into modifcode1
      from uniqueitem ui, uniqueitemmodification uim1, modification m1
     where ui.uniqueitem_id = uim1.uniqueitem_id
       and uim1.modification_id = m1.modification_id
       and uim1.sequencenumber = 1
       and ui.uniqueitem_id = fpUniqueItem_ID;
  exception
    when no_data_found then
      null;
  end;
  begin
    select m2.code
      into modifcode2
      from uniqueitem ui, uniqueitemmodification uim2, modification m2
     where ui.uniqueitem_id = uim2.uniqueitem_id
       and uim2.modification_id = m2.modification_id
       and uim2.sequencenumber = 2
       and ui.uniqueitem_id = fpUniqueItem_ID;
  exception
    when no_data_found then
      null;
  end;
  begin
    select m3.code
      into modifcode3
      from uniqueitem ui, uniqueitemmodification uim3, modification m3
     where ui.uniqueitem_id = uim3.uniqueitem_id
       and uim3.modification_id = m3.modification_id
       and uim3.sequencenumber = 3
       and ui.uniqueitem_id = fpUniqueItem_ID;
  exception
    when no_data_found then
      null;
  end;
  virg        := ',';
  modifresult := '';
  if modifcode1 is not null and modifcode2 is not null and
     modifcode3 is not null then
    modifresult := modifcode1 || virg || modifcode2 || virg || modifcode3;
  end if;
  if modifcode1 is null and modifcode2 is not null and
     modifcode3 is not null then
    modifresult := modifcode2 || virg || modifcode3;
  end if;
  if modifcode1 is null and modifcode2 is null and modifcode3 is not null then
    modifresult := modifcode3;
  end if;
  if modifcode1 is not null and modifcode2 is null and
     modifcode3 is not null then
    modifresult := modifcode1 || virg || modifcode3;
  end if;
  if modifcode1 is not null and modifcode2 is not null and
     modifcode3 is null then
    modifresult := modifcode1 || virg || modifcode2;
  end if;
  if modifcode1 is null and modifcode2 is not null and modifcode3 is null then
    modifresult := modifcode2;
  end if;
  if modifcode1 is not null and modifcode2 is null and modifcode3 is null then
    modifresult := modifcode1;
  end if;

  return modifresult;
end;
/
create or replace function f_concat_route_stop (
       FPstr1     varchar2,
       FPstr2     varchar2
) return varchar2 is
begin
     return FPstr1 || ' / ' || FPstr2;
end;
/
create or replace function F_COSTPRICE (
	processBU			businessunit.businessunit_id%type,
	priceTypeID		costpricelist.pricetype%type,
	productID			product.product_id%type,
	sizeID				sizedefinition.sizedefinition_id%type,
	sizeStarID		sizedefinition.sizedefinition_id%type,
	finMethID			finishingmethod.finishingmethod_id%type,
	crtDate				date
) return number is
	costPrice			costpricelistdetail.price%type:=-1;
begin
	for vCrs in (select cpd.price, 1, cpp.priority, cpd.startdate
								from costpricelistperplant cpp, costpricelistdetail cpd, businessunit b
								where cpp.costpricelist_id = cpd.costpricelist_id and
											cpp.plant_id = b.plant_id and
											b.businessunit_id = processBU and
											cpp.pricetype = priceTypeID and
											crtDate between cpp.startdate and cpp.enddate and
											cpd.startdate <= crtDate and
											cpd.product_id = productID and
											cpd.sizedefinition_id = sizeID and
											cpd.finishingmethod_id = finMethID
							union all
							select cpd.price, 2, cpp.priority, cpd.startdate
								from costpricelistperplant cpp, costpricelistdetail cpd, businessunit b
								where cpp.costpricelist_id = cpd.costpricelist_id and
											cpp.plant_id = b.plant_id and
											b.businessunit_id = processBU and
											cpp.pricetype = priceTypeID and
											crtDate between cpp.startdate and cpp.enddate and
											cpd.startdate <= crtDate and
											cpd.product_id = productID and
											cpd.sizedefinition_id = sizeStarID and
											cpd.finishingmethod_id = finMethID
								order by 3 desc, 2, 4 desc) loop
		costPrice:=vCrs.price;
		exit;
	end loop;
  return costPrice;
end F_COSTPRICE;
/
create or replace function F_CURRENCY
( reportparamID in numeric,
 generalpricelistid in        numeric
 )
return numeric is
 result  numeric ;
 priceType numeric;

begin

select rp.number_value1
       into priceType from reportparam rp
            where rp.reportparam_id = reportparamID ;

select
case  when priceType IN (1,2) -- replacement, SALES
     then
 ( select gpl.currency_id from generalpricelist gpl where gpl.generalpricelist_id = generalpricelistid )
   when priceType = 3  -- supplier
        then
  ( select supplier.currency_id from supplier where supplier.supplier_id = generalpricelistid )
end
into result from dual ;

return coalesce(result, 0);
end F_CURRENCY;
/
create or replace FUNCTION F_CUSTOMERSPERCLUSTER
(customerID in customer.customer_id%type)
return varchar2 is
       result varchar2(3000);
       r varchar2(30);
begin
result:=null;
r:=null;
DECLARE CURSOR Vcsr IS select cc.description
              from customerspercluster cpc, customercluster cc
              where cpc.cluster_id = cc.cluster_id and cpc.customer_id = customerID and cc.active = 'Y';
--exception when no_data_found then null;
begin
open Vcsr;
loop
FETCH Vcsr INTO r;
EXIT WHEN Vcsr%NOTFOUND;
if result is null then result := r ;
   else result := concatenate3(result, ', ', r);
end if;
end loop;
  close Vcsr;
end;
return result;
--close Vcsr;
end F_CUSTOMERSPERCLUSTER;
/
create or replace FUNCTION F_DELIVERYDAY (nDeliveredYN integer) return varchar2 is
begin
     if nDeliveredYN = 0 then return '-';
     else return 'Y';
     end if;
end f_deliveryday;
/
create or replace FUNCTION F_DELIVERYDAYS_US
(deliverydays_us in systemsetting.value%type ,
customerID in customer.customer_id%type ,
languageid in languages.language_id%type)
return varchar2 is
       result varchar2(50);
       r varchar2(7);
       type Tcsr is ref cursor;
       Vcsr Tcsr;
       i number;
begin
result:=null;
r:=null;
if deliverydays_us = 'Y' then
begin
i := 0;
loop
  i:=i+1;
  begin
  open Vcsr for select cd.deliverytype
                from customerdeliveryday cd
                where cd.customer_id=customerID and cd.day_id=i;
  fetch Vcsr into r;
  exception when no_data_found then null;
  end;
  close Vcsr;
  if i = 1 then result := coalesce(r,'-');
           else result := concatenate(result,coalesce(r,'-'));
  end if;
  r:=null;
exit when i = 7;
end loop;
  return result;
end;
else
begin
result := '';
i := 0;
loop
  i:=i+1;
  begin
  open Vcsr for select dd.code
  from day_desc dd, customerdeliveryday cdd
  where cdd.customer_id=customerID and cdd.day_id=dd.day_id
    and dd.language_id=languageid and dd.day_id=i;
  fetch Vcsr into r;
  exception when no_data_found then null;
  end;
  close Vcsr;
if r is not null then
  if result is null then result:=r;
   else result:=concatenate3(result,', ',r);
    end if;
end if;
r:=null;
exit when i = 7;
end loop;
return result;
end;
end if;
return null;
end F_DELIVERYDAYS_US;
/
create or replace function F_DeliverySchemePerCustomer
(customerid in customer.customer_id%type)
return number is
       deliveryschemeid number;
       type Tcsr is ref cursor;
       Vcsr Tcsr;
begin

  deliveryschemeid:=null;
  begin
  open Vcsr for select cds.deliveryscheme_id
                from CustomerDeliveryScheme cds, deliveryscheme ds
                where cds.customer_id = customerid
                  and cds.deliveryscheme_id = ds.deliveryscheme_id
                order by ds.frequency asc;
  fetch Vcsr into deliveryschemeid;
  exception when no_data_found then null;
  end;
  close Vcsr;

  return deliveryschemeid;
end F_DeliverySchemePerCustomer;
/
create or replace function F_DiscountWash
(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         discountlistpercustomer.dateactive%type)
return number is
 generaldiscountlistid number ;
 npriority           discountlistpercustomer.priority%type;
 p                  NUMBER ;
 maxpriority        discountlistpercustomer.priority%type;
 s                  sizedefinition.sizedefinition_id%type ;
 f                  finishingmethod.finishingmethod_id%type;
 i                  number ;
 result             number ;
 maxstartdate       customerwashdiscount.startdate%type;
 productlistpercustomer number;
begin
s := sizedefinitionid;
f := finishingmethodid;
if (customerid is null) or ( s is null ) OR ( f is null ) OR ( productid is null ) then return null; end if;
begin
 select max(priority) into maxpriority from discountlistpercustomer
             where discountlistpercustomer.customer_id = customerid
             and   discountlistpercustomer.pricetype = 1  --  WASH
             and discountlistpercustomer.dateactive <= pricedate
             and discountlistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then maxpriority := 999;
 if maxpriority is null then maxpriority := 999; end if;
end;
begin
 select min(priority) into npriority from discountlistpercustomer
             where discountlistpercustomer.customer_id = customerid
             and   discountlistpercustomer.pricetype = 1
             and discountlistpercustomer.dateactive <= pricedate
             and discountlistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then npriority := 999 ;
 if npriority is null then npriority := 999; end if;
end;
p := npriority ; -- save priority value
i := 1 ;
  loop  --- 1 --------------------------------------------------
      while npriority <= maxpriority loop ---- 2 ----------------------------------
      begin
                 select max(cupri.startdate)
                        into maxstartdate
                    from productlistpercustomer prdcu , customerwashdiscount cupri
                       where cupri.productlistpercustomer_id = prdcu.productlistpercustomer_id
                          and cupri.startdate <= pricedate
                          and pricedate >= prdcu.dateactive
                          and pricedate <= prdcu.dateinactive
                          and prdcu.customer_id = customerid
                          and prdcu.product_id = productid
                          and prdcu.sizedefinition_id = s
                          and prdcu.finishingmethod_id = f
                      group by cupri.productlistpercustomer_id ;
             exception when no_data_found then null;
                       when others then null ;
      end ;
      begin
                 select cupri.productlistpercustomer_id
                        into productlistpercustomer
                    from productlistpercustomer prdcu , customerwashdiscount cupri
                       where cupri.productlistpercustomer_id = prdcu.productlistpercustomer_id
                          and cupri.startdate <= pricedate
                          and pricedate >= prdcu.dateactive
                          and pricedate <= prdcu.dateinactive
                          and prdcu.customer_id = customerid
                          and prdcu.product_id = productid
                          and prdcu.sizedefinition_id = s
                          and prdcu.finishingmethod_id = f
                      group by cupri.productlistpercustomer_id ;
              exception when no_data_found then null;
                        when others then null ;
      end;
      begin
           select cupri.discount
                  into result
                       from customerwashdiscount cupri
                            where cupri.startdate = maxstartdate
                       and cupri.productlistpercustomer_id = productlistpercustomer;
           exception when no_data_found then null;
      end;
      if result is null then
      begin
      begin
        Select discountlistpercustomer.generaldiscountlist_id --  into generaldiscountlistid
          into generaldiscountlistid
           from discountlistpercustomer
                where discountlistpercustomer.customer_id = customerid
                and discountlistpercustomer.pricetype = 1
                and discountlistpercustomer.dateactive <= pricedate
                and discountlistpercustomer.dateinactive >= pricedate
                and discountlistpercustomer.priority = npriority;
        exception when no_data_found then null;
                  when others then null;
      end ;
      if generaldiscountlistid is not null then
      begin
           select grp.discount
                    into result
                    from generalwashdiscount grp, generaldiscountlist, discountlistpercustomer
                    where
                            discountlistpercustomer.customer_id = customerid
                        and discountlistpercustomer.pricetype = 1 -- WASH
                        and discountlistpercustomer.priority = npriority
                        and
                            discountlistpercustomer.generaldiscountlist_id = generaldiscountlist.generaldiscountlist_id
                        and generaldiscountlist.pricetype = 1
                        and generaldiscountlist.active = 'Y'
                        and
                            generaldiscountlist.generaldiscountlist_id = grp.generaldiscountlist_id
                        and grp.product_id = productid
                        and grp.sizedefinition_id = s
                        and grp.finishingmethod_id = f
                        and grp.startdate = (select max(startdate) from generalwashdiscount
                                             where generalwashdiscount.product_id = productid
                                             and generalwashdiscount.generaldiscountlist_id = grp.generaldiscountlist_id
                                             and generalwashdiscount.sizedefinition_id = s
                                             and generalwashdiscount.finishingmethod_id = f
                                             and generalwashdiscount.startdate <= pricedate);
             exception when no_data_found then null;
                       when others then null ;
      end;
      end if;
      end ;
      end if;
      if result is not null then npriority := npriority + 1 ; else npriority := maxpriority + 1; end if;
      end loop ; ----- 2 ---------------------------------------------------

    npriority := p ; -- return to min priority value
    if i = 1 and result is null then
        select  --  select sizedefinition_id for '*' code
        sizedefinition.sizedefinition_id into s
        from sizedefinition where sizedefinition.code = '*' ;
    end if;
    if i = 2 and result is null then
        select -- select finishingmethod_id for '*' code
        finishingmethod.finishingmethod_id into f
        from finishingmethod where finishingmethod.code = '*';
        s:= sizedefinitionid ;
    end if;
    if i = 3 and result is null then
        select  --  select sizedefinition_id for '*' code
        sizedefinition.sizedefinition_id into s
        from sizedefinition where sizedefinition.code = '*' ;
    end if;
    i:= i + 1 ;
  exit when i = 4 or result is not null ;
  end loop; -------- 1 -----------------------------------------------------------

if result is not null then
   return result;
          ELSE RETURN 0 ;
end if;
exception
when no_data_found then return 0 ;
when others then return null;
end F_DiscountWash ;
/
create or replace function F_ENDYEAR(
STARTWEEK in temporarydeliverystop.temporarystopstartweek%type,
ENDWEEK in temporarydeliverystop.temporarystopstartweek%type
) return number is
  Result number;
begin
  IF STARTWEEK-ENDWEEK<=0 THEN Result:=Year(SYSDATE)*100;
  ELSE Result:=(Year(SYSDATE)+1)*100;
  end if;
  return(Result);
end F_ENDYEAR;
/
create or replace function F_ExistsDelivery (
  plpdId  in                   productlistperdistribpoint.productlistperdistribpoint_id%type,
  orig in                      deliveryvariations.origin%type,
  delDate in                   deliveryvariations.deliverydate%type) return numeric is

  cnt         number;

begin

  if orig = 1 then -- manual, web
    select count(*)
    into cnt
    from deliveryvariations dv
        left outer join packingnote pn on pn.packingnote_id = dv.packingnote_id,
      productlistperdistribpoint plpd
    where plpd.productlistperdistribpoint_id = plpdId
      and dv.distributionpoint_id = plpd.distributionpoint_id
      and dv.product_id = plpd.product_id
      and dv.sizedefinition_id = plpd.sizedefinition_id
      and dv.finishingmethod_id = plpd.finishingmethod_id
      and ((dv.packingnote_id is not null and pn.deliverydate >= delDate)
        or (dv.packingnote_id is null and dv.deliverydate >= delDate))
      and dv.origin in (3,6);
  else
    select count(*)
    into cnt
    from deliveryvariations dv
        left outer join packingnote pn on pn.packingnote_id = dv.packingnote_id,
      productlistperdistribpoint plpd
    where plpd.productlistperdistribpoint_id = plpdId
      and dv.distributionpoint_id = plpd.distributionpoint_id
      and dv.product_id = plpd.product_id
      and dv.sizedefinition_id = plpd.sizedefinition_id
      and dv.finishingmethod_id = plpd.finishingmethod_id
      and ((dv.packingnote_id is not null and pn.deliverydate >= delDate)
        or (dv.packingnote_id is null and dv.deliverydate >= delDate));
  end if;

  if cnt is null then cnt := 0; end if;

  return cnt;

end F_ExistsDelivery;
/
create or replace function F_FirstRouteAndStop(customerid in customerdeliveryscheme.customer_id%type)
  return varchar2 is
  deliveryschemeid customerdeliveryscheme.deliveryscheme_id%type;
  routestopid      number;
  result           varchar2(28);
  routenumber      number;
  stopnumber       number;
  type Tcsr is ref cursor;
  Vcsr Tcsr;
begin

  deliveryschemeid:=NULL;
  begin
  open Vcsr for select cds.deliveryscheme_id
                 from CustomerDeliveryScheme cds, deliveryscheme ds
                where cds.customer_id = customerid and
                      cds.deliveryscheme_id = ds.deliveryscheme_id
                order by ds.frequency asc;
  fetch Vcsr into deliveryschemeid;
  exception when no_data_found then null;
  end;
  close Vcsr;

  if deliveryschemeid is null then
    return '';
  end if;

  begin
  open Vcsr for select route.routenumber, routestop.stopnumber
                 from routestop,
                      customerdeliveryscheme,
                      deliveryschemesperstop dstop,
                      route
                where customerdeliveryscheme.deliveryscheme_id =
                      deliveryschemeid and
                      customerdeliveryscheme.customer_id = customerid and
                      customerdeliveryscheme.customer_id = dstop.customer_id and
                      customerdeliveryscheme.deliveryscheme_id =
                      dstop.deliveryscheme_id and
                      customerdeliveryscheme.day_id = dstop.day_id and
                      routestop.routestop_id = dstop.routestop_id and
                      routestop.customer_id = customerid and
                      route.route_id = routestop.route_id;
  fetch Vcsr into routenumber, stopnumber;
  exception when no_data_found then null;
  end;
  close Vcsr;

  result := concatenate3(castnumberasvarcharwithformat(routenumber,
                                                       '999999'),
                         ' / ',
                         castnumberasvarcharwithformat(stopnumber, '999999'));
  return result;
end F_FirstRouteAndStop;
/
create or replace function F_FirstRouteIDperDay(customerid  in customer.customer_id%type,
                                                dayid in day.day_id%type)
  return number is
  routeid     number;
  routestopid routestop.routestop_id%type;
begin
  for vCsr in (select dt.routestop_id
                 from deliveryschemesperstop dt, deliveryscheme d
                where dt.customer_id = customerid and dt.day_id = dayid and
                      dt.deliveryscheme_id = d.deliveryscheme_id and
                      d.frequency =
                      (select min(d.frequency) --,cd.deliveryscheme_id
                         from customerdeliveryscheme cd, deliveryscheme d
                        where cd.customer_id = customerid and
                              cd.day_id = dayid and
                              cd.deliveryscheme_id = d.deliveryscheme_id)) loop
    if vCsr.routestop_id is not null then
      routestopid := vCsr.routestop_id;
      exit;
    end if;
  end loop;
  if routestopid is not null then
    select r.route_id
      into routeid
      from route r, routestop rs
     where rs.routestop_id = routestopid and rs.route_id = r.route_id;
  end if;
  return(routeid);
exception
  when others then
    return null;
end F_FirstRouteIDperDay;
/
create or replace function F_FirstRouteperDay(customerid  in customer.customer_id%type,
                                              planneddate in date)
  return number is
  routenr     number;
  dayid       day.day_id%type;
begin
  dayid := getabsdaynumber(planneddate);
  select min(r.routenumber)
    into routenr
    from routestop rs
         join route r on rs.route_id = r.route_id
   where rs.dateactive <= planneddate
     and rs.dateinactive >= planneddate
     and rs.routestop_id in
              (select dt.routestop_id
                 from deliveryschemesperstop dt
                      join deliveryscheme d on dt.deliveryscheme_id = d.deliveryscheme_id
                where dt.customer_id = customerid and dt.day_id = dayid
                  and d.frequency =
                      (select min(ds.frequency)
                         from customerdeliveryscheme cd
                              join deliveryscheme ds on cd.deliveryscheme_id = ds.deliveryscheme_id
                        where cd.customer_id = customerid and
                              cd.day_id = dayid));
  return(routenr);
exception
  when others then
    return null;
end F_FirstRouteperDay;
/
create or replace function F_FirstRoutestop
(customerid in customerdeliveryscheme.customer_id%type ,
 deliveryschemeid in customerdeliveryscheme.deliveryscheme_id%type)
return number is
              routestopid number ;
begin
   for vCsr in (select routestop.routestop_id
   from routestop, customerdeliveryscheme, deliveryschemesperstop dstop
where customerdeliveryscheme.deliveryscheme_id = deliveryschemeid
  and customerdeliveryscheme.customer_id = customerid
    and customerdeliveryscheme.customer_id = dstop.customer_id
    and customerdeliveryscheme.deliveryscheme_id = dstop.deliveryscheme_id
    and customerdeliveryscheme.day_id = dstop.day_id
        and routestop.routestop_id = dstop.routestop_id
         and routestop.customer_id = customerid
           --and rownum = 1
                    ) loop
       routestopid := vCsr.routestop_id;
    exit;
    end loop;
     return(routestopid);
end F_FirstRoutestop;
/
create or replace function F_FirstRoutestopPerDay
(customerid in customerdeliveryscheme.customer_id%type ,
 deliveryschemeid in customerdeliveryscheme.deliveryscheme_id%type ,
 dayid in day.day_id%type)
return number is
              routestopid number ;
begin
     for vCsr in (
select dstop.routestop_id
into routestopid
from deliveryschemesperstop dstop
where
    dstop.customer_id = customerid
and dstop.deliveryscheme_id = deliveryschemeid
and dstop.day_id = dayid
    ) loop
       routestopid := vCsr.routestop_id;
exit;
end loop;
     return(routestopid);
end F_FirstRoutestopPerDay;
/
create or replace function f_forecastamount(fp_dayid               in day.day_id%type,
                                            fp_distributionpointid in number,
                                            fp_productid           in number,
                                            fp_sizedefinitionid    in number,
                                            fp_finishingmethodid   in number) return number is
  gv_loop_date    date;
begin
  --We loop looking from stockcounts from tomorrow.
  gv_loop_date    := trunc(sysdate) + 1;
  return(f_forecastamount_date(fp_dayid, fp_distributionpointid, fp_productid, fp_sizedefinitionid, fp_finishingmethodid, gv_loop_date));
end f_forecastamount;
/
create or replace function f_forecastamount_date(fp_dayid               in day.day_id%type,
                                                 fp_distributionpointid in number,
                                                 fp_productid           in number,
                                                 fp_sizedefinitionid    in number,
                                                 fp_finishingmethodid   in number,
                                                 fp_loop_date           in date) return number is
  --function f_forecastamount, version 0.3
  --global variables
  gv_loop_dayid   number;
  gv_loop_date    date;
  gv_stda_qty     number;
  gv_dv_qty       number;
  gv_total_amount number;
begin
  --We loop looking from stockcounts from tomorrow.
  gv_loop_date    := fp_loop_date;
  gv_loop_dayid   := getabsdaynumber(gv_loop_date);
  gv_total_amount := 0;
  --Loop for the whole week
  for i in 1 .. 7 loop
    begin
      --get delivery variation qty
      --origin not in (6, 7) or (if customer.allocationmethod = 2 and origin <>2)
      select nvl(sum(dv.amount), 0)
      into   gv_dv_qty
      from   deliveryvariations dv
      where  dv.distributionpoint_id = fp_distributionpointid
      and    dv.product_id = fp_productid
      and    dv.sizedefinition_id = fp_sizedefinitionid
      and    dv.finishingmethod_id = fp_finishingmethodid
      and    dv.processed = 'N'
      and    (dv.origin not in (6, 7) or  -- 1, 3 removed PBR
            (dv.origin <> 2 and
            (select c.allocationmethod
                from   distributionpoint dp
                join   department t
                on     t.department_id = dp.department_id
                join   customer c
                on     c.customer_id = t.customer_id
                where  dp.distributionpoint_id = dv.distributionpoint_id) = 2))
      and    dv.deliverydate = gv_loop_date;
      --take into account possible negative amount
      if gv_total_amount < 0 then
        gv_dv_qty := gv_dv_qty + gv_total_amount;
      end if;
      --get standard delivery qty
      select nvl(sum(stda.amount), 0)
      into   gv_stda_qty
      from   standarddelivery std
      join   standarddeliveryline stdl
      on     stdl.standarddelivery_id = std.standarddelivery_id
      join   standarddeliveryamount stda
      on     stda.standarddeliveryline_id = stdl.standarddeliveryline_id
      join   productlistperdistribpoint plpd
      on     plpd.productlistperdistribpoint_id = stdl.productlistperdistribpoint_id
      where  plpd.distributionpoint_id = fp_distributionpointid
      and    plpd.product_id = fp_productid
      and    plpd.sizedefinition_id = fp_sizedefinitionid
      and    plpd.finishingmethod_id = fp_finishingmethodid
      and    stda.day_id = gv_loop_dayid
      and    gv_loop_date between stdl.dateactive and stdl.dateinactive;
      --check if it is the day to return the value for
      gv_total_amount := gv_stda_qty + gv_dv_qty;
      if fp_dayid = gv_loop_dayid then
        begin
          if gv_total_amount < 0 then
            return 0;
          else
            return gv_total_amount;
          end if;
        end;
      else
        begin
          --next day for loop
          gv_loop_date  := gv_loop_date + 1;
          gv_loop_dayid := gv_loop_dayid + 1;
          if gv_loop_dayid > 7 then
            gv_loop_dayid := 1;
          end if;
        end;
      end if;
    end;
  end loop; --i
  return(0);
end f_forecastamount_date;
/
create or replace function F_GeneralReplacementSalesPrice
( reportparamID in numeric,
 generalpricelistid in        numeric,
 productid in         product.product_id%type ,
 sizedefinitionid in  sizedefinition.sizedefinition_id%type
 )
return real is
 result  real ;
 sizeStarID numeric;
 dateVal date;
 priceType numeric;

begin

select rp.date_value1, rp.number_value1  -- start date
       into dateVal, priceType from reportparam rp
            where rp.reportparam_id = reportparamID ;

select sz.sizedefinition_id into sizeStarID from sizedefinition sz where sz.code = '*' ;

select
case priceType when 1 -- replacement
     then
coalesce(
( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizedefinitionid
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizedefinitionid
                                and generalreplacementprice.startdate <= dateVal )
), ( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizeStarID
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizeStarID
                                and generalreplacementprice.startdate <= dateVal )
), 0)
   when 2  -- sales
        then
coalesce(
( select gsp.price from generalsalesprice gsp
         where gsp.generalpricelist_id = generalpricelistid
         and gsp.product_id = productid
         and gsp.sizedefinition_id = sizedefinitionid
         and gsp.startdate = ( select max(generalsalesprice.startdate) from generalsalesprice
                                where generalsalesprice.generalpricelist_id = generalpricelistid
                                and generalsalesprice.product_id = productid
                                and generalsalesprice.sizedefinition_id = sizedefinitionid
                                and generalsalesprice.startdate <= dateVal )
), ( select gsp.price from generalsalesprice gsp
         where gsp.generalpricelist_id = generalpricelistid
         and gsp.product_id = productid
         and gsp.sizedefinition_id = sizeStarID
         and gsp.startdate = ( select max(generalsalesprice.startdate) from generalsalesprice
                                where generalsalesprice.generalpricelist_id = generalpricelistid
                                and generalsalesprice.product_id = productid
                                and generalsalesprice.sizedefinition_id = sizeStarID
                                and generalsalesprice.startdate <= dateVal )
), 0)
      when 3  -- supplier
        then
coalesce(
( select max(sprice.purchaseprice)
  from productsizepersupproduct pszspp, supplierproductprice sprice, supplierproduct sprd
  where pszspp.product_id = productid
  and pszspp.sizedefinition_id = sizedefinitionid
  and pszspp.supplierproduct_id = sprd.supplierproduct_id
      and sprd.supplier_id = generalpricelistid
  and pszspp.supplierproduct_id = sprice.supplierproduct_id
  and sprice.startdate = ( select max(supplierproductprice.startdate) from supplierproductprice
                           where supplierproductprice.supplierproduct_id = sprice.supplierproduct_id
                           and supplierproductprice.startdate <= dateVal )
), ( select max(sprice.purchaseprice)
     from productsizepersupproduct pszspp, supplierproductprice sprice, supplierproduct sprd
     where pszspp.product_id = productid
     and pszspp.sizedefinition_id = sizeStarID
     and pszspp.supplierproduct_id = sprd.supplierproduct_id
         and sprd.supplier_id = generalpricelistid
     and pszspp.supplierproduct_id = sprice.supplierproduct_id
     and sprice.startdate = ( select max(supplierproductprice.startdate) from supplierproductprice
                              where supplierproductprice.supplierproduct_id = sprice.supplierproduct_id
                              and supplierproductprice.startdate <= dateVal )
), 0)
end
into result from dual ;

return coalesce(result, 0);
end F_GeneralReplacementSalesPrice;
/
create or replace function F_GetActivityStop(activityid in activity.activity_id%type,
                                              stopid    in stop.stop_id%type)
  return varchar2 is
  result varchar2(6000);
  notenum varchar2(20);
begin
  result := '1';
  for Vcsr in (select pn.notenumber,c.delnoteforbulkputupitems,
    CASE WHEN (select COUNT(*) from packingnoteline pnl
      where pnl.putuptype > 1 and pnl.packingnote_id = pn.packingnote_id) > 0 THEN 1 ELSE 0 END PUTUP,
  CASE WHEN (select COUNT(*) from packingnoteline pnl2, PACKINGNOTELINEPERDELSCHEME H
      where PNL2.PACKINGNOTELINE_ID = H.PACKINGNOTELINE_ID
        AND PNL2.PACKINGNOTE_ID = PN.PACKINGNOTE_ID) > 0 THEN 1 ELSE 0 END STRAIGHTEVENEXCHANGE
          from  packingnote pn,packingnoteline pl, product p, productgroup pg, stop st, customer c
               where pn.packingnote_id=pl.packingnote_id
               and pl.product_id=p.product_id
               and p.productgroup_id=pg.productgroup_id
               and pg.activity_id = activityid
               and pn.stop_id = st.stop_id
               and st.customer_link_id = c.customer_id
               and st.stop_id=stopid
               and pn.status_id = (select s.status_id from status s where s.statustype='PN' and s.code='30')
       union
               select pn.notenumber,c.delnoteforbulkputupitems,
               CASE WHEN (select COUNT(*) from packingnoteline pnl
      where pnl.putuptype > 1 and pnl.packingnote_id = pn.packingnote_id) > 0 THEN 1 ELSE 0 END PUTUP,
        CASE WHEN (select COUNT(*) from packingnoteline pnl2, PACKINGNOTELINEPERDELSCHEME H
      where PNL2.PACKINGNOTELINE_ID = H.PACKINGNOTELINE_ID
        AND PNL2.PACKINGNOTE_ID = PN.PACKINGNOTE_ID) > 0 THEN 1 ELSE 0 END STRAIGHTEVENEXCHANGE
               from  packingnote pn,packingnotecontainer pnc, weighingcategory wg, stop st, customer c
               where pn.packingnote_id=pnc.packingnote_id
                     and pnc.weighingcategory_id=wg.weighingcategory_id
                   and wg.activity_id=activityid
                   and pn.stop_id = st.stop_id
               and st.customer_link_id = c.customer_id
               and st.stop_id=stopid
                and pn.status_id = (select s.status_id from status s where s.statustype='PN' and s.code='30')
                   )   loop
    if ((Vcsr.Putup = 1 or Vcsr.Straightevenexchange= 1) and Vcsr.Delnoteforbulkputupitems=0) then
       notenum:=concatenate3('(', castnumberasvarchar(Vcsr.notenumber),')');
       else notenum:= castnumberasvarchar(Vcsr.notenumber);
      end if;
        if (result = '1') then
      result := notenum;
    else
      if (length(result) < 5000) then
        result := concatenate3(result, ', ',notenum);
      else
        result := result || '... ';
      end if;
    end if;
  end loop;
  if result = '1' then
    result := null;
  end if;
  return result;
end F_GetActivityStop;
/
create or replace function F_GETACTUALWEARERBUDGET(
  wearereempid  in weareremployment.weareremployment_id%type,
  refdatemin       in wearerbudgettransaction.transactiondate%type,
  refdatemax       in wearerbudgettransaction.transactiondate%type)
return varchar2 is
  bugtrid wearerbudgettransaction.wearerbudgettransaction_id%type;
  actbug wearerbudgettransaction.actualbudget%type;
  actres wearerbudgettransaction.actualreserved%type;
begin
    select max(web.wearerbudgettransaction_id)
    into bugtrid
    from wearerbudgettransaction web
    where web.transactiondate >= refdatemin
      and web.weareremployment_id = wearereempid;

  if bugtrid is not null then
    select web.actualbudget, web.actualreserved
    into actbug, actres
    from wearerbudgettransaction web
    where web.wearerbudgettransaction_id = bugtrid;
    return concatenate3(to_char(actbug, '999999D99999'), '   ', to_char(actres, '999999D99999'));
  else
    return '';
  end if;

end F_GETACTUALWEARERBUDGET;
/
create or replace function F_GetAgeGroup_1(
                  invoiceDate VARCHAR2,--date type not used - is not working
                  param_referencedate IN invoiceheader.invoicedate%type := null
                  ) return number is
  days       number(30,0);
  invDate    date;
  result     integer;
  referencedate invoiceheader.invoicedate%type;
BEGIN
  invDate := to_date(invoiceDate, 'dd-mm-yyyy');
if param_referencedate IS NULL then referencedate := trunc(sysdate);
else referencedate := param_referencedate;
end if;
if (referencedate < invDate)  THEN result := -1;
ELSE
BEGIN
  days := getdatediff(referencedate, invDate);
  IF days < 30 THEN result := 0;
  ELSE IF days < 60   THEN result := 1;
  ELSE IF days < 90   THEN result := 2;
  ELSE IF days < 120  THEN result := 3;
  ELSE result := 4;
  END IF;
  END IF;
  END IF;
  END IF;
END;
END IF;
RETURN(result);
EXCEPTION
    WHEN OTHERS THEN return -1;
END;
/
create or replace function F_GetAgeGroup_2(
                  invoiceDate       VARCHAR2,--date type not used - is not working
                  startDateCurrent  VARCHAR2,--date type not used - is not working
                  startDate30       VARCHAR2,--date type not used - is not working
                  startDate60       VARCHAR2,--date type not used - is not working
                  startDate90       VARCHAR2--date type not used - is not working
                  ) return number IS
  invDate         date;
  sDateCurrent    date;
  sDate30         date;
  sDate60         date;
  sDate90         date;
  result          integer;
BEGIN
  invDate := to_date(invoiceDate, 'dd-mm-yyyy');
  sDateCurrent := to_date(startDateCurrent, 'dd-mm-yyyy');
  sDate30 := to_date(startDate30, 'dd-mm-yyyy');
  sDate60 := to_date(startDate60, 'dd-mm-yyyy');
  sDate90 := to_date(startDate90, 'dd-mm-yyyy');
  IF invDate > sDateCurrent  THEN result := 0;
  ELSE IF invDate > sDate30  THEN result := 1;
  ELSE IF invDate > sDate60  THEN result := 2;
  ELSE IF invDate > sDate90  THEN result := 3;
  ELSE IF invDate <= sDate90 THEN result := 4;
  ELSE result := -1;
  END IF;
  END IF;
  END IF;
  END IF;
  END IF;
RETURN(result);
EXCEPTION
    WHEN OTHERS THEN return -1;
END;
/
create or replace function F_GetAgeGroup_3(
                  invoiceHeaderID IN artransaction.invoiceheader_id%TYPE,
                  artransdate IN artransaction.artransactiondate%TYPE,
                  param_referencedate IN invoiceheader.invoicedate%type := null
                  ) return number is
  dueDate    date;
  days       number(30,0);
  result     integer;
  referencedate invoiceheader.invoicedate%type;
BEGIN
IF invoiceHeaderID IS NULL THEN dueDate := artransdate;
ELSE
BEGIN
SELECT ihe.paymenttermsduedate
into dueDate
from invoiceheaderextrainfo ihe
where ihe.invoiceheader_id = invoiceHeaderID;
END;
END IF;
if param_referencedate IS NULL then referencedate := trunc(sysdate);
else referencedate := param_referencedate;
end if;
if referencedate <= dueDate THEN result := 0;
ELSE
BEGIN
  days := getdatediff(referencedate, dueDate);
  IF days <= 30 THEN result := 1;
  ELSE IF days <= 60   THEN result := 2;
  ELSE IF days <= 90   THEN result := 3;
  ELSE result := 4;
  END IF;
  END IF;
  END IF;
END;
END IF;
RETURN(result);
EXCEPTION
    WHEN no_data_found THEN return -1;
END;
/
create or replace function F_GETAMOUNT
  (fpnArtransactionID           artransaction.artransaction_id%type,
   fpnParentArtArtransactionID  artransaction.parentartransaction_id%type,
   fpnAmount                    artransaction.amount%type
  ) return  number is

  LVnAmount number;
begin

  if fpnParentArtArtransactionID is null or (fpnParentArtArtransactionID <> fpnArtransactionID)
    then return fpnAmount; end if;

  select sum(b.amount)
  into LVnAmount
  from artransaction a, artransactiondetail b
  where a.artransaction_id = b.artransaction_id
    and (a.artransaction_id = fpnArtransactionID or a.parentartransaction_id = fpnArtransactionID);
  return LVnAmount;

end F_GETAMOUNT;
/
create or replace function F_GetArAgingAmount(debtorID         IN artransaction.billtocustomer_link_id%TYPE,
                                              arAgingMethod    INTEGER, --1,2 or 3
                                              groupe           INTEGER, --0,1,2,3 or 4
                                              startDateCurrent VARCHAR2, --date type not used - is not working
                                              startDate30      VARCHAR2, --date type not used - is not working
                                              startDate60      VARCHAR2, --date type not used - is not working
                                              startDate90      VARCHAR2, --date type not used - is not working
                                              routeid          IN artransaction.route_id%TYPE default -1,
                                              statementheaderid IN artransaction.invoiceheader_id%TYPE default -1,
                                              invoiceheaderid  IN artransaction.invoiceheader_id%TYPE default -1,
                                              artransactionid  IN artransaction.artransaction_id%TYPE default -1,
                                              isDebtor         INTEGER default 1)
  return number is
  --dueDate date;
  --days    number(30, 0);
  amount  artransaction.amount%type;
  referenceDate invoiceheader.invoicedate%type;
BEGIN
  IF arAgingMethod = 3 THEN
    BEGIN
      if (statementheaderid = -1) then
      if (invoiceheaderid = -1) then
        begin
          select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
            into amount
            from artransaction y, artransactiontype at
           where ((isDebtor = 1 and y.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and y.deltocustomer_link_id = debtorID))
             and y.artransactiontype_id = at.artransactiontype_id
             and at.typenumber <> 2
             and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
             and y.debitcredit = 'D'
             and (y.parentartransaction_id is null or y.parentartransaction_id = y.artransaction_id)
             and F_GetAgeGroup_3(y.invoiceheader_id, y.artransactiondate) = groupe
             and (routeid is null or routeid = -1 OR y.route_id = routeid);
          return amount;
        end;
      else
        begin
          select sum(a.amount-a.totalappliedamount)  -- sum(a.amount)
            into amount
            from artransaction a, artransactiontype at
            where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
             and a.artransactiontype_id = at.artransactiontype_id
             and at.typenumber <> 2
             and a.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
             and a.debitcredit = 'D' --and a.originaltransaction_id is not null --this should always be NOT null
             and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
             and (((artransactionid is null or artransactionid = -1)
               and a.invoiceheader_id = invoiceheaderid) or (/*invoiceheaderid is null and*/ artransactionid is not null
               and artransactionid <> -1 and a.artransaction_id = artransactionid))
             and F_GetAgeGroup_3(a.invoiceheader_id, a.artransactiondate) = groupe
             and (routeid is null or routeid = -1 OR a.route_id = routeid);
          return amount;
        end;
      end if;
      else
        begin
          select invoicedate
          into referenceDate
          from invoiceheader
          where invoiceheader_id = statementheaderid;
          select sum(s.amount)
            into amount
            from statementline s, artransaction a
           where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
             and a.debitcredit = 'D'
             and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
             and a.artransaction_id = s.ARTRANSACTION_ID
             and s.INVOICEHEADER_ID = statementheaderid
             and F_GetAgeGroup_3(a.invoiceheader_id, a.artransactiondate, referenceDate) = groupe
             and (routeid is null or routeid = -1 OR a.route_id = routeid);
          return amount;
        end;
      end if;
    END;
  ELSE
    IF arAgingMethod = 2 THEN
      BEGIN
        if (statementheaderid = -1) then
         if (invoiceheaderid = -1) then
          begin
            select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
              into amount
              from artransaction y, artransactiontype at
             where ((isDebtor = 1 and y.billtocustomer_link_id = debtorID)
                    or (isDebtor = 0 and y.deltocustomer_link_id = debtorID))
               and y.artransactiontype_id = at.artransactiontype_id
               and at.typenumber <> 2
               and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
               and y.debitcredit = 'D'
               and (y.parentartransaction_id is null or y.parentartransaction_id = y.artransaction_id)
               and F_GetAgeGroup_2(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate),
                                   startDateCurrent,
                                   startDate30,
                                   startDate60,
                                   startDate90) = groupe
               and (routeid is null or routeid = -1 OR y.route_id = routeid);
            return amount;
          end;
          else
            begin
              select sum(a.amount-a.totalappliedamount)  -- sum(a.amount)
                into amount
                from artransaction a, artransactiontype at
                where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                        or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
                 and a.artransactiontype_id = at.artransactiontype_id
                 and at.typenumber <> 2
                 and a.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
                 and a.debitcredit = 'D' --and a.originaltransaction_id is not null --this should always be NOT null
                 and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
                 and (((artransactionid is null or artransactionid = -1) and a.invoiceheader_id = invoiceheaderid) or (/*invoiceheaderid is null and*/ artransactionid is not null and artransactionid <> -1 and a.artransaction_id = artransactionid))
                 and F_GetAgeGroup_2(GETDATEASVARCHARFIXEDFORMAT(a.artransactiondate),
                                   startDateCurrent,
                                   startDate30,
                                   startDate60,
                                   startDate90) = groupe
                 and (routeid is null or routeid = -1 OR a.route_id = routeid);
              return amount;
            end;
          end if;
        else
          begin
            select sum(s.amount)
              into amount
              from statementline s, artransaction a
             where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
             and a.debitcredit = 'D'
             and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
               and a.artransaction_id = s.ARTRANSACTION_ID
               and s.INVOICEHEADER_ID = statementheaderid
               and F_GetAgeGroup_2(GETDATEASVARCHARFIXEDFORMAT(a.artransactiondate),
                                   startDateCurrent,
                                   startDate30,
                                   startDate60,
                                   startDate90) = groupe
               and (routeid is null or routeid = -1 OR a.route_id = routeid);
            return amount;
          end;
        end if;
      END;
    ELSE      -- arAgingMethod = 1
      BEGIN
        if (statementheaderid = -1) then
         if (invoiceheaderid = -1) then
          begin
            select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
              into amount
              from artransaction y, artransactiontype at --, customerbillinginfo cbi
             where ((isDebtor = 1 and y.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and y.deltocustomer_link_id = debtorID))   --cbi.customer_id and cbi.paybycustomer_link_id =
               and y.artransactiontype_id = at.artransactiontype_id
               and at.typenumber <> 2
               and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
               and y.debitcredit = 'D'
               and (y.parentartransaction_id is null or y.parentartransaction_id = y.artransaction_id)
               and F_GetAgeGroup_1(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate)) = groupe
               and (routeid is null or routeid = -1 OR y.route_id = routeid);
            return amount;
          end;
          else
            begin
              select sum(a.amount-a.totalappliedamount)  -- sum(a.amount)
                into amount
                from artransaction a, artransactiontype at
                where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
                 and a.artransactiontype_id = at.artransactiontype_id
                 and at.typenumber <> 2
                 and a.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
                 and a.debitcredit = 'D' --and a.originaltransaction_id is not null --this should always be NOT null
                 and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
                 and (((artransactionid is null or artransactionid = -1) and a.invoiceheader_id = invoiceheaderid) or (/*invoiceheaderid is null and*/ artransactionid is not null and artransactionid <> -1 and a.artransaction_id = artransactionid))
                 and  F_GetAgeGroup_1(GETDATEASVARCHARFIXEDFORMAT(a.artransactiondate)) = groupe
                 and (routeid is null or routeid = -1 OR a.route_id = routeid);
              return amount;
            end;
          end if;
        else
          begin
            select invoicedate
            into referenceDate
            from invoiceheader
            where invoiceheader_id = statementheaderid;
            select sum(s.amount)
              into amount
              from statementline s, artransaction a
             where ((isDebtor = 1 and a.billtocustomer_link_id = debtorID)
                  or (isDebtor = 0 and a.deltocustomer_link_id = debtorID))
             and a.debitcredit = 'D'
             and (a.parentartransaction_id is null or a.parentartransaction_id = a.artransaction_id)
               and a.artransaction_id = s.ARTRANSACTION_ID
               and s.INVOICEHEADER_ID = statementheaderid
               and F_GetAgeGroup_1(GETDATEASVARCHARFIXEDFORMAT(a.artransactiondate), referenceDate) = groupe
               and (routeid is null or routeid = -1 OR a.route_id = routeid);
            return amount;
          end;
        end if;
        return amount;
      END;
    END IF;
  END IF;
EXCEPTION
  WHEN no_data_found THEN
    RETURN 0;
END;
/
create or replace function f_getaragingamountdelto(
                  deltoID           IN artransaction.deltocustomer_link_id%TYPE,
                  groupe            INTEGER,--0,1,2,3 or 4
                  routeid           IN artransaction.route_id%TYPE  default -1,
                  invoiceheaderid   IN artransaction.invoiceheader_id%TYPE  default -1
                  ) return number is
  arAgingMethod     number;
  amount            artransaction.amount%type;
  MyDate            date;
  MyYear            number;
  MyMonth           number;
  startDateCurrent  VARCHAR2(10);
  startDate30       VARCHAR2(10);
  startDate60       VARCHAR2(10);
  startDate90       VARCHAR2(10);
BEGIN
select ss.value
  into arAgingMethod
  from systemsetting ss, businessunit b, customer c
 where ss.name='ARAGINGMETHOD'
   and ss.plant_id = b.plant_id
   and b.businessunit_id = c.defaultbusinessunit_id
   and c.customer_id = deltoID;

IF arAgingMethod = 3  -- 3 = by payment terms (supports both Net x and Running Month+ )
THEN
BEGIN
      select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.deltocustomer_link_id = deltoID  --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_3(y.invoiceheader_id, y.artransactiondate) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
ELSE IF arAgingMethod = 2 -- 2 = By Month
THEN
BEGIN
      mydate := trunc(sysdate);
      myyear := to_number(to_char(mydate,'YYYY'));
      mymonth := to_number(to_char(mydate,'MM'));
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDateCurrent := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate30 := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate60 := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate90 := to_char(mydate,'dd-mm-yyyy');
      select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.deltocustomer_link_id = deltoID
         --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_2(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate), startDateCurrent, startDate30, startDate60, startDate90) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
ELSE -- arAgingMethod = 1 = By day
BEGIN
      select sum(y.amount - y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.deltocustomer_link_id = deltoID   --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_1(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate)) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
END IF;
END IF;
EXCEPTION
    WHEN no_data_found THEN RETURN 0;
END;
/
create or replace function F_GetArAgingAmountNoRPparam(
                  debtorID          IN artransaction.billtocustomer_link_id%TYPE,
                  groupe            INTEGER,--0,1,2,3 or 4
                  routeid           IN artransaction.route_id%TYPE  default -1,
                  invoiceheaderid   IN artransaction.invoiceheader_id%TYPE  default -1
                  ) return number is
  arAgingMethod     number;
  amount            artransaction.amount%type;
  MyDate            date;
  MyYear            number;
  MyMonth           number;
  startDateCurrent  VARCHAR2(10);
  startDate30       VARCHAR2(10);
  startDate60       VARCHAR2(10);
  startDate90       VARCHAR2(10);
BEGIN
select ss.value
 into arAgingMethod
 from systemsetting ss, businessunit b, customer c
 where ss.name='ARAGINGMETHOD'
   and ss.plant_id = b.plant_id
   and b.businessunit_id = c.defaultbusinessunit_id
   and c.customer_id = debtorID;

IF arAgingMethod = 3  -- 3 = by payment terms (supports both Net x and Running Month+ )
THEN
BEGIN
      select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.billtocustomer_link_id = debtorID
         --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_3(y.invoiceheader_id, y.artransactiondate) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
ELSE IF arAgingMethod = 2 -- 2 = By Month
THEN
BEGIN
      mydate := trunc(sysdate);
      myyear := to_number(to_char(mydate,'YYYY'));
      mymonth := to_number(to_char(mydate,'MM'));
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDateCurrent := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate30 := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate60 := to_char(mydate,'dd-mm-yyyy');
      mymonth := mymonth -1;
      if mymonth = 0 then
        mymonth := 12;
        myyear := myyear -1;
      end if;
      mydate := to_date(myyear||'-'||mymonth||'-01' ,'YYYY-MM-DD');
      startDate90 := to_char(mydate,'dd-mm-yyyy');
      select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.billtocustomer_link_id = debtorID
         --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_2(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate), startDateCurrent, startDate30, startDate60, startDate90) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
ELSE -- arAgingMethod = 1 = By day
BEGIN
      select sum(y.amount-y.totalappliedamount)  -- sum(y.amount)
        into amount
        from artransaction y, artransactiontype at
       where y.billtocustomer_link_id = debtorID
         --AND Y.BUSINESSUNIT_ID = BU_ID
         and y.artransactiontype_id = at.artransactiontype_id
         and at.typenumber <> 2
         and y.isopen_yn = 'Y'                   -- y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or
             y.parentartransaction_id = y.artransaction_id)
         and F_GetAgeGroup_1(GETDATEASVARCHARFIXEDFORMAT(y.artransactiondate)) = groupe
         and (routeid = -1 OR y.route_id = routeid)
         and (invoiceheaderid = -1 OR y.invoiceheader_id = invoiceheaderid);
   return amount;
END;
END IF;
END IF;
EXCEPTION
    WHEN no_data_found THEN RETURN 0;
END;
/
create or replace function F_GetAvgPPAtDatePerSkProdSize(P_RequestedDate    in StockValueAVGPP.Transactiondate%type,
                                                            p_productid        in product.product_id%type,
                                                            p_sizedefinitionid in sizedefinition.sizedefinition_id%type,
                                                            p_stockroomid      in stockroom.stockroom_id%type,
                                                            p_customerowned    in sqstockquantity.customerowned%type,
                                                            p_customerid       in sqstockquantity.customer_link_id%type)
  return number is
  v_avgpurchaseprice  StockValueAVGPP.avgpurchaseprice%type;
begin
  SELECT max(t.avgpurchaseprice)
    INTO v_avgpurchaseprice
    FROM StockValueAVGPP t
   WHERE t.stockvalueavgpp_id =
         (SELECT MAX(s.stockvalueavgpp_id)
            FROM StockValueAVGPP     s,
                 PRODUCT_LINK        pl,
                 SIZEDEFINITION_LINK sl,
                 CUSTOMER_LINK       cl
           WHERE s.product_link_id = pl.product_link_id
             and s.sizedefinition_link_id = sl.sizedefinition_link_id
             and pl.product_id = p_productid
             and sl.sizedefinition_id = p_sizedefinitionid
             --and s.qualitygrade_id = v_qualitygrade_id
             and s.stockroom_id = p_stockroomid
             and trunc(s.transactiondate) <= p_requesteddate
             and ((s.customer_link_id = cl.customer_link_id and
                 cl.customer_id = p_customerid and
                 s.customerowned = p_customerowned) or
                 s.customer_link_id is null))
     and t.product_link_id = p_productid
     and t.sizedefinition_link_id = p_sizedefinitionid
     --and t.qualitygrade_id = v_qualitygrade_id
     and ((t.customer_link_id = p_customerid and
         t.customerowned = p_customerowned) or t.customer_link_id is null);
  return nvl(v_avgpurchaseprice,0);
exception
  when no_data_found then
    return 0;
  when others then
    return 0;
end F_GetAvgPPAtDatePerSkProdSize;
/
create or replace function f_getavgpurchaseprice(p_stockreservationpergrade_id in stockreservationpergrade.stockreservationpergrade_id%type)
  return number is
  -- **********************************************************************
  --
  -- PROGRAM-ID F_GetAvgPurchasePrice
  -- AUTHOR: CMU
  -- DATE-WRITTTEN: 31-07-2007
  --      updated : 25-Feb-2021
  --
  -- SCOPE:
  --      STOCKROOM
  --
  -- ORDER:
  --      502109
  --
  -- PRECONDITIONS:
  --
  -- DESCRIPTION:
  --  The method should operate on table StockValueAVGPP and return the values
  -- for the attribute AvpgPurchasePrice for that record with the most recent transaction.
  --
  -- PROGRAM FLOW::
  --      1. First determine the desired product, size, grade
  --      2. Then search for the most recent price
  --
  -- INPUT PARAMETERS:
  --  P_StockReservationPerGrade_ID [NUMBER]
  --
  -- OUTPUT PARAMETERS:
  --  P_AvgPurchasePrice [NUMBER]
  --
  -- EXCEPTIONS:
  --  if no data found then return 0
  --
  -- IMPLEMENTATION:
  --
  -- POST CONDITIONS:
  --
  -- **********************************************************************
  gv_avgpurchaseprice stockvalueavgpp.avgpurchaseprice%type;
begin
  for x in (select sd.product_id product, sd.sizedefinition_id, sd.customer_id, sd.customerowned,
                   sg.qualitygrade_id, s.managedbybu_id
            from   stockreservationpergrade sg
            join   stockdefinitionperitem sd
            on     sd.stockdefinitionperitem_id = sg.stockdefinitionperitem_id
            join   stockroom s
            on     s.stockroom_id = sd.stockroom_id
            where  sg.stockreservationpergrade_id = p_stockreservationpergrade_id) loop
    begin
      select t.avgpurchaseprice
      into   gv_avgpurchaseprice
      from   stockvalueavgpp t
      where  t.stockvalueavgpp_id =
             (select max(s.stockvalueavgpp_id)
              from   stockvalueavgpp s
              join   stockroom sr
              on     sr.stockroom_id = s.stockroom_id
              where  s.product_link_id = x.product
              and    s.sizedefinition_link_id = x.sizedefinition_id
              and    s.qualitygrade_id = x.qualitygrade_id
              and    sr.managedbybu_id = x.managedbybu_id
              and    (s.customerowned = x.customerowned or s.customer_link_id is null));
      return gv_avgpurchaseprice;
    end;
  end loop;
  return 0;
exception
  when no_data_found then
    return 0;
end f_getavgpurchaseprice;
/
create or replace function F_GetAvgPurchasePricesAtDate
( P_StockReservationPerGrade_ID in  StockReservationPerGrade.StockReservationPerGrade_ID%type,
  P_RequestedDate               in  StockValueAVGPP.Transactiondate%type )
return number is
v_product_id  product.product_id%type;
v_sizedefinition_id sizedefinition.sizedefinition_id%type;
v_customer_id customer.customer_id%type;
v_customerowned stockdefinitionperitem.customerowned%type;
v_qualitygrade_id product.product_id%type;
v_avgpurchaseprice StockValueAVGPP.avgpurchaseprice%type;
v_businessunit_id businessunit.businessunit_id%type;
begin
SELECT sd.product_id product, sd.sizedefinition_id sdf, sd.customer_id, sd.customerowned, sg.qualitygrade_id, bu.businessunit_id
      INTO v_product_id, v_sizedefinition_id, v_customer_id, v_customerowned, v_qualitygrade_id, v_businessunit_id
      FROM stockreservationpergrade sg, stockdefinitionperitem sd, stockroom s, businessunit bu
      WHERE sd.stockdefinitionperitem_id = sg.stockdefinitionperitem_id
      and sd.stockroom_id=s.stockroom_id
      and s.managedbybu_id=bu.businessunit_id
      and sg.stockreservationpergrade_id = P_StockReservationPerGrade_ID;

SELECT max(t.avgpurchaseprice)
INTO v_avgpurchaseprice
FROM StockValueAVGPP t
WHERE
t.stockvalueavgpp_id = ( SELECT  MAX(s.stockvalueavgpp_id)
                            FROM StockValueAVGPP s, PRODUCT_LINK pl, SIZEDEFINITION_LINK sl, CUSTOMER_LINK cl, stockroom sr
                            WHERE
                            s.stockroom_id=sr.stockroom_id
                            and  s.product_link_id = pl.product_link_id
                            and s.sizedefinition_link_id = sl.sizedefinition_link_id
                            and pl.product_id = v_product_id
                            and sl.sizedefinition_id = v_sizedefinition_id
                            and s.qualitygrade_id = v_qualitygrade_id
                            and sr.managedbybu_id=v_businessunit_id
                            and  trunc(s.transactiondate) <= p_requesteddate
                            and ((s.customer_link_id = cl.customer_link_id and cl.customer_id = v_customer_id
                                   and s.customerowned = v_customerowned)
                                 or s.customer_link_id is null))
and t.product_link_id = v_product_id
and t.sizedefinition_link_id = v_sizedefinition_id
and t.qualitygrade_id = v_qualitygrade_id
and ((t.customer_link_id = v_customer_id and t.customerowned = v_customerowned)
or t.customer_link_id is null);
return  v_avgpurchaseprice;
exception
when no_data_found then return 0;
when others then
return  0;
end F_GetAvgPurchasePricesAtDate;
/
create or replace function F_GetBusinessUnit
(plantid in          plant.plant_id%type,
 customerid in       customer.customer_id%type,
 usergroupid in      usergroup.usergroup_id%type)
return VARCHAR2 is
 bucode               businessunit.code%type;
 nodata               boolean;
begin

  bucode := null;
  begin
    select b.code
    into bucode
    from customer c, businessunit b
      where c.defaultbusinessunit_id = b.businessunit_id
        and b.plant_id = plantid
        and c.customer_id = customerid;
    exception when no_data_found then nodata:=true;
  end;

  if nodata then
    begin
      select min(bu.code)
      into bucode
      from customeractivities ca, businessunit bu
      where ca.processbusinessunit_id = bu.businessunit_id
        and bu.plant_id = plantid
        and ca.customer_id = customerid;
      exception when no_data_found then null;
    end;
  end if;

  return bucode;

end F_GetBusinessUnit;
/
create or replace function f_getColliDefault_ECL(fpDistributionpointID distributionpoint.distributionpoint_id%type,
                                                 fpTransportarticleID  transportarticle.transportarticle_id%type,
                                                 fpStopID              stop.stop_id%type)
  return number is
  rvColliDefault number;
  lvRouteID      route.route_id%type;
  lvCustomerID   customer.customer_id%type;
  lvPlantID      plant.plant_id%type;
  stay34         stay.stay_id%type;
  lvmax          number;
begin
  select s.stay_id
    into stay34
    from stay s
   where s.staytype = 1
     and s.staynr = 34;

  select rs.route_id, r.plant_id, s.customer_link_id
    into lvRouteID, lvPlantID, lvCustomerID
    from stop s, routestop rs, route r
   where s.stop_id = fpStopID
     and r.route_id = rs.route_id
     and s.routestop_id = rs.routestop_id;

  rvColliDefault := 0;

  for x in (select ui.product_id prod_id, count(1) items
              from uniqueitem        ui,
                   uniqueitemnonpool un,
                   uniqueitemroute   ur,
                   weareremployment  we,
                   wearer            w
             where ui.uniqueitem_id = un.uniqueitem_id
               and ur.uniqueitem_id = ui.uniqueitem_id
               and un.weareremployment_id = we.weareremployment_id
               and we.distributionpoint_id = fpDistributionpointID
               and w.wearer_id = we.wearer_id
               and w.customer_id = lvCustomerID
               and ur.plannedoutroute_id = lvRouteID
               and ui.stay_id = stay34
               and not exists
             (select 1
                      from uniqueitemflag uf, sortaddressperflag sf
                     where uf.flag_id = sf.flag_id
                       and sf.plant_id = lvPlantID
                       and sf.sortaddress is not null
                       and uf.uniqueitem_id = ui.uniqueitem_id
                       and uf.startdate <= sysdate)
             group by ui.product_id) loop

    begin
      select ppta.maxcartqty
        into lvmax
        from plantproducttransportarticle ppta
       where ppta.plant_id = lvPlantID
         and ppta.product_id = x.prod_id
         and ppta.transportarticle_id = fpTransportarticleID;

    exception
      when no_data_found then
        begin
          select pta.maxcartqty
            into lvmax
            from producttransportarticle pta
           where pta.product_id = x.prod_id
             and pta.transportarticle_id = fpTransportarticleID;
        exception
          when no_data_found then
            begin
              lvmax := 99999;
            end;
        end;
    end;

    rvColliDefault := rvColliDefault + (x.items / lvmax);

  end loop;

  rvColliDefault := ROUND(rvColliDefault + 0.4);
  return rvColliDefault;

end f_getColliDefault_ECL;
/
create or replace function f_getcontactonroutelist(
customer_id in customer.customer_id%type
) return number is
  contact_id number;
begin
  select c.contact_id
  into contact_id
  from contact c
  where c.customer_link_id = customer_id
        and c.showonroutelist = 'Y'
        and rownum < 2;
  return(contact_id);
end f_getcontactonroutelist;
/
create or replace function f_getcontractprice_type(fp_contractid        in number,
                                                   fp_pricetype         in number,
                                                   fp_date              in date,
                                                   fp_productid         in number,
                                                   fp_sizeid            in number,
                                                   fp_finishingmethodid in number)
  return t_contractprice_tab
  pipelined
  parallel_enable is
  --function f_getcontractprice_type version 0.2
  pragma udf;
begin
  case fp_pricetype
    when 1 then
      for w in (select ctprl.contract_id, ctprl.pricetype, gwp.startdate pricedate, gwp.product_id,
                       gwp.finishingmethod_id, gwp.sizedefinition_id, gwp.price
                from   contractpricelist ctprl
                join   generalwashprice gwp
                on     gwp.generalpricelist_id = ctprl.generalpricelist_id
                where  ctprl.contract_id = fp_contractid
                and    gwp.product_id = fp_productid
                and    gwp.sizedefinition_id = fp_sizeid
                and    gwp.finishingmethod_id = fp_finishingmethodid
                and    ctprl.pricetype = 1 --Wash
                and    gwp.startdate <= fp_date
                and    ctprl.startdate <= fp_date
                and    ctprl.enddate >= fp_date
                order  by gwp.startdate desc) loop
        begin
          pipe row(t_contractprice(w.contract_id, w.pricetype, w.pricedate, w.product_id,
                                   w.sizedefinition_id, w.finishingmethod_id, w.price));
          exit;
        end;
      end loop; --w
    when 2 then
      for r in (select ctprl.contract_id, ctprl.pricetype, grp.startdate pricedate, grp.product_id,
                       grp.finishingmethod_id, grp.sizedefinition_id, grp.price
                from   contractpricelist ctprl
                join   generalrentprice grp
                on     grp.generalpricelist_id = ctprl.generalpricelist_id
                where  ctprl.contract_id = fp_contractid
                and    grp.product_id = fp_productid
                and    grp.sizedefinition_id = fp_sizeid
                and    grp.finishingmethod_id = fp_finishingmethodid
                and    ctprl.pricetype = 2 --Rent
                and    grp.startdate <= fp_date
                and    ctprl.startdate <= fp_date
                and    ctprl.enddate >= fp_date
                order  by grp.startdate desc) loop
        begin
          pipe row(t_contractprice(r.contract_id, r.pricetype, r.pricedate, r.product_id,
                                   r.sizedefinition_id, r.finishingmethod_id, r.price));
          exit;
        end;
      end loop; --r
    when 3 then
      for r in (select ctprl.contract_id, ctprl.pricetype, grp.startdate pricedate, grp.product_id,
                       fp_finishingmethodid finishingmethod_id, grp.sizedefinition_id, grp.price
                from   contractpricelist ctprl
                join   generalreplacementprice grp
                on     grp.generalpricelist_id = ctprl.generalpricelist_id
                where  ctprl.contract_id = fp_contractid
                and    grp.product_id = fp_productid
                and    grp.sizedefinition_id = fp_sizeid
                and    ctprl.pricetype = 3 --Replacement
                and    grp.startdate <= fp_date
                and    ctprl.startdate <= fp_date
                and    ctprl.enddate >= fp_date
                order  by grp.startdate desc) loop
        begin
          pipe row(t_contractprice(r.contract_id, r.pricetype, r.pricedate, r.product_id,
                                   r.sizedefinition_id, r.finishingmethod_id, r.price));
          exit;
        end;
      end loop; --s
    when 4 then
      for s in (select ctprl.contract_id, ctprl.pricetype, gsp.startdate pricedate, gsp.product_id,
                       fp_finishingmethodid finishingmethod_id, gsp.sizedefinition_id, gsp.price
                from   contractpricelist ctprl
                join   generalsalesprice gsp
                on     gsp.generalpricelist_id = ctprl.generalpricelist_id
                where  ctprl.contract_id = fp_contractid
                and    gsp.product_id = fp_productid
                and    gsp.sizedefinition_id = fp_sizeid
                and    ctprl.pricetype = 4 --Sales
                and    gsp.startdate <= fp_date
                and    ctprl.startdate <= fp_date
                and    ctprl.enddate >= fp_date
                order  by gsp.startdate desc) loop
        begin
          pipe row(t_contractprice(s.contract_id, s.pricetype, s.pricedate, s.product_id,
                                   s.sizedefinition_id, s.finishingmethod_id, s.price));
          exit;
        end;
      end loop; --s
    else
      pipe row(t_contractprice(fp_contractid, fp_pricetype, fp_date, fp_productid, fp_sizeid,
                               fp_finishingmethodid, null));
  end case;
end f_getcontractprice_type;
/
create or replace function F_GETCOSTREPORTPRICE(FPcustomerid            in customer.customer_id%type,
                                                FPproductid             in product.product_id%type,
                                                FPsizedefinitionid      in sizedefinition.sizedefinition_id%type,
                                                FPfinishingmethodid     in finishingmethod.finishingmethod_id%type,
                                                FPpricedate             in pricelistpercustomer.dateactive%type,
                                                FPmerchandisetype       in product.typeofmerchandise%type,
                                                FPproductweighingcat_id in product.weighingcategory_id%type,
                                                FPpricedecimals         in currency.decimals%type)
  return number is

  LVBillmeth           productlistpercustomer.billingmethod%type;
  LVSpecWeighingcat_id product.weighingcategory_id%type; -- productlistpercustomer.specificweighingcategory_id%type;
  LVCostPrice          number;
  LVInvoiceMethod      number;
  LVInclWashSalesPrice number;
  LVInclRentPrice      number;
  LVInclWeightPrice    number;
  LVInclCostRptPrice   number;
  LVCostRtpPrice       number(15, 6);
  LVSoil               varchar2(1);
  LVWeight             number;
  LVPlpcID             number;
  type Tcsr is ref cursor;
  Vcsr Tcsr;

begin
  -- initialize
  LVCostPrice := 0;
  LVbillmeth  := 0;
  -- read plpc
  begin
    select min(plpc.productlistpercustomer_id),
           min(plpc.billingmethod),
           min(plpc.Specificweighingcategory_id),
           min(plpc.Costpriceinclwashsalesprice),
           min(plpc.Costpriceinclrentprice),
           min(plpc.Costpriceinclweightprice),
           min(plpc.Costpriceinclcostreportprice)
      into LVPlpcID,
           LVbillmeth,
           LVSpecWeighingcat_id,
           LVInclWashSalesPrice,
           LVInclRentPrice,
           LVInclWeightPrice,
           LVInclCostRptPrice
      from productlistpercustomer plpc
     where ((FPpricedate >= plpc.dateactive
       and FPpricedate <= plpc.dateinactive) or FPpricedate >= plpc.dateactive)
       and plpc.customer_id = FPcustomerid
       and plpc.product_id = FPproductid
       and plpc.sizedefinition_id = FPsizedefinitionid
       and plpc.finishingmethod_id = FPfinishingmethodid;
  exception
    when no_data_found then
      null;
  end;
  -- try size *
  if ((LVbillmeth = 0) or (LVbillmeth is null)) then
    begin
      select min(plpc.productlistpercustomer_id),
             min(plpc.billingmethod),
             min(plpc.Specificweighingcategory_id),
             min(plpc.Costpriceinclwashsalesprice),
             min(plpc.Costpriceinclrentprice),
             min(plpc.Costpriceinclweightprice),
             min(plpc.Costpriceinclcostreportprice)
        into LVPlpcID,
             LVbillmeth,
             LVSpecWeighingcat_id,
             LVInclWashSalesPrice,
             LVInclRentPrice,
             LVInclWeightPrice,
             LVInclCostRptPrice
        from productlistpercustomer plpc, sizedefinition s
       where ((FPpricedate >= plpc.dateactive
         and FPpricedate <= plpc.dateinactive) or FPpricedate >= plpc.dateactive)
         and plpc.customer_id = FPcustomerid
         and plpc.product_id = FPproductid
         and plpc.sizedefinition_id = s.sizedefinition_id
         and s.code = '*'
         and plpc.finishingmethod_id = FPfinishingmethodid;
    exception
      when no_data_found then
        null;
    end;
  end if;
  -- Start price calculation
  if NOT ((LVbillmeth = 0) or (LVbillmeth is null)) then
    -- Wash or Sales Price part
    if LVInclWashSalesPrice = 1 then
      if FPmerchandisetype <> 3 then
        LVCostPrice := LVCostPrice + Round(pack_price.Wash_Price(FPcustomerid,
                                                                 FPproductid,
                                                                 FPsizedefinitionid,
                                                                 FPfinishingmethodid,
                                                                 FPpricedate) *
                                           (100 -
                                            pack_price.Wash_Discount(FPcustomerid,
                                                                     FPproductid,
                                                                     FPsizedefinitionid,
                                                                     FPfinishingmethodid,
                                                                     FPpricedate)) / 100,
                                           FPpricedecimals);
      else
        LVCostPrice := LVCostPrice +
                       pack_price.Sales_Price(FPcustomerid,
                                              FPproductid,
                                              FPsizedefinitionid,
                                              FPpricedate);
      end if; -- FPmerchandisetype <> 3
    end if; -- LVInclWashSalesPrice = 1
    -- Rent Price part
    if LVInclRentPrice = 1 then
      LVCostPrice := LVCostPrice + Round(pack_price.Rent_Price(FPcustomerid,
                                                               FPproductid,
                                                               FPsizedefinitionid,
                                                               FPfinishingmethodid,
                                                               FPpricedate,
                                                               0) *
                                         (100 -
                                          pack_price.Rent_Discount(FPcustomerid,
                                                                   FPproductid,
                                                                   FPsizedefinitionid,
                                                                   FPfinishingmethodid,
                                                                   FPpricedate)) / 100,
                                         FPpricedecimals);
    end if; -- LVInclRentPrice = 1
    -- Weight Price part
    if LVInclWeightPrice = 1 and (FPproductweighingcat_id is not null or
       LVSpecWeighingcat_id is not null) then
      begin
        open Vcsr for
          select wcc.invoicemethod
            from weighingcategpercustomer wcc
           where wcc.customer_id = FPCustomerID
             and wcc.weighingcategory_id =
                 nvl(LVSpecWeighingcat_id, FPproductweighingcat_id);
        fetch Vcsr
          into LVInvoiceMethod;
      exception
        when no_data_found then
          null;
      end;
      close Vcsr;

      LVWeight := 0;
      begin
        select prds.theoreticalweight
          into LVWeight
          from productsize prds
         where prds.product_id = FPProductID
           and prds.sizedefinition_id = FPSizedefinitionID;
      exception
        when others then
          LVWeight := 0;
      end;

      LVSoil := null;
      if LVInvoiceMethod = 3 then
        LVSoil := 'N';
      else
        if (LVInvoiceMethod = 2 or LVInvoiceMethod = 4) then
          LVSoil := 'Y';
        end if;
      end if;
      if LVSoil is not null and LVWeight <> 0 then
        LVCostPrice := LVCostPrice +
                       Round(LVWeight * Round(pack_price.Weight_Price(FPCustomerID,
                                                                      nvl(LVSpecWeighingcat_id,
                                                                          FPproductweighingcat_id),
                                                                      LVSoil,
                                                                      FPPricedate) *
                                              (100 -
                                               pack_price.Weight_Discount(FPCustomerID,
                                                                          nvl(LVSpecWeighingcat_id,
                                                                              FPproductweighingcat_id),
                                                                          LVSoil,
                                                                          FPPricedate)) / 100,
                                              FPpricedecimals),
                             FPpricedecimals);
      end if;
    end if; -- LVInclWeightPrice = 1
    -- Cost Report Price part
    if LVInclCostRptPrice = 1 then
      LVCostRtpPrice := 0;
      begin
        select min(ccrp.price)
          into LVCostRtpPrice
          from CUSTOMERCOSTREPORTPRICE ccrp
         where ccrp.productlistpercustomer_id = LVPlpcID
           and ccrp.startdate =
               (select max(cc.startdate)
                  from CUSTOMERCOSTREPORTPRICE cc
                 where cc.productlistpercustomer_id = LVPlpcID
                   and cc.startdate <= FPpricedate);
      exception
        when no_data_found then
          null;
      end;
      LVCostPrice := LVCostPrice + nvl(LVCostRtpPrice, 0);
    end if; -- LVInclCostRptPrice = 1

  end if; -- NOT ((LVbillmeth = 0) or (LVbillmeth is null))
  return(LVCostPrice);
end F_GETCOSTREPORTPRICE;
/
create or replace function f_getcustcostspeccode
  (productid             product.product_id%type,
   sizedefinitionid      sizedefinition.sizedefinition_id%type,
   finishingmethodid     finishingmethod.finishingmethod_id%type,
   plpcdate              productlistpercustomer.dateactive%type,
   weighingcategid       weighingcategory.weighingcategory_id%type,
   cust_id               customer_link.customer_link_id%type,
   invoicelinetypeid     invoicelinetype.invoicelinetype_id%type
   ) return varchar2  is
  cccode varchar2(12);
  val varchar2(12);
  cnt number;
  specialsize number;
  begin
  cnt:=0;
  cccode:='';
  val:='';
  specialsize:=0;
 select   count(cc.customercostspecification_id)into cnt
   from   customercostspecification cc
     where cc.customer_link_id=cust_id;
if cnt=0
    then
      begin
        cccode:='';
     return cccode;
    end;
end if;
if cnt>0 and invoicelinetypeid in (16, 18)
    then
      begin
       cccode:='';
     return cccode;
    end;
end if;
if productid is null and weighingcategid  is null
    then
      begin
        cccode:='';
    return cccode;
    end;
end if;
if weighingcategid  is not  null then
  begin
     select ccs.code  into val from weighingcategory wg,
    weighingcategpercustomer wcc left outer join customercostspecification ccs on wcc.customercostspecification_id=ccs.customercostspecification_id
   where wcc.weighingcategory_id=wg.weighingcategory_id
   and wcc.customer_id=cust_id
   and wg.weighingcategory_id=weighingcategid
   and wcc.dateactive<plpcdate
   and wcc.dateinactive>plpcdate;
      if val is not null then
         cccode:=val;
       end if;
       if val is null and invoicelinetypeid not in (3, 4) then
         begin
          select cc.code  into cccode
          from   customercostspecification cc
          where  cc.customer_link_id=cust_id
          and    cc.useasdefault='Y';
         end;
        end if;
   return cccode;
  end;
end if;
if productid is not null then
   begin
  select count(plpc.productlistpercustomer_id) into cnt
         from productlistpercustomer plpc
         where  plpc.product_id=productid
         and plpc.sizedefinition_id=sizedefinitionid
         and plpc.finishingmethod_id=finishingmethodid
         and plpc.customer_id=cust_id
         and plpc.dateactive<plpcdate
         and plpc.dateinactive>plpcdate;
  if cnt=1 then
           select cc.code into val
           from productlistpercustomer plpc left outer join customercostspecification cc
           on  plpc.customercostspecification_id=cc.customercostspecification_id
           where plpc.product_id=productid
           and plpc.sizedefinition_id=sizedefinitionid
           and plpc.finishingmethod_id=finishingmethodid
           and plpc.customer_id=cust_id
           and plpc.dateactive<plpcdate
           and plpc.dateinactive>plpcdate;
               if val is  not null then
                   cccode:=val;
               end if;
    else
        select count(s.sizedefinition_id) into specialsize from sizedefinition s where s.code='*';
        if specialsize > 0 then
            select cc.code into val
           from productlistpercustomer plpc left outer join customercostspecification cc
           on  plpc.customercostspecification_id=cc.customercostspecification_id
           where plpc.customer_id=cc.customer_link_id
           and plpc.product_id=productid
           and plpc.sizedefinition_id=( select s.sizedefinition_id from sizedefinition s where s.code='*')
           and plpc.finishingmethod_id=finishingmethodid
           and plpc.customer_id=cust_id
           and plpc.dateactive<plpcdate
           and plpc.dateinactive>plpcdate;
               if val is  not null then
                    cccode:=val;
               end if;
               end if;
     end if;
     if val is null and invoicelinetypeid not in (1, 10, 22, 24) then
         begin
            select cc.code into cccode
              from customercostspecification cc
             where cc.customer_link_id = cust_id
               and cc.useasdefault = 'Y';
         end;
     end if;
     -- exception when no_data_found then return defval;
      return cccode;
     end;
 end if;

 return cccode;
end f_getcustcostspeccode;
/
create or replace function f_getcustcostspecdesc
  (productid             product.product_id%type,
   sizedefinitionid      sizedefinition.sizedefinition_id%type,
   finishingmethodid     finishingmethod.finishingmethod_id%type,
   plpcdate              productlistpercustomer.dateactive%type,
   weighingcategoryid    weighingcategory.weighingcategory_id%type,
   cust_id               customer_link.customer_link_id%type,
   invoicelinetypeid     invoicelinetype.invoicelinetype_id%type
   ) return varchar2  is
  cccdesc varchar2(40);
  val varchar2(40);
  cnt number;
  specialsize number;
begin
  cnt:=0;
  cccdesc:='**';-- not defined or not found
  val:='**';
  specialsize:=0;
select   count(cc.customercostspecification_id)into cnt
   from customercostspecification cc
 where cc.customer_link_id=cust_id;
if cnt=0
    then
      begin
        cccdesc:='**';
    return cccdesc;
    end;
end if;
if cnt>0 and invoicelinetypeid in (16, 18)
    then
      begin
       cccdesc:='**';
     return cccdesc;
    end;
end if;
if productid is null and weighingcategoryid is null
    then
      begin
        cccdesc:='**';
    return cccdesc;
    end;
end if;
if weighingcategoryid is not  null then
  begin
   select ccs.description into val
     from weighingcategory wg, weighingcategpercustomer wcc
     left outer join customercostspecification ccs
       on wcc.customercostspecification_id =
          ccs.customercostspecification_id
    where wcc.weighingcategory_id = wg.weighingcategory_id
      and wcc.customer_id = cust_id
      and wg.weighingcategory_id = weighingcategoryid
      and wcc.dateactive < plpcdate
      and wcc.dateinactive > plpcdate;
       if val is not null then cccdesc:=val;
       end if;
			 if val is null and invoicelinetypeid not in (3, 4) then
         begin
          select cc.description into cccdesc
            from customercostspecification cc
           where cc.customer_link_id = cust_id
             and cc.useasdefault = 'Y';
         end;
        end if;
       return cccdesc;
       exception when no_data_found then return '**';
  end;
end if;
if productid is not null then
   begin
  select count(plpc.productlistpercustomer_id) into cnt
         from productlistpercustomer plpc
         where  plpc.product_id=productid
         and plpc.sizedefinition_id=sizedefinitionid
         and plpc.finishingmethod_id=finishingmethodid
         and plpc.customer_id=cust_id
         and plpc.dateactive<plpcdate
         and plpc.dateinactive>plpcdate;
  if cnt=1 then
           select cc.description into val
           from productlistpercustomer plpc left outer join customercostspecification cc
           on  plpc.customercostspecification_id=cc.customercostspecification_id
           where plpc.product_id=productid
           and plpc.sizedefinition_id=sizedefinitionid
           and plpc.finishingmethod_id=finishingmethodid
           and plpc.customer_id=cust_id
           and plpc.dateactive<plpcdate
           and plpc.dateinactive>plpcdate;
               if val is null then cccdesc:='**';
                  else   cccdesc:=val;
               end if;
    else
        select count(s.sizedefinition_id) into specialsize from sizedefinition s where s.code='*';
        if specialsize > 0 then
            select cc.description into val
           from productlistpercustomer plpc left outer join customercostspecification cc
           on  plpc.customercostspecification_id=cc.customercostspecification_id
           where plpc.customer_id=cc.customer_link_id
           and plpc.product_id=productid
           and plpc.sizedefinition_id=( select s.sizedefinition_id from sizedefinition s where s.code='*')
           and plpc.finishingmethod_id=finishingmethodid
           and plpc.customer_id=cust_id
           and plpc.dateactive<plpcdate
           and plpc.dateinactive>plpcdate;
               if val is null then cccdesc:='**';
                  else   cccdesc:=val;
               end if;
           end if;
     end if;
		 if val is null and invoicelinetypeid not in (1, 10, 22, 24) then
         begin
            select cc.description into cccdesc
              from customercostspecification cc
             where cc.customer_link_id = cust_id
               and cc.useasdefault = 'Y';
         end;
     end if;
     return cccdesc;
     exception when no_data_found then return '**';
      end;
 end if;
 return cccdesc;
end f_getcustcostspecdesc;
/
create or replace function F_GetCustType_smg(invoiceheaderid in invoiceheader.invoiceheader_id %type)
  return VARCHAR2 is
  customertype       varchar2(4);
  sendinvoiceto      integer;
  customer           number;
  plantcountryid     number;
  countcustcoverpage number;
  cvpcountry         number;
Begin
  customertype := '';
  begin
  select c.sendinvoiceto
    into sendinvoiceto
    from invoiceheader ih, customer c
   where c.customer_id = ih.deltocustomer_link_id
     and ih.invoiceheader_id = invoiceheaderid;
  exception when no_data_found then return '';
  end;
    if (sendinvoiceto is not null) and  (sendinvoiceto >= 0) then
      Begin
        select p.country_id
          into plantcountryid
          from invoiceheader ih, businessunit bu, plant p
         where ih.invoicebusinessunit_id = bu.businessunit_id
           and bu.plant_id = p.plant_id
           and ih.invoiceheader_id = invoiceheaderid;
        if sendinvoiceto = 0 then
          select ih.deltocustomer_link_id
            into customer
            from invoiceheader ih
           where ih.invoiceheader_id = invoiceheaderid;
        else
          select ih.billtocustomer_link_id
            into customer
            from invoiceheader ih
           where ih.invoiceheader_id = invoiceheaderid;
        end if;
        select count(cvp.customer_id)
          into countcustcoverpage
          from customercoverpageinfo cvp
         where cvp.customer_id = customer;
        if countcustcoverpage > 0 then
          select coalesce(cvp.country_id, plantcountryid)
            into cvpcountry
            from customercoverpageinfo cvp
           where cvp.customer_id = customer;
        else
          select c.country_id
            into cvpcountry
            from  customer c
           where c.customer_id =customer ;
        end if;
        if cvpcountry = plantcountryid then
          customertype := 'inl';
        else
          customertype := 'ausl';
        end if;
      end;
    end if;
    if (sendinvoiceto is not null) and  (sendinvoiceto >= 0) then
       return customertype;
       else return '';
    end if;
end F_GetCustType_smg;
/
create or replace function F_GetDatesOfNoteNumbers_LLG(invoicelineid in invoiceline.invoiceline_id%type)
  return varchar2 is
  result varchar2(6000);
begin
  result := '1';
  for Vcsr in (select distinct to_char(pn.deliverydate, 'dd Mon yyyy') deliverydate
                 from packingnote        pn,
                      packingnoteline    pnl,
                      invoiceline        il,
                      invoicelineproduct ilp
                where pn.packingnote_id = pnl.packingnote_id
                  and pnl.invoiceheader_id = il.invoiceheader_id
                  and il.invoiceline_id = ilp.invoiceline_id
                  and pnl.product_id = ilp.product_link_id
                  and pnl.sizedefinition_id = ilp.sizedefinition_link_id
                  and pnl.finishingmethod_id = ilp.finishingmethod_id
                  and il.invoiceline_id = invoicelineid) loop
    if (result = '1') then
      result := Vcsr.Deliverydate;
    else
      if (length(result) < 5000) then
        result := concatenate3(result,
                               ', ',
                               Vcsr.Deliverydate);
      else
        result := result || '... ';
      end if;
    end if;
  end loop;
  if result = '1' then
    result := null;
  end if;
  return result;
end F_GetDatesOfNoteNumbers_LLG;
/
create or replace function f_GetDaysForLastMonthInvoices(
custID in invoiceheader.billtocustomer_link_id%type,
dayNR in day.daynumber%type
)
  return number is
  mindate DATE;
	maxdate DATE;
  Result number;
begin
  select min(ih.startdate) into mindate
  from invoiceheader ih, status st where ih.billtocustomer_link_id = custID
   and st.status_id = ih.status_id and st.code = '2' --Finalized
   and ih.invoicedate between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
   and not ih.startdate is null;
  select max(ih.enddate) into maxdate
  from invoiceheader ih, status st where ih.billtocustomer_link_id = custID
   and st.status_id = ih.status_id and st.code = '2' --Finalized
   and ih.invoicedate between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
   and not ih.enddate is null;
  SELECT COUNT(1) into Result FROM dual
  WHERE TO_CHAR(mindate + LEVEL - 1, 'D', 'nls_date_language = ENGLISH') IN TO_CHAR(dayNR)
  CONNECT BY TRUNC(mindate) + LEVEL - 1 <= TRUNC(maxdate);
  return Result;
end f_GetDaysForLastMonthInvoices;
/
create or replace function F_GetDeliveriesNo
 (wearerinventoryid in     wearerinventory.wearerinventory_id%type,
  businessunitid in        businessunit.businessunit_id%TYPE,
  routeid in               route.route_id%type,
  stopnr in                routestop.stopnumber%type,
  reportparamid in         reportparam.reportparam_id%type)
return number is
  Result                   number;
begin

--  return stopnr;

  Result:=0;
  select count(*)
  into Result
  from wearerinventory wi, weareremployment we, deliveryscan ds, packingnote pn, reportparam rp
  where wi.weareremployment_id = we.weareremployment_id
    and ds.weareremployment_link_id = we.weareremployment_id
    and ds.distributionpoint_link_id = we.distributionpoint_id
    and ds.product_link_id = wi.product_id
    and ds.sizedefinition_link_id = wi.sizedefinition_id
    and ds.finishingmethod_id = wi.finishingmethod_id
    and ds.packingnote_id = pn.packingnote_id
    and pn.deliverydate = rp.date_value1
    and wi.wearerinventory_id = wearerinventoryid
    and ds.businessunit_id = businessunitid
    and rp.reportparam_id = reportparamid
    and pn.route_id = routeid
    and pn.stopnumber = stopnr;

  return(Result);
end F_GetDeliveriesNo;
/
create or replace function F_GetDeliveryPointWO(workorderid workorder.workorder_id%type)
  return number is
  deliverypointid  number;
  deliverypointids number;
  deliverypointidw number;
  v_workorder_id   number;
  woorigin         number;
  wodistrib        number;
  wowempl          number;

begin
  v_workorder_id := workorderid;
  select wo.origin,
         wo.distributionpoint_link_id,
         wo.weareremployment_link_id
    into woorigin, wodistrib, wowempl
    from workorder wo
   where wo.workorder_id = v_workorder_id;

  if (woorigin in (2, 6, 7) and nvl(wodistrib,0)>0) then
    select dp.deliverypoint_id
      into deliverypointids
      from workorder wo, distributionpoint dp
     where wo.distributionpoint_link_id = dp.distributionpoint_id
           and wo.workorder_id = v_workorder_id;
  end if;
  if nvl(wowempl,0)  > 0 then
    select coalesce(we.deliverypoint_id,
                    gd.deliverypoint_id,
                    bl.deliverypoint_id)
      into deliverypointidw
      from workorder wo, weareremployment we
      left outer join garmentdispenser gd
        on we.garmentdispenser_id = gd.garmentdispenser_id
      left outer join locker bl
        on we.locker_id = bl.locker_id
     where wo.weareremployment_link_id = we.weareremployment_id
       and wo.workorder_id = v_workorder_id;
  end if;

  deliverypointid := coalesce(deliverypointids, deliverypointidw, -1);
  return deliverypointid;
end F_GetDeliveryPointWO;
/
create or replace function F_GETDELIVERYSCHEME(
  distributionpoint_id_ IN NUMBER,
  deliverydate_ IN DATE,
  product_id_ IN NUMBER,
  sizedefinition_id_ IN NUMBER,
  finishingmethod_id_ IN NUMBER )
RETURN VARCHAR2
AS

schemecode_ deliveryscheme.code%TYPE;

CURSOR g_productlist IS
   SELECT *
   FROM productlistperdistribpoint pl
   WHERE pl.distributionpoint_id = distributionpoint_id_
   AND pl.product_id = product_id_
   AND pl.sizedefinition_id = sizedefinition_id_
   AND pl.finishingmethod_id = finishingmethod_id_;

CURSOR g_cpl(productlistperdistribpoint_id_ NUMBER) IS
SELECT dl.*, ds.code
   FROM standarddeliveryline dl, deliveryscheme ds
   WHERE dl.productlistperdistribpoint_id = productlistperdistribpoint_id_
   AND dl.dateactive <= deliverydate_
   AND dl.dateinactive >= deliverydate_
   AND ds.deliveryscheme_id = dl.deliveryscheme_id
   AND ds.deliveryscheme_id =
     (SELECT dst.deliveryscheme_id
      FROM standarddeliveryline dlt, deliveryscheme dst
      WHERE dst.deliveryscheme_id = dlt.deliveryscheme_id
        AND dlt.productlistperdistribpoint_id = productlistperdistribpoint_id_
        AND dlt.standarddeliveryline_id = dl.standarddeliveryline_id
        AND ds.frequency = (SELECT min(frequency)
                            FROM standarddeliveryline dltt, deliveryscheme dstt
                            WHERE dstt.deliveryscheme_id = dltt.deliveryscheme_id
                              AND	dltt.productlistperdistribpoint_id = productlistperdistribpoint_id_ ));

BEGIN
   FOR prod_rec_ IN  g_productlist LOOP
      FOR cpl_rec_ IN g_cpl(prod_rec_.productlistperdistribpoint_id) LOOP
         schemecode_ := cpl_rec_.code;
      END LOOP;
   END LOOP;
   RETURN schemecode_;
END F_GETDELIVERYSCHEME;
/
create or replace function F_GetDelProdPrice
(showprice            number,
 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,
 merchandise in       product.typeofmerchandise%type)
return number is
 begin

 if showprice = 0 then return 0; end if;
 if merchandise is null then return 0; end if;
 if sizedefinitionid is null then return 0; end if;
 if productid is null then return 0; end if;
 if merchandise is null then return 0; end if;
 if merchandise <> 3 then
   if finishingmethodid is null then return 0; end if;
   return pack_price.Wash_Price(customerid, productid, sizedefinitionid, finishingmethodid, pricedate);
 else
   return pack_price.Sales_Price(customerid, productid, sizedefinitionid, pricedate);
 end if;

end F_GetDelProdPrice ;
/
create or replace function F_GetDelProdPriceWithDisc
(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,
 merchandise in       product.typeofmerchandise%type)
return number is
 begin

 if merchandise is null then return 0; end if;
 if sizedefinitionid is null then return 0; end if;
 if productid is null then return 0; end if;
 if merchandise is null then return 0; end if;
 if merchandise <> 3 then
   if finishingmethodid is null then return 0; end if;
   return pack_price.Wash_Price(customerid, productid, sizedefinitionid, finishingmethodid, pricedate)*
   ((100-pack_price.Wash_Discount(customerid, productid, sizedefinitionid, finishingmethodid, pricedate))/100);
 else
   return pack_price.Sales_Price(customerid, productid, sizedefinitionid, pricedate);
 end if;
end F_GetDelProdPriceWithDisc;
/
create or replace function F_GetDepot(
  nCustomerId in    customer.customer_id%type,
  nBuId in          businessunit.businessunit_id%type)
return VARCHAR2 is
  sCode  depot.code%type;
  sDesc  depot.description%type;
  type Tcsr is ref cursor;
  Vcsr Tcsr;
begin

  begin
    open Vcsr for
      SELECT d.code, d.description
      from routestop rs, route r, depot d, businessunit bu
      where rs.customer_id = nCustomerId
        and rs.route_id = r.route_id
        and r.depot_id = d.depot_id
        and d.plant_id = bu.plant_id
        and bu.businessunit_id = nBuId
      order by r.routenumber;
    fetch Vcsr into sCode, sDesc;
    exception when no_data_found then return null;
  end;
  close Vcsr;

  return concatenate(leftpad(sCode, 12, ' '), leftpad(sDesc, 30, ' '));

end F_GetDepot ;
/
create or replace function F_GetEmployeeNameFromBundle(
      uniquebundleid in        uniquebundle.uniquebundle_id%type
) return VARCHAR2 is
  employee_name VARCHAR2(40);
begin
  select su.fullname
    into employee_name
             from systemuser su, (select ubil.systemuser_id from uniquebundleitemlink ubil
             where ubil.uniquebundle_id = uniquebundleid order by ubil.timestamp desc) z
         where rownum = 1 and z.systemuser_id = su.systemuser_id;
  return employee_name;
end;
/
create or replace function f_getfirstrowlocationid_naf
(productlinkid product_link.product_link_id%type,
 sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
 requestedgradeid qualitygrade.qualitygrade_id%type,
 codeunique workorderline.codeuniquely%type,
 stockroomid stockroom.stockroom_id%type)
 return number is
        locationid stockroomlocation.stockroomlocation_id%type:=-1;
begin
  locationid := -1;
  if stockroomid is null then return -1;
    else
  begin
    select stockroomlocation_id
      into locationid
      from (select sl.stockroomlocation_id, rownum r
              from stockroomlocation          sl,
                   stockdefinitionperitem     sdi,
                   stockreservationpergrade   srg,
                   locationtype lt
             where sl.stockroom_id = sdi.stockroom_id
               and srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
               and sl.locationtype_id=lt.locationtype_id
               and lt.pickinglocation= 'Y'
               and sl.stockroom_id = stockroomid
               and sdi.product_id = productlinkid
               and sdi.sizedefinition_id = sizedefinitionlinkid
               and coalesce((select resq.priority from qualitygrade resq where srg.qualitygrade_id=resq.qualitygrade_id),0)<=
                 coalesce((select qq.priority from qualitygrade qq where qq.qualitygrade_id=requestedgradeid),0)
               and (case when codeunique='Y' then ( select sq.qtyunique + sq.qtynonunique from stockquantity sq
                                                  where sq.stockroomlocation_id=sl.stockroomlocation_id
                                                  and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id)
                                 else ( select sq.qtynonunique from stockquantity sq
                                    where sq.stockroomlocation_id=sl.stockroomlocation_id
                                    and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id) end)>0
               order by (case when codeunique='Y' then ( select sq.qtyunique + sq.qtynonunique from stockquantity sq
                              where sq.stockroomlocation_id=sl.stockroomlocation_id
                                 and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id)
                                 else ( select sq.qtynonunique from stockquantity sq
                                      where sq.stockroomlocation_id=sl.stockroomlocation_id
                                 and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id) end),
                            nvl (sl.rowcode,''),sl.locationcode)
     where r < 2;
    exception when no_data_found then null;
 end;
 end if;
return locationid;
end f_getfirstrowlocationid_naf;
/
create or replace function f_getfirstrowlocationid_ven
(productlinkid product_link.product_link_id%type,
 sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
 requestedgradeid qualitygrade.qualitygrade_id%type,
 codeunique workorderline.codeuniquely%type,
 stockroomid stockroom.stockroom_id%type)
 return number is
        locationid stockroomlocation.stockroomlocation_id%type:=-1;
begin
  locationid := -1;
  if stockroomid is null then return -1;
    else
  begin
    select stockroomlocation_id
      into locationid
      from (select sl.stockroomlocation_id, rownum r
              from stockroomlocation          sl,
                   stockdefinitionperitem     sdi,
                   stockreservationpergrade   srg,
                   locationtype lt
             where sl.stockroom_id = sdi.stockroom_id
               and srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
               and sl.locationtype_id=lt.locationtype_id
               and lt.pickinglocation= 'Y'
               and sl.stockroom_id = stockroomid
               and sdi.product_id = productlinkid
               and sdi.sizedefinition_id = sizedefinitionlinkid
               and coalesce((select resq.priority from qualitygrade resq where srg.qualitygrade_id=resq.qualitygrade_id),0)<=
                 coalesce((select qq.priority from qualitygrade qq where qq.qualitygrade_id=requestedgradeid),0)
               and (case when codeunique='Y' then ( select sq.qtyunique + sq.qtynonunique from stockquantity sq
                                                  where sq.stockroomlocation_id=sl.stockroomlocation_id
                                                  and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id)
                                 else ( select sq.qtynonunique from stockquantity sq
                                    where sq.stockroomlocation_id=sl.stockroomlocation_id
                                    and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id) end)>0
               order by (case when codeunique='Y' then ( select sq.qtyunique + sq.qtynonunique from stockquantity sq
                              where sq.stockroomlocation_id=sl.stockroomlocation_id
                                 and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id)
                                 else ( select sq.qtynonunique from stockquantity sq
                                      where sq.stockroomlocation_id=sl.stockroomlocation_id
                                 and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id) end),
                            nvl (sl.rowcode,''),sl.locationcode)
     where r < 2;
    exception when no_data_found then null;
 end;
 end if;
return locationid;
end f_getfirstrowlocationid_ven;
/
create or replace function f_getfirstrowlocation_embl_naf
(productlinkid product_link.product_link_id%type,
 sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
 stockroomid stockroom.stockroom_id%type)
 return number is
        locationid stockroomlocation.stockroomlocation_id%type:=-1;
begin
  locationid := -1;
  if stockroomid is null then return -1;
    else
  begin
    select stockroomlocation_id
      into locationid
      from (select sl.stockroomlocation_id
              from stockroomlocation          sl,
                   stockdefinitionperitem     sdi,
                   stockreservationpergrade   srg,
                   locationtype lt
             where sl.stockroom_id = sdi.stockroom_id
               and srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
               and sl.locationtype_id=lt.locationtype_id
               and lt.pickinglocation= 'Y'
               and sl.stockroom_id = stockroomid
               and sdi.product_id = productlinkid
               and sdi.sizedefinition_id = sizedefinitionlinkid
                  and ( select sq.qtynonunique from stockquantity sq
                                    where sq.stockroomlocation_id=sl.stockroomlocation_id
                                    and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id)is not null
               order by ( select sq.qtynonunique from stockquantity sq
                                      where sq.stockroomlocation_id=sl.stockroomlocation_id
                                 and sq.stockreservationpergrade_id=srg.stockreservationpergrade_id) DESC,
                            nvl (sl.rowcode,''),sl.locationcode)
     where rownum < 2;
    exception when no_data_found then null;
 end;
 end if;
return locationid;
end f_getfirstrowlocation_embl_naf;
/
create or replace function F_GetFixedSettlePrice
( P_StockReservationPerGrade_ID in  StockReservationPerGrade.StockReservationPerGrade_ID%type)
return number is
begin

return  0;

end F_GetFixedSettlePrice ;
/
create or replace function F_GetFixedSettlePriceAtDate
( P_StockReservationPerGrade_ID in  StockReservationPerGrade.StockReservationPerGrade_ID%type,
 P_RequestedDate                in  Stocktransaction.Transactiondate%type )
return number is
begin

return  0;

end F_GetFixedSettlePriceAtDate;
/
create or replace function F_GetIDColumnFromActivePLPC(
					FPnCUSTOMER_ID        in PRODUCTLISTPERCUSTOMER.CUSTOMER_ID%type,
          FPnPRODUCT_ID         in PRODUCTLISTPERCUSTOMER.PRODUCT_ID%type,
          FPnSIZEDEFINITION_ID  in PRODUCTLISTPERCUSTOMER.SIZEDEFINITION_ID%type,
          FPnFINISHINGMETHOD_ID in PRODUCTLISTPERCUSTOMER.FINISHINGMETHOD_ID%type,
          FPnSPECIALSIZE_ID     in PRODUCTLISTPERCUSTOMER.SIZEDEFINITION_ID%type,
          FPnDate               in PRODUCTLISTPERCUSTOMER.DATEACTIVE%type,
					FPnColumn							in number -- 0 = id, 1 = emblemtemplete_id
) return number is
    LVnNumber number;
begin
  begin
		if (FPnColumn = 0) then
      select PRODUCTLISTPERCUSTOMER_ID
        into LVnNumber
        from PRODUCTLISTPERCUSTOMER
       where CUSTOMER_ID = FPnCUSTOMER_ID and
             PRODUCT_ID = FPnPRODUCT_ID and
             SIZEDEFINITION_ID = FPnSIZEDEFINITION_ID and
             FINISHINGMETHOD_ID = FPnFINISHINGMETHOD_ID and
             PRODUCTLISTPERCUSTOMER.DATEACTIVE <= FPnDate and
             PRODUCTLISTPERCUSTOMER.DATEINACTIVE >= FPnDate;
      return LVnNumber;
		end if;
		if (FPnColumn = 1) then
      select EMBLEMTEMPLATE_ID
        into LVnNumber
        from PRODUCTLISTPERCUSTOMER
       where CUSTOMER_ID = FPnCUSTOMER_ID and
             PRODUCT_ID = FPnPRODUCT_ID and
             SIZEDEFINITION_ID = FPnSIZEDEFINITION_ID and
             FINISHINGMETHOD_ID = FPnFINISHINGMETHOD_ID and
             PRODUCTLISTPERCUSTOMER.DATEACTIVE <= FPnDate and
             PRODUCTLISTPERCUSTOMER.DATEINACTIVE >= FPnDate;
      return LVnNumber;
		end if;
  exception
      when NO_DATA_FOUND then
        if (FPnSIZEDEFINITION_ID != FPnSPECIALSIZE_ID)
        then
          return F_GetIDColumnFromActivePLPC(FPnCUSTOMER_ID,
                                  FPnPRODUCT_ID,
                                  FPnSPECIALSIZE_ID,
                                  FPnFINISHINGMETHOD_ID,
                                  FPnSPECIALSIZE_ID,
                                  FPnDate,
																	FPnColumn);
        else
          return null;
        end if;

  end;
  end;
/
create or replace function f_getidforsterilizationrun(sterilizationrunid in uniqueorpacksterile.sterilizationrun_id%type,
                                                      cartid             in cart.cart_id%type,
                                                      productid          in product.product_id%type) return clob is
  result clob;
begin
  result := '1';
  for vcsr in (select ui.primaryid
                 from uniqueitem ui
                      join uniqueorpacksterile ups on ui.uniqueitem_id = ups.uniqueitem_id
                where ups.cart_id = cartid
                  and ups.sterilizationrun_id = sterilizationrunid
                  and ui.product_id = productid
                order by ui.primaryid asc)
  loop
    if (result = '1')
    then
      result := castnumberasvarchar(vcsr.primaryid);
    else
      if (length(result) < 6000)
      then
        result := concatenate3(result, ', ', castnumberasvarchar(vcsr.primaryid));
      else
        result := result || '... ';
      end if;
    end if;
  end loop;
  if result = '1'
  then
    result := null;
  end if;
  return result;
end f_getidforsterilizationrun;
/
create or replace function F_GetIntProcBUID(workorderid workorder.workorder_id%type)
  return number is
  result number;
  customerid number;
  minwolid number;
  wobuid number;
  wolintprocbuid number;
  wointprocbuid number;
 begin
  customerid:=-1;
  minwolid:=-1;
  result:=-1;
  select wo.internalprocessingbu_id into wointprocbuid from workorder wo where wo.workorder_id=workorderid;
  select wo.customer_link_id into customerid from workorder wo where wo.workorder_id=workorderid;
  select min(wol.workorderline_id) into minwolid from workorder wok, workorderline wol
    where wok.workorder_id=wol.workorder_id and wok.workorder_id=workorderid;
  select wo.businessunit_id into wobuid from workorder wo where wo.workorder_id=workorderid;
  select min(ca.internalprocessingbu_id) into  wolintprocbuid from workorder wk, workorderline wol, product p, productgroup pg, activity a, customeractivities ca
       where wk.workorder_id=wol.workorder_id and wol.product_link_id=p.product_id and p.productgroup_id=pg.productgroup_id
       and pg.activity_id=ca.activity_id and ca.customer_id=wk.customer_link_id
       and wk.workorder_id=workorderid and wol.workorderline_id=minwolid ;
 if (customerid is null or minwolid is null) then
  result:=wobuid;
 else
   result:=coalesce(wointprocbuid,wolintprocbuid,wobuid);
 end if;
 return result;
end  F_GetIntProcBUID;
/
create or replace function F_GETINVENTORYQTY
  (fpnCustomerID                customer.customer_id%type,
   fpnProductID                 product.product_id%type,
   fpnSizeId                    sizedefinition.sizedefinition_id%type,
   fpnFinMethID                 finishingmethod.finishingmethod_id%type,
   fpdReportParamID             reportparam.reportparam_id%type
  ) return  number is
  LVnAmount number;
  LVnCnt    number;
begin

  select sum(ss.averageinventoryqty), count(ss.averageinventoryqty)
  into LVnAmount, LVnCnt
  from statusquoheader sh, sqonsiteinventory ss, reportparam rp
  where sh.statusquoheader_id = ss.statusquoheader_id
    and ss.customer_link_id = fpnCustomerID
    and ss.product_link_id = fpnProductID
    and ss.finishingmethod_id = fpnFinMethID
    and ss.sizedefinition_link_id = fpnSizeId
    and rp.reportparam_id = fpdReportParamID
    and sh.statusquodate >= rp.date_value1
    and sh.statusquodate <= rp.date_value2;
  if LVnCnt = 0 then
    LVnAmount:=0;
  else
    LVnAmount:=LVnAmount/LVnCnt;
  end if;

  return LVnAmount;

end F_GETINVENTORYQTY;
/
create or replace function F_GetInvoiceAmount
  (fpnCustomerID                customer.customer_id%type,
   fpbLast number --1 = last amount , 0-average amount
  ) return  number is
  LVnAmount number;
  LVnNo number;
  type Tcsr is ref cursor;
  Vcsr Tcsr;
  LVdMinDate invoiceheader.invoicedate%type;
  LVdMaxDate invoiceheader.invoicedate%type;
begin
  LVnAmount:=0;
  if fpbLast = 1 then
    begin
      open Vcsr for
      select max(ih.invoicenumber) , ih.totalamountexclvat
      from invoiceheader ih, status st
      where ih.deltocustomer_link_id = fpnCustomerID
        and ih.documenttype = 1
        and ih.invoicetype = 1
        and ih.status_id = st.status_id
        and st.code = '2'
      group by ih.totalamountexclvat
      order by max(ih.invoicenumber) desc, ih.totalamountexclvat;
      fetch Vcsr into LVnNo, LVnAmount;
      exception when no_data_found then return 0;
      close Vcsr;
    end;
  else
    begin
      select min(ih.invoicedate), max(ih.invoicedate), sum(ih.totalamountexclvat)
      into LVdMinDate, LVdMaxDate, LVnAmount
      from invoiceheader ih, status st
      where ih.deltocustomer_link_id = fpnCustomerID
        and ih.documenttype = 1 and ih.invoicetype = 1
        and ih.status_id = st.status_id
        and st.code = '2'
        and ih.invoicedate >= trunc(sysdate) - 365;
      if LVdMinDate is not null then
        LVnNo:=trunc((LVdMaxDate-LVdMinDate)/7);
        if LVnNo = 0 then LVnNo := 1; end if;
        LVnAmount:=LVnAmount/LVnNo;
      else
        LVnAmount:=0;
      end if;
    end;
  end if;
  return LVnAmount;
end F_GetInvoiceAmount;
/
create or replace FUNCTION F_GETITEMACTIVITY_DELIVERIES (
                  reportdate       IN date,
                  CUSTOMERID          IN CUSTOMER.Customer_Id%TYPE,
                  PRODUCTID           IN PRODUCT.Product_Id%TYPE,
                  SIZEDEFINITIONID    IN Sizedefinition.Sizedefinition_Id%TYPE,
                  FINISHINGMETHODID   IN finishingmethod.finishingmethod_id%TYPE
                  ) return varchar2 is
  sir    varchar2(1000);
  amount          FLOAT;
  i               INTEGER;
BEGIN
  sir := '';
  amount:=0;
  i:=0;
for vCursor in ( select * from
                       (SELECT SUM(d.amountdelivered) deliveredamount, d.deliverydate
                        FROM deliveryhistory d
                        WHERE d.deliverydate <= reportdate
                        AND d.customer_link_id = CUSTOMERID
                        AND d.product_link_id = PRODUCTID AND d.sizedefinition_link_id = SIZEDEFINITIONID
                        AND d.finishingmethod_id = FINISHINGMETHODID
                        AND d.amountdelivered > 0
                        GROUP BY d.deliverydate
                        ORDER BY d.deliverydate DESC
                ) where rownum <= 8)
LOOP
     if  ltrim(rtrim(Vcursor.deliveredamount)) is not null then
       begin
         i := i + 1;
         amount := amount + Vcursor.deliveredamount;
         sir := concat(sir, rpad(ltrim(rtrim(castNumberAsVarchar(Vcursor.deliveredamount))), 7));
       end;
     else
         sir := concat(sir, '');
     end if;
end LOOP;
     if  i <> 0 then
       begin
         sir := concatenate3('A:', rpad(castNumberAsVarchar(amount), 8), sir);--A is total Amount delivered
         sir := concatenate3('C:', castNumberAsVarchar(i), sir);--C is Count of Deliveries
       end;--sir format is "C:XA:XXXXXXXXYY ZZ WW ...."
     end if;
return(sir);
exception
when no_data_found then return null ;
when others then return null;
END F_GetITEMACTIVITY_DELIVERIES;
/
create or replace FUNCTION F_GETKIDFROM2Z
(
  NO1 IN NUMBER,
  NO2 in number
) RETURN NUMBER
is
 ac number;
 len number;
 res number;

BEGIN  --  test ; NO1 := 12345678;  mod10 = 2;
  len := length(no2);
  ac    := NO1*power(10,len) + no2;
  len    := f_Mod10dim(ac, length(ac)) ;
  res := ac * 10 + len;

 RETURN res;

END  F_GetKIDFrom2Z;
/
create or replace function F_GETLOCATIONCODE
  (stockreservationpergradeid in stockreservationpergrade.stockreservationpergrade_id%type,
   uniquely in workorderline.codeuniquely%type default 'Y'
  ) return  varchar2 is
   rowlocation varchar2(25);
begin

  rowlocation := null;

  begin
    case when uniquely = 'n' then
        select locationcode
        into rowlocation
            from (select rownum r, x.locationcode
                 from (select srl.locationcode
                      from stockroomlocation srl, locationtype lt, stockquantity sq
                      where sq.stockreservationpergrade_id = stockreservationpergradeid
                       and srl.stockroomlocation_id = sq.stockroomlocation_id
                       and srl.locationtype_id=lt.locationtype_id
                       and lt.pickinglocation='Y'
                       order by srl.pickingsequence, sq.qtynonunique desc) x)
           where r < 2;
    else
        select locationcode
        into rowlocation
            from (select rownum r, x.locationcode
                 from (select srl.locationcode
                      from stockroomlocation srl, locationtype lt, stockquantity sq
                      where sq.stockreservationpergrade_id = stockreservationpergradeid
                       and srl.stockroomlocation_id = sq.stockroomlocation_id
                       and srl.locationtype_id=lt.locationtype_id
                       and lt.pickinglocation='Y'
                       order by srl.pickingsequence, (sq.qtyunique + sq.qtynonunique) desc) x)
            where r < 2;
    end case;
    exception when no_data_found then null;
  end;

  return rowlocation;

end F_GETLOCATIONCODE;
/
create or replace function F_GetMainUniqueResidentialFlag(fp_uniqueresidentialitem_id in number)
return number is
lv_flag_id number;
begin
-- this function returns the flag_id with the highest priority that is currently active
-- for the uniqueresidential item that is passed as parameter
begin
select x.flag_id
into lv_flag_id
from (select uf.flag_id
from uniqueresidentialitemflag uf
join flag f
on f.flag_id = uf.flag_id
where uf.uniqueresidentialitem_id = fp_uniqueresidentialitem_id
and uf.startdate <= trunc(SYSDATE)
order by f.priority asc, uf.startdate desc) x
where rownum = 1;
exception
when no_data_found then
lv_flag_id := null;
end;
return lv_flag_id;
end F_GetMainUniqueResidentialFlag;
/
create or replace function f_getmaxorderqty(fp_plpd_id    productlistperdistribpoint.productlistperdistribpoint_id%type,
                                            fp_order_date in date)
  return number is

  gv_systemuserid systemuser.systemuser_id%type := null;
  gv_plantid      plant.plant_id%type := null;
  gv_message      abslog.message%type;

  gv_orderingmethod     productlistperdistribpoint.orderingmethod%type;
  gv_maxorderqtywebpda  number;
  gv_customer_id        customer.customer_id%type;
  gv_maxorderqtyweb     customerinternetoptions.maxorderqtyweb%type;
  gv_standardpackamount department.standardpackamount%type;
  gv_bundlesize         number;

  rv_maxorderqty number;

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

begin
  select plpd.orderingmethod, plpd.maxsstockqty
    into gv_orderingmethod, rv_maxorderqty
    from productlistperdistribpoint plpd
   where plpd.productlistperdistribpoint_id = fp_plpd_id;

  if gv_orderingmethod = 1 then
    return - 1;
  end if;

  if gv_orderingmethod = 2 then
    begin
      select d.customer_id
        into gv_customer_id
        from department                 d,
             distributionpoint          dp,
             productlistperdistribpoint plpd
       where plpd.productlistperdistribpoint_id = fp_plpd_id
         and dp.distributionpoint_id = plpd.distributionpoint_id
         and d.department_id = dp.department_id;

      select to_number(s.value), b.plant_id
        into gv_maxorderqtywebpda, gv_plantid
        from systemsetting s, customer c, businessunit b
       where c.customer_id = gv_customer_id
         and b.businessunit_id = c.defaultbusinessunit_id
         and s.plant_id = b.plant_id
         and s.name = 'MAXORDERQTYWEBPDA';

      select cio.maxorderqtyweb
        into gv_maxorderqtyweb
        from customerinternetoptions cio
       where cio.customer_id = gv_customer_id;

    exception
      when no_data_found then
        begin
          return - 1;
        end;
    end;

    if gv_maxorderqtywebpda = 0 or (gv_maxorderqtywebpda = 2 and gv_maxorderqtyweb = 0) then
      return - 1;
    end if;

    if gv_maxorderqtywebpda = 1 or
       gv_maxorderqtywebpda = 2 and gv_maxorderqtyweb = 1 then
      begin
        select moq.quantity
          into rv_maxorderqty
          from maxorderquantity moq
         where moq.productlistperdistribpoint_id = fp_plpd_id
           and moq.day_id = getdaynumber(fp_order_date);
      exception
        when no_data_found then
          begin
            rv_maxorderqty := 0;
          end;
      end;
    end if;

    if rv_maxorderqty <= 0 then
      begin
        select plpc.maxqtytodeliver, plpc.custombundlesize
          into rv_maxorderqty, gv_bundlesize
          from productlistpercustomer plpc, productlistperdistribpoint plpd
         where plpd.productlistperdistribpoint_id = fp_plpd_id
           and plpc.customer_id = gv_customer_id
           and plpc.product_id = plpd.product_id
           and plpc.sizedefinition_id = plpd.sizedefinition_id
           and plpc.finishingmethod_id = plpd.finishingmethod_id
           and plpc.dateactive <= fp_order_date
           and plpc.dateinactive >= fp_order_date
           and not exists
         (select 1
                  from productlistpercustomer plpc2
                 where plpc.productlistpercustomer_id !=
                       plpc2.productlistpercustomer_id
                   and plpc2.customer_id = plpc.customer_id
                   and plpc2.product_id = plpc.product_id
                   and plpc2.sizedefinition_id = plpc.sizedefinition_id
                   and plpc2.finishingmethod_id = plpc.finishingmethod_id
                   and plpc2.dateactive > plpc.dateactive);
      exception
        when no_data_found then
          begin
            rv_maxorderqty := 0;
          end;
      end;
    end if;

    if rv_maxorderqty <= 0 then
      begin
        select p.maxqtytodeliver
          into rv_maxorderqty
          from product p, productlistperdistribpoint plpd
         where plpd.productlistperdistribpoint_id = fp_plpd_id
           and p.product_id = plpd.product_id;
      exception
        when no_data_found then
          begin
            rv_maxorderqty := 0;
          end;
      end;
    end if;

    if rv_maxorderqty > 0 then
      begin
        select d.standardpackamount
          into gv_standardpackamount
          from department                 d,
               distributionpoint          dp,
               productlistperdistribpoint plpd
         where plpd.productlistperdistribpoint_id = fp_plpd_id
           and dp.distributionpoint_id = plpd.distributionpoint_id
           and d.department_id = dp.department_id;

        if gv_standardpackamount = 'Y' then
          begin
            if gv_bundlesize is null or gv_bundlesize <= 0 then
              select pss.packingamount
                into gv_bundlesize
                from plantproductsizesettings   pss,
                     productlistperdistribpoint plpd
               where plpd.productlistperdistribpoint_id = fp_plpd_id
                 and pss.plant_id = gv_plantid
                 and pss.product_id = plpd.product_id
                 and pss.sizedefinition_id = plpd.sizedefinition_id;
            end if;

            if gv_bundlesize is null or gv_bundlesize <= 0 then
              select ps.packingamount
                into gv_bundlesize
                from productsize ps, productlistperdistribpoint plpd
               where plpd.productlistperdistribpoint_id = fp_plpd_id
                 and ps.product_id = plpd.product_id
                 and ps.sizedefinition_id = plpd.sizedefinition_id;
            end if;

            if gv_bundlesize is null or gv_bundlesize <= 0 then
              select p.packingamount
                into gv_bundlesize
                from product p, productlistperdistribpoint plpd
               where plpd.productlistperdistribpoint_id = fp_plpd_id
                 and p.product_id = plpd.product_id;
            end if;

            if gv_bundlesize > 0 and
               (rv_maxorderqty / gv_bundlesize - trunc(rv_maxorderqty / gv_bundlesize)) > 0 then
              rv_maxorderqty := (trunc(rv_maxorderqty / gv_bundlesize) + 1) *
                                gv_bundlesize;
            end if;
          end;
        end if;

      exception
        when no_data_found then
          begin
            gv_bundlesize := 0;
          end;
      end;

    end if;

    return rv_maxorderqty;
  end if;

  return - 2;
end f_getmaxorderqty;
/
create or replace function F_GetModifications(
  purchaseorderlineid in    purchaseorderline.purchaseorderline_id%type,
  workorderid in            workorder.workorder_id%type,
  languageid in             languages.language_id%type)
return VARCHAR2 is
  result   varchar2(255);
  cnt      int;
begin

  result := '';
  cnt := 0;
  for vCursor in(
    select distinct m.code mod_code,
     (select md.description from modification_desc md
      where md.modification_id = m.modification_id
        and md.language_id = languageid) mod_desc
    from workorderline wl, workorderlinemodification wm, modification m
    where wl.workorderline_id = wm.workorderline_id
      and wm.modification_id = m.modification_id
      and wl.purchaseorderline_id = purchaseorderlineid
      and wl.workorder_id = workorderid
    order by m.code) loop

    cnt := cnt + 1;
    if cnt = 1 then
      result:= '(' || Vcursor.mod_code || ' ' || Vcursor.mod_desc || ')';
    else
      result:= result || ' (' || Vcursor.mod_code || ' ' || Vcursor.mod_desc || ')';
    end if;
  end loop;
  if result is null then result:='-'; end if;
  return result;

end F_GetModifications ;
/
create or replace function F_GetMostRecentFreeOfChargeAdj
 (crtDate date,
  plpd_id in PRODUCTLISTPERDISTRIBPOINT.Productlistperdistribpoint_Id%type)
  return date is
  Result date;
begin
  select max(FOCA.Adjustmentdate)
  into Result
  from FreeOfChargeAdjustment FOCA
  where FOCA.ProductListPerDistribPoint_ID = plpd_id and
        FOCA.AdjustmentDate <= crtDate and FOCA.AdjustmentType in (1, 4);
  return coalesce(Result, to_date('01-01-'||to_char(year(crtDate)), 'DD-MM-YYYY'));
end  F_GetMostRecentFreeOfChargeAdj;
/
create or replace function F_getnextdeliverydate
(currentdate in date,
customerid  in customer.customer_id%type,
typeofmerch in product.typeofmerchandise%type,
deliveryschemeid in deliveryscheme.deliveryscheme_id%type)
return date is
    type visitdates is table of number index by varchar2(8);
    result    date;
    visitdate date;
    dates     visitdates;
    i         integer;
begin
    i := 1;
    for vcursor in (select c.day_id, d.deliveryscheme_id, d.frequency, ds.routestop_id
                    from   customerdeliveryday c
                    join customerdeliveryscheme cd
                    on c.customer_id = cd.customer_id and c.day_id = cd.day_id
                    join deliveryscheme d
                    on d.deliveryscheme_id = cd.deliveryscheme_id
                    left  outer join deliveryschemesperstop ds
                    on c.customer_id = ds.customer_id and c.day_id = ds.day_id and d.deliveryscheme_id = ds.deliveryscheme_id
                    left outer join routestop rs
                    on ds.routestop_id = rs.routestop_id
                    where  c.customer_id = customerid
                    and    c.typeofmerchadise = typeofmerch
                    and    c.deliverytype in ('B', 'D')
                    and    (d.deliveryscheme_id = deliveryschemeid or deliveryschemeid is null)
                    and    (rs.routestop_id is null or currentdate between rs.dateactive and rs.dateinactive)) loop
      begin
        visitdate := pack_sort.getvisitdate(vcursor.deliveryscheme_id, vcursor.day_id, currentdate);
        if visitdate is not null then
          begin
            dates(to_char(visitdate, 'YYYYMMDD')) := i;
            i := i + 1;
          end;
        end if;
      end;
    end loop;
    result := to_date(dates.first, 'YYYYMMDD');
    return(result);
  end;
/
create or replace function F_GetNoDaysOverlap(FPdtStartDate1  date, --startDate1
                                              FPdtEndDate1 date, --EndDate1
                                              FPdtStartDate2 date, --StartDate2
                                              FPdtEndDate2 date --EndDate2
                                              ) RETURN integer is
-- Determine number of days when the date ranges FPdtStartDate1, FPdtEndDate1 and FPdtStartDate2, FPdtEndDate2 overlap.
-- It is the number of days between the min(FPdtStartDate1, FPdtStartDate2) and max(FPdtEndDate1, FPdtEndDate2)
-- It is assumed that the date ranges are valid (Startdate<endDate)
  LVdtMaxFromStartDates   date;
  LVdtMinFromEndDates   date;
  Result number;
begin
  Result := 0;
  if (FPdtStartDate1 > FPdtEndDate1) then return(Result);
  end if; --invalid date range
  if (FPdtStartDate2 > FPdtEndDate2) then return(Result);
  end if; --invalid date range

  LVdtMaxFromStartDates := FPdtStartDate1;
  if (FPdtStartDate1 < FPdtStartDate2) then
    LVdtMaxFromStartDates :=  FPdtStartDate2;
  end if;
  LVdtMinFromEndDates := FPdtEndDate1;
  if (FPdtEndDate1 > FPdtEndDate2) then
    LVdtMinFromEndDates := FPdtEndDate2;
  end if;
  Result := 1 + (LVdtMinFromEndDates - LVdtMaxFromStartDates);
  if (Result <= 0) then
    return(0);
  end if; --- date ranges do not overlap
  return(Result);
end;
/
create or replace function F_GetNoOfPackingNoteLines
 (uniquebundleid in        uniquebundle.uniquebundle_id%type,
  businessunitid in        businessunit.businessunit_id%TYPE,
  plantdepartmentid in     plantdepartment.plantdepartment_id%type,
  reportparamid in         reportparam.reportparam_id%type)
return number is
  Result                   number;
  MinRoute                 number;
  MaxRoute                 number;
  MinDelDate               packingnote.deliverydate%type;
  MaxDelDate               packingnote.deliverydate%type;
  MinDepot                 depot.code%type;
  MaxDepot                 depot.code%type;
  MinPlDep                 plantdepartment.code%type;
  MaxPlDep                 plantdepartment.code%type;

  LVsSqlStatement                 varchar2(32767);
  LVsSqlWhere                     varchar2(32767);
begin

  Result:=0;

  select rp.date_value1, rp.date_value2,
    rp.number_value1, rp.number_value2,
    rp.string_value1, rp.string_value2,
    rp.string_value3, rp.string_value4
  into MinDelDate, MaxDelDate,
    MinRoute, MaxRoute,
    MinDepot, MaxDepot, MinPlDep, MaxPlDep
  from reportparam rp
  where rp.reportparam_id = reportparamid;


  if MinDepot <> ' ' and MaxDepot <> 'ZZZZZZZZZZZZ' then -- selection depot
    select count(pnl.packingnoteline_id)
    into Result
    from packingnote pn, route ru, depot de,
      packingnoteline pnl, uniquebundle ub, plantdepartment pd,
      status st, businessunit bu, status stb
    where pn.packingnote_id = pnl.packingnote_id
      and pnl.finishingmethod_id = ub.finishingmethod_id
      and pnl.sizedefinition_id = ub.sizedefinition_link_id
      and pnl.product_id = ub.product_link_id
      and ub.deliverynotenumber = 0
      and pn.plantdepartment_id = pd.plantdepartment_id
      and pn.status_id = st.status_id
      and st.code in ('10', '20')
      and ub.status_id = stb.status_id
      and stb.code = '10'
      and ub.businessunit_id = bu.businessunit_id
      and bu.plant_id = pd.plant_id
      and pn.processbusinessunit_id = bu.businessunit_id
      and ru.depot_id = de.depot_id
      and pn.route_id = ru.route_id and ru.active = 'Y'
      and ub.uniquebundle_id = uniquebundleid
      and bu.businessunit_id = businessunitid
      and pn.deliverydate >= MinDelDate and pn.deliverydate <= MaxDelDate
      and de.code >= MinDepot and de.code <= MaxDepot
      and pd.code >= MinPlDep and pd.code <= MaxPlDep
      and pn.plantdepartment_id = plantdepartmentid;
  else -- all depot
    if MinRoute <> 0 and MaxRoute <> 999999 then -- route selection
      select count(pnl.packingnoteline_id)
      into Result
      from packingnote pn, route ru,
        packingnoteline pnl, uniquebundle ub, plantdepartment pd,
        status st, businessunit bu, status stb
      where pn.packingnote_id = pnl.packingnote_id
        and pnl.finishingmethod_id = ub.finishingmethod_id
        and pnl.sizedefinition_id = ub.sizedefinition_link_id
        and pnl.product_id = ub.product_link_id
        and ub.deliverynotenumber = 0
        and pn.plantdepartment_id = pd.plantdepartment_id
        and pn.status_id = st.status_id
        and st.code in ('10', '20')
        and ub.status_id = stb.status_id
        and stb.code = '10'
        and ub.businessunit_id = bu.businessunit_id
        and bu.plant_id = pd.plant_id
        and pn.processbusinessunit_id = bu.businessunit_id
        and pn.route_id = ru.route_id and ru.active = 'Y'
        and ub.uniquebundle_id = uniquebundleid
        and bu.businessunit_id = businessunitid
        and pn.deliverydate >= MinDelDate and pn.deliverydate <= MaxDelDate
        and ru.routenumber >= MinRoute and ru.routenumber <= MaxRoute
        and pd.code >= MinPlDep and pd.code <= MaxPlDep
        and pn.plantdepartment_id = plantdepartmentid;
    else -- all route
      select count(pnl.packingnoteline_id)
      into Result
      from packingnote pn, packingnoteline pnl, uniquebundle ub, plantdepartment pd,
        status st, businessunit bu, status stb
      where pn.packingnote_id = pnl.packingnote_id
        and pnl.finishingmethod_id = ub.finishingmethod_id
        and pnl.sizedefinition_id = ub.sizedefinition_link_id
        and pnl.product_id = ub.product_link_id
        and ub.deliverynotenumber = 0
        and pn.plantdepartment_id = pd.plantdepartment_id
        and pn.status_id = st.status_id
        and st.code in ('10', '20')
        and ub.status_id = stb.status_id
        and stb.code = '10'
        and ub.businessunit_id = bu.businessunit_id
        and bu.plant_id = pd.plant_id
        and pn.processbusinessunit_id = bu.businessunit_id
        and ub.uniquebundle_id = uniquebundleid
        and bu.businessunit_id = businessunitid
        and pn.deliverydate >= MinDelDate and pn.deliverydate <= MaxDelDate
        and pd.code >= MinPlDep and pd.code <= MaxPlDep
        and pn.plantdepartment_id = plantdepartmentid;
    end if;
  end if;

  return(Result);
end F_GetNoOfPackingNoteLines;
/
create or replace function F_GetNoteNumbersOnDate (
delDate in packingnote.deliverydate%type,
invoiceheaderid in invoiceheader.invoiceheader_id%type,
productid in product.product_id%type,
sizeid in sizedefinition.sizedefinition_id%type,
finmetid in finishingmethod.finishingmethod_id%type)
  return varchar2 is
  result varchar2(6000);
begin
result := '1';
for Vcsr in
      (select p.notenumber
      from packingnote p, packingnoteline l
      where p.packingnote_id=l.packingnote_id
      and p.deliverydate = delDate
      and l.invoiceheader_id = invoiceheaderid
      and l.product_id = productid and l.sizedefinition_id = sizeid
      and l.finishingmethod_id=finmetid)
loop
if (result = '1') then result := castnumberasvarchar(Vcsr.Notenumber);
else if (length(result) < 5000) then result := concatenate3(result, ', ', castnumberasvarchar(Vcsr.Notenumber));
     else  result := result || '... ';
end if;
end if;
end loop;
  if result = '1' then result := null; end if;
  return result;
end F_GetNoteNumbersOnDate;
/
create or replace function F_GETOLDWEIGHT
(isSoil in            reportparam.number_value1%type,
 ticketNo in          weighingticket.ticketnumber%type,
 weighingCat in       weighingticketline.weighingcategory_id%type)
return number is
 amonunt number;
 weighingticketID  weighingticket.weighingticket_id%type;
 checkPN boolean;
begin

  if isSoil = 1 then
    select sum(wl.grossweight - wl.tareweight)
    into amonunt
    from weighingticket w, weighingticketline wl
    where w.weighingticket_id = wl.weighingticket_id
      and wl.weighingcategory_id = weighingCat
      and w.ticketnumber = ticketNo
      and w.soilticket = 'Y' ;
  else
    begin
      checkPN := false;
      begin
      select w.weighingticket_id
      into weighingticketID
      from weighingticket w
      where w.ticketnumber = ticketNo
      and w.soilticket ='N';
      exception when no_data_found then checkPN := true;
      end;
      if checkPN then
        select sum(pc.grossweight - pc.tareweight - pc.soilportion)
        into amonunt
        from packingnote p, packingnotecontainer pc
        where p.packingnote_id = pc.packingnote_id
          and p.notenumber = ticketNo
          and pc.weighingcategory_id = weighingCat;
      else
        select sum(wl.grossweight - wl.tareweight - wl.soilportion)
        into amonunt
        from weighingticketline wl
        where wl.weighingticket_id = weighingticketID
          and wl.weighingcategory_id = weighingCat;
      end if;
    end;
  end if;

  return amonunt;

end F_GETOLDWEIGHT ;
/
create or replace function F_GetParLevel
  (fpnMinYear            reportparam.copy_number%type,
   fpnMaxYear            reportparam.number_value3%type,
   fpnMinMonth           reportparam.number_value1%type,
   fpnMaxMonth           reportparam.number_value2%type,
--   fpnGroup              reportparam.number_value3%type,
   fpsGroup              reportparam.string_value%type,
   fpnCustomerID         customer.customer_id%type,
   fpnCostCenterID       costcenter.costcenter_id%type,
   fpnDepartmentID       department_link.department_link_id%type,
   fpnDistribPointID     distributionpoint_link.distributionpoint_link_id%type,
   fpnProductID          product.product_id%type,
   fpnSizeID             sizedefinition.sizedefinition_id%type,
   fpnFinMethodID        finishingmethod.finishingmethod_id%type
  ) return  number is
  LVnParLevel number;
begin

  if fpsGroup = '1' then --customer level
    select avg(qty)
    into LVnParLevel
    from (select d.deliverydate deldate, sum(d.amountstandard) qty
          from deliveryhistory d, customermonth cm
          where cm.customer_id = fpnCustomerID
--            and cm.YEAR = fpnMinYear
--            AND CM.MONTH BETWEEN fpnMinMonth AND fpnMaxMonth
            and cm.YEAR*100+CM.MONTH BETWEEN fpnMinYear*100+fpnMinMonth and fpnMaxYear*100+fpnMaxMonth
            and d.sizedefinition_link_id = fpnSizeID
            and d.finishingmethod_id = fpnFinMethodID
            and d.product_link_id = fpnProductID
            and d.deliverydate between cm.startdate and cm.enddate
            and d.amountstandard > 0
         group by d.deliverydate);
    if LVnParLevel is null then LVnParLevel:=0; end if;
    return LVnParLevel;
  end if;

  if fpsGroup = '4' then --costcenter level
    select avg(qty)
    into LVnParLevel
    from (select d.deliverydate deldate, sum(d.amountstandard) qty
          from deliveryhistory d, customermonth cm, distributionpoint dp
          where cm.customer_id = fpnCustomerID
--            and cm.YEAR = fpnMinYear
--            AND CM.MONTH BETWEEN fpnMinMonth AND fpnMaxMonth
            and cm.YEAR*100+CM.MONTH BETWEEN fpnMinYear*100+fpnMinMonth and fpnMaxYear*100+fpnMaxMonth
            and d.distributionpoint_link_id = dp.distributionpoint_id
            and dp.costcenter_id = fpnCostCenterID
            and d.sizedefinition_link_id = fpnSizeID
            and d.finishingmethod_id = fpnFinMethodID
            and d.product_link_id = fpnProductID
            and d.deliverydate between cm.startdate and cm.enddate
            and d.amountstandard > 0
         group by d.deliverydate);
    if LVnParLevel is null then LVnParLevel:=0; end if;
    return LVnParLevel;
  end if;

  if fpsGroup = '2' then --department level
    select avg(qty)
    into LVnParLevel
    from (select d.deliverydate deldate, sum(d.amountstandard) qty
          from deliveryhistory d, customermonth cm
          where cm.customer_id = fpnCustomerID
--            and cm.YEAR = fpnMinYear
--            AND CM.MONTH BETWEEN fpnMinMonth AND fpnMaxMonth
            and cm.YEAR*100+CM.MONTH BETWEEN fpnMinYear*100+fpnMinMonth and fpnMaxYear*100+fpnMaxMonth
            and d.department_link_id = fpnDepartmentID
            and d.sizedefinition_link_id = fpnSizeID
            and d.finishingmethod_id = fpnFinMethodID
            and d.product_link_id = fpnProductID
            and d.deliverydate between cm.startdate and cm.enddate
            and d.amountstandard > 0
         group by d.deliverydate);
    if LVnParLevel is null then LVnParLevel:=0; end if;
    return LVnParLevel;
  end if;

  if fpsGroup = '3' then -- distrib point
    select avg(qty)
    into LVnParLevel
    from (select d.deliverydate deldate, sum(d.amountstandard) qty
          from deliveryhistory d, customermonth cm
          where cm.customer_id = fpnCustomerID
--            and cm.YEAR = fpnMinYear
--            AND CM.MONTH BETWEEN fpnMinMonth AND fpnMaxMonth
            and cm.YEAR*100+CM.MONTH BETWEEN fpnMinYear*100+fpnMinMonth and fpnMaxYear*100+fpnMaxMonth
            and d.department_link_id = fpnDepartmentID
            and d.distributionpoint_link_id = fpnDistribPointID
            and d.sizedefinition_link_id = fpnSizeID
            and d.finishingmethod_id = fpnFinMethodID
            and d.product_link_id = fpnProductID
            and d.deliverydate between cm.startdate and cm.enddate
            and d.amountstandard > 0
         group by d.deliverydate);
    if LVnParLevel is null then LVnParLevel:=0; end if;
    return LVnParLevel;
  end if;

  return 0;
end F_GetParLevel;
/
create or replace function f_getpatientdays(
       p_id       number,
       p_rp_id    reportparam.reportparam_id%type,
       pd_group   varchar2)
return number is
/*version 2.0*/
   v_pd number := 0;
startdt number;
  enddt number;
begin
 select min(rp.copy_number*100 + rp.number_value1),
        max(rp.number_value3*100 + rp.number_value2)
   into startdt, enddt
   from reportparam rp
  where rp.reportparam_id = p_rp_id;
  if pd_group = 'CUST' then
  select sum(pdy.patientdays)
    into v_pd
    from patientday pdy
         join distributionpoint dp
              join department dep on dp.department_id = dep.department_id
         on pdy.distributionpoint_link_id = dp.distributionpoint_id
   where dep.customer_id = p_id
     and pdy.year*100 + pdy.month between startdt and enddt
     and pdy.week = 0
     and exists(select dh.deliveryhistory_id
                  from deliveryhistory dh, customermonth cum
                 where cum.customer_id = pdy.customer_link_id
                   and dh.customer_link_id = pdy.customer_link_id
                   and dh.deliverydate between cum.startdate and cum.enddate
                   and cum.year*100 + cum.month between startdt and enddt);
  end if;
  if pd_group = 'CC' then
  select sum(pdy.patientdays)
    into v_pd
    from patientday pdy
         join distributionpoint dp on pdy.distributionpoint_link_id = dp.distributionpoint_id
   where dp.costcenter_id = p_id
     and pdy.year*100 + pdy.month between startdt and enddt
     and exists(select dh.deliveryhistory_id
                  from deliveryhistory dh, customermonth cum
                 where cum.customer_id = pdy.customer_link_id
                   and dh.distributionpoint_link_id = pdy.distributionpoint_link_id
                   and dh.deliverydate between cum.startdate and cum.enddate
                   and cum.year*100 + cum.month between startdt and enddt);
  end if;
  if pd_group = 'DEP' then
  select sum(pdy.patientdays)
    into v_pd
    from patientday pdy
         join distributionpoint dp on pdy.distributionpoint_link_id = dp.distributionpoint_id
   where dp.department_id = p_id
     and pdy.year*100 + pdy.month between startdt and enddt
     and exists(select dh.deliveryhistory_id
                  from deliveryhistory dh, customermonth cum
                 where cum.customer_id = pdy.customer_link_id
                   and dh.distributionpoint_link_id = pdy.distributionpoint_link_id
                   and dh.deliverydate between cum.startdate and cum.enddate
                   and cum.year*100 + cum.month between startdt and enddt);
   end if;
  if pd_group = 'DSP' then
  select sum(pdy.patientdays)
    into v_pd
    from patientday pdy
   where pdy.distributionpoint_link_id = p_id
     and pdy.year*100 + pdy.month between startdt and enddt
     and pdy.week = 0;
  end if;
return nvl(v_pd, 0);
end;
/
create or replace function F_GetPoundPrice
  (fpnProductID in         product.product_id%type,
   fpnFinMethID in         finishingmethod.finishingmethod_id%type,
   fpnSizeID in            sizedefinition.sizedefinition_id%type,
   fpnCustomerID in        customer.customer_id%type,
   fpnWeighCatID in        weighingcategory.weighingcategory_id%type,
   fpnPricedate in         pricelistpercustomer.dateactive%type
  ) return  number is
LVnInvoiceMethod number;
LVnWeightPrice number;
LVnMaxWashes number;
LVsSoil varchar2(1);
type Tcsr is ref cursor;
Vcsr Tcsr;
begin

  if fpnWeighCatID is null then return 0; end if;
  LVnInvoiceMethod := null;
  LVsSoil := null;
  LVnMaxWashes := null;

  begin
    open Vcsr for
      select p.maxwashes
      from productlistpercustomer p
      where p.product_id = fpnProductID
        and p.sizedefinition_id = fpnSizeID
        and p.finishingmethod_id = fpnFinMethID
        and p.customer_id = fpnCustomerID
        and fpnPricedate between p.dateactive and p.dateinactive;
      fetch Vcsr into LVnMaxWashes;
    exception when no_data_found then null;
  end;
  close Vcsr;

  if ((LVnMaxWashes = 0) or (LVnMaxWashes is null)) then
    begin
      open Vcsr for
        select p.maxwashes
        from productlistpercustomer p, sizedefinition s
        where p.product_id = fpnProductID
          and p.sizedefinition_id = s.sizedefinition_id
          and s.code = '*'
          and p.finishingmethod_id = fpnFinMethID
          and p.customer_id = fpnCustomerID
          and fpnPricedate between p.dateactive and p.dateinactive;
        fetch Vcsr into LVnMaxWashes;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if (LVnMaxWashes is null) then LVnMaxWashes:=0; end if;
  if (LVnMaxWashes <> 0) then return 0; end if;

  begin
    open Vcsr for
      select wcc.invoicemethod
      from weighingcategpercustomer wcc
      where wcc.customer_id =  fpnCustomerID
        and wcc.weighingcategory_id = fpnWeighCatID;
      fetch Vcsr into LVnInvoiceMethod;
    exception when no_data_found then null;
  end;
  close Vcsr;

  if LVnInvoiceMethod = 3 then LVsSoil := 'N';
  else if (LVnInvoiceMethod = 2 or LVnInvoiceMethod = 4) then LVsSoil := 'Y'; end if;
  end if;

  if LVsSoil is not null then
    LVnWeightPrice := pack_price.Weight_Price(fpnCustomerID, fpnWeighCatID, LVsSoil, fpnPricedate);
  else
    LVnWeightPrice := 0;
  end if;

  return LVnWeightPrice;

end F_GetPoundPrice;
/
create or replace function f_getpreviousdeliverydate(
                  customerid  in customer.customer_id%type,
                  referencedate in date)
  return date is /*version 1.0*/
  result    date;
  visitdate date;
  i         integer;
  limit365  integer;
begin
  i := 0;
  limit365 := 0;
  visitdate := referencedate - 1;
  result := referencedate;
  while ((i = 0) and (limit365 < 365))
  loop
    begin
      i := pack_sort.iscustomervisitdateint(customerid, visitdate);
      limit365 := limit365 + 1;
      if i = 1
        then result := visitdate;
        else visitdate := visitdate - 1;
      end if;
    end;
  end loop;
  return(result);
end;
/
create or replace function F_GetPriceFromType
(pricetype in         number, -- 1-purhase price, 2-sales price, 3-replacement price
 consolidate in       number, -- 1-consoldate, 0-detailed
 customerid in        customer.customer_id%type,
 supplierid in        product.supplier_id%type,
 productid in         product.product_id%type ,
 sizeid in            sizedefinition.sizedefinition_id%type ,
 pricedate in         pricelistpercustomer.dateactive%type,
 defpricedate in      pricelistpercustomer.dateactive%type)
return number is
 crdate pricelistpercustomer.dateactive%type;
 begin

 if consolidate=1 then crdate := defpricedate; else crdate := pricedate; end if;
 case priceType
   when 1 -- purchase
     then return F_PURCHASEPRICE(supplierid, productid, sizeid, crdate);
   when 2 -- sales
     then return pack_price.Sales_Price(customerid, productid, sizeid, crdate);
   when 3 -- replacement
     then return pack_price.Replacement_Price(customerid, productid, sizeid, null,crdate);
   else return 0;
 end case;

end F_GetPriceFromType ;
/
create or replace function F_GetProcBUID(workorderid workorder.workorder_id%type)
  return number is
  result number;
  customerid number;
  minwolid number;
  wobuid number;
  wolprocbuid number;
  customerprocbuid number;
 begin
  customerid:=-1;
  minwolid:=-1;
  result:=-1;
  select wo.customer_link_id into customerid from workorder wo where wo.workorder_id=workorderid;
  select min(wol.workorderline_id) into minwolid from workorder wok, workorderline wol
    where wok.workorder_id=wol.workorder_id and wok.workorder_id=workorderid;
  select wo.businessunit_id into wobuid from workorder wo where wo.workorder_id=workorderid;
  select min(ca.processbusinessunit_id) into  wolprocbuid from workorder wk, workorderline wol, product p, productgroup pg, activity a, customeractivities ca
       where wk.workorder_id=wol.workorder_id and wol.product_link_id=p.product_id and p.productgroup_id=pg.productgroup_id
       and pg.activity_id=ca.activity_id and ca.customer_id=wk.customer_link_id
       and wk.workorder_id=workorderid and wol.workorderline_id=minwolid ;
       if (customerid is not null) then
       select c.defaultbusinessunit_id into  customerprocbuid  from workorder w, customer c
        where w.customer_link_id=c.customer_id and w.workorder_id=workorderid;
      end if;
 if (customerid is null or minwolid is null) then
  result:=wobuid;
 else
   result:=coalesce(wolprocbuid,customerprocbuid);
 end if;
 return result;
end  F_GetProcBUID;
/
create or replace function F_GetProductCode
(productcode in       product.code%type,
 customerid in        customer.customer_id%type,
 productid in         product.product_id%type,
 sizeid in            sizedefinition.sizedefinition_id%type,
 finnmethid in        finishingmethod.finishingmethod_id%type)
return VARCHAR2 is
 code                 productlistpercustomer.customcode%type;
 nodata               boolean;
 sizestarid           sizedefinition.sizedefinition_id%type;
begin
  if finnmethid is null then return productcode; end if;
  if sizeid is null then return productcode; end if;
  code:='';
  nodata:=false;
  -- check plpc using size and finmeth
  begin
    select max(p.customcode)
    into code
    from productlistpercustomer p
    where p.customer_id = customerid
      and p.product_id = productid
      and p.sizedefinition_id = sizeid
      and p.finishingmethod_id = finnmethid;
    if code is null then nodata:=true; end if;
--   exception when no_data_found then nodata:=true;
  end;
  if not nodata then
    if code is null then return productcode;
    else return code; end if;
  else
    nodata:=false;
    -- check plpc with size *
    select s.sizedefinition_id
    into sizestarid
    from sizedefinition s
    where s.code = '*';
    begin
      select max(p.customcode)
      into code
      from productlistpercustomer p
      where p.customer_id = customerid
        and p.product_id = productid
        and p.sizedefinition_id = sizestarid
        and p.finishingmethod_id = finnmethid;
      if code is null then nodata:=true; end if;
--     exception when no_data_found then nodata:=true;
    end;
    if not nodata then
      if code is not null then return code; end if;
    end if;
    return productcode;
  end if;
end F_GetProductCode ;
/
create or replace function F_GetProductDesc
(customerid in        customer.customer_id%type,
 productid in         product.product_id%type,
 sizeid in            sizedefinition.sizedefinition_id%type,
 finnmethid in        finishingmethod.finishingmethod_id%type,
 languageid in        languages.language_id%type)
return varchar2 is
 descr                product_desc.description%type;
 nodata               boolean;
 sizestarid           sizedefinition.sizedefinition_id%type;
begin

  if finnmethid is null then
    begin
      select p.description
      into descr
      from product_desc p
      where p.language_id = languageid
        and p.product_id = productid;
    exception when no_data_found then null;
    end;
    return descr;
  end if;
  if sizeid is null then
    begin
      select p.description
      into descr
      from product_desc p
      where p.language_id = languageid
        and p.product_id = productid;
    exception when no_data_found then null;
    end;
    return descr;
  end if;
  nodata:=false;
  -- check plpc using size and finmeth
  begin
    select max(p.customdescription)
    into descr
    from productlistpercustomer p
    where p.customer_id = customerid
      and p.product_id = productid
      and p.sizedefinition_id = sizeid
      and p.finishingmethod_id = finnmethid;
    if descr is null then nodata:=true; end if;
--   exception when no_data_found then nodata:=true;
  end;
  if not nodata then
    if descr is null then
      begin
        select p.description
        into descr
        from product_desc p
        where p.language_id = languageid
          and p.product_id = productid;
      exception when no_data_found then null;
      end;
      return descr;
    else return descr; end if;
  else
    nodata:=false;
    -- check plpc with size *
    select s.sizedefinition_id
    into sizestarid
    from sizedefinition s
    where s.code = '*';
    begin
      select max(p.customdescription)
      into descr
      from productlistpercustomer p
      where p.customer_id = customerid
        and p.product_id = productid
        and p.sizedefinition_id = sizestarid
        and p.finishingmethod_id = finnmethid;
      if descr is null then nodata:=true; end if;
--     exception when no_data_found then nodata:=true;
    end;
    if not nodata then
      if descr is not null then return descr; end if;
    end if;
    begin
      select p.description
      into descr
      from product_desc p
      where p.language_id = languageid
        and p.product_id = productid;
    exception when no_data_found then null;
    end;
    return descr;
  end if;
end F_GetProductDesc ;
/
create or replace function F_GetRecWeightPrice
(showprice             number,
 customerid in         customer.customer_id%type ,
 weighingcategoryid in product.product_id%type ,
 soil               in generalweightprice.soil%type,
 pricedate in          pricelistpercustomer.dateactive%type)
return number is
 begin

 if customerid is null then return 0; end if;
 if showprice = 0 then return 0; end if;
 if weighingcategoryid is null then return 0; end if;
 return pack_price.Weight_Price(customerid, weighingcategoryid, soil, pricedate);

end F_GetRecWeightPrice ;
/
create or replace function F_GetRepairsNo
 (wearerinventoryid in     wearerinventory.wearerinventory_id%type,
  businessunitid in        businessunit.businessunit_id%TYPE,
  routeid in               route.route_id%type,
  stopnr in                routestop.stopnumber%type,
  reportparamid in         reportparam.reportparam_id%type)
return number is
  Result                   number;
begin

-- return routeid;

  Result:=0;
    select count(*)
    into Result
    from repairhistory rh, wearerinventory wi, weareremployment we, deliveryscan ds,
      packingnote pn, reportparam rp
    where wi.weareremployment_id = we.weareremployment_id
      and ds.weareremployment_link_id = we.weareremployment_id
      and ds.distributionpoint_link_id = we.distributionpoint_id
      and ds.product_link_id = wi.product_id
      and ds.sizedefinition_link_id = wi.sizedefinition_id
      and ds.finishingmethod_id = wi.finishingmethod_id
      and ds.packingnote_id = pn.packingnote_id
      and pn.deliverydate = rp.date_value1
      and rh.businessunit_id = ds.businessunit_id
      and rh.uniqueitem_link_id = ds.uniqueitem_link_id
      and rh.repairdate <= rp.date_value1
      and rh.repairdate > rp.date_value1 - 7
      and wi.wearerinventory_id = wearerinventoryid
      and ds.businessunit_id = businessunitid
      and rp.reportparam_id = reportparamid
      and pn.route_id = routeid
      and pn.stopnumber = stopnr;

  return(Result);
end F_GetRepairsNo;
/
create or replace function f_getrowcodeloc_smg(productlinkid        product_link.product_link_id%type,
                                               sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
                                               requestedgradeid     qualitygrade.qualitygrade_id%type,
                                               stockroomid          stockroom.stockroom_id%type,
                                               isUnique             workorderline.codeuniquely%type,
                                               isRow                varchar2)
 return varchar2 is
  retcode varchar2(25);
begin
  retcode := null;
  if stockroomid is null then
    return null;
  else
    begin
      for vcursor in (
                      select A.retcode as retcode
                      --into rowcode
                        from (select

                                case
                                  when isRow = 'Y' then
                                   sl.rowcode
                                  else
                                   sl.locationcode
                                end as retcode,

                                case
                                  when isUnique = 'Y' then
                                   (select sum(sq.qtyunique +
                                               sq.qtyuniquewithmodifications)
                                      from stockquantity sq
                                     where sq.stockreservationpergrade_id =
                                           srg.stockreservationpergrade_id
                                       and sq.stockroomlocation_id =
                                           sl.stockroomlocation_id)
                                  else
                                   (select sum(sq.qtyunique +
                                               sq.qtyuniquewithmodifications +
                                               sq.qtynonunique)
                                      from stockquantity sq
                                     where sq.stockreservationpergrade_id =
                                           srg.stockreservationpergrade_id
                                       and sq.stockroomlocation_id =
                                           sl.stockroomlocation_id)
                                end sumqty
                               --,               rownum r
                                 from stockroom                  s,
                                      stockroomlocation          sl,
                                      standardlocationperproduct slp

                                 left outer join standardlocationpersize sls
                                   on slp.standardlocationperproduct_id =
                                      sls.standardlocationperproduct_id,
                                stockdefinitionperitem sdi
                                 left outer join stockreservationpergrade srg
                                   on srg.stockdefinitionperitem_id =
                                      sdi.stockdefinitionperitem_id
                                where s.stockroom_id = sl.stockroom_id
                                  and s.stockroom_id = sdi.stockroom_id
                                  and slp.stockroomlocation_id =
                                      sl.stockroomlocation_id
                                  and slp.product_id = sdi.product_id
                                  and sdi.product_id = productlinkid
                                  and (sls.sizedefinition_id =
                                      sizedefinitionlinkid or
                                      slp.definepersize = 'N')
                                  and sdi.sizedefinition_id =
                                      sizedefinitionlinkid
                                     --and srg.qualitygrade_id = requestedgradeid
                                  and s.stockroom_id = stockroomid
                                  and coalesce((select resq.priority from qualitygrade resq where srg.qualitygrade_id=resq.qualitygrade_id),0)<=
                 coalesce((select qq.priority from qualitygrade qq where qq.qualitygrade_id=requestedgradeid),0)
                                order by  slp.priority asc, sumqty desc

                               ) A
                      --where r < 2

                      ) loop
        begin

          if (vcursor.retcode is not null) then
            return vcursor.retcode;
          end if;
        end;
      end loop;

    exception
      when no_data_found then
        null;
    end;
  end if;
  return retcode;
end f_getrowcodeloc_smg;
/
create or replace function f_getrowcode_smg
(productlinkid product_link.product_link_id%type,
 sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
 requestedgradeid qualitygrade.qualitygrade_id%type,
 stockroomid stockroom.stockroom_id%type)
 return varchar2 is
        rowcode varchar2(25);
begin
  rowcode := null;
  if stockroomid is null then return null;
    else
  begin
    select rowcode
      into rowcode
      from (select sl.rowcode, rownum r
              from stockroom                  s,
                   stockroomlocation          sl,
                   standardlocationperproduct slp
              left outer join standardlocationpersize sls
                on slp.standardlocationperproduct_id =sls.standardlocationperproduct_id,
                 stockdefinitionperitem     sdi
                 left outer join stockreservationpergrade   srg on srg.stockdefinitionperitem_id =
                   sdi.stockdefinitionperitem_id
             where s.stockroom_id = sl.stockroom_id
               and s.stockroom_id = sdi.stockroom_id
               and slp.stockroomlocation_id = sl.stockroomlocation_id
               and slp.product_id = sdi.product_id
               and sdi.product_id = productlinkid
               and (sls.sizedefinition_id = sizedefinitionlinkid or
                   slp.definepersize = 'N')
               and sdi.sizedefinition_id = sizedefinitionlinkid
               --and srg.qualitygrade_id = requestedgradeid
               and s.stockroom_id = stockroomid
             order by slp.priority)
     where r < 2;
    exception when no_data_found then null;
 end;
 end if;
return rowcode;
end f_getrowcode_smg;
/
create or replace function F_GETROWLOCATION
  (stockreservationpergradeid in stockreservationpergrade.stockreservationpergrade_id%type,
   uniquely in workorderline.codeuniquely%type default 'Y'
  ) return  varchar2 is
   rowlocation varchar2(25);
begin

  rowlocation := null;

  begin
    case when uniquely = 'n' then
        select rowcode
        into rowlocation
            from (select rownum r, x.rowcode
                 from (select srl.rowcode
                      from stockroomlocation srl, locationtype lt, stockquantity sq
                      where sq.stockreservationpergrade_id = stockreservationpergradeid
                       and srl.stockroomlocation_id = sq.stockroomlocation_id
                       and srl.locationtype_id=lt.locationtype_id
                       and lt.pickinglocation='Y'
                       order by srl.pickingsequence, sq.qtynonunique desc) x)
            where r < 2;
    else
        select rowcode
        into rowlocation
            from (select rownum r, x.rowcode
                 from (select srl.rowcode
                      from stockroomlocation srl, locationtype lt, stockquantity sq
                      where sq.stockreservationpergrade_id = stockreservationpergradeid
                       and srl.stockroomlocation_id = sq.stockroomlocation_id
                       and srl.locationtype_id=lt.locationtype_id
                       and lt.pickinglocation='Y'
                       order by srl.pickingsequence, (sq.qtyunique + sq.qtynonunique) desc) x)
            where r < 2;
    end case;
    exception when no_data_found then null;
  end;

  return rowlocation;

end F_GETROWLOCATION;
/
create or replace function f_getrowlocationprodsizestock(fp_productlinkid    product_link.product_link_id%type,
                                                fp_sizedefinitionid sizedefinition.sizedefinition_id%type,
                                                fp_stockroomid      stockroom.stockroom_id%type)
  return varchar2 is
  lv_rowlocation varchar2(50);
begin
  lv_rowlocation := null;
  if fp_stockroomid is null
  then
    return null;
  else
    begin
      select x.rowlocation
        into lv_rowlocation
        from (select sl.rowcode || '   ' || sl.locationcode rowlocation,
                      rownum r
                 from stockroom s
                 join stockroomlocation sl on sl.stockroom_id =
                                              s.stockroom_id
                 join standardlocationperproduct slp on slp.stockroomlocation_id =
                                                        sl.stockroomlocation_id
                 left outer join standardlocationpersize sls on (slp.standardlocationperproduct_id =
                                                                sls.standardlocationperproduct_id and
                                                                sls.sizedefinition_id =
                                                                fp_sizedefinitionid)
                 join stockdefinitionperitem sdi on (sdi.stockroom_id =
                                                    s.stockroom_id and
                                                    sdi.product_id =
                                                    slp.product_id and
                                                    sdi.sizedefinition_id =
                                                    fp_sizedefinitionid)
                where sdi.product_id = fp_productlinkid
                  and s.stockroom_id = fp_stockroomid
                order by slp.priority) x
       where x.r = 1;
    exception
      when no_data_found then
        lv_rowlocation := null;
    end;
  end if;
  return lv_rowlocation;
end f_getrowlocationprodsizestock;
/
create or replace function f_getrowlocation_smg
(productlinkid product_link.product_link_id%type,
 sizedefinitionlinkid sizedefinition_link.sizedefinition_link_id%type,
 requestedgradeid qualitygrade.qualitygrade_id%type,
 stockroomid stockroom.stockroom_id%type)
 return varchar2 is
 rowlocation varchar2(25);
begin
  rowlocation := null;
  if stockroomid is null then return null;
    else
  begin
    select locationcode
      into rowlocation
      from (select sl.locationcode, rownum r
              from stockroom                  s,
                   stockroomlocation          sl,
                   standardlocationperproduct slp
              left outer join standardlocationpersize sls
                on slp.standardlocationperproduct_id =sls.standardlocationperproduct_id,
                 stockdefinitionperitem     sdi
                 left outer join stockreservationpergrade   srg on srg.stockdefinitionperitem_id =
                   sdi.stockdefinitionperitem_id
             where s.stockroom_id = sl.stockroom_id
               and s.stockroom_id = sdi.stockroom_id
               and slp.stockroomlocation_id = sl.stockroomlocation_id
               and slp.product_id = sdi.product_id
               and sdi.product_id = productlinkid
               and (sls.sizedefinition_id = sizedefinitionlinkid or
                   slp.definepersize = 'N')
               and sdi.sizedefinition_id = sizedefinitionlinkid
               --and srg.qualitygrade_id = requestedgradeid
               and s.stockroom_id = stockroomid
             order by slp.priority)
     where r < 2;
    exception when no_data_found then null;
 end;
 end if;
return rowlocation;
end f_getrowlocation_smg;
/
create or replace function f_getrowlocation_unf(fp_productlinkid    product_link.product_link_id%type,
                                                fp_sizedefinitionid sizedefinition.sizedefinition_id%type,
                                                fp_stockroomid      stockroom.stockroom_id%type)
  return varchar2 is
  lv_rowlocation varchar2(25);
begin
  lv_rowlocation := null;
  if fp_stockroomid is null
  then
    return null;
  else
    begin
      select x.rowlocation
        into lv_rowlocation
        from (select sl.rowcode || '   ' || sl.locationcode rowlocation,
                      rownum r
                 from stockroom s
                 join stockroomlocation sl on sl.stockroom_id =
                                              s.stockroom_id
                 join standardlocationperproduct slp on slp.stockroomlocation_id =
                                                        sl.stockroomlocation_id
                 left outer join standardlocationpersize sls on (slp.standardlocationperproduct_id =
                                                                sls.standardlocationperproduct_id and
                                                                sls.sizedefinition_id =
                                                                fp_sizedefinitionid)
                 join stockdefinitionperitem sdi on (sdi.stockroom_id =
                                                    s.stockroom_id and
                                                    sdi.product_id =
                                                    slp.product_id and
                                                    sdi.sizedefinition_id =
                                                    fp_sizedefinitionid)
                where sdi.product_id = fp_productlinkid
                  and s.stockroom_id = fp_stockroomid
                order by slp.priority) x
       where x.r = 1;
    exception
      when no_data_found then
        lv_rowlocation := null;
    end;
  end if;
  return lv_rowlocation;
end f_getrowlocation_unf;

/
create or replace function F_GetSoilWeight
  (fpnCustomerID in        customer.customer_id%type,
   fpnProductID in         product.product_id%type,
   fpnSizeID in            sizedefinition.sizedefinition_id%type,
   fpnFinMethID in         finishingmethod.finishingmethod_id%type,
   fpnPricedate in         pricelistpercustomer.dateactive%type
  ) return  number is
  LVnSoilWeight number;
begin

  LVnSoilWeight := null;

  begin
    select pl.soilweight
    into LVnSoilWeight
    from productlistpercustomer pl
    where pl.customer_id = fpnCustomerID
      and pl.product_id = fpnProductID
      and pl.sizedefinition_id = fpnSizeID
      and pl.finishingmethod_id = fpnFinMethID
      and fpnPricedate between pl.dateactive and pl.dateinactive;
    exception
    when others then null;
  end;

  if LVnSoilWeight is null then
    begin
      select pl.soilweight
      into LVnSoilWeight
      from productlistpercustomer pl, sizedefinition s
      where pl.customer_id = fpnCustomerID
        and pl.product_id = fpnProductID
        and pl.sizedefinition_id = s.sizedefinition_id
        and pl.finishingmethod_id = fpnFinMethID
        and s.code = '*'
        and fpnPricedate between pl.dateactive and pl.dateinactive;
    exception
    when others then
      LVnSoilWeight := 0;
    end;
  end if;

  return LVnSoilWeight;

end F_GetSoilWeight;
/
create or replace function F_GetStationNameFromBundle(
      uniquebundleid in        uniquebundle.uniquebundle_id%type
) return VARCHAR2 is
  station_name VARCHAR2(40);
begin
  select ws.description
    into station_name
             from workstation ws, systemuser su, (select ubil.systemuser_id from uniquebundleitemlink ubil
             where ubil.uniquebundle_id = uniquebundleid order by ubil.timestamp desc) z
         where rownum = 1 and z.systemuser_id = su.systemuser_id and su.LASTLOGINATWORKSTATION = ws.WORKSTATION_ID;
  return station_name;
end;
/
create or replace function F_GetStockActivity_Items(reportparamid reportparam.reportparam_id%type,
                                                    plantid       plant.plant_id%type)
  return number is
  totalcircinv number;
begin
  select sum(i.totalcircinv)
    into totalcircinv
    from statusquoheader h,
         sqitemincirculation i,
         businessunit bu,
         plant t,
         (select t.plant_id,
                 max(q.statusquodate) statusquodate,
                 rp2.reportparam_id
            from statusquoheader q,
                 businessunit    bu,
                 plant           t,
                 reportparam     rp2
           where q.processbusinessunit_id = bu.businessunit_id
             and bu.plant_id = t.plant_id
             AND rp2.date_value2 >= q.statusquodate
           group by t.plant_id, rp2.reportparam_id) x
   where h.statusquoheader_id = i.statusquoheader_id
     and x.statusquodate = h.statusquodate
     and h.processbusinessunit_id = bu.businessunit_id
     and bu.plant_id = t.plant_id
     and t.plant_id = x.plant_id
     and t.plant_id = plantid
     AND x.reportparam_id = reportparamid;
   return totalcircinv;
end F_GetStockActivity_Items;
/
create or replace function F_GetStockActivity_Revenue(reportparamid reportparam.reportparam_id%type,
                                                      plantid       plant.plant_id%type)
  return number is
  totalcircrevenue number;
begin
  select sum(case
               when il.adjustmentreason_id is null then
                il.amount
               else
                il.adjustedamount
             end)
    into totalcircrevenue
    from invoiceheader      ih,
         invoiceline        il,
         routecontrol       rc,
         businessunit       bu,
         plant              pl,
         status             st,
         invoicelinetype    ilt,
         invoicelineproduct ilp,
         product            p,
         reportparam        rp
   where ih.invoiceheader_id = il.invoiceheader_id
     and ih.routecontrol_id = rc.routecontrol_id
     and ih.invoicebusinessunit_id = bu.businessunit_id
     and bu.plant_id = pl.plant_id
     and ih.status_id = st.status_id
     and il.invoiceline_id = ilp.invoiceline_id
     and ilp.product_link_id = p.product_id
     and ilt.invoicelinetype_id = il.invoicelinetype_id
     and ih.documenttype = 1
     and st.statustype = 'in'
     and st.code = '2'
     and il.extend = 'y'
     and ilt.type = 1
     and p.typeofmerchandise = 2
     and rc.drivingdate >= rp.date_value1
     and rc.drivingdate <= rp.date_value2
     and rp.reportparam_id = reportparamid
     and pl.plant_id = plantid;
   return totalcircrevenue;
end F_GetStockActivity_Revenue;
/
create or replace function F_GetStockroomPrice
(qualitygradeid  in    qualitygrade.qualitygrade_id%type,
 stockroomid in        stockroom.stockroom_id%type,
 productid in          product.product_id%type ,
 sizeid in             sizedefinition.sizedefinition_id%type ,
 pricedate in          pricelistpercustomer.dateactive%type
 )
return number is
 valuationType number;
 supplierprod number;
 supplierstockroom number;
 srgid number;
 Fifoprice number;
 begin
select qq.stockvaluationmethod into valuationType  from qualitygrade qq
where qq.qualitygrade_id=qualitygradeid;
select p.supplier_id into supplierprod from product p where p.product_id=productid;
select  coalesce(( select sdi.defaultsupplier_id  from stockdefinitionperitem sdi
where sdi.stockroom_id=stockroomid and sdi.product_id=productid and sdi.sizedefinition_id=sizeid
and sdi.customer_id is null),-1)  into supplierstockroom from dual;
select coalesce ((select  srg.stockreservationpergrade_id  from stockdefinitionperitem sdi, stockreservationpergrade srg
where sdi.stockdefinitionperitem_id=srg.stockdefinitionperitem_id
      and sdi.stockroom_id=stockroomid
      and sdi.product_id=productid
      and sdi.sizedefinition_id=sizeid
      and srg.qualitygrade_id=qualitygradeid
      and sdi.customer_id is null),-1) into srgid from dual;
select coalesce(supplierstockroom,supplierprod) into supplierstockroom  from dual;
 select coalesce((select sum(s.qtyactualstock * s.piecevalue) / sum(s.qtyactualstock)
        from stockvaluefifo s where s.stockreservationpergrade_id=srgid),0) into Fifoprice from dual;
 case valuationType
   when 0 -- PurchasePrice
     then return F_PURCHASEPRICE(supplierstockroom, productid, sizeid, pricedate);
     when 1 -- FIFO
     then return Fifoprice;
   when 2 -- AvgPurchasePrices
     then return F_GetAvgPurchasePricesAtDate (srgid, pricedate);
   when 3 -- FixedRentPrice
     then return F_GetFixedSettlePriceAtDate (srgid,pricedate );
   else return 0;
 end case;
end F_GetStockroomPrice ;
/
create or replace function F_GetStopAndDelScheme(
  customerid in customerdeliveryscheme.customer_id%type ,
  routeid in    route.route_id%type)
return varchar2 is
 stopanddelscheme varchar2(255);
 freq number;
 type Tcsr is ref cursor;
 Vcsr Tcsr;
begin

   stopanddelscheme:=null;
   begin
   open Vcsr for
     select to_char(MIN(rs.stopnumber)) || ' / ' || ds.code, ds.frequency
     from routestop rs, deliveryschemesperstop dss, deliveryscheme ds
     where rs.routestop_id = dss.routestop_id
       and rs.route_id = routeid
       and dss.customer_id = customerid
       and dss.deliveryscheme_id = ds.deliveryscheme_id
     group by ds.code, ds.frequency
     order by ds.frequency asc;
   fetch Vcsr into stopanddelscheme, freq;
   exception when no_data_found then null;
   end;
   close Vcsr;

   return stopanddelscheme;

end F_GetStopAndDelScheme;
/
create or replace function F_GetStopAndDelSchemeHUE(
  customerid in customerdeliveryscheme.customer_id%type ,
  routeno in    route.routenumber%type)
return varchar2 is
 stopanddelscheme varchar2(255);
 freq number;
 stopno number;
 type Tcsr is ref cursor;
 Vcsr Tcsr;
begin

   stopanddelscheme:=null;
   begin
   open Vcsr for
     select rs.stopnumber, ds.frequency
     from routestop rs, deliveryschemesperstop dss, deliveryscheme ds, route r
     where rs.routestop_id = dss.routestop_id
       and rs.route_id = r.route_id
       and r.routenumber = routeno
       and dss.customer_id = customerid
       and dss.deliveryscheme_id = ds.deliveryscheme_id
     order by ds.frequency asc, rs.stopnumber asc;
   fetch Vcsr into stopno, freq;
   exception when no_data_found then null;
   end;
   close Vcsr;

   begin
   open Vcsr for
     select to_char(rs.stopnumber) || ' / ' || ds.code, ds.frequency
     from routestop rs, deliveryschemesperstop dss, deliveryscheme ds, route r
     where rs.routestop_id = dss.routestop_id
       and rs.route_id = r.route_id
       and rs.stopnumber = stopno
       and r.routenumber = routeno
       and dss.customer_id = customerid
       and dss.deliveryscheme_id = ds.deliveryscheme_id
       and ds.frequency = freq;
   fetch Vcsr into stopanddelscheme, freq;
   exception when no_data_found then null;
   end;
   close Vcsr;

   return stopanddelscheme;

end F_GetStopAndDelSchemeHUE;
/
create or replace function f_getsupplierproductcode
  (productid in product.product_id%type,
   sizedefinitionid in sizedefinition.sizedefinition_id%type,
   supplierid in supplier.supplier_id%type
  ) return  varchar2 is
   supplierproductcode varchar2(30);
begin
  supplierproductcode := null;
  begin
   select v.supplierproductcode
   into supplierproductcode
          from (select sp.supplierproductcode, rownum
             from supplierproduct          sp,
                  productsizepersupproduct psp,
                  product                  p1,
                  supplierproductprice     spp
            where psp.supplierproduct_id = sp.supplierproduct_id
              and p1.product_id = psp.product_id
              and p1.supplier_id = sp.supplier_id
              and sp.supplier_id = supplierid
              and psp.product_id(+) = productid
              and psp.sizedefinition_id = sizedefinitionid
              and spp.supplierproduct_id = sp.supplierproduct_id
              and spp.startdate <= sysdate
            order by spp.startdate desc) v
            where rownum = 1;
    exception when no_data_found then null;
  end;
  return supplierproductcode;
end f_getsupplierproductcode;
/
create or replace function f_getsuppliersizecode
  (productid in product.product_id%type,
   sizedefinitionid in sizedefinition.sizedefinition_id%type,
   supplierid in supplier.supplier_id%type
  ) return  varchar2 is
   suppliersizecode varchar2(30);
begin
  suppliersizecode := null;
  begin
   select v.suppliersizecode
   into suppliersizecode
          from (select sp.suppliersizecode, rownum
             from supplierproduct          sp,
                  productsizepersupproduct psp,
                  product                  p1,
                  supplierproductprice     spp
            where psp.supplierproduct_id = sp.supplierproduct_id
              and p1.product_id = psp.product_id
              and p1.supplier_id = sp.supplier_id
              and sp.supplier_id = supplierid
              and psp.product_id(+) = productid
              and psp.sizedefinition_id = sizedefinitionid
              and spp.supplierproduct_id = sp.supplierproduct_id
              and spp.startdate <= sysdate
            order by spp.startdate desc) v
            where rownum = 1;
    exception when no_data_found then null;
  end;
  return suppliersizecode;
end f_getsuppliersizecode;
/
create or replace function F_GetTheoreticalWeight
  (fpnTheoreticalweight  productsize.theoreticalweight%type,
   fpnProductID          product.product_id%type,
   fpnSizeID             sizedefinition.sizedefinition_id%type
  ) return  number is

  LVnWeight number;
begin

  begin
    select prds.theoreticalweight
    into LVnWeight
    from productsize prds
    where prds.product_id = fpnProductID
      and prds.sizedefinition_id = fpnSizeID;
  exception
    when others then
      LVnWeight:= 0;
  end;

  if LVnWeight = 0  then LVnWeight:=fpnTheoreticalweight;
  end if;

  return LVnWeight;

end F_GetTheoreticalWeight;
/
create or replace function F_GetTheoreticalWeightPLPC --version 0.1
  (fpnCustomerID         customer.customer_id%type,
   fpnProductID          product.product_id%type,
   fpnSizeID             sizedefinition.sizedefinition_id%type,
   fpnFinishingMethodID  finishingmethod.finishingmethod_id%type
  ) return  number is

  LVnWeight number;
begin
  begin
    select plpc.soilweight
      into LVnWeight
      from productlistpercustomer plpc
     where plpc.product_id = fpnProductID
       and plpc.sizedefinition_id = fpnSizeID
       and plpc.finishingmethod_id = fpnFinishingMethodID
       and plpc.customer_id = fpnCustomerID;
   exception
    when others then
      LVnWeight:= 0;
  end;
  if (LVnWeight = 0) then
    begin
      select prds.theoreticalweight
      into LVnWeight
      from productsize prds
      where prds.product_id = fpnProductID
        and prds.sizedefinition_id = fpnSizeID;
    exception
      when others then
        LVnWeight:= 0;
    end;
   if (LVnWeight = 0) then
     begin
       select p.theoreticalweight
         into LVnWeight
         from product p
        where p.product_id = fpnProductID;
      exception
      when others then
        LVnWeight:= 0;
      end;
    end if;
  end if;

  return LVnWeight;

end F_GetTheoreticalWeightPLPC;
/
create or replace function F_GETTOTALCIRCINV
  (fpnCustomerID                customer.customer_id%type,
   fpnProductID                 product.product_id%type,
   fpnSizeId                    sizedefinition.sizedefinition_id%type,
   fpnFinMethID                 finishingmethod.finishingmethod_id%type,
   fpdReportParamID             reportparam.reportparam_id%type
  ) return  number is
  LVnAmount number;
  LVnCnt    number;
  LVnSq     varchar2(255);
  selectStatement   varchar2(500);
begin
  LVnAmount := 0;

  select count(*)
  into LVnCnt
    from statusquoheader sh, reportparam rp
    where rp.reportparam_id = fpdReportParamID
      and sh.statusquodate >= rp.date_value1
      and sh.statusquodate <= rp.date_value2;

  if LVnCnt <> 0 then
      select sum(sqi.Totalcircinv)
      into LVnAmount
      from statusquoheader sh, reportparam rp, SQITEMINCIRCULATION sqi
      where rp.reportparam_id = fpdReportParamID
        and sh.statusquodate >= rp.date_value1
        and sh.statusquodate <= rp.date_value2
        and sh.statusquoheader_id = sqi.statusquoheader_id
        and sqi.customer_link_id = fpnCustomerID
        and sqi.product_link_id = fpnProductID
        and sqi.finishingmethod_id = fpnFinMethID
        and sqi.sizedefinition_link_id = fpnSizeId
        and sqi.totalcircinv > 0;
   end if;

  if LVnCnt = 0 then
    LVnAmount:=0;
  else
    LVnAmount:=(LVnAmount*100)+LVnCnt;
  end if;

  return LVnAmount;

end F_GETTOTALCIRCINV;
/
create or replace function f_getuniqueitemlastcust(lvnuniqueitemid uniqueitem.uniqueitem_id%type)
  return varchar2 is
  lastcust varchar2(60);
begin
  lastcust := '';
  select coalesce(to_char(cl.customernumber) || ' ' || cl.name, '')
    into lastcust
    from uniqueitem             ui,
         weareremployment_link  wel,
         distributionpoint_link dpl,
         department_link        dl,
         customer_link          cl
   where ui.poolitem = 0
     and ui.lastweareremployment_link_id = wel.weareremployment_id
     and wel.distributionpoint_link_id = dpl.distributionpoint_link_id
     and dpl.department_link_id = dl.department_link_id
     and dl.customer_link_id = cl.customer_link_id
     and ui.uniqueitem_id = lvnuniqueitemid;
  return(lastcust);
exception
  when others then
    return null;
end f_getuniqueitemlastcust;
/
create or replace function F_GetUserGroupId
(plantid in          plant.plant_id%type,
 customerid in       customer.customer_id%type)
return number is
 usergroupid          businessunitsperusergroup.usergroup_id%type;
 bucode               businessunit.code%type;
 nodata               boolean;
begin

  bucode := null;
  begin
    select b.code
    into bucode
    from customer c, businessunit b
      where c.defaultbusinessunit_id = b.businessunit_id
        and b.plant_id = plantid
        and c.customer_id = customerid;
    exception when no_data_found then nodata:=true;
  end;

  if nodata then
    begin
      select min(bu.code)
      into bucode
      from customeractivities ca, businessunit bu
      where ca.processbusinessunit_id = bu.businessunit_id
        and bu.plant_id = plantid
        and ca.customer_id = customerid;
      exception when no_data_found then null;
    end;
  end if;

  if bucode is null then return null; end if;

  if bucode is not null then
    select bug.usergroup_id
    into usergroupid
    from businessunit bu, businessunitsperusergroup bug
    where bu.businessunit_id = bug.businessunit_id
      and bu.code = bucode;
  end if;

  return usergroupid;

end F_GetUserGroupId;
/
create or replace function F_GetVat
(showprice            number,
 customerid in        customer.customer_id%type ,
 productid in         product.product_id%type ,
 countryactive in     country.country_id%type,
 country in           country.country_id%type,
 taxdate in           taxgroup.startdatetaxrate%type)
return number is
 startdate            taxgroup.startdatetaxrate%type;
 oldvatrate           taxgroup.oldtaxrate%type;
 vatrate              taxgroup.taxrate%type;
 taxcode              taxgroup.code%type;
 begin

 if showprice = 0 then return 0; end if;
 if productid is null then return 0; end if;
 if customerid is null then return 0; end if;

-- get the vat corresponding to product and active country
 begin
   select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
   into taxcode, startdate, oldvatrate, vatrate
   from producttax p, taxgroup t
   where p.product_id = productid
     and p.country_id = countryactive
     and p.taxgroup_id = t.taxgroup_id;
 exception when others then return 0;
 end;
-- check if the active country is the same with the report country
 if countryactive = country then
   if taxdate >= startdate then
     return vatrate;
   else
     return oldvatrate;
   end if;
 end if;
-- get the vat corresponding to country report
 begin
 select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
 into taxcode, startdate, oldvatrate, vatrate
 from taxgroup t
 where t.country_id = country
   and t.code = taxcode;
 exception when others then return 0;
 end;
 if taxdate >= startdate then
   return vatrate;
 else
   return oldvatrate;
 end if;

end F_GetVat ;
/
create or replace function F_GetWeightVat
(showprice             number,
 customerid in         customer.customer_id%type ,
 weighingcategoryid in weighingcategory.weighingcategory_id%type ,
 countryactive in      country.country_id%type,
 country in            country.country_id%type,
 taxdate in            taxgroup.startdatetaxrate%type)
return number is
 startdate             taxgroup.startdatetaxrate%type;
 oldvatrate            taxgroup.oldtaxrate%type;
 vatrate               taxgroup.taxrate%type;
 taxcode               taxgroup.code%type;
 begin

 if showprice = 0 then return 0; end if;
 if weighingcategoryid is null then return 0; end if;
 if customerid is null then return 0; end if;

-- get the vat corresponding to weight and active country
 begin
   select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
   into taxcode, startdate, oldvatrate, vatrate
   from weighingcategorytax p, taxgroup t
   where p.weighingcategory_id = weighingcategoryid
     and p.country_id = countryactive
     and p.taxgroup_id = t.taxgroup_id;
 exception when others then return 0;
 end;
-- check if the active country is the same with the report country
 if countryactive = country then
   if taxdate >= startdate then
     return vatrate;
   else
     return oldvatrate;
   end if;
 end if;
-- get the vat corresponding to country report
 begin
 select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
 into taxcode, startdate, oldvatrate, vatrate
 from taxgroup t
 where t.country_id = country
   and t.code = taxcode;
 exception when others then return 0;
 end;
 if taxdate >= startdate then
   return vatrate;
 else
   return oldvatrate;
 end if;

end F_GetWeightVat;
/
create or replace function f_get_amount_correctionticket (packingnoteid number)
return number is
lv_amount number;
begin
select nvl(sum(pnl.deliveredamount),0) into lv_amount
         from packingnoteline pnl
         where PNL.PACKINGNOTE_ID in
               (select PN.PACKINGNOTE_ID
                  from PACKINGNOTE PN
                 where PN.CORRECTIONFORNOTE_ID = packingnoteid);
return lv_amount;
end f_get_amount_correctionticket;
/
create or replace function f_get_amount_corrticketline (packingnoteid number, productid number, sizeid number, fmid number)
return number is
lv_amount number;
begin
select nvl(sum(pnl.deliveredamount),0) into lv_amount
         from packingnoteline pnl
         where PNL.PACKINGNOTE_ID in
               (select PN.PACKINGNOTE_ID
                  from PACKINGNOTE PN
                 where PN.CORRECTIONFORNOTE_ID = packingnoteid)
               and pnl.product_id = productid
               and pnl.sizedefinition_id = sizeid
               and pnl.finishingmethod_id = fmid;
return lv_amount;
end f_get_amount_corrticketline;
/
create or replace function F_GET_BUNDLE_QTY
  (fpnCustomerID in        customer.customer_id%type,
   fpnProductID in         product.product_id%type,
   fpnSizeID in            sizedefinition.sizedefinition_id%type,
   fpnFinMethID in         finishingmethod.finishingmethod_id%type,
   fpdDate in              productlistpercustomer.dateactive%type,
   fpsCheckPLPCSizeStar    varchar2,
   fpsCheckProductSize     varchar2
  ) return  number is
bundleQTY number;
type Tcsr is ref cursor;
Vcsr Tcsr;
begin

  bundleQTY := null;

  begin
    open Vcsr for
        select plpc.custombundlesize from productlistpercustomer plpc
        where plpc.customer_id = fpnCustomerID
          and plpc.product_id = fpnProductID
          and plpc.sizedefinition_id = fpnSizeID
          and plpc.finishingmethod_id = fpnFinMethID
          and fpdDate between plpc.dateactive and plpc.dateinactive;
      fetch Vcsr into bundleQTY;
    exception when no_data_found then null;
  end;
  close Vcsr;

  if (((bundleQTY = 0) or (bundleQTY is null)) and (fpsCheckPLPCSizeStar = 'Y')) then
    begin
      open Vcsr for
        select plpc.custombundlesize from productlistpercustomer plpc, sizedefinition s
        where plpc.customer_id = fpnCustomerID
          and plpc.product_id = fpnProductID
          and plpc.sizedefinition_id = s.sizedefinition_id and s.code = '*'
          and plpc.finishingmethod_id = fpnFinMethID
          and fpdDate between plpc.dateactive and plpc.dateinactive;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if (((bundleQTY = 0) or (bundleQTY is null)) and (fpsCheckProductSize = 'Y')) then
    begin
      open Vcsr for
        select ps.packingamount from productsize ps
        where ps.product_id = fpnProductID and ps.sizedefinition_id = fpnSizeID;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if ((bundleQTY = 0) or (bundleQTY is null)) then
    begin
      open Vcsr for
        select p.packingamount from product p where p.product_id = fpnProductID;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  return bundleQTY;

end F_GET_BUNDLE_QTY;
/
create or replace function F_GET_BUNDLE_QTY_ANG
  (fpnPlantID in           plant.plant_id%type,
   fpnCustomerID in        customer.customer_id%type,
   fpnProductID in         product.product_id%type,
   fpnSizeID in            sizedefinition.sizedefinition_id%type,
   fpnFinMethID in         finishingmethod.finishingmethod_id%type,
   fpdDate in              productlistpercustomer.dateactive%type,
   fpsCheckPLPCSizeStar    varchar2,
   fpsCheckProductSize     varchar2
  ) return  number is
bundleQTY number;
type Tcsr is ref cursor;
Vcsr Tcsr;
begin

  bundleQTY := null;

  begin
    open Vcsr for
        select plpc.custombundlesize from productlistpercustomer plpc
        where plpc.customer_id = fpnCustomerID
          and plpc.product_id = fpnProductID
          and plpc.sizedefinition_id = fpnSizeID
          and plpc.finishingmethod_id = fpnFinMethID
          and fpdDate between plpc.dateactive and plpc.dateinactive;
      fetch Vcsr into bundleQTY;
    exception when no_data_found then null;
  end;
  close Vcsr;

  if (((bundleQTY = 0) or (bundleQTY is null)) and (fpsCheckPLPCSizeStar = 'Y')) then
    begin
      open Vcsr for
        select plpc.custombundlesize from productlistpercustomer plpc, sizedefinition s
        where plpc.customer_id = fpnCustomerID
          and plpc.product_id = fpnProductID
          and plpc.sizedefinition_id = s.sizedefinition_id and s.code = '*'
          and plpc.finishingmethod_id = fpnFinMethID
          and fpdDate between plpc.dateactive and plpc.dateinactive;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if (((bundleQTY = 0) or (bundleQTY is null)) and (fpsCheckProductSize = 'Y')) then
    begin
      open Vcsr for
        select ps.packingamount from productsize ps
        where ps.product_id = fpnProductID and ps.sizedefinition_id = fpnSizeID;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if ((bundleQTY = 0) or (bundleQTY is null)) then
    begin
      open Vcsr for
        select pps.packingamount from plantproductsizesettings pps
        where pps.product_id = fpnProductID and pps.sizedefinition_id = fpnSizeID
        and pps.plant_id = fpnPlantID;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  if ((bundleQTY = 0) or (bundleQTY is null)) then
    begin
      open Vcsr for
        select p.packingamount from product p where p.product_id = fpnProductID;
        fetch Vcsr into bundleQTY;
      exception when no_data_found then null;
    end;
    close Vcsr;
  end if;

  return bundleQTY;

end F_GET_BUNDLE_QTY_ANG;
/
create or replace function f_get_interleave2of5(fp_barcode in varchar2) return varchar2 is
  lv_checksum_odd  number := 0;
  lv_checksum_even number := 0;
  lv_checkdigit    varchar2(1);
  lv_odd           boolean := true;
begin
  --f_get_interleave2of5 version 0.4
  for i in reverse 1 .. length(fp_barcode) loop
    begin
      lv_checkdigit := substr(fp_barcode, i, 1);
      if lv_odd then
        lv_checksum_odd := lv_checksum_odd + to_number(lv_checkdigit);
        lv_odd          := false;
      else
        lv_checksum_even := lv_checksum_even + to_number(lv_checkdigit);
        lv_odd           := true;
      end if;
    end;
  end loop;
  --( 10 - [ (3 * Odd + Even) modulo 10 ] ) modulo 10
  lv_checkdigit := to_char(mod(10 - mod(((3 * lv_checksum_odd) + lv_checksum_even), 10), 10));
  return fp_barcode || lv_checkdigit;
exception
  when others then
    return fp_barcode;
end f_get_interleave2of5;
/
create or replace function f_get_nextdate4day(fp_startdate        in date default trunc(sysdate),
                                              fp_nextdayid        in number default 1,
                                              fp_pack_on_countday in varchar default 'N')
  return date is
  gv_startdaynr number;
begin
  --f_get_nextdate4day version 0.2
  --get the next possible Monday/Tuesday.. for fp_nextdayid after fp_startdate
  select dywd.day
  into   gv_startdaynr
  from   date_yearweekday dywd
  where  dywd.date_ = trunc(nvl(fp_startdate, sysdate));
  --for this condition when met, the return date is equal to orignial (start-)date
  if (nvl(fp_pack_on_countday, 'N') = 'Y' and gv_startdaynr = nvl(fp_nextdayid, 0)) then
    return trunc(nvl(fp_startdate, sysdate));
  else
    --when day is empty, same date next week is returned
    return next_day(trunc(nvl(fp_startdate, sysdate)),
                    (to_char(to_date('15-06-2020', 'dd-mm-yyyy') +
                              (nvl(fp_nextdayid, gv_startdaynr) - 1), 'dy')));
  end if;
end f_get_nextdate4day;
/
create or replace function f_get_OSIA(plpcid number, inventorydate date)
  return number is
  res             number;
  v_plpcid        number;
  v_inventorydate date;
begin
  v_plpcid        := plpcid;
  v_inventorydate := inventorydate;
  select (case
           when a.SOILCOUNTMETHOD > 0 then
            (select COALESCE(sum(OSIA.QUANTITY), 0)
               from ONSITEINVENTORYADJUSTMENT OSIA, STANDARDDELIVERYLINE B
              where OSIA.PRODUCTLISTPERDISTRIBPOINT_ID =
                    B.PRODUCTLISTPERDISTRIBPOINT_ID
                and B.PRODUCTLISTPERCUSTOMER_ID = a.productlistpercustomer_id
                and OSIA.INVENTORYDATE <= v_inventorydate)
           else
            0
         end)
    into res
    from productlistpercustomer a
   where a.productlistpercustomer_id = v_plpcid;
  return res;
end f_get_OSIA;
/
create or replace function f_get_osia_plpd(plpdId number, inventoryDate date)
  return number is
  res             number;
  v_plpdId        number := plpdId;
  v_inventoryDate date := inventoryDate;
begin
  select SUM(ONSI.QUANTITY) into res
          from ONSITEINVENTORYADJUSTMENT ONSI
         where ONSI.PRODUCTLISTPERDISTRIBPOINT_ID = v_plpdId
          and ONSI.INVENTORYDATE <= v_inventoryDate;
  return res;
end f_get_osia_plpd;
/
create or replace function f_get_rqa(plpcid number, sizeDefId number, sizeCode varchar2, qtyReturned number, deliverydate date)
  return number is
  res            number;
  v_qtyReturned    number;
/* version 1.1 */
begin
  v_qtyReturned := qtyReturned;

  if sizeCode='*' then
    select nvl(sum(rqa.quantity), 0)
    into res
    from
    standarddeliveryline sdl join
    rentalqtyadjustment rqa
    on sdl.productlistperdistribpoint_id =
    rqa.productlistperdistribpoint_id
    where deliverydate between sdl.dateactive and sdl.dateinactive -- only active standarddeliverylines
    and sdl.productlistpercustomer_id = plpcid
    and rqa.adjustmentdate <= deliverydate;
  else
      select nvl(sum(rqa.quantity), 0)
      into res
      from rentalqtyadjustment rqa
      join standarddeliveryline s
      on s.productlistperdistribpoint_id = rqa.productlistperdistribpoint_id
      join productlistperdistribpoint plpd
      on plpd.productlistperdistribpoint_id = s.productlistperdistribpoint_id
      where deliverydate between s.dateactive and s.dateinactive
            and plpd.sizedefinition_id = sizedefid
            and s.productlistpercustomer_id = plpcid
            and rqa.adjustmentdate <= deliverydate;
  end if;
  if v_qtyReturned < 0 then
    v_qtyReturned := 0;
  end if;
  res := res - v_qtyReturned;
  if res < 0 then
    res := 0;
  end if;
  return res;
end f_get_rqa;
/
create or replace function f_get_rqa_forRelLoanBilling(plpcid       number,
                                                       deliverydate date)
  return number is
  res            number;
  v_plpcid       number;
  v_deliverydate date;
begin
  v_plpcid       := plpcid;
  v_deliverydate := deliverydate;
  select /*+ index (DV XPKDELIVERYVARIATIONS)*/
   nvl(sum(RQA.QUANTITY), 0)
    into res
    from RENTALQTYADJUSTMENT RQA
    left outer join DELIVERYVARIATIONS DV
      on RQA.DELIVERYVARIATIONS_ID = DV.DELIVERYVARIATIONS_ID
   where (select count(1)
            from STANDARDDELIVERYLINE S
           where S.PRODUCTLISTPERDISTRIBPOINT_ID =
                 rqa.productlistperdistribpoint_id
             and S.PRODUCTLISTPERCUSTOMER_ID = v_plpcid) > 0
     and (DECODE(NVL(RQA.DELIVERYVARIATIONS_ID, 0),
                 0,
                 RQA.ADJUSTMENTDATE,
                 DV.DELIVERYDATE) <= v_deliverydate);
  return res;
end f_get_rqa_forRelLoanBilling;
/
create or replace function f_get_rqa_forRelLoanBill_plpd(plpdId number, deliveryDate date)
  return number is
  res            number;
  v_plpdId       number := plpdId;
  v_deliveryDate date := deliveryDate;
begin
  select /*+ index (DV XPKDELIVERYVARIATIONS)*/
   nvl(sum(RQA.QUANTITY), 0) into res
    from RENTALQTYADJUSTMENT RQA
    left outer join DELIVERYVARIATIONS DV
      on RQA.DELIVERYVARIATIONS_ID = DV.DELIVERYVARIATIONS_ID
   where RQA.PRODUCTLISTPERDISTRIBPOINT_ID = v_plpdId
   and (decode(nvl(RQA.DELIVERYVARIATIONS_ID, 0), 0, RQA.ADJUSTMENTDATE, DV.DELIVERYDATE) <= v_deliveryDate);
  return res;
end f_get_rqa_forRelLoanBill_plpd;
/
create or replace function f_get_rqa_plpd(plpdId number, deliveryDate date, firstDelivery number)
  return number is
  res            number;
  v_plpdId       number := plpdId;
  v_deliveryDate date := deliveryDate;
  v_firstDelivery number := firstDelivery;
begin
  if (v_firstDelivery = 0) then
    select nvl(sum(RQA.QUANTITY), 0) into res
            from RENTALQTYADJUSTMENT RQA
            left outer join DELIVERYVARIATIONS DV
              on RQA.DELIVERYVARIATIONS_ID = DV.DELIVERYVARIATIONS_ID
           where RQA.PRODUCTLISTPERDISTRIBPOINT_ID = v_plpdId
             and RQA.ADJUSTMENTDATE <= v_deliveryDate;
  end if;
  if (v_firstDelivery = 1) then
    select nvl(sum(RQA.QUANTITYFIRSTDELIVERY), 0) into res
            from RENTALQTYADJUSTMENT RQA
           where RQA.PRODUCTLISTPERDISTRIBPOINT_ID = v_plpdId
             and RQA.ADJUSTMENTDATE <= v_deliveryDate;
  end if;

  return res;
end f_get_rqa_plpd;
/
create or replace function F_IsInYearWeekLifespan(
					startYear				integer,
					startWeek				integer,
					year						integer,
					week						integer,
					endYear					integer,
					endWeek					integer
) return integer is
  result boolean;
begin

	result :=
		(startYear < year and year < endYear) or
		(startYear = year and startWeek <= week and year < endYear) or
		(startYear < year and year = endYear and week <= endWeek) or
		(startYear = year and startWeek <= week and year = endYear and week <= endWeek);

	if (result) then return 1;  end if;
	return 0;

end F_IsInYearWeekLifespan;
/
create or replace function f_istemporarydeliverystop(fp_standarddeliverylineid in number,
                                                     fp_date                   in date default trunc(sysdate))
  return number is
  /*function f_istemporarydeliverystop version 0.2*/
  functionresult number(1);
  lv_date        date;
begin
  lv_date := nvl(fp_date, trunc(sysdate));
  select count(1)
  into   functionresult
  from   temporarydeliverystop tds
  where  tds.standarddeliveryline_id = fp_standarddeliverylineid
  and    lv_date between tds.startdate and tds.enddate;
  if functionresult = 0 then
    begin
      select count(1)
      into   functionresult
      from   temporarydeliverystop tds
      where  tds.standarddeliveryline_id = fp_standarddeliverylineid
      and    getyearofweek(lv_date) * 100 + getisoweek(lv_date) between
             tds.temporarystopstartyear * 100 + tds.tempstopstartweekforyear and
             tds.temporarystopendyear * 100 + tds.tempstopendweekforyear;
    end;
  end if;
  if functionresult = 0 then
    begin
      select count(1)
      into   functionresult
      from   temporarydeliverystop tds
      where  tds.standarddeliveryline_id = fp_standarddeliverylineid
      and    getisoweek(lv_date) between tds.temporarystopstartweek and tds.temporarystopendweek;
    end;
  end if;
  return(functionresult);
end f_istemporarydeliverystop;
/
create or replace FUNCTION F_LastRentPriceIncrease(
custID IN customer.customer_id%TYPE,
datestart IN customerrentprice.startdate%TYPE)
return varchar2 is -- PERCENTAGE ' 999.99' STARTDATE'YYYYMMDD'
       res varchar2(30);
       newdate DATE;
       olddate DATE;
       newprice NUMBER;
       oldprice NUMBER;
			 newID NUMBER;
			 oldID NUMBER;
			 i NUMBER;
			 ok NUMBER;
       type Tcsr is ref cursor ;
       Vcsr Tcsr;
begin
res:=NULL;
olddate:=getabsmindate();
newdate:=getabsmaxdate();
oldprice:=0;
newprice:=0;
oldID:=0;
newID:=0;
OPEN Vcsr FOR
    SELECT crp.startdate, crp.price, plpc.product_id
    FROM customerrentprice crp, productlistpercustomer plpc
    WHERE crp.startdate <= datestart AND plpc.customer_id = custID AND
          crp.productlistpercustomer_id = plpc.productlistpercustomer_id AND crp.price > 0
    ORDER BY crp.startdate desc, crp.customerrentprice_id DESC;
i := 1 ;
ok := 0 ;
loop
exit when (ok = 1 and i > 2) OR Vcsr%notfound;
     IF i = 1 THEN FETCH Vcsr INTO newdate, newprice, newID;
                   olddate:=newdate;
                   oldprice:=newprice;
									 oldID:=newID;
     ELSE FETCH Vcsr INTO olddate, oldprice, oldID;
          IF oldID=newID THEN ok := 1;
          end if;
     end if;
i := i + 1;
end loop;
IF oldprice <> 0 THEN res := concatenate(castnumberasvarcharwithformat((100 * ((newprice - oldprice)/ oldprice)), '999.99'), to_char(newdate, 'YYYYMMDD'));
END IF;
return res;
end F_LastRentPriceIncrease;
/
create or replace FUNCTION F_LastWashPriceIncrease(
custID IN customer.customer_id%TYPE,
datestart IN customerwashprice.startdate%TYPE)
return varchar2 is -- PERCENTAGE ' 999.99' STARTDATE'YYYYMMDD'
       res varchar2(30);
       newdate DATE;
			 olddate DATE;
			 newprice NUMBER;
			 oldprice NUMBER;
			 newID NUMBER;
			 oldID NUMBER;
			 i NUMBER;
			 ok NUMBER;
       type Tcsr is ref cursor ;
       Vcsr Tcsr;
begin
res:=NULL;
olddate:=getabsmindate();
newdate:=getabsmaxdate();
oldprice:=0;
newprice:=0;
oldID:=0;
newID:=0;
OPEN Vcsr FOR
	  SELECT cwp.startdate, cwp.price, plpc.product_id
    FROM customerwashprice cwp, productlistpercustomer plpc
    WHERE cwp.startdate <= datestart AND plpc.customer_id = custID AND
		      cwp.productlistpercustomer_id = plpc.productlistpercustomer_id AND cwp.price > 0
    ORDER BY cwp.startdate desc, cwp.customerwashprice_id DESC;
i := 1 ;
ok := 0 ;
loop
exit when (ok = 1 and i > 2) OR Vcsr%notfound;
     IF i = 1 THEN FETCH Vcsr INTO newdate, newprice, newID;
		               olddate:=newdate;
									 oldprice:=newprice;
									 oldID:=newID;
		 ELSE FETCH Vcsr INTO olddate, oldprice, oldID;
          IF oldID=newID THEN ok := 1;
          end if;
     end if;
i := i + 1;
end loop;
IF oldprice <> 0 THEN res := concatenate(castnumberasvarcharwithformat((100 * ((newprice - oldprice)/ oldprice)), '999.99'), to_char(newdate, 'YYYYMMDD'));
END IF;
return res;
end F_LastWashPriceIncrease;
/
create or replace FUNCTION F_LastWeightPriceIncrease(
custID IN customer.customer_id%TYPE,
datestart IN customerweightprice.startdate%TYPE)
return varchar2 is -- PERCENTAGE ' 999.99' STARTDATE'YYYYMMDD'
       res varchar2(30);
       newdate DATE;
       olddate DATE;
       newprice NUMBER;
       oldprice NUMBER;
			 newID NUMBER;
			 oldID NUMBER;
			 i NUMBER;
			 ok NUMBER;
       type Tcsr is ref cursor ;
       Vcsr Tcsr;
begin
res:=NULL;
olddate:=getabsmindate();
newdate:=getabsmaxdate();
oldprice:=0;
newprice:=0;
oldID:=0;
newID:=0;
OPEN Vcsr FOR
    SELECT cwp.startdate, cwp.price, wc.weighingcategory_id
    FROM customerweightprice cwp, weighingcategpercustomer wc
    WHERE cwp.startdate <= datestart AND wc.customer_id = custID AND
          cwp.weighingcategpercustomer_id = wc.weighingcategpercustomer_id AND cwp.price > 0
					and exists (select 1 from weighingcategory_desc wcd where wcd.weighingcategory_id = wc.weighingcategory_id
					                     and (wcd.description = 'Pounds Clean' or wcd.description = 'Pounds Soil'))
    ORDER BY cwp.startdate desc, cwp.customerweightprice_id DESC;
i := 1 ;
ok := 0 ;
loop
exit when (ok = 1 and i > 2) OR Vcsr%notfound;
     IF i = 1 THEN FETCH Vcsr INTO newdate, newprice, newID;
                   olddate:=newdate;
                   oldprice:=newprice;
									 oldID:=newID;
     ELSE FETCH Vcsr INTO olddate, oldprice, oldID;
          IF oldID=newID THEN ok := 1;
          end if;
     end if;
i := i + 1;
end loop;
IF oldprice <> 0 THEN res := concatenate(castnumberasvarcharwithformat((100 * ((newprice - oldprice)/ oldprice)), '999.99'), to_char(newdate, 'YYYYMMDD'));
END IF;
return res;
end F_LastWeightPriceIncrease;
/
create or replace function f_longtochar_indxexpr(v_table varchar2,
                                                 v_index varchar2,
                                                 v_columnpos varchar2)
  return varchar2 as
  lv_varchar varchar2(32767);
  lv_long    long;
begin
  select cl2.COLUMN_EXPRESSION
  into lv_long
              from user_ind_expressions cl2
             where cl2.TABLE_NAME = v_table
               and cl2.INDEX_NAME = v_index
               and cl2.COLUMN_POSITION = v_columnpos;
    lv_varchar := substr(lv_long, 1, 32767);
  return lv_varchar;
end f_longtochar_indxexpr;
/
create or replace function F_LTS_WashPriceType
(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)
return number is
-- price              number;
 generalpricelistid number ;
 npriority           pricelistpercustomer.priority%type;
 p                  NUMBER ;
 maxpriority        pricelistpercustomer.priority%type;
 s                  sizedefinition.sizedefinition_id%type ;
 f                  finishingmethod.finishingmethod_id%type;
 i                  number ;
 result             number ;

begin
s := sizedefinitionid;
f := finishingmethodid;
if s is null then return 0; end if;
if f is null then return 0; end if;
if productid is null then return 0; end if;
begin
 select max(pricelistpercustomer.priority) into maxpriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
             and   pricelistpercustomer.pricetype = 1  -- this means wash price
             and pricedate between pricelistpercustomer.dateactive and pricelistpercustomer.dateinactive;
-- exception when no_data_found then maxpriority := 999;
 if maxpriority is null then maxpriority := 999; end if;
end;
begin
 select min(pricelistpercustomer.priority) into npriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
               and pricelistpercustomer.pricetype = 1
               and pricedate between pricelistpercustomer.dateactive and pricelistpercustomer.dateinactive;
-- exception when no_data_found then npriority := 999;
 if npriority is null then npriority := 999; end if;
end;
p := npriority ; -- save priority value
i := 1 ;
while npriority <= maxpriority and result is null loop ---------------------------------------------------
begin
  generalpricelistid:=null;
  Select pricelistpercustomer.generalpricelist_id into generalpricelistid
                   from pricelistpercustomer
     where pricelistpercustomer.customer_id = customerid
     and pricelistpercustomer.pricetype = 1
     and pricelistpercustomer.dateactive <= pricedate
     and pricelistpercustomer.dateinactive >= pricedate
     and pricelistpercustomer.priority = npriority;
  exception when no_data_found then null;
end ;
if generalpricelistid is not null then
begin
     select grp.pricetype
              into result
              from generalwashprice grp, generalpricelist, pricelistpercustomer
              where   pricelistpercustomer.customer_id = customerid
                  and pricelistpercustomer.pricetype = 1 -- this means wash price
                  and pricelistpercustomer.priority = npriority
                  and pricelistpercustomer.generalpricelist_id = generalpricelist.generalpricelist_id
                  and generalpricelist.pricetype = 1
                  and generalpricelist.active = 'Y'
                  and generalpricelist.generalpricelist_id = grp.generalpricelist_id
                  and grp.product_id = productid
                  and grp.sizedefinition_id = s
                  and grp.finishingmethod_id = f
                  and grp.startdate = (select max(startdate) from generalwashprice
                                       where generalwashprice.generalpricelist_id = generalpricelist.generalpricelist_id
                                       and generalwashprice.product_id = productid
                                       and generalwashprice.sizedefinition_id = s
                                       and generalwashprice.finishingmethod_id = f
                                       and generalwashprice.startdate <= pricedate);
       exception when no_data_found then null;
                 when others then null ;
end;
end if;

 npriority := npriority + 1 ;
end loop ; ---------------------------------------------------------------------------
if result is null
  then return 999;
  else return result;
end if;
exception when no_data_found then return 0 ;
          when others then return 0;
end F_LTS_WashPriceType ;
/
create or replace function f_mindesc(invoicelineid invoiceline.invoiceline_id%type, p_id product.product_id%type, c_id customer.customer_id%type)
  return number is
  amountpn number;
begin
  for vCursor in (select cri.week, cri.quantity, cri.year
                    from costreportinfo cri
                   where cri.invoiceline_id = invoicelineid) loop
  select sum(dh.amountdelivered)
   into amountpn
   from deliveryhistory dh
where dh.customer_link_id=c_id
and dh.product_link_id=p_id
and dh.week=vCursor.Week
and dh.year=vCursor.Year;
  if amountpn is null  then amountpn:=0; end if;
    if amountpn < vCursor.Quantity then
      return 1;
    end if;
  end loop;
  return 0;
end f_mindesc;
/
create or replace FUNCTION F_MOD10DIM
(
  NO IN NUMBER
, DIM IN NUMBER
) RETURN NUMBER
is
 res        number(4,0);   -- MAX 37 *9
 mod12      number(1,0); -- 0,1,2
 n10s       number(38,0);
 nox        number(38,0);
 dimensionX number(38,0);
 i          number(1,0);    -- MAX 1
 res10      number(2,0); -- MAX 18
 mod10      number(2,0);  -- MAX 9
BEGIN  --  test ; no := 12345678;  mod10 = 2; --  DBMS_OUTPUT.PUT_LINE(to_char(no) || ' - ' || to_char(dim));
  if ((dim is null) or (dim = 0) or ( dim > 30) ) then return null; end if ;
  n10s           := power(10,dim-1);      -- max size 10^(dim-1)
  dimensionX     := dim;
  mod12          := 0;
  res            := 0;
  nox            := no;
  while dimensionX > 0
  loop
     dimensionX := dimensionX - 1;
     mod12 := dimensionX mod 2;
     if mod12 = 0 then mod12 := 2;
     end if;
     i :=floor(nox/n10s);     -- get ciffer
     nox :=nox - (i * n10s);  -- remove first cifer in no = i
     n10s := n10s/10;         -- next lower dimension
     IF (i > 0) then          --calc
        if (i*mod12) < 10 then  -- multiply
           res := res + (i*mod12);
        else  -- cross sum
           res := res + 1;
           res10:= i*mod12;
           res10:= res10 mod 10;
           res := res + res10;
        end if;
     end if;
   end loop;
   mod10 := (10 - (res mod 10));
   if (mod10 = 10)  then
      mod10 := 0;
   end if;
RETURN mod10;
END F_MOD10DIM;
/
create or replace function F_MODIFICATIONCODE
       ( table_id in integer
       )
       return varchar2
is
  modifcode1  modification.code%type;
  modifcode2  modification.code%type;
  modifcode3  modification.code%type;
  modifresult varchar2(1000);
  separator   varchar2(1000);
begin
  begin
    select m1.code
      into modifcode1
      from workorderlinemodification wolm1, modification m1
     where wolm1.workorderline_id = table_id
       and wolm1.modification_id = m1.modification_id
       and wolm1.sequencenumber = 1;
  exception
    when no_data_found then
      null;
  end;
  begin
    select m2.code
      into modifcode2
      from workorderlinemodification wolm2, modification m2
     where wolm2.workorderline_id = table_id
       and wolm2.modification_id = m2.modification_id
       and wolm2.sequencenumber = 2;
  exception
    when no_data_found then
      null;
  end;
  begin
    select m3.code
      into modifcode3
      from workorderlinemodification wolm3, modification m3
     where wolm3.workorderline_id = table_id
       and wolm3.modification_id = m3.modification_id
       and wolm3.sequencenumber = 3;
  exception
    when no_data_found then
      null;
  end;
  separator   := '                                                / ';
  modifresult := '';
  if modifcode1 is not null and modifcode2 is not null and
     modifcode3 is not null then
    modifresult := modifcode1 || separator || modifcode2 || separator || modifcode3;
  end if;
  if modifcode1 is null and modifcode2 is not null and
     modifcode3 is not null then
    modifresult := modifcode2 || separator || modifcode3;
  end if;
  if modifcode1 is null and modifcode2 is null and modifcode3 is not null then
    modifresult := modifcode3;
  end if;
  if modifcode1 is not null and modifcode2 is null and
     modifcode3 is not null then
    modifresult := modifcode1 || separator || modifcode3;
  end if;
  if modifcode1 is not null and modifcode2 is not null and
     modifcode3 is null then
    modifresult := modifcode1 || separator || modifcode2;
  end if;
  if modifcode1 is null and modifcode2 is not null and modifcode3 is null then
    modifresult := modifcode2;
  end if;
  if modifcode1 is not null and modifcode2 is null and modifcode3 is null then
    modifresult := modifcode1;
  end if;

  return modifresult;
end;
--end  F_MODIFICATIONCODE ;
/
create or replace function F_MODIFICATIONS
       ( table_id in integer,
         table_name in varchar2 -- U = uniqueitemmodification ; W = wearerinventorymodification
       )
       return varchar2
is
  result  varchar2(40);
  seq    integer;
begin
result := '' ;
seq := 1 ;
loop
  if table_id is not null and table_name = 'U' then
      begin -- U --
        for v_csr in ( select modi.code from modification modi, uniqueitemmodification uqmod
                              where uqmod.uniqueitem_id= table_id
                              and uqmod.sequencenumber = seq
                              and uqmod.modification_id = modi.modification_id )
                   loop
                       result := concatenate(result,v_csr.code );
                   end loop ;
      end ;
  else
      begin -- W --
        for v_csr in ( select modi.code from modification modi, wearerinventorymodification weymod
                              where weymod.wearerinventory_id = table_id
                              and weymod.sequencenumber = seq
                              and weymod.modification_id = modi.modification_id )
                   loop
                       result := concatenate(result,v_csr.code );
                   end loop ;
      end ;
  end if ;
  result := concatenate(coalesce(result, ' '), ' ; ');
 exit when seq = 3 ;
           seq := seq + 1 ;
end loop;
    return LTrim(result) ;
exception
when no_data_found then return null;
when others then return null ;
end  F_MODIFICATIONS ;
/
create or replace function f_num2char(fp_number    in number,
                                      fp_decimals  in number default 2,
                                      fp_separator in varchar2 default '.') return varchar2 is
  --function f_num2char version 0.1
  --maximum length is 16 including the decimals
  pragma udf;
  gv_charnum varchar2(16);
begin
  if nvl(fp_separator, '.') = '.' then
    begin
      case nvl(fp_decimals, 2)
        when 0 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '9999999999999999',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
        when 1 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '99999999999990D9',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
        when 2 then
          gv_charnum := trim(to_char(round(fp_number, nvl(fp_decimals, 2)), '9999999999990D99',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
        when 3 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '999999999990D999',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
        when 4 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '99999999990D9999',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
        else
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '9999999990D99999',
                                     'NLS_NUMERIC_CHARACTERS=''. '''));
      end case;
    end;
  else
    begin
      case nvl(fp_decimals, 2)
        when 0 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '9999999999999999',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
        when 1 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '99999999999990D9',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
        when 2 then
          gv_charnum := trim(to_char(round(fp_number, nvl(fp_decimals, 2)), '9999999999990D99',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
        when 3 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '999999999990D999',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
        when 4 then
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '99999999990D9999',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
        else
          gv_charnum := trim(to_char(round(fp_number, fp_decimals), '9999999990D99999',
                                     'NLS_NUMERIC_CHARACTERS='', '''));
      end case;
    end;
  end if;
  return(gv_charnum);
end f_num2char;
/
create or replace function F_ODD_EVEN ( numberVal number )
return
 varchar2
 is
 aux integer;
 result varchar2(4) ;
begin
aux := numberVal /2.0 ;
result :=
case
   when (numberVal/2.0)- aux <> 0 then 'ODD'
         else 'EVEN'
               end ;
return result;
end F_ODD_EVEN;
/
create or replace function f_onsiqty(p_plpd_id productlistperdistribpoint.productlistperdistribpoint_id%type, p_onside_date date) return number is
 v_quantity number:=0;
 begin
select SUM(o.quantity) into v_quantity
                  from onsiteinventoryadjustment o
                 where o.productlistperdistribpoint_id = p_plpd_id
                   and o.inventorydate <=p_onside_date
                   and not ((o.inventorydate = p_onside_date and o.origin = 7 and o.reference is Null) or
                        (o.inventorydate = p_onside_date and
                        (o.onsiteinventoryadjustment_id >
                        (select max(OSIA2.OnsiteInventoryAdjustment_ID)
                                 from OnsiteInventoryAdjustment OSIA2
                                where OSIA2.Origin = 7
                                  and OSIA2.InventoryDate = p_onside_date
                                  and OSIA2.Reference is Null))));
return v_quantity;
end f_onsiqty;
/
create or replace function F_OrderedCorrection (
  StockroomId  in              StockDefinitionPerItem.Stockroom_ID%type,
  ProductId in                 StockdefinitionPerItem.Product_ID%type,
  SizeDefinitionId in          StockDefinitionPerItem.SizeDefinition_ID%type,
  CustomerID in                StockDefinitionPerItem.Customer_ID%type,
  PUniqueItem in               PurchaseOrderLine.UniqueItem%type,
  DirectIssue                  Varchar2
) return number is

   Outstanding   number;

begin

    If DirectIssue = 'Y'then

      select sum (pol.QuantityOrderedDirectIssue - pol.QuantityReceivedDirectIssue - pol.QuantityCancelled)
      into Outstanding
      from PurchaseOrderheader PO, PurchaseOrderLine POL, Status st
      where pol.PURCHASEORDERHEADER_ID = po.PURCHASEORDERHEADER_ID
      and st.STATUS_ID = po.STATUS_ID
      and st.CODE in ('10', '20', '25', '30')
      and po.STOCKROOM_ID = StockroomID
      and POL.PRODUCT_LINK_ID = ProductID
      and POL.SIZEDEFINITION_LINK_ID = SizeDefinitionID
      and POL.UNIQUEITEM = PUniqueItem
      AND ((PO.CUSTOMER_LINK_ID = CustomerID ) OR(PO.CUSTOMER_LINK_ID IS NULL AND CustomerID IS NULL));

    else

      select sum (pol.QuantityOrdered - pol.QuantityReceived - pol.QuantityCancelled)
      into Outstanding
      from PurchaseOrderheader PO, PurchaseOrderLine POL, Status st
      where pol.PURCHASEORDERHEADER_ID = po.PURCHASEORDERHEADER_ID
      and st.STATUS_ID = po.STATUS_ID
      and st.CODE in ('10', '20', '25', '30')
      and po.STOCKROOM_ID = StockroomID
      and POL.PRODUCT_LINK_ID = ProductID
      and POL.SIZEDEFINITION_LINK_ID = SizeDefinitionID
      and POL.UNIQUEITEM = PUniqueItem
      AND ((PO.CUSTOMER_LINK_ID = CustomerID ) OR(PO.CUSTOMER_LINK_ID IS NULL AND CustomerID IS NULL));

    end if;

  if Outstanding is null then return 0; end if;

  return outstanding;

  exception
    when no_data_found then return 0;
end F_OrderedCorrection;
/
create or replace function f_orderedcorrectiongrade(fpstockroomid      in stockdefinitionperitem.stockroom_id%type,
                                                    fpproductid        in stockdefinitionperitem.product_id%type,
                                                    fpsizedefinitionid in stockdefinitionperitem.sizedefinition_id%type,
                                                    fpcustomerid       in stockdefinitionperitem.customer_id%type,
                                                    fppuniqueitem      in purchaseorderline.uniqueitem%type,
                                                    fpdirectissue      varchar2,
                                                    fpqualitygrade     purchaseorderline.requestedgrade_id%type)
  return number is
  --function f_orderedcorrectiongrade version 1.1
  lvoutstanding number;
begin
  if fpdirectissue = 'Y' then
    begin
      select sum(pol.quantityordereddirectissue - pol.quantityreceiveddirectissue -
                  pol.quantitycancelled)
      into   lvoutstanding
      from   purchaseorderheader po
      join   purchaseorderline pol
      on     pol.purchaseorderheader_id = po.purchaseorderheader_id
      join   status st
      on     st.status_id = po.status_id
      where  st.code in ('10', '20', '25', '30')
      and    po.stockroom_id = fpstockroomid
      and    pol.product_link_id = fpproductid
      and    pol.sizedefinition_link_id = fpsizedefinitionid
      and    pol.uniqueitem = fppuniqueitem
      and    pol.requestedgrade_id = fpqualitygrade
      and    (pol.quantityordereddirectissue -
            (pol.quantityreceiveddirectissue + pol.quantitycancelled) > 0)
      and    ((po.customer_link_id = fpcustomerid) or
            (po.customer_link_id is null and fpcustomerid is null));
    end;
  else
    begin
      select sum(pol.quantityordered - pol.quantityreceived - pol.quantitycancelled)
      into   lvoutstanding
      from   purchaseorderheader po
      join   purchaseorderline pol
      on     pol.purchaseorderheader_id = po.purchaseorderheader_id
      join   status st
      on     st.status_id = po.status_id
      where  st.code in ('10', '20', '25', '30')
      and    po.stockroom_id = fpstockroomid
      and    pol.product_link_id = fpproductid
      and    pol.sizedefinition_link_id = fpsizedefinitionid
      and    pol.uniqueitem = fppuniqueitem
      and    pol.requestedgrade_id = fpqualitygrade
      and    (pol.quantityordered - (pol.quantityreceived + pol.quantitycancelled) > 0)
      and    ((po.customer_link_id = fpcustomerid) or
            (po.customer_link_id is null and fpcustomerid is null));
    end;
  end if;
  if lvoutstanding < 0 then
    return 0;
  end if;
  return nvl(lvoutstanding, 0);
exception
  when no_data_found then
    return 0;
end f_orderedcorrectiongrade;
/
create or replace function f_packernoofbundles
(tobedeliveredamount in packingnoteline.tobedeliveredamount%type,
 bundleqty           in packingnoteline.bundleqty%type)
return number is
       result number ;
begin
     result := 0;
if ((bundleqty is null) or (bundleqty = 0))
then if ((tobedeliveredamount is not null) and (tobedeliveredamount <> 0))
     then result := tobedeliveredamount;
     end if;
else
     if ((bundleqty*trunc(tobedeliveredamount/bundleqty)=tobedeliveredamount) and (tobedeliveredamount <> 0))
        then result:=trunc(tobedeliveredamount/bundleqty);
        else
          if tobedeliveredamount = 0
          then result:=0;
          else result:=1 + trunc(tobedeliveredamount/bundleqty);
          end if;
     end if;
end if;
return(result);
end;
/
create or replace function f_previousstatement(currentdate date,
                                               billto      integer,
                                               delto       integer) return number is
  result       invoiceheader.prebillamount%type;
  previousdate invoiceheader.invoicedate%type;
begin
  if delto is null
  then
    begin
      select x.invoicedate
        into previousdate
        from (select ih.invoicedate
                from invoiceheader ih
               where ih.documenttype = 2
                 and ih.invoicedate < currentdate
                 and ih.billtocustomernumber = billto
            order by ih.invoicedate desc) x
       where rownum < 2;
      select y.prebillamount
        into result
        from (select ih.prebillamount
                from invoiceheader ih
               where ih.documenttype = 2
                 and ih.invoicedate = previousdate
                 and ih.billtocustomernumber = billto
            order by ih.prebillamount desc) y
       where rownum < 2;
    end;
  else
    begin
      select x.invoicedate
        into previousdate
        from (select ih.invoicedate
                from invoiceheader ih
               where ih.documenttype = 2
                 and ih.invoicedate < currentdate
                 and ih.deltocustomernumber = delto
            order by ih.invoicedate desc) x
       where rownum < 2;
      select y.prebillamount
        into result
        from (select ih.prebillamount
                from invoiceheader ih
               where ih.documenttype = 2
                 and ih.invoicedate = previousdate
                 and ih.deltocustomernumber = delto
            order by ih.prebillamount desc) y
       where rownum < 2;
    end;
  end if;
  return(result);
end f_previousstatement;
/
create or replace function F_PriceInsurance_details
(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)
return varchar2 is
 npriority           pricelistpercustomer.priority%type;
 generalpricelistid number ;
 maxpriority        pricelistpercustomer.priority%type;
 s                  sizedefinition.sizedefinition_id%type ;
 f                  finishingmethod.finishingmethod_id%type;
 result             varchar2(30) ;
  type Tcsr is ref cursor ;
   Vcsr Tcsr;
begin
s := sizedefinitionid;
f := finishingmethodid;
if (s is null) or (f is null) or (productid is null) then return null; end if;
begin
 select max(priority) into maxpriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
             and   pricelistpercustomer.pricetype = 9 -- insurance
             and pricelistpercustomer.dateactive <= pricedate
             and pricelistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then maxpriority := 999;
 if maxpriority is null then maxpriority := 999; end if;
end;
begin
 select min(priority) into npriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
             and   pricelistpercustomer.pricetype = 9
             and pricelistpercustomer.dateactive <= pricedate
             and pricelistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then npriority := 999 ;
 if npriority is null then npriority := 999; end if;
end;
while npriority <= maxpriority loop ---------------------------------------------------
begin
  generalpricelistid:=null;
  open Vcsr for
     Select pricelistpercustomer.generalpricelist_id --  into generalpricelistid
                   from pricelistpercustomer
     where pricelistpercustomer.customer_id = customerid
     and pricelistpercustomer.pricetype = 9
     and pricelistpercustomer.dateactive <= pricedate
     and pricelistpercustomer.dateinactive >= pricedate
     and pricelistpercustomer.priority = npriority;
  fetch Vcsr into generalpricelistid;
  exception when no_data_found then null;
end ;
if generalpricelistid is not null then
begin
     select (GetFormattedPriceDetails(gip.startdate,gip.price))
              into result
              from generalinsuranceprice gip, generalpricelist, pricelistpercustomer
              where
                      pricelistpercustomer.customer_id = customerid
                  and pricelistpercustomer.pricetype = 9 -- insurance
                  and pricelistpercustomer.dateactive <= pricedate
                  and pricelistpercustomer.dateinactive >= pricedate
                  and pricelistpercustomer.priority = npriority
                  and
                      pricelistpercustomer.generalpricelist_id = generalpricelist.generalpricelist_id
                  and generalpricelist.pricetype = 9
                  and generalpricelist.active = 'Y'
                  and
                      generalpricelist.generalpricelist_id = gip.generalpricelist_id
                  and gip.product_id = productid
                  and gip.sizedefinition_id = s
                  and gip.finishingmethod_id = f
                  and gip.startdate = (select max(startdate) from generalinsuranceprice
                                       where generalinsuranceprice.product_id = productid
                                       and generalinsuranceprice.generalpricelist_id = gip.generalpricelist_id
                                       and generalinsuranceprice.sizedefinition_id = s
                                       and generalinsuranceprice.finishingmethod_id = f
                                       and generalinsuranceprice.startdate <= pricedate);
       exception when no_data_found then null;
                 when others then null ;
 end;
end if;
    npriority := npriority + 1 ;
end loop ; ---------------------------------------------------------------------------
if result is null
then
  begin
select (GetFormattedPriceDetails(cupri.startdate, cupri.price))
       into result
            from customerinsuranceprice cupri
                 where cupri.customer_id = customerid
                       and cupri.startdate = (
                                           select max(customerinsuranceprice.startdate)
                                                  from customerinsuranceprice
                                           where customerinsuranceprice.customer_id = customerid
                                           and customerinsuranceprice.startdate <= pricedate);
  end;
end if;
if result is not null
   then return concatenate(result, '  0  0');
        else
            return null;
                   end if ;
    exception
when no_data_found then return null ;
-- when others	return -1;
end F_PriceInsurance_details ;
/
create or replace function F_PRICEINTERNALMERCHANDIZE
( plantID numeric,
  productID numeric,
  sizedefinitionID numeric,
  finishingmethodID numeric )
return
 number
 is
result number;
high_priority number;
low_priority number;
costpricelistID number;
 begin
select min(cplp.priority), max(cplp.priority)
       into high_priority, low_priority
            from costpricelistperplant cplp
                 where cplp.plant_id = plantID
                       and cplp.pricetype = 1;
loop  ---- 1 ---- LOOP BY PRIORITY
select cplp.costpricelist_id
       into costpricelistID  -- costpricelistID is updated cf. with priority increase
            from costpricelistperplant cplp
                 where cplp.plant_id = plantID and cplp.priority = high_priority
                       and cplp.pricetype = 1;
select coalesce(
  ( select cpld.price from costpricelistdetail cpld
           where
               cpld.costpricelist_id = costpricelistID
           and cpld.product_id = productID
           and cpld.sizedefinition_id = sizedefinitionID
           and cpld.finishingmethod_id = ( select MIN(costpricelistdetail.finishingmethod_id)
                                         from costpricelistdetail
                                  where
                                      costpricelistdetail.costpricelist_id = costpricelistID
                                  and costpricelistdetail.product_id = productID
                                  and costpricelistdetail.sizedefinition_id = sizedefinitionID
                                  and costpricelistdetail.startdate <= trunc(sysdate)
                                  )
           and cpld.startdate = ( select max(costpricelistdetail.startdate) from costpricelistdetail
                                  where
                                      costpricelistdetail.costpricelist_id = costpricelistID
                                  and costpricelistdetail.product_id = productID
                                  and costpricelistdetail.sizedefinition_id = sizedefinitionID
                                  and costpricelistdetail.finishingmethod_id = cpld.finishingmethod_id
                                  and costpricelistdetail.startdate <= trunc(sysdate) ) )
, ( select cpld.price from costpricelistdetail cpld -- SZ * PRICE
           where
               cpld.costpricelist_id = costpricelistID
           and cpld.product_id = productID
           and cpld.sizedefinition_id = (SELECT SZ.SIZEDEFINITION_ID FROM SIZEDEFINITION SZ WHERE SZ.CODE = '*')
           and cpld.finishingmethod_id = ( select min(costpricelistdetail.finishingmethod_id) from costpricelistdetail
                                  where
                                      costpricelistdetail.costpricelist_id = costpricelistID
                                  and costpricelistdetail.product_id = productID
                                  and costpricelistdetail.sizedefinition_id = (SELECT SZ.SIZEDEFINITION_ID FROM SIZEDEFINITION SZ WHERE SZ.CODE = '*')
                                  and costpricelistdetail.startdate <= trunc(sysdate) )
           and cpld.startdate = ( select max(costpricelistdetail.startdate) from costpricelistdetail
                                  where
                                      costpricelistdetail.costpricelist_id = costpricelistID
                                  and costpricelistdetail.product_id = productID
                                  and costpricelistdetail.sizedefinition_id = (SELECT SZ.SIZEDEFINITION_ID FROM SIZEDEFINITION SZ WHERE SZ.CODE = '*')
                                  and costpricelistdetail.finishingmethod_id = cpld.finishingmethod_id
                                  and costpricelistdetail.startdate <= trunc(sysdate) ) )
, ( select cpld.price from costpricelistdetail cpld -- SZ*, FM * PRICE
           where
               cpld.costpricelist_id = costpricelistID
           and cpld.product_id = productID
           and cpld.sizedefinition_id = (SELECT SZ.SIZEDEFINITION_ID FROM SIZEDEFINITION SZ WHERE SZ.CODE = '*')
           and cpld.finishingmethod_id = (SELECT FM.FINISHINGMETHOD_ID FROM FINISHINGMETHOD FM WHERE FM.CODE = '*')
           and cpld.startdate = ( select max(costpricelistdetail.startdate) from costpricelistdetail
                                  where
                                      costpricelistdetail.costpricelist_id = costpricelistID
                                  and costpricelistdetail.product_id = productID
                                  and costpricelistdetail.sizedefinition_id = (SELECT SZ.SIZEDEFINITION_ID FROM SIZEDEFINITION SZ WHERE SZ.CODE = '*')
                                  and costpricelistdetail.finishingmethod_id = (SELECT FM.FINISHINGMETHOD_ID FROM FINISHINGMETHOD FM WHERE FM.CODE = '*')
                                  and costpricelistdetail.startdate <= trunc(sysdate) ) )
, 0)
into result
  from dual;
high_priority := high_priority + 1;
exit when result <> 0 OR high_priority > low_priority;
end loop; ---- 1 ----

return result ;
end F_PRICEINTERNALMERCHANDIZE;
/
create or replace function F_PriceRepair_details
(customerid in         customer.customer_id%type ,
 repairtypeid in repairtype.repairtype_id%type  ,
 pricedate in          pricelistpercustomer.dateactive%type,
 PiecesOrMinute in number )  -- 1 : price per pieces 2: price per minute
return varchar2 is
 npriority          pricelistpercustomer.priority%type;
 maxpriority        pricelistpercustomer.priority%type;
 maxstartdate2      customerrepairprice.startdate%type;
 result             varchar2(30);
begin
begin
 select max(priority) into maxpriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
             and   pricelistpercustomer.pricetype = 6  -- this means repair price
             and pricelistpercustomer.dateactive <= pricedate
             and pricelistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then maxpriority := 999;
 if maxpriority is null then maxpriority := 999; end if;
end;
begin
 select min(priority) into npriority from pricelistpercustomer
             where pricelistpercustomer.customer_id = customerid
             and   pricelistpercustomer.pricetype = 6
             and pricelistpercustomer.dateactive <= pricedate
             and pricelistpercustomer.dateinactive >= pricedate ;
-- exception when no_data_found then npriority := 999 ;
 if npriority is null then npriority := 999; end if;
end;
while npriority <= maxpriority loop ---------------------------------------------------
begin
     select case PiecesOrMinute
                 when 1 then ( GetFormattedPriceDetails(grp.startdate, SUM(grp.price)))
                      when 2 then ( GetFormattedPriceDetails(grp.startdate, SUM(grp.priceperminute)))
                           end
           into result
              from generalrepairprice grp, generalpricelist, pricelistpercustomer
              where
                      pricelistpercustomer.customer_id = customerid
                  and pricelistpercustomer.pricetype = 6 -- this means repair price
                  and pricelistpercustomer.priority = npriority
                  and
                      pricelistpercustomer.generalpricelist_id = generalpricelist.generalpricelist_id
                  and generalpricelist.pricetype = 6
                  and generalpricelist.active = 'Y'
                  and
                      generalpricelist.generalpricelist_id = grp.generalpricelist_id
                  and grp.repairtype_id = repairtypeid
                  and grp.startdate = (select max(generalrepairprice.startdate)
                                              from generalrepairprice
                                                   where generalrepairprice.repairtype_id = repairtypeid
                                                   and generalrepairprice.generalpricelist_id = grp.generalpricelist_id
                                                   and generalrepairprice.startdate <= pricedate)
                                  group by grp.generalpricelist_id, grp.startdate ;
     exception when no_data_found then result := null;
                 when others then result := null ;
end;
 npriority := npriority + 1 ;
end loop ;   -----------------------------------------------------------------------------------
if result is null
then
begin
select max(customerrepairprice.startdate)
       into maxstartdate2
           from customerrepairprice
                where customerrepairprice.customer_id = customerid
                      and customerrepairprice.repairtype_id = repairtypeid
                          and customerrepairprice.startdate <= pricedate ;
        select
           case PiecesOrMinute
                 when 1 then ( GetFormattedPriceDetails(maxstartdate2, SUM(cupri.price)))
                      when 2 then ( GetFormattedPriceDetails(maxstartdate2, SUM(cupri.priceperminute)))
                           end
           into result
              from customerrepairprice cupri
                 where cupri.customer_id = customerid
                       and cupri.repairtype_id = repairtypeid
                           and cupri.startdate = maxstartdate2;
       exception when no_data_found then result := null;
                 when others then result := null ;
end ;
else
   result := concatenate(result, '  0  0');
end if;
  return result ;
exception
when no_data_found then return null ;
when others then return null;
end F_PriceRepair_details ;
/
create or replace function F_PriceWash_benchmark
(generalpricelistid in        numeric,
 productid in         product.product_id%type ,
 sizedefinitionid in  sizedefinition.sizedefinition_id%type ,
 finishingmethodid in finishingmethod.finishingmethod_id%type,
 REPORTPARAMID in numeric,
 period_type in varchar2  -- W: week, M: month
 )
return real is
 result  real ;
 period_year numeric ;
 period_value numeric ;

begin

select rp.number_value1,
       ( Case period_type when 'W' then rp.number_value3
                else rp.number_value5 end )
  into period_year, period_value
from reportparam rp
       where rp.reportparam_id = REPORTPARAMID ;
select coalesce(
(
select gwp.price from generalwashprice gwp
       where gwp.generalpricelist_id = generalpricelistid
                and gwp.product_id = productid
                and gwp.sizedefinition_id = sizedefinitionid
                and gwp.finishingmethod_id = finishingmethodid
                and gwp.startdate = (
                                    select max(generalwashprice.startdate)from generalwashprice
                                    where generalwashprice.generalpricelist_id = gwp.generalpricelist_id
                                          and generalwashprice.product_id = gwp.product_id
                                          and generalwashprice.sizedefinition_id = gwp.sizedefinition_id
                                          and generalwashprice.finishingmethod_id = gwp.finishingmethod_id
    and YEAR(generalwashprice.startdate) * 100 +
        ( Case period_type when 'W'
             then GETISOWEEK(generalwashprice.startdate)
                  else MONTH(generalwashprice.startdate)
                       end ) <= period_year * 100 + period_value
                       )
), (
 select gwp.price from generalwashprice gwp  -- size *
       where gwp.generalpricelist_id = generalpricelistid
                and gwp.product_id = productid
                and gwp.sizedefinition_id = ( select sz.sizedefinition_id from sizedefinition sz where sz.code = '*' )
                and gwp.finishingmethod_id = finishingmethodid
                and gwp.startdate = (
                                    select max(generalwashprice.startdate)from generalwashprice
                                    where generalwashprice.generalpricelist_id = gwp.generalpricelist_id
                                          and generalwashprice.product_id = gwp.product_id
                                          and generalwashprice.sizedefinition_id = gwp.sizedefinition_id
                                          and generalwashprice.finishingmethod_id = gwp.finishingmethod_id
    and YEAR(generalwashprice.startdate) * 100 +
        ( Case period_type when 'W'
             then GETISOWEEK(generalwashprice.startdate)
                  else MONTH(generalwashprice.startdate)
                       end ) <= period_year * 100 + period_value
                       )
), (
 select gwp.price from generalwashprice gwp  -- size *, fm *
       where gwp.generalpricelist_id = generalpricelistid
                and gwp.product_id = productid
                and gwp.sizedefinition_id = ( select sz.sizedefinition_id from sizedefinition sz where sz.code = '*' )
                and gwp.finishingmethod_id = ( select fm.finishingmethod_id from finishingmethod fm where fm.code = '*')
                and gwp.startdate = (
                                    select max(generalwashprice.startdate)from generalwashprice
                                    where generalwashprice.generalpricelist_id = gwp.generalpricelist_id
                                          and generalwashprice.product_id = gwp.product_id
                                          and generalwashprice.sizedefinition_id = gwp.sizedefinition_id
                                          and generalwashprice.finishingmethod_id = gwp.finishingmethod_id
    and YEAR(generalwashprice.startdate) * 100 +
        ( Case period_type when 'W'
             then GETISOWEEK(generalwashprice.startdate)
                  else MONTH(generalwashprice.startdate)
                       end ) <= period_year * 100 + period_value
                       )
), 0) into result from dual ;

return (result);
end F_PriceWash_benchmark;
/
create or replace function F_ProductDeliveryDays
(productlistpercustomerid in productdeliveryday.productlistpercustomer_id%type,
languagesid languages.language_id%type)
return  varchar2 is
  result   varchar2(7);
begin
result := '' ;
for vCsr in
    ( select substr(description,0,1) daydesc from day_desc , productdeliveryday
            where day_desc.day_id = productdeliveryday.day_id
            and productdeliveryday.productlistpercustomer_id = productlistpercustomerid
            and day_desc.language_id = languagesid
     )
 loop
     begin
     if  vCsr.daydesc is not null then
         result:= concatenate(result,vCsr.daydesc);
     end if;
     exception
     when others then null;
     end;
end loop;
dbms_output.put_line(result);
return(Result);
--exception when no_data_found then return 'zz';
end F_ProductDeliveryDays;
/
create or replace function F_PURCHASEPRICE (
	supplierID		supplier.supplier_id%type,
	productID			product.product_id%type,
	sizeID				sizedefinition.sizedefinition_id%type,
	crtDate				date
) return number is
  price supplierproductprice.purchaseprice%type:=0;
begin
  for vCrs in (select spp.purchaseprice
								from supplierproduct s, productsizepersupproduct pss, supplierproductprice spp,
                  sizedefinition szi
								where s.supplierproduct_id = pss.supplierproduct_id and
											s.supplierproduct_id = spp.supplierproduct_id and
											s.supplier_id = supplierID and
											pss.product_id = productID and
                      szi.sizedefinition_id = pss.sizedefinition_id and
											(  pss.sizedefinition_id = sizeID
                         or
                         pss.sizedefinition_id = (select sz.sizedefinition_id
                         from sizedefinition sz
                         where sz.code = '*')
                       ) and
											trunc(spp.startdate) <= crtDate
                order by szi.code desc, spp.startdate desc) loop
		price:=vCrs.purchaseprice;
		exit;
	end loop;
  return price;
end F_PURCHASEPRICE;
/
create or replace function F_RDNCORRECTED(
       fp_packingnote_id in packingnote.packingnote_id%type)
return varchar2 is
 a varchar2(250);
  cursor get_correctedRDN is
     select distinct  pn.notenumber,to_char(to_char(pn.deliverydate,'dd.mm.yyyy'))deliverydate
from clientdeliverynote cdn, clientdeliverynote cdn2, packingnote pn
where cdn.correctionclientdelnote_id=cdn2.clientdeliverynote_id
      and cdn2.packingnote_id=pn.packingnote_id
      and cdn.packingnote_id=fp_packingnote_id
     order by pn.notenumber;
  result varchar2(255);
begin

  result := '-1';
  for res_rec in get_correctedRDN loop
    if (result = '-1') then
      begin
        a:=concatenate3(res_rec.notenumber,'  ', res_rec.deliverydate);
      result:= concatenate('', a);
      end ;
    else
      if (length(result) < 250) then
        begin
        a:=concatenate3(res_rec.notenumber,'  ', res_rec.deliverydate);
        result := concatenate3(result, ',', a);
        end;
      else
        result := result || '... ';
      end if;
    end if;
  end loop;
  if (result = '-1') then
    result := '-';
  end if;
  return(result);
end F_RDNCORRECTED;
/
create or replace function F_RepairPrice(customerid     in customer.customer_id%type,
                                         repairtypeid   in repairtype.repairtype_id%type,
                                         pricedate      in pricelistpercustomer.dateactive%type,
                                         PiecesOrMinute in number) -- 1 : price per pieces 2: price per minute
 return number is
  npriority     pricelistpercustomer.priority%type;
  maxpriority   pricelistpercustomer.priority%type;
  maxstartdate2 customerrepairprice.startdate%type;
  result        number;
begin
  begin
    select max(customerrepairprice.startdate)
      into maxstartdate2
      from customerrepairprice
     where customerrepairprice.customer_id = customerid
       and customerrepairprice.repairtype_id = repairtypeid
       and customerrepairprice.startdate <= pricedate;
    select case PiecesOrMinute
             when 1 then
              cupri.price
             when 2 then
              cupri.priceperminute
           end
      into result
      from customerrepairprice cupri
     where cupri.customer_id = customerid
       and cupri.repairtype_id = repairtypeid
       and cupri.startdate = maxstartdate2;
  exception
    when no_data_found then
      result := null;
    when others then
      result := null;
  end;
  if result is null then
    begin
      select max(priority)
        into maxpriority
        from pricelistpercustomer
       where pricelistpercustomer.customer_id = customerid
         and pricelistpercustomer.pricetype = 6 -- this means repair price
         and pricelistpercustomer.dateactive <= pricedate
         and pricelistpercustomer.dateinactive >= pricedate;
      if maxpriority is null then
        maxpriority := 999;
      end if;
    end;
    begin
      select min(priority)
        into npriority
        from pricelistpercustomer
       where pricelistpercustomer.customer_id = customerid
         and pricelistpercustomer.pricetype = 6
         and pricelistpercustomer.dateactive <= pricedate
         and pricelistpercustomer.dateinactive >= pricedate;
      if npriority is null then
        npriority := 999;
      end if;
    end;
    while npriority <= maxpriority loop
      ---------------------------------------------------
      begin
        select case PiecesOrMinute
                 when 1 then
                  grp.price
                 when 2 then
                  grp.priceperminute
               end
          into result
          from generalrepairprice grp,
               generalpricelist,
               pricelistpercustomer
         where pricelistpercustomer.customer_id = customerid
           and pricelistpercustomer.pricetype = 6 -- this means repair price
           and pricelistpercustomer.priority = npriority
           and pricelistpercustomer.generalpricelist_id =
               generalpricelist.generalpricelist_id
           and generalpricelist.pricetype = 6
           and generalpricelist.active = 'Y'
           and generalpricelist.generalpricelist_id =
               grp.generalpricelist_id
           and grp.repairtype_id = repairtypeid
           and grp.startdate =
               (select max(generalrepairprice.startdate)
                  from generalrepairprice
                 where generalrepairprice.repairtype_id = repairtypeid
                   and generalrepairprice.generalpricelist_id =
                       grp.generalpricelist_id
                   and generalrepairprice.startdate <= pricedate)
         group by grp.generalpricelist_id,
                  grp.startdate,
                  grp.price,
                  grp.priceperminute;
      exception
        when no_data_found then
          result := null;
        when others then
          result := null;
      end;
      npriority := npriority + 1;
    end loop; -----------------------------------------------------------------------------------
  end if;
  return result;
exception
  when no_data_found then
    return null;
  when others then
    return null;
end F_RepairPrice;
/
create or replace function F_ReplacementSalesPrice
( reportparamID in numeric,
 generalpricelistid in        numeric,
 productid in         product.product_id%type ,
 sizedefinitionid in  sizedefinition.sizedefinition_id%type
 )
return real is
 result  real ;
 sizeStarID numeric;
 EvalPeriod numeric;
 priceType numeric;

begin

select rp.number_value3*100+rp.number_value4 -- start period
 into EvalPeriod from reportparam rp
            where rp.reportparam_id = reportparamID ;

select rp.number_value1
       into priceType from reportparam rp
            where rp.reportparam_id = reportparamID ;

select sz.sizedefinition_id into sizeStarID from sizedefinition sz where sz.code = '*' ;

select
case priceType when 1 -- replacement
     then
coalesce(
( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizedefinitionid
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizedefinitionid
                                and YEAR(generalreplacementprice.startdate)*100+GETISOWEEK(generalreplacementprice.startdate) <= EvalPeriod )
), ( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizeStarID
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizeStarID
                                and YEAR(generalreplacementprice.startdate)*100+GETISOWEEK(generalreplacementprice.startdate) <= EvalPeriod )
), 0)
   when 2  -- sales
        then
coalesce(
( select gsp.price from generalsalesprice gsp
         where gsp.generalpricelist_id = generalpricelistid
         and gsp.product_id = productid
         and gsp.sizedefinition_id = sizedefinitionid
         and gsp.startdate = ( select max(generalsalesprice.startdate) from generalsalesprice
                                where generalsalesprice.generalpricelist_id = generalpricelistid
                                and generalsalesprice.product_id = productid
                                and generalsalesprice.sizedefinition_id = sizedefinitionid
                                and YEAR(generalsalesprice.startdate)*100+GETISOWEEK(generalsalesprice.startdate) <= EvalPeriod )
), ( select gsp.price from generalsalesprice gsp
         where gsp.generalpricelist_id = generalpricelistid
         and gsp.product_id = productid
         and gsp.sizedefinition_id = sizeStarID
         and gsp.startdate = ( select max(generalsalesprice.startdate) from generalsalesprice
                                where generalsalesprice.generalpricelist_id = generalpricelistid
                                and generalsalesprice.product_id = productid
                                and generalsalesprice.sizedefinition_id = sizeStarID
                                and YEAR(generalsalesprice.startdate)*100+GETISOWEEK(generalsalesprice.startdate) <= EvalPeriod )
), 0)
      when 3  -- supplier
        then
coalesce(
( select max(sprice.purchaseprice)
  from productsizepersupproduct pszspp, supplierproductprice sprice, supplierproduct sprd
  where pszspp.product_id = productid
  and pszspp.sizedefinition_id = sizedefinitionid
  and pszspp.supplierproduct_id = sprd.supplierproduct_id
      and sprd.supplier_id = generalpricelistid
  and pszspp.supplierproduct_id = sprice.supplierproduct_id
  and sprice.startdate = ( select max(supplierproductprice.startdate) from supplierproductprice
                           where supplierproductprice.supplierproduct_id = sprice.supplierproduct_id
                           and YEAR(supplierproductprice.startdate)*100+GETISOWEEK(supplierproductprice.startdate) <= EvalPeriod )
), ( select max(sprice.purchaseprice)
     from productsizepersupproduct pszspp, supplierproductprice sprice, supplierproduct sprd
     where pszspp.product_id = productid
     and pszspp.sizedefinition_id = sizeStarID
     and pszspp.supplierproduct_id = sprd.supplierproduct_id
         and sprd.supplier_id = generalpricelistid
     and pszspp.supplierproduct_id = sprice.supplierproduct_id
     and sprice.startdate = ( select max(supplierproductprice.startdate) from supplierproductprice
                              where supplierproductprice.supplierproduct_id = sprice.supplierproduct_id
                              and YEAR(supplierproductprice.startdate)*100+GETISOWEEK(supplierproductprice.startdate) <= EvalPeriod )
), 0)
end
into result from dual ;

return coalesce(result, 0);
end F_ReplacementSalesPrice;
/
create or replace function F_REPLACEMENT_INTERNAL_PRICE
(
 generalpricelistid in        numeric,
 productid in         numeric,
 sizedefinitionid in  numeric
 )
return real is
 result  real ;
 sizeStarID numeric;

begin

select sz.sizedefinition_id into sizeStarID from sizedefinition sz where sz.code = '*' ;

select
coalesce(
( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizedefinitionid
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizedefinitionid
                                and generalreplacementprice.startdate <= trunc(sysdate) )
), ( select grp.price from generalreplacementprice grp
         where grp.generalpricelist_id = generalpricelistid
         and grp.product_id = productid
         and grp.sizedefinition_id = sizeStarID
         and grp.startdate = ( select max(generalreplacementprice.startdate) from generalreplacementprice
                                where generalreplacementprice.generalpricelist_id = generalpricelistid
                                and generalreplacementprice.product_id = productid
                                and generalreplacementprice.sizedefinition_id = sizeStarID
                                and generalreplacementprice.startdate <= trunc(sysdate) )
), 0)
into result
     from dual ;

return result;
end F_REPLACEMENT_INTERNAL_PRICE;
/
create or replace function f_replacement_price(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)
    return number is
    price                  customerreplacementprice.price%type;
    price_found_yn         varchar2(1);
    price_start_date       customerreplacementprice.startdate%type;
    result_code            number;
    result_desc            varchar2(1);
    price_list_type        varchar2(1);
    price_list_code        generalpricelist.code%type;
    price_list_desc        generalpricelist.description%type;
    price_found            boolean;
    price_not_relevant     boolean;
    lv_size                sizedefinition.sizedefinition_id%type;
    lv_finishingmethod     finishingmethod.finishingmethod_id%type;
    i                      number;
    dummy                  number;
    lv_pricedate           date;
    lv_pricelist_type      varchar2(1);
    lv_price               customerreplacementprice.price%type;
    lv_price_start_date    customerreplacementprice.startdate%type;
    lv_generalpricelistid       generalreplacementprice.generalpricelist_id%type;
    lv_pricelist_code           generalpricelist.code%type;
    lv_pricelist_desc           generalpricelist.description%type;
    lv_productlistpercustomerid productlistpercustomer.productlistpercustomer_id%type;
    lv_billingmethod            productlistpercustomer.billingmethod%type;
    lv_typeofmerchandise        product.typeofmerchandise%type;
    lv_inventorybillingtype     productlistpercustomer.inventorybillingtype%type;
    type tcsr                   is ref cursor;
    vcsr                        tcsr;
    vpricelistpercust           tcsr;

  begin -- main replacement
    /* ------------------------ i n i t i a l i s a t i o n ------------------------------------------------------*/
    price_found            := false;
    price_not_relevant     := false;
    price                  := null;
    price_found_yn         := 'N';
    price_start_date       := null;
    result_code            := null;
    result_desc            := null;
    price_list_type        := null;
    price_list_code        := null;
    price_list_desc        := null;

    if pricedate is null then
      select sysdate into lv_pricedate from dual;
    else
      lv_pricedate := pricedate;
    end if;
    lv_size := sizedefinitionid;
    lv_finishingmethod := finishingmethodid;
    if (customerid is null) or (productid is null) or (sizedefinitionid is null) then
      result_code := 8; -- error in parameters
    end if;
    i := 1;
    -- start outer loop on exact match, size * etc.
    /* ############################ o u t e r l o o p ############################################################*/
    while (i < 5) and (result_code is null) and (not price_found) and
          (not price_not_relevant) loop
      open vpricelistpercust for
        select pricelistpercustomer.generalpricelist_id
          from pricelistpercustomer
         where pricelistpercustomer.customer_id = customerid
           and pricelistpercustomer.pricetype = 3 -- replacement price
           and pricelistpercustomer.dateactive <= lv_pricedate
           and pricelistpercustomer.dateinactive >= lv_pricedate
         order by pricelistpercustomer.priority;
      fetch vpricelistpercust
        into lv_generalpricelistid;
      -- load billingmethod etc to determine price usage
      lv_billingmethod     := null;
      lv_typeofmerchandise := null;
      open vcsr for
        select plpc.productlistpercustomer_id,
               plpc.billingmethod,
               p.typeofmerchandise,
               plpc.inventorybillingtype
          from productlistpercustomer plpc, product p
         where plpc.customer_id = customerid
           and plpc.product_id = productid
           and p.product_id = productid
           and plpc.sizedefinition_id = lv_size
           and (plpc.finishingmethod_id = lv_finishingmethod or lv_finishingmethod is null)  -- passing null for fm is allowed
           and ((lv_pricedate >= plpc.dateactive and
                 lv_pricedate <= plpc.dateinactive) or i>2)-- only filter on active during 1st 2 iterations
         order by plpc.dateactive desc;
      if vcsr%notfound then
        null;
      else
        fetch vcsr
          into lv_productlistpercustomerid, lv_billingmethod, lv_typeofmerchandise, lv_inventorybillingtype;
        if lv_billingmethod = 4 and lv_inventorybillingtype <> 5 then /*piece rate only and no loss charges*/
          price_not_relevant := true;
          result_code        := 2; -- price not relevant, billing method piece rate only
        end if;
        if lv_typeofmerchandise = 3 then /* disposable / sales only*/
          price_not_relevant := true;
          result_code        := 3; -- price not relevant, disposable or sales only product
        end if;
      end if;
      close vcsr;
      -- start inner loop on pricelistpercustomer
      /* --------------------- i n n e r l o o p ----------------------------------------------------------*/
      while (not vpricelistpercust%notfound) and (not price_found) and
            (not price_not_relevant) loop
        --if not price_found then
        if lv_generalpricelistid is not null then
          -- general price list
          begin
            lv_price            := null;
            lv_price_start_date := null;
            lv_pricelist_type   := 'G'; -- general
            open vcsr for
              select x.*, rownum
                from (select grp.price,
                             grp.startdate,
                             g.code,
                             g.description
                        from generalreplacementprice grp, generalpricelist g
                       where g.generalpricelist_id = lv_generalpricelistid
                         and g.pricetype = 3 -- replacement price
                         and g.active = 'Y'
                         and grp.generalpricelist_id = g.generalpricelist_id
                         and grp.product_id = productid
                         and grp.sizedefinition_id = lv_size
                         and grp.startdate <= lv_pricedate
                         and g.code <> 'GLPL'
                       order by grp.startdate desc) x
               where rownum = 1; -- take first
            fetch vcsr
              into lv_price, lv_price_start_date, lv_pricelist_code, lv_pricelist_desc, dummy;
            close vcsr;
            if lv_price is not null then
              price_found := true;
            end if;
          exception
            when no_data_found then
              null;
            when others then
              null;
          end;
        else  --  generalpricelistid is not null  customer specific pricelist
          begin
            lv_price            := null;
            lv_price_start_date := null;
            lv_pricelist_type   := 'C'; -- customer specific
            open vcsr for
              select x.*, rownum
                from (select cupri.price,
                             cupri.startdate
                        from customerreplacementprice cupri
                       where cupri.customer_id = customerid
                         and cupri.product_id = productid
                         and cupri.sizedefinition_id = lv_size
                         and cupri.startdate <= lv_pricedate
                       order by cupri.startdate desc) x
               where rownum = 1; -- take first
            fetch vcsr
              into lv_price, lv_price_start_date, dummy;
            close vcsr;
            if lv_price is not null then
              price_found := true;
            end if;
          end; -- else
        end if; -- end if generalpricelistid is not null
        fetch vpricelistpercust
          into lv_generalpricelistid; -- continue with next pricelistpercustomer
      end loop; -- end while not vpricelistpercust%notfound
      /* --------------- e n d   i n n e r l o o p ----------------------------------------------------------*/
      if (not price_found) and (not price_not_relevant) then
        /* iterations:
           1 = with plpc active and passed size
           2 = with plpc active and size *.             skipped when passed size was *
           3 = with plpc inactive and passed size.      skipped when active plpc was found
           4 = with plpc inactive and size *            skipped when passed size was *
        */
        i := i + 1;
        if i = 2 then --  select sizedefinition_id for '*' code
          select sizedefinition.sizedefinition_id
            into lv_size
            from sizedefinition
           where sizedefinition.code = '*';
          if lv_size = sizedefinitionid -- if in iteration 1 was size * already tried, because size * was passed.
            then i := i + 1;  -- skip iteration 2
          end if;
        end if;
        if i = 3 then -- select original size again and try for an inactive plpc
          if lv_productlistpercustomerid is not null
            then i := 5; -- don't search further
            else lv_size := sizedefinitionid;
          end if;
        end if;
        if i = 4 then --  select sizedefinition_id for '*' code try again for inactive plpc
          select sizedefinition.sizedefinition_id
            into lv_size
            from sizedefinition
           where sizedefinition.code = '*';
          if lv_size = sizedefinitionid -- in iteration 3 was size * already tried, because size * was passed.
            then i := i + 1;  -- skip iteration 4
          end if;
        end if;
      end if;
    end loop; -- end while i < 5
    /* ##################### E N D   O U T E R L O O P ############################################################*/
    if price_found then
      price            := lv_price;
      price_found_yn   := 'y';
      price_start_date := lv_price_start_date;
      result_code      := '0';
      result_desc      := 'y';--decode_error('y' || to_char(result_code));
      price_list_type  := lv_pricelist_type;
      price_list_code  := lv_pricelist_code;
      if (lv_pricelist_type = 'g' and lv_pricelist_desc is not null)
        then price_list_desc := lv_pricelist_desc;
        else price_list_desc := 'customer specific.';
      end if;
    else
      if result_code is null then -- no price found
        result_code := 1;
      end if;
      result_desc := 'y';--decode_error('n' || result_code);
      price       := 0;
    end if;
return price;
end f_replacement_price;
/
create or replace function F_Replacement_Price_ILS(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)
    return number is
    price                  customerreplacementprice.price%type;
    price_found_yn         varchar2(1);
    price_start_date       customerreplacementprice.startdate%type;
    result_code            number;
    result_desc            varchar2(1);
    price_list_type        varchar2(1);
    price_list_code        generalpricelist.code%type;
    price_list_desc        generalpricelist.description%type;
    price_found            boolean;
    price_not_relevant     boolean;
    lv_size                sizedefinition.sizedefinition_id%type;
    lv_finishingmethod     finishingmethod.finishingmethod_id%type;
    i                      number;
    dummy                  number;
    lv_pricedate           date;
    lv_pricelist_type      varchar2(1);
    lv_price               customerreplacementprice.price%type;
    lv_price_start_date    customerreplacementprice.startdate%type;
    lv_generalpricelistid       generalreplacementprice.generalpricelist_id%type;
    lv_pricelist_code           generalpricelist.code%type;
    lv_pricelist_desc           generalpricelist.description%type;
    lv_productlistpercustomerid productlistpercustomer.productlistpercustomer_id%type;
    lv_billingmethod            productlistpercustomer.billingmethod%type;
    lv_typeofmerchandise        product.typeofmerchandise%type;
    lv_inventorybillingtype     productlistpercustomer.inventorybillingtype%type;
    type Tcsr                   is ref cursor;
    Vcsr                        Tcsr;
    VPriceListperCust           Tcsr;

  begin -- main replacement
    /* ------------------------ I N I T I A L I S A T I O N ------------------------------------------------------*/
    price_found            := false;
    price_not_relevant     := false;
    price                  := null;
    price_found_yn         := 'N';
    price_start_date       := null;
    result_code            := null;
    result_desc            := null;
    price_list_type        := null;
    price_list_code        := null;
    price_list_desc        := null;

    if pricedate is null then
      select sysdate into lv_pricedate from dual;
    else
      lv_pricedate := pricedate;
    end if;
    lv_size := sizedefinitionid;
    lv_finishingmethod := finishingmethodid;
    if (customerid is null) OR (productid is null) OR (sizedefinitionid is null) then
      result_code := 8; -- error in parameters
    end if;
    i := 1;
    -- start outer loop on exact match, size * etc.
    /* ############################ O U T E R L O O P ############################################################*/
    while (i < 5) and (result_code is null) and (not price_found) and
          (not price_not_relevant) loop
      open VPriceListperCust for
        Select pricelistpercustomer.generalpricelist_id
          from pricelistpercustomer
         where pricelistpercustomer.customer_id = customerid
           and pricelistpercustomer.pricetype = 3 -- replacement price
           and pricelistpercustomer.dateactive <= lv_pricedate
           and pricelistpercustomer.dateinactive >= lv_pricedate
         order by pricelistpercustomer.priority;
      fetch VPriceListperCust
        into lv_generalpricelistid;
      -- load billingmethod etc to determine price usage
      lv_billingmethod     := null;
      lv_typeofmerchandise := null;
      open Vcsr for
        select plpc.productlistpercustomer_id,
               plpc.billingmethod,
               p.typeofmerchandise,
               plpc.inventorybillingtype
          from productlistpercustomer plpc, product p
         where plpc.customer_id = customerid
           and plpc.product_id = productid
           and p.product_id = productid
           and plpc.sizedefinition_id = lv_size
           and (plpc.finishingmethod_id = lv_finishingmethod or lv_finishingmethod is null)  -- passing null for FM is allowed
           and ((lv_pricedate >= plpc.dateactive and
                 lv_pricedate <= plpc.dateinactive) or i>2)-- only filter on active during 1st 2 iterations
         order by plpc.dateactive desc;
      if Vcsr%notfound then
        null;
      else
        fetch Vcsr
          into lv_productlistpercustomerid, lv_billingmethod, lv_typeofmerchandise, lv_inventorybillingtype;
        if lv_billingmethod = 4 and lv_inventorybillingtype <> 5 then /*piece rate only and no loss charges*/
          price_not_relevant := true;
          result_code        := 2; -- Price not relevant, billing method piece rate only
        end if;
        if lv_typeofmerchandise = 3 then /* disposable / sales only*/
          price_not_relevant := true;
          result_code        := 3; -- Price not relevant, disposable or sales only product
        end if;
      end if;
      close Vcsr;
      -- start inner loop on pricelistpercustomer
      /* --------------------- I N N E R L O O P ----------------------------------------------------------*/
      while (not VPriceListperCust%notfound) and (not price_found) and
            (not price_not_relevant) loop
        --if not price_found then
        if lv_generalpricelistid is not null then
          -- general price list
          begin
            lv_price            := null;
            lv_price_start_date := null;
            lv_pricelist_type   := 'G'; -- general
            open Vcsr for
              select x.*, rownum
                from (select grp.price,
                             grp.startdate,
                             g.code,
                             g.description
                        from generalreplacementprice grp, generalpricelist g
                       where g.generalpricelist_id = lv_generalpricelistid
                         and g.pricetype = 3 -- replacement price
                         and g.active = 'Y'
                         and grp.generalpricelist_id = g.generalpricelist_id
                         and grp.product_id = productid
                         and grp.sizedefinition_id = lv_size
                         and grp.startdate <= lv_pricedate
                         and g.code <> 'GLPL'
                       order by grp.startdate desc) x
               where rownum = 1; -- take first
            fetch Vcsr
              into lv_price, lv_price_start_date, lv_pricelist_code, lv_pricelist_desc, dummy;
            close Vcsr;
            if lv_price is not null then
              price_found := true;
            end if;
          exception
            when no_data_found then
              null;
            when others then
              null;
          end;
        else  --  generalpricelistid is not null  customer specific pricelist
          begin
            lv_price            := null;
            lv_price_start_date := null;
            lv_pricelist_type   := 'C'; -- customer specific
            open Vcsr for
              select x.*, rownum
                from (select cupri.price,
                             cupri.startdate
                        from customerreplacementprice cupri
                       where cupri.customer_id = customerid
                         and cupri.product_id = productid
                         and cupri.sizedefinition_id = lv_size
                         and cupri.startdate <= lv_pricedate
                       order by cupri.startdate desc) x
               where rownum = 1; -- take first
            fetch Vcsr
              into lv_price, lv_price_start_date, dummy;
            close Vcsr;
            if lv_price is not null then
              price_found := true;
            end if;
          end; -- else
        end if; -- end if generalpricelistid is not null
        fetch VPriceListperCust
          into lv_generalpricelistid; -- continue with next pricelistpercustomer
      end loop; -- end while not VPriceListperCust%notfound
      /* --------------- E N D   I N N E R L O O P ----------------------------------------------------------*/
      if (not price_found) and (not price_not_relevant) then
        /* iterations:
           1 = with plpc active and passed size
           2 = with plpc active and size *.             Skipped when passed size was *
           3 = with plpc inactive and passed size.      Skipped when active plpc was found
           4 = with plpc inactive and size *            Skipped when passed size was *
        */
        i := i + 1;
        if i = 2 then --  select sizedefinition_id for '*' code
          select sizedefinition.sizedefinition_id
            into lv_size
            from sizedefinition
           where sizedefinition.code = '*';
          if lv_size = sizedefinitionid -- if in iteration 1 was size * already tried, because size * was passed.
            then i := i + 1;  -- skip iteration 2
          end if;
        end if;
        if i = 3 then -- select original size again and try for an inactive plpc
          if lv_productlistpercustomerid is not null
            then i := 5; -- don't search further
            else lv_size := sizedefinitionid;
          end if;
        end if;
        if i = 4 then --  select sizedefinition_id for '*' code try again for inactive plpc
          select sizedefinition.sizedefinition_id
            into lv_size
            from sizedefinition
           where sizedefinition.code = '*';
          if lv_size = sizedefinitionid -- in iteration 3 was size * already tried, because size * was passed.
            then i := i + 1;  -- skip iteration 4
          end if;
        end if;
      end if;
    end loop; -- end while i < 5
    /* ##################### E N D   O U T E R L O O P ############################################################*/
    if price_found then
      price            := lv_price;
      price_found_yn   := 'Y';
      price_start_date := lv_price_start_date;
      result_code      := '0';
      result_desc      := 'Y';--decode_error('Y' || to_char(result_code));
      price_list_type  := lv_pricelist_type;
      price_list_code  := lv_pricelist_code;
      if (lv_pricelist_type = 'G' and lv_pricelist_desc is not null)
        then price_list_desc := lv_pricelist_desc;
        else price_list_desc := 'Customer Specific.';
      end if;
    else
      if result_code is null then -- no price found
        result_code := 1;
      end if;
      result_desc := 'Y';--decode_error('N' || result_code);
      price       := 0;
    end if;
return price;
end F_Replacement_Price_ILS;
/
create or replace function F_RestockingPrice
(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,
 merchandise in       product.typeofmerchandise%type)
return number is
 begin

 if merchandise is null then return 0; end if;
 if sizedefinitionid is null then return 0; end if;
 if productid is null then return 0; end if;
 if merchandise is null then return 0; end if;

 if merchandise <> 3 then
   if finishingmethodid is null then return 0; end if;
   return pack_price.Wash_Price(customerid, productid, sizedefinitionid, finishingmethodid, pricedate);
 else
   return pack_price.Sales_Price(customerid, productid, sizedefinitionid, pricedate);
 end if;

end F_RestockingPrice ;
/
create or replace function F_RestockingPrice_ang
(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,
 merchandise in       product.typeofmerchandise%type)
return number is

 billmeth productlistpercustomer.billingmethod%type;
 rentprice varchar2(20);
 result number;

 begin

 if merchandise is null then return 0; end if;
 if sizedefinitionid is null then return 0; end if;
 if productid is null then return 0; end if;
 if merchandise is null then return 0; end if;

 begin
  select min(prdcu.billingmethod)
  into billmeth
  from productlistpercustomer prdcu
  where pricedate >= prdcu.dateactive
    and pricedate <= prdcu.dateinactive
    and prdcu.customer_id = customerid
    and prdcu.product_id = productid
    and prdcu.sizedefinition_id = sizedefinitionid
    and prdcu.finishingmethod_id = finishingmethodid;
  exception when no_data_found then null;
 end;

 if billmeth is not null then
   if billmeth = 2 then
     return pack_price.Rent_Price(customerid, productid, sizedefinitionid, finishingmethodid, trunc(sysdate),0);
   end if;
 end if;

 if merchandise <> 3 then
   if finishingmethodid is null then return 0; end if;
   return pack_price.Wash_Price(customerid, productid, sizedefinitionid, finishingmethodid, pricedate);
 else
   return pack_price.Sales_Price(customerid, productid, sizedefinitionid, pricedate);
 end if;

end F_RestockingPrice_ang ;
/
create or replace function F_ROUTEFILTER(
  customerid          customer.customer_id%type,
  weareremploymentid  weareremployment.weareremployment_id%type,
  rpno1               reportparam.number_value1%type,
  rpno2               reportparam.number_value2%type)
  return number is
  result customer.customer_id%type;
  type Tcsr is ref cursor ;
  Vcsr Tcsr;
begin

  if rpno1 = 0 and rpno2 = 999999 then return 1; end if;
  if weareremploymentid = -1 then
    begin
      open Vcsr for
      select rs.customer_id
      from routestop rs, route r
      where rs.customer_id = customerid
        and rs.route_id = r.route_id
        and r.routenumber between rpno1 and rpno2;
      fetch Vcsr into result;
      if Vcsr%found then return 1;
      else return 0; end if;
    end;
  else
/*    begin
      open Vcsr for
      select rs.customer_id
      from routestop rs, route r
      where rs.customer_id = customerid
        and rs.route_id = r.route_id
        and rs.deliverypoint_id = weareremploymentid
        and r.routenumber between rpno1 and rpno2;
      fetch Vcsr into result;
      if Vcsr%found then return 1;
      else
        begin
          open Vcsr for
          select rs.customer_id
          from routestop rs, route r
          where rs.customer_id = customerid
            and rs.route_id = r.route_id
            and rs.deliverypoint_id is null
            and r.routenumber between rpno1 and rpno2;
          fetch Vcsr into result;
          if Vcsr%found then return 1;
          else return 0; end if;
        end;
      end if;
      end;*/
      if weareremploymentid is null then
        begin
          open Vcsr for
          select rs.customer_id
          from routestop rs, route r
          where rs.customer_id = customerid
            and rs.route_id = r.route_id
            and rs.deliverypoint_id is null
            and r.routenumber between rpno1 and rpno2;
          fetch Vcsr into result;
          if Vcsr%found then return 1;
          else return 0; end if;
        end;
      else
        begin
          open Vcsr for
          select rs.customer_id
          from routestop rs, route r
          where rs.customer_id = customerid
            and rs.route_id = r.route_id
            and rs.deliverypoint_id = weareremploymentid
            and r.routenumber between rpno1 and rpno2;
          fetch Vcsr into result;
          if Vcsr%found then return 1;
          else return 0; end if;
        end;
      end if;
  end if;

end F_ROUTEFILTER;
/
create or replace function F_ROUTEID (
customerid  in   numeric
) return numeric
is
routeid numeric;
aux numeric;

begin

  select count( distinct route.routenumber) into aux
       from routestop rs, route
            where rs.customer_id = customerid
                  and rs.route_id = route.route_id  ;

select
       case when aux = 1 then ( select min(route.route_id)
                                  from routestop rs, route
                                    where rs.customer_id = customerid
                                          and rs.route_id = route.route_id )
            when aux > 1 then -1 -- Multiple
            when aux = 0 then -2  -- No rute
        end
  into routeid
from customer cu
where cu.customer_id = customerid ;

return routeid;

end F_ROUTEID;
/
create or replace function f_routeidmats (
customerid  in   numeric
) return numeric
is
routeid numeric;
aux numeric;
begin
  select count( distinct route.routenumber) into aux
       from routestop rs, route
            where rs.customer_id = customerid
                  and rs.route_id = route.route_id  ;
select
       case when aux = 1 then ( select min(route.route_id)
                                  from routestop rs, route
                                    where rs.customer_id = customerid
                                          and rs.route_id = route.route_id )
            when aux > 1 then ( select min(route.route_id)
                                  from routestop rs, route
                                    where rs.customer_id = customerid
                                          and rs.route_id = route.route_id )
            when aux = 0 then -1 -- no rute
        end
  into routeid
from customer cu
where cu.customer_id = customerid;
return routeid;
end f_routeidmats;
/
create or replace function F_SDays(
                  Vstatementnumber varchar2,
                  days1 integer, days2 integer,
                  sDate varchar2,--date type not used - is not working
                  eDate varchar2 --date type not used - is not working
                  ) return number is
  invNr           number(30,0);
  var1            number(28,6);
  startDate         date;
  endDate           date;
begin
  invNr := to_number(Vstatementnumber);
  --also putting this var into sql statement is not working
  startDate := to_date(sDate, 'dd-mm-yyyy');
  endDate := to_date(eDate, 'dd-mm-yyyy');
  if (startDate is null or endDate is null) then
     --agging method 1
    select sum(s.amount) into var1 from invoiceheader i, statementline s
    where i.invoicenumber = invNr
    and i.invoiceheader_id = s.invoiceheader_id
    and i.documenttype = 2
    and s.debitcredit ='D'
    and i.invoicedate - s.transactiondate < days1
    and i.invoicedate - s.transactiondate >= days2;
    return var1;
  else
     --agging method 2
    -- ALWAYS endDate < startDate
    if (days2 = 0) then
       -- start period
      select sum(s.amount) into var1 from invoiceheader i, statementline s
      where i.invoicenumber = invNr
      and i.invoiceheader_id = s.invoiceheader_id
      and i.documenttype = 2
      and s.debitcredit ='D'
      and trunc(s.transactiondate) > to_date(eDate, 'dd-mm-yyyy');
      return var1;
    end if;
    if (days1 = 999) then
       -- end period
      select sum(s.amount) into var1 from invoiceheader i, statementline s
      where i.invoicenumber = invNr
      and i.invoiceheader_id = s.invoiceheader_id
      and i.documenttype = 2
      and s.debitcredit ='D'
      and trunc(s.transactiondate) <= to_date(sDate, 'dd-mm-yyyy');
      --trunc(startDate);
      return var1;
    end if;
    -- middle period
    select sum(s.amount) into var1 from invoiceheader i, statementline s
    where i.invoicenumber = invNr
    and i.invoiceheader_id = s.invoiceheader_id
    and i.documenttype = 2
    and s.debitcredit ='D'
    and trunc(s.transactiondate) >= to_date(sDate, 'dd-mm-yyyy')
    and trunc(s.transactiondate) < to_date(eDate, 'dd-mm-yyyy');
    return var1;
  end if;
end F_SDays;
/
create or replace function F_SHOW_ROUTESTOP
(stopid in                  stop.stop_id%type,
 routestopid in             stop.routestop_id%type,
 plantid in                 plant.plant_id%type)
return number is
  existspn                  number;
  printalldelnotes          systemsetting.value%type;
begin

--  check if the stop was manually added
  if routestopid is null then return 1; end if;
--  check if exists packing note linked to the stop
  -- get the systemsettings
  begin
    printalldelnotes:='Y';
    select ss.value
    into printalldelnotes
    from systemsetting ss
    where ss.plant_id = plantid
      and ss.name = 'ROUTELISTPRINTALLDELNOTES';
    exception when no_data_found then printalldelnotes:='Y';
  end;
  -- check when print all del notes
  if printalldelnotes = 'Y' then
    begin
      select count(*)
      into existspn
      from packingnote pn, stop st, customer c
      where pn.stop_id = st.stop_id
        and st.customer_link_id = c.customer_id
        and st.stop_id = stopid;
      if existspn > 0 then return 1; end if;
    end;
  else
    begin
      select count(*)
      into existspn
      from packingnote pn0
      where pn0.stop_id = stopid
        and not exists
        (select *
         from packingnote pn, stop st, customer c, routecontrol rc, route r
         where pn.stop_id = st.stop_id
           and pn.stop_id = pn0.stop_id
           and pn0.packingnote_id = pn.packingnote_id
           and st.customer_link_id = c.customer_id
           and st.routecontrol_id = rc.routecontrol_id
           and rc.route_id = r.route_id
           and c.delnoteforbulkputupitems = 0
           and r.putupreportpercustomer > 0
           and exists (select * from packingnoteline pnl
               where pnl.putuptype = 1 and pnl.packingnote_id = pn.packingnote_id));
      if existspn > 0 then return 1; end if;
    end;
  end if;
--  check if exists straight even return linked to the stop
  select count(*)
  into existspn
  from straightevenreturn sir
  where sir.stop_id = stopid;
  if existspn > 0 then return 1; end if;
-- check if stop is defined as Get
  select count(*)
  into existspn
  from routestop rs
  where rs.stoptype = 2
    and rs.routestop_id = routestopid;
  if existspn > 0 then return 1; end if;

  return 0;
end F_SHOW_ROUTESTOP;
/
create or replace function F_SHOW_ROUTESTOP_STD
(stopid in                  stop.stop_id%type,
 routestopid in             stop.routestop_id%type,
 stoptype in                routestop.stoptype%type,
 plantid in                 plant.plant_id%type)
return number is
  existspn                  number;
  stopsonroutelist          systemsetting.value%type;
  printalldelnotes          systemsetting.value%type;
begin

  -- get the systemsettings
  begin
    stopsonroutelist:='0';
    select ss.value
    into stopsonroutelist
    from systemsetting ss
    where ss.plant_id = plantid
      and ss.name = 'STOPSONROUTELIST';
    exception when no_data_found then stopsonroutelist:='0';
  end;

/*  if stopsonroutelist = '1' then
    if (routestopid is not null) and stoptype <> 4 then return 1;
    else if stoptype <> 4 then return 0; end if;
    end if;
  end if;*/

  if stopsonroutelist = '1' then
    if (routestopid is not null) and stoptype <> 4 then return 1; end if;
    if (routestopid is null) then return 1; end if;
    if (not(routestopid is not null) and stoptype = 4) then return 0; end if;
  end if;

--  check if the stop was manually added
  if routestopid is null then return 1; end if;
--  check if exists packing note linked to the stop
  -- get the systemsettings
  begin
    printalldelnotes:='Y';
    select ss.value
    into printalldelnotes
    from systemsetting ss
    where ss.plant_id = plantid
      and ss.name = 'ROUTELISTPRINTALLDELNOTES';
    exception when no_data_found then printalldelnotes:='Y';
  end;
  -- check when print all del notes
  if printalldelnotes = 'Y' then
    begin
      select count(*)
      into existspn
      from packingnote pn, stop st, customer c
      where pn.stop_id = st.stop_id
	    and pn.status_id <> 8 --cancel
        and st.customer_link_id = c.customer_id
        and st.stop_id = stopid;
      if existspn > 0 then return 1; end if;
    end;
  else
    begin
      select count(*)
      into existspn
      from packingnote pn0
      where pn0.stop_id = stopid
        and not exists
        (select *
         from packingnote pn, stop st, customer c, routecontrol rc, route r
         where pn.stop_id = st.stop_id
           and pn.stop_id = pn0.stop_id
           and pn0.packingnote_id = pn.packingnote_id
           and st.customer_link_id = c.customer_id
           and st.routecontrol_id = rc.routecontrol_id
           and rc.route_id = r.route_id
           and c.delnoteforbulkputupitems = 0
           and r.putupreportpercustomer > 0
           and exists (select * from packingnoteline pnl
               where pnl.putuptype = 1 and pnl.packingnote_id = pn.packingnote_id));
      if existspn > 0 then return 1; end if;
    end;
  end if;
--  check if exists straight even return linked to the stop
  select count(*)
  into existspn
  from straightevenreturn sir
  where sir.stop_id = stopid;
  if existspn > 0 then return 1; end if;
-- check if stop is defined as Get
  select count(*)
  into existspn
    from stop st
   where st.stoptype = 2
     and st.stop_id = stopid;
  if existspn > 0 then return 1; end if;
  return 0;
end F_SHOW_ROUTESTOP_STD;
/
create or replace FUNCTION F_Spell_Number (p_number IN NUMBER)
RETURN VARCHAR2
AS
TYPE myArray IS TABLE OF VARCHAR2 (255);
l_str myArray
 := myArray ('',
             ' thousand ',
             ' million ',
             ' billion ',
             ' trillion ',
             ' quadrillion ',
             ' quintillion ',
             ' sextillion ',
             ' septillion ',
             ' octillion ',
             ' nonillion ',
             ' decillion ',
             ' undecillion ',
             ' duodecillion ');
l_num      VARCHAR2 (50) DEFAULT TRUNC (p_number);
l_decim    VARCHAR2 (50) DEFAULT trim(to_char(p_number));
l_return   VARCHAR2 (4000);
l_returndec   VARCHAR2 (4000);
commasep char;
commapos pls_integer;
BEGIN
commasep  := substr(to_char(1/2),1,1);
commapos  := instr(l_decim,commasep);
if (commapos > 0)
  then
  l_decim   := SUBSTR (l_decim, commapos+1, length(l_decim)-commapos);
    FOR i IN 1 .. l_str.COUNT
    LOOP
    EXIT WHEN l_num IS NULL;
    IF (SUBSTR (l_num, LENGTH (l_num) - 2, 3) <> 0)
    THEN
     l_return :=
        TO_CHAR (TO_DATE (SUBSTR (l_num, LENGTH (l_num) - 2, 3), 'J'),
                 'Jsp')
        || l_str (i)
        || l_return;
    END IF;
     l_num := SUBSTR (l_num, 1, LENGTH (l_num) - 3);
    END LOOP;
    FOR i IN 1 .. l_str.COUNT
    LOOP
    EXIT WHEN l_decim IS NULL;
    IF (SUBSTR (l_decim, LENGTH (l_decim) - 2, 3) <> 0)
    THEN
     l_returndec :=
        TO_CHAR (TO_DATE (SUBSTR (l_decim, LENGTH (l_decim) - 2, 3), 'J'),
                 'Jsp')
        || l_str (i)
        || l_returndec;
    END IF;
     l_decim := SUBSTR (l_decim, 1, LENGTH (l_decim) - 3);
    END LOOP;
    l_return := l_return || ' comma ' || l_returndec;
  else
    FOR i IN 1 .. l_str.COUNT
    LOOP
    EXIT WHEN l_num IS NULL;
    IF (SUBSTR (l_num, LENGTH (l_num) - 2, 3) <> 0)
    THEN
     l_return :=
        TO_CHAR (TO_DATE (SUBSTR (l_num, LENGTH (l_num) - 2, 3), 'J'),
                 'Jsp')
        || l_str (i)
        || l_return;
    END IF;
     l_num := SUBSTR (l_num, 1, LENGTH (l_num) - 3);
    END LOOP;
end if;
RETURN l_return;
END;
/
create or replace function F_Spell_NumberDE(val in number)
return varchar2
is
v_val varchar2(200);
v_text varchar2(4000);
v_exp_text varchar2(6);
v_teiltext varchar2(200);
commapos pls_integer;
exppos pls_integer;
commasep char;
tsd_stelle pls_integer;
i pls_integer DEFAULT 1;
c char(3);
function get_text(ziffer in varchar2)
return varchar2
is
begin
case trim(ziffer)
    when commasep then return ' Komma';
    when '0' then return ' Null';
    when '1' then return ' Ein';
    when '2' then return ' Zwei';
    when '3' then return ' Drei';
    when '4' then return ' Vier';
    when '5' then return ' Fünf';
    when '6' then return ' Sechs';
    when '7' then return ' Sieben';
    when '8' then return ' Acht';
    when '9' then return ' Neun';
    else return ' Fehler_Text';
    end case;
end;
function get_hunderter_text(ziffer in varchar2)
return varchar2
is
v_text_hunderter varchar2(150);
v_text_zehner varchar2(150);
v_text_einer varchar2(150);
begin
--Hunderter-Stelle
If (substr(ziffer,1,1)!='0') then
   v_text_hunderter := get_text(substr(ziffer,1,1))||'hundert';
   --wenn nachfolgender Einer/Zehner-Wert, dann 'und' ranhängen
   if (substr(ziffer,2,1) != '0' or substr(ziffer,3,1) != '0') then
         v_text_hunderter := v_text_hunderter||'und';
      end if;
   end if;
--nun die Einer
if (substr(ziffer,3,1)!='0') then
     v_text_einer := get_text(substr(ziffer,3,1));
   --wenn im Bereich 10..19, dann Einer-Text auf 4 Stellen beschneiden (Sieben->Sieb|zehn)
   if (substr(ziffer,2,1) = '1') then
     v_text_einer := substr(v_text_einer,1,5);
     end if;
   --wenn Zehner >=20, dann 'und' zwischen Zehner und Einer einfügen
   if (substr(ziffer,2,1) not in ('0','1')) then
     v_text_einer := v_text_einer||'und';
     end if;
   --aus Ein wird hier Eins, wenn kein Zehner vorhanden
   if (substr(ziffer,2,1) = '0' and substr(ziffer,3,1)='1') then
     v_text_einer := v_text_einer||'s';
     end if;
  end if;
--nun die Zehner
if (substr(ziffer,2,1) != '0') then
   v_text_zehner := substr(get_text(substr(ziffer,2,1)),1,5)||'zig';
   end if;
--10 und 20 korrigieren
if (v_text_zehner=' Einzig') then v_text_zehner := ' Zehn'; end if;
if (v_text_zehner=' Zweizig') then v_text_zehner := ' Zwanzig'; end if;
--11 und 12 konvertieren
if (v_text_einer||v_text_zehner=' Ein Zehn') then v_text_zehner := ' Elf'; v_text_einer:= null; end
if;
if (v_text_einer||v_text_zehner=' Zwei Zehn') then v_text_zehner := ' Zwölf'; v_text_einer:= null;
end if;
--Groß/Klein- und Zusammenschreibung abhängig vom vorausgehenden Text einstellen
if ( v_text_hunderter is not null) then
   v_text_zehner := trim(lower(v_text_zehner));
   v_text_einer := trim(lower(v_text_einer));
   end if;
if ( v_text_einer is not null) then
   v_text_zehner := trim(lower(v_text_zehner));
   end if;
return v_text_hunderter||v_text_einer||v_text_zehner;
end;
function get_tausender_text(stelle in pls_integer, val in pls_integer)
return varchar2
is
ret_text varchar2(100);
begin
  case stelle
    when 0 then return null;
    when 1 then ret_text := ' Tausend';
    when 2 then ret_text := ' Million';
    when 3 then ret_text := ' Milliarde';
    when 4 then ret_text := ' Billion';
    when 5 then ret_text := ' Billiarde';
    when 6 then ret_text := ' Trillion';
    when 7 then ret_text := ' Trilliarde';
    when 8 then ret_text := ' Quadrillion';
    when 9 then ret_text := ' Quadrilliarde';
    when 10 then ret_text := ' Quintillion';
    when 11 then ret_text := ' Quintilliarde';
    when 12 then ret_text := ' Sextillion';
    when 13 then ret_text := ' Sextilliarde';
    when 14 then ret_text := ' Septillion';
    when 15 then ret_text := ' Septilliarde';
    when 16 then ret_text := ' Oktillion';
    when 17 then ret_text := ' Oktilliarde';
    when 18 then ret_text := ' Nonillion';
    when 19 then ret_text := ' Nonilliarde';
    when 20 then ret_text := ' Dezillion';
    when 21 then ret_text := ' Dezilliarde';
        else ret_text := ' mal Zehn hoch'||get_hunderter_text(lpad(3*stelle,3,'0'));
    end case;
if (val > 1) then
  ret_text := replace(ret_text,'ion','ionen');
  ret_text := replace(ret_text,'iarde','iarden');
  end if;
return ret_text;
end;
begin
--Null-Wert sofort als 'unbekannt' zuück
if (val is null) then return 'unbekannt'; end if;
--Auslesen des aktuellenDezimalzeichens
commasep:=substr(to_char(1/2),1,1);
--Wert als Text und commapos bestimmen
  v_val      := trim(to_char(val));
commapos  := instr(v_val,commasep);
--Bei Exponentialwert Exp-Teil extrahieren
exppos := instr(v_val,'E');
if (exppos > 0) then
  v_exp_text :=substr(v_val, exppos+1);
  v_val := substr(v_val,1,exppos-1);
  v_val := rtrim(v_val,'0');
  end if;
--Betrag auswerten und String anpassen
if (substr(v_val,1,1)='-') then
  v_text := 'Minus';
  v_val     := substr(v_val,2);
  commapos  := commapos - 1;
  end if;
--String auffüllen auf durch 3 teilbare Stellenzahl mit führenden Nullen
if (commapos < 1) then
  v_val := lpad(v_val, (trunc(length(v_val)/3)+1)*3,'0')||commasep;
  else
  v_val      := lpad(v_val,length(v_val)+(trunc((commapos-1)/3)+1)*3-abs(commapos-1),'0');
  end if;
commapos  := instr(v_val,commasep);
--Vorkommastellen
while (i<=commapos-1) loop
  c := substr(v_val,i,3);
  v_teiltext := get_hunderter_text(c);
  if (v_teiltext is not null) then
    tsd_stelle := trunc((commapos-1-i)/3);
    if (tsd_stelle >1 and v_teiltext=' Eins') then
      v_teiltext:=' Eine';
      end if;
    if (tsd_stelle = 1 and v_teiltext=' Eins') then
      v_teiltext:=' Ein';
      end if;
    v_text := v_text||v_teiltext||get_tausender_text(tsd_stelle, to_number(c));
    end if;
  i := i + 3;
  end loop;
--Vorkomma-Null
if (v_text is null or v_text = 'Minus') then
  v_text:= trim(v_text||' Null');
  end if;
--Nachkommastellen
--wenn Nachkommastellen vorhanden, dann aufzaehlen
if (commapos<length(v_val)) then
  --durchlaufen der Nachkommastellen
  for i in commapos .. length(v_Val) loop
    v_teiltext := get_text(substr(v_val, i,1));
    if v_teiltext=' Ein' then v_teiltext:=' Eins'; end if;
    v_text := v_text||v_teiltext;
    end loop;
  end if;
--wenn Exponentialdarstellung, dann exp-Wert angeben
if (v_exp_text is not null) then
  if (v_text=' Eins') then v_text:=' Ein'; end if;
  v_text := v_text ||' mal Zehn hoch';
   --Betrag auswerten und String anpassen
  if (substr(v_exp_text ,1,1)='-') then
    v_text := v_text || ' Minus';
    end if;
  v_text := v_text || get_hunderter_text(substr(v_exp_text,2));
  end if;
return trim(v_text);
end;
/
create or replace function F_Spell_NumberNL(val in number)
return varchar2
is
v_val varchar2(200);
v_text varchar2(4000);
v_exp_text varchar2(6);
v_teiltext varchar2(200);
commapos pls_integer;
exppos pls_integer;
commasep char;
tsd_stelle pls_integer;
i pls_integer DEFAULT 1;
c char(3);
function get_text(ziffer in varchar2)
return varchar2
is
begin
case trim(ziffer)
    when commasep then return ' EURO';
    when '0' then return ' Nul';
    when '1' then return ' Een';
    when '2' then return ' Twee';
    when '3' then return ' Drie';
    when '4' then return ' Vier';
    when '5' then return ' Vijf';
    when '6' then return ' Zes';
    when '7' then return ' Zeven';
    when '8' then return ' Acht';
    when '9' then return ' Negen';
    else return ' Fouttekst';
    end case;
end;
function get_zehner_text(ziffer in varchar2)
return varchar2
is
v_text_zehner varchar2(150);
v_text_einer varchar2(150);
begin
--nun die Einer
if (substr(ziffer,3,1)!='0') then
     v_text_einer := get_text(substr(ziffer,3,1));
   --wenn im Bereich 10..19, dann Einer-Text auf 4 Stellen beschneiden (Sieben->Sieb|zehn)
   if (substr(ziffer,2,1) = '1') then
     v_text_einer := substr(v_text_einer,1,5);
     end if;
   --wenn Zehner >=20, dann 'und' zwischen Zehner und Einer einfügen
   if (substr(ziffer,2,1) not in ('0','1')) then
     v_text_einer := v_text_einer||'en';
     end if;
   --aus Ein wird hier Eins, wenn kein Zehner vorhanden
   --if (substr(ziffer,2,1) = '0' and substr(ziffer,3,1)='1') then
   --  v_text_einer := v_text_einer||'s';     end if;
end if;
--nun die Zehner
if (substr(ziffer,2,1) != '0') then
   v_text_zehner := substr(get_text(substr(ziffer,2,1)),1,5)||'tig';
   end if;
--10 und 20 30  40 80 korrigieren
if (v_text_zehner=' Eentig') then v_text_zehner := ' Tien'; end if;
if (v_text_zehner=' Tweetig') then v_text_zehner := ' Twintig'; end if;
if (v_text_zehner=' Drietig') then v_text_zehner := ' Dertig'; end if;
if (v_text_zehner=' Viertig') then v_text_zehner := ' Veertig'; end if;
if (v_text_zehner=' Zevetig') then v_text_zehner := ' Zeventig'; end if;
if (v_text_zehner=' Achttig') then v_text_zehner := ' Tachtig'; end if;
if (v_text_zehner=' Negetig') then v_text_zehner := ' Negentig'; end if;
--11,12, 13 und 14 konvertieren
if (v_text_einer||v_text_zehner=' Een Tien') then v_text_zehner := ' Elf'; v_text_einer:= null;
end if;
if (v_text_einer||v_text_zehner=' Twee Tien') then v_text_zehner := ' Twaalf'; v_text_einer:= null;
end if;
if (v_text_einer||v_text_zehner=' Drie Tien') then v_text_zehner := ' Dertien'; v_text_einer:= null;
end if;
if (v_text_einer||v_text_zehner=' Vier Tien') then v_text_zehner := ' Veertien'; v_text_einer:= null;
end if;
--Groß/Klein- und Zusammenschreibung abhängig vom vorausgehenden Text einstellen
   v_text_zehner := trim(lower(v_text_zehner));
   v_text_einer := trim(lower(v_text_einer));
return v_text_einer||v_text_zehner;
end;
function get_hunderter_text(ziffer in varchar2)
return varchar2
is
v_text_hunderter varchar2(150);
v_text_zehner varchar2(150);
v_text_einer varchar2(150);
begin
--Hunderter-Stelle
If (substr(ziffer,1,1)!='0') then
   v_text_hunderter := get_text(substr(ziffer,1,1))||'honderd';
   --wenn nachfolgender Einer/Zehner-Wert, dann 'und' ranhängen
   if (substr(ziffer,2,1) != '0' or substr(ziffer,3,1) != '0') then
         v_text_hunderter := v_text_hunderter||' ';--en';
      end if;
   end if;
v_text_zehner:=get_zehner_text(ziffer);
return v_text_hunderter||v_text_zehner;
end;
function get_tausender_text(stelle in pls_integer, val in pls_integer)
return varchar2
is
ret_text varchar2(100);
begin
  case stelle
    when 0 then return null;
    when 1 then ret_text := ' Duizend';
    when 2 then ret_text := ' Miljoen';
    when 3 then ret_text := ' Miljard';
    when 4 then ret_text := ' Triljoen';
/*    when 5 then ret_text := ' Quadriljoen';
    when 6 then ret_text := ' Trillion';
    when 7 then ret_text := ' Trilliarde';
    when 8 then ret_text := ' Quadrillion';
    when 9 then ret_text := ' Quadrilliarde';
    when 10 then ret_text := ' Quintillion';
    when 11 then ret_text := ' Quintilliarde';
    when 12 then ret_text := ' Sextillion';
    when 13 then ret_text := ' Sextilliarde';
    when 14 then ret_text := ' Septillion';
    when 15 then ret_text := ' Septilliarde';
    when 16 then ret_text := ' Oktillion';
    when 17 then ret_text := ' Oktilliarde';
    when 18 then ret_text := ' Nonillion';
    when 19 then ret_text := ' Nonilliarde';
    when 20 then ret_text := ' Dezillion';
    when 21 then ret_text := ' Dezilliarde';*/
        else ret_text := ' maal tien hoog'||get_hunderter_text(lpad(3*stelle,3,'0'));
    end case;
if (val > 1) then
  ret_text := replace(ret_text,'ion','ionen');
  ret_text := replace(ret_text,'iarde','iarden');
  end if;
return ret_text;
end;
begin--====================================MAIN BODY
--Null-Wert sofort als 'unbekannt' zuück
if (val is null) then return 'onbekend'; end if;
--Auslesen des aktuellenDezimalzeichens
commasep:=substr(to_char(1/2),1,1);
--Wert als Text und commapos bestimmen
  v_val   := trim(to_char(val));
commapos  := instr(v_val,commasep);
--Bei Exponentialwert Exp-Teil extrahieren
exppos := instr(v_val,'E');
if (exppos > 0) then
  v_exp_text :=substr(v_val, exppos+1);
  v_val := substr(v_val,1,exppos-1);
  v_val := rtrim(v_val,'0');
  end if;
--Betrag auswerten und String anpassen
if (substr(v_val,1,1)='-') then
  v_text := 'Minus';
  v_val     := substr(v_val,2);
  commapos  := commapos - 1;
  end if;
--String auffüllen auf durch 3 teilbare Stellenzahl mit führenden Nullen
if (commapos < 1) then
  v_val := lpad(v_val, (trunc(length(v_val)/3)+1)*3,'0')||commasep;
  else
  v_val      := lpad(v_val,length(v_val)+(trunc((commapos-1)/3)+1)*3-abs(commapos-1),'0');
  end if;
commapos  := instr(v_val,commasep);
--Vorkommastellen
while (i<=commapos-1) loop
  c := substr(v_val,i,3);
  v_teiltext := get_hunderter_text(c);
  if (v_teiltext is not null) then
    tsd_stelle := trunc((commapos-1-i)/3);
    if (tsd_stelle >1 and v_teiltext=' Een') then
      v_teiltext:=' Een';
      end if;
    if (tsd_stelle = 1 and v_teiltext=' Een') then
      v_teiltext:=' Een';
      end if;
    v_text := v_text||v_teiltext||get_tausender_text(tsd_stelle, to_number(c));
    end if;
  i := i + 3;
  end loop;
--Vorkomma-Null
if (v_text is null or v_text = 'Minus') then
  v_text:= trim(v_text||' Nul');
  end if;
--Nachkommastellen
--wenn Nachkommastellen vorhanden, dann aufzaehlen
if (commapos < length(v_val))
then   begin
  if (substr(v_val, commapos+1, 1) = '0')
    then v_teiltext := ' EURO NUL '||get_zehner_text('0'||substr(v_val, commapos+1,length(v_Val)-commapos))||' EUROCENT ';
    else v_teiltext := ' EURO '||get_zehner_text('0'||substr(v_val, commapos+1,length(v_Val)-commapos))||' EUROCENT ';
  end if;
    end;
else v_teiltext := ' EURO NUL EUROCENT ';
end if;
    v_text := v_text||v_teiltext;
--wenn Exponentialdarstellung, dann exp-Wert angeben
if (v_exp_text is not null) then
  if (v_text=' Een') then v_text:=' Eens'; end if;
  v_text := v_text ||' Maal tien hoog';
   --Betrag auswerten und String anpassen
  if (substr(v_exp_text ,1,1)='-') then
    v_text := v_text || ' Minus';
    end if;
  v_text := v_text || get_hunderter_text(substr(v_exp_text,2));
end if;
return trim(UPPER(v_text));
end;--====================================MAIN BODY
/
create or replace function F_STOCKPRICE
  (pricetype in          number, -- 1-replacement price list, 2-actual purchase price, 3-sales price
   productid in          product.product_id%type ,
   sizedefinitionid in   sizedefinition.sizedefinition_id%type,
   generalpricelistid in generalpricelist.generalpricelist_id%type,
   pricedate in          pricelistpercustomer.dateactive%type,
   plantid in            plant.plant_id%type default null)
return number is

   pragma udf;

   type Tcsr is ref cursor ;
   Vcsr Tcsr;
   price                number;
   sizestarid           sizedefinition.sizedefinition_id%type;
   ssEXCHANGERATEDETERMINATION number default 0;
begin

  if productid is null then return 0; end if;
  if sizedefinitionid is null then return 0; end if;
  if pricedate is null then return 0; end if;

  select s.sizedefinition_id into sizestarid
  from sizedefinition s where s.code = '*';

  if (plantid is not null) then
    select ss.value
    into ssEXCHANGERATEDETERMINATION
    from systemsetting ss
    where ss.name = 'EXCHANGERATEDETERMINATION'
    and ss.plant_id = plantid;
  end if;

  price:=0;
  case pricetype
    when 1 then --replacement price list
      begin
        if generalpricelistid is null then return 0; end if;
        open Vcsr for
        select grp.price * (case when (ssEXCHANGERATEDETERMINATION =0)
                                 then cr.exchangerate
                                 else (select cer.exchangerate
                                      from currencyexchangerate cer
                                      where cer.basecurrency_id = cr.currency_id
                                      and cer.startdate = ( select max(c.startdate) from currencyexchangerate c
                                                            where c.basecurrency_id = cr.currency_id
                                                            and c.startdate <=sysdate)) end)
        from generalreplacementprice grp, generalpricelist gp, currency cr, sizedefinition sz
        where grp.generalpricelist_id = gp.generalpricelist_id
          and grp.product_id = productid
          and (grp.sizedefinition_id = sizedefinitionid or grp.sizedefinition_id = sizestarid)
          and grp.startdate <= pricedate
          and gp.currency_id = cr.currency_id
          and gp.generalpricelist_id = generalpricelistid
          and sz.sizedefinition_id = grp.sizedefinition_id
        order by sz.code desc, grp.startdate desc;
        fetch Vcsr into price;
        exception when no_data_found then
    null;
      end;
    when 2 then --actual purchase price
      begin
        open Vcsr for
        select spp.purchaseprice * (case when (ssEXCHANGERATEDETERMINATION =0)
                                     then cr.exchangerate
                                     else (select cer.exchangerate
                                          from currencyexchangerate cer
                                          where cer.basecurrency_id = cr.currency_id
                                          and cer.startdate = ( select max(c.startdate) from currencyexchangerate c
                                                                where c.basecurrency_id = cr.currency_id
                                                                and c.startdate <=sysdate)) end)
        from product p, supplierproduct sp, ProductSizePerSupProduct sps,
        supplierproductprice spp, supplier s, currency cr, sizedefinition sz
        where p.product_id = sps.product_id
          and sp.supplierproduct_id = sps.supplierproduct_id
          and sp.supplier_id = p.supplier_id
          and sp.supplierproduct_id = spp.supplierproduct_id
          and (sps.sizedefinition_id = sizedefinitionid or sps.sizedefinition_id = sizestarid)
          and sps.product_id = productid
          and spp.startdate <= pricedate
          and p.supplier_id = s.supplier_id
          and s.currency_id = cr.currency_id
          and sz.sizedefinition_id = sps.sizedefinition_id
        order by sz.code desc, spp.startdate desc;
        fetch Vcsr into price;
        exception when no_data_found then null;
      end;
    when 3 then--sales price
      begin
        if generalpricelistid is null then return 0; end if;
        open Vcsr for
        select grp.price * (case when (ssEXCHANGERATEDETERMINATION =0)
                                 then cr.exchangerate
                                 else (select cer.exchangerate
                                      from currencyexchangerate cer
                                      where cer.basecurrency_id = cr.currency_id
                                      and cer.startdate = ( select max(c.startdate) from currencyexchangerate c
                                                            where c.basecurrency_id = cr.currency_id
                                                            and c.startdate <=sysdate)) end)
        from generalsalesprice grp, generalpricelist gp, currency cr, sizedefinition sz
        where grp.generalpricelist_id = gp.generalpricelist_id
          and grp.product_id = productid
          and (grp.sizedefinition_id = sizedefinitionid or grp.sizedefinition_id = sizestarid)
          and grp.startdate <= pricedate
          and gp.currency_id = cr.currency_id
          and gp.generalpricelist_id = generalpricelistid
          and sz.sizedefinition_id = grp.sizedefinition_id
        order by sz.code desc, grp.startdate desc;
        fetch Vcsr into price;
        exception when no_data_found then null;
      end;
    end case;

  close Vcsr;
  return price;
end F_STOCKPRICE;
/
create or replace function f_StringToHexToBase64
  (fp_legalname     legalentity.legalname%type,
   fp_vatnumber     legalentity.vatnumber%type,
   fp_invoicedate   invoiceheader.invoicedate%type,
   fp_prebillamount invoiceheader.prebillamount%type,
   fp_vatamount     invoiceheader.totalamountexclvat%type
  ) return clob is
  --version 1.0
  lv_raw clob;
  lv_hex clob;
  lv_base64 clob;
begin
  lv_hex := '01';
  lv_hex := lv_hex || ltrim(TO_CHAR(LENGTH(fp_legalname),'0X'));
  select RAWTOHEX(fp_legalname) into lv_raw from dual;
  lv_hex := lv_hex || lv_raw;
  lv_hex := lv_hex || '02';
  lv_hex := lv_hex || ltrim(TO_CHAR(LENGTH(fp_vatnumber),'0X'));
  select RAWTOHEX(fp_vatnumber) into lv_raw from dual;
  lv_hex := lv_hex || lv_raw;
  lv_hex := lv_hex || '03';
  lv_hex := lv_hex || ltrim(TO_CHAR(LENGTH(to_char(fp_invoicedate, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')),'0X'));
  select RAWTOHEX(to_char(fp_invoicedate, 'YYYY-MM-DD"T"HH24:MI:SS"Z"')) into lv_raw from dual;
  lv_hex := lv_hex || lv_raw;
  lv_hex := lv_hex || '04';
  lv_hex := lv_hex || ltrim(TO_CHAR(LENGTH(castNumberAsVarcharWithFormat(fp_prebillamount, 'FM999999.009')),'0X'));
  select RAWTOHEX(castNumberAsVarcharWithFormat(fp_prebillamount, 'FM999999.009')) into lv_raw from dual;
  lv_hex := lv_hex || lv_raw;
  lv_hex := lv_hex || '05';
  lv_hex := lv_hex || ltrim(TO_CHAR(LENGTH(castNumberAsVarcharWithFormat(fp_vatamount, 'FM999999.009')),'0X'));
  select RAWTOHEX(castNumberAsVarcharWithFormat(fp_vatamount, 'FM999999.009')) into lv_raw from dual;
  lv_hex := lv_hex || lv_raw;
  lv_base64 := base64encode(utl_raw.cast_to_raw(UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW(lv_hex))));
  return lv_base64;
exception
  when others then
    return null;
end f_StringToHexToBase64;
/
create or replace function f_sumrqa(p_reportparam_id reportparam.reportparam_id%type,
                                    p_adjustmentdate reportparam.date_value2%type,
                                    p_deliverydate deliveryhistory.deliverydate%type,
                                    p_code product.code%type)
RETURN NUMBER IS
suma number:=0;
begin
select sum(rqa.quantity) into suma from rentalqtyadjustment rqa
where rqa.adjustmentdate <= p_adjustmentdate
and rqa.productlistperdistribpoint_id in(
    select plpd.productlistperdistribpoint_id
    from  --  productlistpercustomer plpc,
     productlistperdistribpoint plpd, product pr, deliveryhistory dh,
     distributionpoint dp, department de, customer cu, reportparam rp--, languages lan
where plpd.product_id = pr.product_id and plpd.distributionpoint_id = dp.distributionpoint_id
      and dp.department_id = de.department_id and de.customer_id = cu.customer_id
      --and plpc.product_id = pr.product_id and plpc.customer_id = cu.customer_id
      and dh.customer_link_id = cu.customer_id and dh.distributionpoint_link_id = dp.distributionpoint_id
      and dh.department_link_id = de.department_id and dh.product_link_id = pr.product_id
      and dh.deliverydate >= rp.date_value1 and dh.deliverydate <= rp.date_value2
      and cu.customernumber >= rp.number_value1 and cu.customernumber <= rp.number_value2
      --and rqa.adjustmentdate <= rp.date_value2
      and rp.reportparam_id = p_reportparam_id
      --and dh.deliverydate=p_deliverydate
      and pr.code = p_code);
if suma is null then suma:=0;
end if;
return suma;
end f_sumrqa;
/
create or replace function F_TAXRATE
(customerid in        customer.customer_id%type ,
 productid in         product.product_id%type ,
 country in           country.country_id%type,
 taxdate in           taxgroup.startdatetaxrate%type)
return number is
 startdate            taxgroup.startdatetaxrate%type;
 oldvatrate           taxgroup.oldtaxrate%type;
 vatrate              taxgroup.taxrate%type;
 taxcode              taxgroup.code%type;
 countryActive        number;
 begin

 if productid is null then return 0; end if;
 if customerid is null then return 0; end if;

-- get active country
/*  select c.country_id
  into countryActive
  from country c where c.definetax = 'Y';*/

-- get the vat corresponding to product and active country
 begin
   select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
   into taxcode, startdate, oldvatrate, vatrate
   from producttax p, taxgroup t, country c
   where p.product_id = productid
     and p.country_id = c.country_id
     and p.taxgroup_id = t.taxgroup_id
     and c.definetax = 'Y';
 exception when others then return 0;
 end;
   if countryActive = country then
   begin
     if taxdate >= startdate then
       return vatrate;
     else
       return oldvatrate;
     end if;
     end;
   end if;

-- get the vat corresponding to country report
 begin
 select t.code, t.startdatetaxrate, t.oldtaxrate, t.taxrate
 into taxcode, startdate, oldvatrate, vatrate
 from taxgroup t
 where t.country_id = country
   and t.code = taxcode;
 exception when others then return 0;
 end;
 if taxdate >= startdate then
   return vatrate;
 else
   return oldvatrate;
 end if;

end F_TAXRATE ;
/
create or replace function F_turnoverfortaxes
(turnovergroupID    turnovergroup.turnovergroup_id%type,
plantID             plant.plant_id%type)
return number is
  result   turnovergroup.taxgroup_id%type;
  taxdef      systemsetting.value%type;
  i integer;
begin
select systemsetting.value  into taxdef
from systemsetting
where systemsetting.name='TAXDEFINITION'
and systemsetting.plant_id = plantID;
if taxdef='US' then
  select count(states_id) into i  from states where states.turnovergroup_id = turnovergroupID;
else
  select count(taxgroup_id) into i  from taxgroup where taxgroup.turnovergroup_id = turnovergroupID;
end if;
if i=0 then result := 0; -- turnovergroup is not used for taxes
else result:= 1; -- turnovergroup is used for taxes
end if;
return(result);
end F_turnoverfortaxes;
/
create or replace function F_WBR_ACTUALAMOUNT
  (ismonth                 number,
   costcenterid            distributionpoint.costcenter_id%type,
   nMinYear                budget.year%type,
   nMaxYear                budget.year%type,
   nmonthweek1             budget.week%type,
   nmonthweek2             budget.week%type
  ) return  number is
  LVnAmount number;
begin

  if ismonth = 1 then
    begin
      select sum(cci.amount)
      into LVnAmount
      from costcenter cc, invoiceheader ih, invoiceline il,
        invoicelinetype ilt, costcenterinvoiceline cci, invoicefrequency ivf
      where cc.customer_id = ih.deltocustomer_link_id
        and ih.invoiceheader_id = il.invoiceheader_id
        and il.invoicelinetype_id = ilt.invoicelinetype_id
        and ilt.type in (2,5)
        and il.invoiceline_id = cci.invoiceline_id
        and cc.costcenter_id = cci.costcenter_link_id
        and ih.invoicefrequency_id = ivf.invoicefrequency_id
        and ivf.invoicefrequencynumber > 100  and ivf.invoicefrequencynumber < 200
        and cc.costcenter_id = costcenterid
--        and ih.endyear = nMinYear
--        and ih.endmonth between nmonthweek1 and nmonthweek2;
        and ih.endyear*100+ih.endmonth between (nMinYear*100+nmonthweek1) and (nMaxYear*100+nmonthweek2);
    exception when others then return 0;
    end;
  else
    begin
      select sum(cri.amount)
      into LVnAmount
      from costcenter cc, invoiceheader ih, invoiceline il,
        invoicelinetype ilt, costreportinfo cri, invoicefrequency ivf
      where cc.customer_id = ih.deltocustomer_link_id
        and ih.invoiceheader_id = il.invoiceheader_id
        and il.invoicelinetype_id = ilt.invoicelinetype_id
        and ilt.type in (2,5)
        and il.invoiceline_id = cri.invoiceline_id
        and cc.costcenter_id = cri.costcenter_link_id
        and ih.invoicefrequency_id = ivf.invoicefrequency_id
        and ivf.invoicefrequencynumber <= 100
        and cc.costcenter_id = costcenterid
--        and cri.year = nMinYear
--        and cri.week between nmonthweek1 and nmonthweek2;
        and cri.year*100+cri.week between (nMinYear*100+nmonthweek1) and (nMaxYear*100+nmonthweek2);
    exception when others then return 0;
    end;
  end if;

  if LVnAmount is null then return 0;
  else return LVnAmount;
  end if;

end F_WBR_ACTUALAMOUNT;
/
create or replace function F_WBR_BUDGETAMOUNT
  (ismonth                 number,
   costcenterid            distributionpoint.costcenter_id%type,
   nMinYear                budget.year%type,
   nMaxYear                budget.year%type,
   nmonthweek1             budget.week%type,
   nmonthweek2             budget.week%type
  ) return  number is
  LVnAmount number;
begin

  if ismonth = 1 then
      begin
        select sum(bg.amount)
        into LVnAmount
        from distributionpoint dp, budget bg
        where dp.department_id = bg.department_link_id
          and dp.costcenter_id = costcenterid
--          and bg.year = nMinYear
--          and bg.month between nmonthweek1 and nmonthweek2
          and bg.year*100+bg.month between (nMinYear*100+nmonthweek1) and (nMaxYear*100+nmonthweek2)
          and bg.week = 0;
      exception when others then return 0;
      end;
  else
      begin
        select sum(bg.amount)
        into LVnAmount
        from distributionpoint dp, budget bg
        where dp.department_id = bg.department_link_id
          and dp.costcenter_id = costcenterid
--          and bg.year = nMinYear
--          and bg.week between nmonthweek1 and nmonthweek2
          and bg.year*100+bg.week between (nMinYear*100+nmonthweek1) and (nMaxYear*100+nmonthweek2)
          and bg.month = 0;
      exception when others then return 0;
      end;
  end if;

  if LVnAmount is null then return 0;
  else return LVnAmount;
  end if;

end F_WBR_BUDGETAMOUNT;
/
create or replace function F_WOL_MODIFICATIONS(
       fp_workorderline_id in workorderline.workorderline_id%type,
       fp_language_id in languages.language_id%type)
return varchar2 is
  cursor get_modification is
    select mod.description
      from workorderlinemodification wolm, modification_desc mod
     where mod.modification_id = wolm.modification_id
       and wolm.workorderline_id = fp_workorderline_id
       and mod.language_id = fp_language_id
     order by wolm.sequencenumber;
  result varchar2(255);
begin
  result := '-1';
  for res_rec in get_modification loop
    if (result = '-1') then
      result := concatenate('(', res_rec.description);
    else
      if (length(result) < 240) then
        result := concatenate3(result, ',', res_rec.description);
      else
        result := result || '... ';
      end if;
    end if;
  end loop;
  if (result = '-1') then
    result := '-';
  else
    result := concatenate(result, ')');
  end if;
  return(result);
end F_WOL_MODIFICATIONS;
/
create or replace function GETABSDAYNUMBER(dt in date) return integer is
	monday date := to_date('08/09/2003', 'dd/mm/yyyy');
	diff int;
begin

	diff:=to_char(monday, 'd');
	if (diff = 1) then
		return to_char(dt, 'd');
	else
		if (to_char(dt, 'd') = 1) then return 7;
		else return to_char(dt, 'd') - 1;
		end if;
	end if;

end GETABSDAYNUMBER;
/
create or replace function getABSMaxDate return date is
begin
  return to_date('31/12/2099', 'DD/MM/YYYY');
end;
/
create or replace function getABSMinDate return date is
begin
  return to_date('01/01/1900', 'DD/MM/YYYY');
end;
/
create or replace function GetActualWearerBudget(
  wearerEmploymentID      weareremployment.weareremployment_id%type,
  referenceDateMin        date,
  referenceDateMax        date
) return wearerbudgettransaction_type is
  wbtID                   wearerbudgettransaction.wearerbudgettransaction_id%type:=0;
  actualBudgetValue       wearerbudgettransaction.actualbudget%type:=0;
  actualReaservedValue    wearerbudgettransaction.actualreserved%type:=0;
  actualReservedAdjustment wearerbudgettransaction.reservedadjustment%type:=0;
begin

  if (referenceDateMin = referenceDateMax) then
    for vCursor in (select wbt.wearerbudgettransaction_id, wbt.actualbudget, wbt.actualreserved, wbt.reservedadjustment
                    from wearerbudgettransaction wbt
                    where wbt.weareremployment_id = wearerEmploymentID and
                          wbt.transactiondate <= referenceDateMin and
                          wbt.wearerbudgettransaction_id = (select max(wbt.wearerbudgettransaction_id)
                                                            from wearerbudgettransaction wbt
                                                            where wbt.weareremployment_id = wearerEmploymentID and
                                                                  wbt.transactiondate <= referenceDateMin)) loop
      wbtID:=vCursor.wearerbudgettransaction_id;
      actualBudgetValue:=vCursor.actualbudget;
      actualReaservedValue:= vCursor.actualreserved;
      actualReservedAdjustment:=vCursor.Reservedadjustment;
      exit;
    end loop;
  else
    for vCursor in (select wbt.wearerbudgettransaction_id, wbt.actualbudget, wbt.actualreserved, wbt.reservedadjustment
                    from wearerbudgettransaction wbt
                    where wbt.weareremployment_id = wearerEmploymentID and
                          wbt.transactiondate between referenceDateMin and referenceDateMax
                    order by wbt.wearerbudgettransaction_id desc) loop
      wbtID:=vCursor.wearerbudgettransaction_id;
      actualBudgetValue:=vCursor.actualbudget;
      actualReaservedValue:= vCursor.actualreserved;
      actualReservedAdjustment:=vCursor.Reservedadjustment;
      exit;
    end loop;
  end if;

  return wearerbudgettransaction_type(wbtID, actualBudgetValue, actualReaservedValue, actualReservedAdjustment);
end;
/
create or replace function getamericanweeknumber(fp_date in date) return number is
begin
  return cast(to_char(fp_date, 'IW') as numeric);
end getamericanweeknumber;
/
create or replace function getaveragedeliverylastweeks(fpdistributionpoint_id distributionpoint.distributionpoint_id%type,
                                                       fpproduct_id           product.product_id%type,
                                                       fpsizedefinition_id    sizedefinition.sizedefinition_id%type,
                                                       fpfinishingmethod_id   finishingmethod.finishingmethod_id%type,
                                                       fpreferencedate        date default sysdate,
                                                       fpaveragetype          integer default 1,
                                                       fplanguage_id          number) return number is
  -- Version 2.02
  -- Declaration variables
  lvresult                      number := 0;
  lvplpc_id                     number := 0;
  lvcust_id                     number := 0;
  lvweeks_active                number := 0;
  lvfirstday_fpreferencedate    date := getfirstdayofweek(trunc(fpreferencedate));
  lvlastday_fpreferencedate     date := getlastdayofweek(trunc(fpreferencedate));
  lv_avg_deliv_last_4_weeks     number := 0;
  lv_avg_per_deliv_last_4_weeks number := 0;

begin
  -- Check parameter
  if (fpaveragetype not in (1, 2)) then
    return - 999;
  end if;
  -- Get cust
 select d.customer_id
   into lvcust_id
   from distributionpoint dp, department d
  where d.department_id = dp.department_id
    and dp.distributionpoint_id = fpdistributionpoint_id;
  -- Get plpc
  select plpc.productlistpercustomer_id
  into   lvplpc_id
  from   productlistpercustomer plpc
  where  plpc.dateactive <= lvfirstday_fpreferencedate
  and    plpc.dateinactive >= lvlastday_fpreferencedate
  and    plpc.customer_id = lvcust_id --Via parameter
  and    plpc.product_id = fpproduct_id -- parameter
  and    plpc.sizedefinition_id = fpsizedefinition_id -- parameter
  and    plpc.finishingmethod_id = fpfinishingmethod_id; -- parameter
-- Determine weeks active from plpc
select (lvfirstday_fpreferencedate -
        greatest(case
                    when getabsdaynumber(plpc.dateactive) <= 3 then
                     getfirstdayofweek(plpc.dateactive) -- count the week for mo/we/tu
                    else
                     getlastdayofweek(plpc.dateactive) + 1 -- don't count the week for th/fr
                  end,
                  lvfirstday_fpreferencedate - 28)) / 7 weeks_active
 into lvweeks_active
  from productlistpercustomer plpc
 where plpc.productlistpercustomer_id = lvplpc_id;

    select decode ( fpaveragetype, 1,
    case max(lvweeks_active)
              when 4 then
               round((sum(x.wk1) + sum(x.wk2) + sum(x.wk3) + sum(x.wk4)) / 4)
              when 3 then
               round((sum(x.wk2) + sum(x.wk3) + sum(x.wk4)) / 3)
              when 2 then
               round((sum(x.wk3) + sum(x.wk4)) / 2)
              when 1 then
               sum(x.wk4)
              else
               0
            end
            , 0 ) avg_delivery_last_4_weeks
            , decode ( fpaveragetype , 2,
           case max(lvweeks_active)
              when 4 then
               round((sum(x.wk1) + sum(x.wk2) + sum(x.wk3) + sum(x.wk4)) /
                     (decode(sum(x.v_wk1) + sum(x.v_wk2) + sum(x.v_wk3) + sum(x.v_wk4), 0, 1,
                             sum(x.v_wk1) + sum(x.v_wk2) + sum(x.v_wk3) + sum(x.v_wk4))))
              when 3 then
               round((sum(x.wk2) + sum(x.wk3) + sum(x.wk4)) /
                     (decode(sum(x.v_wk2) + sum(x.v_wk3) + sum(x.v_wk4), 0, 1,
                             sum(x.v_wk2) + sum(x.v_wk3) + sum(x.v_wk4))))
              when 2 then
               round((sum(x.wk3) + sum(x.wk4)) /
                     (decode(sum(x.v_wk3) + sum(x.v_wk4), 0, 1, sum(x.v_wk3) + sum(x.v_wk4))))
              when 1 then
               round((sum(x.wk4) / (decode(sum(x.v_wk4), 0, 1, sum(x.v_wk4)))))
              else
               0
            end, 0) avg_per_delivery_last_4_weeks
    into lv_avg_deliv_last_4_weeks, lv_avg_per_deliv_last_4_weeks
    from   -- determine active weeks
            (
             select
                    -- Calculate total delivery per week for last 4 weeks
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 28 and
                            lvfirstday_fpreferencedate - 22 then
                        sum(pl.deliveredamount)
                       else
                        0
                     end wk1,
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 21 and
                            lvfirstday_fpreferencedate - 15 then
                        sum(pl.deliveredamount)
                       else
                        0
                     end wk2,
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 14 and
                            lvfirstday_fpreferencedate - 8 then
                        sum(pl.deliveredamount)
                       else
                        0
                     end wk3,
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 7 and
                            lvfirstday_fpreferencedate - 1 then
                        sum(pl.deliveredamount)
                       else
                        0
                     end wk4,
                    -- Calculate total visits per week for last 4 weeks, only when fpaveragetype=2
                    decode ( fpaveragetype , 2,
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 28 and
                            lvfirstday_fpreferencedate - 22 then
                        count(1)
                       else
                        0
                     end, 0) v_wk1,
                    decode ( fpaveragetype , 2, case
                       when p.deliverydate between lvfirstday_fpreferencedate - 21 and
                            lvfirstday_fpreferencedate - 15 then
                        count(1)
                       else
                        0
                     end, 0) v_wk2,
                    decode ( fpaveragetype , 2,
                    case
                       when p.deliverydate between lvfirstday_fpreferencedate - 14 and
                            lvfirstday_fpreferencedate - 8 then
                        count(1)
                       else
                        0
                     end, 0) v_wk3,
                    decode ( fpaveragetype , 2, case
                       when p.deliverydate between lvfirstday_fpreferencedate - 7 and
                            lvfirstday_fpreferencedate - 1 then
                        count(1)
                       else
                        0
                     end, 0) v_wk4,
                     0 weeks_active
             from   packingnote p, packingnoteline pl, status s
             where  s.status_id = p.status_id
             and    pl.packingnote_id = p.packingnote_id
             and    p.distributionpoint_id = fpdistributionpoint_id -- parameter
             and    pl.product_id = fpproduct_id -- parameter
             and    pl.sizedefinition_id = fpsizedefinition_id -- parameter
             and    pl.finishingmethod_id = fpfinishingmethod_id -- parameter
             and    s.code = '30'
             and    p.deliverydate >= lvfirstday_fpreferencedate - 28 -- monday 4 weeks ago
             and    p.deliverydate <= lvfirstday_fpreferencedate - 1 -- until but not including start date of this week.
             group  by p.distributionpoint_id, pl.product_id, pl.sizedefinition_id,
                       pl.finishingmethod_id, p.deliverydate) x;

      -- Determine average to be returned
      if (fpaveragetype = 1) then
        lvresult := lv_avg_deliv_last_4_weeks;
      else
        lvresult := lv_avg_per_deliv_last_4_weeks;
      end if;

  -- Return the result
  if (lvresult < 10) then
    return lvresult;
  else
    return(ceil(lvresult * 0.1) / 0.1);
  end if;

exception
  when no_data_found then
    return 0;
end getaveragedeliverylastweeks;
/
create or replace function getbool(fp_fieldvalue in varchar2) return varchar2 is
/*getbool v 0.1*/
Result              varchar2(5);
begin
    if(upper(fp_fieldvalue) = 'Y') then
      Result := 'TRUE';
     else
    Result := 'FALSE';
   end if;
   return (Result);
end ;
/
create or replace function getDatabaseCode return varchar2 is
  customerCode varchar2(3);
begin
  select code into customerCode from databasesettings;
  return (customerCode);
end getDatabaseCode;
/
create or replace function GETDATEASVARCHARFIXEDFORMAT(
	 date1					reportparam.date_value1%type
) return varchar2 is
begin
	return to_char(date1, 'dd-mm-yyyy');
end;
/
create or replace function getDateDiff(dtDate1 date, dtDate2 date) return integer is
begin
  return dtDate1 - dtDate2;
end;
/
create or replace function getdateforweekyear(fpnday  integer, --The Day number
                                              fpnweek integer, --The week number
                                              fpnyear integer --The year in the format "YYYY"
                                              ) return date is
  lv_nls_territory varchar2(160);
  lv_date          date;

  function getdateforweekyear_old return date is
    lvfirstdaynumber number;
    lvfirstdayofyear date;
  begin
    lvfirstdayofyear := to_date('01-01-' || fpnyear, 'DD-MM-YYYY');
    lvfirstdaynumber := getabsdaynumber(lvfirstdayofyear);
    if getisoweek(lvfirstdayofyear) > 1 then
      lvfirstdaynumber := lvfirstdaynumber - 7;
    end if;
    return trunc(to_date(to_char(fpnyear), 'YYYY'), 'YYYY') +(7 * (fpnweek - 1)) + fpnday - lvfirstdaynumber;
  end getdateforweekyear_old;
begin
  if fpnday is null or fpnweek is null or fpnyear is null then
    return null;
  end if;
  select ds.nls_territory into lv_nls_territory from databasesettings ds;
  if lv_nls_territory in ('AMERICA', 'CANADA', 'AUSTRALIA') then
    select dyw.date_
    into   lv_date
    from   date_yearweekday dyw
    where  dyw.us_year = fpnyear
    and    dyw.us_week = fpnweek
    and    dyw.day = fpnday;
    return lv_date;
  else
    select dyw.date_
    into   lv_date
    from   date_yearweekday dyw
    where  dyw.year = fpnyear
    and    dyw.week = fpnweek
    and    dyw.day = fpnday;
    return lv_date;
  end if;
exception
  when no_data_found then
    return getdateforweekyear_old;
end getdateforweekyear;
/
create or replace function getdateforweekyearSMG(fpnday  integer, --The Day number
                                              fpnweek integer, --The week number
                                              fpnyear integer --The year in the format "YYYY"
                                              ) return date is
  lvdtdate          date;
  lvfirstdaynumber  number;
  --territory         varchar2(40);
  lvfirstdayofyear  date;
  lvfirstweeknumber number;
  lvday             number;
begin
 /* select x.nls_territory into territory from databasesettings x;*/
  lvfirstdayofyear  := to_date('01-01-' || fpnyear, 'DD-MM-yyyy');
  lvfirstweeknumber := getisoweek(lvfirstdayofyear);
  lvfirstdaynumber  := pack_utilities.GetDayNumber(lvfirstdayofyear);
  --to_number(to_char(lvfirstdayofyear, 'D'));
  /*if territory in ('AMERICA', 'CANADA') then
    lvfirstdaynumber  := to_number(to_char(lvfirstdayofyear, 'D'));
    lvday := fpnday + 1;
    if lvfirstdaynumber = 1 then
      lvday := lvday - 7;
    end if;
  else*/
    lvday := fpnday;
 -- end if;*/
  if lvfirstweeknumber > 1 then
    if lvfirstdaynumber > 0 then
      lvfirstdaynumber := lvfirstdaynumber - 7;
    end if;
  end if;
  lvdtdate := trunc(to_date(to_char(fpnyear), 'YYYY'), 'YYYY') + (7 * (fpnweek - 1)) + lvday -
              lvfirstdaynumber;
  return lvdtdate;
end getdateforweekyearSMG;
/
create or replace function getdateforweekyear_US(fpnday  integer, --The Day number
                                              fpnweek integer, --The week number
                                              fpnyear integer --The year in the format "YYYY"
                                              ) return date is
  lvdtdate          date;
  lvfirstdaynumber  number;
  lvfirstdayofyear  date;
  lvfirstweeknumber number;
  lvday             number;
begin
  lvfirstdayofyear  := to_date('01-01-' || fpnyear, 'DD-MM-yyyy');
  lvfirstweeknumber := getisoweek(lvfirstdayofyear);
  lvfirstdaynumber  := to_number(to_char(lvfirstdayofyear, 'D'));
  lvday := fpnday + 1;
  if lvfirstdaynumber = 1 then
    lvday := lvday - 7;
  end if;
  if lvfirstweeknumber > 1 then
    if lvfirstdaynumber > 0 then
      lvfirstdaynumber := lvfirstdaynumber - 7;
    end if;
  end if;
  lvdtdate := trunc(to_date(to_char(fpnyear), 'YYYY'), 'YYYY') + (7 * (fpnweek - 1)) + lvday -
              lvfirstdaynumber;
  return lvdtdate;
end getdateforweekyear_US;
/
create or replace function GetDateForYearMonthDay(
    thisYear      varchar2,
    thisMonth     varchar2,
    thisDay       varchar2
) return date is
begin
  return to_date(thisDay||'/'||thisMonth||'/'||thisYear, 'dd/mm/yyyy');
exception when others then return null;
end GetDateForYearMonthDay;
/
create or replace function getDayAsVarchar(vDate	date) return varchar2 is
begin
	return to_char(vDate, 'dd');
end;
/
create or replace function getDayDescription(dtDate         date,
                                             fp_nlsdatelang varchar2 default null)
  return varchar2 is
begin
  if fp_nlsdatelang is null then
    return to_char(dtDate, 'Day');
  else
    return to_char(dtDate, 'Day', fp_nlsdatelang);
  end if;
end;
/
create or replace function getdaynumber(fp_date in date) return number is
begin
  if fp_date is null then
    return null;
  else
    return trunc(fp_date) - getfirstdayofweek(fp_date) + 1; --to_number(to_char(fp_date, 'D'));
  end if;
end getdaynumber;
/
create or replace function getDeliverySchemeAndRouteCode(fp_customerid customer.customer_id%type)
  return varchar2 is
  lv_deliverycode varchar2(20);
begin

  select   case
           when count(distinct r.routenumber) = 1 then
            max(r.routenumber) || ''
           when count((r.routenumber)) = 0 then
            ''
           else
            'Multiple'
         end
    into lv_deliverycode
      from DELIVERYSCHEMESPERSTOP DSPS,
       ROUTE                  R,
       DELIVERYSCHEME         DS,
       ROUTESTOP              RS
 where DSPS.CUSTOMER_ID = fp_customerid
   and DSPS.ROUTESTOP_ID = RS.ROUTESTOP_ID
   and RS.ROUTE_ID = R.ROUTE_ID
   and DSPS.DELIVERYSCHEME_ID = DS.DELIVERYSCHEME_ID
   and ((trunc(RS.dateactive) <= trunc(sysdate) and
       trunc(RS.dateinactive) > trunc(sysdate)) or
       (trunc(RS.dateactive) > trunc(sysdate) and
       trunc(RS.dateinactive) > trunc(sysdate)));

  return lv_deliverycode;

exception
  when others then
    begin
      return null;
    end;
end getDeliverySchemeAndRouteCode;
/
create or replace function getenddatefullrent(
currentdate                in date,
customerID                 in customer.customer_id%type,
productID                  in product.product_id%type,
sizeID                     in sizedefinition.sizedefinition_id%type,
finishingmethodID          in finishingmethod.finishingmethod_id%type,
daysincircprevissue        in integer   ) return date is
  Result date;
  gv_sizestar sizedefinition.sizedefinition_id%type;
begin
select nvl(s.sizedefinition_id, -1) into gv_sizestar from sizedefinition s where s.code = '*';
for vCursor in(  select b.calculationweeks, 1
  from productlistpercustomer a, residualvaluescheme b
  where a.residualvaluescheme_id = b.residualvaluescheme_id
 	and a.customer_id = customerID
 	and a.product_id = productID
 	and a.sizedefinition_id in ( sizeID, gv_sizestar )
 	and a.finishingmethod_id = finishingmethodID
  union all
  select b.calculationweeks, 2
  from productlistpercustomer a, residualvaluescheme b
  where a.residualvaluescheme_id = b.residualvaluescheme_id
 	and a.customer_id = customerID
 	and a.product_id = productID
 	and a.sizedefinition_id in ( sizeID, gv_sizestar )
  order by 2)loop
   if Vcursor.calculationweeks is not null then
   begin
   Result:= currentdate+(7 * Vcursor.calculationWeeks - daysInCircPrevIssue);
   exit; end;
   end if;
  end loop;
  return(Result);
end getenddatefullrent;
/
create or replace function getfirstdayofweek(vdate date) return date is
begin
  if vdate is null then
    return null;
  else
    return getdateforweekyear(1, getisoweek(vdate), getyearofweek(vdate));
  end if;
end getfirstdayofweek;
/
create or replace function getFirstDeliveryWeekForYear(year      in integer,
                                                       frequency in integer,
                                                       offset    in integer)
  return integer is
  Result        integer;
  firstweek     integer;
  currentyear   integer;
  a             integer;
  w             integer;
  lastweek      integer;
  referenceYear databasesettings.referenceyear%type;
  referenceWeek databasesettings.referenceweek%type;
begin
  select d.referenceyear, d.referenceweek
    into referenceYear, referenceWeek
    from databasesettings d;
  firstWeek   := referenceweek + offset;
  currentYear := referenceYear;
  if year >= referenceyear then
    begin
      while (currentyear < year) loop
        begin
          w           := getweeksinyear(currentyear);
          a           := mod((w - firstweek), frequency);
          firstweek   := frequency - a;
          currentyear := currentyear + 1;
        end;
      end loop;
    end;
  else
    while (currentYear > year) loop
      begin
        currentYear := currentYear - 1;
        w           := getweeksinyear(currentyear);
        lastWeek    := w - (frequency - firstWeek);
        firstweek   := mod(lastweek, frequency);
        if (firstWeek = 0) then
          firstWeek := frequency;
        end if;
      end;
    end loop;
  end if;
  Result := firstweek;
  return(Result);
end getFirstDeliveryWeekForYear;
/
create or replace function GetFormattedPriceDetails (
		FPdate					date,
		FPprice					number
) return varchar2 is
begin
  if fpdate is null or fpprice is null then return null;
  else return concatenate3(to_char(FPdate, 'YYYYMMDD'), '   ', to_char(FPprice, '999999D99999'));
end if;
end;
/
create or replace function gethousenumber(housestring varchar2, leftright varchar2) return varchar2 is
i integer;
n integer;
housenumber varchar2(30);
aux varchar2(30);
begin
i:=1;
n:= length(housestring);
housenumber:='';
aux:='';
 if leftright='l' then
for i in 1..n
loop
aux:= substr(housestring, i, 1);
if aux in ('0','1','2','3','4','5','6','7','8','9') then
housenumber:=housenumber||aux;
else
return housenumber;
end if;
end loop;
else
for i in 0..n
loop
aux:= substr(housestring, n-i, 1);
if aux in ('0','1','2','3','4','5','6','7','8','9') then
housenumber:=housenumber||aux;
else
return housenumber;
end if;
end loop;
end if;
return housenumber;
exception when others then return null;
end gethousenumber;
/
create or replace function GETISOWEEK(VDATE date) return int is
  LV_WEEK          int;
begin
  select
    case
      when DS.NLS_TERRITORY in ('AMERICA', 'CANADA', 'AUSTRALIA') then DYW.US_WEEK
      else DYW.WEEK
      end into LV_WEEK
  from DATE_YEARWEEKDAY DYW, DATABASESETTINGS DS
  where DYW.DATE_ = trunc(VDATE);
  return LV_WEEK;

exception
  when NO_DATA_FOUND then
    return cast(TO_CHAR(trunc(VDATE), 'IW') as numeric);
end GETISOWEEK;
/
create or replace function getlastclientrentdate(fp_clientid     client.client_id%type,
                                                 fp_documenttype invoiceheader.documenttype%type)
  return date is
  --08.2025 ABSN-4830
  lv_maxdate date;
  lv_mindate date;
begin
  select max(ih.enddate)
    into lv_maxdate
    from invoiceheader ih
    join invoiceline il
      on il.invoiceheader_id = ih.invoiceheader_id
    join invoicelineclientrent cr
      on cr.invoiceline_id = il.invoiceline_id
   where cr.client_link_id = fp_clientid
     and ih.documenttype = fp_documenttype
     and ih.status_id = (select s.status_id
                           from status s
                          where s.statustype = 'IN'
                            and s.code = '2') --finalized / settled
     and ih.credited <> 2; --fully credited, restore

 if lv_maxdate is null then
    select min(rr.startdate)
      into lv_mindate
      from residentialrent rr
      join client c
        on c.customer_id = rr.customer_id
     where c.client_id = fp_clientid;
    return lv_mindate;
  else
    return lv_maxdate;
  end if;
end getlastclientrentdate;
/
create or replace function getLastDay(vDate date) return date is
begin
	return last_day(vDate);
end ;
/
create or replace function getLastDayofWeek(vDate date) return date is
begin
 return getdateforweekyear(7,getisoweek(vDate),getyearofweek(vDate));
end;
/
create or replace function GETMAXLEGACYCUSTOMERNUMBER return number is
  legacyNumber 		number;
  maxLegacyNumber number:=0;
begin

	for c in (select legacycustomernumber from customer) loop
		begin
			legacyNumber:=to_number(c.legacycustomernumber);
			if (legacyNumber > maxLegacyNumber) then
				maxLegacyNumber:=legacyNumber;
			end if;
		exception when others then null;
		end;
	end loop;
	return maxLegacyNumber;
end;
/
create or replace function GETMAXLEGACYPRODUCTCODE return number is
  legacyNumber 		number;
  maxLegacyNumber number:=0;
begin

	for c in (select LEGACYPRODUCTCODE from PRODUCT ) loop
		begin
			legacyNumber:=to_number(c.LEGACYPRODUCTCODE);
			if (legacyNumber > maxLegacyNumber) then
				maxLegacyNumber:=legacyNumber;
			end if;
		exception when others then null;
		end;
	end loop;
	return maxLegacyNumber;
end;
/
create or replace function GETMINFINISHINGMETHOD(
			productID				product.product_id%type
) return varchar2 is
	fmID		finishingmethod.finishingmethod_id%type;
	fmCode	finishingmethod.code%type;
  fmPriceFactor finishingmethod.pricefactor%type;
begin

  select f.finishingmethod_id, f.code, f.pricefactor
		into fmID, fmCode, fmPriceFactor
		from finishingmethod f
	--	group by f.finishingmethod_id, f.code--, fmPriceFactor
		where f.finishingmethod_id = (select min(pfm.finishingmethod_id)
																		from productfinishingmethod pfm
																		where pfm.product_id = productID);

		return concatenate3(rightpad(fmCode, 6, ' '), rightpad(''||fmPriceFactor, 6, ' '), fmID);
exception when no_data_found then
		return concatenate3(rightpad(' ', 6, ' '), rightpad('1', 6, ' '), 0);
end GETMINFINISHINGMETHOD;





/
create or replace function GetMinLanguage return number is
  minLanguageID	languages.language_id%type ;
begin
  select min(language_id) into minLanguageID from languages;
  return minLanguageID;
end;
/
create or replace function GetMinSystemUser return number is
  minSysUSerID systemuser.systemuser_id%type;
begin
  select min(systemuser_id) into minSysUSerID from systemuser;
  return minSysUSerID;
end;
/
create or replace function getMonthAsVarchar(vDate	date) return varchar2 is
begin
	return to_char(vDate, 'MM');
end;
/
create or replace function getNoteNumbersForInvoiceLine(invoiceLineID number) return varchar2 is
  result varchar2(512);
begin
  for c in (select pn.notenumber
            from invoiceline il,
                 invoicelineproduct ilp,
                 packingnote        pn,
                 packingnoteline    pnl
          where il.invoiceline_id = invoiceLineID
             and il.invoiceline_id = ilp.invoiceline_id
             and il.invoiceheader_id = pnl.invoiceheader_id
             and pn.packingnote_id = pnl.packingnote_id
             and ilp.product_link_id = pnl.product_id
             and ilp.sizedefinition_link_id = pnl.sizedefinition_id
             and ilp.finishingmethod_id = pnl.finishingmethod_id) loop
    result := result || c.notenumber || ', ';
  end loop;
  if (length(result) > 2) then result := substr(result, 0, length(result) - 2); end if;
  return result;
end getNoteNumbersForInvoiceLine;
/
create or replace function getpickupdate(FPNumber number, FPCountDate date, FPDistribPointID number)
return date is
i number;
pickupdate1 date;
pickupdate2 date;
pickupdate3 date;
pickupdate4 date;
pickupdate5 date;

begin
i := 1;

for vCsr in (select distinct bt.pickupdate
  from bagtag bt
 where bt.pickupdate <= FPCountDate
   and bt.deliverydate is not null
   and bt.distributionpoint_id = FPDistribPointID
   and rownum <= 5
 order by bt.pickupdate desc) loop
       if i=1 then pickupdate1 := vCsr.Pickupdate; end if;
       if i=2 then pickupdate2 := vCsr.Pickupdate; end if;
       if i=3 then pickupdate3 := vCsr.Pickupdate; end if;
       if i=4 then pickupdate4 := vCsr.Pickupdate; end if;
       if i=5 then pickupdate5 := vCsr.Pickupdate; end if;
       i := i + 1;
 end loop;

 if FPNumber = 1 then return pickupdate1; end if;
 if FPnumber = 2 then return pickupdate2; end if;
 if FPNumber = 3 then return pickupdate3; end if;
 if FPNumber = 4 then return pickupdate4; end if;
 if FPnumber = 5 then return pickupdate5; end if;

end;
/
create or replace function getRound(
	nNumber	number,
	nDigits	integer
) return number is
begin
	return round(nNumber, nDigits);
end;
/
create or replace function getRoundToInteger(
	nNumber	number
) return number is
begin
	return round(nNumber);
end;
/
create or replace function getRoundUp(nNumber number)
return number is
    /***************************************************************************************\
    * -- Author     : APO                                                                   *
    * -- Created    : 2025-03-24 ABSN-462, used to determine the round up a number          *
    * -- Version    : 1.0                                                                   *
    * -- Updated    :                                                                       *
    * -- Remarks    :                                                                       *
    \***************************************************************************************/
  lv_truncated number;
begin
  lv_truncated := trunc(nNumber);
  if nNumber = lv_truncated then
    return lv_truncated;
  else
    return lv_truncated + 1;
  end if;
end;
/
create or replace function getroutestopcode(fp_routestopid routestop.routestop_id%type)	return varchar2 is
	lv_routecode route.routecode%type;
	lv_deliverynumber number;
	lv_deliverycode   deliveryscheme.code%type;
	lv_customerid     customer.customer_id%type;
	lv_daydigit       number;
	lv_sortsequence   routestop.sortsequence%type;
	lv_datecheck      date;
begin
	--version 1.9 look at the routestops itself and not the customerdeliverydays, code cleanup
	select x.routecode,
				 (select min(ds.code)
						 from deliveryschemesperstop dsp
						 join deliveryscheme ds
							 on ds.deliveryscheme_id = dsp.deliveryscheme_id
						 join routestop wdb
							 on wdb.routestop_id = dsp.routestop_id
						 join route wr
							 on wr.route_id = wdb.route_id
						where wdb.customer_id = x.customer_id
									and wr.routecode = x.routecode
									and x.datecheck between wdb.dateactive and wdb.dateinactive) deliverycode,
				 x.customer_id, x.sortsequence, x.datecheck
		into lv_routecode, lv_deliverycode, lv_customerid, lv_sortsequence,
				 lv_datecheck
		from (select rs.customer_id, r.routecode, rs.sortsequence,
									case
										when rs.dateactive > trunc(sysdate) then
										 trunc(rs.dateactive, 'IW') + 6
										else
										 trunc(sysdate, 'IW') + 6
									end datecheck
						 from routestop rs
						 join route r
							 on rs.route_id = r.route_id
						where r.routecode is not null
									and rs.routestop_id = fp_routestopid) x;
	lv_deliverynumber := to_number(substr(lv_deliverycode, 1, 2)) +
											 to_number(substr(lv_deliverycode, 4, 5)) - 1;
	if (lv_routecode is null) then
		return null;
	end if;
	select case count(distinct r.drivingday_id)
					 when 1 then
						case min(r.drivingday_id)
							when 7 then
							 1
							when 6 then
							 9
							else
							 min(r.drivingday_id) + 1
						end
					 when 2 then
						case sum(distinct r.drivingday_id)
							when 5 then
							 case min(r.drivingday_id)
								 when 1 then
									7
								 else
									9
							 end
							when 7 then
							 case min(r.drivingday_id)
								 when 2 then
									8
								 else
									9
							 end
							else
							 9
						end
					 else
						9
				 end
		into lv_daydigit
		from routestop rs
		join route r
			on r.route_id = rs.route_id
	 where rs.customer_id = lv_customerid
				 and r.routecode = lv_routecode
				 and lv_datecheck between rs.dateactive and rs.dateinactive;
	if (nvl(lv_deliverynumber, 1) = 1) then
		lv_deliverynumber := 0;
	elsif lv_deliverynumber > 7 then
		lv_deliverynumber := 9;
	end if;
	return trim(lv_routecode) || lv_daydigit || lpad(lv_sortsequence, 2, '0') || to_char(lv_deliverynumber);
exception
	when no_data_found then
		return null;
end getroutestopcode;
/
create or replace function getSortUSAsc(
	 FProutenumber					invoiceheader.routenumber%type,
	 FPstopnumber						invoiceheader.stopnumber%type,
	 FPdeltocustomernumber	invoiceheader.deltocustomernumber%type,
	 FPinvoicenumber				invoiceheader.invoicenumber%type
) return varchar2 is
begin
	return concatenateWithBlank(
           concatenateWithBlank(
             castnumberasvarcharwithformat(COALESCE(FProutenumber,0),'000000000000'),
             castnumberasvarcharwithformat(COALESCE(FPstopnumber,0),'000000000000')),
           concatenateWithBlank(
             castnumberasvarcharwithformat(COALESCE(FPdeltocustomernumber,0),'000000000000'),
             castnumberasvarcharwithformat(COALESCE(FPinvoicenumber,0),'00000000000000000000')));
end;
/
create or replace function getSortUSDesc(
	 FProutenumber					invoiceheader.routenumber%type,
	 FPstopnumber						invoiceheader.stopnumber%type,
	 FPdeltocustomernumber	invoiceheader.deltocustomernumber%type,
	 FPinvoicenumber				invoiceheader.invoicenumber%type
) return varchar2 is
begin
	return concatenateWithBlank(
           concatenateWithBlank(
             castnumberasvarcharwithformat(COALESCE(FProutenumber,0),'000000000000'),
             castnumberasvarcharwithformat(9999999999 - COALESCE(FPstopnumber,0),'000000000000')),
           concatenateWithBlank(
             castnumberasvarcharwithformat(COALESCE(FPdeltocustomernumber,0),'000000000000'),
             castnumberasvarcharwithformat(COALESCE(FPinvoicenumber,0),'00000000000000000000')));
end;
/
create or replace function getSQItemInCirculation(
      sqHeaderID        statusquoheader.statusquoheader_id%type,
      dipID             distributionpoint.distributionpoint_id%type,
      weID              weareremployment.weareremployment_id%type,
      productID         product.product_id%type,
      sizeID            sizedefinition.sizedefinition_id%type,
      finmethID         finishingmethod.finishingmethod_id%type
) return number is
  sqItemID number;
  cursor cPSFMWE is
    select sqitemincirculation_id
    from sqitemincirculation x
		where x.statusquoheader_id = sqHeaderID and
					x.distributionpoint_link_id = dipID and
					x.weareremployment_link_id = weID and
					x.product_link_id = productID and
					x.sizedefinition_link_id = sizeID and
					x.finishingmethod_id = finmethID;
  cursor cPSFM is
    select sqitemincirculation_id
    from sqitemincirculation x
		where x.statusquoheader_id = sqHeaderID and
					x.distributionpoint_link_id = dipID and
					x.weareremployment_link_id is null and
					x.product_link_id = productID and
					x.sizedefinition_link_id = sizeID and
					x.finishingmethod_id = finmethID;
begin
  if (weID is not null) then
    open cPSFMWE;
    fetch cPSFMWE into sqItemID;
    close cPSFMWE;
  else
    open cPSFM;
    fetch cPSFM into sqItemID;
    close cPSFM;
  end if;
  return sqItemID;
end getSQItemInCirculation;
/
create or replace function GetSubstring(
		FPstr		varchar2,
		FPpos		integer
) return varchar2 is
begin
	return substr(FPstr, FPpos);
end;
/
create or replace function GetSubstringOnLength(
		FPstr		varchar2,
		FPpos		integer,
		FPlen		integer
) return varchar2 is
begin
	return substr(FPstr, FPpos, FPlen);
end;
/
create or replace function getSysdateForTimezone return date is
  gv_timezone databasesettings.timezone%type;
  stmt        varchar(200);
  res         date;
begin
  select d.timezone
    into gv_timezone
    from databasesettings d;
  stmt := q'[SELECT cast(CAST(SYSTIMESTAMP AT TIME ZONE ']' || gv_timezone ||
          q'[' AS TIMESTAMP WITH TIME ZONE) as date) sd FROM dual]';
  execute immediate stmt into res;
  return res;
end getSysdateForTimezone;
/
create or replace function getTimeAsNumeric(vDate	date) return int is
begin
	return	cast(TO_CHAR(vDate,'HH24') as numeric)*10000 +
					cast(TO_CHAR(vDate,'MI') as numeric)*100 +
					cast(TO_CHAR(vDate,'SS') as numeric);
end;
/
create or replace function getTimeOnly(vDate date) return varchar2 is
begin
  return to_char(vDate, 'HH24:MI:SS');
end;
/
create or replace function GetWeekNumber(FPdtDate date) return varchar2 is
	weekNo					varchar2(2);
begin
	weekNo:=getisoweek(FPdtDate);
	if (length(weekNo) < 2) then weekNo:=concatenate('0',weekNo); end if;
  return weekNo;
end;
/
create or replace function GETWEEKSDIFFERENCE (minyear integer, minweek integer, maxyear integer, maxweek integer) return integer is
  Result integer;
  i integer;
begin
     if (minyear is null or minweek is null or maxyear is null or maxweek is null) then return -1;
     end if;
     if ((maxyear < minyear) or ((maxyear = minyear) and (maxweek < minweek))) then return -1;
     end if;
     Result := maxweek - minweek + 1;
     if (maxyear = minyear) then return(Result);
     end if;
     FOR i IN minyear..maxyear-1 LOOP
         Result := Result + GETWEEKSINYEAR(i);
     end loop;
  return(Result);
end GETWEEKSDIFFERENCE;
/
create or replace function getweeksinyear(year in integer) return integer is
  Result integer;
begin
  if year is null then return null; end if;
  -- Result := to_number(to_char(to_date(concatenate('31,12', year), 'DD-MM-YYYY'),'IW'));
  Result := getisoweek(to_date('31' || '12' || year, 'DDMMYYYY'));
  if result = 1 then
    -- Result := to_number(to_char(to_date(concatenate('24,12', year), 'DD-MM-YYYY'),'IW'));
    Result := getisoweek(to_date('24' || '12' || year, 'DDMMYYYY'));
  end if;
  return(Result);
end getweeksinyear;
/
create or replace function getyearofweek(vdate date) return int is
  LV_YEAR          int;
begin
  select
    case
      when DS.NLS_TERRITORY in ('AMERICA', 'CANADA', 'AUSTRALIA') then DYW.US_YEAR
      else DYW.YEAR
      end into LV_YEAR
  from DATE_YEARWEEKDAY DYW, DATABASESETTINGS DS
  where DYW.DATE_ = trunc(VDATE);
  return LV_YEAR;
exception
  when no_data_found then
    return cast(to_char(vdate, 'IYYY') as numeric);
end getyearofweek;
/
create or replace function GET_ACTIVE_STOCK
  (productid                      product.product_id%type,
   sizeid                         sizedefinition.sizedefinition_id%type ,
   stocklocation                  product.storeactivestocklocation%type
  ) return  number is

  LVnAmount          number;

begin

   LVnAmount:=0;
   if stocklocation = 'N' then return LVnAmount; end if;

   select count(*)
   into LVnAmount
   from uniqueitem ui
   where ui.product_id = productid
     and ui.sizedefinition_id = sizeid
     and ui.activestocklocation_id is not null;

   return LVnAmount;

end GET_ACTIVE_STOCK;
/
create or replace function GET_AMOUNTDELIVERED
 (deltocustomerid    in invoiceheader.deltocustomer_link_id%type,
  productid          in invoicelineproduct.product_link_id%type,
  sizeid             in invoicelineproduct.sizedefinition_link_id%type,
  drivingdate        in invoiceheader.invoicedate%type,
  invoicelinetypeid  in invoiceline.invoicelinetype_id%type)
return number is
  result             invoicelineproduct.deliveredqty%type;
  yeari number;
  weeki number;

 begin

  yeari := getYearofWeek(drivingdate);
  weeki := getISOWeek(drivingdate);

  SELECT sum(ilp.deliveredqty)
  into result
  FROM invoiceheader ih, invoiceline il, invoicelineproduct ilp, status st
  WHERE ih.deltocustomer_link_id = deltocustomerid
    and ih.invoiceheader_id = il.invoiceheader_id and il.invoiceline_id = ilp.invoiceline_id
    and ilp.product_link_id = productid
    and ilp.sizedefinition_link_id = sizeid
    and getYearofWeek(ih.invoicedate) = yeari
    and getISOWeek(ih.invoicedate) = weeki
  and ih.status_id = st.status_id and st.statustype = 'IN' and st.code <> '3'
  and il.invoicelinetype_id = invoicelinetypeid;

  return result;

end GET_AMOUNTDELIVERED;
/
create or replace FUNCTION GET_AR_AMOUNT (
        pBUSINESSUNIT_ID                              in     artransaction.businessunit_id%type,
        pbilltocustomer_ID                            in     artransaction.billtocustomer_link_id%type,
        prange_date                                   in     number,
        pstartDate                                    in     reportparam.date_value1%type,
        pendDate                                      in     reportparam.date_value1%type
) return number is
    amount artransaction.amount%type;
begin
 amount:=0;

 if prange_date = -1 then
   select sum(y.amount)
   into amount
     from artransaction y
     where y.billtocustomer_link_id = pbilltocustomer_ID
       AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
       and y.closingtransaction_id is null
       and y.debitcredit = 'C';
    return amount;
 end if;

 if (pstartDate is null) or (pendDate is null) then
    --AGINGMETHOD = 1
   if prange_date = 0 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and trunc(sysdate) - y.artransactiondate < 30;
      return amount;
   end if;
   if prange_date = 30 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and trunc(sysdate) - y.artransactiondate >= 30
         and trunc(sysdate) - y.artransactiondate < 60;
      return amount;
   end if;
   if prange_date = 60 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and trunc(sysdate) - y.artransactiondate >= 60
         and trunc(sysdate) - y.artransactiondate < 90;
      return amount;
   end if;
   if prange_date = 90 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = BUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and trunc(sysdate) - y.artransactiondate >= 90
         and trunc(sysdate) - y.artransactiondate < 120;
      return amount;
   end if;
   if prange_date = 120 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and trunc(sysdate) - y.artransactiondate >= 120;
      return amount;
   end if;
  else
      -- AGINGMETHOD = 2
   if prange_date = 0 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and y.artransactiondate >= pstartDate;
      return amount;
   end if;
   if (prange_date = 30 or prange_date = 60 or prange_date = 90) then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and y.artransactiondate >= pstartDate
         and y.artransactiondate < pendDate;
      return amount;
   end if;
   if prange_date = 120 then
     select sum(y.amount)
     into amount
       from artransaction y
       where y.billtocustomer_link_id = pbilltocustomer_ID
         AND Y.BUSINESSUNIT_ID = pBUSINESSUNIT_ID
         and y.closingtransaction_id is null
         and y.debitcredit = 'D'
         and (y.parentartransaction_id is null or y.parentartransaction_id=y.artransaction_id)
         and y.artransactiondate < pstartDate;
      return amount;
   end if;
  end if;

exception
    when no_data_found then return 0;
end;
/
create or replace function get_check_digit_matrix(fp_number in varchar2) return varchar2 is
  --function get_check_digit_matrix version 0.1
  gv_length     number;
  gv_number     number(1);
  gv_carryover  number := 0;
  gv_checkdigit number := 0;

  procedure get_carryover(fp_x in number, fp_y in number) is
  begin
    --get_carryover
    select cdm.carryover, cdm.checkdigit
    into   gv_carryover, gv_checkdigit
    from   check_digit_matrix cdm
    where  cdm.x = fp_x
    and    cdm.y = fp_y;
  end get_carryover;
begin
  --get length
  gv_length := length(fp_number);
  --loop number
  for x in 1 .. gv_length loop
    begin
      gv_number := to_number(substr(fp_number, x, 1));
      get_carryover(gv_carryover, gv_number);
    end;
  end loop; --x
  --get the checkdigit
  get_carryover(0, gv_carryover);
  return fp_number || to_char(gv_checkdigit);
end get_check_digit_matrix;
/
create or replace function get_circinventory(p_customer customer.customer_id%type,
                                            dp_id distributionpoint.distributionpoint_id%type,
                                            p_product product.product_id%type,
                                            p_size sizedefinition.sizedefinition_id%type,
                                            p_fm finishingmethod.finishingmethod_id%type,
                                            countsum varchar)
RETURN NUMBER
AS
res number:=0;
v_scode varchar2(30);
begin
  select sd.code into v_scode from sizedefinition sd where sd.sizedefinition_id=p_size;
 if countsum='sum' then
   if v_scode='*' then
     select /*+parallel*/ sum(weinv.circinventory) into res from
     wearer wea inner join weareremployment wemp on wea.wearer_id= wemp.wearer_id
     inner join wearerinventory weinv on weinv.weareremployment_id=wemp.weareremployment_id
     where wea.customer_id = p_customer
     and weinv.product_id = p_product
     and weinv.finishingmethod_id = p_fm;
   end if;
   if v_scode<>'*' then
     select /*+parallel*/ sum(weinv.circinventory) into res from
     wearer wea inner join weareremployment wemp on wea.wearer_id= wemp.wearer_id
     inner join wearerinventory weinv on weinv.weareremployment_id=wemp.weareremployment_id
     where wea.customer_id = p_customer
     and weinv.product_id = p_product
     and weinv.sizedefinition_id=p_size
     and weinv.finishingmethod_id = p_fm;
   end if;
   end if;
   if countsum='count' then
        if v_scode='*' then
       select /*+parallel*/ count(winv.wearerinventory_id) into res from wearerinventory winv, weareremployment were
        where winv.product_id = p_product
        and winv.finishingmethod_id = p_fm
        and winv.weareremployment_id = were.weareremployment_id and were.distributionpoint_id=dp_id ;
    end if;
             if v_scode<>'*' then
       select /*+parallel*/ count(winv.wearerinventory_id) into res from wearerinventory winv, weareremployment were
        where winv.product_id = p_product
        and winv.finishingmethod_id = p_fm
        and winv.sizedefinition_id=p_size
        and winv.weareremployment_id = were.weareremployment_id and were.distributionpoint_id=dp_id ;
     end if;
 end if;
 return res;
end;
/
create or replace function get_container_ords(fp_primaryid in varchar2) return sys_refcursor as
  c sys_refcursor;
  --function get_container_ords version 0.1
begin
  open c for
    select bu.code businessunitcode, bu.description businessunitname, cn.primaryid, c.customernumber,
           c.name customername, t.departmentnumber, t.description departmentname,
           dp.distributionpointnumber consumptionpointnumber, dp.description consumptionpointname,
           cn.lastinscandate, cn.lastoutscandate,
           case
             when cn.lastoutscandate > cn.lastinscandate or cn.lastinscandate is null then
              round((sysdate - cn.lastoutscandate) / 7, 0)
             else
              0
           end weeks_at_customer, cn.tareweight, st.factorydescription stay,
           pk.notenumber last_notenumber, pnc.timestamp last_notecontainer_timestamp
    from   container cn
    join   businessunit bu
    on     bu.businessunit_id = cn.businessunit_id
    join   stay st
    on     st.stay_id = cn.stay_id
    left   join(distributionpoint dp
    join   department t
    on     t.department_id = dp.department_id
    join   customer c
    on     c.customer_id = t.customer_id) on dp.distributionpoint_id = cn.distributionpoint_id
    left   join((select pncx.container_id,
                        max(pncx.packingnotecontainer_id) max_packingnotecontainer_id
                 from   packingnotecontainer pncx
                 group  by pncx.container_id) x
    join   packingnotecontainer pnc
    on     pnc.packingnotecontainer_id = x.max_packingnotecontainer_id
    join   packingnote pk
    on     pk.packingnote_id = pnc.packingnote_id) on x.container_id = cn.container_id
    where  cn.primaryid = fp_primaryid;
  return c;
end get_container_ords;
/
create or replace function Get_Cust_Delivery_Days(CustomerID IN customer.customer_id%TYPE)
return  varchar2 is
  sir   varchar2(1000);
begin
  sir := '';
for vCursor in( select DISTINCT d.daynumber
                from customerdeliveryday cdd, day d
                where cdd.day_id = d.day_id AND cdd.customer_id = CustomerID
                order by daynumber
                ) LOOP
     if  ltrim(rtrim(Vcursor.daynumber)) is not null then
         sir:= concatenate3(sir, ltrim(rtrim(castNumberAsVarchar(Vcursor.daynumber))), ' ');
     else
         sir:= concat(sir, ' ');
     end if;
end loop;
return(sir);
end Get_Cust_Delivery_Days;
/
create or replace function Get_Cust_Delivery_Routes(CustomerID IN customer.customer_id%TYPE)
return  varchar2 is
  sir   varchar2(1000);
begin
  sir := '';
for vCursor in( select DISTINCT d.daynumber,
                  (Select min(ro.routenumber)
                  from Route ro, RouteStop rs where ro.route_id = rs.route_id AND
                  ro.drivingday_id = cdd.Day_ID and rs.Customer_ID = CustomerID) routenumber
                from customerdeliveryday cdd, day d
                where cdd.day_id = d.day_id AND cdd.customer_id = CustomerID
                order by daynumber
                )
LOOP
     if  ltrim(rtrim(Vcursor.routenumber)) is not null then
         sir:= concatenate3(sir, ltrim(rtrim(castNumberAsVarchar(Vcursor.routenumber))), ' ');
     else
         sir:= concat(sir, ' ');
     end if;
end LOOP;
return(sir);
end Get_Cust_Delivery_Routes;
/
create or replace function GET_DELCOMP_CIRCINVENTORY
 (customerid in  customer.customer_id%type,
  distributionpointid in packingnote.distributionpoint_id%type,
  productid in         product.product_id%type,
  deldate in       packingnote.deliverydate%type)
return number is
  result             deliveryhistory.amountdelivered%type;
begin

 result := 0;
 select sum(rqa.quantity)
 into result
   from rentalqtyadjustment rqa, productlistperdistribpoint plpd, distributionpoint di, department d
   where rqa.productlistperdistribpoint_id = plpd.productlistperdistribpoint_id
     and plpd.product_id = productid
     and plpd.distributionpoint_id = di.distributionpoint_id
     AND plpd.distributionpoint_id = distributionpointid
     and di.department_id = d.department_id
     and d.customer_id = customerid
     and rqa.adjustmentdate <= deldate;

  return result;

end GET_DELCOMP_CIRCINVENTORY;
/
create or replace function GET_DELCOMP_DELFRECV
 (customerroute_type in number,
  customerid in  customer.customer_id%type,
  productid in         product.product_id%type,
  routeid in route.route_id%type,
  deldate in       invoiceheader.invoicedate%type)
return varchar2 is
  result             varchar2(7);
  dayid number;
  type Tcsr is ref cursor ;
  Vcsr Tcsr;
 begin

  result := '';
  if customerroute_type = 1 then --customer
    begin
      open Vcsr for
        select distinct pdd.day_id
        from productlistpercustomer plpc, productdeliveryday pdd
        where plpc.productlistpercustomer_id = pdd.productlistpercustomer_id
          and plpc.customer_id = customerid
          and plpc.product_id = productid
          and plpc.dateactive <= deldate
          and plpc.dateinactive > deldate;
        fetch Vcsr into dayid;
        if Vcsr%found then
          loop
            result := result || to_char(dayid);
            fetch Vcsr into dayid;
            if Vcsr%notfound then exit; end if;
          end loop;
        end if;
      --  exception when no_data_found then result := '';
    end;
  else
    begin
      open Vcsr for
        select distinct pdd.day_id --route
        from productlistpercustomer plpc, productdeliveryday pdd, route ro, routestop rs
        where plpc.productlistpercustomer_id = pdd.productlistpercustomer_id
          and ro.route_id = rs.route_id
          and plpc.customer_id = rs.customer_id
          and plpc.product_id = productid
          and plpc.dateactive <= deldate
          and plpc.dateinactive > deldate
          and rs.customer_id = customerid
          and ro.route_id = routeid;
        fetch Vcsr into dayid;
        if Vcsr%found then
          loop
            result := result || to_char(dayid);
            fetch Vcsr into dayid;
            if Vcsr%notfound then exit; end if;
          end loop;
        end if;
   --     exception when no_data_found then result := '';
    end;
  end if;

  return result;

end GET_DELCOMP_DELFRECV;
/
create or replace function GET_DELCOMP_MINQTY
 (customerid in  customer.customer_id%type,
  productid in         product.product_id%type,
  distributionpointid in packingnote.distributionpoint_id%type,
  deldate in       packingnote.deliverydate%type)
return number is
  result             productlistpercustomer.minimumquantity%type;
  sizeid  sizedefinition.sizedefinition_id%type;
  finmeth finishingmethod.finishingmethod_id%type;
  plplcdate productlistpercustomer.dateactive%type;
  minqty productlistpercustomer.minimumquantity%type;
  minturn productlistpercustomer.minimumturnaround%type;
  type Tcsr is ref cursor;
  Vcsr Tcsr;

 begin

   result := 0;
   open Vcsr for
    select plpc.sizedefinition_id, plpc.finishingmethod_id, max(plpc.dateactive)
    from productlistpercustomer plpc
    where plpc.product_id = productid
      and plpc.customer_id = customerid
      and plpc.dateinactive > deldate
      and plpc.dateactive <= deldate
      and plpc.billingmethod = 2 -- rent on fixed amount
    group by plpc.sizedefinition_id, plpc.finishingmethod_id;
    fetch Vcsr into sizeid, finmeth, plplcdate;
    if Vcsr%found then
      loop
        select plpc.minimumquantity, plpc.minimumturnaround
        into minqty, minturn
        from productlistpercustomer plpc
        where plpc.product_id = productid
          and plpc.customer_id = customerid
          and plpc.sizedefinition_id = sizeid
          and plpc.finishingmethod_id = finmeth
          and plpc.dateactive = plplcdate
          and plpc.billingmethod = 2; -- rent on fixed amount
        if minqty <> 0 then
          result := result + minqty;
        else
          if minturn <> 0 then
            result := result + (minturn / 100) * GET_DELCOMP_CIRCINVENTORY(customerid, distributionpointid, productid, deldate);
          end if;
        end if;
        fetch Vcsr into sizeid, finmeth, plplcdate;
        if Vcsr%notfound then exit; end if;
        end loop;
    end if;

  return result;

end GET_DELCOMP_MINQTY;
/
create or replace function GET_DELCOMP_PRICE
(invoiceheaderid in   invoiceheader.invoiceheader_id%type ,
 productid in         product.product_id%type ,
 typeofmerch in       product.typeofmerchandise%type)
return number is
 result             number ;
 begin

 --Note: assume that the price is the same for all sizes / finishing methods since this report excludes garments.
 --In practice there will probably only 1 size defined, size '-'.

 result := 0;
 if typeofmerch = 1 then --Wash/delivery
   select max(il.price)
   into result
   from invoiceline il, invoicelineproduct ilp
   where il.invoiceline_id = ilp.invoiceline_id
     and il.invoicelinetype_id = 2
     and il.invoiceheader_id = invoiceheaderid
     and ilp.product_link_id = productid;
 end if;
 if typeofmerch = 3 then --sales
   select max(il.price)
   into result
   from invoiceline il, invoicelineproduct ilp
   where il.invoiceline_id = ilp.invoiceline_id
     and il.invoicelinetype_id = 5
     and il.invoiceheader_id = invoiceheaderid
     and ilp.product_link_id = productid;
 end if;

 if result is null then result := 0; end if;
 return result;

end GET_DELCOMP_PRICE;
/
create or replace function GET_DELCOMP_WEEKQUANTITY
(packingnoteid in packingnote.packingnote_id%type,
 packingnotelineid in  packingnoteline.packingnoteline_id%type)
return number is
 result             number ;
 begin

  SELECT sum(dh.amountdelivered)
  INTO result
  FROM deliveryhistory dh, packingnote pn, packingnoteline pnl
  WHERE dh.processbusinessunit_id = pn.processbusinessunit_id
    and pn.packingnote_id = pnl.packingnote_id
    and dh.year = pn.year
    and dh.week = pn.week
    and dh.distributionpoint_link_id = pn.distributionpoint_id
    and dh.product_link_id = pnl.product_id
    and pn.packingnote_id = packingnoteid
    and pnl.packingnoteline_id = packingnotelineid;

  if result is null then result := 0; end if;
  return result;

end GET_DELCOMP_WEEKQUANTITY;
/
create or replace function Get_DeliveryScheme_Code(
customerID IN customer.customer_id%TYPE,
productID IN product.product_id%TYPE,
sizeDefinitionID IN sizeDefinition.sizeDefinition_id%TYPE,
finishingMethodID IN finishingMethod.finishingMethod_id%TYPE
)
return  varchar2 is
  sir   varchar2(1000);
BEGIN
for vCursor in( select DISTINCT ds.code deliveryscheme, ds.frequency
           from deliveryscheme ds, standarddeliveryline sdl, productlistperdistribpoint plpd, distributionpoint dp, department dep
           where ds.deliveryscheme_id = sdl.deliveryscheme_id AND
                 sdl.productlistperdistribpoint_id = plpd.productlistperdistribpoint_id AND
                 plpd.distributionpoint_id = dp.distributionpoint_id AND
                 dp.department_id = dep.department_id AND dep.customer_id = customerID AND
                 plpd.product_id = productID AND plpd.finishingmethod_id = finishingMethodID AND
                 (plpd.sizedefinition_id = sizeDefinitionID OR plpd.sizedefinition_id IN (SELECT sd.sizedefinition_id FROM Sizedefinition sd WHERE sd.code = '*'))
                order by ds.frequency ASC
                )
LOOP
     if  (ltrim(rtrim(Vcursor.deliveryscheme)) is not null) THEN
         BEGIN
         sir := ltrim(rtrim(Vcursor.deliveryscheme));
         EXIT;
         END;
     end if;
end loop;
IF sir IS NOT NULL THEN return(sir);
ELSE
BEGIN
for vCursor2 in( select DISTINCT ds.code deliveryscheme, ds.frequency
           from customerdeliveryscheme cds, deliveryscheme ds
           where cds.customer_id = customerID AND cds.deliveryscheme_id = ds.deliveryscheme_id
           order by ds.frequency ASC
                )
LOOP
     if  (ltrim(rtrim(vCursor2.deliveryscheme)) is not null) THEN
         BEGIN
         sir := ltrim(rtrim(vCursor2.deliveryscheme));
         EXIT;
         END;
     end if;
end loop;
END;
END IF;
return(sir);
end Get_DeliveryScheme_Code;
/
create or replace function get_depreciation_percent(fp_resvaluescheme_id number,
                                                    fp_washes_or_weeks   number,
                                                    fp_decimals          number default null) return number is
  --function get_depreciation_percent version 0.4
  lv_depreciation_percentage number := 0;
  lv_washes_or_weeks         number;
  lv_decimals                number := nvl(fp_decimals, 0);

  procedure get_percentage is
  begin
    select max(case
                 when r.definitiontype = 2 -- linear
                  then
                  round(r.startpercentage -
                        (((lv_washes_or_weeks - r.rangestart) / (r.rangeend - r.rangestart)) *
                        (r.startpercentage - r.endpercentage)), lv_decimals)
                 else -- fixed
                  r.fixedpercentage
               end) depr_percentage
    into   lv_depreciation_percentage
    from   resvalschemedefinition r
    where  r.residualvaluescheme_id = fp_resvaluescheme_id
    and    r.rangestart <= lv_washes_or_weeks
    and    r.rangeend >= lv_washes_or_weeks;
  end get_percentage;
begin
  lv_washes_or_weeks := fp_washes_or_weeks;
  get_percentage;
  if lv_depreciation_percentage is null and fp_washes_or_weeks <= 0 then
    begin
      lv_washes_or_weeks := 1;
      get_percentage;
    end;
  end if;
  return nvl(lv_depreciation_percentage, 0);
end get_depreciation_percent;
/
create or replace function GET_EXPECTED_RETURNS
  (period                    number, -- 1 for week1, 2 for week 2
   reportparamid                  reportparam.reportparam_id%type,
   productlistperdistribpointid   productlistperdistribpoint.productlistperdistribpoint_id%type,
   businessunitid                 businessunit.businessunit_id%type
  ) return  number is

  LVnAmount          number;

begin

   LVnAmount:=0;
if period = 1 then
   select sum(ser.qtyreturned)
   into LVnAmount
   from straightevenreturn ser, productlistperdistribpoint plpd, status st, reportparam rp
   where plpd.product_id = ser.product_id
     and plpd.sizedefinition_id = ser.sizedefinition_id
     and plpd.finishingmethod_id = ser.finishingmethod_id
     and plpd.distributionpoint_id = ser.distributionpoint_id
     and plpd.productlistperdistribpoint_id = productlistperdistribpointid
     and ser.processbusinessunit_id = businessunitid
     and ser.status_id = st.status_id
     and st.code <> '30' and st.statustype = 'SR'
     and ser.pickupdate between (rp.date_value1 - 6) and rp.date_value1
     and rp.reportparam_id = reportparamid;
else
   select sum(ser.qtyreturned)
   into LVnAmount
   from straightevenreturn ser, productlistperdistribpoint plpd, status st, reportparam rp
   where plpd.product_id = ser.product_id
     and plpd.sizedefinition_id = ser.sizedefinition_id
     and plpd.finishingmethod_id = ser.finishingmethod_id
     and plpd.distributionpoint_id = ser.distributionpoint_id
     and plpd.productlistperdistribpoint_id = productlistperdistribpointid
     and ser.processbusinessunit_id = businessunitid
     and ser.status_id = st.status_id
     and st.code <> '30' and st.statustype = 'SR'
     and ser.pickupdate between (rp.date_value2 - 6) and rp.date_value2
     and rp.reportparam_id = reportparamid;
end if;
   return LVnAmount;

end GET_EXPECTED_RETURNS;
/
create or replace function get_flexfield_date(fp_fieldID            number,
                                                fp_dialogCode         dialogs.code%type,
                                                fp_flexFieldCode      characteristic.code%type) return date is
  --version 0.2
  pragma udf;
  lv_datevalue dialogflexfields.datevalue%type;
begin
  select dff.datevalue
    into lv_datevalue
    from dialogflexfields dff
    join dialogs dia on dff.dialog_id = dia.dialog_id
    join characteristic ch on (dff.characteristic_id = ch.characteristic_id and ch.dialog_id = dff.dialog_id)
   where dff.entity_id = fp_fieldID
     and ch.code = fp_flexFieldCode
     and dia.code = fp_dialogCode;
  return lv_datevalue;
  exception
    when no_data_found then
      return null;
end get_flexfield_date;
/
create or replace function get_flexfield_number(fp_fieldID            number,
                                                fp_dialogCode         dialogs.code%type,
                                                fp_flexFieldCode      characteristic.code%type) return number is
  --version 0.2
  pragma udf;
  lv_numbervalue dialogflexfields.numbervalue%type;
begin
  select nvl(cfv.numbervalue, dff.numbervalue)
    into lv_numbervalue
    from dialogflexfields dff
    join dialogs dia on dff.dialog_id = dia.dialog_id
    join characteristic ch on (dff.characteristic_id = ch.characteristic_id and ch.dialog_id = dff.dialog_id)
    left join characteristicpredefvalue cfv on cfv.characteristicpredefvalue_id = dff.characteristicpredefvalue_id
                                           and cfv.characteristic_id = ch.characteristic_id
   where dff.entity_id = fp_fieldID
     and ch.code = fp_flexFieldCode
     and dia.code = fp_dialogCode;
  return lv_numbervalue;
  exception
    when no_data_found then
      return null;
end get_flexfield_number;
/
create or replace function get_flexfield_string(fp_entityID           number,
                                                fp_dialogCode         dialogs.code%type,
                                                fp_flexFieldCode      characteristic.code%type) return varchar2 is
  --version 0.2
  pragma udf;
  lv_stringvalue dialogflexfields.stringvalue%type;
begin
  select nvl(cfv.stringvalue,dff.stringvalue)
    into lv_stringvalue
    from dialogflexfields dff
    join dialogs dia on dff.dialog_id = dia.dialog_id
    join characteristic ch on (dff.characteristic_id = ch.characteristic_id and ch.dialog_id = dff.dialog_id)
    left join characteristicpredefvalue cfv on cfv.characteristicpredefvalue_id = dff.characteristicpredefvalue_id
                                           and cfv.characteristic_id = ch.characteristic_id
   where dff.entity_id = fp_entityID
     and ch.code = fp_flexFieldCode
     and dia.code = fp_dialogCode;
    return lv_stringvalue;
  exception
    when no_data_found then
      return null;
end get_flexfield_string;
/
create or replace function get_invoiceprice(fp_startdate         in date,
                                            fp_enddate           in date,
                                            fp_invoicelinetypeid in number,
                                            fp_customerid        in number,
                                            fp_productid         in number,
                                            fp_sizeid            in number,
                                            fp_finishingmethodid in number) return number is
  pragma udf;
  lv_price number;
begin
  --function get_invoiceprice version 0.1
  --we fist take price from invoice
  select max(il.price)
  into   lv_price
  from   invoiceheader ih
  join   invoiceline il
  on     il.invoiceheader_id = ih.invoiceheader_id
  join   invoicelineproduct ilp
  on     ilp.invoiceline_id = il.invoiceline_id
  where  ih.invoicedate between fp_startdate and fp_enddate
  and    il.invoicelinetype_id = fp_invoicelinetypeid
  and    ih.deltocustomer_link_id = fp_customerid
  and    ilp.product_link_id = fp_productid
  and    ilp.sizedefinition_link_id = fp_sizeid
  and    ilp.finishingmethod_id = fp_finishingmethodid;
  if lv_price is null then
    begin
      --if not found we start to use packprice
      case fp_invoicelinetypeid
        when 1 then
          lv_price := pack_price.rent_price(fp_customerid, fp_productid, fp_sizeid,
                                            fp_finishingmethodid, fp_enddate);
        when 2 then
          lv_price := pack_price.wash_price(fp_customerid, fp_productid, fp_sizeid,
                                            fp_finishingmethodid, fp_enddate);
        when 5 then
          lv_price := pack_price.sales_price(fp_customerid, fp_productid, fp_sizeid, fp_enddate);
        when 7 then
          lv_price := pack_price.replacement_price(fp_customerid, fp_productid, fp_sizeid,
                                                   fp_finishingmethodid, fp_enddate);
        else
          lv_price := null;
      end case;
    end;
  end if;
  return(lv_price);
end get_invoiceprice;
/
create or replace function get_keephistinvdataperiod(fpninvoice_id invoiceheader.invoiceheader_id%type) return number is
  result number := 0;
  cursor get_period is
     select pif.keephistinvdataperiods
     from invoiceheader ih, businessunit ibu, plantinvoicefrequency pif
     where ibu.businessunit_id = ih.invoicebusinessunit_id
       and pif.plant_id = ibu.plant_id
       and pif.invoicefrequency_id = ih.invoicefrequency_id
       and pif.documenttype = 1
       and ih.invoiceheader_id = fpninvoice_id;
begin
  for pif_rec in get_period loop
     result := pif_rec.keephistinvdataperiods;
  end loop;
  return(result);
end get_keephistinvdataperiod;

/
create or replace FUNCTION get_lastpayment (
        BUSINESSUNIT_ID                              in     artransaction.businessunit_id%type,
        billtocustomer_ID                            in     artransaction.billtocustomer_link_id%type,
        lastpaymentdate                              in     artransaction.artransactiondate%type
) return number is
    lastpayment artransaction.amount%type;
begin
 select sum(y1.amount)
 into lastpayment
     from artransaction y1 , artransactiontype x21
     where y1.billtocustomer_link_id = billtocustomer_ID
       AND Y1.BUSINESSUNIT_ID = BUSINESSUNIT_ID
       and y1.artransactiontype_id = x21.artransactiontype_id
       and x21.typenumber = 5 and x21.debitcredit = 'C'
       and y1.artransactiondate = lastpaymentdate;
    return lastpayment;
exception
    when no_data_found then return 0;
end;
/
create or replace FUNCTION get_lastpayment_UNF (
        billtocustomer_ID in artransaction.billtocustomer_link_id%type,
        lastpaymentdate in artransaction.artransactiondate%type
) return number is
    lastpayment artransaction.amount%type;
begin
 select sum(y1.amount)
 into lastpayment
     from artransaction y1 , artransactiontype x21
     where y1.billtocustomer_link_id = billtocustomer_ID
       and y1.artransactiontype_id = x21.artransactiontype_id
       and x21.typenumber = 5 and x21.debitcredit = 'C'
       and y1.artransactiondate = lastpaymentdate;
    return lastpayment;
exception
    when no_data_found then return 0;
end;
/
create or replace function get_maxinventory(p_customer customer.customer_id%type, dp_id distributionpoint.distributionpoint_id%type, p_product product.product_id%type,  p_size sizedefinition.sizedefinition_id%type, p_fm finishingmethod.finishingmethod_id%type, countsum varchar)
RETURN NUMBER
AS
res number:=0;
v_scode varchar2(30);
begin
  select sd.code into v_scode from sizedefinition sd where sd.sizedefinition_id=p_size;
 if countsum='sum' then
   if v_scode='*' then
     select /*+parallel*/ nvl( sum(weinv.maxinventory),0) into res from
     wearer wea inner join weareremployment wemp on wea.wearer_id= wemp.wearer_id
     inner join wearerinventory weinv on weinv.weareremployment_id=wemp.weareremployment_id
     where wea.customer_id = p_customer
     and weinv.product_id = p_product
     and weinv.finishingmethod_id = p_fm
     and wemp.distributionpoint_id=dp_id;
   end if;
   if v_scode<>'*' then
     select /*+parallel*/  nvl(sum(weinv.maxinventory),0) into res from
     wearer wea inner join weareremployment wemp on wea.wearer_id= wemp.wearer_id
     inner join wearerinventory weinv on weinv.weareremployment_id=wemp.weareremployment_id
     where wea.customer_id = p_customer
     and weinv.product_id = p_product
     and weinv.sizedefinition_id=p_size
     and weinv.finishingmethod_id = p_fm
     and wemp.distributionpoint_id=dp_id;
   end if;
   end if;
   if countsum='count' then
        if v_scode='*' then
       select /*+parallel*/ count(winv.wearerinventory_id) into res from wearerinventory winv, weareremployment were
        where winv.product_id = p_product
        and winv.finishingmethod_id = p_fm
        and winv.weareremployment_id = were.weareremployment_id and were.distributionpoint_id=dp_id ;
    end if;
             if v_scode<>'*' then
       select /*+parallel*/ count(winv.wearerinventory_id) into res from wearerinventory winv, weareremployment were
        where winv.product_id = p_product
        and winv.finishingmethod_id = p_fm
        and winv.sizedefinition_id=p_size
        and winv.weareremployment_id = were.weareremployment_id and were.distributionpoint_id=dp_id ;
     end if;

 end if;
 return res;
end;
/
create or replace function GET_NEEDED
  (period                    number, -- 1 for week1, 2 for week 2
   reportparamid                  reportparam.reportparam_id%type,
   productlistperdistribpointid   productlistperdistribpoint.productlistperdistribpoint_id%type
--   paramyear1 - number_value, paramweek1 - number_value1
--   paramyear2 - number_value2, paramweek2 - number_value3
  ) return  number is

--  seasonid           season.season_id%type;
  seasonweek         number;
  LVnAmount          number;
  LVnTemp            number;
  test boolean;
begin

  LVnAmount:=0;
if period = 1 then
  for vCursor in(
    select sdl.standarddeliveryline_id,
      s.season_id, sw.weeknumber,
      ISTEMPORARYDELIVERYSTOP2(rp.number_value, rp.number_value1, sdl.standarddeliveryline_id)
      + ISTEMPORARYDELIVERYSTOP_DATE(rp.date_value1, sdl.standarddeliveryline_id) is_temporarydeliverystop,
--      sdl.temporarystopendweek, sdl.temporarystopstartweek, sdl.temporarystopstartyear,
--      sdl.temporarystopendyear, sdl.tempstoprentforweek, sdl.tempstoprentforyearweek,
--      sdl.tempstopstartweekforyear, sdl.tempstopendweekforyear,
      ds.deliveryscheme_id, ds.frequency, ds.offsetweek,
      rp.number_value, rp.number_value1, rp.number_value2, rp.number_value3
    from standarddeliveryline sdl
      left outer join (season s
        left outer join seasonweek sw on s.season_id = sw.season_id)
          on sdl.season_id = s.season_id
      left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id,
      reportparam rp
     where rp.reportparam_id = reportparamid
      and sdl.productlistperdistribpoint_id = productlistperdistribpointid
      and sdl.dateactive <= rp.date_value1
      and sdl.dateinactive > rp.date_value1) LOOP

  LVnTemp := 0;
-- season check
  if (vCursor.season_id is not null) and vCursor.weeknumber <> vCursor.number_value1 then goto x; end if;
-- temporary stop check
  if vCursor.is_temporarydeliverystop <> 0 then goto x; end if;
/*  if vCursor.temporarystopstartweek <> 0 then
    if (vCursor.number_value1 >= vCursor.temporarystopstartweek
        and vCursor.number_value1 <= vCursor.temporarystopendweek) then goto x;
    end if;
  end if;
  if vCursor.temporarystopstartyear <> 0 then
    if F_IsInYearWeekLifespan(
      vCursor.temporarystopstartyear, vCursor.tempstopstartweekforyear,
      vCursor.number_value, vCursor.number_value1,
      vCursor.temporarystopendyear, vCursor.tempstopendweekforyear) = 1
      then goto x;
    end if;
  end if;*/
-- deliveryscheme check
  if (vCursor.deliveryscheme_id is not null) and
    (not IsWeekDeliveryweek(vCursor.number_value, vCursor.number_value1, vCursor.frequency, vCursor.offsetweek))
  then goto x; end if;

  select sum(sda.amount)
  into LVnTemp
  from standarddeliveryamount sda
  where sda.standarddeliveryline_id = vCursor.standarddeliveryline_id;

  <<x>>  LVnAmount:=LVnAmount + LVnTemp;
  end loop;
else
  for vCursor in(
    select sdl.standarddeliveryline_id,
      s.season_id, sw.weeknumber,
/*      sdl.temporarystopendweek, sdl.temporarystopstartweek, sdl.temporarystopstartyear,
      sdl.temporarystopendyear, sdl.tempstoprentforweek, sdl.tempstoprentforyearweek,
      sdl.tempstopstartweekforyear, sdl.tempstopendweekforyear,*/
      ISTEMPORARYDELIVERYSTOP2(rp.number_value2, rp.number_value3, sdl.standarddeliveryline_id)
      + ISTEMPORARYDELIVERYSTOP_DATE(rp.date_value2, sdl.standarddeliveryline_id) is_temporarydeliverystop,
      ds.deliveryscheme_id, ds.frequency, ds.offsetweek,
      rp.number_value, rp.number_value1, rp.number_value2, rp.number_value3
    from standarddeliveryline sdl
      left outer join (season s
        left outer join seasonweek sw on s.season_id = sw.season_id)
          on sdl.season_id = s.season_id
      left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id,
      reportparam rp
     where rp.reportparam_id = reportparamid
      and sdl.productlistperdistribpoint_id = productlistperdistribpointid
      and sdl.dateactive <= rp.date_value2
      and sdl.dateinactive > rp.date_value2) LOOP

  LVnTemp := 0;
-- season check
  if (vCursor.season_id is not null) and vCursor.weeknumber <> vCursor.number_value3 then goto y; end if;
-- temporary stop check
  if vCursor.is_temporarydeliverystop <> 0 then goto y; end if;
/*  if vCursor.temporarystopstartweek <> 0 then
    if (vCursor.number_value3 >= vCursor.temporarystopstartweek
        and vCursor.number_value3 <= vCursor.temporarystopendweek) then goto y;
    end if;
  end if;
  if vCursor.temporarystopstartyear <> 0 then
    if F_IsInYearWeekLifespan(
      vCursor.temporarystopstartyear, vCursor.tempstopstartweekforyear,
      vCursor.number_value2, vCursor.number_value3,
      vCursor.temporarystopendyear, vCursor.tempstopendweekforyear) = 1
      then goto y;
    end if;
  end if;*/
-- deliveryscheme check
  if (vCursor.deliveryscheme_id is not null) and
    (not IsWeekDeliveryweek(vCursor.number_value2, vCursor.number_value3, vCursor.frequency, vCursor.offsetweek))
  then goto y; end if;

  select sum(sda.amount)
  into LVnTemp
  from standarddeliveryamount sda
  where sda.standarddeliveryline_id = vCursor.standarddeliveryline_id;

  <<y>>  LVnAmount:=LVnAmount + LVnTemp;
  end loop;
end if;

 return LVnAmount;

end GET_NEEDED;
/
create or replace function get_nextinvoicelevels(fpninvoice_id in invoiceheader.invoiceheader_id%type,
                                                 fpnlevels     in number) return number is
  result number := fpnlevels;
  tmp    number := 0;
  cursor get_invoices is
     select ih2.invoiceheader_id
     from invoiceheader ih, invoiceheader ih2
     where ih2.invoiceheader_id <> ih.invoiceheader_id
       and ih2.invoicebusinessunit_id = ih.invoicebusinessunit_id
       and ih2.documenttype = ih.documenttype
       and ih2.invoicetype = ih.invoicetype
       and ih2.invoicefrequency_id = ih.invoicefrequency_id
       and ih2.deltocustomer_link_id = ih.deltocustomer_link_id
       and ih2.billtocustomer_link_id = ih.billtocustomer_link_id
       --and ih2.credited = 0
       and ih2.status_id = (select st.status_id
                             from status st
                            where st.statustype = 'IN'
                              and st.code = '2')
       and ((ih2.parentinvoiceheader_id is null) or
            (ih2.parentinvoiceheader_id != ih2.invoiceheader_id))
       and ih2.nextperiodstartdate = get_nextperiodstartdate(ih.nextperiodstartdate,
                                                             ih.invoicefrequency_id)

       and exists (select 1
                   from  activityperinvoice api, activityperinvoice api2
                   where api2.activity_id = api.activity_id
                   and api.invoiceheader_id = ih.invoiceheader_id
                   and api2.invoiceheader_id = ih2.invoiceheader_id)

       and ih.invoiceheader_id = fpninvoice_id
       and ih.documenttype = 1
       and ih.invoicetype in (1,6)
       --and ih.invoicenumber > 0
       and ih.status_id = (select st.status_id
                             from status st
                            where st.statustype = 'IN'
                              and st.code = '2')
       --and ih.credited = 0
       and ((ih.parentinvoiceheader_id is null) or
            (ih.parentinvoiceheader_id != ih.invoiceheader_id))
       and ih.nextperiodstartdate is not null
       and rownum = 1;
begin
  for ih_rec in get_invoices loop
     result := result + 1;
     tmp := get_nextinvoicelevels(ih_rec.invoiceheader_id, result);
     result := tmp;
  end loop;
  return(result);
end get_nextinvoicelevels;
/
create or replace function get_nextperiodstartdate(fpdtstartdate          in invoiceheader.nextperiodstartdate%type,
                                                   fpninvoicefrequency_id in invoiceheader.invoicefrequency_id%type)
                                                   return date is
  Result date;
  cursor get_invoicefrequency is
     select if.invoicefrequencynumber
       from invoicefrequency if
      where if.invoicefrequency_id = fpninvoicefrequency_id;
begin
  for if_rec in get_invoicefrequency loop
    case fpninvoicefrequency_id
      when 10 then
          result := fpdtstartdate + 7;
      when 40 then
          begin
            if (getisoweek(fpdtstartdate) = 53) then
                result := fpdtstartdate + 7;
            else
                result := fpdtstartdate + 28;
            end if;
          end;
      when 110 then
          result := add_months(fpdtstartdate,1);
      when 130 then
          result := add_months(fpdtstartdate,3);
      when 160 then
          result := add_months(fpdtstartdate,6);
      when 170 then
          result := add_months(fpdtstartdate,12);
       else
          result := to_date('31-12-2099', 'dd-MM-yyyy');
   end case;
  end loop;
  return(Result);
end get_nextperiodstartdate;
/
create or replace function get_peppol_endpoint(fp_customerid in number)
  return t_peppol_endpoint_tab
  pipelined
  parallel_enable is
  --function get_peppol_endpoint version 0.2
  pragma udf;
  rec_peppol_endpoint peppol_endpoint%rowtype;
  lv_endpointid       varchar2(30);
  lv_cocnumber        varchar2(30);
  lv_vatcode          varchar2(30);

  procedure get_country_code is
  begin
    --get_country_code
    select substr(ct.code, 1, 2), c.cocnumber, replace(replace(c.vatnumber, '.'), ' ')
    into   rec_peppol_endpoint.country_code, lv_cocnumber, lv_vatcode
    from   customer c
    join   country ct
    on     ct.country_id = c.country_id
    where  c.customer_id = fp_customerid;
  end get_country_code;

  procedure get_flexfield_peppol_code is
  begin
    --get_flexfield_peppol_code
    select max(coalesce((select cpv.stringvalue
                         from   characteristicpredefvalue cpv
                         where  cpv.characteristicpredefvalue_id = dff.characteristicpredefvalue_id),
                         (select max(cpv.stringvalue)
                           from   characteristicpredefvalue cpv
                           where  cpv.defaultvalue = 'Y'), 'VAT')) peppol
    into   rec_peppol_endpoint.flexfield_peppol_code
    from   dialogflexfields dff
    where  dff.entity_id = fp_customerid
    and    dff.dialog_id = (select d.dialog_id from dialogs d where d.code = 'Customer')
    and    dff.characteristic_id =
           (select ch.characteristic_id from characteristic ch where ch.code = 'PEPPOL');
    --if empty default is VAT
    rec_peppol_endpoint.flexfield_peppol_code := nvl(rec_peppol_endpoint.flexfield_peppol_code,
                                                     'VAT');
  end get_flexfield_peppol_code;

  procedure get_schemeid is
  begin
    --get_schemeid
    select max(pe.schemeid)
    into   rec_peppol_endpoint.schemeid
    from   peppol_endpoint pe
    where  pe.country_code = rec_peppol_endpoint.country_code
    and    pe.flexfield_peppol_code = rec_peppol_endpoint.flexfield_peppol_code;
    --if empty default is 0088
    rec_peppol_endpoint.schemeid := nvl(rec_peppol_endpoint.schemeid, '0088');
  end get_schemeid;

  procedure get_enddpointid is
  begin
    --get_enddpointid
    case rec_peppol_endpoint.flexfield_peppol_code
      when 'GLN' then
        select max(cg.globallocationnumber)
        into   lv_endpointid
        from   customergeneral cg
        where  cg.customer_id = fp_customerid;
      when 'VAT' then
        lv_endpointid := lv_vatcode;
      when 'COC' then
        lv_endpointid := lv_cocnumber;
      else
        raise no_data_found;
    end case;
  end get_enddpointid;
begin
  --get country code
  get_country_code;
  --get flexfield peppol code
  get_flexfield_peppol_code;
  --get scheme id
  get_schemeid;
  --get endpoint id
  get_enddpointid;
  --return values
  pipe row(t_peppol_endpoint(fp_customerid, rec_peppol_endpoint.schemeid, lv_endpointid,
                             rec_peppol_endpoint.country_code, lv_vatcode));
exception
  when no_data_found then
    begin
      --return empty values
      pipe row(t_peppol_endpoint(fp_customerid, null, null, null, null));
    end;
end get_peppol_endpoint;
/
create or replace function get_peppol_legalentity(fp_legalentityid in number)
  return t_peppol_endpoint_tab
  pipelined
  parallel_enable is
  --function get_peppol_legalentity version 0.2
  pragma udf;
  rec_peppol_endpoint peppol_endpoint%rowtype;
  lv_endpointid       varchar2(30);
  lv_cocnumber        varchar2(30);
  lv_vatcode          varchar2(30);

  procedure get_country_code is
  begin
    --get_country_code
    select substr(ct.code, 1, 2), le.cocnumber, replace(replace(le.vatnumber, '.'), ' ')
    into   rec_peppol_endpoint.country_code, lv_cocnumber, lv_vatcode
    from   legalentity le
    join   country ct
    on     ct.country_id = le.country_id
    where  le.legalentity_id = fp_legalentityid;
  end get_country_code;

  procedure get_flexfield_peppol_code is
  begin
    --get_flexfield_peppol_code
    select max(coalesce((select cpv.stringvalue
                         from   characteristicpredefvalue cpv
                         where  cpv.characteristicpredefvalue_id = dff.characteristicpredefvalue_id),
                         (select max(cpv.stringvalue)
                           from   characteristicpredefvalue cpv
                           where  cpv.defaultvalue = 'Y'), 'VAT')) peppol
    into   rec_peppol_endpoint.flexfield_peppol_code
    from   dialogflexfields dff
    where  dff.entity_id = fp_legalentityid
    and    dff.dialog_id = (select d.dialog_id from dialogs d where d.code = 'LegalEntity')
    and    dff.characteristic_id =
           (select ch.characteristic_id from characteristic ch where ch.code = 'PEPPOL_LEGAL');
    --if empty default is VAT
    rec_peppol_endpoint.flexfield_peppol_code := nvl(rec_peppol_endpoint.flexfield_peppol_code,
                                                     'VAT');
  end get_flexfield_peppol_code;

  procedure get_schemeid is
  begin
    --get_schemeid
    select max(pe.schemeid)
    into   rec_peppol_endpoint.schemeid
    from   peppol_endpoint pe
    where  pe.country_code = rec_peppol_endpoint.country_code
    and    pe.flexfield_peppol_code = rec_peppol_endpoint.flexfield_peppol_code;
    --if empty default is 0088
    rec_peppol_endpoint.schemeid := nvl(rec_peppol_endpoint.schemeid, '0088');
  end get_schemeid;

  procedure get_enddpointid is
  begin
    --get_enddpointid
    case rec_peppol_endpoint.flexfield_peppol_code
      when 'VAT' then
        lv_endpointid := lv_vatcode;
      when 'GLN' then
        --for now mis-use the fax as gln-number
        select max(le.fax)
        into   lv_endpointid
        from   legalentity le
        where  le.legalentity_id = fp_legalentityid;
      when 'COC' then
        lv_endpointid := lv_cocnumber;
      else
        raise no_data_found;
    end case;
  end get_enddpointid;
begin
  --get country code
  get_country_code;
  --get flexfield peppol code
  get_flexfield_peppol_code;
  --get scheme id
  get_schemeid;
  --get endpoint id
  get_enddpointid;
  --return values
  pipe row(t_peppol_endpoint(fp_legalentityid, rec_peppol_endpoint.schemeid, lv_endpointid,
                             rec_peppol_endpoint.country_code, lv_vatcode));
exception
  when no_data_found then
    begin
      --return empty values
      pipe row(t_peppol_endpoint(fp_legalentityid, null, null, null, null));
    end;
end get_peppol_legalentity;
/
create or replace function get_peppol_schemeid(fp_countrycode   in varchar2,
                                               fp_flexfieldcode in varchar2) return varchar2 is
  lv_schemeid varchar2(4);
begin
  --get_peppol_schemeid version 0.2
  select max(pe.schemeid)
  into   lv_schemeid
  from   peppol_endpoint pe
  where  pe.country_code = substr(fp_countrycode, 1, 2)
  and    pe.flexfield_peppol_code = trim(upper(fp_flexfieldcode));
  --if empty default is 0088
  return(nvl(lv_schemeid, '0088'));
end get_peppol_schemeid;
/
create or replace function Get_Prod_Delivery_Days(productlistpercustomerID IN productlistpercustomer.productlistpercustomer_id%TYPE)
return  varchar2 is
  sir   varchar2(1000);
begin
  sir := '';
for vCursor in( select DISTINCT d.daynumber
                from productdeliveryday pdd, day d
                where pdd.day_id = d.day_id AND pdd.productlistpercustomer_id = productlistpercustomerID
                order by daynumber
                ) LOOP
     if  ltrim(rtrim(Vcursor.daynumber)) is not null then
         sir:= concatenate3(sir, ltrim(rtrim(castNumberAsVarchar(Vcursor.daynumber))), ' ');
     else
         sir:= concat(sir, ' ');
     end if;
end loop;
return(sir);
end Get_Prod_Delivery_Days;
/
create or replace function get_qtyforresidential(cdnnumber in clientdeliverynote.clientdeliverynotenumber%type, cdnline clientdeliverynoteline.clientdeliverynoteline_id%type, wscode workstation.code%type) return number is
qty number:=0;
vcdn clientdeliverynote.clientdeliverynotenumber%type;
vcdl clientdeliverynoteline.clientdeliverynoteline_id%type;
vtrans number;
vtrans2 number:=0;
vcdn2 clientdeliverynote.clientdeliverynotenumber%type;
vcdl2 clientdeliverynoteline.clientdeliverynoteline_id%type;
BEGIN
for vCursor in( select distinct risc.uniqueresidentialitem_link_id
         from residentialitemscan risc
         where risc.clientdeliverynotenumber=cdnnumber
         and risc.clientdeliverynoteline_id=cdnline
         and risc.transactiontype_id in (2,81)
         and risc.scanstation=wscode
                ) LOOP
         select v.clientdeliverynotenumber, v.clientdeliverynoteline_id, v.transactiontype_id into vcdn, vcdl, vtrans from(
         select risc.clientdeliverynotenumber, risc.clientdeliverynoteline_id, risc.transactiontype_id from residentialitemscan risc where
         risc.uniqueresidentialitem_link_id=vCursor.Uniqueresidentialitem_Link_Id
         and risc.transactiontype_id in (2,81)
         and risc.scanstation=wscode
         order by nvl(risc.clientdeliverynotenumber,0), nvl(risc.clientdeliverynoteline_id,0) desc
         ) v  where rownum=1;
         if vtrans=81 then
        for vcursor2 in(    select 1 vtrans2, risc.clientdeliverynotenumber vcdn2, risc.clientdeliverynoteline_id vcdl2 from residentialitemscan risc where
            risc.uniqueresidentialitem_link_id=vCursor.Uniqueresidentialitem_Link_Id
            and risc.transactiontype_id=2) loop

               if   vcursor2.vtrans2>0 then
                  if vcursor2.vcdn2=cdnnumber and vcursor2.vcdl2=cdnline then qty:=qty+1;
                  elsif vcursor2.vcdn2=cdnnumber and vcursor2.vcdl2 is null then qty:=qty+1;
                  elsif vcursor2.vcdn2 is null then qty:=qty+1;
                  end if;
         end if;
         end loop;
         end if;
         if vtrans=2 then qty:=qty+1; end if;
END LOOP;
return qty;
END;


/
create or replace function get_qtyloss(
 invoiceheaderid in invoiceheader.invoiceheader_id%type,
productid in product.product_id%type,
amount in uniqueitemloss.creditamount%type,
ragtype in number
 )
 return number is
 qty number;
 begin
   qty:=0;

 case   when ragtype=0 then
    select count(1)
      into qty
      from uniqueitemloss uil, uniqueitem ui
     where uil.creditinvoiceheader_id = invoiceheaderid
       and uil.uniqueitem_link_id = ui.uniqueitem_id
       and uil.lossstatus <> 5
       and uil.creditamount = amount
       and ui.product_id = productid;
  when ragtype = 1 then
    select count(1)
      into qty
      from uniqueitemloss uil, raggeditem ri
     where uil.creditinvoiceheader_id = invoiceheaderid
       and uil.lossstatus <> 5
       and uil.creditamount = amount
       and ri.product_link_id = productid
        and uil.uniqueitem_link_id = ri.raggeditem_id;
        end case;
    return qty;

end get_qtyloss;
/
create or replace function get_qtylossDEBIT(
 invoiceheaderid in invoiceheader.invoiceheader_id%type,
productid in product.product_id%type
 )
 return number is
 qty number;
 qtyrag number;
 begin
   qty:=0;
   qtyrag:=0;

 select count(1) into qty
from uniqueitemloss         uil,
      uniqueitem ui
where uil.lossinvoiceheader_id = invoiceheaderid
   and uil.uniqueitem_link_id = ui.uniqueitem_id
   and uil.lossstatus <> 5
   and ui.product_id = productid;

     select count(1)
      into qtyrag
      from uniqueitemloss uil, raggeditem ri
     where uil.lossinvoiceheader_id = invoiceheaderid
       and uil.lossstatus <> 5
       and ri.product_link_id = productid
        and uil.uniqueitem_link_id = ri.raggeditem_id;
        qty:=qty+qtyrag;
           return qty;
end get_qtylossDEBIT;
/
create or replace function GET_REQMATS
  (startdate                  reportparam.date_value1%type,
   productlistperdistribpointid   productlistperdistribpoint.productlistperdistribpoint_id%type
  ) return  number is
  LVnAmount          number;
  LVnTemp            number;
  LVnYear            number;
  LVnWeek            number;
begin
    LVnAmount:=0;
    -- SET DATE, YEAR, WEEK
    LVnYear:=Year(startdate);
    LVnWeek:=GETISOWEEK(startdate);
    if LVnWeek=53 and month(startdate)=1 then LVnYear:=LVnYear-1; end if;
    --test
    <<loop1>>
    for vCursor in(
      select distinct sdl.standarddeliveryline_id, --getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear) sdadate,
        s.season_id, nvl(sw.weeknumber, 0) weeknumber,
       -- istemporarydeliverystop_date(getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear), sdl.standarddeliveryline_id) is_temporarydeliverystop,
        ISTEMPORARYDELIVERYSTOP4(LVnYear, LVnWeek, getdateforweekyear(sda.day_id, LVnWeek, LVnYear), sdl.standarddeliveryline_id) isdeliverystop,
        ds.deliveryscheme_id, ds.frequency, ds.offsetweek,
        d.customer_id, d.department_id
      from standarddeliveryline sdl
        left outer join (season s
          left outer join seasonweek sw on s.season_id = sw.season_id)
            on sdl.season_id = s.season_id
        left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id,
        productlistperdistribpoint plpd, distributionpoint dp, department d, standarddeliveryamount sda
       where sdl.productlistperdistribpoint_id = productlistperdistribpointid and sda.standarddeliveryline_id=sdl.standarddeliveryline_id
        and sdl.dateactive <= startdate and sdl.dateinactive > startdate and exists
                     (select a.standarddeliveryline_id
                            from   standarddeliveryamount a
                            where  a.standarddeliveryline_id = sdl.standarddeliveryline_id and
                                   a.amount > 0)
        and sdl.productlistperdistribpoint_id = plpd.productlistperdistribpoint_id
        and plpd.distributionpoint_id = dp.distributionpoint_id
        and dp.department_id = d.department_id
        and (select c.dateinactive from customer c where c.customer_id= d.customer_id)>startdate
                                   ) LOOP
    LVnTemp := 0;
    -- season check
    if (vCursor.season_id is not null) and vCursor.weeknumber <> LVnWeek then goto x; end if;
    -- temporary stop check
    -- if vCursor.is_temporarydeliverystop <> 0 then goto x; end if;
      --  stop check
     if vCursor.isdeliverystop <> 0 then goto x; end if;
    -- deliveryscheme check
    if (vCursor.deliveryscheme_id is not null) and
      (not IsWeekDeliveryweek(LVnYear, LVnWeek, vCursor.frequency, vCursor.offsetweek))
    then goto x; end if;
    -- get amount
    select nvl(sum(sda.amount), 0) into LVnTemp
      from standarddeliveryamount sda
     where sda.standarddeliveryline_id = vCursor.Standarddeliveryline_Id
       and (select count(1)
              from nonbusinessday nbd
             where nbd.customer_id = vCursor.Customer_Id
               and nbd.department_id = vCursor.Department_Id
               and nbd.nonbusinessday = getdateforweekyear(sda.day_id, LVnWeek, LVnYear)) = 0;
    <<x>>  LVnAmount:=LVnAmount + LVnTemp;
    if LVnAmount is null then LVnAmount:=0; end if;
  end loop loop1;
  return LVnAmount;
end GET_REQMATS;
/
create or replace function GET_REQMATS_SMG
  (startdate                  reportparam.date_value1%type,
   productlistperdistribpointid   productlistperdistribpoint.productlistperdistribpoint_id%type
  ) return  number is
  LVnAmount          number;
  LVnTemp            number;
  LVnYear            number;
  LVnWeek            number;
begin
    LVnAmount:=0;
    -- SET DATE, YEAR, WEEK
    LVnYear:=Year(startdate);
    LVnWeek:=GETISOWEEK(startdate);
    if LVnWeek=53 and month(startdate)=1 then LVnYear:=LVnYear-1; end if;
    --test
    <<loop1>>
    for vCursor in(
      select distinct sdl.standarddeliveryline_id, --getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear) sdadate,
        s.season_id, nvl(sw.weeknumber, 0) weeknumber,
       -- istemporarydeliverystop_date(getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear), sdl.standarddeliveryline_id) is_temporarydeliverystop,
      --  ISTEMPORARYDELIVERYSTOPSMG(LVnYear, LVnWeek, getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear), sdl.standarddeliveryline_id) isdeliverystop,
        ds.deliveryscheme_id, ds.frequency, ds.offsetweek,
        d.customer_id, d.department_id
      from standarddeliveryline sdl
        left outer join (season s
          left outer join seasonweek sw on s.season_id = sw.season_id)
            on sdl.season_id = s.season_id
        left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id,
        productlistperdistribpoint plpd, distributionpoint dp, department d, standarddeliveryamount sda
       where sdl.productlistperdistribpoint_id = productlistperdistribpointid and sda.standarddeliveryline_id=sdl.standarddeliveryline_id
        and sdl.dateactive <= startdate and sdl.dateinactive > startdate and exists
                     (select a.standarddeliveryline_id
                            from   standarddeliveryamount a
                            where  a.standarddeliveryline_id = sdl.standarddeliveryline_id and
                                   a.amount > 0)
        and sdl.productlistperdistribpoint_id = plpd.productlistperdistribpoint_id
        and plpd.distributionpoint_id = dp.distributionpoint_id
        and dp.department_id = d.department_id
        and (select c.dateinactive from customer c where c.customer_id= d.customer_id)>startdate
                                   ) LOOP
    LVnTemp := 0;
    -- season check
    if (vCursor.season_id is not null) and vCursor.weeknumber <> LVnWeek then goto x; end if;
    -- temporary stop check
    -- if vCursor.is_temporarydeliverystop <> 0 then goto x; end if;
      --  stop check
   --  if vCursor.isdeliverystop <> 0 then goto x; end if;
    -- deliveryscheme check
    if (vCursor.deliveryscheme_id is not null) and
      (not IsWeekDeliveryweek(LVnYear, LVnWeek, vCursor.frequency, vCursor.offsetweek))
    then goto x; end if;
    -- get amount
    select nvl(sum(sda.amount), 0) into LVnTemp
      from standarddeliveryamount sda
     where sda.standarddeliveryline_id = vCursor.Standarddeliveryline_Id
       and (select count(1)
              from nonbusinessday nbd
             where nbd.customer_id = vCursor.Customer_Id
               and nbd.department_id = vCursor.Department_Id
               and nbd.nonbusinessday = getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear)) = 0
               and ISTEMPORARYDELIVERYSTOPSMG(LVnYear, LVnWeek, getdateforweekyearSMG(sda.day_id, LVnWeek, LVnYear), sda.standarddeliveryline_id)=0;
    <<x>>  LVnAmount:=LVnAmount + LVnTemp;
    if LVnAmount is null then LVnAmount:=0; end if;
  end loop loop1;
  return LVnAmount;
end GET_REQMATS_SMG;
/
create or replace function GET_REQUIREMENTS
  (reportparamid                  reportparam.reportparam_id%type,
   productlistperdistribpointid   productlistperdistribpoint.productlistperdistribpoint_id%type
  ) return  varchar2 is

  LVnAmount          number;
  LVnTemp            number;

  startdate          reportparam.date_value1%type;
  noofweeks          reportparam.number_value%type;
  LVnYear            number;
  LVnWeek            number;
  cnt                number;
  LVsReturn          varchar2(96);
begin

  select rp.date_value1, rp.number_value1
  into startdate, noofweeks
  from reportparam rp
  where rp.reportparam_id = reportparamid;

  LVsReturn:='';
  cnt:=1;
  <<loop1>>
  while cnt <= noofweeks loop
    LVnAmount:=0;
    -- SET DATE, YEAR, WEEK
    if cnt <> 1 then startdate:=startdate+7; end if;
    LVnYear:=Year(startdate);
    LVnWeek:=GETISOWEEK(startdate);
    --test
--   LVsReturn:=LVsReturn || ' ' || castnumberasvarcharwithformat(LVnWeek, '999999');
    <<loop2>>
    for vCursor in(
      select sdl.standarddeliveryline_id,
        s.season_id, nvl(sw.weeknumber, 0) weeknumber,
        ISTEMPORARYDELIVERYSTOP2(LVnYear, LVnWeek, sdl.standarddeliveryline_id) is_temporarydeliverystop,
--        sdl.temporarystopendweek, sdl.temporarystopstartweek, sdl.temporarystopstartyear,
--        sdl.temporarystopendyear, sdl.tempstoprentforweek, sdl.tempstoprentforyearweek,
--        sdl.tempstopstartweekforyear, sdl.tempstopendweekforyear,
        ds.deliveryscheme_id, ds.frequency, ds.offsetweek,
        d.customer_id, d.department_id
      from standarddeliveryline sdl
        left outer join (season s
          left outer join seasonweek sw on s.season_id = sw.season_id)
            on sdl.season_id = s.season_id
        left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id,
        productlistperdistribpoint plpd, distributionpoint dp, department d
       where sdl.productlistperdistribpoint_id = productlistperdistribpointid
        and sdl.dateactive <= startdate and sdl.dateinactive > startdate and exists
                     (select a.standarddeliveryline_id
                            from   standarddeliveryamount a
                            where  a.standarddeliveryline_id = sdl.standarddeliveryline_id and
                                   a.amount > 0)
        and sdl.productlistperdistribpoint_id = plpd.productlistperdistribpoint_id
        and plpd.distributionpoint_id = dp.distributionpoint_id
        and dp.department_id = d.department_id
/*(      select sdl.standarddeliveryline_id,
        s.season_id, sw.weeknumber,
        sdl.temporarystopstartweek, sdl.temporarystopendweek,
        sdl.temporarystopstartyear, sdl.temporarystopendyear,
        sdl.tempstoprentforweek, sdl.tempstoprentforyearweek,
        sdl.tempstopstartweekforyear, sdl.tempstopendweekforyear,
        ds.deliveryscheme_id, ds.frequency, ds.offsetweek
      from standarddeliveryline sdl
        left outer join (season s
          left outer join seasonweek sw on s.season_id = sw.season_id)
            on sdl.season_id = s.season_id
        left outer join deliveryscheme ds on sdl.deliveryscheme_id = ds.deliveryscheme_id
       where sdl.productlistperdistribpoint_id = productlistperdistribpointid
        and sdl.dateactive <= startdate
        and sdl.dateinactive > startdate)   */
                                   ) LOOP

    LVnTemp := 0;
    -- season check
    if (vCursor.season_id is not null) and vCursor.weeknumber <> LVnWeek then goto x; end if;
    -- temporary stop check
    if vCursor.is_temporarydeliverystop <> 0 then goto x; end if;
/*    if vCursor.temporarystopstartweek <> 0 then
      if (LVnWeek >= vCursor.temporarystopstartweek
          and LVnWeek <= vCursor.temporarystopendweek) then goto x;
      end if;
    end if;
    if vCursor.temporarystopstartyear <> 0 then
      if F_IsInYearWeekLifespan(
        vCursor.temporarystopstartyear, vCursor.tempstopstartweekforyear,
        LVnYear, LVnWeek,
        vCursor.temporarystopendyear, vCursor.tempstopendweekforyear) = 1
        then goto x;
      end if;
    end if;*/
    -- deliveryscheme check
    if (vCursor.deliveryscheme_id is not null) and
      (not IsWeekDeliveryweek(LVnYear, LVnWeek, vCursor.frequency, vCursor.offsetweek))
    then goto x; end if;

    -- get amount
/*    select sum(sda.amount) into LVnTemp
    from standarddeliveryamount sda
    where sda.standarddeliveryline_id = vCursor.standarddeliveryline_id;*/

    select nvl(sum(sda.amount), 0) into LVnTemp
      from standarddeliveryamount sda
     where sda.standarddeliveryline_id = vCursor.Standarddeliveryline_Id
       and (select count(1)
              from nonbusinessday nbd
             where nbd.customer_id = vCursor.Customer_Id
               and nbd.department_id = vCursor.Department_Id
               and nbd.nonbusinessday = getdateforweekyear(sda.day_id, LVnWeek, LVnYear)) = 0;

    <<x>>  LVnAmount:=LVnAmount + LVnTemp;
    end loop loop1;

    if LVnAmount is null then LVnAmount:=0; end if;
    LVsReturn:=LVsReturn || ' ' || castnumberasvarcharwithformat(LVnAmount, '999999');
    cnt := cnt + 1;
  end loop loop2;

  return LVsReturn;

end GET_REQUIREMENTS;
/
create or replace function GET_ROUTEANDFILTER
(reportparamid in     reportparam.reportparam_id%type,
 customerid in        customer.customer_id%type)
return number is -- routenumber '999999', route desc '.. 30 char ..'
  isprintperroute  number;
  routeid          number;
  minroute         number;
  maxroute         number;
  type Tcsr is ref cursor ;
  Vcsr Tcsr;
begin

--RETURN 641;

  begin
    SELECT RP.NUMBER_VALUE, RP.NUMBER_VALUE1, RP.NUMBER_VALUE2
    INTO isprintperroute, minroute, maxroute
    FROM REPORTPARAM RP
    WHERE RP.REPORTPARAM_ID = reportparamid;
  exception
    when others then return -1;
  end;

  if isprintperroute = 1 then -- have to return routenumber
    begin
      select min(r1.route_id)
      into routeid
      from routestop rs1,customer c1,route r1,customerdeliveryday cdd1
      where rs1.route_id = r1.route_id
        and rs1.customer_id = c1.customer_id
        and cdd1.customer_id = c1.customer_id
        and cdd1.customer_id = customerid
        and cdd1.typeofmerchadise = 2
        and r1.routenumber between minroute and maxroute
        and cdd1.day_id = (select min(cdd.day_id)
      from routestop rs,customer c,route r,customerdeliveryday cdd
      where rs.route_id = r.route_id
        and rs.customer_id = c.customer_id
        and cdd.customer_id = c.customer_id
        and cdd.typeofmerchadise = 2
        and cdd.customer_id = customerid
        and r.routenumber between minroute and maxroute);
      return routeid;
    end;
  else -- only filter on route
    begin
      if minroute = 0 and maxroute = 999999 then return -1; -- select all route so don't filter
      else
        begin
          open Vcsr for
             select r.route_id
             from routestop rs,customer c,route r,customerdeliveryday cdd
             where rs.route_id = r.route_id
               and rs.customer_id = c.customer_id
               and cdd.customer_id = c.customer_id
               and cdd.typeofmerchadise = 2
               and cdd.customer_id = customerid
               and r.routenumber between minroute and maxroute;
          fetch Vcsr into routeid;
        exception when no_data_found then return -1;
        end;
      end if;
    end;
  end if;

  return routeid;

end GET_ROUTEANDFILTER;
/
create or replace function GET_ROUTESTOPFREQUENCY
(reportparamid in     reportparam.reportparam_id%type,
 customerid in        customer.customer_id%type)
return varchar2 is  -- routenumber '999999', stopnumber '999999', scheme AAAAAA
  type Tcsr is ref cursor ;
  Vcsr Tcsr;
  routeno             route.routenumber%type;
  stopno              routestop.stopnumber%type;
  schemecode          deliveryscheme.code%type;
begin

--return to_char(customerid);

  begin
    open Vcsr for
    select r.routenumber, rs.stopnumber, ds.code
    from deliveryschemesperstop dss, deliveryscheme ds, customer cu,
      routestop rs, route r, reportparam rp
    where dss.deliveryscheme_id = ds.deliveryscheme_id
      and dss.customer_id = cu.customer_id
      and dss.routestop_id = rs.routestop_id
      and r.route_id = rs.route_id
      and r.routenumber between rp.number_value1 and rp.number_value2
      and cu.customer_id = customerid
      and rp.reportparam_id = reportparamid
    order by dss.day_id, ds.frequency;
  fetch Vcsr into routeno, stopno, schemecode;
  exception when no_data_found then return NULL;
  end;

  return concatenate3(CASTNUMBERASVARCHARWITHFORMAT(routeno, '999999'), CASTNUMBERASVARCHARWITHFORMAT(stopno, '999999'), leftpad(schemecode, 6, ' '));

end GET_ROUTESTOPFREQUENCY;
/
create or replace function get_serviceemblemcharge(fp_emblemtemplatelineid in number,
                                                   fp_emblemtype           in number default null,
                                                   fp_pricedate            in date default trunc(sysdate))
  return number is
  fp_chargelinesum number;
begin
  --get_serviceemblemcharge version 0.1
  select sum(etl.qtypergarment *
              coalesce((select etlp.price
                       from   emblemtemplatelineprice etlp
                       where  etlp.emblemtemplateline_id = etl.emblemtemplateline_id
                       and    etlp.startdate =
                              (select max(etlp2.startdate)
                                from   emblemtemplatelineprice etlp2
                                where  etlp2.emblemtemplateline_id = etlp.emblemtemplateline_id
                                and    etlp2.startdate <= nvl(fp_pricedate, trunc(sysdate)))),
                       (select max(gep.price)
                         from   generalemblemprice gep
                         where  gep.product_id = etl.product_id
                         and    gep.sizedefinition_id = etl.sizedefinition_id
                         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 <= nvl(fp_pricedate, trunc(sysdate)))
                         and    exists
                          (select 1
                                 from   pricelistpercustomer plc
                                 where  plc.customer_id = et.customer_id
                                 and    plc.generalpricelist_id = gep.generalpricelist_id)), 0)) chargelinesum
  into   fp_chargelinesum
  from   emblemtemplateline etl
  join   emblemtemplate et
  on     et.emblemtemplate_id = etl.emblemtemplate_id
  where  etl.emblemtemplate_id = fp_emblemtemplatelineid
  and    (fp_emblemtype is null or (fp_emblemtype = etl.emblemtype));
  return(fp_chargelinesum);
end get_serviceemblemcharge;
/
create or replace function GET_SOILRES_CIRCINVENTORY
 (customerno  in customer.customernumber%type,
  productcode in product.code%type,
  sizecode    in sizedefinition.code%type,
  finmethcode in finishingmethod.code%type,
  deldate in       packingnote.deliverydate%type)
return number is
  result             rentalqtyadjustment.quantity%type;
begin

  SELECT sum(rqa.quantity)
  into result
  FROM rentalqtyadjustment rqa, productlistperdistribpoint pld,distributionpoint dp, department dep,
    customer cus, product p, sizedefinition s, finishingmethod f
  WHERE rqa.productlistperdistribpoint_id = pld.productlistperdistribpoint_id
    and pld.distributionpoint_id = dp.distributionpoint_id
    and dp.department_id = dep.department_id
    and dep.customer_id = cus.customer_id
    and pld.product_id = p.product_id
    and pld.sizedefinition_id = s.sizedefinition_id
    and pld.finishingmethod_id = f.finishingmethod_id
    and p.code = productcode
    and s.code = sizecode
    and f.code = finmethcode
    and cus.customernumber = customerno
    and rqa.adjustmentdate <= deldate;

  if  result is null then return 0; end if;
  return result;

end GET_SOILRES_CIRCINVENTORY;
/
create or replace function GET_TABLE_NEXT_ID_FOR_MERGE_CASE(seq_name IN VARCHAR2)
  return number is
  seq_value number;
begin
  execute immediate 'select ' || seq_name || '.NEXTVAL from dual'
    into seq_value;
  return seq_value;
end GET_TABLE_NEXT_ID_FOR_MERGE_CASE;
/
create or replace function get_timediffseconds(p_date1 date, p_date2 date) return number
AS
totalSeconds number;
BEGIN
SELECT ROUND ( EXTRACT (DAY FROM x.timeDiff)  *24 * 60 * 60 +
             EXTRACT (HOUR FROM x.timeDiff) * 60*  60 +
               EXTRACT (MINUTE FROM x.timeDiff) * 60 + EXTRACT (SECOND FROM timeDiff)) into totalSeconds from (
              select (TO_TIMESTAMP(TO_CHAR(p_date1 , 'yyyy-mm-dd HH24:mi:ss'), 'yyyy-mm-dd HH24:mi:ss') - TO_TIMESTAMP(TO_CHAR(p_date2, 'yyyy-mm-dd HH24:mi:ss'),'yyyy-mm-dd HH24:mi:ss')) timediff  from dual
               )x;
return  totalSeconds;
END;
/
create or replace function GET_TOTALSTOCK_QUANTITY
  (productid                      product.product_id%type,
   sizeid                         sizedefinition.sizedefinition_id%type ,
   stockroomid                    stockroom.stockroom_id%type
  ) return  number is
  LVnAmount         number;
begin

   LVnAmount:=0;

    select sum(sq.qtyunique + sq.qtyuniquewithmodifications+ sq.qtynonunique )
    into LVnAmount
    from stockreservationpergrade srg, stockdefinitionperitem sdi, stockquantity sq
    where  srg.stockdefinitionperitem_id = sdi.stockdefinitionperitem_id
    and sq.stockreservationpergrade_id = srg.stockreservationpergrade_id
    and sdi.product_id = productid
    and sdi.sizedefinition_id = sizeid
    and sdi.stockroom_id = stockroomid;
    return LVnAmount;
exception
    when no_data_found then return 0;

end GET_TOTALSTOCK_QUANTITY;
/
create or replace function get_uniqueresidentialitem_ords(fp_primaryid in varchar2,
                                                          fp_loginname in varchar2)
  return sys_refcursor as
  c sys_refcursor;
  --function get_uniqueresidentialitem_ords version 0.1
begin
  open c for
    select bu.code businessunitcode, bu.description businessunit_desc, uri.primaryid,
           c.customernumber, c.name customername, t.departmentnumber, t.description department_desc,
           tr.roomnumber, cl.name clientname,
           case cl.gender
              when 1 then
               'Male'
              when 2 then
               'Female'
              else
               'Unknown'
            end gender, p.code product_code,
           (select pd.description
             from   product_desc pd
             where  pd.product_id = uip.product_id
             and    pd.language_id = c.language_id) product_desc, uip.assigndate, uri.lastinscandate,
           uri.lastoutscandate, uri.lastrewashdate, uri.lastchangedate, uri.numberofwashes,
           uri.numberofrepairs, uri.numberofrewashes,
           case
             when uri.lastoutscandate > uri.lastinscandate or uri.lastinscandate is null then
              round((sysdate - uri.lastoutscandate) / 7, 0)
             else
              0
           end weeks_at_customer,
           nvl((select max('Y')
                from   webuser wu
                join   webusercustomer wuc
                on     wuc.webuser_id = wu.webuser_id
                where  wuc.customer_id = c.customer_id
                and    wu.loginname = fp_loginname), 'N') webuser_match
    from   uniqueresidentialitem uri
    join   businessunit bu
    on     bu.businessunit_id = uri.businessunit_id
    join   client cl
    on     cl.client_id = uri.client_id
    left   join clientresident clr
    on     clr.client_id = uri.client_id
    left   join departmentroom tr
    on     tr.departmentroom_id = clr.departmentroom_id
    left   join department t
    on     t.department_id = tr.department_id
    left   join customer c
    on     c.customer_id = t.customer_id
    left   join uniqueresidentialitemproduct uip
    on     uip.uniqueresidentialitem_id = uri.uniqueresidentialitem_id
    left   join product p
    on     p.product_id = uip.product_id
    where  uri.primaryid = fp_primaryid;
  return c;
end get_uniqueresidentialitem_ords;
/
create or replace function get_weeklyrevenueqty(p_billingmethod productlistpercustomer.billingmethod%type, p_customer customer.customer_id%type, p_product product.product_id%type, p_size sizedefinition.sizedefinition_id%type, p_fm finishingmethod.finishingmethod_id%type, p_distribpoint distributionpoint.distributionpoint_id%type)
return number
AS
WeeklyRevenueQty number:=0;
v_scode sizedefinition.code%type;
begin
  select sd.code into v_scode from sizedefinition sd where sd.sizedefinition_id=p_size;
  if p_billingmethod = 1   then
     if v_scode='*' then
        select /*+parallel INDEX(sqset XIE1SQSETINCIRCULATION)*/
         count(sqset.sqsetincirculation_id) into WeeklyRevenueQty
        from sqsetincirculation sqset
        where sqset.customer_link_id = p_customer
        and sqset.product_link_id = p_product
        and sqset.finishingmethod_id = p_fm
       and (select we.distributionpoint_id from weareremployment we where we.weareremployment_id=sqset.weareremployment_link_id)= p_distribpoint;
        end if;
      if v_scode<>'*' then
          select /*+parallel INDEX(sqset XIE1SQSETINCIRCULATION)*/
           count(sqset.sqsetincirculation_id) into WeeklyRevenueQty
          from sqsetincirculation sqset
          where sqset.customer_link_id = p_customer
          and sqset.product_link_id = p_product
          and sqset.sizedefinition_link_id=p_size
          and sqset.finishingmethod_id = p_fm
        and (select we.distributionpoint_id from weareremployment we where we.weareremployment_id=sqset.weareremployment_link_id)= p_distribpoint;
      end if;
         end if;
  if p_billingmethod = 3 then
     if v_scode='*' then
       select /*+parallel INDEX(sqset XIE1SQSETINCIRCULATION)*/
        sum(sqset.maxinv) into WeeklyRevenueQty
         from sqsetincirculation sqset
         where sqset.customer_link_id = p_customer
         and sqset.product_link_id = p_product
         and sqset.finishingmethod_id = p_fm
          and (select we.distributionpoint_id from weareremployment we where we.weareremployment_id=sqset.weareremployment_link_id)= p_distribpoint;
          end if;
       if v_scode<>'*' then
         select /*+parallel INDEX(sqset XIE1SQSETINCIRCULATION)*/
          sum(sqset.maxinv) into WeeklyRevenueQty
         from sqsetincirculation sqset
         where sqset.customer_link_id = p_customer
         and sqset.product_link_id = p_product
         and sqset.sizedefinition_link_id=p_size
         and sqset.finishingmethod_id = p_fm
         and (select we.distributionpoint_id from weareremployment we where we.weareremployment_id=sqset.weareremployment_link_id)= p_distribpoint;
        end if;
  end if;
  if WeeklyRevenueQty is null then WeeklyRevenueQty:=0; end if;
return WeeklyRevenueQty;
end;
/
create or replace function get_wo_refno(weareremploymentID number,
                                        invoiceheaderID number)
  return varchar2 is
  LVsReturn varchar2(96);
begin
  LVsReturn := '';
  for vCursor in (select distinct (wo.referencenumber)
                    from GARMENTSALESHISTORY gsh,
                         weareremployment    we,
                         wearer              w,
                         workorderline       wol,
                         workorder           wo
                   where gsh.weareremployment_link_id =
                         we.weareremployment_id
                     and we.wearer_id = w.wearer_id
                     and gsh.workorderline_id = wol.workorderline_id
                     and wol.workorder_id = wo.workorder_id
                     and gsh.invoiceheader_id = invoiceheaderID
                     and we.weareremployment_id = weareremploymentID
                   ) loop

  if LVsReturn is null then
    LVsReturn:= vCursor.Referencenumber;
  else
    LVsReturn := LVsReturn  || ', ' || vCursor.Referencenumber ;
  end if;

  end loop;

  return LVsReturn;
end;
/
create or replace function insertspace_after_x_characters (varnumber number, x int)
       return varchar2 is
  res varchar2(100);
  varstring varchar2(100);
  len number;
  i int;
  j int;
begin
  select cast(varnumber as varchar2(100)) into varstring from dual;
  -- xstring:= to_char(x);
   len := length (varstring);
   res := substr (varstring, 1, x);
   i := x+1;
   j := 1;
   while j <= (len -1)/x loop
   res := res || ' ';
   res := res || SUBSTR(varstring,i,x);
   i := i + x;
   j := j + 1;
   end loop;
 return res;
end;
/
create or replace function invalid_objects_for_release return integer is
  status integer;
begin
  status := 0;

  for c in (select 'alter ' || decode(object_type,
                                      'PACKAGE BODY',
                                      'package',
                                      object_type) || ' "' || object_name ||
                   '" compile' ||
                   decode(object_type, 'PACKAGE BODY', ' body', '') ddl
              from user_objects
             where status = 'INVALID'
             order by object_type) loop
    begin
      execute immediate c.ddl;
    exception
      when others then
        status := status + 1;
    end;
  end loop;
  return status;

end invalid_objects_for_release;
/
create or replace function isDeliveryWeek(year      in integer,
                                          week      in integer,
                                          frequency in integer,
                                          offset    in integer)
  return varchar2 is
  Result    varchar2(1);
  firstweek integer;
  weeknr    integer;
begin
  if frequency = 1 then
    Result := 'Y';
  else
    firstWeek := getFirstDeliveryWeekForYear(year, frequency, offset);
    if (firstWeek = frequency) then
      firstWeek := 0;
    end if;
    weeknr := week;
    while (weeknr > firstWeek) loop
      weeknr := weeknr - frequency;
    end loop;
    if (weeknr = firstWeek) then
      Result := 'Y';
    else
      Result := 'N';
    end if;
  end if;
  return(Result);
end isDeliveryWeek;
/
create or replace function isdeliveryweek4date(fp_date      in date,
                                               fp_frequency in number,
                                               fp_offset    in number) return number
  parallel_enable is
  functionresult number;
  --function isdeliveryweek4date version 0.1
  lv_startweekseq number;
  lv_endweekseq   number;
  pragma udf;
begin
  functionresult := 0;
  --get reference year/week
  select dyw.weekseq + fp_offset
  into   lv_startweekseq
  from   databasesettings d
  join   date_yearweekday dyw
  on     dyw.year = d.referenceyear
  and    dyw.week = d.referenceweek
  and    dyw.day = 1;
  --get end year week
  select dyw.weekseq into lv_endweekseq from date_yearweekday dyw where dyw.date_ = fp_date;
  --is delivery week
  if mod(lv_endweekseq - lv_startweekseq, fp_frequency) = 0 then
    functionresult := 1;
  end if;
  --return value
  return(functionresult);
exception
  when no_data_found then
    return 0;
end isdeliveryweek4date;
/
create or replace function IsElevenProof(fpBankaccount in bankinstitution.laundrybankaccount%type) return number
is
  lvResult      number := 0;
  lvAccount     bankinstitution.laundrybankaccount%type;
  lvSumofdigits number := 0;

begin
  if ((length(fpBankaccount) < 9) or (length(fpBankaccount) > 10)) then
     lvResult := 0;
  else
     begin
       lvAccount := lpad(fpBankaccount, 10, 0);
       -- Calculate sum of digits
       lvSumofdigits := lvSumofdigits + (10 * substr(lvAccount,1,1));
       lvSumofdigits := lvSumofdigits + ( 9 * substr(lvAccount,2,1));
       lvSumofdigits := lvSumofdigits + ( 8 * substr(lvAccount,3,1));
       lvSumofdigits := lvSumofdigits + ( 7 * substr(lvAccount,4,1));
       lvSumofdigits := lvSumofdigits + ( 6 * substr(lvAccount,5,1));
       lvSumofdigits := lvSumofdigits + ( 5 * substr(lvAccount,6,1));
       lvSumofdigits := lvSumofdigits + ( 4 * substr(lvAccount,7,1));
       lvSumofdigits := lvSumofdigits + ( 3 * substr(lvAccount,8,1));
       lvSumofdigits := lvSumofdigits + ( 2 * substr(lvAccount,9,1));
       lvSumofdigits := lvSumofdigits + ( 1 * substr(lvAccount,10,1));
       -- Divide sum of digits by 11
       if (mod(lvSumofdigits,11) = 0) then
         lvResult := 1;
       else
         lvResult := 0;
       end if;
     end;
  end if;
  -- Return result
  return(lvResult);
exception
  when OTHERS then
    return 0;
end IsElevenProof;
/
create or replace function ISNUMERIC(FPnCODE in workstation.code%type)
  return integer is
  i integer;
begin
  IF (cast(FPnCODE as numeric)) > 0 THEN
    return 1;
  else
    begin
      i := to_number(FPnCODE);
      if i = 0 then
        return 1;
      end if;
    end;
  END IF;

  return 0;

EXCEPTION
  WHEN OTHERS THEN
    return 0;
end ISNUMERIC;
/
create or replace function IsStraightEvenReturnProd(customerid        in customer.customer_id%type,
                                                    productid         in product.product_id%type,
                                                    sizedefinitionid  in sizedefinition.sizedefinition_id%type,
                                                    finishingmethodid in finishingmethod.finishingmethod_id%type,
                                                    deliverydate      in packingnote.productiondate%type)
  return integer is
  Result integer;

  specialsizeid sizedefinition.sizedefinition_id%type;
  plpcid        productlistpercustomer.productlistpercustomer_id%type;
begin
  Result := 0; -- 1=true 0=false
  select s.sizedefinition_id
    into specialsizeid
    from sizedefinition s
   where s.code = '*';
  plpcid := f_getidcolumnfromactiveplpc(customerid,
                                        productid,
                                        sizedefinitionid,
                                        finishingmethodid,
                                        specialsizeid,
                                        deliverydate,
                                        0);
  if plpcid is not null then
    begin
      select 1
        into Result
        from productlistpercustomer p
       where p.productlistpercustomer_id = plpcid
         and p.straightevenexchange = 'Y';
    exception
      when no_data_found then
        result := 0;
    end;
  else
    result := 0;
  end if;

  return(Result);
end IsStraightEvenReturnProd;
/
create or replace function ISTEMPORARYDELIVERYSTOP
 (yearn      in integer,
  weekn      in integer,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type)
  return integer is
  Result    integer;
begin


  select count(*)
  into Result
  from temporarydeliverystop tds
  where
    tds.standarddeliveryline_id = standarddeliverylineid and
    (
      (yearn*100+weekn between (coalesce(tds.TEMPORARYSTOPSTARTYEAR,0)*100+coalesce(tds.TEMPSTOPSTARTWEEKFORYEAR,0))
       and
      (coalesce(tds.TEMPORARYSTOPENDYEAR,0)*100+coalesce(tds.TEMPSTOPENDWEEKFORYEAR,0)))
    OR
      (yearn*100+weekn between (getYearofWeek(sysdate)*100+(coalesce(tds.TEMPORARYSTOPSTARTWEEK,0)))
       AND
      (F_ENDYEAR(coalesce(tds.TEMPORARYSTOPSTARTWEEK,0),coalesce(tds.TEMPORARYSTOPENDWEEK,0))+coalesce(tds.TEMPORARYSTOPENDWEEK,0)))
    );

  return Result;

end ISTEMPORARYDELIVERYSTOP;
/
create or replace function ISTEMPORARYDELIVERYSTOP2
 (yearn      in integer,
  weekn      in integer,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type)
  return integer is
  Result    integer;
begin

  select count(*)
  into Result
  from temporarydeliverystop tds
  where
    tds.standarddeliveryline_id = standarddeliverylineid and
    (
      (coalesce(tds.temporarystopstartweek,0) <> 0 and weekn between tds.temporarystopstartweek and tds.temporarystopendweek)
     or
       (coalesce(tds.temporarystopstartyear,0) <> 0
        and
       (F_IsInYearWeekLifespan(tds.temporarystopstartyear, tds.tempstopstartweekforyear,
           yearn, weekn, tds.temporarystopendyear, tds.tempstopendweekforyear) = 1)
       )
    );

  return Result;

end ISTEMPORARYDELIVERYSTOP2;
/
create or replace function ISTEMPORARYDELIVERYSTOP3
 (yearn      in integer,
  weekn      in integer,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type,
  dateIn       in date := sysdate)
  return integer is
  Result    integer;

  existsdelivstop integer;
  temp_startdate  date;
  temp_enddate date;
  temp_dstopID long;
  temp_startweek temporarydeliverystop.temporarystopstartweek%type;
  temp_endweek  temporarydeliverystop.temporarystopendweek%type;
  temp_startyear temporarydeliverystop.temporarystopstartyear%type;
  temp_endyear  temporarydeliverystop.temporarystopendyear%type;
  temp_startweekforyear temporarydeliverystop.tempstopstartweekforyear%type;
  temp_endweekforyear temporarydeliverystop.tempstopendweekforyear%type;

  cursor vCursor(lineID standarddeliveryline.standarddeliveryline_id%type) is

    select
          tds.temporarydeliverystop_id,
          tds.startdate,
          tds.enddate,
          tds.temporarystopstartweek,
          tds.temporarystopendweek,
          tds.temporarystopstartyear,
          tds.temporarystopendyear,
          tds.tempstopstartweekforyear,
          tds.tempstopendweekforyear
    from  temporarydeliverystop tds
    where tds.standarddeliveryline_id = lineID;

begin

  Result := 0;

  begin
    select count(*)
    into existsdelivstop
    from  temporarydeliverystop tds
    where tds.standarddeliveryline_id = standarddeliverylineid;
    exception
      when no_data_found then
        existsdelivstop := 0;
  end;

  if(existsdelivstop>0) then

    open vCursor(standarddeliverylineid);

    fetch vCursor
    into temp_dstopID, temp_startdate, temp_enddate, temp_startweek, temp_endweek, temp_startyear, temp_endyear, temp_startweekforyear, temp_endweekforyear;

    while (vCursor%found and Result = 0) loop
      begin

          if (temp_startdate is null and temp_enddate is null) then
              if(
                  ( coalesce(temp_startweek,0) = 0
                    or
                    (weekn between temp_startweek and temp_endweek)
                  )
                 and
                   ( coalesce(temp_startyear,0) = 0
                    or
                      (
                        (
                           (yearn = temp_startyear and weekn >= temp_startweekforyear)
                           or
                           (yearn > temp_startyear)
                        )
                        and
                          (
                            (yearn = temp_endyear and weekn <= temp_endweekforyear)
                            or
                            (yearn < temp_endyear)
                          )
                      )
                   )
                ) then
                Result := Result + 1;
                end if;
            else if (dateIn <> sysdate and temp_startweek = 0 and temp_startyear = 0 and temp_startweekforyear = 0) then
              Result := ISTEMPORARYDELIVERYSTOP_DATE(dateIn, standarddeliverylineid);

            else
              if(
                  (yearn = getyearofweek(temp_startdate)
                    and  (yearn = getyearofweek(temp_enddate)
                    and weekn  between getisoweek(temp_startdate) and getisoweek(temp_enddate))
                  )
                  or
                  ( getyearofweek(temp_startdate) < getyearofweek(temp_enddate)
                     and  yearn = getyearofweek(temp_startdate)
                     and  weekn >= getisoweek(temp_startdate)
                  )
                  or
                  ( getyearofweek(temp_startdate) < getyearofweek(temp_enddate)
                     and  yearn = getyearofweek(temp_enddate)
                     and  weekn <= getisoweek(temp_enddate)
                  )
                  or
                  ( getyearofweek(temp_startdate) < getyearofweek(temp_enddate)
                     and  yearn > getyearofweek(temp_startdate)
                     and  yearn < getisoweek(temp_enddate)
                  )
                ) then
               Result := Result + 1;
               end if;
              end if;
            end if;
      end;

      fetch vCursor
      into temp_dstopID, temp_startdate, temp_enddate, temp_startweek, temp_endweek, temp_startyear, temp_endyear, temp_startweekforyear, temp_endweekforyear;

      end loop;
      close vCursor;
  end if;

  return Result;

end ISTEMPORARYDELIVERYSTOP3;
/
create or replace function ISTEMPORARYDELIVERYSTOP4
 (yearn      in integer,
  weekn      in integer,
  crtdate date,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type)
  return integer is
  Result1    integer;
  Result2    integer;
begin
  select count(*)
  into Result1
  from temporarydeliverystop tds
  where
    tds.standarddeliveryline_id = standarddeliverylineid and
    (( tds.standarddeliveryline_id = standarddeliverylineid and crtdate between tds.startdate and tds.enddate)
    OR
      (coalesce(tds.temporarystopstartweek,0) <> 0 and weekn between tds.temporarystopstartweek and tds.temporarystopendweek)
     or
       (coalesce(tds.temporarystopstartyear,0) <> 0
        and
       (F_IsInYearWeekLifespan(tds.temporarystopstartyear, tds.tempstopstartweekforyear,
           yearn, weekn, tds.temporarystopendyear, tds.tempstopendweekforyear) = 1)
       )
    );
    if Result1>0 then return Result1; end if;
 select count(*)
  into Result2
  from temporarydeliverystop tds
  where tds.standarddeliveryline_id = standarddeliverylineid
    and tds.temporarystopstartweek>tds.temporarystopendweek and
    (
      (coalesce(tds.temporarystopstartweek,0) <> 0 and weekn between tds.temporarystopstartweek and 54)
     OR
      (coalesce(tds.temporarystopendweek,0) <> 0 and weekn between 0 and tds.temporarystopendweek)
    );
  return Result2;
end ISTEMPORARYDELIVERYSTOP4;


/
create or replace function ISTEMPORARYDELIVERYSTOPSMG
 (yearn      in integer,
  weekn      in integer,
  crtdate date,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type)
  return integer is
  Result1    integer;
  Result2    integer;
begin
  select count(*)
  into Result1
  from temporarydeliverystop tds
  where
    tds.standarddeliveryline_id = standarddeliverylineid and
    (( tds.standarddeliveryline_id = standarddeliverylineid and crtdate between tds.startdate and tds.enddate)
    OR
      (coalesce(tds.temporarystopstartweek,0) <> 0 and weekn between tds.temporarystopstartweek and tds.temporarystopendweek)
     or
       (coalesce(tds.temporarystopstartyear,0) <> 0
        and
       (F_IsInYearWeekLifespan(tds.temporarystopstartyear, tds.tempstopstartweekforyear,
           yearn, weekn, tds.temporarystopendyear, tds.tempstopendweekforyear) = 1)
       )
    );
    if Result1>0 then return Result1; end if;

 select count(*)
  into Result2
  from temporarydeliverystop tds
  where tds.standarddeliveryline_id = standarddeliverylineid
    and tds.temporarystopstartweek>tds.temporarystopendweek and
    (
      (coalesce(tds.temporarystopstartweek,0) <> 0 and weekn between tds.temporarystopstartweek and 54)
     OR
      (coalesce(tds.temporarystopendweek,0) <> 0 and weekn between 0 and tds.temporarystopendweek)
    );
  return Result2;
--return result;
end ISTEMPORARYDELIVERYSTOPSMG;
/
create or replace function ISTEMPORARYDELIVERYSTOP_DATE
 (crtDate date,
  standarddeliverylineid in standarddeliveryline.standarddeliveryline_id%type)
  return integer is
  Result    integer;
begin
  select count(*)
  into Result
  from temporarydeliverystop tds
  where
    tds.standarddeliveryline_id = standarddeliverylineid and crtdate between tds.startdate and tds.enddate;
  return Result;
end  ISTEMPORARYDELIVERYSTOP_DATE;
/
create or replace function IsWeekDeliveryweek(
year      in integer,
week      in integer,
frequency in integer,
offset    in integer) return boolean is
  Result              boolean;
  firstweek           integer;
  weeknr              integer;
begin
    if frequency = 1 then  Result:=true;
    else
      firstWeek := getFirstDeliveryWeekForYear(year, frequency, offset);
      if (firstWeek = frequency) then firstWeek := 0; end if;
      weeknr:=week;
      while(weeknr > firstWeek ) loop
      weeknr := weeknr - frequency;
      end loop;
      if (weeknr = firstWeek) then Result:= true;
      else Result:= false;
      end if;
    end if;
  return(Result);
end IsWeekDeliveryweek;
/
create or replace function isweekdeliveryweeknumeric(
year      in integer,
week      in integer,
frequency in integer,
offset    in integer) return integer is
  Result              integer;
  firstweek           integer;
  weeknr              integer;
begin
    if frequency = 1 then  Result := 1;
    else
      firstWeek := getFirstDeliveryWeekForYear(year, frequency, offset);
      if (firstWeek = frequency) then firstWeek := 0; end if;
      weeknr:=week;
      while(weeknr > firstWeek ) loop
      weeknr := weeknr - frequency;
      end loop;
      if (weeknr = firstWeek) then Result:= 1;
      else Result:= 0;
      end if;
    end if;
  return(Result);
end isweekdeliveryweeknumeric;
/
create or replace function isworkorderonpicklist(P_WorkOrder_ID in Number)
  return char is
  Result           char;
  v_origin         numeric;
  v_no_of_lines    numeric;
  v_no_of_lines_as numeric;

begin
  SELECT wo.origin
    INTO v_origin
    FROM workorder wo
   WHERE wo.workorder_id = p_workorder_id;

  SELECT count(*)
    INTO v_no_of_lines
    FROM PICKLISTLINEORIGIN plo
   WHERE plo.BaseLineType = v_origin
     AND upper(plo.BaseLineTable) = 'WORKORDERLINE'
     AND EXISTS
   (SELECT 1
            FROM WORKORDERLINE wol
           WHERE wol.WorkOrder_ID = p_WorkOrder_ID
             AND wol.WorkOrderLine_ID = plo.baselinetable_link_id);

  SELECT count(*)
    INTO v_no_of_lines_as
    FROM PICKLISTLINEORIGINAS plo
   WHERE plo.BaseLineType = v_origin
     AND upper(plo.BaseLineTable) = 'WORKORDERLINE'
     AND EXISTS
   (SELECT 1
            FROM WORKORDERLINE wol
           WHERE wol.WorkOrder_ID = p_WorkOrder_ID
             AND wol.WorkOrderLine_ID = plo.baselinetable_link_id);

  IF ((v_no_of_lines + v_no_of_lines_as) > 0) THEN
    Result := 'Y';
  ELSE
    Result := 'N';
  end if;
  return(Result);
end isworkorderonpicklist;
/
create or replace function leftPad(
		FPstring varchar2,
		FPpos number,
		FPchar char
) return varchar2 is
begin
  return lpad(FPstring, FPpos, FPchar);
end ;
/
create or replace function Month(vDate	date) return int is
begin
	return cast(to_char(vDate, 'MM') as numeric);
end;
/
create or replace function plpc_lookup(pcustomerid        in number,
                                       pproductid         in number,
                                       psizeid            in number,
                                       pfinishingmethodid in number,
                                       pdate              in date) return number
  parallel_enable is
    /***************************************************************************************\
    * -- Author     : PVD                                                                   *
    * -- Created    : 2025-03-24 ABSN-462, used to determine the productlistpercustomer_id  *
    *                            from the PLPC matching precise size,                       *
    *                            or size * if precise size does not exist in PLPC           *
    * -- Version    : 1.0                                                                   *
    * -- Updated    :                                                                       *
    * -- Remarks    :                                                                       *
    \***************************************************************************************/
  plpcid number;
  --function plpc_lookup, returns plpc id
  pragma udf;
begin
  for x in (select case
                     when plpc.sizedefinition_id = psizeid then
                      0
                     else
                      1
                   end sizecheck, plpc.productlistpercustomer_id
            from   productlistpercustomer plpc
            where  plpc.customer_id = pcustomerid
            and    plpc.product_id = pproductid
            and    (plpc.sizedefinition_id = psizeid or
                  plpc.sizedefinition_id =
                  (select s.sizedefinition_id from sizedefinition s where s.code = '*'))
            and    plpc.finishingmethod_id = pfinishingmethodid
            and    pdate between plpc.dateactive and plpc.dateinactive
            order  by 1) loop
    begin
      plpcid := x.productlistpercustomer_id;
      exit;
    end;
  end loop;
  return (plpcid);
exception
  when no_data_found then
    return(0);
end plpc_lookup;
/
create or replace function printclientdelnote(fp_notenumber in varchar2,
                                              fp_sysuser    in varchar2,
                                              fp_bucode     in varchar2,
                                              fp_wscode     in varchar2,
                                              fp_url        in varchar2) return clob is
  --function printclientdelnote version 1.1
  /*ABS-169689 print_clientdeliverynote rest call for update 90800
    ABS-170641 Database objects that use apex_web_service, put on Standard*/

  --build json object
  lv_body clob := '{
    "dialogCode" : "OutscanSort",
    "noteNr" : "' || fp_notenumber || '",
    "sysUser" : "' || fp_sysuser || '",
    "buCode" : "' || fp_bucode || '",
    "wsCode" : "' || fp_wscode || '"
}';
begin
  /*--rest service call
  utl_http.set_body_charset('UTF-8');
  apex_web_service.g_request_headers.delete();
  apex_web_service.g_request_headers(1).name := 'Content-Type';
  apex_web_service.g_request_headers(1).value := 'application/json';
  return apex_web_service.make_rest_request(p_url => fp_url, p_http_method => 'POST',
                                            p_body => lv_body);*/
  return 'Apex not installed yet';
end printclientdelnote;
/
create or replace function productgroupformat(fp_productgroupid in number) return varchar2 is
  result varchar2(255);
begin
  select max(g.code) into result from productgroup g where g.productgroup_id = fp_productgroupid;
  if substr(result, 1, 1) = 'L' then
    result := 'LINEN DELIVERY';
  else
    case result
      when '111' then
        result := 'GARMENTS FOR DELIVERY';
      when '112' then
        result := 'GARMENTS FOR DELIVERY';
      when '340' then
        result := 'GARMENTS FOR DELIVERY';
      when '500' then
        result := 'GARMENTS FOR DELIVERY';
      when '021' then
        result := 'LINEN DELIVERY';
      when '310' then
        result := 'LINEN DELIVERY';
      when '320' then
        result := 'LINEN DELIVERY';
      when '330' then
        result := 'LINEN DELIVERY';
      when '412' then
        result := 'LINEN DELIVERY';
      when '031' then
        result := 'MAT FOR DELIVERY';
      when '032' then
        result := 'MAT FOR DELIVERY';
      when '033' then
        result := 'MAT FOR DELIVERY';
      when '034' then
        result := 'MAT FOR DELIVERY';
      when '041' then
        result := 'MAT FOR DELIVERY';
      when '202' then
        result := 'MAT FOR DELIVERY';
      when '403' then
        result := 'MAT FOR DELIVERY';
      when '011' then
        result := 'WASHROOM FOR DELIVERY';
      when '012' then
        result := 'WASHROOM FOR DELIVERY';
      when '081' then
        result := 'WASHROOM FOR DELIVERY';
      when '091' then
        result := 'WASHROOM FOR DELIVERY';
      when '201' then
        result := 'WASHROOM FOR DELIVERY';
      when '203' then
        result := 'WASHROOM FOR DELIVERY';
      when '221' then
        result := 'WASHROOM FOR DELIVERY';
      when '231' then
        result := 'WASHROOM FOR DELIVERY';
      when '400' then
        result := 'WASHROOM FOR DELIVERY';
      when '410	' then
        result := 'WASHROOM FOR DELIVERY';
      when '420	' then
        result := 'WASHROOM FOR DELIVERY';
      when '435	' then
        result := 'WASHROOM FOR DELIVERY';
      when '440	' then
        result := 'WASHROOM FOR DELIVERY';
      when '450	' then
        result := 'WASHROOM FOR DELIVERY';
      when '460	' then
        result := 'WASHROOM FOR DELIVERY';
      when '470	' then
        result := 'WASHROOM FOR DELIVERY';
      when '482	' then
        result := 'WASHROOM FOR DELIVERY';
      when '490	' then
        result := 'WASHROOM FOR DELIVERY';
      when '150	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '405	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '422	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '437	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '442	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '452	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '472	' then
        result := 'CONSUMABLE FOR DELIVERY';
      when '485	' then
        result := 'CONSUMABLE FOR DELIVERY';
      else
        result := 'OTHER DELIVERY';
    end case;
  end if;
  return(result);
end productgroupformat;
/
create or replace function rightPad(
		FPstring varchar2,
		FPpos number,
		FPchar char
) return varchar2 is
begin
  return rpad(FPstring, FPpos, FPchar);
end ;
/
create or replace function STRINGLENGTH(FPstring varchar2) return number is
begin
  return length(FPstring);
end STRINGLENGTH;
/
create or replace function Year(vDate	date) return int is
begin
	return cast(to_char(vDate, 'YYYY') as numeric);
end;
/
create or replace function YearMonthDay(vDate	date) return int is
begin
	return cast(to_char(vDate, 'YYYYMMDD') as numeric);
end;
/
set define on 
/

