@caseparts-org/casecore 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,3 +10,5 @@ export type { Pricing, CustomerClass } from './cart/ClassPricing';
10
10
  export { getClassPricing } from './cart/ClassPricing';
11
11
  export type { BaseCartItem, CartContextValue, CartProviderProps, } from './cart/CartContext';
12
12
  export { CartProvider, useCartContext } from './cart/CartContext';
13
+ export type { WarehouseInventory, Inventory, Availability, CustomPartAvailabilityResult, UnifiedAvailabilityResult, } from './inventory/PartAvailability';
14
+ export { default as calcPartAvailability, calcDetailedPartAvailability, CUSTOM_PART_LEAD_TIMES, isDiscontinued, computeStockAvailability, computeCustomPartAvailability, shouldSuggestContactLink, computeAvailability } from './inventory/PartAvailability';
package/dist/index.js CHANGED
@@ -7,3 +7,4 @@ export { buildClaimsFromPayload } from './utils/ClaimsUtils';
7
7
  export { default as useMicroFlex } from './hooks/useMicroFlex';
8
8
  export { getClassPricing } from './cart/ClassPricing';
9
9
  export { CartProvider, useCartContext } from './cart/CartContext';
10
+ export { default as calcPartAvailability, calcDetailedPartAvailability, CUSTOM_PART_LEAD_TIMES, isDiscontinued, computeStockAvailability, computeCustomPartAvailability, shouldSuggestContactLink, computeAvailability } from './inventory/PartAvailability';
@@ -0,0 +1,36 @@
1
+ export interface WarehouseInventory {
2
+ Unreserved: number;
3
+ Available: number;
4
+ }
5
+ export interface Inventory {
6
+ MPK: WarehouseInventory;
7
+ SEA: WarehouseInventory;
8
+ STL: WarehouseInventory;
9
+ }
10
+ export interface Availability {
11
+ description: string;
12
+ id: string;
13
+ }
14
+ export default function calcPartAvailability(inventory: Inventory | undefined, discontinued: boolean): Availability | '';
15
+ export declare function calcDetailedPartAvailability(inventory: Inventory | undefined, discontinued: boolean): Availability;
16
+ export declare const CUSTOM_PART_LEAD_TIMES: Record<string, string>;
17
+ export declare function isDiscontinued(partStatus: number): boolean;
18
+ export declare function computeStockAvailability(inventory: Inventory | undefined, partStatus: number, detailed: boolean): Availability | '';
19
+ export interface CustomPartAvailabilityResult {
20
+ availability: Availability | null;
21
+ leadTime: string | null;
22
+ }
23
+ export declare function computeCustomPartAvailability(customType: string, _inventory: Inventory | undefined, _partStatus: number): CustomPartAvailabilityResult;
24
+ export declare function shouldSuggestContactLink(availability: Availability, useFullDescription: boolean): boolean;
25
+ export interface UnifiedAvailabilityResult {
26
+ availability: Availability | '' | null;
27
+ leadTime: string | null;
28
+ source: 'custom' | 'stock';
29
+ }
30
+ export declare function computeAvailability(options: {
31
+ isCustom: boolean;
32
+ customType?: string;
33
+ inventory: Inventory | undefined;
34
+ partStatus: number;
35
+ detailed?: boolean;
36
+ }): UnifiedAvailabilityResult;
@@ -0,0 +1,117 @@
1
+ export default function calcPartAvailability(inventory, discontinued) {
2
+ if (!inventory || !inventory.MPK && !inventory.SEA && !inventory.STL) {
3
+ return '';
4
+ }
5
+ const inStock = inventory.MPK.Unreserved > 5 || inventory.SEA.Unreserved > 5 || inventory.STL.Unreserved > 5;
6
+ const limited = inventory.MPK.Unreserved > 0 || inventory.SEA.Unreserved > 0 || inventory.STL.Unreserved > 0;
7
+ if (inStock) {
8
+ return { description: 'In Stock', id: 'available' };
9
+ }
10
+ else if (discontinued) {
11
+ return { description: "Discontinued", id: "discontinued" };
12
+ }
13
+ else if (limited) {
14
+ return { description: 'Limited availability', id: 'limited' };
15
+ }
16
+ return { description: 'Contact us', id: 'contactus' };
17
+ }
18
+ export function calcDetailedPartAvailability(inventory, discontinued) {
19
+ const unreserved = (whse) => inventory ? inventory[whse].Unreserved : inventory[whse];
20
+ const available = (whse) => inventory ? inventory[whse].Available : inventory[whse];
21
+ const quantity = 1;
22
+ // Deal with discontinued parts
23
+ if (discontinued) {
24
+ const total = unreserved("MPK") + unreserved("STL") + unreserved("SEA");
25
+ const message = total >= quantity
26
+ ? { description: "This part is discontinued, supplies are limited", id: "limited" }
27
+ : total > 0
28
+ ? { description: `This part is discontinued and we only have ${total} in stock`, id: 'available' }
29
+ : { description: "Contact us. This part is discontinued but we might have compatible alternatives.", id: "contactus" };
30
+ return message;
31
+ }
32
+ // Count up the number of warehouses with sufficient unreserved quantity
33
+ const mpk = unreserved("MPK") >= quantity ? 1 : 0;
34
+ const stl = unreserved("STL") >= quantity ? 1 : 0;
35
+ const sea = unreserved("SEA") >= quantity ? 1 : 0;
36
+ const whseCount = mpk + stl + sea;
37
+ if (unreserved("MPK") < 5 && unreserved("SEA") < 5 && unreserved("STL") < 5) {
38
+ let limitedStockDescr = null;
39
+ if (whseCount === 3)
40
+ limitedStockDescr = 'Limited availability at all warehouses';
41
+ else if (whseCount === 1)
42
+ limitedStockDescr = `Limited availability in ${mpk ? "Los Angeles" : stl ? "St. Louis" : "Seattle"}`;
43
+ else if (mpk && stl)
44
+ limitedStockDescr = 'Limited availability in Los Angeles & St. Louis';
45
+ else if (mpk && sea)
46
+ limitedStockDescr = 'Limited availability in Los Angeles & Seattle';
47
+ else if (stl && sea)
48
+ limitedStockDescr = 'Limited availability in St. Louis & Seattle';
49
+ if (limitedStockDescr) {
50
+ return { description: limitedStockDescr, id: 'limited' };
51
+ }
52
+ }
53
+ let inStockDescr = null;
54
+ if (whseCount === 3)
55
+ inStockDescr = 'In Stock at All Warehouses';
56
+ else if (whseCount === 1)
57
+ inStockDescr = `In stock in ${mpk ? "Los Angeles" : stl ? "St. Louis" : "Seattle"}`;
58
+ else if (mpk && stl)
59
+ inStockDescr = 'In Stock in Los Angeles & St. Louis';
60
+ else if (mpk && sea)
61
+ inStockDescr = 'In Stock in Los Angeles & Seattle';
62
+ else if (stl && sea)
63
+ inStockDescr = 'In Stock in St. Louis & Seattle';
64
+ if (inStockDescr) {
65
+ return { description: inStockDescr, id: 'available' };
66
+ }
67
+ if (available("MPK") + available("STL") + available("SEA") >= quantity) {
68
+ return { description: 'Limited availability', id: 'limited' };
69
+ }
70
+ return { description: 'Contact us for availability', id: 'contactus' };
71
+ }
72
+ // Map of custom part lead times
73
+ export const CUSTOM_PART_LEAD_TIMES = {
74
+ Heater: "1 Business Day or Less",
75
+ Wire: "1 Business Day or Less",
76
+ Gasket: "1-2 Business Days",
77
+ };
78
+ // Centralized discontinued check
79
+ export function isDiscontinued(partStatus) {
80
+ return partStatus === 3;
81
+ }
82
+ // Computes availability for a stock (non-custom) part.
83
+ // Wrapper around existing calcPartAvailability / calcDetailedPartAvailability.
84
+ export function computeStockAvailability(inventory, partStatus, detailed) {
85
+ const discontinued = isDiscontinued(partStatus);
86
+ return detailed
87
+ ? calcDetailedPartAvailability(inventory, discontinued)
88
+ : calcPartAvailability(inventory, discontinued);
89
+ }
90
+ // Computes availability info for a custom part (e.g. Heater, Wire, Gasket).
91
+ export function computeCustomPartAvailability(customType, _inventory, _partStatus) {
92
+ const leadTime = CUSTOM_PART_LEAD_TIMES[customType] || null;
93
+ return { availability: null, leadTime };
94
+ }
95
+ // Helper to decide whether UI should render a contact link
96
+ export function shouldSuggestContactLink(availability, useFullDescription) {
97
+ return availability.id === "contactus" && useFullDescription;
98
+ }
99
+ // Wrapper choosing custom vs stock logic.
100
+ // isCustom: true requires customType.
101
+ // detailed applies only to stock (ignored for custom unless you later extend).
102
+ export function computeAvailability(options) {
103
+ const { isCustom, customType, inventory, partStatus, detailed = false } = options;
104
+ if (isCustom) {
105
+ if (!customType) {
106
+ return { availability: null, leadTime: null, source: 'custom' };
107
+ }
108
+ if (customType === 'Heater') {
109
+ const availability = computeStockAvailability(inventory, partStatus, true);
110
+ return { availability, leadTime: null, source: 'stock' };
111
+ }
112
+ const { availability, leadTime } = computeCustomPartAvailability(customType, inventory, partStatus);
113
+ return { availability, leadTime, source: 'custom' };
114
+ }
115
+ const availability = computeStockAvailability(inventory, partStatus, detailed);
116
+ return { availability, leadTime: null, source: 'stock' };
117
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@caseparts-org/casecore",
3
3
  "private": false,
4
- "version": "0.0.13",
4
+ "version": "0.0.14",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",