التنقل في الفئات التجارية

حصل خطأ عند معالجة القالب.
The following has evaluated to null or missing:
==> serviceLocator.findService("com.marketplace.brand.service.BrandLocalService")  [in template "20096#20121#36181" at line 7, column 30]

----
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: #assign brandLocalService = serviceLo...  [in template "20096#20121#36181" at line 7, column 1]
----
1<#assign categoryCounter = 0 /> 
2<#assign portalURL = themeDisplay.getPortalURL() /> 
3<#assign publicSiteURL = portalURL + themeDisplay.getPathFriendlyURLPublic() + layout.getGroup().friendlyURL /> 
4<#assign cAllUrl = "${publicSiteURL}/market" /> 
5<#assign assetEntryLocalService=serviceLocator.findService("com.liferay.asset.kernel.service.AssetEntryLocalService") /> 
6<#assign cpDefinitionLocalService=serviceLocator.findService("com.liferay.commerce.product.service.CPDefinitionLocalService") /> 
7<#assign brandLocalService = serviceLocator.findService("com.marketplace.brand.service.BrandLocalService") /> 
8<#assign assetEntryAssetCategoryRelLocalService = serviceLocator.findService("com.liferay.asset.entry.rel.service.AssetEntryAssetCategoryRelLocalService") /> 
9 
10<#function getPublishedProductCount brandId> 
11	<#assign productCount=0 /> 
12	<#assign  assetEntryAssetCategoryRel = assetEntryAssetCategoryRelLocalService.getAssetEntryAssetCategoryRelsByAssetCategoryId(brandId) /> 
13	<#list assetEntryAssetCategoryRel as assetEntryCategoryRel> 
14		<#assign assetEntry = assetEntryLocalService.fetchAssetEntry(assetEntryCategoryRel.getAssetEntryId()) /> 
15       <#if assetEntry??> 
16					<#assign classPK = assetEntry.getClassPK() /> 
17				  <#assign cpDefinition = cpDefinitionLocalService.getCPDefinition(classPK) /> 
18				 <#if cpDefinition??> 
19             <#if cpDefinition.isPublished() && cpDefinition.getStatus() == 0> 
20                 <#assign productCount = productCount + 1 /> 
21             </#if> 
22         </#if> 
23			</#if>  
24	</#list> 
25  <#return productCount?number /> 
26</#function> 
27	 
28<script> 
29	var brandsMap = new Map(); 
30</script> 
31 
32<div class="container"> 
33	<a class="navbar-brand"><b>All Brand</b></a> 
34  <form class="form-inline"> 
35		<div class="input-group"> 
36			<div class="input-group-prepend"> 
37				<span class="input-group-text" id="basic-addon1"> <img src="/o/buycorp-classic-theme/images/icon/search-icon.png" ></span> 
38			</div> 
39			<input class="form-control mr-sm-2 blp-search p-0" type="search" id="categorySearch" list="searchResults" placeholder="Search By Brand Name" aria-label="Search" aria-describedby="basic-addon1" /> 
40		</div> 
41  </form> 
42	<nav class="navbar navbar-light bg-light blp-navigation justify-content-between"> 
43		<span  class="ml-2"style="font-family: Roboto; font-size: 20px; font-weight: 400; letter-spacing: 0.71em;"> 
44			<#assign characters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] /> 
45			<#list characters as letter> 
46				<a href="#${letter}" class="alphabet-link">${letter}</a> 
47			</#list> 
48    </span> 
49  </nav> 
50	<div class="blp-search-card d-none"> 
51		<div id="searchResults"></div> 
52	</div> 
53	<br /> 
54	<br /> 
55	<div class="d-flex flex-wrap maxBoxScroll" id="<@portlet.namespace />cpAssetCategoryNavigation"> 
56 
57	<#if entries?has_content> 
58		<#assign brandMap = {} /> 
59		<#list entries as brand> 
60			<#assign customBrandObj = brandLocalService.findByFBYAssetCategoryId(brand.getCategoryId()) /> 
61			<#assign isBrandInactive = customBrandObj.getBrandInactive() /> 
62			<#assign isBrandApproved = customBrandObj.getBrandApprovalStatus() == "Approved" /> 
63			<#assign displayBrand = true /> 
64			 
65			<#if isBrandInactive && isBrandApproved> 
66				<#assign displayBrand = false /> 
67			</#if> 
68			 
69			<#assign isBrandActive = customBrandObj.getIsActive() /> 
70			<#if isBrandActive && displayBrand> 
71				<#assign productCount = getPublishedProductCount(brand.getCategoryId()) /> 
72				<#assign brandMap = brandMap + {brand.getCategoryId() : brand.getName()} /> 
73				<#if productCount gt 0> 
74					<script> 
75						brandsMap.set(${brand.getCategoryId()}, '${brand.getName()}'); 
76					</script> 
77				</#if> 
78				<#assign categoryCounter = categoryCounter + 1 /> 
79			</#if> 
80		</#list> 
81		 
82		<#assign alphbeticalBrandMap = {} /> 
83		 
84		<#list brandMap as k,v> 
85			<#assign firstLetter = v?substring(0,1)?upper_case /> 
86			<#if alphbeticalBrandMap[firstLetter]??> 
87				<#-- The letter already exists in the map, so we add the brand to the existing list --> 
88					<#assign alphbeticalBrandMap = alphbeticalBrandMap + { (firstLetter)?string : (alphbeticalBrandMap[firstLetter]![]) + [{k: v}] } /> 
89			<#else> 
90				<#-- The letter does not exist in the map, so we create a new list --> 
91				<#assign alphbeticalBrandMap = alphbeticalBrandMap + { (firstLetter)?string : [{k: v}] } /> 
92			</#if> 
93		</#list> 
94		<#-- Debugging: Print the contents of alphbeticalBrandMap --> 
95		 <div class="container"> 
96			 <div class="blp-page"> 
97				 <#list alphbeticalBrandMap?keys as letter> 
98					 <div class="row" style="border-bottom:1px solid#e8e8e8;"> 
99						 <div class="col-md-1 brand-symbol"> 
100							 <h1  id="${letter}"> ${letter}</h1> 
101						 </div> 
102						 <#-- Get the list of brands associated with this letter --> 
103						<#assign newBrandsList = alphbeticalBrandMap[letter] /> 
104						<div class="col-md-11"> 
105							<div class="row brand-name"> 
106								<#list newBrandsList as brandEntry> 
107									<#assign brandId = (brandEntry?keys[0])?number> 
108										<#assign productCount = getPublishedProductCount(brandId) /> 
109										<#assign cUrl = "${publicSiteURL}/market?brand=${brandId}" /> 
110										<div class="col-md-2 "> 
111											<#if productCount gt 0> 
112												<a href="${cUrl}"><p>${brandEntry[brandEntry?keys[0]]} (${productCount})</p></a> 
113											<#else> 
114												<p>${brandEntry[brandEntry?keys[0]]} (${productCount})</p> 
115											</#if> 
116										</div> 
117									</#list> 
118								</div> 
119							</div> 
120						</div> 
121					</#list> 
122				</div> 
123			</div> 
124		</div>     
125  </#if> 
126 </div> 
127</div> 
128 
129<script> 
130	const searchElement = document.getElementById('categorySearch'); 
131 
132	const searchData = (event) => { 
133		const filteredMap = new Map( 
134		[...brandsMap].filter(([k, v]) => v.toLowerCase().includes(event.target.value.toLowerCase())) 
135		); 
136		showResults(filteredMap); 
137  }; 
138 
139	const debounce = (callback, waitTime) => { 
140		let timer; 
141		return (...args) => { 
142			clearTimeout(timer); 
143			timer = setTimeout(() => { 
144				callback(...args); 
145			}, waitTime); 
146		}; 
147	}; 
148 
149	const debounceHandler = debounce(searchData, 1000); 
150	searchElement.addEventListener('input', debounceHandler); 
151 
152	var showResults = filteredCategories => { 
153 
154		let searchResultsList = document.getElementById('searchResults'); 
155		searchResultsList.innerHTML = ''; 
156 
157		if(searchElement.value.trim().length == 0) { 
158			$('.blp-search-card').addClass('d-none'); 
159			return; 
160
161		$('.blp-search-card').removeClass('d-none'); 
162 
163		if (filteredCategories.size == 0) { 
164			let noResultItem = document.createElement('div'); 
165			noResultItem.textContent = 'No brands found'; 
166			searchResultsList.appendChild(noResultItem); 
167		} else { 
168			filteredCategories.forEach((value, key) => { 
169 
170				let listItem = document.createElement('li'); 
171				listItem.setAttribute('categoryid', key); 
172 
173				let anchor = document.createElement('a'); 
174				anchor.setAttribute('href', '${publicSiteURL}/market?brand=' + key + ''); 
175				anchor.innerText = value; 
176 
177				listItem.appendChild(anchor); 
178				searchResultsList.appendChild(listItem); 
179			}); 
180
181	}; 
182 
183</script> 
184 
185									  
186	<style> 
187	 
188 
189 .text-secondary{font-weight:400; font-size:12px;} 
190		.blp-navigation{ background-color: rgba(242, 246, 246, 1) !important;  border-radius: 6px; margin-top: 15px;} 
191 
192 .navbar-brand b{font-family:roboto; font-weight:600;  font-size:24px; color: #373737;;} 
193 .blp-search {border-left-style: none;} 
194 .input-group-text{background-color:#fff; border-color: #E8E8E8;}  
195.input-group:hover .input-group-text, .input-group:hover .form-control.blp-search  
196		{ border-color: #888888!important;} 
197.input-group .input-group-text:focus,  
198.input-group .form-control.blp-search:focus { 
199    border-color: #5D9795 !important; 
200    box-shadow: 0 0 0 0.2rem rgba(52, 125, 122, 0.24) !important; 
201
202		.alphabet-link {color:#373737;} 
203		.alphabet-link:hover{text-decoration:none;} 
204		 
205		 
206		 
207 	.blp-page{ padding-top:12px; 
208  h1 {text-align: center;background-color: rgba(43, 73, 96, 1); 
209		color: rgba(255, 255, 255, 1);width: 60px;height: 55px;}} 
210		.input-group	{margin-left:auto;} 
211		.form-inline{float:right;} 
212			.blp-search-card {background-color: #fff; border-color: rgba(0, 0, 0, 0.125); border-radius: 0.25rem;border-style: solid; 
213    border-width: 0.065rem; margin-bottom: 1.5rem;margin-top: -68px;position: absolute;word-wrap: break-word;right:4.5rem;  
214    padding: 8px; z-index: 1;list-style-type: none; max-height: 136px; overflow-y:auto; width: 100%; 
215    max-width: 206px; 
216
217			.brand-symbol	{ padding: 8px; margin-top: 8px;} 
218		  .brand-name{    margin-top: 7px;} 
219			.brand-name	p{  font-size: 14px;font-weight: 400; margin:0;  padding-top: 5px;line-height:20px;} 
220		.brand-name a:hover{color:#2B4960;} 
221      .maxBoxScroll {overflow-y: auto; max-height: 100%;} 
222		 
223		@media (max-width:768px) 
224
225    .brand-name .col-md-2{ 
226      flex:0 0  25%; 
227        max-width:80%; 
228
229
230 
231	</style>