DBA Data[Home] [Help]

PACKAGE BODY: APPS.POR_AUTOSOURCE_UTIL_PKG

Source


1 PACKAGE BODY POR_AUTOSOURCE_UTIL_PKG AS
2     /* $Header: PORSRCUB.pls 120.9.12020000.6 2013/05/10 03:42:27 bpulivar ship $ */
3 
4   -- Logging Static Variables
5   G_CURRENT_RUNTIME_LEVEL      NUMBER;
6   G_LEVEL_UNEXPECTED	       CONSTANT NUMBER	     := FND_LOG.LEVEL_UNEXPECTED;
7   G_LEVEL_ERROR 	       CONSTANT NUMBER	     := FND_LOG.LEVEL_ERROR;
8   G_LEVEL_EXCEPTION	       CONSTANT NUMBER	     := FND_LOG.LEVEL_EXCEPTION;
9   G_LEVEL_EVENT 	       CONSTANT NUMBER	     := FND_LOG.LEVEL_EVENT;
10   G_LEVEL_PROCEDURE	       CONSTANT NUMBER	     := FND_LOG.LEVEL_PROCEDURE;
11   G_LEVEL_STATEMENT	       CONSTANT NUMBER	     := FND_LOG.LEVEL_STATEMENT;
12   G_MODULE_NAME 	       CONSTANT VARCHAR2(50) := 'ICX.PLSQL.POR_AUTOSOURCE_UTIL_PKG.';
13 
14     /* Check if the item is internally orderable in the destination organization */
15     FUNCTION  is_internal_orderable(p_item_id           IN    NUMBER,
16                                     p_organization_id   IN    NUMBER
17     ) RETURN NUMBER
18 
19     IS
23     BEGIN
20 
21        l_internal_order_enabled_flag VARCHAR(1) := 'N';
22 
24 
25        select internal_order_enabled_flag
26        into l_internal_order_enabled_flag
27        from mtl_system_items
28        where inventory_item_id = p_item_id
29              and organization_id = p_organization_id;
30 
31        IF l_internal_order_enabled_flag = 'Y' THEN
32           RETURN 1;
33        END IF;
34 
35        RETURN 0;
36 
37        EXCEPTION
38          WHEN OTHERS THEN
39            RETURN 0;
40 
41     END is_internal_orderable;
42 
43 
44     FUNCTION  is_item_purchasable(p_item_id           IN    NUMBER,
45                                   p_organization_id   IN    NUMBER
46     ) RETURN NUMBER
47 
48     IS
49 
50        l_purchasable_flag VARCHAR(1) := 'N';
51 
52     BEGIN
53 
54        IF fnd_profile.value('REQUISITION_TYPE') = 'INTERNAL' THEN
55           RETURN 0;
56        END IF;
57 
58        select purchasing_enabled_flag
59        into l_purchasable_flag
60        from mtl_system_items
61        where inventory_item_id = p_item_id
62              and organization_id = p_organization_id;
63 
64        IF l_purchasable_flag = 'Y' THEN
65           RETURN 1;
66        END IF;
67 
68        RETURN 0;
69 
70        EXCEPTION
71          WHEN OTHERS THEN
72             RETURN 0;
73 
74     END is_item_purchasable;
75 
76     /* Used to get the unit of issue of the destination org */
77     FUNCTION  get_unit_of_issue(p_item_id           IN    NUMBER,
78                                 p_organization_id   IN    NUMBER
79     ) RETURN VARCHAR
80 
81     IS
82 
83        l_unit_of_issue VARCHAR(25);
84 
85     BEGIN
86        select nvl(msi.unit_of_issue,msi.primary_unit_of_measure)
87        into l_unit_of_issue
88        from mtl_system_items msi
89        where msi.inventory_item_id = p_item_id
90              and msi.organization_id = p_organization_id;
91 
92        RETURN l_unit_of_issue;
93 
94        EXCEPTION
95          WHEN OTHERS THEN
96             RETURN NULL;
97 
98     END get_unit_of_issue;
99 
100     /* Used to determine if the item flags are correctly in the source org $ */
101     FUNCTION  is_item_shippable(p_item_id           IN    NUMBER,
102                                 p_organization_id   IN    NUMBER
103     ) RETURN NUMBER
104 
105     IS
106 
107        l_oe_transactable_flag VARCHAR(1);
108        l_shippable_flag VARCHAR(1);
109        l_mtl_transactable_flag VARCHAR(1);
110        l_stockable_flag VARCHAR(1);
111 
112     BEGIN
113 
114        -- check the shippable, stockable, oe transactable and mtl_transactable flags
115        select shippable_item_flag, so_transactions_flag, stock_enabled_flag, mtl_transactions_enabled_flag
116        into l_shippable_flag, l_oe_transactable_flag, l_stockable_flag, l_mtl_transactable_flag
117        from mtl_system_items
118        where inventory_item_id = p_item_id
119            and organization_id = p_organization_id;
120 
121        IF l_shippable_flag='Y' and l_oe_transactable_flag='Y' and l_stockable_flag='Y' and l_mtl_transactable_flag='Y' THEN
122           RETURN 1;
123        END IF;
124 
125        RETURN 0;
126 
127        EXCEPTION
128          WHEN OTHERS THEN
129             RETURN 0;
130 
131     END is_item_shippable;
132 
133     /* Check if there is a valid shipping network between the source org and the destination org */
134     FUNCTION  is_valid_shipping_network(p_from_organization_id     IN    NUMBER,
135                                         p_to_organization_id       IN    NUMBER
136     ) RETURN NUMBER
137 
138     IS
139 
140        l_is_valid_shipping_network VARCHAR(1);
141 
142     BEGIN
143 
144        IF p_from_organization_id = p_to_organization_id THEN
145           RETURN 1;
146        END IF;
147 
148        select 1 into l_is_valid_shipping_network
149        from mtl_interorg_parameters
150        where from_organization_id = p_from_organization_id
151          and to_organization_id = p_to_organization_id;
152 
153        IF l_is_valid_shipping_network = '1' THEN
154           RETURN 1;
155        END IF;
156 
157        RETURN 0;
158 
159        EXCEPTION
160          WHEN OTHERS THEN
161            RETURN 0;
162 
163     END is_valid_shipping_network;
164 
165     /* Make sure the item is properly assigned to the source org */
166     FUNCTION  is_item_assigned(p_item_id                  IN    NUMBER,
167                                p_source_organization_id   IN    NUMBER
168     ) RETURN NUMBER
169 
170     IS
171 
172        l_is_item_assigned VARCHAR(1);
173 
174     BEGIN
175 
176        SELECT 1 into l_is_item_assigned
177        FROM   mtl_system_items msi
178        WHERE  msi.inventory_item_id = p_item_id
179          and  msi.organization_id = p_source_organization_id;
180 
181        IF l_is_item_assigned = '1' THEN
182           RETURN 1;
183        END IF;
184 
185        RETURN 0;
186 
187        EXCEPTION
188          WHEN OTHERS THEN
189            RETURN 0;
190 
191     END is_item_assigned;
192 
196     /* be sourced from the organization, then it will return the source org id, the subinventory  */
193     /* The main autosource API that is called by Autosource.java and SourceInfo.java.             */
194     /* Contains all of the autosource logic to pick the correct source based on the sourcing      */
195     /* rules and make sure the item can be sourced from that organization.  If the item can       */
197     /* and the cost price.  If there are any errors, then the api will return what error msg code */
198     /* should be displayed.                                                                       */
199     FUNCTION  autosource(p_item_id                    IN            NUMBER,
200                          p_category_id                IN            NUMBER,
201                          p_dest_organization_id       IN            NUMBER,
202                          p_dest_subinventory          IN            VARCHAR2,
203                          p_vendor_id                  IN            NUMBER,
204                          p_vendor_site_id             IN            NUMBER,
205                          p_not_purchasable_override   IN            VARCHAR2,
206                          p_unit_of_issue              IN OUT NOCOPY VARCHAR2,
207                          p_source_organization_id     OUT    NOCOPY NUMBER,
208                          p_source_subinventory        OUT    NOCOPY VARCHAR2,
209                          p_sourcing_type              OUT    NOCOPY VARCHAR2,
210                          p_cost_price                 OUT    NOCOPY NUMBER,
211                          p_error_msg_code             OUT    NOCOPY VARCHAR2
212     ) RETURN BOOLEAN
213 
214     IS
215 
216       l_custom_package_flag BOOLEAN;
217       l_is_purchasable_flag VARCHAR2(1) := 'N';
218       l_set_id NUMBER;
219       l_avail_quantity NUMBER;
220       l_source_type NUMBER;
221       l_source_organization_id NUMBER;
222       l_source_subinventory VARCHAR2(10);
223       l_sourcing_rule_exist_err BOOLEAN := TRUE;
224       l_is_item_assigned_err BOOLEAN := TRUE;
225       l_is_ship_network_assigned_err BOOLEAN := TRUE;
226       --bug 2986842
227       l_is_item_shippable_err BOOLEAN := TRUE;
228       l_count NUMBER := 0;
229       l_first_source_org_id NUMBER := -9999;
230 
231       l_vendor_id NUMBER;
232       l_vendor_site_id NUMBER;
233 
234       l_procedure_name VARCHAR2(10) := 'AUTOSOURCE';
235 
236       cursor c_sourcing is
237       SELECT ALL_SOURCES_V.SOURCE_ORGANIZATION_ID,
238              ALL_SOURCES_V.SOURCE_TYPE,
239              ALL_SOURCES_V.VENDOR_ID,
240              ALL_SOURCES_V.VENDOR_SITE_ID
241       FROM
242       (
243         SELECT SOURCE_ORGANIZATION_ID, SOURCE_TYPE, VENDOR_ID, VENDOR_SITE_ID,
244                RANK, ALLOCATION_PERCENT, SOURCING_LEVEL
245           FROM MRP_ITEM_SOURCING_LEVELS_V
246          WHERE INVENTORY_ITEM_ID = p_item_id
247            AND ORGANIZATION_ID = p_dest_organization_id
248            AND ASSIGNMENT_SET_ID = l_set_id
249            AND (SOURCE_TYPE = 1 OR
250                 (SOURCE_TYPE = 3 AND
251                  'Y' = l_is_purchasable_flag AND
252                  VENDOR_ID = p_vendor_id AND
253                  NVL(VENDOR_SITE_ID, p_vendor_site_id) = p_vendor_site_id))
254            AND SYSDATE BETWEEN EFFECTIVE_DATE AND NVL(DISABLE_DATE, SYSDATE+1)
255       ) ALL_SOURCES_V
256       ORDER BY ALL_SOURCES_V.SOURCING_LEVEL ASC,
257                ALL_SOURCES_V.ALLOCATION_PERCENT DESC,
258                NVL(ALL_SOURCES_V.RANK, 9999) ASC;
259 
260 -- Bug 14262930 : modifying following cursor to take care of INV profile
261 -- while selecting the on hand quantity from sub inventories.
262 
263       cursor c_avail_quantity is
264       SELECT msub.secondary_inventory_name,
265              (nvl(mos.total_qoh,0) - sum(nvl(mrs.primary_reservation_quantity,0))) avail_quantity
266       FROM mtl_secondary_inventories msub,
267            mtl_onhand_sub_v mos,
268            mtl_reservations mrs,
269            mtl_system_items msi
270       WHERE msub.organization_id = l_source_organization_id -- bug 5470125, do not bind p_source_organization_id
271         AND 'Y' = (CASE WHEN Nvl(fnd_profile.value('INV:EXPENSE_TO_ASSET_TRANSFER'),2) = 2
272                    AND msub.asset_inventory = 2
273                    THEN 'N'
274                    ELSE 'Y'
275                    END)
276         and msi.organization_id = l_source_organization_id
277         and msi.inventory_item_id = p_item_id
278         and (trunc(sysdate) < nvl(msub.disable_date, trunc(sysdate + 1)))
279         and msub.quantity_tracked = 1
280         and msub.secondary_inventory_name = mos.subinventory_code (+)
281         and mos.inventory_item_id = mrs.inventory_item_id (+)
282         and mos.organization_id = mrs.organization_id (+)
283         and mos.subinventory_code = mrs.subinventory_code (+)
284         and mos.inventory_item_id (+) = p_item_id
285         and mos.organization_id (+) = l_source_organization_id
286         and (msi.restrict_subinventories_code = 2
287              or (msi.restrict_subinventories_code = 1
288                  and exists (select null
289                              from mtl_item_sub_inventories mis
290                              where mis.organization_id = msi.organization_id
291                                and mis.inventory_item_id = msi.inventory_item_id
292                                and mis.secondary_inventory = msub.secondary_inventory_name)
293                  )
294              )
295         and msub.reservable_type=1 --  bug 2986842 need to restrict to reservable subinventory
296                                    --  otherwise po creation will fail
297       GROUP BY msub.secondary_inventory_name, mos.total_qoh
298       ORDER BY avail_quantity DESC, msub.secondary_inventory_name ASC;
299 
300     BEGIN
301 
305          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME || l_procedure_name, 'Start Autosource');
302       G_CURRENT_RUNTIME_LEVEL := FND_LOG.G_CURRENT_RUNTIME_LEVEL;
303 
304       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
306       END IF;
307 
308       p_error_msg_code := '';
309 
310       if is_internal_orderable(p_item_id,p_dest_organization_id) = 0 then
311          p_error_msg_code := 'ICX_POR_NOT_ORDERABLE_ERROR';
312          return FALSE;
313       end if;
314 
315       l_custom_package_flag := por_autosource_custom_pkg.autosource(p_item_id,
316                                                                     p_category_id,
317                                                                     p_dest_organization_id,
318                                                                     p_dest_subinventory,
319                                                                     p_vendor_id,
320                                                                     p_vendor_site_id,
321                                                                     p_not_purchasable_override,
322                                                                     p_unit_of_issue,
323                                                                     p_source_organization_id,
324                                                                     p_source_subinventory,
325                                                                     p_sourcing_type,
326                                                                     p_cost_price,
327                                                                     p_error_msg_code);
328       -- check if the autosource logic was customized
329       if l_custom_package_flag = TRUE then
330 
331          IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
332             FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME || l_procedure_name, 'Return Custom');
333          END IF;
334 
335          return TRUE;
336       end if;
337 
338       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
339          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
340                         l_procedure_name, 'Item ID: ' || to_char(p_item_id));
341          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
342                         l_procedure_name, 'Category ID: ' || to_char(p_category_id));
343          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
344                         l_procedure_name, 'Dest Org ID: ' || to_char(p_dest_organization_id));
345          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
346                         l_procedure_name, 'Dest Subinv: ' || p_dest_subinventory);
347          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
348                         l_procedure_name, 'Vendor ID: ' || to_char(p_vendor_id));
349          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
350                         l_procedure_name, 'Vendor Site ID: ' || to_char(p_vendor_site_id));
351          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
352                         l_procedure_name, 'Not Purchasable Override: ' || p_not_purchasable_override);
353          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
354                         l_procedure_name, 'Unit of Issue: ' || p_unit_of_issue);
355       END IF;
356 
357       -- first find the MRP: Assignment Set profile value
358       l_set_id := to_number(fnd_profile.value('MRP_DEFAULT_ASSIGNMENT_SET'));
359 
360       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
361          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
362                         l_procedure_name, 'Assignment Set ID: ' || to_char(l_set_id));
363       END IF;
364 
365       -- get the unit of issue of the destination org
366       p_unit_of_issue := get_unit_of_issue(p_item_id,p_dest_organization_id);
367 
368       if l_set_id is null then
369          p_error_msg_code := 'ICX_POR_SRC_SETUP_INC';
370          IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
371             FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME || l_procedure_name, 'Return F');
372          END IF;
373          return FALSE;
374       end if;
375 
376       -- check if the item is purchasable
377       --  if the not purchasable override flag is set to true, then the item cannot be purchasable.
378       if p_not_purchasable_override = 'N' and is_item_purchasable(p_item_id, p_dest_organization_id) = 1 then
379          l_is_purchasable_flag := 'Y';
380       else
381          l_is_purchasable_flag := 'N';
382       end if;
383 
384       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
385          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
386                         l_procedure_name, 'Is Purchasable Flag: ' || l_is_purchasable_flag);
387       END IF;
388 
389       -- run the sourcing query
390       OPEN c_sourcing;
391       loop fetch c_sourcing into
392            l_source_organization_id,
393            l_source_type,
394            l_vendor_id,
395            l_vendor_site_id;
396        exit when c_sourcing%NOTFOUND;
397 
398        IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
399           FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
400                          l_procedure_name, 'Source Org ID: ' || to_char(l_source_organization_id));
401           FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
402                          l_procedure_name, 'Source Type: ' || l_source_type);
403        END IF;
404 
405        if PO_ASL_SV.check_asl_action('2_SOURCING',l_vendor_id,
406                                      l_vendor_site_id, p_item_id, -1,
407                                      p_dest_organization_id ) <> 0 then
408 
409          -- if the sourcing rules say to pick the supplier, return supplier
410          if l_source_type = 3 then
414                               l_procedure_name, 'Return T ' || p_sourcing_type);
411             p_sourcing_type := 'SUPPLIER';
412             IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
413                FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
415             END IF;
416             return true;
417          end if;
418 
419          l_sourcing_rule_exist_err := FALSE;
420 
421          -- check if the item is assigned to this particular source org
422          if is_item_assigned(p_item_id, l_source_organization_id) = 1 then
423 
424             IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
425                FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
426                               l_procedure_name, 'Is Item Assigned: 1');
427             END IF;
428 
429             l_is_item_assigned_err := FALSE;
430             -- check if there is a valid shipping network betweem the destination org and this particular source org
431             if is_valid_shipping_network(l_source_organization_id, p_dest_organization_id) = 1 then
432 
433                IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
434                   FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
435                                  l_procedure_name, 'Is Valid Shipping Network: 1');
436                END IF;
437 
438                l_is_ship_network_assigned_err := FALSE;
439                -- check if the item flags are correctly set in this particular source org
440                if is_item_shippable(p_item_id, l_source_organization_id) = 1 then
441 
442                   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
443                      FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
444                                     l_procedure_name, 'Is Item Shippable: 1');
445                   END IF;
446 
447                   l_is_item_shippable_err := FALSE;
448 
449                   PO_REQ_LINES_SV1.get_cost_price(p_item_id,l_source_organization_id,p_unit_of_issue,p_cost_price);
450 
451                   -- Explicitly rounding the price as UI automatically rounds it to 10 digits. This is treated as a
452                   -- price change and charge account is regenerated. Hence, rounding it off to 10 to prevent the same
453                   p_cost_price := round(p_cost_price,10);
454 
455                   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
456                      FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
457                                     l_procedure_name, 'Cost Price:' || to_char(p_cost_price));
458                   END IF;
459 
460                   OPEN c_avail_quantity;
461                   fetch c_avail_quantity into
462                       l_source_subinventory,
463                       l_avail_quantity;
464                   close c_avail_quantity;
465 
466                   -- if the available quantity is greather than 0
467                   -- default to this source org and subinventory
468                   -- otherwise keep search the sourcing rule
469 
470                   IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
471                      FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
472                                     l_procedure_name, 'Avail Qty:' || to_char(l_avail_quantity));
473                   END IF;
474 
475                   if l_avail_quantity > 0 then
476                     p_sourcing_type := 'INTERNAL';
477                     p_source_organization_id := l_source_organization_id;
478                     p_source_subinventory := l_source_subinventory;
479                     close c_sourcing;
480                     IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
481                        FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
482                                       l_procedure_name, 'Return T ' || p_sourcing_type);
483                     END IF;
484                     return true;
485                   elsif l_avail_quantity = 0 then
486                      --Bug 14842729 if there is no on hand quantity, source type depends on Profile  POR_SRC_INT_STO_ITMS_NO_AVAIL
487                     IF (Nvl(FND_PROFILE.Value('POR_SRC_INT_STO_ITMS_NO_AVAIL'),'INTERNALLY') = 'INTERNALLY') THEN
488                       p_sourcing_type := 'INTERNAL';
489                       p_source_organization_id := l_source_organization_id;
490                       --p_source_subinventory := l_source_subinventory;
491                       close c_sourcing;
492                       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
493                          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
494                                       l_procedure_name, 'Return T ' || p_sourcing_type);
495                       END IF;
496 		      return true;
497                      END IF;
498                   end if;
499 
500                   --save the first record so if the avail qty is 0 in all subinv do not
501                   --populate the subinv and default the first source org if there is no error
502                   --Bug 14842729 if there is no on hand quantity, source type depends on Profile  POR_SRC_INT_STO_ITMS_NO_AVAIL
503                   if  ( (l_count = 0) and not (l_sourcing_rule_exist_err or l_is_item_assigned_err or l_is_ship_network_assigned_err or l_is_item_shippable_err)
504                       and (Nvl(FND_PROFILE.Value('POR_SRC_INT_STO_ITMS_NO_AVAIL'),'INTERNALLY') = 'INTERNALLY'))  then
505 
506                      IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
507                         FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
508                                        l_procedure_name, 'Count = 0');
509                      END IF;
510 
511                      l_first_source_org_id := l_source_organization_id ;
512                   end if;
513                   l_count := l_count + 1;
514                end if;
515             end if;
516          end if;
517        end if;
518       end loop;
519       if c_sourcing%ISOPEN then
520          close c_sourcing;
521       end if;
522 
523       -- if l_count > 0 and l_first_source_org_id is not -9999 then
524       -- it means that a source org was returned but no sub inv is there
525       if ( ( l_count > 0) and (l_first_source_org_id <> -9999) ) then
526          p_sourcing_type := 'INTERNAL';
527          p_source_organization_id := l_first_source_org_id;
528          IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
529             FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
530                            l_procedure_name, 'Return T ' || p_sourcing_type);
531          END IF;
532          return TRUE;
533       end if;
534 
535       -- if we didn't find an internal source and the item is purchasable, return Supplier
536       if (l_is_purchasable_flag = 'Y') then
537          p_sourcing_type := 'SUPPLIER';
538          IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
539             FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
540                            l_procedure_name, 'Return T ' || p_sourcing_type);
541          END IF;
542          return TRUE;
543       end if;
544 
545       p_sourcing_type := null;
546 
547       -- if we didn't find an internal source and the item is strictly internally
548       -- orderable, select error msg code and return false
549       if l_sourcing_rule_exist_err then
550          p_error_msg_code := 'ICX_POR_SRC_RULE_NOEXIST';
551       elsif l_is_item_assigned_err then
552          p_error_msg_code := 'ICX_POR_NO_INT_SOURCES_ERR';
553       elsif l_is_ship_network_assigned_err then
554          p_error_msg_code := 'ICX_POR_NO_INT_SOURCES_ERR';
555       elsif l_is_item_shippable_err then
556          p_error_msg_code := 'ICX_POR_SRC_ITEM_SHIP_ERR';
557       else
558          p_error_msg_code := 'ICX_POR_NO_INT_SOURCES_ERR';
559       end if;
560 
561       IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
562          FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
563                         l_procedure_name, 'Return F');
564       END IF;
565 
566       return FALSE;
567 
568     EXCEPTION
569        WHEN OTHERS THEN
570           p_error_msg_code := 'Exception';
571           if c_sourcing%ISOPEN then
572              close c_sourcing;
573           end if;
574           IF (G_LEVEL_STATEMENT >= G_CURRENT_RUNTIME_LEVEL ) THEN
575              FND_LOG.STRING(G_LEVEL_STATEMENT, G_MODULE_NAME ||
576                         l_procedure_name, 'Exception Return F');
577           END IF;
578           RETURN FALSE;
579 
580     END autosource;
581 
582 END POR_AUTOSOURCE_UTIL_PKG; -- package