Oracle EBS WIP任务单批量发料功能开发

最近公司线材半成品需要分层成多个半成品,由一束线的半成品变成三四十多个半成品,该业务需求会带来哪些影响呢?

  1. 增加半成品的物料类别、物料编码、工艺路线、资源和BOM清单等等
  2. 会产生大量任务单,从任务单发料至完工各个环境工作量增加,导致管理成本上升

仓库就提出任务单能不能批量发料功能?从技术角度来说,理论上是可以实现在的。经过对业务部关键用户的需求调研和分析得出如下:

  1. 由于不同装配件所有用到的原材料或半成品在不同仓库不同用户有权限发料
  2. 部分原材料或半成品实物与系统的现有量不相符,其中原因:实物与系统操作的及时性问题所导致的。关键用户同意按照系统现有量扣帐。
  3. 启用批次的物料采用先进先出原则扣帐
  4. 采用模拟标准任务单发料直接往表mtl_material_transactions_temp和MTL_TRANSACTION_LOTS_TEMP插入数据。

本次开发借鉴标准系统标准API:
1. WIP_POPULATE_TEMP.Insert_Temp 往表mtl_material_transactions_temp
2. inv_quantity_tree_pub.query_quantities 判断现有量 API

主要代码如下,其中核心代码CUX_WIPBATTXMAT_PKG.InsertTemp

CREATE OR REPLACE Package CUX_WIPBATTXMAT_PKG As
  --任务单装配
  Type CUX_WIPDISCRETEJOBS Is Record(
    TRANSACTION_HEADER_ID  Number,
    WIP_ENTITY_ID          Number, --任务单ID
    WIP_ENTITY_NAME        Varchar2(240), --任务单编号
    JOB_TYPE_MEANING       Varchar2(80), --类型
    ASSEMBLY_NUM           Varchar2(40), --装配件
    ASSEMBLY_DESC          Varchar2(240), --装配件说明
    CLASS_CODE             Varchar2(10), --分类
    STATUS_TYPE_DISP       Varchar2(80), --状态
    START_QUANTITY         Number, --数量
    DATE_RELEASED          Date, --发放日期
    INVENTORY_ITEM_ID      Number, --装配件ID
    TRANSACTION_TYPE       Varchar2(80), --事务处理类型
    TRANSACTION_DATE       Date, --事务处理日期
    TRANSFER_SUBINVENTORY  Varchar2(8), --子库存
    TRANSFER_LOCATION_ID   Number, --货位ID
    TRANSFER_LOCATION_CODE Varchar2(30) --货位代码
    );
  --提交请求  GB任务单批量发料请求
  procedure SubmitRpt(ERRBUF            OUT VARCHAR2,
                      RETCODE           OUT NUMBER,
                      P_ORGANIZATION_ID NUMBER,
                      P_GROUP_ID        Number,
                      P_USER_ID         Number);

  --提交单个任务单组件发放
  Procedure WipCmpRelRequest(P_GROUP_ID              In Number,
                      P_WIP_ENTITY_ID         IN NUMBER,
                      P_TRANSACTION_DATE      IN Date,
                      P_ORGANIZATION_ID       IN NUMBER,
                      P_SUBINVENTORY          IN VARCHAR2,
                      P_LOCATOR_ID            IN NUMBER,
                      P_TRANSACTION_HEADER_ID In NUMBER,
                      P_USER_ID               IN NUMBER,
                      P_DEBUG_FLAG            Varchar2);

  procedure WipCmpRel(ERRBUF            OUT VARCHAR2,
                   RETCODE           OUT NUMBER,
                   P_GROUP_ID              In Number,
                   P_WIP_ENTITY_ID         IN NUMBER,
                   P_TRANSACTION_DATE      IN Varchar2,
                   P_ORGANIZATION_ID       IN NUMBER,
                   P_SUBINVENTORY          IN VARCHAR2,
                   P_LOCATOR_ID            IN NUMBER,
                   P_TRANSACTION_HEADER_ID In NUMBER,
                   P_USER_ID               IN NUMBER,
                   P_DEBUG_FLAG            Varchar2);
  
  Procedure InsertTemp(P_TRANSACTION_MODE      IN NUMBER,
                       P_WIP_ENTITY_ID         IN NUMBER,
                       P_LINE_ID               IN NUMBER,
                       P_TRANSACTION_DATE      IN DATE,
                       P_TRANSACTION_TYPE_ID   IN NUMBER,
                       P_TRANSACTION_ACTION_ID IN NUMBER,
                       P_SUBINVENTORY          IN VARCHAR2,
                       P_LOCATOR_ID            IN NUMBER,
                       P_ASSEMBLY_QUANTITY     IN NUMBER,
                       P_OPERATION_SEQ_NUM     IN NUMBER,
                       P_DEPARTMENT_ID         IN NUMBER,
                       P_CRITERIA_SUB          IN VARCHAR2,
                       P_ORGANIZATION_ID       IN NUMBER,
                       P_ACCT_PERIOD_ID        IN NUMBER,
                       P_LAST_UPDATED_BY       IN NUMBER,
                       P_ENTITY_TYPE           IN NUMBER,
                       P_TRANSACTION_HEADER_ID IN NUMBER,
                       P_DEBUG_FLAG            Varchar2,
                       X_COMMIT_COUNT          In Out Number);
End CUX_WIPBATTXMAT_PKG;
CREATE OR REPLACE Package Body CUX_WIPBATTXMAT_PKG As
  Procedure Log(p_Msg In Varchar2) Is
  Begin
    Fnd_File.Put_Line(Fnd_File.Log, p_Msg);
  End Log;

  --===============================================================
  -- Output
  --===============================================================
  Procedure Output(p_Msg In Varchar2) Is
  Begin
    Fnd_File.Put_Line(Fnd_File.Output, p_Msg);
  End Output;
  --批量发料失效的明细
 procedure WipCmpRelFailure(P_ORGANIZATION_ID NUMBER, P_GROUP_ID Number) Is
   Cursor Cr Is
     Select WDJ.WIP_ENTITY_ID,
            WDJ.WIP_ENTITY_NAME,
            WDJ.STATUS_TYPE_DISP,
            MSI.SEGMENT1            COMP_NUM,
            MSI.DESCRIPTION         COMP_DESC,
            WRO.REQUIRED_QUANTITY,
            WRO.QUANTITY_ISSUED,
            WRO.SUPPLY_SUBINVENTORY
       From CUX.CUX_WIPBATISSUED_ALL   WIPB,
            WIP_DISCRETE_JOBS_V        WDJ,
            WIP_REQUIREMENT_OPERATIONS WRO,
            MTL_SYSTEM_ITEMS_B         MSI
      Where WIPB.WIP_ENTITY_ID = WDJ.WIP_ENTITY_ID
        And WDJ.WIP_ENTITY_ID = WRO.WIP_ENTITY_ID
        And WRO.Inventory_Item_Id = MSI.INVENTORY_ITEM_ID
        And WRO.organization_id = MSI.ORGANIZATION_ID
        And WIPB.Group_Id = P_GROUP_ID
        And WIPB.ORGANIZATION_ID = P_ORGANIZATION_ID
        And (WRO.WIP_SUPPLY_TYPE = 1 Or WRO.WIP_SUPPLY_TYPE = 2)
        And WDJ.STATUS_TYPE = 3
        And Nvl(WRO.QUANTITY_ISSUED, 0) - WRO.REQUIRED_QUANTITY < 0
      Order By WDJ.WIP_ENTITY_ID;
   i Number :=1;     
 Begin
   OUTPUT('<TR BGCOLOR="#E6E6FA"><TD COLSPAN="10">任务单未发料明细</TD></TR>');
   Output('<tr BGCOLOR="#FFE66F">
      <td align="center">序号</td>
      <td align="center">任务单</td>
      <td align="center">状态</td>
      <td align="center">任务单标识</td>
      <td align="center">组件</td>
      <td align="center">组件说明</td>
      <td align="center">子库存</td>
      <td align="center">数量</td>
      <td align="center">已发料</td>
      <td align="center">未发数</td></tr>');
   For Rs In Cr Loop
     Output('<tr>
      <td align="center">'|| i ||'</td>
      <td>'||Rs.Wip_Entity_Name||'</td>
      <td>'||Rs.Status_Type_Disp||'</td>
      <td>'||Rs.Wip_Entity_Id||'</td>
      <td>'||Rs.Comp_Num||'</td>
      <td>'||Rs.Comp_Desc||'</td>
      <td>'||Rs.Supply_Subinventory||'</td>
      <td>'||Rs.Required_Quantity||'</td>
      <td>'||Rs.Quantity_Issued||'</td>
      <td>'||(Rs.Required_Quantity - Nvl(Rs.Quantity_Issued,0))||'</td></tr>');
      i := i +1;
   End Loop;
 End WipCmpRelFailure;
  --提交请求  GB任务单批量发料请求
  procedure SubmitRpt(ERRBUF            OUT VARCHAR2,
                      RETCODE           OUT NUMBER,
                      P_ORGANIZATION_ID NUMBER,
                      P_GROUP_ID        Number,
                      P_USER_ID         Number) Is
    Cursor Cr Is
      Select *
        From CUX.CUX_WIPBATISSUED_ALL
       Where GROUP_ID = P_GROUP_ID
         And ORGANIZATION_ID = P_ORGANIZATION_ID
         And PROCESS_FLAG =2 ;
    l_TrxHdrId Number;
  Begin
    ---更新为处理中
    Update CUX.CUX_WIPBATISSUED_ALL
       Set PROCESS_FLAG = 2
     Where GROUP_ID = P_GROUP_ID
       And ORGANIZATION_ID = P_ORGANIZATION_ID
       And PROCESS_FLAG = 1;
    Commit;
    CUX_GOBAOPUBLIC_PKG.HTMLSTART('GB任务单批量发料请求');
    OUTPUT('<TABLE CLASS="CONTEXT" BORDERCOLOR="#669933" WIDTH="100%" BORDER=1>
           <TR BGCOLOR="#E6E6FA"><TD COLSPAN="10">提交日期:' ||  TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') ||  '</TD></TR>
           <TR BGCOLOR="#E6E6FA"><TD COLSPAN="10">组标识:' ||P_GROUP_ID || '</TD></TR>');
    Select mtl_material_transactions_s.NEXTVAL
      INTO l_TrxHdrId
      FROM SYS.dual;
    For Rs In Cr Loop
      WipCmpRelRequest(P_GROUP_ID,
             Rs.Wip_Entity_Id,
             Rs.Transaction_Date,
             Rs.Organization_Id,
             Rs.Subinventory_Code,
             Rs.Locator_Id,
             l_TrxHdrId,
             P_USER_ID,
             'Y');
    End Loop;
    WipCmpRelFailure(P_ORGANIZATION_ID, P_GROUP_ID);
    OUTPUT('</TABLE></BODY></HTML>');
  End SubmitRpt;
  
  --提交单个任务单组件发放
  Procedure WipCmpRelRequest(P_GROUP_ID              In Number,
                      P_WIP_ENTITY_ID         IN NUMBER,
                      P_TRANSACTION_DATE      IN DATE,
                      P_ORGANIZATION_ID       IN NUMBER,
                      P_SUBINVENTORY          IN VARCHAR2,
                      P_LOCATOR_ID            IN NUMBER,
                      P_TRANSACTION_HEADER_ID In NUMBER,
                      P_USER_ID               IN NUMBER,
                      P_DEBUG_FLAG            Varchar2) Is
    v_ReqID          Number;
    l_phase          Varchar(200);
    l_status         Varchar(200);
    l_dev_phase      Varchar(200);
    l_dev_status     Varchar(200);
    l_message        Varchar(2000);
    l_request_status boolean;  
    l_TranDate       Varchar2(30);                    
  Begin
    l_TranDate := To_Char(P_TRANSACTION_DATE,'YYYY/MM/DD HH24:MI:SS');
    v_ReqID := fnd_request.submit_request('CUX',
                                          'CUX_WIPBATTXMATSINGLE',
                                          null,
                                          null,
                                          false,
                                          P_GROUP_ID,
                                          P_WIP_ENTITY_ID,
                                          l_TranDate,
                                          P_ORGANIZATION_ID,
                                          P_SUBINVENTORY,
                                          P_LOCATOR_ID,
                                          P_TRANSACTION_HEADER_ID,
                                          P_USER_ID,
                                          P_DEBUG_FLAG);
    If (Nvl(v_ReqID, 0) > 0) Then
      COMMIT;
      Log('请求ID:'||v_ReqID);
      l_request_status := Fnd_Concurrent.Wait_For_Request(v_ReqID,
                                                          5,
                                                          0,
                                                          l_phase,
                                                          l_status,
                                                          l_dev_phase,
                                                          l_dev_status,
                                                          l_message);
      IF l_request_status THEN
        IF l_dev_status = 'NORMAL' THEN
          Log('[GB任务单组件发放:'|| P_WIP_ENTITY_ID ||']运行成功');
        ELSE
          Log('[GB任务单组件发放:'|| P_WIP_ENTITY_ID ||']运行失败:' || l_dev_status);
          Return;
        END IF;
      ELSE
        Log('请求[GB任务单组件发放:'|| P_WIP_ENTITY_ID ||'未完成,无法查看报表内容!');
        Return;
      END IF;
    End If;
  End WipCmpRelRequest;
  ---任务单装配件输出
  procedure WipDiscreteJobsHtml(P_WipDiscreteJobs CUX_WIPDISCRETEJOBS) Is
  Begin
    CUX_GOBAOPUBLIC_PKG.HTMLSTART('GB任务单组件发放');
    OUTPUT('<TABLE CLASS="CONTEXT" BORDERCOLOR="#669933" WIDTH="100%" BORDER=1>
           <TR BGCOLOR="#E6E6FA"><TD COLSPAN="13">提交日期:' ||  TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') ||  '</TD></TR>');
    Output('<tr BGCOLOR="#E6E6FA"><td colspan="3">任务单:'|| P_WipDiscreteJobs.WIP_ENTITY_NAME ||'</td>
      <td colspan="3">装配件:'||P_WipDiscreteJobs.ASSEMBLY_NUM||'-'||
      P_WipDiscreteJobs.ASSEMBLY_DESC ||'</td>
      <td colspan="3">状态:'||P_WipDiscreteJobs.STATUS_TYPE_DISP||'</td>
      <td colspan="2">类型:'||P_WipDiscreteJobs.JOB_TYPE_MEANING||'</td>
      <td colspan="2">分类:'||P_WipDiscreteJobs.CLASS_CODE||'</td>
      </tr><tr BGCOLOR="#E6E6FA">
      <td colspan="2">发放日期:'||To_Char(P_WipDiscreteJobs.DATE_RELEASED,'YYYY-MM-DD')||'</td>
      <td colspan="3">事务处理日期:'||To_Char(P_WipDiscreteJobs.TRANSACTION_DATE,'YYYY-MM-DD HH24:MI:SS')||'</td>
      <td>事务处理类型:'||P_WipDiscreteJobs.TRANSACTION_TYPE||'</td>
      <td colspan="2">子库存:'||P_WipDiscreteJobs.TRANSFER_SUBINVENTORY||'</td>
      <td colspan="2">货位:'||P_WipDiscreteJobs.TRANSFER_LOCATION_CODE||'</td>
      <td colspan="3"></td></tr>');
    Output('<tr BGCOLOR="#FFE66F">
      <td align="center">事务处理题头标识</td>
      <td align="center">事务处理标识</td>
      <td align="center">任务单标识</td>
      <td align="center">组件标识</td>
      <td align="center">组件</td>
      <td align="center">组件说明</td>
      <td align="center">单位</td>
      <td align="center">子库存</td>
      <td align="center">货位</td>
      <td align="center">要求数量</td>
      <td align="center">发料数量</td>
      <td align="center">现有量</td>
      <td align="center">可用量</td></tr>');
  End WipDiscreteJobsHtml;              
  --
  procedure WipCmpRel(ERRBUF            OUT VARCHAR2,
                   RETCODE           OUT NUMBER,
                   P_GROUP_ID              In Number,
                   P_WIP_ENTITY_ID         IN NUMBER,
                   P_TRANSACTION_DATE      IN Varchar2,
                   P_ORGANIZATION_ID       IN NUMBER,
                   P_SUBINVENTORY          IN VARCHAR2,
                   P_LOCATOR_ID            IN NUMBER,
                   P_TRANSACTION_HEADER_ID In NUMBER,
                   P_USER_ID               IN NUMBER,
                   P_DEBUG_FLAG            Varchar2) Is
    Cursor CrGrp Is
      Select Distinct WDJ.WIP_ENTITY_ID,
                      WDJ.WIP_ENTITY_NAME,
                      WDJ.JOB_TYPE_MEANING,
                      WDJ.CLASS_CODE,
                      WDJ.STATUS_TYPE_DISP,
                      MSI.SEGMENT1         ASSEMBLY_NUM,
                      MSI.DESCRIPTION      ASSEMBLY_DESC,
                      WDJ.START_QUANTITY,
                      WDJ.PRIMARY_ITEM_ID,
                      WDJ.DATE_RELEASED,
                      WRO.WIP_SUPPLY_TYPE
        From WIP_DISCRETE_JOBS_V        WDJ,
             WIP_REQUIREMENT_OPERATIONS WRO,
             MTL_SYSTEM_ITEMS_B         MSI
       Where WDJ.WIP_ENTITY_ID = WRO.WIP_ENTITY_ID
         And WDJ.primary_item_id = MSI.INVENTORY_ITEM_ID
         And WDJ.organization_id = MSI.ORGANIZATION_ID
         And WDJ.WIP_ENTITY_ID = P_WIP_ENTITY_ID
         And (WRO.WIP_SUPPLY_TYPE = 1 Or
             (WRO.WIP_SUPPLY_TYPE = 2 And Length(P_SUBINVENTORY) Is Not Null))
         And WDJ.STATUS_TYPE = 3
         And Nvl(WRO.QUANTITY_ISSUED, 0) - WRO.REQUIRED_QUANTITY < 0;
    l_TransactionMode     Number; --事务处理模式
    l_TransactionTypeId   Number; --事务处理类型ID
    l_TransactionActionId Number; --事务处理活动ID
    l_TransactionTypeName Varchar2(80); --事务处理类型
    l_DataReleased        Date; --任务单的发放日期
    l_EntityType          Number; --任务单类型
    l_AcctPeriodId        Number; --会计期ID
    x_OpenPast            boolean := FALSE; --是否打开会计期
    x_ret_status          varchar2(1);
    x_msg_data            varchar2(2000);
    l_WipDiscreteJobs     CUX_WIPDISCRETEJOBS;
    l_CommitCount         Number;
    l_ProcessFlag         Number:=1;
    l_TransDate           Date;
  Begin
    l_TransDate := To_Date(P_TRANSACTION_DATE,'YYYY/MM/DD HH24:MI:SS');
    Log('P_TRANSACTION_DATE:'|| l_TransDate );
    Log('P_GROUP_ID:'||P_GROUP_ID);
    Log('P_WIP_ENTITY_ID:'||P_WIP_ENTITY_ID);
    Log('P_ORGANIZATION_ID:'||P_ORGANIZATION_ID);
    Log('P_SUBINVENTORY:'||P_SUBINVENTORY);
    Log('P_LOCATOR_ID:'||P_LOCATOR_ID);
    Log('P_TRANSACTION_HEADER_ID:'||P_TRANSACTION_HEADER_ID);
    Log('P_USER_ID:'||P_USER_ID);
    Log('P_DEBUG_FLAG:'||P_DEBUG_FLAG);
    --获得任务单发放日期
    Begin
      Select WDJ.DATE_RELEASED, WE.ENTITY_TYPE
        Into l_DataReleased, l_EntityType
        From WIP_DISCRETE_JOBS WDJ, WIP_ENTITIES WE
       Where WDJ.WIP_ENTITY_ID = WE.WIP_ENTITY_ID
         And WDJ.WIP_ENTITY_ID = P_WIP_ENTITY_ID
         And WDJ.STATUS_TYPE = 3;
    Exception
      When No_Data_Found Then
        Null; --
    End;
    --事务处理模式
    l_TransactionMode := fnd_profile.VALUE('TRANSACTION_PROCESS_MODE');
    --事务处理日期验证
    invttmtx.tdatechk(org_id           => P_ORGANIZATION_ID,
                      transaction_date => l_TransDate,
                      period_id        => l_AcctPeriodId,
                      open_past_period => x_OpenPast);
    If (l_AcctPeriodId = -1) Then
      dbms_output.put_line(P_WIP_ENTITY_ID ||':会计期未打开!');
      Return;
    End If;
    If (l_TransDate < l_DataReleased) Then
      dbms_output.put_line(P_WIP_ENTITY_ID ||':事务处理日期不能小于任务单的发放日期!');
      Return;
    End If;
    
    /**
    第一步:根据任务单的组件明细找出“供应类型”、“子库存”和“货位”等等
    **/
    For RsGrp In CrGrp Loop
      l_CommitCount := 0;
      /**
      第二:根据供应类型、子库存和货位分开发料,产生临时数据
      2.1 WIP_SUPPLY_TYPE =2 装配拉式 事务处理类型为“子库存转移”
      2.2 WIP_SUPPLY_TYPE =1 推式 事务处理类型为“WIP组件发放”
      **/

      If (RsGrp.WIP_SUPPLY_TYPE = 1) Then
        l_TransactionTypeId := 35; --WIP组件发放
      Else
        l_TransactionTypeId := 2; --子库存转移
      End If;
      --事务处理活动ID
      Begin
        Select MTT.TRANSACTION_ACTION_ID, MTT.TRANSACTION_TYPE_NAME
          Into l_TransactionActionId, l_TransactionTypeName
          From MTL_TRANSACTION_TYPES MTT
         Where MTT.TRANSACTION_TYPE_ID = l_TransactionTypeId;
      Exception
        When No_Data_Found Then
          Null;
      End;
      If (P_DEBUG_FLAG = 'Y') Then
        l_WipDiscreteJobs.TRANSACTION_HEADER_ID := P_TRANSACTION_HEADER_ID;
        l_WipDiscreteJobs.WIP_ENTITY_ID         := RsGrp.Wip_Entity_Id; --任务单ID
        l_WipDiscreteJobs.WIP_ENTITY_NAME       := RsGrp.Wip_Entity_Name; --任务单编号
        l_WipDiscreteJobs.JOB_TYPE_MEANING      := RsGrp.Job_Type_Meaning; --类型
        l_WipDiscreteJobs.ASSEMBLY_NUM          := RsGrp.Assembly_Num; --装配件
        l_WipDiscreteJobs.ASSEMBLY_DESC         := RsGrp.Assembly_Desc; --装配件说明
        l_WipDiscreteJobs.CLASS_CODE            := RsGrp.Class_Code; --分类
        l_WipDiscreteJobs.STATUS_TYPE_DISP      := RsGrp.Status_Type_Disp; --状态
        l_WipDiscreteJobs.START_QUANTITY        := RsGrp.Start_Quantity; --数量
        l_WipDiscreteJobs.DATE_RELEASED         := RsGrp.Date_Released; --发放日期
        l_WipDiscreteJobs.INVENTORY_ITEM_ID     := RsGrp.Primary_Item_Id; --装配件ID
        l_WipDiscreteJobs.TRANSACTION_TYPE      := l_TransactionTypeName; --事务处理类型
        l_WipDiscreteJobs.TRANSACTION_DATE      := l_TransDate; --事务处理日期
        If(l_TransactionTypeId = 2)Then
          l_WipDiscreteJobs.TRANSFER_SUBINVENTORY := P_SUBINVENTORY; --子库存
          l_WipDiscreteJobs.TRANSFER_LOCATION_ID  := P_LOCATOR_ID; --货位ID
          --货位代码
          If (P_LOCATOR_ID Is Not Null) Then
            Begin
              Select MIL.SEGMENT1
                Into l_WipDiscreteJobs.TRANSFER_LOCATION_CODE
                FROM MTL_ITEM_LOCATIONS MIL
               Where MIL.SUBINVENTORY_CODE = P_SUBINVENTORY
                 And MIL.ORGANIZATION_ID = P_ORGANIZATION_ID;
            Exception
              When No_Data_Found Then
                l_WipDiscreteJobs.TRANSFER_LOCATION_CODE := Null;
            End;
          End If;
        Else
          l_WipDiscreteJobs.TRANSFER_SUBINVENTORY := Null; --子库存
          l_WipDiscreteJobs.TRANSFER_LOCATION_ID  := Null; --货位ID
          l_WipDiscreteJobs.TRANSFER_LOCATION_CODE := Null;
        End If;
        WipDiscreteJobsHtml(l_WipDiscreteJobs);
        Log('----------'||l_WipDiscreteJobs.WIP_ENTITY_NAME||'---------------');
        Log('事务处理日期:'||l_WipDiscreteJobs.TRANSACTION_DATE);
        Log('事务处理类型:'||l_WipDiscreteJobs.TRANSACTION_TYPE);
      End If;
      /*dbms_output.put_line('l_TransactionTypeId:' || l_TransactionTypeId);
      dbms_output.put_line('l_TransactionActionId:' || l_TransactionActionId);
      dbms_output.put_line('l_TransactionMode:' || l_TransactionMode);*/
      CUX_WIPBATTXMAT_PKG.InsertTemp(p_transaction_mode      => l_TransactionMode,
                                     p_wip_entity_id         => P_WIP_ENTITY_ID,
                                     p_line_id               => Null,
                                     p_transaction_date      => l_TransDate,
                                     p_transaction_type_id   => l_TransactionTypeId,
                                     p_transaction_action_id => l_TransactionActionId,
                                     p_subinventory          => P_SUBINVENTORY,
                                     p_locator_id            => P_LOCATOR_ID,
                                     p_assembly_quantity     => Null,
                                     p_operation_seq_num     => Null,
                                     p_department_id         => Null,
                                     p_criteria_sub          => Null,
                                     p_organization_id       => P_ORGANIZATION_ID,
                                     p_acct_period_id        => l_AcctPeriodId,
                                     p_last_updated_by       => P_USER_ID,
                                     p_entity_type           => l_EntityType,
                                     p_transaction_header_id => P_TRANSACTION_HEADER_ID,
                                     P_DEBUG_FLAG            => P_DEBUG_FLAG,
                                     X_COMMIT_COUNT          =>l_CommitCount
                                     );
    End Loop;
    log('l_CommitCount:'||l_CommitCount);
    If(l_CommitCount=0)Then
      Output('<tr><td colspan="13">None</td></tr>');
      l_ProcessFlag := 3; ---更新为完成
    Else
      -- update records to lock if concurrent request
      If (l_TransactionMode = WIP_CONSTANTS.IMMED_CONC) Then
        update mtl_material_transactions_temp
           set lock_flag = 'Y'
         where transaction_header_id = P_TRANSACTION_HEADER_ID;
      End If;

      wip_mtlTempProc_priv.processTemp(p_initMsgList  => 'T',
                                       p_txnHdrID     => P_TRANSACTION_HEADER_ID,
                                       p_txnMode      => l_TransactionMode,
                                       x_returnStatus => x_ret_status,
                                       x_errorMsg     => x_msg_data);

      If (x_ret_status <> 'S') Then
        Output('<tr BGCOLOR="red">
         <td colspan="13">批量发料失败!'||x_msg_data||'</td></tr>
         <tr><td colspan="13">None</td></tr>');
        --dbms_output.put_line('x_msg_data' || x_msg_data);
        Rollback;
        l_ProcessFlag := 1; ---更新为待定
      Else
        Output('<tr BGCOLOR="#FFE66F">
         <td colspan="13">批量发料成功!</td></tr>
         <tr><td colspan="13">None</td></tr>');
        Commit;
        l_ProcessFlag := 3; ---更新为完成
      End If;
    End If;
    Begin
      Update CUX.CUX_WIPBATISSUED_ALL
         Set PROCESS_FLAG = l_ProcessFlag
       Where WIP_ENTITY_ID = P_WIP_ENTITY_ID
         And GROUP_ID = P_GROUP_ID
         And ORGANIZATION_ID = P_ORGANIZATION_ID
         And PROCESS_FLAG = 2;
      Commit;
    Exception
      When Others Then
        Null;
    End;
    OUTPUT('</TABLE></BODY></HTML>');
  Exception
    When Others Then
      Output('<tr BGCOLOR="#FFE66F">
       <td colspan="13">批量发料失败!'|| Sqlerrm||'</td></tr>
       <tr><td colspan="13">None</td></tr>');
      OUTPUT('</TABLE></BODY></HTML>');
      Rollback;
      Begin
      Update CUX.CUX_WIPBATISSUED_ALL
         Set PROCESS_FLAG = 1
       Where WIP_ENTITY_ID = P_WIP_ENTITY_ID
         And GROUP_ID = P_GROUP_ID
         And ORGANIZATION_ID = P_ORGANIZATION_ID
         And PROCESS_FLAG = 2;
      Commit;
    Exception
      When Others Then
        Null;
    End;
    OUTPUT('</TABLE></BODY></HTML>');
  End WipCmpRel;
  ---获得可用量
  Procedure getAtt(P_TRANSACTION_HEADER_ID      Number,
                   P_INVENTORY_ITEM_ID          Number,
                   P_ORGANIZATION_ID            Number,
                   P_REVISION_QTY_CONTROL_CODE  Number,
                   P_LOT_CONTROL_CODE           Number,
                   P_SERIAL_NUMBER_CONTROL_CODE Number,
                   P_REVISION                   Varchar2,
                   P_LOT_NUMBER                 Varchar2,
                   P_SUBINVENTORY_CODE          Varchar2,
                   P_LOCATOR_ID                 Number,
                   X_QOH                        In Out Number,
                   X_ATT                        In Out Number) Is
    --判断现有所用的变量
    l_qty_on_hand              NUMBER;
    l_qty_res_on_hand          NUMBER;
    l_qty_res                  NUMBER;
    l_qty_sug                  NUMBER;
    l_qty_att                  NUMBER;
    l_qty_available_to_reserve NUMBER;
    l_is_revision_control      BOOLEAN;
    l_is_lot_control           BOOLEAN;
    l_is_serial_control        BOOLEAN;
    l_msg_count                NUMBER;
    l_msg_data                 VARCHAR2(2000);
    l_return_status            VARCHAR2(1);
    l_qty_temp                 Number:=0; ---待等的事务数量
  BEGIN
    X_QOH := 0;
    X_ATT := 0;
    --版本管控
    If (P_REVISION_QTY_CONTROL_CODE = 2) Then
      l_is_revision_control := TRUE;
    Else
      l_is_revision_control := FALSE;
    End If;
    --批次管控
    If (P_LOT_CONTROL_CODE = 2) Then
      l_is_lot_control := TRUE;
    Else
      l_is_lot_control := FALSE;
    End If;
    --序列管控
    If (P_SERIAL_NUMBER_CONTROL_CODE = 2) Then
      l_is_serial_control := TRUE;
    Else
      l_is_serial_control := FALSE;
    End If;
    --判断现有量是否足够
    inv_quantity_tree_pub.query_quantities(p_api_version_number  => 1.0,
                                           p_init_msg_lst        => 'F', --inv_client_globals.g_false,
                                           x_return_status       => l_return_status,
                                           x_msg_count           => l_msg_count,
                                           x_msg_data            => l_msg_data,
                                           p_organization_id     => P_ORGANIZATION_ID,
                                           p_inventory_item_id   => P_INVENTORY_ITEM_ID,
                                           p_tree_mode           => 2, -- Transaction Mode
                                           p_is_revision_control => l_is_revision_control,
                                           p_is_lot_control      => l_is_lot_control,
                                           p_is_serial_control   => l_is_serial_control,
                                           --p_demand_source_type_id   => l_Rec.Transaction_Source_Type_Id,
                                           --p_demand_source_header_id => l_Rec.Transaction_Source_Id,
                                           --p_demand_source_line_id   => l_Rec.Trx_Source_Line_Id,
                                           p_revision          => P_REVISION,
                                           p_lot_number        => P_LOT_NUMBER,
                                           p_subinventory_code => P_SUBINVENTORY_CODE,
                                           p_locator_id        => P_LOCATOR_ID,
                                           p_onhand_source     => 3, --inv_client_globals.g_all_subs,
                                           x_qoh               => l_qty_on_hand,
                                           x_rqoh              => l_qty_res_on_hand,
                                           x_qr                => l_qty_res,
                                           x_qs                => l_qty_sug,
                                           x_att               => l_qty_att, --可用量
                                           x_atr               => l_qty_available_to_reserve); --可保留量
    Log('x_qoh:'|| l_qty_on_hand ||' x_rqoh:'|| l_qty_res_on_hand ||
     ' x_qr:'||l_qty_res ||' x_qs:' || l_qty_sug ||' x_att:'|| l_qty_att ||
     ' x_atr:'||l_qty_available_to_reserve);
    IF (l_return_status = 'S') THEN
      X_QOH := l_qty_on_hand;
      If(P_LOT_NUMBER Is Not Null)Then
        Select Sum(TRANSACTION_QUANTITY) Into l_qty_temp
          From MTL_TRANSACTION_LOTS_TEMP
         Where TRANSACTION_TEMP_ID In
               (Select TRANSACTION_TEMP_ID
                  From MTL_MATERIAL_TRANSACTIONS_TEMP
                 Where TRANSACTION_HEADER_ID = P_TRANSACTION_HEADER_ID)
           And LOT_NUMBER = P_LOT_NUMBER;
      End If;
      X_ATT := l_qty_att - abs(Nvl(l_qty_temp,0));
    END IF;
  END getAtt;
  --任务单组件输出
  procedure WipReqOptsHtml(P_MTT           mtl_material_transactions_temp%Rowtype,
                          P_COMPONENT_NUM Varchar2,
                          P_QOH           Number,
                          P_ATT           Number,
                          P_FLAG          Number) Is
    l_BgColor Varchar2(200);
    l_TranQty Number;
  Begin
    If(P_ATT<=0)Then
      l_BgColor :=' bgcolor="red" ';
    Else
      l_BgColor :='';
      If(Abs(P_MTT.TRANSACTION_QUANTITY)<= P_ATT)Then
        l_TranQty := Abs(P_MTT.TRANSACTION_QUANTITY);
      Else
        l_TranQty := P_ATT;
        l_BgColor :=' bgcolor="yellow" ';
      End If;
    End If;
    If(P_FLAG=1)Then
      l_BgColor :=' bgcolor="red" ';
    End If;
    Output('<tr>
      <td>' || P_MTT.Transaction_Header_Id || '</td>
      <td>' || P_MTT.Transaction_Temp_Id || '</td>
      <td>' || P_MTT.TRANSACTION_SOURCE_ID || '</td>
      <td>' || P_MTT.INVENTORY_ITEM_ID || '</td>
      <td'|| l_BgColor ||'>' || P_COMPONENT_NUM || '</td>
      <td'|| l_BgColor ||'>' || P_MTT.ITEM_DESCRIPTION || '</td>
      <td>' || P_MTT.Item_Primary_Uom_Code || '</td>
      <td>' || P_MTT.SUPPLY_SUBINVENTORY || '</td>
      <td></td>
      <td>' || Abs(P_MTT.Number_Of_Lots_Entered) || '</td>
      <td>' || l_TranQty || '</td>
      <td>' || P_QOH || '</td>
      <td>' || P_ATT || '</td>
      </tr>');
  End WipReqOptsHtml;
  --任务单批次发料信息
  Procedure WipLotsHtml(P_MTT                  mtl_material_transactions_temp%Rowtype,
                        P_LOT_NUMBER           Varchar2,
                        P_EXPIRATION_DATE      Date,
                        P_TRANSACTION_QUANTITY Number,
                        P_QOH                  Number,
                        P_ATT                  Number) Is
    l_BgColor Varchar2(200);
  Begin
    If(Abs(P_TRANSACTION_QUANTITY)<=0)Then
      l_BgColor :=' bgcolor="red" ';
    Else
      l_BgColor :='';
    End If;
    Output('<tr><td>' || P_MTT.Transaction_Header_Id || '</td>
      <td>' || P_MTT.Transaction_Temp_Id || '</td>
      <td '||l_BgColor||'>' || P_LOT_NUMBER || '</td>
      <td>' || To_Char(P_EXPIRATION_DATE,'YYYY-MM-DD') || '</td>
      <td>' || P_TRANSACTION_QUANTITY || '</td>
      <td>' || P_QOH || '</td>
      <td>' || P_ATT || '</td></tr>');
  End WipLotsHtml;
  --
  procedure InsertMTT(P_MTT           In Out mtl_material_transactions_temp%Rowtype,
                      P_COMPONENT_NUM Varchar2,
                      P_DEBUG_FLAG    Varchar2,
                      X_COMMIT_COUNT  In Out Number) Is
    l_Att            Number := 0;
    l_LotTotalQty    Number := 0; --批次总数量
    l_LotRec         MTL_TRANSACTION_LOTS_TEMP%RowType;
    l_PlusMinus_Flag Number; --正负标志
    Cursor CrLot Is
      Select MOQ.Inventory_Item_Id,
             Sum(MOQ.Transaction_Quantity) Transaction_Quantity,
             MLN.LOT_NUMBER,
             MLN.CREATION_DATE,
             MLN.EXPIRATION_DATE
        From MTL_ONHAND_QUANTITIES_DETAIL MOQ, MTL_LOT_NUMBERS MLN
       Where MOQ.INVENTORY_ITEM_ID = MLN.INVENTORY_ITEM_ID
         And MOQ.ORGANIZATION_ID = MLN.ORGANIZATION_ID
         And MOQ.Lot_Number = MLN.LOT_NUMBER
         And MOQ.Inventory_Item_Id = P_MTT.INVENTORY_ITEM_ID
         And MOQ.Organization_Id = P_MTT.ORGANIZATION_ID
       Group By MOQ.Inventory_Item_Id,
                MLN.LOT_NUMBER,
                MLN.CREATION_DATE,
                MLN.EXPIRATION_DATE
       Order By MLN.EXPIRATION_DATE;
    l_OnHand NUMBER;
    l_Flag   Number:=0;
  Begin
    l_Flag :=0;
    Log('P_MTT.Item_Revision_Qty_Control_Code:'|| P_MTT.Item_Revision_Qty_Control_Code);
    Log('P_MTT.Revision:'||P_MTT.Revision);
    --首判断总数量是否够
    getAtt(P_MTT.Transaction_Header_Id,
           P_MTT.Inventory_Item_Id,
           P_MTT.Organization_Id,
           P_MTT.Item_Revision_Qty_Control_Code,
           1, --l_Rec.Item_Lot_Control_Code,
           1, --l_Rec.Item_Serial_Control_Code,
           P_MTT.Revision,
           P_MTT.Lot_Number,
           P_MTT.Subinventory_Code,
           P_MTT.Locator_Id,
           l_OnHand,
           l_Att);
    l_Att := Nvl(l_Att,0);
    If ((l_Att > 0 And P_MTT.TRANSACTION_UOM <> 'PCS') Or
      (l_Att > 1 And P_MTT.TRANSACTION_UOM = 'PCS')) Then
      l_PlusMinus_Flag := P_MTT.Transaction_Quantity /
                            abs(P_MTT.Transaction_Quantity);
      If(P_MTT.Item_Lot_Control_Code = 2)Then
        l_LotTotalQty    := abs(P_MTT.Transaction_Quantity);
      End If;
      Select mtl_material_transactions_s.NEXTVAL
          INTO P_MTT.Transaction_Temp_Id
          FROM SYS.dual;
      If(Abs(P_MTT.TRANSACTION_QUANTITY)>l_Att)Then
        l_Flag := 1;
        P_MTT.TRANSACTION_QUANTITY :=l_PlusMinus_Flag * l_Att;
        P_MTT.PRIMARY_QUANTITY :=l_PlusMinus_Flag * l_Att;
      End If;
      INSERT INTO mtl_material_transactions_temp Values P_MTT;
      X_COMMIT_COUNT := X_COMMIT_COUNT +1;
      Log('物料编码:'|| P_COMPONENT_NUM ||',需求数量:'|| Abs(P_MTT.Number_Of_Lots_Entered) ||
        ',发料数量:'|| Abs(P_MTT.TRANSACTION_QUANTITY) ||',可用量:'|| l_Att);
    End If;
    --任务单组件
    If (P_DEBUG_FLAG = 'Y') Then
      WipReqOptsHtml(P_MTT, P_COMPONENT_NUM, l_OnHand, l_Att,l_Flag);
    End If;
    ---批次管控 创建批次行记录
    If (P_MTT.Item_Lot_Control_Code = 2 And ((l_Att > 0 And P_MTT.TRANSACTION_UOM <> 'PCS') Or
      (l_Att > 1 And P_MTT.TRANSACTION_UOM = 'PCS')) ) Then
      If(P_DEBUG_FLAG='Y')Then
        Output('<tr><td colspan="13" align="center">
          <table CLASS="CONTEXT" BORDERCOLOR="#669933" BORDER=1>
          <tr><td>事务处理题标识</td>
          <td>事务处理标识</td>
          <td>批次</td>
          <td>到期日期</td>
          <td>数量</td>
          <td>现有量</td>
          <td>可用量</td></tr>');
      End If;
      For RsLot In CrLot Loop
        l_LotRec.Transaction_Quantity := 0;
        l_LotRec.TRANSACTION_TEMP_ID  := P_MTT.TRANSACTION_TEMP_ID;
        l_LotRec.LOT_NUMBER           := RsLot.Lot_Number;
        l_LotRec.LOT_EXPIRATION_DATE  := RsLot.Expiration_Date;
        l_LotRec.LAST_UPDATE_DATE     := Sysdate;
        l_LotRec.LAST_UPDATED_BY      := P_MTT.Created_By;
        l_LotRec.CREATION_DATE        := Sysdate;
        l_LotRec.CREATED_BY           := P_MTT.Created_By;
        l_LotRec.LAST_UPDATE_LOGIN    := -1;

        l_Att := 0;
        l_OnHand :=0;
        --首判断某批次可用数量
        getAtt(P_MTT.Transaction_Header_Id,
               P_MTT.Inventory_Item_Id,
               P_MTT.Organization_Id,
               P_MTT.Item_Revision_Qty_Control_Code,
               P_MTT.Item_Lot_Control_Code,
               P_MTT.Item_Serial_Control_Code,
               P_MTT.Revision,
               RsLot.Lot_Number,
               P_MTT.Subinventory_Code,
               P_MTT.Locator_Id,
               l_OnHand,
               l_Att);
        If (l_Att > 0) Then
          --单位为PCS的取整数
          If (P_MTT.TRANSACTION_UOM = 'PCS') Then
            l_Att := floor(l_Att);
          End If;
          --计算批次总数量余额
          If (l_LotTotalQty <= l_Att) Then
            l_LotRec.TRANSACTION_QUANTITY := l_PlusMinus_Flag *
                                             l_LotTotalQty;
            l_LotRec.PRIMARY_QUANTITY     := l_PlusMinus_Flag *
                                             l_LotTotalQty;
            l_LotTotalQty                 := 0;
          Else
            l_LotTotalQty                 := l_LotTotalQty - l_Att;
            l_LotRec.TRANSACTION_QUANTITY := l_PlusMinus_Flag * l_Att;
            l_LotRec.PRIMARY_QUANTITY     := l_PlusMinus_Flag * l_Att;
          End If;
          Insert Into MTL_TRANSACTION_LOTS_TEMP Values l_LotRec;
          Log('批次:'|| l_LotRec.Lot_Number ||',发料数量:'|| Abs(l_LotRec.TRANSACTION_QUANTITY)
            ||',可用量:'|| l_Att);
          If (P_DEBUG_FLAG = 'Y') Then
            WipLotsHtml(P_MTT,
                        RsLot.Lot_Number,
                        RsLot.Expiration_Date,
                        l_LotRec.Transaction_Quantity,
                        l_OnHand,l_Att);
          End If;
          If (l_LotTotalQty = 0) Then
            Exit;
          End If;
        End If;
      End Loop;
      If(P_DEBUG_FLAG='Y')Then
        Output('</table></td></tr>');
      End If;
      --若批次总数量与临时事务处理数量的绝对值相同,则删除临时事务处理记录,反之,更新临时事务处理的数量
      If (l_LotTotalQty = abs(P_MTT.TRANSACTION_QUANTITY)) Then
        Delete From mtl_material_transactions_temp
         Where transaction_header_id = P_MTT.Transaction_Header_Id
           And transaction_temp_id = P_MTT.Transaction_Temp_Id;
        X_COMMIT_COUNT := X_COMMIT_COUNT - 1;
      Else
        Select Sum(Transaction_Quantity)
          Into l_LotTotalQty
          From MTL_TRANSACTION_LOTS_TEMP
         Where TRANSACTION_TEMP_ID = P_MTT.Transaction_Temp_Id;
        --更新临时事务处理的数量
        Update mtl_material_transactions_temp
           Set transaction_quantity = l_LotTotalQty,
               primary_quantity     = l_LotTotalQty
         Where transaction_header_id = P_MTT.Transaction_Header_Id
           And transaction_temp_id = P_MTT.Transaction_Temp_Id;
      End If;
    End If;
  End InsertMTT;
  /*
  p_transaction_mode :MMT事务处理模式:1为
  p_wip_entity_id 任务单ID
  p_line_id ??
  p_transaction_date 事务处理日期
  p_transaction_type_id 事务处理类型ID
  p_transaction_action_id 事务处理活动ID
  p_subinventory  子库存
  p_locator_id   货位
  p_assembly_quantity 标准-装配件数量
  p_operation_seq_num 标准-工序
  p_department_id    标准-部门ID
  p_criteria_sub     标准-子库存
  p_organization_id  库存组织ID
  p_acct_period_id   会计期ID
  p_last_updated_by  修改人
  p_entity_type      实体类型
  p_transaction_header_id 事务处理题头ID
  p_commit_counter  提交数量
  */
  Procedure InsertTemp(P_TRANSACTION_MODE      IN NUMBER,
                       P_WIP_ENTITY_ID         IN NUMBER,
                       P_LINE_ID               IN NUMBER,
                       P_TRANSACTION_DATE      IN DATE,
                       P_TRANSACTION_TYPE_ID   IN NUMBER,
                       P_TRANSACTION_ACTION_ID IN NUMBER,
                       P_SUBINVENTORY          IN VARCHAR2,
                       P_LOCATOR_ID            IN NUMBER,
                       P_ASSEMBLY_QUANTITY     IN NUMBER,
                       P_OPERATION_SEQ_NUM     IN NUMBER,
                       P_DEPARTMENT_ID         IN NUMBER,
                       P_CRITERIA_SUB          IN VARCHAR2,
                       P_ORGANIZATION_ID       IN NUMBER,
                       P_ACCT_PERIOD_ID        IN NUMBER,
                       P_LAST_UPDATED_BY       IN NUMBER,
                       P_ENTITY_TYPE           IN NUMBER,
                       P_TRANSACTION_HEADER_ID IN NUMBER,
                       P_DEBUG_FLAG            VARCHAR2,
                       X_COMMIT_COUNT          In Out Number) Is
    x_transaction_source_type_id NUMBER;
    x_transaction_source_id      NUMBER;
    x_item_segments              VARCHAR2(2000);
    x_locator_id                 NUMBER;
    x_locator_control            NUMBER;
    x_locator_segments           VARCHAR2(2000);
    x_valid_locator_flag         VARCHAR2(2);
    x_dummy                      BOOLEAN;
    x_rev                        VARCHAR2(5) := NULL;
    x_wip_commit_flag            VARCHAR2(2);
    i                            NUMBER := 0;
    x_released_revs_type         NUMBER;
    x_released_revs_meaning      Varchar2(30);

    l_Rec mtl_material_transactions_temp%Rowtype;

    l_PlusMinus_Flag Number; --正负标志
    CURSOR CDIS IS
      SELECT WIP_COMPONENT.Determine_Txn_Quantity(p_transaction_action_id,
                                                  wro.quantity_per_assembly,
                                                  wro.required_quantity,
                                                  wro.quantity_issued,
                                                  p_assembly_quantity) transaction_quantity,
             wro.inventory_item_id,
             msinv.secondary_inventory_name subinventory_code,
             wro.quantity_issued,
             wro.required_quantity,
             wro.quantity_per_assembly,
             bd.department_id,
             bd.department_code,
             wro.operation_seq_num,
             wro.wip_supply_type,
             wro.supply_subinventory,
             wro.supply_locator_id,
             msi.mtl_transactions_enabled_flag,
             msi.description,
             msi.location_control_code,
             msi.restrict_subinventories_code,
             msi.restrict_locators_code,
             msi.revision_qty_control_code,
             msi.primary_uom_code,
             mum.uom_class,
             msi.inventory_asset_flag,
             msi.allowed_units_lookup_code,
             msi.shelf_life_code,
             msi.shelf_life_days,
             /* decode(msi.serial_number_control_code,2,2,5,2,1) serial_control_code, */
             decode(msi.serial_number_control_code, 2, 2, 5, 5, 1) serial_control_code, /* Bug 2914137 */
             msi.lot_control_code,
             msinv.locator_type,
             msi.start_auto_lot_number,
             msi.auto_lot_alpha_prefix,
             msi.start_auto_serial_number,
             msi.auto_serial_alpha_prefix,
             mil.inventory_location_id,
             mil.disable_date locator_disable_date,
             mp.stock_locator_control_code,
             WIP_COMPONENT.Valid_Subinventory(msinv.secondary_inventory_name,
                                              msi.inventory_item_id,
                                              p_organization_id) valid_subinventory_flag,
             mil.project_id,
             mil.task_id,
             wdj.project_id source_project_id,
             wdj.task_id source_task_id,
             msi.eam_item_type,
             MSI.SEGMENT1 COMPONENT_NUM
        FROM mtl_parameters             mp,
             mtl_item_locations         mil,
             mtl_secondary_inventories  msinv,
             mtl_units_of_measure       mum,
             bom_departments            bd,
             mtl_system_items           msi,
             wip_discrete_jobs          wdj,
             wip_requirement_operations wro
       WHERE wro.wip_entity_id = p_wip_entity_id
         AND wro.organization_id = p_organization_id
         --AND WRO.INVENTORY_ITEM_ID = 1897
         AND WIP_COMPONENT.is_valid(p_transaction_action_id,
                                    wro.wip_supply_type,
                                    wro.required_quantity,
                                    wro.quantity_issued,
                                    p_assembly_quantity,
                                    p_entity_type) = WIP_CONSTANTS.YES
         AND WIP_COMPONENT.meets_criteria(wro.operation_seq_num,
                                          p_operation_seq_num,
                                          wro.department_id,
                                          p_department_id,
                                          wro.supply_subinventory,
                                          p_criteria_sub) =
             WIP_CONSTANTS.YES
         AND wdj.wip_entity_id = wro.wip_entity_id
         AND wdj.organization_id = wro.organization_id
         AND bd.department_id(+) = wro.department_id
         AND bd.organization_id(+) = wro.organization_id
         AND msi.inventory_item_id = wro.inventory_item_id
         AND msi.organization_id = wro.organization_id
         AND mum.uom_code = msi.primary_uom_code
         AND msinv.organization_id(+) = wro.organization_id
         AND msinv.secondary_inventory_name(+) =
             decode(p_transaction_action_id,
                    WIP_CONSTANTS.SUBTRFR_ACTION,
                    p_subinventory,
                    NVL(wro.supply_subinventory, p_subinventory))
         And Exists ---限制用户发料子库存
       (Select 1
                From CUX_MATERIAL_ISSUED MRI
               Where MRI.MATERIAL_ID = P_LAST_UPDATED_BY
                 And MRI.ITEM_VALUE =
                     decode(p_transaction_action_id,
                            WIP_CONSTANTS.SUBTRFR_ACTION,
                            p_subinventory,
                            NVL(wro.supply_subinventory, p_subinventory))
                 And MRI.ORGANIZATION_ID = P_ORGANIZATION_ID
                 And MRI.MANAGER_CATEGORY = 'SUBINVENTORY')
         AND mil.organization_id(+) = wro.organization_id
         AND mil.inventory_location_id(+) =
             decode(p_transaction_action_id,
                    WIP_CONSTANTS.SUBTRFR_ACTION,
                    p_locator_id,
                    NVL(wro.supply_locator_id, p_locator_id))
         AND mp.organization_id = wro.organization_id
       ORDER BY wro.operation_seq_num;
  Begin
    x_wip_commit_flag := 'Y';
    /* Source Type and Source are set differently for Subinventory Replen */
    IF p_transaction_action_id = WIP_CONSTANTS.SUBTRFR_ACTION THEN
      /* Bug fix 5744865  */
      SELECT transaction_source_type_id
        into x_transaction_source_type_id
        from mtl_transaction_types
       where transaction_type_id = p_transaction_type_id;
      -- x_transaction_source_type_id := 13;
      x_transaction_source_id := NULL;
    ELSE
      x_transaction_source_type_id := 5;
      x_transaction_source_id      := p_wip_entity_id;
    END IF;

    --  set up release type
    /* 2999230 */
    wip_common.Get_Released_Revs_Type_Meaning(x_released_revs_type,
                                              x_released_revs_meaning);

    FOR C IN CDIS LOOP
      --Log('ddddddddddddddd');
      --dbms_output.put_line('subinventory_code:' || c.subinventory_code);
      x_dummy := FND_FLEX_KEYVAL.validate_ccid(appl_short_name  => 'INV',
                                               key_flex_code    => 'MSTK',
                                               structure_number => 101,
                                               combination_id   => C.inventory_item_id,
                                               data_set         => p_organization_id);

      x_item_segments := FND_FLEX_KEYVAL.concatenated_values;

      x_locator_id := C.inventory_location_id;
      /* Fix for Bug# 2149033. Added x_locator_id condition in if condition */
      IF (C.subinventory_code IS NOT NULL) and (x_locator_id IS NOT NULL) THEN
        x_valid_locator_flag := WIP_COMPONENT.Valid_Locator(x_locator_id,
                                                            C.inventory_item_id,
                                                            p_organization_id,
                                                            C.stock_locator_control_code,
                                                            C.locator_type,
                                                            C.location_control_code,
                                                            C.restrict_locators_code,
                                                            C.locator_disable_date,
                                                            x_locator_control);

        IF x_locator_control = 1 THEN
          x_locator_segments := NULL;
        ELSE

          x_dummy := FND_FLEX_KEYVAL.validate_ccid(appl_short_name  => 'INV',
                                                   key_flex_code    => 'MTLL',
                                                   structure_number => 101,
                                                   combination_id   => x_locator_id,
                                                   data_set         => p_organization_id);

          -- fix for bug 4084598
          --x_locator_segments := FND_FLEX_KEYVAL.concatenated_values;
        END IF;
      ELSE
        x_valid_locator_flag := 'N';
        x_locator_id         := null; --no locator when sub is not populated
        x_locator_segments   := NULL;
      END IF;

      IF C.revision_qty_control_code = WIP_CONSTANTS.REV THEN
        BOM_REVISIONS.Get_Revision(type         => 'PART',
                                   eco_status   => x_released_revs_meaning,
                                   examine_type => 'ALL',
                                   org_id       => P_Organization_Id,
                                   item_id      => C.inventory_item_id,
                                   rev_date     => p_transaction_date,
                                   itm_rev      => x_rev);
      ELSE
        x_rev := NULL;
      END IF;

      IF C.mtl_transactions_enabled_flag = 'N' OR
         (C.valid_subinventory_flag = 'N') OR (x_valid_locator_flag = 'N') OR
         (C.lot_control_code <> 1 AND C.transaction_quantity <> 0) OR
         (C.serial_control_code <> 1 AND C.transaction_quantity <> 0) OR
         (C.lot_control_code <> 1 AND C.serial_control_code <> 1) OR
         (C.transaction_quantity = 0 AND p_assembly_quantity IS NOT NULL AND
         p_transaction_action_id IN
         (WIP_CONSTANTS.RETNEGC_ACTION, WIP_CONSTANTS.RETCOMP_ACTION)) THEN
        x_wip_commit_flag := 'N';
      ELSE
        x_wip_commit_flag := 'Y';
      END IF;
      --Log('x_wip_commit_flag:'|| x_wip_commit_flag);
      -- bug3430508: do not insert subinv/loc if material status
      --             disables it
      if (inv_material_status_grp.is_status_applicable(NULL, -- p_wms_installed,
                                                       NULL,
                                                       p_transaction_type_id, -- p_trx_type_id (is this same as trx_type_id?)
                                                       NULL,
                                                       NULL,
                                                       p_organization_id,
                                                       C.inventory_item_id,
                                                       C.subinventory_code,
                                                       NULL,
                                                       NULL,
                                                       NULL,
                                                       'Z') = 'N') then
        C.subinventory_code := null;
        x_locator_id        := null;
      end if;

      if (inv_material_status_grp.is_status_applicable(NULL, -- p_wms_installed,
                                                       NULL,
                                                       p_transaction_type_id, -- p_trx_type_id (is this same as trx_type_id?)
                                                       NULL,
                                                       NULL,
                                                       p_organization_id,
                                                       C.inventory_item_id,
                                                       NULL,
                                                       x_locator_id,
                                                       NULL,
                                                       NULL,
                                                       'L') = 'N') then
        x_locator_id := null;
      end if;

      If (x_wip_commit_flag = 'N') Then
        l_PlusMinus_Flag := C.transaction_quantity /
                            Abs(C.transaction_quantity);

        l_Rec.Transaction_Temp_Id   := Null;
        l_Rec.item_segments         := x_item_segments;
        l_Rec.locator_segments      := x_locator_segments;
        l_Rec.primary_switch        := i;
        l_Rec.transaction_header_id := p_transaction_header_id;
        If (p_transaction_mode = 2) Then
          l_Rec.transaction_mode := 2;
        Else
          l_Rec.transaction_mode := 1;
        End If;
        l_Rec.lock_flag         := 'N';
        l_Rec.inventory_item_id := C.inventory_item_id;
        l_Rec.subinventory_code := C.subinventory_code;
        If (C.eam_item_type = 3) Then
          l_Rec.primary_quantity     := 1;
          l_Rec.transaction_quantity := 1;
        Else
          If (C.Primary_Uom_Code = 'PCS') Then
            --单位为PCS上向取整
            l_Rec.primary_quantity     := l_PlusMinus_Flag *
                                          Ceil(Abs(C.transaction_quantity));
            l_Rec.transaction_quantity := l_PlusMinus_Flag *
                                          Ceil(Abs(C.transaction_quantity));

          Else
            l_Rec.primary_quantity     := C.transaction_quantity;
            l_Rec.transaction_quantity := C.transaction_quantity;

          End If;
        End If;
        l_Rec.number_of_lots_entered := C.transaction_quantity;

        l_Rec.transaction_date           := p_transaction_date;
        l_Rec.organization_id            := p_organization_id;
        l_Rec.acct_period_id             := p_acct_period_id;
        l_Rec.last_update_date           := SYSDATE;
        l_Rec.last_updated_by            := p_last_updated_by;
        l_Rec.creation_date              := SYSDATE;
        l_Rec.created_by                 := p_last_updated_by;
        l_Rec.transaction_source_id      := x_transaction_source_id;
        l_Rec.transaction_source_type_id := x_transaction_source_type_id;
        l_Rec.transaction_type_id        := p_transaction_type_id;
        l_Rec.transaction_action_id      := p_transaction_action_id;
        l_Rec.wip_entity_type            := p_entity_type;
        l_Rec.repetitive_line_id         := p_line_id;
        l_Rec.department_id              := C.department_id;
        l_Rec.department_code            := C.department_code;
        l_Rec.locator_id                 := x_locator_id;
        l_Rec.required_flag              := 1;
        l_Rec.operation_seq_num          := C.operation_seq_num;
        If (p_transaction_action_id = 2) Then
          l_Rec.transfer_subinventory := C.supply_subinventory;
          l_Rec.transfer_to_location  := C.supply_locator_id;
        Else
          l_Rec.transfer_subinventory := NULL;
          l_Rec.transfer_to_location  := NULL;
        End If;
        l_Rec.wip_supply_type                := C.wip_supply_type;
        l_Rec.supply_subinventory            := C.supply_subinventory;
        l_Rec.supply_locator_id              := C.supply_locator_id;
        l_Rec.item_trx_enabled_flag          := C.mtl_transactions_enabled_flag;
        l_Rec.item_description               := C.description;
        l_Rec.item_location_control_code     := C.location_control_code;
        l_Rec.item_restrict_subinv_code      := C.restrict_subinventories_code;
        l_Rec.item_restrict_locators_code    := C.restrict_locators_code;
        l_Rec.item_revision_qty_control_code := C.revision_qty_control_code;
        l_Rec.revision                       := x_rev;
        l_Rec.item_primary_uom_code          := C.primary_uom_code;
        l_Rec.transaction_uom                := C.primary_uom_code;
        l_Rec.item_uom_class                 := C.uom_class;
        l_Rec.item_inventory_asset_flag      := C.inventory_asset_flag;
        l_Rec.allowed_units_lookup_code      := C.allowed_units_lookup_code;
        l_Rec.item_shelf_life_code           := C.shelf_life_code;
        l_Rec.item_shelf_life_days           := C.shelf_life_days;
        l_Rec.item_serial_control_code       := C.serial_control_code;
        l_Rec.item_lot_control_code          := C.lot_control_code;
        l_Rec.current_locator_control_code   := C.locator_type;
        l_Rec.wip_commit_flag                := x_wip_commit_flag;

        l_Rec.next_lot_number         := C.start_auto_lot_number;
        l_Rec.next_serial_number      := C.start_auto_serial_number;
        l_Rec.lot_alpha_prefix        := C.auto_lot_alpha_prefix;
        l_Rec.serial_alpha_prefix     := C.auto_serial_alpha_prefix;
        l_Rec.valid_subinventory_flag := C.valid_subinventory_flag;
        l_Rec.valid_locator_flag      := x_valid_locator_flag;
        l_Rec.negative_req_flag       := sign(C.required_quantity);
        l_Rec.posting_flag            := 'Y';
        l_Rec.process_flag            := 'Y';
        l_Rec.project_id              := C.project_id;
        l_Rec.task_id                 := C.task_id;
        l_Rec.source_project_id       := C.source_project_id;
        l_Rec.source_task_id          := C.source_task_id;
        --dbms_output.put_line('Inventory_Item_Id:' || l_Rec.Inventory_Item_Id);
        InsertMTT(l_Rec, C.Component_Num, P_DEBUG_FLAG,X_COMMIT_COUNT);

      End If;
      i := i + 1;
    END LOOP;
    --dbms_output.put_line('i:' || i);
  End InsertTemp;

End CUX_WIPBATTXMAT_PKG;
注意:本案批量发料必须要一张任务单发料以后,才能发下一张任务单物料,否则,会出现误判现有量够用。


猜你喜欢

转载自blog.csdn.net/chenxianping/article/details/79290116