Oracle EBS 基础概念:采购单号的客制研究

标准功能采购单号取值

当采购单编号设置为“手动”,打开采购单表单时,采购单栏位为黄色,用户需要手动输入编号。
在这里插入图片描述
在这里插入图片描述
当PO编号设置为“自动”,PO栏位状态为不能编辑,保存采购单头时系统自动分配编号。
在这里插入图片描述
在这里插入图片描述

个性化设置采购单号

个性化示例1: 开立采购单时,自动产生采购单号,序列号为320********

--创建序列号
CREATE SEQUENCE PO_SEQ
INCREMENT BY 1
START WITH 3200000001   
NOMAXvalue  
NOCYCLE
CACHE 10;
-- 个性化赋值时直接用select to_char(PO_SEQ.NextVal) from dual 取值会报错
-- Solution:创建获取序列下一个值的函数
create or replace function get_seq_next (seq_name in varchar2) return number
is
  seq_val number ;
begin
  execute immediate 'select '|| seq_name|| '.nextval from dual' into seq_val ;
  return seq_val ;
end get_seq_next;

– 设置个性化
在这里插入图片描述在这里插入图片描述
采购单编号需设置为“手动”,“自动编号”是保存“采购单头层”时触发器ON-INSERT触发,在个性化触发之后,如果设置“自动”,保存采购单头时会以自动编号的规则生成采购单号。

缺点:打开采购单界面就会取一个序号,即使没有保存采购单,也会用掉一个序号,造成采购单号跳号。
解决方法可参考下面这个示例,不取数据库Sequence的值,而是查询出最大的值加1。

个性化设置采购单号

个性化示例2:
在这里插入图片描述

--建立生成采购单号的Procedure
create or replace procedure CUX_PO_SEGMENT1
          (p_org_id in number,
           p_vendor_id in number,
           po_num out varchar2 )IS
    
    V_MACODE CHAR(1);
    V_VENDOR_CODE CHAR(5);
    V_COUNT NUMBER;
    V_NUMBER CHAR(4);
    V_PO_NUM varchar2(20);

BEGIN
    V_MACODE:='1';

    --根據供應商ID查詢供應商編號(5位),不足5位左邊用0補齊
    SELECT TRIM(TO_CHAR(TO_NUMBER(SEGMENT1),'00000')) INTO V_VENDOR_CODE FROM PO_VENDORS WHERE VENDOR_ID=p_vendor_id;

    --檢查供應商是否有建立過採購單
    SELECT COUNT(*) INTO V_COUNT
      FROM PO_HEADERS_ALL A ,PO_VENDORS B
     WHERE A.VENDOR_ID=B.VENDOR_ID
       AND SUBSTR(A.SEGMENT1,2,5)=V_VENDOR_CODE                --供應商編號(5位)
       AND SUBSTR(A.SEGMENT1,7,2)=TRIM(TO_CHAR(SYSDATE,'YY'))  --年份(2位)
       AND A.TYPE_LOOKUP_CODE='STANDARD'                       --採購單
       AND A.ORG_ID =p_org_id ;

    --沒有建立過採購單,取第一個號碼:1 + 供應商(5位) + 年份(2位) + '0001'
    IF V_COUNT=0 THEN
        po_num :=TRIM(V_MACODE)||TRIM(V_VENDOR_CODE)||TRIM(TO_CHAR(SYSDATE,'YY'))||'0001';

    --有建立過採購單,取值:1 + 供應商(5位) + 年份(2位) + 現有該供應商、OU、年份下最大的流水號加1
    ELSE
        SELECT LTRIM(RTRIM(TO_CHAR(MAX(TO_NUMBER(SUBSTR(SEGMENT1,10,4)))+1,'0000')))
          INTO V_NUMBER
         FROM PO_HEADERS_ALL
        WHERE SUBSTR(SEGMENT1,2,5)=V_VENDOR_CODE
        AND SUBSTR(SEGMENT1,7,2)=TRIM(TO_CHAR(SYSDATE,'YY'))
        AND ORG_ID =p_org_id;

        po_num :=TRIM(V_MACODE)||TRIM(V_VENDOR_CODE)||TRIM(TO_CHAR(SYSDATE,'YY'))||TRIM(V_NUMBER);
    END IF;
END;

因为需要输入完供应商后,才能生成采购单号(采购单号需包含供应商编码信息)。
所以在采购单界面地点栏位的“WHEN-VALIDATE-ITEM”触发器中调用CUX_PO_SEGMENT1
在这里插入图片描述
触发器代码:

declare
    v_org_id number;
begin
    po_headers_c01.vendor_site_code('WHEN-VALIDATE-ITEM');
    copy ('Y','PARAMETER.query_vndr_addr'); 

    v_org_id := fnd_profile.value('ORG_ID');
    
    if :po_headers.segment1 is null then
        CUX_PO_SEGMENT1(v_org_id,:po_headers.vendor_id,:po_headers.segment1);
    end if;
  
    exception
         when others then 
              po_message_c.show;
              raise form_trigger_failure;        
end;

效果:打开采购单界面,输入供应商后,TAB一下或光标点击地点栏位,保存采购单头,产生采购单号。
在这里插入图片描述

另一种流水规则:按月生成流水号

在序列号的实际应用场景中,常会出现按照某种条件从头开始计算序号的需要,如按年月生成流水号,2019年10月的第一个流水号为19100001,而11月的第一个流水号则为19110001。这种情况下单纯使用序列SEQUENCE则无法实现,而如果每次生成序号时从表中选取最大值又容易造成重复序号。本例采用自治事务与序列相结合的方式,实现按年月生成“YYMM+四位流水”格式的序列号,流水号要求每月重新计算。

--创建数据表记录已经生成过第一个流水号的月份
CREATE TABLE cux_gl_number_temp
(
  current_month NUMBER UNIQUE
);
--创建序号
CREATE SEQUENCE cux_gl_number_s  
START WITH 1 
INCREMENT BY 1;
--创建自治函数生成序列号
CREATE OR REPLACE FUNCTION get_cux_gl_number RETURN VARCHAR2 IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    l_current_month NUMBER := to_char(SYSDATE, 'yymm');
    l_gl_number     VARCHAR2(8);
BEGIN
    BEGIN
        --每个月的第一次插入数据,成功,删除序列号,重新建立序列号(流水号)
        --不是第一次插入,报错,跳转到Exception,继续取流水号
        INSERT INTO cux_gl_number_temp(current_month)
        VALUES(l_current_month);
        COMMIT;

        BEGIN
          EXECUTE IMMEDIATE 'drop sequence cux_gl_number_s';
        EXCEPTION
          WHEN OTHERS THEN
            NULL;
        END;

        EXECUTE IMMEDIATE 'create sequence cux_gl_number_s start with 1 increment by 1';
        select l_current_month || lpad(cux_gl_number_s.nextval, 4, '0')
          into l_gl_number from dual;

    
    EXCEPTION
      WHEN OTHERS THEN
        select l_current_month || lpad(cux_gl_number_s.nextval, 4, '0')
        into l_gl_number from dual;
    END;

    RETURN l_gl_number;
END get_cux_gl_number;
--测试
begin
    dbms_output.put_line(get_cux_gl_number());
end;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值