zoukankan      html  css  js  c++  java
  • Oracle中对象表的定义,nested table的使用.附带Route下载的老版本代码

    如下建立的表脚本

    DROP TABLE TMS.TMS_OBJ_ROUTE_DATA CASCADE CONSTRAINTS;

    CREATE TABLE TMS.TMS_OBJ_ROUTE_DATA
    (
      ROUTE_HEADER_COL,
      ROUTE_STOPS_COL      TMS.ROUTE_STOPS,
      PO_COL               TMS.POS,
      STOP_DETAILS_COL  TMS.STOP_DETAILS,
      PO_STOP_DETAILS_COL  TMS.PO_STOP_DETAILS,
      EXPT_TEXT_COL        VARCHAR2(512 BYTE),
      EXPT_CODE_COL        VARCHAR2(10 BYTE),
      SVR_DATE_COL         DATE,
      DEVICE_ID_COL        VARCHAR2(20 BYTE),
      INSTANCEID_COL       INTEGER
    )
    NESTED TABLE ROUTE_STOPS_COL STORE AS ROUTE_STOPS_ST,
    NESTED TABLE PO_COL STORE AS POS_ST,
    NESTED TABLE STOP_DETAILS_COL STORE AS STOP_DETAILS_ST,
    NESTED TABLE PO_STOP_DETAILS_COL STORE AS PO_STOP_DETAILS_ST,
    NESTED TABLE SETTINGS_COL STORE AS SETTINGS_ST

    TABLESPACE TMSDATA
    PCTUSED    0
    PCTFREE    10
    INITRANS   1
    MAXTRANS   255
    STORAGE    (
                INITIAL          104K
                NEXT             104K
                MINEXTENTS       1
                MAXEXTENTS       UNLIMITED
                PCTINCREASE      0
                BUFFER_POOL      DEFAULT
               )
    LOGGING
    NOCOMPRESS
    NOCACHE
    NOPARALLEL
    MONITORING;


    GRANT SELECT ON TMS.TMS_OBJ_ROUTE_DATA TO TMS_GUEST;
    在使用中类似这样插入

       INSERT INTO tms_obj_route_data
                      VALUES (p_route_data.route_header, p_route_data.route_stops,
                              p_route_data.stop_pos, p_route_data.stop_details,
                              p_route_data.po_stop_details,
                              'Exception code can not be null when the status is E',
                              v_instance_id);

    附录是一个博主老版本route下载的代码,中间使用到了对象表。

    CREATE OR REPLACE PACKAGE BODY TMS.tms_ws
    AS
       FUNCTION fnexceptlist
          RETURN ex_table
       IS
          out_table   ex_table := NEW ex_table (NULL);
          isfirst     BOOLEAN  := TRUE;
       BEGIN
          FOR x IN (SELECT exception_code, exception_code_description,
                           exception_type
                      FROM tms_exception_code
                     WHERE language_code = 'EN'
                       AND exception_type IN ('STOP', 'ITEM'))
          LOOP
             IF NOT isfirst
             THEN
                out_table.EXTEND;
             END IF;

             out_table (out_table.LAST) :=
                NEW ex_rec (x.exception_code,
                            x.exception_code_description,
                            x.exception_type
                           );
             isfirst := FALSE;
          END LOOP;

          RETURN out_table;
       END;

       FUNCTION find_trailer (
          p_truck_route_instance_id         tms_route_header.truck_route_instance_id%TYPE,
          p_trailer_name                    tms_route_header.trailer_id_original_1%TYPE,
          p_dow                             tms_route_header.dow%TYPE,
          p_load_dt                         tms_route_header.host_created_dt%TYPE,
          p_trailer_out               OUT   tms_route_header.trailer_id_original_1%TYPE
       )
          RETURN BOOLEAN
       AS
          --declaration;
          v_trailer_id   tms_route_header.trailer_id_original_1%TYPE;

          CURSOR trailer_data
          IS
             SELECT DISTINCT trl.trailer_name
                        FROM tms_route_header hdr,
                             tms_stop_detail dtl,
                             wms_intf_trailer_content trl
                       WHERE dtl.truck_route_instance_id =
                                                       hdr.truck_route_instance_id
                         AND trl.sub_truck_route_id = hdr.truck_route_id
                         AND trl.sub_dow = hdr.dow
                         AND trl.location_id = dtl.shipping_unit_id
                         AND trl.intf_dt > SYSDATE - 7
                         AND hdr.truck_route_instance_id =
                                                         p_truck_route_instance_id
                         AND trl.trailer_name <> p_trailer_name;
       --end declaration;
       BEGIN
          OPEN trailer_data;

          LOOP
             FETCH trailer_data
              INTO v_trailer_id;

             EXIT WHEN trailer_data%NOTFOUND;

             BEGIN
                --if the trailer_id did not pass the hasbol function already, just skip to the next record.
                IF wms.wms_tms_intf.trailer_has_bol (v_trailer_id,
                                                     p_dow,
                                                     p_load_dt
                                                    )
                THEN
                   UPDATE tms_route_header
                      SET trailer_id_original_1 = v_trailer_id
                    WHERE truck_route_instance_id = p_truck_route_instance_id;

                   COMMIT;
                   p_trailer_out := v_trailer_id;
                   RETURN TRUE;
                END IF;
             EXCEPTION
                WHEN NO_DATA_FOUND
                THEN
                   NULL;
             END;
          END LOOP;

          p_trailer_out := p_trailer_name;
          RETURN FALSE;
       END;

       FUNCTION route_download_deviceid (
          p_route_no          NUMBER,
          p_dow               VARCHAR2,
          p_allow_duplicate   NUMBER,
          p_device_id         VARCHAR2
       )
          RETURN route_data
       AS
          v_route_data   route_data
                                 := NEW route_data (NULL, NULL, NULL, NULL, NULL);
       BEGIN
          BEGIN
             v_route_data :=
                            route_download (p_route_no, p_dow, p_allow_duplicate);
          EXCEPTION
             WHEN OTHERS
             THEN      --Only the exception throw out is route downloaded already.
                DECLARE
                   ERROR_CODE   NUMBER := SQLCODE;
                BEGIN
                   IF ERROR_CODE = -20001
                   THEN
                      raise_application_error (-20001,
                                               'Route already downloaded.'
                                              );
                   END IF;

                   IF ERROR_CODE = -20005
                   THEN
                      raise_application_error (-20005,
                                               'Route failed auth from wms.'
                                              );
                   END IF;

                   raise_application_error (-20008,
                                               'ERRCODE:'
                                            || SQLCODE
                                            || ' ERRTEXT:'
                                            || SQLERRM
                                           );
                END;
          END;

          -- When no exception, we record this download, because we throw exception for download it again.
          IF v_route_data.route_header IS NOT NULL
          THEN
             INSERT INTO tms_route_download
                         (truck_route_instance_id, device_id,
                          download_date
                         )
                  VALUES (v_route_data.route_header.instance_id, p_device_id,
                          SYSDATE
                         );
          END IF;

          RETURN v_route_data;
       END;

       FUNCTION route_download (
          p_route_no          IN   NUMBER,
          p_dow               IN   VARCHAR2,
          p_allow_duplicate   IN   NUMBER
       )
          RETURN route_data
       AS
          invalid_route_downloaded   EXCEPTION;
          invalid_route_auth         EXCEPTION;
          -- pragma EXCEPTION_INIT(invalid_route_downloaded,-2292);
          v_instance_id              INTEGER;
          v_route_data               route_data
                                 := NEW route_data (NULL, NULL, NULL, NULL, NULL);
          v_route_header             route_header;
          v_route_stops              route_stops;
          v_stop_details             stop_details;
          v_pos                      pos;
          v_po_stop_details          po_stop_details;
          v_first_index              BOOLEAN;

          TYPE auth_type IS RECORD (
             t_truck_route_instance_id   tms_route_header.truck_route_instance_id%TYPE,
             t_trailer_name              tms_route_header.trailer_id_original_1%TYPE,
             t_dow                       tms_route_header.dow%TYPE,
             t_load_dt                   tms_route_header.host_created_dt%TYPE,
             t_download_date             tms_route_header.download_date%TYPE
          );

          auth_rec                   auth_type;
       BEGIN
          BEGIN
             SELECT truck_route_instance_id,
                    trailer_id_original_1,
                    dow,
                    host_created_dt,
                    download_date
               INTO auth_rec
               FROM (SELECT *
                       FROM (SELECT   rh.truck_route_instance_id,
                                      rh.trailer_id_original_1, rh.dow,
                                      rh.host_created_dt,
                                      (SELECT MIN
                                                 (dld.download_date)
                                         FROM tms.tms_route_download dld
                                        WHERE dld.truck_route_instance_id =
                                                        rh.truck_route_instance_id)
                                                                    download_date
                                 FROM tms.tms_route_header rh
                                WHERE rh.truck_route_id = p_route_no
                                  AND rh.dow = p_dow
                                  AND rh.delete_flag = 'N'
                                  AND rh.scheduled_departure_date > SYSDATE - 6
                             ORDER BY ABS (SYSDATE - rh.scheduled_departure_date)) u
                      WHERE ROWNUM = 1);
          EXCEPTION
             WHEN NO_DATA_FOUND
             THEN
                RETURN v_route_data;                            --emtpy data back
          END;

          IF NOT wms.wms_tms_intf.trailer_has_bol (auth_rec.t_trailer_name,
                                                   auth_rec.t_dow,
                                                   auth_rec.t_load_dt
                                                  )
          THEN
             IF NOT find_trailer (auth_rec.t_truck_route_instance_id,
                                  auth_rec.t_trailer_name,
                                  auth_rec.t_dow,
                                  auth_rec.t_load_dt,
                                  auth_rec.t_trailer_name
                                 )
             THEN
                RAISE invalid_route_auth;
             --RETURN v_route_data; --empty data back
             END IF;
          END IF;

          v_route_header :=
             NEW route_header (auth_rec.t_truck_route_instance_id,
                               p_route_no,
                               auth_rec.t_dow,
                               auth_rec.t_trailer_name,
                               SYSDATE
                              );
          v_route_data.route_header := v_route_header;
          v_instance_id := v_route_header.instance_id;
          --Fill ROUTE_STOPS
          v_route_stops := NEW route_stops (NULL);

          IF p_allow_duplicate = 0
          THEN
             IF auth_rec.t_download_date IS NOT NULL
             THEN
                RAISE invalid_route_downloaded;
             END IF;
          END IF;

          SELECT   route_stop (s.stop_id,
                               l.location_name,
                               s.location_id,
                               l.address_1,
                               l.address_2,
                               l.city,
                               l.state_abbr,
                               l.alarm_code,
                               s.scheduled_arrival_dt,
                               s.scheduled_departure_dt,
                               s.actual_arrival_dt,
                               s.actual_departure_dt,
                               s.contacts,
                               s.special_instructions,
                               DECODE (s.status, 'OPEN', NULL, s.status),
                               s.exception_code,
                               'Y',
                               s.stop_seq,
                               s.enroute_time,
                               s.exception_comments
                              )
          BULK COLLECT INTO v_route_stops
              FROM tms.tms_route_stop s INNER JOIN tms_location l
                   ON l.location_id = s.location_id
             WHERE s.truck_route_instance_id = v_instance_id
               AND s.delete_flag = 'N'
          ORDER BY stop_seq ASC;

          v_route_data.route_stops := v_route_stops;
          --Fill STOP_DETAILS
          v_stop_details := NEW stop_details (NULL);

          SELECT stop_detail (x.stop_detail_id,
                              NULL,
                              SUBSTR (x.task_type, 0, 1),
                              x.shipping_unit_id,
                              x.description,
                              x.package_type,
                              x.status,
                              x.scan_flag,
                              x.exception_code,
                              NULL,
                              x.scan_dt,
                              x.weight,
                              x.weight_uom,
                              x.stop_id,
                              'Y',
                              DECODE (x.exception_code,
                                      NULL, NVL (x.exception_comment,
                                                 x.container_id
                                                ),
                                      x.exception_comment
                                     )
                             )
          BULK COLLECT INTO v_stop_details
            FROM tms.tms_stop_detail x
           WHERE truck_route_instance_id = v_instance_id
             AND delete_flag = 'N'
             AND shipping_unit_id <> 'FAKE PALLET';

          v_route_data.stop_details := v_stop_details;
          --Fill POS
          v_pos := NEW pos (NULL);

          SELECT po (x.stop_id,
                     x.po_id,
                     x.delete_flag,
                     x.weight,
                     x.weight_uom,
                     'Y'
                    )
          BULK COLLECT INTO v_pos
            FROM tms.tms_po x
           WHERE truck_route_instance_id = v_instance_id AND delete_flag = 'N';

          v_route_data.stop_pos := v_pos;
          --Fill PO_STOP_DETAILS
          v_po_stop_details := NEW po_stop_details (NULL);

          SELECT po_stop_detail (x.stop_detail_id,
                                 x.po_id,
                                 x.stop_id,
                                 x.delete_flag,
                                 'Y'
                                )
          BULK COLLECT INTO v_po_stop_details
            FROM tms.tms_po_stop_detail x
           WHERE truck_route_instance_id = v_instance_id AND delete_flag = 'N';

          v_route_data.po_stop_details := v_po_stop_details;
          RETURN v_route_data;
       EXCEPTION
          WHEN NO_DATA_FOUND
          THEN
             RETURN v_route_data;
          WHEN invalid_route_downloaded
          THEN
             raise_application_error (-20001, 'Route already downloaded.');
          WHEN invalid_route_auth
          THEN
             raise_application_error (-20005, 'Route failed auth from wms.');
       END;

       FUNCTION route_download_deviceid_ex (
          p_route_no          IN       NUMBER,
          p_dow               IN       VARCHAR2,
          p_allow_duplicate   IN       NUMBER,
          p_device_id         IN       VARCHAR2,
          o_req_result        OUT      reqresult
       )
          RETURN route_data_ex
       AS
          invalid_route_downloaded   EXCEPTION;
          invalid_route_auth         EXCEPTION;
          -- pragma EXCEPTION_INIT(invalid_route_downloaded,-2292);
          v_instance_id              INTEGER;
          v_route_data               route_data_ex
                              := NEW route_data_ex (NULL, NULL, NULL, NULL, NULL);
          v_route_header             route_header_ex;
          v_route_stops              route_stops;
          v_stop_details             stop_details_ex;
          v_pos                      pos;
          v_po_stop_details          po_stop_details;
          v_first_index              BOOLEAN;

          TYPE auth_type IS RECORD (
             t_truck_route_instance_id   tms_route_header.truck_route_instance_id%TYPE,
             t_trailer_name              tms_route_header.trailer_id_original_1%TYPE,
             t_dow                       tms_route_header.dow%TYPE,
             t_load_dt                   tms_route_header.host_created_dt%TYPE,
             t_download_date             tms_route_header.download_date%TYPE
          );

          auth_rec                   auth_type;
       BEGIN
          BEGIN
             SELECT truck_route_instance_id,
                    trailer_id_original_1,
                    dow,
                    host_created_dt,
                    download_date
               INTO auth_rec
               FROM (SELECT *
                       FROM (SELECT   rh.truck_route_instance_id,
                                      rh.trailer_id_original_1, rh.dow,
                                      rh.host_created_dt,
                                      (SELECT MIN
                                                 (dld.download_date)
                                         FROM tms.tms_route_download dld
                                        WHERE dld.truck_route_instance_id =
                                                        rh.truck_route_instance_id)
                                                                    download_date
                                 FROM tms.tms_route_header rh
                                WHERE rh.truck_route_id = p_route_no
                                  AND rh.dow = p_dow
                                  AND rh.delete_flag = 'N'
                                  AND rh.scheduled_departure_date  > SYSDATE - 6
                             ORDER BY rh.truck_route_instance_id DESC) u
                      WHERE ROWNUM = 1);
          EXCEPTION
             WHEN NO_DATA_FOUND
             THEN
                o_req_result :=
                   NEW reqresult (0,
                                  -20000,
                                  'Route download without data.',
                                  SYSDATE
                                 );
                RETURN v_route_data;                             --emtpy data back
          END;

          IF NOT wms.wms_tms_intf.trailer_has_bol (auth_rec.t_trailer_name,
                                                   auth_rec.t_dow,
                                                   auth_rec.t_load_dt
                                                  )
          THEN
             IF NOT find_trailer (auth_rec.t_truck_route_instance_id,
                                  auth_rec.t_trailer_name,
                                  auth_rec.t_dow,
                                  auth_rec.t_load_dt,
                                  auth_rec.t_trailer_name
                                 )
             THEN
                RAISE invalid_route_auth;
             END IF;
          END IF;

          v_route_header :=
             NEW route_header_ex (auth_rec.t_truck_route_instance_id,
                                  p_route_no,
                                  auth_rec.t_dow,
                                  auth_rec.t_trailer_name,
                                  SYSDATE,
                                  '',
                                  '',
                                  ''
                                 );
          v_route_data.route_header := v_route_header;
          v_instance_id := v_route_header.instance_id;
          --Fill ROUTE_STOPS
          v_route_stops := NEW route_stops (NULL);

          IF p_allow_duplicate = 0
          THEN
             IF auth_rec.t_download_date IS NOT NULL
             THEN
                RAISE invalid_route_downloaded;
             END IF;
          END IF;

          SELECT   route_stop (s.stop_id,
                               l.location_name,
                               s.location_id,
                               l.address_1,
                               l.address_2,
                               l.city,
                               l.state_abbr,
                               l.alarm_code,
                               s.scheduled_arrival_dt,
                               s.scheduled_departure_dt,
                               s.actual_arrival_dt,
                               s.actual_departure_dt,
                               s.contacts,
                               s.special_instructions,
                               DECODE (s.status, 'OPEN', NULL, s.status),
                               s.exception_code,
                               'Y',
                               s.stop_seq,
                               s.enroute_time,
                               s.exception_comments
                              )
          BULK COLLECT INTO v_route_stops
              FROM tms.tms_route_stop s INNER JOIN tms_location l
                   ON l.location_id = s.location_id
             WHERE s.truck_route_instance_id = v_instance_id
               AND s.delete_flag = 'N'
          ORDER BY stop_seq ASC;

          v_route_data.route_stops := v_route_stops;
          --Fill STOP_DETAILS
          v_stop_details := NEW stop_details_ex (NULL);

          SELECT stop_detail_ex (stop_detail_id,
                                 NULL,
                                 SUBSTR (task_type, 0, 1),
                                 shipping_unit_id,
                                 description,
                                 package_type,
                                 status,
                                 scan_flag,
                                 exception_code,
                                 NULL,
                                 scan_dt,
                                 weight,
                                 weight_uom,
                                 stop_id,
                                 'Y',
                                 exception_comment,
                                 container_id,
                                 next_detail_id,
                                 'N',
                                 item_id,
                                 ''
                                )
          BULK COLLECT INTO v_stop_details
            FROM tms.tms_stop_detail
           WHERE truck_route_instance_id = v_instance_id
             AND delete_flag = 'N'
             AND shipping_unit_id <> 'FAKE PALLET';

          v_route_data.stop_details := v_stop_details;
          --Fill POS
          v_pos := NEW pos (NULL);

          SELECT po (x.stop_id,
                     x.po_id,
                     x.delete_flag,
                     x.weight,
                     x.weight_uom,
                     'Y'
                    )
          BULK COLLECT INTO v_pos
            FROM tms.tms_po x
           WHERE truck_route_instance_id = v_instance_id AND delete_flag = 'N';

          v_route_data.stop_pos := v_pos;
          --Fill PO_STOP_DETAILS
          v_po_stop_details := NEW po_stop_details (NULL);

          SELECT po_stop_detail (x.stop_detail_id,
                                 x.po_id,
                                 x.stop_id,
                                 x.delete_flag,
                                 'Y'
                                )
          BULK COLLECT INTO v_po_stop_details
            FROM tms.tms_po_stop_detail x
           WHERE truck_route_instance_id = v_instance_id AND delete_flag = 'N';

          v_route_data.po_stop_details := v_po_stop_details;

          INSERT INTO tms_route_download
                      (truck_route_instance_id, device_id, download_date
                      )
               VALUES (v_route_data.route_header.instance_id, p_device_id, SYSDATE
                      );

          o_req_result :=
                     NEW reqresult (1, 0, 'Route download successfully.', SYSDATE);
          RETURN v_route_data;
       EXCEPTION
          --it's impossible to go to here, bulk collect into will not cause no_data_found .
          /*
             WHEN NO_DATA_FOUND
             THEN
                o_req_result :=
                   NEW reqresult (0, -20000, 'Route download without data.',
                                  SYSDATE);
                RETURN v_route_data;
                */
          WHEN invalid_route_downloaded
          THEN
             o_req_result :=
                   NEW reqresult (0, -20001, 'Route already downloaded.',
                                  SYSDATE);
             RETURN v_route_data;
          --raise_application_error (-20001, 'Route already downloaded.');
          WHEN invalid_route_auth
          THEN
             o_req_result :=
                 NEW reqresult (0, -20005, 'Route failed auth from wms.',
                                SYSDATE);
             RETURN v_route_data;
          WHEN OTHERS
          THEN
             o_req_result := NEW reqresult (0, SQLCODE, SQLERRM, SYSDATE);
             RETURN v_route_data;
       --  raise_application_error (-20005, 'Route failed auth from wms.');
       END;

       FUNCTION data_to_hh (p_instance_id IN NUMBER, last_update IN DATE)
          RETURN route_data
       AS
          v_route_data        route_data
                                 := NEW route_data (NULL, NULL, NULL, NULL, NULL);
          v_route_header      route_header;
          v_route_stops       route_stops;
          v_stop_details      stop_details;
          v_pos               pos;
          v_po_stop_details   po_stop_details;
          v_first_index       BOOLEAN;
          p_lastupdate        DATE            := last_update;
       BEGIN
          SELECT route_header (truck_route_instance_id,
                               truck_route_id,
                               dow,
                               trailer_id_original_1,
                               SYSDATE
                              )
            INTO v_route_header
            FROM tms.tms_route_header
           WHERE truck_route_instance_id = p_instance_id;

          v_route_data.route_header := v_route_header;
          --Fill ROUTE_STOPS
          v_route_stops := NEW route_stops (NULL);
          v_first_index := TRUE;

          SELECT   route_stop (s.stop_id,
                               l.location_name,
                               s.location_id,
                               l.address_1,
                               l.address_2,
                               l.city,
                               l.state_abbr,
                               l.alarm_code,
                               s.scheduled_arrival_dt,
                               s.scheduled_departure_dt,
                               s.actual_arrival_dt,
                               s.actual_departure_dt,
                               s.contacts,
                               s.special_instructions,
                               s.status,
                               s.exception_code,
                               'Y',
                               s.stop_seq,
                               s.enroute_time,
                               s.exception_comments
                              )
          BULK COLLECT INTO v_route_stops
              FROM tms.tms_route_stop s INNER JOIN tms_location l
                   ON l.location_id = s.location_id
             WHERE s.truck_route_instance_id = p_instance_id
               AND s.delete_flag = 'N'
               AND s.last_update > p_lastupdate
          ORDER BY stop_seq ASC;

          v_route_data.route_stops := v_route_stops;
          --Fill STOP_DETAILS
          v_stop_details := NEW stop_details (NULL);

          SELECT stop_detail (stop_detail_id,
                              NULL,
                              SUBSTR (task_type, 0, 1),
                              shipping_unit_id,
                              description,
                              package_type,
                              DECODE (status, 'OPEN', NULL, status),
                              scan_flag,
                              exception_code,
                              NULL,
                              scan_dt,
                              weight,
                              weight_uom,
                              stop_id,
                              'Y',
                              DECODE (exception_code,
                                      NULL, NVL (exception_comment, container_id),
                                      exception_comment
                                     )
                             )
          BULK COLLECT INTO v_stop_details
            FROM tms.tms_stop_detail
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate
             AND shipping_unit_id <> 'FAKE PALLET';

          v_route_data.stop_details := v_stop_details;
          --Fill POS
          v_pos := NEW pos (NULL);

          SELECT po (x.stop_id,
                     x.po_id,
                     x.delete_flag,
                     x.weight,
                     x.weight_uom,
                     'Y'
                    )
          BULK COLLECT INTO v_pos
            FROM tms.tms_po x
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate;

          v_route_data.stop_pos := v_pos;
          --Fill PO_STOP_DETAILS
          v_po_stop_details := NEW po_stop_details (NULL);

          SELECT po_stop_detail (x.stop_detail_id,
                                 x.po_id,
                                 x.stop_id,
                                 x.delete_flag,
                                 'Y'
                                )
          BULK COLLECT INTO v_po_stop_details
            FROM tms.tms_po_stop_detail x
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate;

          v_route_data.po_stop_details := v_po_stop_details;
          RETURN v_route_data;
       EXCEPTION
          WHEN NO_DATA_FOUND
          THEN
             RETURN v_route_data;
       END;

       FUNCTION data_to_hh_ex (p_instance_id IN NUMBER, last_update IN DATE)
          RETURN route_data_ex
       AS
          v_route_data        route_data_ex
                              := NEW route_data_ex (NULL, NULL, NULL, NULL, NULL);
          v_route_header      route_header_ex;
          v_route_stops       route_stops;
          v_stop_details      stop_details_ex;
          v_pos               pos;
          v_po_stop_details   po_stop_details;
          v_first_index       BOOLEAN;
          p_lastupdate        DATE            := last_update;
       BEGIN
          SELECT route_header_ex (truck_route_instance_id,
                                  truck_route_id,
                                  dow,
                                  trailer_id_original_1,
                                  SYSDATE,
                                  '',
                                  '',
                                  ''
                                 )
            INTO v_route_header
            FROM tms.tms_route_header
           WHERE truck_route_instance_id = p_instance_id;

          v_route_data.route_header := v_route_header;
          --Fill ROUTE_STOPS
          v_route_stops := NEW route_stops (NULL);
          v_first_index := TRUE;

          SELECT   route_stop (s.stop_id,
                               l.location_name,
                               s.location_id,
                               l.address_1,
                               l.address_2,
                               l.city,
                               l.state_abbr,
                               l.alarm_code,
                               s.scheduled_arrival_dt,
                               s.scheduled_departure_dt,
                               s.actual_arrival_dt,
                               s.actual_departure_dt,
                               s.contacts,
                               s.special_instructions,
                               s.status,
                               s.exception_code,
                               'Y',
                               s.stop_seq,
                               s.enroute_time,
                               s.exception_comments
                              )
          BULK COLLECT INTO v_route_stops
              FROM tms.tms_route_stop s INNER JOIN tms_location l
                   ON l.location_id = s.location_id
             WHERE s.truck_route_instance_id = p_instance_id
               AND s.delete_flag = 'N'
               AND s.last_update > p_lastupdate
          ORDER BY stop_seq ASC;

          v_route_data.route_stops := v_route_stops;
          --Fill STOP_DETAILS
          v_stop_details := NEW stop_details_ex (NULL);

          SELECT stop_detail_ex (stop_detail_id,
                                 NULL,
                                 SUBSTR (task_type, 0, 1),
                                 shipping_unit_id,
                                 description,
                                 package_type,
                                 DECODE (status, 'OPEN', NULL, status),
                                 scan_flag,
                                 exception_code,
                                 NULL,
                                 scan_dt,
                                 weight,
                                 weight_uom,
                                 stop_id,
                                 'Y',
                                 exception_comment,
                                 container_id,
                                 next_detail_id,
                                 'N',
                                 '',
                                 ''
                                )
          BULK COLLECT INTO v_stop_details
            FROM tms.tms_stop_detail
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate
             AND shipping_unit_id <> 'FAKE PALLET';

          v_route_data.stop_details := v_stop_details;
          --Fill POS
          v_pos := NEW pos (NULL);

          SELECT po (x.stop_id,
                     x.po_id,
                     x.delete_flag,
                     x.weight,
                     x.weight_uom,
                     'Y'
                    )
          BULK COLLECT INTO v_pos
            FROM tms.tms_po x
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate;

          v_route_data.stop_pos := v_pos;
          --Fill PO_STOP_DETAILS
          v_po_stop_details := NEW po_stop_details (NULL);

          SELECT po_stop_detail (x.stop_detail_id,
                                 x.po_id,
                                 x.stop_id,
                                 x.delete_flag,
                                 'Y'
                                )
          BULK COLLECT INTO v_po_stop_details
            FROM tms.tms_po_stop_detail x
           WHERE truck_route_instance_id = p_instance_id
             AND delete_flag = 'N'
             AND last_update > p_lastupdate;

          v_route_data.po_stop_details := v_po_stop_details;
          RETURN v_route_data;
       EXCEPTION
          WHEN NO_DATA_FOUND
          THEN
             RETURN v_route_data;
       END;

       FUNCTION route_suggest (p_route_no NUMBER, p_dow VARCHAR2)
          RETURN suggest_route_table
       AS
          v_suggest_data_table   suggest_route_table
                                                := NEW suggest_route_table (NULL);
          v_stop_status_table    stop_status_table
                                                  := NEW stop_status_table (NULL);
          v_first_index          BOOLEAN;
          v_first_idx            BOOLEAN;
          v_routestatus          VARCHAR2 (3);
       BEGIN
          v_first_index := TRUE;

          FOR x IN
             (WITH target_stops AS
                   (SELECT DISTINCT campus_id location_id
                               FROM wms_truck_route_vw
                              WHERE truck_route_id = p_route_no
                                AND truck_stop_seq > 1),
                   candidate_routes AS
                   (SELECT   /*+ leading(h) */
                             truck_route_id, dow, h.truck_route_instance_id
                    FROM     tms_route_header h,
                             tms_route_stop s,
                             target_stops t,
                             tms_location loc
                       WHERE h.scheduled_departure_date > SYSDATE - 6
                         AND h.truck_route_instance_id = s.truck_route_instance_id
                         AND t.location_id = s.location_id
                         AND loc.location_id = s.location_id
                         AND h.delete_flag = 'N'
                    GROUP BY truck_route_id, dow, h.truck_route_instance_id
                      HAVING COUNT (*) > 1
                         AND COUNT (DECODE (loc.hub, 'Y', NULL, 1)) > 0)
              SELECT   truck_route_id, dow,
                       (SELECT NVL (trailer_id_original_1,
                                    'UNKNOWN')
                          FROM tms_route_header rheader
                         WHERE can.truck_route_instance_id =
                                     rheader.truck_route_instance_id
                           AND ROWNUM <= 1) trailer_name,
                       (SELECT host_created_dt
                          FROM tms_route_header rheader
                         WHERE can.truck_route_instance_id =
                                         rheader.truck_route_instance_id
                           AND ROWNUM <= 1) load_day,
                       (SELECT MIN (dld.download_date)
                          FROM tms.tms_route_download dld
                         WHERE dld.truck_route_instance_id =
                                        can.truck_route_instance_id)
                                                                    download_date,
                       truck_route_instance_id
                  FROM candidate_routes can
              ORDER BY truck_route_instance_id DESC)
          LOOP
             IF NOT v_first_index
             THEN
                v_suggest_data_table.EXTEND;
             END IF;

             v_first_index := FALSE;
             v_first_idx := TRUE;
             v_stop_status_table := NEW stop_status_table (NULL);

             --clear it to regain the records
             FOR y IN (SELECT   stop_id, location_name, decode(status,'OPEN',null,status) status, stop_seq
                           FROM tms_route_stop s INNER JOIN tms_location l
                                ON l.location_id = s.location_id
                          WHERE s.truck_route_instance_id =
                                                         x.truck_route_instance_id
                            AND s.delete_flag = 'N'
                       ORDER BY stop_seq ASC)
             LOOP
                IF NOT v_first_idx
                THEN
                   v_stop_status_table.EXTEND;
                END IF;

                v_first_idx := FALSE;
                v_stop_status_table (v_stop_status_table.LAST) :=
                   NEW stop_status (y.stop_id,
                                    y.location_name,
                                    y.status,
                                    y.stop_seq
                                   );
             END LOOP;

             IF NOT wms.wms_tms_intf.trailer_has_bol (x.trailer_name,
                                                      x.dow,
                                                      x.load_day
                                                     )
             THEN
                v_routestatus := 'THB';        -- brief word for trailer_has bool
             ELSE
                v_routestatus := 'NML';                                 --normal;
             END IF;

             v_suggest_data_table (v_suggest_data_table.LAST) :=
                NEW suggest_route_data (v_stop_status_table,
                                        x.truck_route_id,
                                        x.dow,
                                        x.download_date,
                                        v_routestatus
                                       );
          END LOOP;

          RETURN v_suggest_data_table;
       END;

       FUNCTION route_update_eod (
          p_route_data      IN   route_data,
          p_is_end_of_day   IN   INTEGER,
          p_dt_eod          IN   DATE,
          p_device_id            VARCHAR2
       )
          RETURN id_update
       AS
    ---------------------------------------------*Declare some variable*---------------------------------------------------------
          constant_unattachpo   CHAR (14)                     := 'Unattached POs';
          v_route_stops         route_stops;
          v_stop_details        stop_details;
          v_pos                 pos;
          v_po_stop_details     po_stop_details;
          v_route_stop          route_stop;
          v_stop_detail         stop_detail;
          v_po_stop_detail      po_stop_detail;
          v_po                  po;
          v_last_update         DATE                                  := SYSDATE;
          v_eod                 DATE;
          v_instance_id         INTEGER                               := 0;
          v_data_counter        INTEGER                               := 0;
          v_isfirst             BOOLEAN                               := TRUE;
          v_new_id              INTEGER;
          v_unattach_exist      INTEGER                               := 0;
          t_idupdate            id_update;
          tc_idmap              id_map                       := NEW id_map (NULL);
          t_idrelation          id_relation;
          v_location_id         tms.tms_route_stop.location_id%TYPE;
          v_count               NUMBER;
          v_pallet_count        NUMBER;
          v_num                 NUMBER                                := 0;
          v_counterr            NUMBER (4);
          v_alreadyrun          NUMBER                                := 0;
          miss_route_status     EXCEPTION;
          v_miss_stp            INTEGER;
          v_cntempty            INTEGER                               := 0;
          v_cntsd               INTEGER                               := 0;
    --------------------------------------------------*End declare*---------------------------------------------------------------
       BEGIN
          --get object to local variable.
          --v_route_data := p_route_data;
          v_route_stops := p_route_data.route_stops;
          v_stop_details := p_route_data.stop_details;
          v_po_stop_details := p_route_data.po_stop_details;
          v_pos := p_route_data.stop_pos;

          --This if for initialize the empty collections, so we do not need initialize it later.
          IF v_route_stops IS NULL
          THEN
             --  ex_route_stops := NEW route_stops (NULL);
             v_route_stops := NEW route_stops (NULL);
          END IF;

          IF v_pos IS NULL
          THEN
             -- ex_pos := NEW pos (NULL);
             v_pos := NEW pos (NULL);
          END IF;

          IF v_stop_details IS NULL
          THEN
             -- ex_stop_details := NEW stop_details (NULL);
             v_stop_details := NEW stop_details (NULL);
          END IF;

          IF v_po_stop_details IS NULL
          THEN
             --  ex_po_stop_details := NEW po_stop_details (NULL);
             v_po_stop_details := NEW po_stop_details (NULL);
          END IF;

    ------End initialize the empty collections
          v_instance_id := p_route_data.route_header.instance_id;

          --Insert into the log table when end of day, so we know they do this operation.
          IF p_is_end_of_day = 1
          THEN
             INSERT INTO tms_handheld_log
                  VALUES (SUBSTR (p_device_id, 1, 20), SYSDATE, 0,
                          'BGL-ENDOFDAY', TO_CHAR (v_instance_id), SYSDATE,
                          tms_handheld_seq.NEXTVAL);
          END IF;

          UPDATE tms_route_header
             SET last_update = v_last_update
           WHERE truck_route_instance_id = v_instance_id;


          --loop for route_stop
          LOOP
             EXIT WHEN v_route_stops.FIRST IS NULL;
             v_route_stop := v_route_stops (v_route_stops.NEXT (v_data_counter));

             UPDATE tms_route_stop
                SET actual_arrival_dt = v_route_stop.actual_arrival,
                    enroute_time = v_route_stop.enroute_dt,
                    actual_departure_dt = v_route_stop.actual_departure,
                    special_instructions = v_route_stop.special_instructions,
                    exception_code = v_route_stop.exception_code,
                    exception_comments = v_route_stop.exception_comments,
                    status =
                       DECODE (v_route_stop.status,
                               NULL, 'OPEN',
                               v_route_stop.status
                              ),
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_route_stop.stop_id;

             IF v_stop_details.COUNT = 0
             --If we do not upload every thing ,we erase the unattachedPo.
             THEN
                DELETE FROM tms_stop_detail
                      WHERE stop_id = v_route_stop.stop_id
                        AND shipping_unit_id = constant_unattachpo;

                DELETE FROM tms_po_stop_detail
                      WHERE shipping_unit_id = constant_unattachpo
                        AND stop_id = v_route_stop.stop_id;
             END IF;

             v_data_counter := v_data_counter + 1;
             EXIT WHEN v_data_counter >= p_route_data.route_stops.COUNT;
          END LOOP;

          --loop for stop_detail
          v_unattach_exist := 0;
          v_data_counter := 0;

          LOOP
             EXIT WHEN v_stop_details.FIRST IS NULL;
             v_stop_detail :=
                            v_stop_details (v_stop_details.NEXT (v_data_counter));

             IF     v_stop_detail.scan_timestamp IS NULL
                AND v_stop_detail.line_status = 'E'
             THEN
                v_stop_detail.scan_timestamp := SYSDATE;
             END IF;

             UPDATE tms_stop_detail
                SET shipping_unit_id = v_stop_detail.scan_id,
                    intf_status =
                       DECODE (v_stop_detail.scan_timestamp,
                               NULL, intf_status,
                               scan_dt, intf_status,
                               'READY'
                              ),
                    status = v_stop_detail.line_status,
                    scan_flag = v_stop_detail.scan_ind,
                    scan_dt = v_stop_detail.scan_timestamp,
                    description = v_stop_detail.description,
                    weight = v_stop_detail.weight,
                    weight_uom = v_stop_detail.weight_uom,
                    exception_code = v_stop_detail.exception_code,
                    exception_comment =
                       DECODE (v_stop_detail.exception_code,
                               NULL, NULL,
                               v_stop_detail.exception_comment
                              ),                --v_stop_detail.exception_comment,
                    package_type = v_stop_detail.package_type,
                    last_update = v_last_update,
                    container_id =
                       DECODE (v_stop_detail.exception_code,
                               NULL, v_stop_detail.exception_comment,
                               NULL
                              )
              --when the exceptionCode is null,we set the value to the column.
             WHERE  truck_route_instance_id = v_instance_id
                AND stop_id = v_stop_detail.stop_id
                AND shipping_unit_id = v_stop_detail.scan_id
                AND task_type != 'DROP'
                AND task_type =
                       DECODE (v_stop_detail.pick_up_drop_off_ind,
                               'D', 'DROP',
                               'P', 'PICK',
                               'E', 'EMPT',
                               'L', 'LOAD',
                               'ERR'
                              );

             v_cntsd := SQL%ROWCOUNT;

             IF v_cntsd = 0
             THEN
                UPDATE tms_stop_detail
                   SET shipping_unit_id = v_stop_detail.scan_id,
                       intf_status =
                          DECODE (v_stop_detail.scan_timestamp,
                                  NULL, intf_status,
                                  scan_dt, intf_status,
                                  'READY'
                                 ),
                       status = v_stop_detail.line_status,
                       scan_flag = v_stop_detail.scan_ind,
                       stop_id = v_stop_detail.stop_id,
                       scan_dt = v_stop_detail.scan_timestamp,
                       description = v_stop_detail.description,
                       weight = v_stop_detail.weight,
                       weight_uom = v_stop_detail.weight_uom,
                       exception_code = v_stop_detail.exception_code,
                       exception_comment =
                          DECODE (v_stop_detail.exception_code,
                                  NULL, NULL,
                                  v_stop_detail.exception_comment
                                 ),             --v_stop_detail.exception_comment,
                       package_type = v_stop_detail.package_type,
                       last_update = v_last_update,
                       container_id =
                          DECODE (v_stop_detail.exception_code,
                                  NULL, v_stop_detail.exception_comment,
                                  NULL
                                 )
                 --when the exceptionCode is null,we set the value to the column.
                WHERE  truck_route_instance_id = v_instance_id
                   -- AND stop_id = v_stop_detail.stop_id
                   AND shipping_unit_id = v_stop_detail.scan_id
                   AND task_type = 'DROP'
                   AND task_type =
                          DECODE (v_stop_detail.pick_up_drop_off_ind,
                                  'D', 'DROP',
                                  'P', 'PICK',
                                  'E', 'EMPT',
                                  'L', 'LOAD',
                                  'ERR'
                                 );

                v_cntsd := SQL%ROWCOUNT;
             END IF;

             IF v_cntsd = 0
             THEN
                IF v_stop_detail.scan_id = constant_unattachpo
                THEN
                   v_unattach_exist := 2;
                END IF;

                SELECT tms.tms_bgl_route_stop_detail_seq.NEXTVAL
                  INTO v_new_id
                  FROM DUAL;

                INSERT INTO tms_temp_stop_detail
                     VALUES (v_new_id, v_stop_detail.stop_detail_id);

                v_stop_detail.stop_detail_id := v_new_id;

                INSERT INTO tms_stop_detail
                            (stop_detail_id, truck_route_instance_id,
                             stop_id, destination_id, trailer_id,
                             task_type,
                             shipping_unit_id, description,
                             package_type,
                             weight,
                             weight_uom, host_created_dt,
                             status,
                             exception_code,
                             scan_flag,
                             scan_dt, last_update,
                             exception_comment,
                             container_id,
                             intf_status
                            )
                     VALUES (v_stop_detail.stop_detail_id, v_instance_id,
                             v_stop_detail.stop_id, 0, '',
                             DECODE (v_stop_detail.pick_up_drop_off_ind,
                                     'D', 'DROP',
                                     'P', 'PICK',
                                     'E', 'EMPT',
                                     'L', 'LOAD',
                                     'ERR'
                                    ),
                             v_stop_detail.scan_id, v_stop_detail.description,
                             v_stop_detail.package_type,
                             NVL (v_stop_detail.weight, 0),
                             v_stop_detail.weight_uom, SYSDATE,
                             v_stop_detail.line_status,
                             v_stop_detail.exception_code,
                             v_stop_detail.scan_ind,
                             v_stop_detail.scan_timestamp, SYSDATE,
                             DECODE (v_stop_detail.exception_code,
                                     NULL, NULL,
                                     v_stop_detail.exception_comment
                                    ),
                             --  v_stop_detail.exception_comment,
                             DECODE (v_stop_detail.exception_code,
                                     NULL, v_stop_detail.exception_comment,
                                     NULL
                                    ),
                             'READY'
                            );
             ELSE
                IF v_stop_detail.stop_detail_id < 0
                THEN
                   --For some reason, the negative value is not updated in client and it's uploaded again,
                   --the oracle side get the right value, we just make the value correct so po_stop_detail will not inserted wrong value.
                   SELECT stop_detail_id
                     INTO v_new_id
                     FROM tms_stop_detail
                    WHERE truck_route_instance_id = v_instance_id
                      AND stop_id = v_stop_detail.stop_id
                      AND shipping_unit_id = v_stop_detail.scan_id;

                   /* This is not nesscary since the unique key is stop_id and scan_id.

                   AND task_type =
                          DECODE (v_stop_detail.pick_up_drop_off_ind,
                                  'D', 'DROP',
                                  'P', 'PICK',
                                  'E', 'EMPT',
                                  'L', 'LOAD'
                                 );
                        */
                   INSERT INTO tms_temp_stop_detail
                        VALUES (v_new_id, v_stop_detail.stop_detail_id);
                --At this point , the temp table had the correct positive stop_detail_id that we can handle the
                --po_stop_detail properly.
                END IF;

                IF v_stop_detail.scan_id = constant_unattachpo
                THEN
                   v_unattach_exist := 1;
                END IF;
             END IF;

             --if the error code has issue. We can record it into our object table.
             SELECT COUNT (stop_detail_id)
               INTO v_counterr
               FROM tms_stop_detail
              WHERE exception_code IS NULL
                AND status = 'E'
                AND stop_detail_id = v_stop_detail.stop_detail_id;

             IF v_counterr > 0 AND v_alreadyrun = 0
             THEN
                --if insert once, we will not insert for another loop;
              null;
                v_alreadyrun := 1;
             END IF;

             --generate the location code and the number of composite pallets which were dropped off
             BEGIN
                BEGIN
                   SELECT   s.location_id, COUNT (*)
                       INTO v_location_id, v_count
                       FROM tms_stop_detail d, tms.tms_route_stop s
                      WHERE d.stop_id = s.stop_id
                        AND d.stop_id = v_stop_detail.stop_id
                        AND d.shipping_unit_id = v_stop_detail.scan_id
                        AND d.truck_route_instance_id = s.truck_route_instance_id
                        AND d.truck_route_instance_id = v_instance_id
                        AND composite_pallet (d.shipping_unit_id) = 1
                        AND d.task_type IN ('DROP')
                        AND d.status IN ('Y')
                   GROUP BY d.task_type, s.location_id;

                   SELECT COUNT (*)
                     INTO v_num
                     FROM tms_empty_pallet
                    WHERE location_id = v_location_id;

                   IF v_num = 0
                   THEN
                      INSERT INTO tms_empty_pallet
                           VALUES (v_location_id, v_count);
                   ELSE
                      UPDATE tms_empty_pallet
                         SET pallet_count = pallet_count + v_count
                       WHERE location_id = v_location_id;
                   END IF;
                EXCEPTION
                   WHEN OTHERS
                   THEN
                      DECLARE
                         ERROR_CODE   NUMBER         := SQLCODE;
                         error_msg    VARCHAR2 (512) := SQLERRM;
                      BEGIN
                         IF ERROR_CODE != 100
                         THEN                                     --no data found
                            null;
                         END IF;
                      END;
                END;

                BEGIN
                   v_num := 0;

                   FOR inx IN (SELECT   s.location_id, d.status,
                                        d.exception_code, COUNT (*) count_num
                                   FROM tms.tms_stop_detail d,
                                        tms.tms_route_stop s
                                  WHERE d.stop_id = s.stop_id
                                    AND d.stop_id = v_stop_detail.stop_id
                                    AND d.shipping_unit_id = v_stop_detail.scan_id
                                    AND d.truck_route_instance_id =
                                                         s.truck_route_instance_id
                                    AND d.truck_route_instance_id = v_instance_id
                                    AND d.task_type IN ('EMPT')
                                    AND d.status IN ('Y', 'E')
                               GROUP BY s.location_id, d.status, d.exception_code
                               ORDER BY d.status DESC)
                   LOOP
                      v_num := v_num + 1;

                      SELECT COUNT (*)
                        INTO v_count
                        --the number of composite pallets dropped off on this store
                      FROM   tms_stop_detail d, tms.tms_route_stop s
                       WHERE d.stop_id = s.stop_id
                         AND d.stop_id = v_stop_detail.stop_id
                         AND d.truck_route_instance_id = s.truck_route_instance_id
                         AND d.truck_route_instance_id = v_instance_id
                         AND composite_pallet (d.shipping_unit_id) = 1
                         AND d.task_type IN ('DROP')
                         AND d.status IN ('Y');

                      IF v_num = 1
                      THEN
                         IF inx.status = 'Y'
                         THEN
                            SELECT pallet_count
                              INTO v_pallet_count
                              FROM tms_empty_pallet
                             WHERE location_id = inx.location_id;

                            IF inx.count_num >= v_pallet_count
                            THEN
                               UPDATE tms_empty_pallet
                                  SET pallet_count = v_count
                                WHERE location_id = inx.location_id;
                            ELSE
                               UPDATE tms_empty_pallet
                                  SET pallet_count = pallet_count - inx.count_num
                                WHERE location_id = inx.location_id;
                            END IF;
                         ELSIF inx.status = 'E' AND inx.exception_code = 'MISS'
                         THEN
                            UPDATE tms_empty_pallet
                               SET pallet_count = v_count
                             WHERE location_id = inx.location_id;
                         END IF;
                      END IF;
                   END LOOP;
                EXCEPTION
                   WHEN OTHERS
                   THEN
                      DECLARE
                         ERROR_CODE   NUMBER         := SQLCODE;
                         error_msg    VARCHAR2 (512) := SQLERRM;
                      BEGIN
                         IF ERROR_CODE != 100
                         THEN                                     --no data found
                            null;
                         END IF;
                      END;
                END;
             END;

             v_data_counter := v_data_counter + 1;
             v_stop_details (v_data_counter) := v_stop_detail;
             EXIT WHEN v_data_counter >= p_route_data.stop_details.COUNT;
          END LOOP;

          IF v_unattach_exist = 0
          THEN
             DELETE FROM tms_stop_detail
                   WHERE stop_id = v_stop_detail.stop_id
                     AND shipping_unit_id = constant_unattachpo;

             DELETE FROM tms_po_stop_detail
                   WHERE shipping_unit_id = constant_unattachpo
                     AND stop_id = v_stop_detail.stop_id;
          END IF;

          v_data_counter := 0;

          --loop for po
          LOOP
             EXIT WHEN v_pos.FIRST IS NULL;
             v_po := v_pos (v_pos.NEXT (v_data_counter));

             UPDATE tms_po
                SET weight = v_po.weight,
                    weight_uom = v_po.weight_uom,
                    delete_flag = v_po.delete_flag,
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_po.stop_id
                AND po_id = v_po.po_id;

             IF SQL%NOTFOUND
             THEN
                INSERT INTO tms_po
                            (stop_id, po_id, truck_route_instance_id,
                             weight, weight_uom, last_update
                            )
                     VALUES (v_po.stop_id, v_po.po_id, v_instance_id,
                             v_po.weight, v_po.weight_uom, v_last_update
                            );
             END IF;

             v_data_counter := v_data_counter + 1;
             EXIT WHEN v_data_counter >= p_route_data.stop_pos.COUNT;
          END LOOP;

          --loop for po_stop_detail
          v_data_counter := 0;

          LOOP
             EXIT WHEN v_po_stop_details.FIRST IS NULL;
             v_po_stop_detail :=
                      v_po_stop_details (v_po_stop_details.NEXT (v_data_counter));

             IF v_po_stop_detail.stop_detail_id < 0
             THEN
                BEGIN
                   SELECT sd_new_id
                     INTO v_new_id
                     FROM tms_temp_stop_detail
                    WHERE sd_old_id = v_po_stop_detail.stop_detail_id;

                   v_po_stop_detail.stop_detail_id := v_new_id;
                EXCEPTION
                   WHEN NO_DATA_FOUND
                   THEN
                      NULL;
                END;
             END IF;

             UPDATE tms.tms_po_stop_detail
                SET delete_flag = v_po_stop_detail.delete_flag,
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_po_stop_detail.stop_id
                AND stop_detail_id = v_po_stop_detail.stop_detail_id
                AND po_id = v_po_stop_detail.po_id;

             IF SQL%NOTFOUND
             THEN
                INSERT INTO tms.tms_po_stop_detail
                            (stop_detail_id,
                             po_id, truck_route_instance_id,
                             stop_id,
                             shipping_unit_id,
                             last_update
                            )
                     VALUES (v_po_stop_detail.stop_detail_id,
                             v_po_stop_detail.po_id, v_instance_id,
                             v_po_stop_detail.stop_id,
                             (SELECT shipping_unit_id
                                FROM tms_stop_detail
                               WHERE ROWNUM <= 1
                                 AND stop_detail_id =
                                                   v_po_stop_detail.stop_detail_id),
                             v_last_update
                            );
             END IF;

             v_data_counter := v_data_counter + 1;
             v_po_stop_details (v_data_counter) := v_po_stop_detail;
             EXIT WHEN v_data_counter >= p_route_data.po_stop_details.COUNT;
          END LOOP;

          --put the information into the objects to return.
          FOR x IN (SELECT sd_old_id, sd_new_id
                      FROM tms_temp_stop_detail)
          LOOP
             IF NOT v_isfirst
             THEN
                tc_idmap.EXTEND;
             END IF;

             v_isfirst := FALSE;
             tc_idmap (tc_idmap.LAST) :=
                                        NEW id_relation (x.sd_old_id, x.sd_new_id);
          END LOOP;

          DELETE FROM tms_temp_stop_detail;

          --end the return;
          IF p_is_end_of_day = 1 OR p_is_end_of_day = 2
          THEN
             UPDATE tms_route_header h
                SET end_of_day = p_dt_eod,
                    completion_program_name = 'BGL'
              WHERE h.truck_route_instance_id = v_instance_id
                AND NOT EXISTS (
                       SELECT 0
                         FROM tms_route_stop s
                        WHERE h.truck_route_instance_id =
                                                         s.truck_route_instance_id
                          AND (   s.status IS NULL
                               OR s.status NOT IN ('COMPLETE', 'EXCEPT')
                              ));

             IF SQL%NOTFOUND
             THEN
                IF p_is_end_of_day = 2
                THEN
                   UPDATE tms_route_header h
                      SET end_of_day = p_dt_eod
                    WHERE h.truck_route_instance_id = v_instance_id;
                ELSE
                 null;
                   RAISE miss_route_status;
                END IF;
             END IF;
          END IF;

          t_idupdate := NEW id_update (NULL, tc_idmap);
          COMMIT;
          RETURN t_idupdate;
       EXCEPTION
          WHEN miss_route_status
          THEN
             DECLARE
                v_stops     VARCHAR2 (500);
                v_exist     INTEGER;

                CURSOR stops_cur
                IS
                   SELECT stop_id
                     FROM tms_route_stop
                    WHERE truck_route_instance_id = v_instance_id
                      AND status IS NULL;

                v_stop_id   NUMBER (12);
             BEGIN
                OPEN stops_cur;

                LOOP
                   FETCH stops_cur
                    INTO v_stop_id;

                   EXIT WHEN stops_cur%NOTFOUND;
                   v_stops := v_stops || TO_CHAR (v_stop_id) || ',';
                END LOOP;

                CLOSE stops_cur;

                IF v_stops IS NOT NULL
                THEN
                   SELECT INSTR (v_stops, ',', LENGTH (v_stops) - 1, 1)
                     INTO v_exist
                     FROM DUAL;

                   IF v_exist != 0
                   THEN
                      --that means the string is not end with ',' . we removed it.
                      SELECT SUBSTR (v_stops, 1, LENGTH (v_stops) - 1)
                        INTO v_stops
                        FROM DUAL;
                   END IF;
                END IF;

                raise_application_error (-20002,
                                            'Stops are not existed in **'
                                         || v_stops
                                         || '$$'
                                        );
             END;
          WHEN OTHERS
          THEN
             ROLLBACK;

             --Record the exception data into that entity for -2292 only.
             DECLARE
                ERROR_CODE   NUMBER         := SQLCODE;
                error_msg    VARCHAR2 (512) := SQLERRM;
             BEGIN
              null;
                raise_application_error (-20006,
                                         TO_CHAR (ERROR_CODE) || error_msg);
                RETURN NULL;
             END;
       END;

       FUNCTION route_update_eod_ex (
          p_route_data      IN       route_data_ex,
          p_is_end_of_day   IN       INTEGER,
          p_dt_eod          IN       DATE,
          p_device_id                VARCHAR2,
          o_req_result      OUT      reqresult
       )
          RETURN id_update
       AS
    ---------------------------------------------*Declare some variable*---------------------------------------------------------
          constant_unattachpo   CHAR (14)                     := 'Unattached POs';
          v_route_stops         route_stops;
          v_stop_details        stop_details_ex;
          v_pos                 pos;
          v_po_stop_details     po_stop_details;
          v_route_stop          route_stop;
          v_stop_detail         stop_detail_ex;
          v_po_stop_detail      po_stop_detail;
          v_po                  po;
          v_last_update         DATE                                  := SYSDATE;
          v_eod                 DATE;
          v_instance_id         INTEGER                               := 0;
          v_data_counter        INTEGER                               := 0;
          v_isfirst             BOOLEAN                               := TRUE;
          v_new_id              INTEGER;
          v_unattach_exist      INTEGER                               := 0;
          t_idupdate            id_update;
          tc_idmap              id_map                       := NEW id_map (NULL);
          t_idrelation          id_relation;
          v_location_id         tms.tms_route_stop.location_id%TYPE;
          v_count               NUMBER;
          v_pallet_count        NUMBER;
          v_num                 NUMBER                                := 0;
          v_counterr            NUMBER (4);
          v_alreadyrun          NUMBER                                := 0;
          miss_route_status     EXCEPTION;
          v_miss_stp            INTEGER;
          v_cntempty            INTEGER                               := 0;
          v_cntsd               INTEGER                               := 0;
    --------------------------------------------------*End declare*---------------------------------------------------------------
       BEGIN
          --get object to local variable.
          --v_route_data := p_route_data;
          v_route_stops := p_route_data.route_stops;
          v_stop_details := p_route_data.stop_details;
          v_po_stop_details := p_route_data.po_stop_details;
          v_pos := p_route_data.stop_pos;

          --This if for initialize the empty collections, so we do not need initialize it later.
          IF v_route_stops IS NULL
          THEN
             --  ex_route_stops := NEW route_stops (NULL);
             v_route_stops := NEW route_stops (NULL);
          END IF;

          IF v_pos IS NULL
          THEN
             -- ex_pos := NEW pos (NULL);
             v_pos := NEW pos (NULL);
          END IF;

          IF v_stop_details IS NULL
          THEN
             -- ex_stop_details := NEW stop_details (NULL);
             v_stop_details := NEW stop_details_ex (NULL);
          END IF;

          IF v_po_stop_details IS NULL
          THEN
             --  ex_po_stop_details := NEW po_stop_details (NULL);
             v_po_stop_details := NEW po_stop_details (NULL);
          END IF;

    ------End initialize the empty collections
          v_instance_id := p_route_data.route_header.instance_id;

          --Insert into the log table when end of day, so we know they do this operation.
          IF p_is_end_of_day = 1
          THEN
             INSERT INTO tms_handheld_log
                  VALUES (SUBSTR (p_device_id, 1, 20), SYSDATE, 0,
                          'BGL-ENDOFDAY', TO_CHAR (v_instance_id), SYSDATE,
                          tms_handheld_seq.NEXTVAL);
          END IF;

          UPDATE tms_route_header
             SET last_update = v_last_update
           WHERE truck_route_instance_id = v_instance_id;

          --loop for route_stop
          LOOP
             EXIT WHEN v_route_stops.FIRST IS NULL;
             v_route_stop := v_route_stops (v_route_stops.NEXT (v_data_counter));

             UPDATE tms_route_stop
                SET actual_arrival_dt = v_route_stop.actual_arrival,
                    enroute_time = v_route_stop.enroute_dt,
                    actual_departure_dt = v_route_stop.actual_departure,
                    special_instructions = v_route_stop.special_instructions,
                    exception_code = v_route_stop.exception_code,
                    exception_comments = v_route_stop.exception_comments,
                    status =
                       DECODE (v_route_stop.status,
                               NULL, 'OPEN',
                               v_route_stop.status
                              ),
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_route_stop.stop_id;

             IF v_stop_details.COUNT = 0
             --If we do not upload every thing ,we erase the unattachedPo.
             THEN
                DELETE FROM tms_stop_detail
                      WHERE stop_id = v_route_stop.stop_id
                        AND shipping_unit_id = constant_unattachpo;

                DELETE FROM tms_po_stop_detail
                      WHERE shipping_unit_id = constant_unattachpo
                        AND stop_id = v_route_stop.stop_id;
             END IF;

             v_data_counter := v_data_counter + 1;
             EXIT WHEN v_data_counter >= p_route_data.route_stops.COUNT;
          END LOOP;

          --loop for stop_detail
          v_unattach_exist := 0;
          v_data_counter := 0;

          LOOP
             EXIT WHEN v_stop_details.FIRST IS NULL;
             v_stop_detail :=
                            v_stop_details (v_stop_details.NEXT (v_data_counter));

             IF     v_stop_detail.scan_timestamp IS NULL
                AND v_stop_detail.line_status = 'E'
             THEN
                v_stop_detail.scan_timestamp := SYSDATE;
             END IF;

             UPDATE tms_stop_detail
                SET shipping_unit_id = v_stop_detail.scan_id,
                    intf_status =
                       DECODE (v_stop_detail.scan_timestamp,
                               NULL, intf_status,
                               scan_dt, intf_status,
                               'READY'
                              ),
                    status = v_stop_detail.line_status,
                    scan_flag = v_stop_detail.scan_ind,
                    scan_dt = v_stop_detail.scan_timestamp,
                    description = v_stop_detail.description,
                    weight = v_stop_detail.weight,
                    weight_uom = v_stop_detail.weight_uom,
                    exception_code = v_stop_detail.exception_code,
                    exception_comment = v_stop_detail.exception_comment,
                    --v_stop_detail.exception_comment,
                    package_type = v_stop_detail.package_type,
                    last_update = v_last_update,
                    container_id = v_stop_detail.container_id
              --when the exceptionCode is null,we set the value to the column.
             WHERE  truck_route_instance_id = v_instance_id
                AND stop_id = v_stop_detail.stop_id
                AND shipping_unit_id = v_stop_detail.scan_id
                AND task_type != 'DROP'
                AND task_type =
                       DECODE (v_stop_detail.pick_up_drop_off_ind,
                               'D', 'DROP',
                               'P', 'PICK',
                               'E', 'EMPT',
                               'L', 'LOAD',
                               'ERR'
                              );

             v_cntsd := SQL%ROWCOUNT;

             IF v_cntsd = 0
             THEN
                UPDATE tms_stop_detail
                   SET shipping_unit_id = v_stop_detail.scan_id,
                       intf_status =
                          DECODE (v_stop_detail.scan_timestamp,
                                  NULL, intf_status,
                                  scan_dt, intf_status,
                                  'READY'
                                 ),
                       status = v_stop_detail.line_status,
                       scan_flag = v_stop_detail.scan_ind,
                       stop_id = v_stop_detail.stop_id,
                       scan_dt = v_stop_detail.scan_timestamp,
                       description = v_stop_detail.description,
                       weight = v_stop_detail.weight,
                       weight_uom = v_stop_detail.weight_uom,
                       exception_code = v_stop_detail.exception_code,
                       exception_comment = v_stop_detail.exception_comment,
                       package_type = v_stop_detail.package_type,
                       last_update = v_last_update,
                       container_id = v_stop_detail.container_id
                 WHERE truck_route_instance_id = v_instance_id
                   AND shipping_unit_id = v_stop_detail.scan_id
                   AND task_type = 'DROP'
                   AND task_type =
                          DECODE (v_stop_detail.pick_up_drop_off_ind,
                                  'D', 'DROP',
                                  'P', 'PICK',
                                  'E', 'EMPT',
                                  'L', 'LOAD',
                                  'ERR'
                                 );

                v_cntsd := SQL%ROWCOUNT;
             END IF;

             IF v_cntsd = 0
             THEN
                IF v_stop_detail.scan_id = constant_unattachpo
                THEN
                   v_unattach_exist := 2;
                END IF;

                SELECT tms.tms_bgl_route_stop_detail_seq.NEXTVAL
                  INTO v_new_id
                  FROM DUAL;

                INSERT INTO tms_temp_stop_detail
                     VALUES (v_new_id, v_stop_detail.stop_detail_id);

                v_stop_detail.stop_detail_id := v_new_id;

                INSERT INTO tms_stop_detail
                            (stop_detail_id, truck_route_instance_id,
                             stop_id, destination_id, trailer_id,
                             task_type,
                             shipping_unit_id, description,
                             package_type,
                             weight,
                             weight_uom, host_created_dt,
                             status,
                             exception_code,
                             scan_flag,
                             scan_dt, last_update,
                             exception_comment,
                             container_id, intf_status
                            )
                     VALUES (v_stop_detail.stop_detail_id, v_instance_id,
                             v_stop_detail.stop_id, 0, '',
                             DECODE (v_stop_detail.pick_up_drop_off_ind,
                                     'D', 'DROP',
                                     'P', 'PICK',
                                     'E', 'EMPT',
                                     'L', 'LOAD',
                                     'ERR'
                                    ),
                             v_stop_detail.scan_id, v_stop_detail.description,
                             v_stop_detail.package_type,
                             NVL (v_stop_detail.weight, 0),
                             v_stop_detail.weight_uom, SYSDATE,
                             v_stop_detail.line_status,
                             v_stop_detail.exception_code,
                             v_stop_detail.scan_ind,
                             v_stop_detail.scan_timestamp, SYSDATE,
                             v_stop_detail.exception_comment,
                             v_stop_detail.container_id, 'READY'
                            );
             ELSE
                IF v_stop_detail.stop_detail_id < 0
                THEN
                   --For some reason, the negative value is not updated in client and it's uploaded again,
                   --the oracle side get the right value, we just make the value correct so po_stop_detail will not inserted wrong value.
                   SELECT stop_detail_id
                     INTO v_new_id
                     FROM tms_stop_detail
                    WHERE truck_route_instance_id = v_instance_id
                      AND stop_id = v_stop_detail.stop_id
                      AND shipping_unit_id = v_stop_detail.scan_id;

                   /* This is not nesscary since the unique key is stop_id and scan_id.

                   AND task_type =
                          DECODE (v_stop_detail.pick_up_drop_off_ind,
                                  'D', 'DROP',
                                  'P', 'PICK',
                                  'E', 'EMPT',
                                  'L', 'LOAD'
                                 );
                        */
                   INSERT INTO tms_temp_stop_detail
                        VALUES (v_new_id, v_stop_detail.stop_detail_id);
                --At this point , the temp table had the correct positive stop_detail_id that we can handle the
                --po_stop_detail properly.
                END IF;

                IF v_stop_detail.scan_id = constant_unattachpo
                THEN
                   v_unattach_exist := 1;
                END IF;
             END IF;

             --if the error code has issue. We can record it into our object table.
             SELECT COUNT (stop_detail_id)
               INTO v_counterr
               FROM tms_stop_detail
              WHERE exception_code IS NULL
                AND status = 'E'
                AND stop_detail_id = v_stop_detail.stop_detail_id;

             IF v_counterr > 0 AND v_alreadyrun = 0
             THEN
                NULL;
                 --if insert once, we will not insert for another loop;
                 /*
                 INSERT INTO tms_obj_route_data
                      VALUES (p_route_data.route_header, p_route_data.route_stops,
                              p_route_data.stop_pos, p_route_data.stop_details,
                              p_route_data.po_stop_details,
                              'Exception code can not be null when the status is E',
                              v_instance_id);
                */
                v_alreadyrun := 1;
             END IF;

             --generate the location code and the number of composite pallets which were dropped off
             BEGIN
                BEGIN
                   SELECT   s.location_id, COUNT (*)
                       INTO v_location_id, v_count
                       FROM tms_stop_detail d, tms.tms_route_stop s
                      WHERE d.stop_id = s.stop_id
                        AND d.stop_id = v_stop_detail.stop_id
                        AND d.shipping_unit_id = v_stop_detail.scan_id
                        AND d.truck_route_instance_id = s.truck_route_instance_id
                        AND d.truck_route_instance_id = v_instance_id
                        AND composite_pallet (d.shipping_unit_id) = 1
                        AND d.task_type IN ('DROP')
                        AND d.status IN ('Y')
                   GROUP BY d.task_type, s.location_id;

                   SELECT COUNT (*)
                     INTO v_num
                     FROM tms_empty_pallet
                    WHERE location_id = v_location_id;

                   IF v_num = 0
                   THEN
                      INSERT INTO tms_empty_pallet
                           VALUES (v_location_id, v_count);
                   ELSE
                      UPDATE tms_empty_pallet
                         SET pallet_count = pallet_count + v_count
                       WHERE location_id = v_location_id;
                   END IF;
                EXCEPTION
                   WHEN OTHERS
                   THEN
                      DECLARE
                         ERROR_CODE   NUMBER         := SQLCODE;
                         error_msg    VARCHAR2 (512) := SQLERRM;
                      BEGIN
                         IF ERROR_CODE != 100
                         THEN                                     --no data found
                            NULL;
                         /*
                            INSERT INTO tms_obj_route_data
                                 VALUES (p_route_data.route_header,
                                         p_route_data.route_stops,
                                         p_route_data.stop_pos,
                                         p_route_data.stop_details,
                                         p_route_data.po_stop_details, error_msg,
                                         v_instance_id);
                                         */
                         END IF;
                      END;
                END;

                BEGIN
                   v_num := 0;

                   FOR inx IN (SELECT   s.location_id, d.status,
                                        d.exception_code, COUNT (*) count_num
                                   FROM tms.tms_stop_detail d,
                                        tms.tms_route_stop s
                                  WHERE d.stop_id = s.stop_id
                                    AND d.stop_id = v_stop_detail.stop_id
                                    AND d.shipping_unit_id = v_stop_detail.scan_id
                                    AND d.truck_route_instance_id =
                                                         s.truck_route_instance_id
                                    AND d.truck_route_instance_id = v_instance_id
                                    AND d.task_type IN ('EMPT')
                                    AND d.status IN ('Y', 'E')
                               GROUP BY s.location_id, d.status, d.exception_code
                               ORDER BY d.status DESC)
                   LOOP
                      v_num := v_num + 1;

                      SELECT COUNT (*)
                        INTO v_count
                        --the number of composite pallets dropped off on this store
                      FROM   tms_stop_detail d, tms.tms_route_stop s
                       WHERE d.stop_id = s.stop_id
                         AND d.stop_id = v_stop_detail.stop_id
                         AND d.truck_route_instance_id = s.truck_route_instance_id
                         AND d.truck_route_instance_id = v_instance_id
                         AND composite_pallet (d.shipping_unit_id) = 1
                         AND d.task_type IN ('DROP')
                         AND d.status IN ('Y');

                      IF v_num = 1
                      THEN
                         IF inx.status = 'Y'
                         THEN
                            SELECT pallet_count
                              INTO v_pallet_count
                              FROM tms_empty_pallet
                             WHERE location_id = inx.location_id;

                            IF inx.count_num >= v_pallet_count
                            THEN
                               UPDATE tms_empty_pallet
                                  SET pallet_count = v_count
                                WHERE location_id = inx.location_id;
                            ELSE
                               UPDATE tms_empty_pallet
                                  SET pallet_count = pallet_count - inx.count_num
                                WHERE location_id = inx.location_id;
                            END IF;
                         ELSIF inx.status = 'E' AND inx.exception_code = 'MISS'
                         THEN
                            UPDATE tms_empty_pallet
                               SET pallet_count = v_count
                             WHERE location_id = inx.location_id;
                         END IF;
                      END IF;
                   END LOOP;
                EXCEPTION
                   WHEN OTHERS
                   THEN
                      DECLARE
                         ERROR_CODE   NUMBER         := SQLCODE;
                         error_msg    VARCHAR2 (512) := SQLERRM;
                      BEGIN
                         IF ERROR_CODE != 100
                         THEN                                     --no data found
                            NULL;
                         /*
                            INSERT INTO tms_obj_route_data
                                 VALUES (p_route_data.route_header,
                                         p_route_data.route_stops,
                                         p_route_data.stop_pos,
                                         p_route_data.stop_details,
                                         p_route_data.po_stop_details, error_msg,
                                         v_instance_id);
                                         */
                         END IF;
                      END;
                END;
             END;

             v_data_counter := v_data_counter + 1;
             v_stop_details (v_data_counter) := v_stop_detail;
             EXIT WHEN v_data_counter >= p_route_data.stop_details.COUNT;
          END LOOP;

          IF v_unattach_exist = 0
          THEN
             DELETE FROM tms_stop_detail
                   WHERE stop_id = v_stop_detail.stop_id
                     AND shipping_unit_id = constant_unattachpo;

             DELETE FROM tms_po_stop_detail
                   WHERE shipping_unit_id = constant_unattachpo
                     AND stop_id = v_stop_detail.stop_id;
          END IF;

          v_data_counter := 0;

          --loop for po
          LOOP
             EXIT WHEN v_pos.FIRST IS NULL;
             v_po := v_pos (v_pos.NEXT (v_data_counter));

             UPDATE tms_po
                SET weight = v_po.weight,
                    weight_uom = v_po.weight_uom,
                    delete_flag = v_po.delete_flag,
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_po.stop_id
                AND po_id = v_po.po_id;

             IF SQL%NOTFOUND
             THEN
                INSERT INTO tms_po
                            (stop_id, po_id, truck_route_instance_id,
                             weight, weight_uom, last_update
                            )
                     VALUES (v_po.stop_id, v_po.po_id, v_instance_id,
                             v_po.weight, v_po.weight_uom, v_last_update
                            );
             END IF;

             v_data_counter := v_data_counter + 1;
             EXIT WHEN v_data_counter >= p_route_data.stop_pos.COUNT;
          END LOOP;

          --loop for po_stop_detail
          v_data_counter := 0;

          LOOP
             EXIT WHEN v_po_stop_details.FIRST IS NULL;
             v_po_stop_detail :=
                      v_po_stop_details (v_po_stop_details.NEXT (v_data_counter));

             IF v_po_stop_detail.stop_detail_id < 0
             THEN
                BEGIN
                   SELECT sd_new_id
                     INTO v_new_id
                     FROM tms_temp_stop_detail
                    WHERE sd_old_id = v_po_stop_detail.stop_detail_id;

                   v_po_stop_detail.stop_detail_id := v_new_id;
                EXCEPTION
                   WHEN NO_DATA_FOUND
                   THEN
                      NULL;
                END;
             END IF;

             UPDATE tms.tms_po_stop_detail
                SET delete_flag = v_po_stop_detail.delete_flag,
                    last_update = v_last_update
              WHERE truck_route_instance_id = v_instance_id
                AND stop_id = v_po_stop_detail.stop_id
                AND stop_detail_id = v_po_stop_detail.stop_detail_id
                AND po_id = v_po_stop_detail.po_id;

             IF SQL%NOTFOUND
             THEN
                INSERT INTO tms.tms_po_stop_detail
                            (stop_detail_id,
                             po_id, truck_route_instance_id,
                             stop_id,
                             shipping_unit_id,
                             last_update
                            )
                     VALUES (v_po_stop_detail.stop_detail_id,
                             v_po_stop_detail.po_id, v_instance_id,
                             v_po_stop_detail.stop_id,
                             (SELECT shipping_unit_id
                                FROM tms_stop_detail
                               WHERE ROWNUM <= 1
                                 AND stop_detail_id =
                                                   v_po_stop_detail.stop_detail_id),
                             v_last_update
                            );
             END IF;

             v_data_counter := v_data_counter + 1;
             v_po_stop_details (v_data_counter) := v_po_stop_detail;
             EXIT WHEN v_data_counter >= p_route_data.po_stop_details.COUNT;
          END LOOP;

          --put the information into the objects to return.
          FOR x IN (SELECT sd_old_id, sd_new_id
                      FROM tms_temp_stop_detail)
          LOOP
             IF NOT v_isfirst
             THEN
                tc_idmap.EXTEND;
             END IF;

             v_isfirst := FALSE;
             tc_idmap (tc_idmap.LAST) :=
                                        NEW id_relation (x.sd_old_id, x.sd_new_id);
          END LOOP;

    --We really did not need to do this stuff. it's ON COMMIT PRESERVE ROWS
    --      DELETE FROM tms_temp_stop_detail;

          --end the return;
          IF p_is_end_of_day = 1 OR p_is_end_of_day = 2
          THEN
             UPDATE tms_route_header h
                SET end_of_day = p_dt_eod,
                    completed_by = p_route_data.route_header.completed_by,
                    completion_program_name = 'BGL'
              WHERE h.truck_route_instance_id = v_instance_id
                AND NOT EXISTS (
                       SELECT 0
                         FROM tms_route_stop s
                        WHERE h.truck_route_instance_id =
                                                         s.truck_route_instance_id
                          AND (   s.status IS NULL
                               OR s.status NOT IN ('COMPLETE', 'EXCEPT')
                              ));

             IF SQL%NOTFOUND
             THEN
                IF p_is_end_of_day = 2
                THEN
                   UPDATE tms_route_header h
                      SET end_of_day = p_dt_eod
                    WHERE h.truck_route_instance_id = v_instance_id;
                ELSE
                   NULL;
                   /*
                      INSERT INTO tms_obj_route_data
                           VALUES (p_route_data.route_header,
                                   p_route_data.route_stops, p_route_data.stop_pos,
                                   p_route_data.stop_details,
                                   p_route_data.po_stop_details, 'Without Eod',
                                   v_instance_id);
                      */
                   COMMIT;
                   RAISE miss_route_status;
                END IF;
             END IF;
          END IF;

          t_idupdate := NEW id_update (NULL, tc_idmap);
          COMMIT;
          o_req_result := NEW reqresult (1, 0, 'Update successfully.', SYSDATE);
          --    o_REQ_RESULT:=new
          RETURN t_idupdate;
       EXCEPTION
          WHEN miss_route_status
          THEN
             DECLARE
                v_stops     VARCHAR2 (500);
                v_exist     INTEGER;

                CURSOR stops_cur
                IS
                   SELECT stop_id
                     FROM tms_route_stop
                    WHERE truck_route_instance_id = v_instance_id
                      AND status IS NULL;

                v_stop_id   NUMBER (12);
             BEGIN
                OPEN stops_cur;

                LOOP
                   FETCH stops_cur
                    INTO v_stop_id;

                   EXIT WHEN stops_cur%NOTFOUND;
                   v_stops := v_stops || TO_CHAR (v_stop_id) || ',';
                END LOOP;

                CLOSE stops_cur;

                IF v_stops IS NOT NULL
                THEN
                   SELECT INSTR (v_stops, ',', LENGTH (v_stops) - 1, 1)
                     INTO v_exist
                     FROM DUAL;

                   IF v_exist != 0
                   THEN
                      --that means the string is not end with ',' . we removed it.
                      SELECT SUBSTR (v_stops, 1, LENGTH (v_stops) - 1)
                        INTO v_stops
                        FROM DUAL;
                   END IF;
                END IF;

                o_req_result := NEW reqresult (0, -20008, v_stops, SYSDATE);
                RETURN NULL;
             --raise_application_error (-20002, 'Stops are not existed in **'||v_stops||'$$' );
             END;
          WHEN OTHERS
          THEN
             ROLLBACK;

             --Record the exception data into that entity for -2292 only.
             DECLARE
                ERROR_CODE   NUMBER         := SQLCODE;
                error_msg    VARCHAR2 (512) := SQLERRM;
                v_objcnt pls_integer;
             BEGIN
               select count(1) into v_objcnt from tms_obj_route_data where  instanceid_col =v_instance_id;
               if v_objcnt=0 then
                   INSERT INTO tms_obj_route_data
                        VALUES (p_route_data.route_header, p_route_data.route_stops,
                                p_route_data.stop_pos, p_route_data.stop_details,
                                p_route_data.po_stop_details,null, error_msg,to_char(ERROR_CODE),sysdate,p_device_id,
                                v_instance_id);
                   COMMIT;
                   end if;
                o_req_result := NEW reqresult (0, SQLCODE, SQLERRM, SYSDATE);
                -- raise_application_error (-20006,to_char(ERROR_CODE)||ERROR_MSG);
                RETURN NULL;
             END;
       END;
    END tms_ws;
    /

    魔兽就是毒瘤,大家千万不要玩。
  • 相关阅读:
    我们是在开发产品还是项目?
    创业期的软件开发管理(一)
    由“I”到“T”
    创业期的软件开发管理(二)
    平台架构用户系统
    产品的臃肿过程
    平台架构——体系结构
    狼群的架构暗示
    如何创建一个好的索引
    哈希索引
  • 原文地址:https://www.cnblogs.com/tracy/p/1712548.html
Copyright © 2011-2022 走看看