001// --------------------------------------------------------------------------------
002// Copyright 2002-2026 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.offer.server.logic;
018
019import com.echothree.control.user.offer.common.spec.OfferItemUniversalSpec;
020import com.echothree.model.control.accounting.server.logic.CurrencyLogic;
021import com.echothree.model.control.content.server.logic.ContentLogic;
022import com.echothree.model.control.core.common.ComponentVendors;
023import com.echothree.model.control.core.common.EntityTypes;
024import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
025import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
026import com.echothree.model.control.inventory.server.logic.InventoryConditionLogic;
027import com.echothree.model.control.item.common.ItemPriceTypes;
028import com.echothree.model.control.item.common.exception.MissingMaximumUnitPriceException;
029import com.echothree.model.control.item.common.exception.MissingMinimumUnitPriceException;
030import com.echothree.model.control.item.common.exception.MissingUnitPriceException;
031import com.echothree.model.control.item.common.exception.MissingUnitPriceIncrementException;
032import com.echothree.model.control.item.common.exception.UnknownItemPriceException;
033import com.echothree.model.control.item.common.exception.UnknownItemPriceTypeException;
034import com.echothree.model.control.item.server.control.ItemControl;
035import com.echothree.model.control.item.server.logic.ItemLogic;
036import com.echothree.model.control.offer.common.exception.CannotManuallyCreateOfferItemPriceWhenOfferItemPriceFilterSetException;
037import com.echothree.model.control.offer.common.exception.CannotManuallyCreateOfferItemWhenOfferItemSelectorSetException;
038import com.echothree.model.control.offer.common.exception.CannotManuallyDeleteOfferItemPriceWhenOfferItemPriceFilterSetException;
039import com.echothree.model.control.offer.common.exception.CannotManuallyDeleteOfferItemWhenOfferItemSelectorSetException;
040import com.echothree.model.control.offer.common.exception.DuplicateOfferItemException;
041import com.echothree.model.control.offer.common.exception.DuplicateOfferItemPriceException;
042import com.echothree.model.control.offer.common.exception.InvalidItemCompanyException;
043import com.echothree.model.control.offer.common.exception.UnknownOfferItemException;
044import com.echothree.model.control.offer.common.exception.UnknownOfferItemPriceException;
045import com.echothree.model.control.offer.server.control.OfferItemControl;
046import com.echothree.model.control.party.server.control.PartyControl;
047import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic;
048import com.echothree.model.data.accounting.server.entity.Currency;
049import com.echothree.model.data.inventory.server.entity.InventoryCondition;
050import com.echothree.model.data.item.server.entity.Item;
051import com.echothree.model.data.offer.server.entity.Offer;
052import com.echothree.model.data.offer.server.entity.OfferItem;
053import com.echothree.model.data.offer.server.entity.OfferItemFixedPrice;
054import com.echothree.model.data.offer.server.entity.OfferItemPrice;
055import com.echothree.model.data.offer.server.entity.OfferItemVariablePrice;
056import com.echothree.model.data.offer.server.value.OfferItemFixedPriceValue;
057import com.echothree.model.data.offer.server.value.OfferItemVariablePriceValue;
058import com.echothree.model.data.uom.server.entity.UnitOfMeasureType;
059import com.echothree.util.common.message.ExecutionErrors;
060import com.echothree.util.common.persistence.BasePK;
061import com.echothree.util.server.control.BaseLogic;
062import com.echothree.util.server.message.ExecutionErrorAccumulator;
063import com.echothree.util.server.persistence.EntityPermission;
064import com.echothree.util.server.validation.ParameterUtils;
065import java.util.List;
066import javax.enterprise.context.ApplicationScoped;
067import javax.enterprise.inject.spi.CDI;
068import javax.inject.Inject;
069
070@ApplicationScoped
071public class OfferItemLogic
072        extends BaseLogic {
073
074    @Inject
075    ItemControl itemControl;
076
077    @Inject
078    OfferItemControl offerItemControl;
079
080    @Inject
081    PartyControl partyControl;
082
083    @Inject
084    ContentLogic contentLogic;
085
086    @Inject
087    CurrencyLogic currencyLogic;
088
089    @Inject
090    EntityInstanceLogic entityInstanceLogic;
091
092    @Inject
093    InventoryConditionLogic inventoryConditionLogic;
094
095    @Inject
096    ItemLogic itemLogic;
097
098    @Inject
099    OfferLogic offerLogic;
100
101    @Inject
102    UnitOfMeasureTypeLogic unitOfMeasureTypeLogic;
103
104    protected OfferItemLogic() {
105        super();
106    }
107
108    public static OfferItemLogic getInstance() {
109        return CDI.current().select(OfferItemLogic.class).get();
110    }
111
112    // --------------------------------------------------------------------------------
113    //   Offer Items
114    // --------------------------------------------------------------------------------
115
116    // This one is intended to be used internally to ensure any dependent actions occur.
117    public OfferItem createOfferItem(final Offer offer, final Item item, final BasePK createdBy) {
118        return offerItemControl.createOfferItem(offer, item, createdBy);
119    }
120
121    // This one is intended to be used by interactive users of the application to ensure all necessary
122    // validation occurs.
123    public OfferItem createOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
124        final BasePK createdBy) {
125        OfferItem offerItem = null;
126        final var offerDetail = offer.getLastDetail();
127
128        if(offerDetail.getOfferItemSelector() == null) {
129            var partyDepartment = partyControl.getPartyDepartment(offerDetail.getDepartmentParty());
130            var partyDivision = partyControl.getPartyDivision(partyDepartment.getDivisionParty());
131            var partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty());
132
133            if(partyCompany.getParty().equals(item.getLastDetail().getCompanyParty())) {
134                offerItem = offerItemControl.getOfferItem(offer, item);
135
136                if(offerItem == null) {
137                    offerItem = createOfferItem(offer, item, createdBy);
138                } else {
139                    handleExecutionError(DuplicateOfferItemException.class, eea, ExecutionErrors.DuplicateOfferItem.name(),
140                            offerDetail.getOfferName(), item.getLastDetail().getItemName());
141                }
142            } else {
143                handleExecutionError(InvalidItemCompanyException.class, eea, ExecutionErrors.InvalidItemCompany.name(),
144                        partyCompany.getPartyCompanyName(),
145                        partyControl.getPartyCompany(item.getLastDetail().getCompanyParty()).getPartyCompanyName());
146            }
147        } else {
148            handleExecutionError(CannotManuallyCreateOfferItemWhenOfferItemSelectorSetException.class, eea,
149                    ExecutionErrors.CannotManuallyCreateOfferItemWhenOfferItemSelectorSet.name(),
150                    offerDetail.getOfferName());
151        }
152
153        return offerItem;
154    }
155
156    public OfferItem getOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
157            final EntityPermission entityPermission) {
158        var offerItem = offerItemControl.getOfferItem(offer, item, entityPermission);
159
160        if(offerItem == null) {
161            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
162                    offer.getLastDetail().getOfferName(), item.getLastDetail().getItemName());
163        }
164
165        return offerItem;
166    }
167
168    public OfferItem getOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item) {
169        return getOfferItem(eea, offer, item, EntityPermission.READ_ONLY);
170    }
171
172    public OfferItem getOfferItemForUpdate(final ExecutionErrorAccumulator eea, final Offer offer, final Item item) {
173        return getOfferItem(eea, offer, item, EntityPermission.READ_WRITE);
174    }
175
176    public OfferItem getOfferItemByUniversalSpec(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec,
177            final EntityPermission entityPermission) {
178        var offerName = universalSpec.getOfferName();
179        var itemName = universalSpec.getItemName();
180        var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(offerName, itemName);
181        var possibleEntitySpecs= entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
182        OfferItem offerItem = null;
183
184        if(nameParameterCount == 2 && possibleEntitySpecs == 0) {
185            var offer = offerLogic.getOfferByName(eea, offerName);
186            var item = itemLogic.getItemByName(eea, itemName);
187
188            if(eea == null || !eea.hasExecutionErrors()) {
189                offerItem = getOfferItem(eea, offer, item);
190            }
191        } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) {
192            var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
193                    ComponentVendors.ECHO_THREE.name(), EntityTypes.OfferItem.name());
194
195            if(eea == null || !eea.hasExecutionErrors()) {
196                offerItem = offerItemControl.getOfferItemByEntityInstance(entityInstance, entityPermission);
197            }
198        } else {
199            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
200        }
201
202        return offerItem;
203    }
204
205    public OfferItem getOfferItemByUniversalSpec(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec) {
206        return getOfferItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
207    }
208
209    public OfferItem getOfferItemByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec) {
210        return getOfferItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
211    }
212
213    public void deleteOfferItem(final OfferItem offerItem, final BasePK deletedBy) {
214        offerItemControl.deleteOfferItem(offerItem, deletedBy);
215    }
216
217    public void deleteOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item, final BasePK deletedBy) {
218        var offerDetail = offer.getLastDetail();
219
220        if(offerDetail.getOfferItemSelector() == null) {
221            var offerItem = getOfferItemForUpdate(eea, offer, item);
222
223            if(!hasExecutionErrors(eea)) {
224                deleteOfferItem(offerItem, deletedBy);
225            }
226        } else {
227            handleExecutionError(CannotManuallyDeleteOfferItemWhenOfferItemSelectorSetException.class, eea,
228                    ExecutionErrors.CannotManuallyDeleteOfferItemWhenOfferItemSelectorSet.name(), offerDetail.getOfferName());
229        }
230    }
231
232    public void deleteOfferItem(final ExecutionErrorAccumulator eea, final OfferItem offerItem, final BasePK deletedBy) {
233        final var offerDetail = offerItem.getOffer().getLastDetail();
234
235        if(offerDetail.getOfferItemSelector() == null) {
236            deleteOfferItem(offerItem, deletedBy);
237        } else {
238            handleExecutionError(CannotManuallyDeleteOfferItemWhenOfferItemSelectorSetException.class, eea,
239                    ExecutionErrors.CannotManuallyDeleteOfferItemWhenOfferItemSelectorSet.name(),
240                    offerDetail.getOfferName());
241        }
242    }
243
244    public void deleteOfferItems(List<OfferItem> offerItems, BasePK deletedBy) {
245        offerItems.forEach((offerItem) -> 
246                deleteOfferItem(offerItem, deletedBy)
247        );
248    }
249
250    public void deleteOfferItemsByOffer(Offer offer, BasePK deletedBy) {
251        deleteOfferItems(offerItemControl.getOfferItemsByOfferForUpdate(offer), deletedBy);
252    }
253
254    public void deleteOfferItemsByOffers(List<Offer> offers, BasePK deletedBy) {
255        offers.forEach((offer) -> 
256                deleteOfferItemsByOffer(offer, deletedBy)
257        );
258    }
259
260    // --------------------------------------------------------------------------------
261    //   Offer Item Prices
262    // --------------------------------------------------------------------------------
263
264    public OfferItemPrice createOfferItemPrice(final OfferItem offerItem, final InventoryCondition inventoryCondition,
265            final UnitOfMeasureType unitOfMeasureType, final Currency currency, final BasePK createdBy) {
266        return offerItemControl.createOfferItemPrice(offerItem, inventoryCondition, unitOfMeasureType, currency, createdBy);
267    }
268
269    public void createOfferItemPrice(final ExecutionErrorAccumulator eea, final String offerName, final String itemName, final String inventoryConditionName,
270            final String unitOfMeasureTypeName, final String currencyIsoName, final String strUnitPrice, final String strMinimumUnitPrice,
271            final String strMaximumUnitPrice, final String strUnitPriceIncrement, final BasePK createdBy) {
272        var offer = offerLogic.getOfferByName(eea, offerName);
273
274        if(eea == null || !eea.hasExecutionErrors()) {
275            final var offerDetail = offer.getLastDetail();
276
277            if(offerDetail.getOfferItemPriceFilter() == null) {
278                var item = itemLogic.getItemByName(eea, itemName);
279                var inventoryCondition = inventoryConditionLogic.getInventoryConditionByName(eea, inventoryConditionName);
280                var currency = currencyLogic.getCurrencyByName(eea, currencyIsoName);
281
282                if(eea == null || !eea.hasExecutionErrors()) {
283                    var itemDetail = item.getLastDetail();
284                    var unitOfMeasureKind = itemDetail.getUnitOfMeasureKind();
285                    var unitOfMeasureType = unitOfMeasureTypeLogic.getUnitOfMeasureTypeByName(eea,
286                            unitOfMeasureKind, unitOfMeasureTypeName);
287
288                    if(eea == null || !eea.hasExecutionErrors()) {
289                        var offerItem = offerItemControl.getOfferItem(offer, item);
290
291                        if(offerItem != null) {
292                            var itemPrice = itemControl.getItemPrice(item, inventoryCondition, unitOfMeasureType, currency);
293
294                            if(itemPrice != null) {
295                                var offerItemPrice = offerItemControl.getOfferItemPrice(offerItem, inventoryCondition,
296                                        unitOfMeasureType, currency);
297
298                                if(offerItemPrice == null) {
299                                    var itemPriceTypeName = itemDetail.getItemPriceType().getItemPriceTypeName();
300
301                                    if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) {
302                                        if(strUnitPrice != null) {
303                                            var unitPrice = Long.valueOf(strUnitPrice);
304
305                                            offerItemPrice = this.createOfferItemPrice(offerItem, inventoryCondition,
306                                                    unitOfMeasureType, currency, createdBy);
307                                            this.createOfferItemFixedPrice(offerItemPrice, unitPrice, createdBy);
308                                        } else {
309                                            handleExecutionError(MissingUnitPriceException.class, eea, ExecutionErrors.MissingUnitPrice.name());
310                                        }
311                                    } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) {
312                                        Long minimumUnitPrice = null;
313                                        Long maximumUnitPrice = null;
314                                        Long unitPriceIncrement = null;
315
316                                        if(strMinimumUnitPrice != null) {
317                                            minimumUnitPrice = Long.valueOf(strMinimumUnitPrice);
318                                        } else {
319                                            handleExecutionError(MissingMinimumUnitPriceException.class, eea, ExecutionErrors.MissingMinimumUnitPrice.name());
320                                        }
321
322                                        if(strMaximumUnitPrice != null) {
323                                            maximumUnitPrice = Long.valueOf(strMaximumUnitPrice);
324                                        } else {
325                                            handleExecutionError(MissingMaximumUnitPriceException.class, eea, ExecutionErrors.MissingMaximumUnitPrice.name());
326                                        }
327
328                                        if(strUnitPriceIncrement != null) {
329                                            unitPriceIncrement = Long.valueOf(strUnitPriceIncrement);
330                                        } else {
331                                            handleExecutionError(MissingUnitPriceIncrementException.class, eea, ExecutionErrors.MissingUnitPriceIncrement.name());
332                                        }
333
334                                        if(minimumUnitPrice != null && maximumUnitPrice != null && unitPriceIncrement != null) {
335                                            offerItemPrice = this.createOfferItemPrice(offerItem, inventoryCondition,
336                                                    unitOfMeasureType, currency, createdBy);
337                                            this.createOfferItemVariablePrice(offerItemPrice, minimumUnitPrice, maximumUnitPrice,
338                                                    unitPriceIncrement, createdBy);
339                                        }
340                                    } else {
341                                        handleExecutionError(UnknownItemPriceTypeException.class, eea, ExecutionErrors.UnknownItemPriceType.name());
342                                    }
343                                } else {
344                                    handleExecutionError(DuplicateOfferItemPriceException.class, eea, ExecutionErrors.DuplicateOfferItemPrice.name());
345                                }
346                            } else {
347                                handleExecutionError(UnknownItemPriceException.class, eea, ExecutionErrors.UnknownItemPrice.name());
348                            }
349                        } else {
350                            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(), offerName, itemName);
351                        }
352                    }
353                }
354            } else {
355                handleExecutionError(CannotManuallyCreateOfferItemPriceWhenOfferItemPriceFilterSetException.class, eea,
356                        ExecutionErrors.CannotManuallyCreateOfferItemPriceWhenOfferItemPriceFilterSet.name(),
357                        offerDetail.getOfferName());
358            }
359        }
360    }
361
362    public OfferItemPrice getOfferItemPrice(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
363            final InventoryCondition inventoryCondition, final UnitOfMeasureType unitOfMeasureType, final Currency currency) {
364        var offerItem = offerItemControl.getOfferItem(offer, item);
365        OfferItemPrice offerItemPrice = null;
366
367        if(offerItem != null) {
368            offerItemPrice = offerItemControl.getOfferItemPrice(offerItem, inventoryCondition, unitOfMeasureType, currency);
369
370            if(offerItemPrice == null) {
371                handleExecutionError(UnknownOfferItemPriceException.class, eea, ExecutionErrors.UnknownOfferItemPrice.name(), offer.getLastDetail().getOfferName(),
372                        item.getLastDetail().getItemName(), inventoryCondition.getLastDetail().getInventoryConditionName(),
373                        unitOfMeasureType.getLastDetail().getUnitOfMeasureTypeName(), currency.getCurrencyIsoName());
374            }
375        } else {
376            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
377                    offer.getLastDetail().getOfferName(), item.getLastDetail().getItemName());
378        }
379
380        return offerItemPrice;
381    }
382
383    // This one is intended to be used internally to ensure any dependent actions occur.
384    public void deleteOfferItemPrice(final OfferItemPrice offerItemPrice, final BasePK deletedBy) {
385        var offerItem = offerItemPrice.getOfferItemForUpdate();
386        var item = offerItem.getItem();
387
388        contentLogic.deleteContentCategoryItemByOfferItemPrice(offerItemPrice, deletedBy);
389
390        offerItemControl.deleteOfferItemPrice(offerItemPrice, deletedBy);
391
392        // If all OfferItemPrices have been deleted, delete the OfferItem as well.
393        if(offerItemControl.countOfferItemPricesByItem(item) == 0) {
394            deleteOfferItem(offerItem, deletedBy);
395        }
396    }
397
398    // This one is intended to be used by interactive users of the application to ensure all necessary
399    // validation occurs.
400    public void deleteOfferItemPrice(final ExecutionErrorAccumulator eea, final String offerName, final String itemName,
401            final String inventoryConditionName, final String unitOfMeasureTypeName, final String currencyIsoName,
402            final BasePK deletedBy) {
403        var offer = offerLogic.getOfferByName(eea, offerName);
404
405        if(eea == null || !eea.hasExecutionErrors()) {
406            final var offerDetail = offer.getLastDetail();
407
408            if(offerDetail.getOfferItemPriceFilter() == null) {
409                var item = itemLogic.getItemByName(eea, itemName);
410                var inventoryCondition = inventoryConditionLogic.getInventoryConditionByName(eea, inventoryConditionName);
411                var currency = currencyLogic.getCurrencyByName(eea, currencyIsoName);
412
413                if(eea == null || !eea.hasExecutionErrors()) {
414                    var unitOfMeasureKind = item.getLastDetail().getUnitOfMeasureKind();
415                    var unitOfMeasureType = unitOfMeasureTypeLogic.getUnitOfMeasureTypeByName(eea,
416                            unitOfMeasureKind, unitOfMeasureTypeName);
417
418                    if(eea == null || !eea.hasExecutionErrors()) {
419                        var offerItem = offerItemControl.getOfferItem(offer, item);
420
421                        if(offerItem != null) {
422                            var offerItemPrice = offerItemControl.getOfferItemPriceForUpdate(offerItem, inventoryCondition,
423                                    unitOfMeasureType, currency);
424
425                            if(offerItemPrice != null) {
426                                deleteOfferItemPrice(offerItemPrice, deletedBy);
427                            } else {
428                                handleExecutionError(UnknownOfferItemPriceException.class, eea, ExecutionErrors.UnknownOfferItemPrice.name(),
429                                        offerName, itemName, inventoryConditionName, unitOfMeasureTypeName, currencyIsoName);
430                            }
431                        } else {
432                            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
433                                    offerName, itemName);
434                        }
435                    }
436                }
437            } else {
438                handleExecutionError(CannotManuallyDeleteOfferItemPriceWhenOfferItemPriceFilterSetException.class, eea,
439                        ExecutionErrors.CannotManuallyDeleteOfferItemPriceWhenOfferItemPriceFilterSet.name(),
440                        offerDetail.getOfferName());
441            }
442        }
443    }
444
445    public void deleteOfferItemPrices(List<OfferItemPrice> offerItemPrices, BasePK deletedBy) {
446        offerItemPrices.forEach((offerItemPrice) -> 
447                deleteOfferItemPrice(offerItemPrice, deletedBy)
448        );
449    }
450
451    public void deleteOfferItemPricesByOfferItem(OfferItem offerItem, BasePK deletedBy) {
452        deleteOfferItemPrices(offerItemControl.getOfferItemPricesByOfferItemForUpdate(offerItem), deletedBy);
453    }
454
455    public void deleteOfferItemPricesByItemAndUnitOfMeasureType(Item item, UnitOfMeasureType unitOfMeasureType, BasePK deletedBy) {
456        deleteOfferItemPrices(offerItemControl.getOfferItemPricesByItemAndUnitOfMeasureTypeForUpdate(item, unitOfMeasureType), deletedBy);
457    }
458
459    // --------------------------------------------------------------------------------
460    //   Offer Item Fixed Prices
461    // --------------------------------------------------------------------------------
462
463    public OfferItemFixedPrice createOfferItemFixedPrice(final OfferItemPrice offerItemPrice, final Long unitPrice, final BasePK createdBy) {
464        return offerItemControl.createOfferItemFixedPrice(offerItemPrice, unitPrice, createdBy);
465    }
466
467    public void updateOfferItemFixedPriceFromValue(final OfferItemFixedPriceValue offerItemFixedPriceValue, final BasePK updatedBy) {
468        var offerItemFixedPrice = offerItemControl.updateOfferItemFixedPriceFromValue(offerItemFixedPriceValue, updatedBy);
469
470        if(offerItemFixedPrice != null) {
471            contentLogic.updateContentCatalogItemPricesByOfferItemPrice(offerItemFixedPrice.getOfferItemPrice(), updatedBy);
472        }
473    }
474
475    // --------------------------------------------------------------------------------
476    //   Offer Item Variable Prices
477    // --------------------------------------------------------------------------------
478
479    public OfferItemVariablePrice createOfferItemVariablePrice(final OfferItemPrice offerItemPrice, final Long minimumUnitPrice,
480            final Long maximumUnitPrice, final Long unitPriceIncrement, final BasePK createdBy) {
481        return offerItemControl.createOfferItemVariablePrice(offerItemPrice, minimumUnitPrice, maximumUnitPrice, unitPriceIncrement, createdBy);
482    }
483
484    public void updateOfferItemVariablePriceFromValue(final OfferItemVariablePriceValue offerItemVariablePriceValue, final BasePK updatedBy) {
485        var offerItemVariablePrice = offerItemControl.updateOfferItemVariablePriceFromValue(offerItemVariablePriceValue, updatedBy);
486
487        if(offerItemVariablePrice != null) {
488            contentLogic.updateContentCatalogItemPricesByOfferItemPrice(offerItemVariablePrice.getOfferItemPrice(), updatedBy);
489        }
490    }
491
492}