Skip to Main Content
Sort
An error occurred while processing the template.
The following has evaluated to null or missing:
==> productCategories.items  [in template "37794063322763#20119#53162" at line 44, column 46]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: categories = productCategories.items  [in template "37794063322763#20119#53162" at line 44, column 33]
----
1<#assign  
2				 defaultImgMap = { 
3				 "220": "/documents/d/guest/220-coming-soon", 
4				 "220EV": "/documents/d/guest/220ev-coming-soon", 
5				 "520": "/documents/d/guest/520-coming-soon", 
6				 "389": "/documents/d/guest/389-coming-soon", 
7				 "520EV": "/documents/d/guest/520ev-coming-soon", 
8				 "535": "/documents/d/guest/535-coming-soon", 
9				 "536": "/documents/d/guest/536-coming-soon", 
10				 "537": "/documents/d/guest/537-coming-soon", 
11				 "548": "/documents/d/guest/548-coming-soon", 
12				 "567": "/documents/d/guest/567-coming-soon", 
13				 "579": "/documents/d/guest/579-coming-soon", 
14				 "579EV": "/documents/d/guest/579ev-coming-soon", 
15				 "589": "/documents/d/guest/589-coming-soon" 
16
17				 /> 
18<#assign 
19				 commerceContext = renderRequest.getAttribute("COMMERCE_CONTEXT") 
20				 account = commerceContext.getAccountEntry() 
21				 accountId = account.getAccountEntryId() 
22				 chanelId = commerceContext.getCommerceChannelId() 
23				 /> 
24<div class="product-card-tiles"> 
25	<#if entries?has_content> 
26		<#list entries as curCPCatalogEntry> 
27			 
28			<#assign 
29				cpDefinitionId = curCPCatalogEntry.getCPDefinitionId() 
30				productId = curCPCatalogEntry.getCProductId() 
31				productName = curCPCatalogEntry.getName() 
32				productShortDescription = curCPCatalogEntry.getShortDescription() 
33				productDescription = curCPCatalogEntry.getDescription() 
34				friendlyURL = cpContentHelper.getFriendlyURL(curCPCatalogEntry, themeDisplay) 
35				defaultImageURL = cpContentHelper.getDefaultImageFileURL(accountId, cpDefinitionId) 
36				defaultImageFileVersion = cpContentHelper.getCPDefinitionImageFileVersion(cpDefinitionId, request) 
37				productDetail = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}?accountId=${accountId}&nestedFields=categories,productSpecifications") 
38				defaultImageURL = productDetail.urlImage?replace('https://localhost', '') 
39				fileEntryIdAttr = 'data-fileentryid="' + defaultImageFileVersion.fileEntryId + '"' 
40				specifications = productDetail.productSpecifications 
41				customFields = productDetail.customFields 
42 
43				productCategories = restClient.get("/headless-commerce-delivery-catalog/v1.0/channels/${chanelId}/products/${productId}/categories?pageSize=40") 
44				categories = productCategories.items 
45 
46			  erc = productDetail.externalReferenceCode 
47				infoObj = {} 
48				tags = productDetail.tags 
49				featuredSpecificationKeys = ["fit", "weight", "material"] 
50				isSuggested = false 
51				suggestedClass = "" 
52							  
53							 visiblePrice = "" 
54							 miles = "" 
55							 neworUsed = "" 
56							 locationName = "" 
57							 locationId = "" 
58							 displayPrice = false 
59							  
60							 truckBadgesArray = [{"id": "", "value": ""}] 
61							  
62							  
63			 /> 
64			<#if categories?has_content> 
65					<#list categories as category> 
66						<#if category.vocabulary?replace(' ', '') = 'truckbadges'> 
67							<#assign truckBadgesArray += [{"id": category.id, "value": category.name}] /> 
68						<#else> 
69							<#assign infoObj = infoObj + {category.vocabulary?replace(' ', ''): {"id": category.id, "value": category.name}} /> 
70						</#if> 
71					</#list> 
72						<#assign infoObj = infoObj + {"truckbadges": truckBadgesArray} /> 
73				</#if> 
74 
75			<div class="d-none"> 
76				<#list customFields as customField> 
77					<#if customField.name = 'Visible Price'> 
78						<#assign visiblePrice = customField.customValue.data /> 
79					</#if> 
80 
81					<#if customField.name = 'Display Price'> 
82						<#assign displayPrice = customField.customValue.data /> 
83					</#if> 
84				 
85					<#if customField.name = 'Miles'> 
86						<#assign miles = customField.customValue.data /> 
87					</#if> 
88				</#list> 
89				 
90				<#if infoObj.year?has_content> 
91          <#assign productName = infoObj.year.value /> 
92			  </#if> 
93				<#if infoObj.make?has_content> 
94          <#assign productName = productName + " " + infoObj.make.value /> 
95			  </#if> 
96				<#if infoObj.model?has_content> 
97          <#assign productName = productName + " " + infoObj.model.value /> 
98					 
99					<#if defaultImageURL?trim?contains('/o/commerce-media/default/?groupId=') || defaultImageURL?trim?contains('commercial-truck-coming-soon')> 
100						<#if defaultImgMap[infoObj.model.value?lower_case]?? > 
101							<#assign fileEntryIdAttr = '' /> 
102							<#assign defaultImageURL = defaultImgMap[infoObj.model.value?lower_case] /> 
103						</#if> 
104					</#if> 
105 
106				</#if>				 
107				 
108				<#if categories?has_content> 
109					<#list categories as category> 
110						<#if category.vocabulary = 'conditions'> 
111							<#assign newOrUsed = category.name /> 
112							<#if category.name = 'Used'> 
113								<#assign newOrUsed = 'Pre-Owned'/> 
114							</#if> 
115						</#if> 
116					 
117						<#if category.vocabulary = 'location'> 
118							<#assign locationName = category.name /> 
119							<#assign locationId = category.id /> 
120						</#if> 
121						 
122						<!--<span class="btn btn-outline-primary product-category">${category.vocabulary}: ${category.name}</span> --> 
123					</#list> 
124				</#if> 
125				 
126				<#if specifications?has_content> 
127					<#list specifications as specification> 
128						<#if featuredSpecificationKeys?seq_contains(specification.specificationKey) > 
129							<span class="badge badge-secondary">${specification.value}"</span> 
130						</#if> 
131					</#list> 
132				</#if> 
133			</div> 
134 
135			<#assign sku = "" /> 
136			<#if cpContentHelper.getDefaultCPSku(curCPCatalogEntry)?has_content> 
137				<#assign sku = cpContentHelper.getDefaultCPSku(curCPCatalogEntry).getSku()/> 
138			</#if> 
139							 
140			<#if tags?seq_contains("suggested")> 
141				<#assign isSuggested = true /> 
142				<#assign suggestedClass = "suggested" /> 
143			</#if> 
144			<div class="product-listing-card"> 
145				<div class="product-card-top click-here-box"> 
146					<img src="${defaultImageURL}" ${fileEntryIdAttr} class="img-fluid" alt="${productName}" /> 
147					 
148					<#if infoObj.truckbadges??> 
149						<#list infoObj.truckbadges as truckBadge> 
150							<#if truckBadge.value = "Red Oval"> 
151								<div class="overlay-badge top-right"> 
152									<img src="/documents/d/guest/red-oval" class="overlay-badge-img red-oval-badge" alt="Red Oval" /> 
153								</div> 
154							</#if> 
155							 
156							<#if truckBadge.value = "Work Ready"> 
157								<div class="overlay-badge top-left"> 
158									<img src="/documents/d/guest/work-ready" class="overlay-badge-img work-ready-badge" alt="Work Ready" /> 
159								</div> 
160							</#if> 
161						</#list> 
162					</#if> 
163										 
164					<div class="aspect-ratio-item-bottom-left"> 
165						<@liferay_commerce_ui["availability-label"] CPCatalogEntry=curCPCatalogEntry /> 
166					</div> 
167						 
168					<#if isSuggested> 
169						<div class="aspect-ratio-item-bottom-right"> 
170							<span class="label label-inverse-primary ${suggestedClass}" > 
171								<span class="label-item label-item-expand"> 
172									Suggested 
173								</span> 
174							</span> 
175						</div> 
176					</#if> 
177					 
178					<a href="${friendlyURL}" class="click-here-link d-none">Learn More</a> 
179				</div> 
180				 
181				<div class="product-card-body click-here-box ${suggestedClass}"> 
182					<p class="mb-1">Stock Number: <b>${curCPCatalogEntry.getName()}</b></p> 
183					<h3 class="product-card-title ${suggestedClass}" title="${productName}"><a href="${friendlyURL}" class="color-inherit click-here-link">${productName}</a></h3> 
184					<div class="product-card-details"> 
185						<ul class="prod-main-info"> 
186							<#if displayPrice[0] == "Yes" && visiblePrice?has_content> 
187								<#assign formattedPrice = visiblePrice?string.currency> 
188								<li class="prod-price">${formattedPrice}</li> 
189							<#else> 
190								<li class="prod-price">Call For Pricing</li> 
191							</#if> 
192							<#if miles != "" && miles != "0"> 
193								<#assign cleanMiles = miles?replace("[^0-9]", "", "r") /> 
194								<#assign formattedMiles = cleanMiles?number?string('#,##0.###') /> 
195							  <li class="prod-miles"><span class="miles-text">${formattedMiles}</span> mi</li> 
196							</#if> 
197						</ul> 
198						 
199						<#if newOrUsed??> 
200							<span class="new-or-used-badge">${newOrUsed}</span> 
201						</#if> 
202					</div> 
203				</div> 
204 
205				<div class="product-card-footer"> 
206					<#if locationName != ""> 
207						<div class="product-card-location"> 
208							<p>Available in: <a href="/product-list?location=${locationId}">${locationName}</a></p> 
209						</div> 
210					</#if> 
211				</div> 
212 
213			</div>			 
214		</#list> 
215	</#if> 
216</div> 

New Trucks

Need a new truck for your fleet? Look no further than The Pete Store’s extensive inventory of premium Peterbilt trucks. Our experts will help you customize your truck's specifications to perfectly match your job requirements.


*Offer subject to credit approval. Standard credit underwriting guidelines through a Pete Store partner lender apply. Not all trucks will qualify, and actual dealer incentives and finance terms may vary and will depend on many factors, including applicant and/or guarantor credit profile(s) and additional approval conditions. The Pete Store, selling dealer, and our banking partners reserve the right to amend, supersede, or terminate this program at any time. Additional state restrictions may apply. Cannot be combined with any other offers.