@@ -132,6 +132,20 @@ public function autoCompleteIpn(Part $part, string $description, int $suggestPar
132132 $ category = $ part ->getCategory ();
133133 $ ipnSuggestions = ['commonPrefixes ' => [], 'prefixesPartIncrement ' => []];
134134
135+ //Show global prefix first if configured
136+ if ($ this ->ipnSuggestSettings ->globalPrefix !== null && $ this ->ipnSuggestSettings ->globalPrefix !== '' ) {
137+ $ ipnSuggestions ['commonPrefixes ' ][] = [
138+ 'title ' => $ this ->ipnSuggestSettings ->globalPrefix ,
139+ 'description ' => $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.global_prefix ' )
140+ ];
141+
142+ $ increment = $ this ->generateNextPossibleGlobalIncrement ();
143+ $ ipnSuggestions ['prefixesPartIncrement ' ][] = [
144+ 'title ' => $ this ->ipnSuggestSettings ->globalPrefix . $ increment ,
145+ 'description ' => $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.global_prefix ' )
146+ ];
147+ }
148+
135149 if (strlen ($ description ) > 150 ) {
136150 $ description = substr ($ description , 0 , 150 );
137151 }
@@ -160,17 +174,17 @@ public function autoCompleteIpn(Part $part, string $description, int $suggestPar
160174 if ($ category instanceof Category) {
161175 $ currentPath = $ category ->getPartIpnPrefix ();
162176 $ directIpnPrefixEmpty = $ category ->getPartIpnPrefix () === '' ;
163- $ currentPath = $ currentPath === '' ? ' n.a. ' : $ currentPath ;
177+ $ currentPath = $ currentPath === '' ? $ this -> ipnSuggestSettings -> fallbackPrefix : $ currentPath ;
164178
165179 $ increment = $ this ->generateNextPossiblePartIncrement ($ currentPath , $ part , $ suggestPartDigits );
166180
167181 $ ipnSuggestions ['commonPrefixes ' ][] = [
168- 'title ' => $ currentPath . ' - ' ,
182+ 'title ' => $ currentPath . $ this -> ipnSuggestSettings -> numberSeparator ,
169183 'description ' => $ directIpnPrefixEmpty ? $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix_empty.direct_category ' , ['%name% ' => $ category ->getName ()]) : $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.direct_category ' )
170184 ];
171185
172186 $ ipnSuggestions ['prefixesPartIncrement ' ][] = [
173- 'title ' => $ currentPath . ' - ' . $ increment ,
187+ 'title ' => $ currentPath . $ this -> ipnSuggestSettings -> numberSeparator . $ increment ,
174188 'description ' => $ directIpnPrefixEmpty ? $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix_empty.direct_category ' , ['%name% ' => $ category ->getName ()]) : $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.direct_category.increment ' )
175189 ];
176190
@@ -179,18 +193,19 @@ public function autoCompleteIpn(Part $part, string $description, int $suggestPar
179193
180194 while ($ parentCategory instanceof Category) {
181195 // Prepend the parent category's prefix to the current path
182- $ currentPath = $ parentCategory ->getPartIpnPrefix () . '- ' . $ currentPath ;
183- $ currentPath = $ parentCategory ->getPartIpnPrefix () === '' ? 'n.a.- ' . $ currentPath : $ currentPath ;
196+ $ effectiveIPNPrefix = $ parentCategory ->getPartIpnPrefix () === '' ? $ this ->ipnSuggestSettings ->fallbackPrefix : $ parentCategory ->getPartIpnPrefix ();
197+
198+ $ currentPath = $ effectiveIPNPrefix . $ this ->ipnSuggestSettings ->categorySeparator . $ currentPath ;
184199
185200 $ ipnSuggestions ['commonPrefixes ' ][] = [
186- 'title ' => $ currentPath . ' - ' ,
201+ 'title ' => $ currentPath . $ this -> ipnSuggestSettings -> numberSeparator ,
187202 'description ' => $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.hierarchical.no_increment ' )
188203 ];
189204
190205 $ increment = $ this ->generateNextPossiblePartIncrement ($ currentPath , $ part , $ suggestPartDigits );
191206
192207 $ ipnSuggestions ['prefixesPartIncrement ' ][] = [
193- 'title ' => $ currentPath . ' - ' . $ increment ,
208+ 'title ' => $ currentPath . $ this -> ipnSuggestSettings -> numberSeparator . $ increment ,
194209 'description ' => $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.hierarchical.increment ' )
195210 ];
196211
@@ -199,7 +214,7 @@ public function autoCompleteIpn(Part $part, string $description, int $suggestPar
199214 }
200215 } elseif ($ part ->getID () === null ) {
201216 $ ipnSuggestions ['commonPrefixes ' ][] = [
202- 'title ' => ' n.a. ' ,
217+ 'title ' => $ this -> ipnSuggestSettings -> fallbackPrefix ,
203218 'description ' => $ this ->translator ->trans ('part.edit.tab.advanced.ipn.prefix.not_saved ' )
204219 ];
205220 }
@@ -246,6 +261,33 @@ public function getIpnSuggestByDescription(string $description): ?string
246261 return $ this ->getNextIpnSuggestion ($ givenIpnsWithSameDescription );
247262 }
248263
264+ private function generateNextPossibleGlobalIncrement (): string
265+ {
266+ $ qb = $ this ->createQueryBuilder ('part ' );
267+
268+
269+ $ qb ->select ('part.ipn ' )
270+ ->where ('REGEXP(part.ipn, :ipnPattern) = TRUE ' )
271+ ->setParameter ('ipnPattern ' , '^ ' . preg_quote ($ this ->ipnSuggestSettings ->globalPrefix , '/ ' ) . '\d+$ ' )
272+ ->orderBy ('NATSORT(part.ipn) ' , 'DESC ' )
273+ ->setMaxResults (1 )
274+ ;
275+
276+ $ highestIPN = $ qb ->getQuery ()->getOneOrNullResult ();
277+ if ($ highestIPN !== null ) {
278+ //Remove the prefix and extract the increment part
279+ $ incrementPart = substr ($ highestIPN ['ipn ' ], strlen ($ this ->ipnSuggestSettings ->globalPrefix ));
280+ //Extract a number using regex
281+ preg_match ('/(\d+)$/ ' , $ incrementPart , $ matches );
282+ $ incrementInt = isset ($ matches [1 ]) ? (int ) $ matches [1 ] + 1 : 0 ;
283+ } else {
284+ $ incrementInt = 1 ;
285+ }
286+
287+
288+ return str_pad ((string ) $ incrementInt , $ this ->ipnSuggestSettings ->suggestPartDigits , '0 ' , STR_PAD_LEFT );
289+ }
290+
249291 /**
250292 * Generates the next possible increment for a part within a given category, while ensuring uniqueness.
251293 *
@@ -266,7 +308,7 @@ private function generateNextPossiblePartIncrement(string $currentPath, Part $cu
266308 {
267309 $ qb = $ this ->createQueryBuilder ('part ' );
268310
269- $ expectedLength = strlen ($ currentPath ) + 1 + $ suggestPartDigits ; // Path + '-' + $suggestPartDigits digits
311+ $ expectedLength = strlen ($ currentPath ) + strlen ( $ this -> ipnSuggestSettings -> categorySeparator ) + $ suggestPartDigits ; // Path + '-' + $suggestPartDigits digits
270312
271313 // Fetch all parts in the given category, sorted by their ID in ascending order
272314 $ qb ->select ('part ' )
0 commit comments