001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 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.persistence.Session;
065import com.echothree.util.server.validation.ParameterUtils;
066import java.util.List;
067
068public class OfferItemLogic
069        extends BaseLogic {
070
071    private OfferItemLogic() {
072        super();
073    }
074
075    private static class OfferItemLogicHolder {
076        static OfferItemLogic instance = new OfferItemLogic();
077    }
078
079    public static OfferItemLogic getInstance() {
080        return OfferItemLogicHolder.instance;
081    }
082
083    // --------------------------------------------------------------------------------
084    //   Offer Items
085    // --------------------------------------------------------------------------------
086
087    // This one is intended to be used internally to ensure any dependent actions occur.
088    public OfferItem createOfferItem(final Offer offer, final Item item, final BasePK createdBy) {
089        var offerItemControl = Session.getModelController(OfferItemControl.class);
090
091        return offerItemControl.createOfferItem(offer, item, createdBy);
092    }
093
094    // This one is intended to be used by interactive users of the application to ensure all necessary
095    // validation occurs.
096    public OfferItem createOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
097        final BasePK createdBy) {
098        OfferItem offerItem = null;
099        final var offerDetail = offer.getLastDetail();
100
101        if(offerDetail.getOfferItemSelector() == null) {
102            var partyControl = Session.getModelController(PartyControl.class);
103            var partyDepartment = partyControl.getPartyDepartment(offerDetail.getDepartmentParty());
104            var partyDivision = partyControl.getPartyDivision(partyDepartment.getDivisionParty());
105            var partyCompany = partyControl.getPartyCompany(partyDivision.getCompanyParty());
106
107            if(partyCompany.getParty().equals(item.getLastDetail().getCompanyParty())) {
108                var offerItemControl = Session.getModelController(OfferItemControl.class);
109
110                offerItem = offerItemControl.getOfferItem(offer, item);
111
112                if(offerItem == null) {
113                    createOfferItem(offer, item, createdBy);
114                } else {
115                    handleExecutionError(DuplicateOfferItemException.class, eea, ExecutionErrors.DuplicateOfferItem.name(),
116                            offerDetail.getOfferName(), item.getLastDetail().getItemName());
117                }
118            } else {
119                handleExecutionError(InvalidItemCompanyException.class, eea, ExecutionErrors.InvalidItemCompany.name(),
120                        partyCompany.getPartyCompanyName(),
121                        partyControl.getPartyCompany(item.getLastDetail().getCompanyParty()).getPartyCompanyName());
122            }
123        } else {
124            handleExecutionError(CannotManuallyCreateOfferItemWhenOfferItemSelectorSetException.class, eea,
125                    ExecutionErrors.CannotManuallyCreateOfferItemWhenOfferItemSelectorSet.name(),
126                    offerDetail.getOfferName());
127        }
128
129        return offerItem;
130    }
131
132    public OfferItem getOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
133            final EntityPermission entityPermission) {
134        var offerItemControl = Session.getModelController(OfferItemControl.class);
135        var offerItem = offerItemControl.getOfferItem(offer, item, entityPermission);
136
137        if(offerItem == null) {
138            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
139                    offer.getLastDetail().getOfferName(), item.getLastDetail().getItemName());
140        }
141
142        return offerItem;
143    }
144
145    public OfferItem getOfferItem(final ExecutionErrorAccumulator eea, final Offer offer, final Item item) {
146        return getOfferItem(eea, offer, item, EntityPermission.READ_ONLY);
147    }
148
149    public OfferItem getOfferItemForUpdate(final ExecutionErrorAccumulator eea, final Offer offer, final Item item) {
150        return getOfferItem(eea, offer, item, EntityPermission.READ_WRITE);
151    }
152
153    public OfferItem getOfferItemByUniversalSpec(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec,
154            final EntityPermission entityPermission) {
155        var offerName = universalSpec.getOfferName();
156        var itemName = universalSpec.getItemName();
157        var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(offerName, itemName);
158        var possibleEntitySpecs= EntityInstanceLogic.getInstance().countPossibleEntitySpecs(universalSpec);
159        OfferItem offerItem = null;
160
161        if(nameParameterCount == 2 && possibleEntitySpecs == 0) {
162            var offer = OfferLogic.getInstance().getOfferByName(eea, offerName);
163            var item = ItemLogic.getInstance().getItemByName(eea, itemName);
164
165            if(!eea.hasExecutionErrors()) {
166                offerItem = getOfferItem(eea, offer, item);
167            }
168        } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) {
169            var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, universalSpec,
170                    ComponentVendors.ECHO_THREE.name(), EntityTypes.OfferItem.name());
171
172            if(!eea.hasExecutionErrors()) {
173                var offerItemControl = Session.getModelController(OfferItemControl.class);
174
175                offerItem = offerItemControl.getOfferItemByEntityInstance(entityInstance, entityPermission);
176            }
177        } else {
178            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
179        }
180
181        return offerItem;
182    }
183
184    public OfferItem getOfferItemByUniversalSpec(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec) {
185        return getOfferItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
186    }
187
188    public OfferItem getOfferItemByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final OfferItemUniversalSpec universalSpec) {
189        return getOfferItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
190    }
191
192    public void deleteOfferItem(final OfferItem offerItem, final BasePK deletedBy) {
193        var offerItemControl = Session.getModelController(OfferItemControl.class);
194
195        offerItemControl.deleteOfferItem(offerItem, deletedBy);
196    }
197
198    public void deleteOfferItem(final ExecutionErrorAccumulator eea, final OfferItem offerItem, final BasePK deletedBy) {
199        final var offerDetail = offerItem.getOffer().getLastDetail();
200
201        if(offerDetail.getOfferItemSelector() == null) {
202            deleteOfferItem(offerItem, deletedBy);
203        } else {
204            handleExecutionError(CannotManuallyDeleteOfferItemWhenOfferItemSelectorSetException.class, eea,
205                    ExecutionErrors.CannotManuallyDeleteOfferItemWhenOfferItemSelectorSet.name(),
206                    offerDetail.getOfferName());
207        }
208    }
209
210    public void deleteOfferItems(List<OfferItem> offerItems, BasePK deletedBy) {
211        offerItems.forEach((offerItem) -> 
212                deleteOfferItem(offerItem, deletedBy)
213        );
214    }
215
216    public void deleteOfferItemsByOffer(Offer offer, BasePK deletedBy) {
217        var offerItemControl = Session.getModelController(OfferItemControl.class);
218
219        deleteOfferItems(offerItemControl.getOfferItemsByOfferForUpdate(offer), deletedBy);
220    }
221
222    public void deleteOfferItemsByOffers(List<Offer> offers, BasePK deletedBy) {
223        offers.forEach((offer) -> 
224                deleteOfferItemsByOffer(offer, deletedBy)
225        );
226    }
227
228    // --------------------------------------------------------------------------------
229    //   Offer Item Prices
230    // --------------------------------------------------------------------------------
231
232    public OfferItemPrice createOfferItemPrice(final OfferItem offerItem, final InventoryCondition inventoryCondition,
233            final UnitOfMeasureType unitOfMeasureType, final Currency currency, final BasePK createdBy) {
234        var offerItemControl = Session.getModelController(OfferItemControl.class);
235
236        return offerItemControl.createOfferItemPrice(offerItem, inventoryCondition, unitOfMeasureType, currency, createdBy);
237    }
238
239    public void createOfferItemPrice(final ExecutionErrorAccumulator eea, final String offerName, final String itemName, final String inventoryConditionName,
240            final String unitOfMeasureTypeName, final String currencyIsoName, final String strUnitPrice, final String strMinimumUnitPrice,
241            final String strMaximumUnitPrice, final String strUnitPriceIncrement, final BasePK createdBy) {
242        var offer = OfferLogic.getInstance().getOfferByName(eea, offerName);
243
244        if(eea == null || !eea.hasExecutionErrors()) {
245            final var offerDetail = offer.getLastDetail();
246
247            if(offerDetail.getOfferItemPriceFilter() == null) {
248                var item = ItemLogic.getInstance().getItemByName(eea, itemName);
249                var inventoryCondition = InventoryConditionLogic.getInstance().getInventoryConditionByName(eea, inventoryConditionName);
250                var currency = CurrencyLogic.getInstance().getCurrencyByName(eea, currencyIsoName);
251
252                if(eea == null || !eea.hasExecutionErrors()) {
253                    var itemDetail = item.getLastDetail();
254                    var unitOfMeasureKind = itemDetail.getUnitOfMeasureKind();
255                    var unitOfMeasureType = UnitOfMeasureTypeLogic.getInstance().getUnitOfMeasureTypeByName(eea,
256                            unitOfMeasureKind, unitOfMeasureTypeName);
257
258                    if(eea == null || !eea.hasExecutionErrors()) {
259                        var offerItemControl = Session.getModelController(OfferItemControl.class);
260                        var offerItem = offerItemControl.getOfferItem(offer, item);
261
262                        if(offerItem != null) {
263                            var itemControl = Session.getModelController(ItemControl.class);
264                            var itemPrice = itemControl.getItemPrice(item, inventoryCondition, unitOfMeasureType, currency);
265
266                            if(itemPrice != null) {
267                                var offerItemPrice = offerItemControl.getOfferItemPrice(offerItem, inventoryCondition,
268                                        unitOfMeasureType, currency);
269
270                                if(offerItemPrice == null) {
271                                    var itemPriceTypeName = itemDetail.getItemPriceType().getItemPriceTypeName();
272
273                                    if(itemPriceTypeName.equals(ItemPriceTypes.FIXED.name())) {
274                                        if(strUnitPrice != null) {
275                                            var unitPrice = Long.valueOf(strUnitPrice);
276
277                                            offerItemPrice = OfferItemLogic.getInstance().createOfferItemPrice(offerItem, inventoryCondition,
278                                                    unitOfMeasureType, currency, createdBy);
279                                            OfferItemLogic.getInstance().createOfferItemFixedPrice(offerItemPrice, unitPrice, createdBy);
280                                        } else {
281                                            handleExecutionError(MissingUnitPriceException.class, eea, ExecutionErrors.MissingUnitPrice.name());
282                                        }
283                                    } else if(itemPriceTypeName.equals(ItemPriceTypes.VARIABLE.name())) {
284                                        Long minimumUnitPrice = null;
285                                        Long maximumUnitPrice = null;
286                                        Long unitPriceIncrement = null;
287
288                                        if(strMinimumUnitPrice != null) {
289                                            minimumUnitPrice = Long.valueOf(strMinimumUnitPrice);
290                                        } else {
291                                            handleExecutionError(MissingMinimumUnitPriceException.class, eea, ExecutionErrors.MissingMinimumUnitPrice.name());
292                                        }
293
294                                        if(strMaximumUnitPrice != null) {
295                                            maximumUnitPrice = Long.valueOf(strMaximumUnitPrice);
296                                        } else {
297                                            handleExecutionError(MissingMaximumUnitPriceException.class, eea, ExecutionErrors.MissingMaximumUnitPrice.name());
298                                        }
299
300                                        if(strUnitPriceIncrement != null) {
301                                            unitPriceIncrement = Long.valueOf(strUnitPriceIncrement);
302                                        } else {
303                                            handleExecutionError(MissingUnitPriceIncrementException.class, eea, ExecutionErrors.MissingUnitPriceIncrement.name());
304                                        }
305
306                                        if(minimumUnitPrice != null && maximumUnitPrice != null && unitPriceIncrement != null) {
307                                            offerItemPrice = OfferItemLogic.getInstance().createOfferItemPrice(offerItem, inventoryCondition,
308                                                    unitOfMeasureType, currency, createdBy);
309                                            OfferItemLogic.getInstance().createOfferItemVariablePrice(offerItemPrice, minimumUnitPrice, maximumUnitPrice,
310                                                    unitPriceIncrement, createdBy);
311                                        }
312                                    } else {
313                                        handleExecutionError(UnknownItemPriceTypeException.class, eea, ExecutionErrors.UnknownItemPriceType.name());
314                                    }
315                                } else {
316                                    handleExecutionError(DuplicateOfferItemPriceException.class, eea, ExecutionErrors.DuplicateOfferItemPrice.name());
317                                }
318                            } else {
319                                handleExecutionError(UnknownItemPriceException.class, eea, ExecutionErrors.UnknownItemPrice.name());
320                            }
321                        } else {
322                            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(), offerName, itemName);
323                        }
324                    }
325                }
326            } else {
327                handleExecutionError(CannotManuallyCreateOfferItemPriceWhenOfferItemPriceFilterSetException.class, eea,
328                        ExecutionErrors.CannotManuallyCreateOfferItemPriceWhenOfferItemPriceFilterSet.name(),
329                        offerDetail.getOfferName());
330            }
331        }
332    }
333
334    public OfferItemPrice getOfferItemPrice(final ExecutionErrorAccumulator eea, final Offer offer, final Item item,
335            final InventoryCondition inventoryCondition, final UnitOfMeasureType unitOfMeasureType, final Currency currency) {
336        var offerItemControl = Session.getModelController(OfferItemControl.class);
337        var offerItem = offerItemControl.getOfferItem(offer, item);
338        OfferItemPrice offerItemPrice = null;
339
340        if(offerItem != null) {
341            offerItemPrice = offerItemControl.getOfferItemPrice(offerItem, inventoryCondition, unitOfMeasureType, currency);
342
343            if(offerItemPrice == null) {
344                handleExecutionError(UnknownOfferItemPriceException.class, eea, ExecutionErrors.UnknownOfferItemPrice.name(), offer.getLastDetail().getOfferName(),
345                        item.getLastDetail().getItemName(), inventoryCondition.getLastDetail().getInventoryConditionName(),
346                        unitOfMeasureType.getLastDetail().getUnitOfMeasureTypeName(), currency.getCurrencyIsoName());
347            }
348        } else {
349            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
350                    offer.getLastDetail().getOfferName(), item.getLastDetail().getItemName());
351        }
352
353        return offerItemPrice;
354    }
355
356    // This one is intended to be used internally to ensure any dependent actions occur.
357    public void deleteOfferItemPrice(final OfferItemPrice offerItemPrice, final BasePK deletedBy) {
358        var offerItemControl = Session.getModelController(OfferItemControl.class);
359        var offerItem = offerItemPrice.getOfferItemForUpdate();
360        var item = offerItem.getItem();
361
362        ContentLogic.getInstance().deleteContentCategoryItemByOfferItemPrice(offerItemPrice, deletedBy);
363
364        offerItemControl.deleteOfferItemPrice(offerItemPrice, deletedBy);
365
366        // If all OfferItemPrices have been deleted, delete the OfferItem as well.
367        if(offerItemControl.countOfferItemPricesByItem(item) == 0) {
368            deleteOfferItem(offerItem, deletedBy);
369        }
370    }
371
372    // This one is intended to be used by interactive users of the application to ensure all necessary
373    // validation occurs.
374    public void deleteOfferItemPrice(final ExecutionErrorAccumulator eea, final String offerName, final String itemName,
375            final String inventoryConditionName, final String unitOfMeasureTypeName, final String currencyIsoName,
376            final BasePK deletedBy) {
377        var offer = OfferLogic.getInstance().getOfferByName(eea, offerName);
378
379        if(eea == null || !eea.hasExecutionErrors()) {
380            final var offerDetail = offer.getLastDetail();
381
382            if(offerDetail.getOfferItemPriceFilter() == null) {
383                var item = ItemLogic.getInstance().getItemByName(eea, itemName);
384                var inventoryCondition = InventoryConditionLogic.getInstance().getInventoryConditionByName(eea, inventoryConditionName);
385                var currency = CurrencyLogic.getInstance().getCurrencyByName(eea, currencyIsoName);
386
387                if(eea == null || !eea.hasExecutionErrors()) {
388                    var unitOfMeasureKind = item.getLastDetail().getUnitOfMeasureKind();
389                    var unitOfMeasureType = UnitOfMeasureTypeLogic.getInstance().getUnitOfMeasureTypeByName(eea,
390                            unitOfMeasureKind, unitOfMeasureTypeName);
391
392                    if(eea == null || !eea.hasExecutionErrors()) {
393                        var offerItemControl = Session.getModelController(OfferItemControl.class);
394                        var offerItem = offerItemControl.getOfferItem(offer, item);
395
396                        if(offerItem != null) {
397                            var offerItemPrice = offerItemControl.getOfferItemPriceForUpdate(offerItem, inventoryCondition,
398                                    unitOfMeasureType, currency);
399
400                            if(offerItemPrice != null) {
401                                deleteOfferItemPrice(offerItemPrice, deletedBy);
402                            } else {
403                                handleExecutionError(UnknownOfferItemPriceException.class, eea, ExecutionErrors.UnknownOfferItemPrice.name(),
404                                        offerName, itemName, inventoryConditionName, unitOfMeasureTypeName, currencyIsoName);
405                            }
406                        } else {
407                            handleExecutionError(UnknownOfferItemException.class, eea, ExecutionErrors.UnknownOfferItem.name(),
408                                    offerName, itemName);
409                        }
410                    }
411                }
412            } else {
413                handleExecutionError(CannotManuallyDeleteOfferItemPriceWhenOfferItemPriceFilterSetException.class, eea,
414                        ExecutionErrors.CannotManuallyDeleteOfferItemPriceWhenOfferItemPriceFilterSet.name(),
415                        offerDetail.getOfferName());
416            }
417        }
418    }
419
420    public void deleteOfferItemPrices(List<OfferItemPrice> offerItemPrices, BasePK deletedBy) {
421        offerItemPrices.forEach((offerItemPrice) -> 
422                deleteOfferItemPrice(offerItemPrice, deletedBy)
423        );
424    }
425
426    public void deleteOfferItemPricesByOfferItem(OfferItem offerItem, BasePK deletedBy) {
427        var offerItemControl = Session.getModelController(OfferItemControl.class);
428
429        deleteOfferItemPrices(offerItemControl.getOfferItemPricesByOfferItemForUpdate(offerItem), deletedBy);
430    }
431
432    public void deleteOfferItemPricesByItemAndUnitOfMeasureType(Item item, UnitOfMeasureType unitOfMeasureType, BasePK deletedBy) {
433        var offerItemControl = Session.getModelController(OfferItemControl.class);
434
435        deleteOfferItemPrices(offerItemControl.getOfferItemPricesByItemAndUnitOfMeasureTypeForUpdate(item, unitOfMeasureType), deletedBy);
436    }
437
438    // --------------------------------------------------------------------------------
439    //   Offer Item Fixed Prices
440    // --------------------------------------------------------------------------------
441
442    public OfferItemFixedPrice createOfferItemFixedPrice(final OfferItemPrice offerItemPrice, final Long unitPrice, final BasePK createdBy) {
443        var offerItemControl = Session.getModelController(OfferItemControl.class);
444
445        return offerItemControl.createOfferItemFixedPrice(offerItemPrice, unitPrice, createdBy);
446    }
447
448    public void updateOfferItemFixedPriceFromValue(final OfferItemFixedPriceValue offerItemFixedPriceValue, final BasePK updatedBy) {
449        var offerItemControl = Session.getModelController(OfferItemControl.class);
450        var offerItemFixedPrice = offerItemControl.updateOfferItemFixedPriceFromValue(offerItemFixedPriceValue, updatedBy);
451
452        if(offerItemFixedPrice != null) {
453            ContentLogic.getInstance().updateContentCatalogItemPricesByOfferItemPrice(offerItemFixedPrice.getOfferItemPrice(), updatedBy);
454        }
455    }
456
457    // --------------------------------------------------------------------------------
458    //   Offer Item Variable Prices
459    // --------------------------------------------------------------------------------
460
461    public OfferItemVariablePrice createOfferItemVariablePrice(final OfferItemPrice offerItemPrice, final Long minimumUnitPrice,
462            final Long maximumUnitPrice, final Long unitPriceIncrement, final BasePK createdBy) {
463        var offerItemControl = Session.getModelController(OfferItemControl.class);
464
465        return offerItemControl.createOfferItemVariablePrice(offerItemPrice, minimumUnitPrice, maximumUnitPrice, unitPriceIncrement, createdBy);
466    }
467
468    public void updateOfferItemVariablePriceFromValue(final OfferItemVariablePriceValue offerItemVariablePriceValue, final BasePK updatedBy) {
469        var offerItemControl = Session.getModelController(OfferItemControl.class);
470        var offerItemVariablePrice = offerItemControl.updateOfferItemVariablePriceFromValue(offerItemVariablePriceValue, updatedBy);
471
472        if(offerItemVariablePrice != null) {
473            ContentLogic.getInstance().updateContentCatalogItemPricesByOfferItemPrice(offerItemVariablePrice.getOfferItemPrice(), updatedBy);
474        }
475    }
476
477}