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.order.server.logic; 018 019import com.echothree.model.control.order.common.exception.DuplicateOrderLineSequenceException; 020import com.echothree.model.control.order.common.exception.UnknownOrderLineSequenceException; 021import com.echothree.model.control.order.server.control.OrderAdjustmentControl; 022import com.echothree.model.control.order.server.control.OrderControl; 023import com.echothree.model.control.order.server.control.OrderLineAdjustmentControl; 024import com.echothree.model.control.order.server.control.OrderLineControl; 025import com.echothree.model.data.cancellationpolicy.server.entity.CancellationPolicy; 026import com.echothree.model.data.inventory.server.entity.InventoryCondition; 027import com.echothree.model.data.item.server.entity.Item; 028import com.echothree.model.data.order.server.entity.Order; 029import com.echothree.model.data.order.server.entity.OrderLine; 030import com.echothree.model.data.order.server.entity.OrderShipmentGroup; 031import com.echothree.model.data.returnpolicy.server.entity.ReturnPolicy; 032import com.echothree.model.data.uom.server.entity.UnitOfMeasureType; 033import com.echothree.util.common.message.ExecutionErrors; 034import com.echothree.util.common.persistence.BasePK; 035import com.echothree.util.server.control.BaseLogic; 036import com.echothree.util.server.message.ExecutionErrorAccumulator; 037import com.echothree.util.server.persistence.EntityPermission; 038import com.echothree.util.server.persistence.Session; 039import javax.inject.Inject; 040 041public class BaseOrderLineLogic 042 extends BaseLogic { 043 044 @Inject 045 OrderAdjustmentControl orderAdjustmentControl; 046 047 @Inject 048 OrderControl orderControl; 049 050 @Inject 051 OrderLineAdjustmentControl orderLineAdjustmentControl; 052 053 @Inject 054 OrderLineControl orderLineControl; 055 056 @Inject 057 OrderLogic orderLogic; 058 059 protected BaseOrderLineLogic() { 060 super(); 061 } 062 063 public OrderLine createOrderLine(final Session session, final ExecutionErrorAccumulator eea, final Order order, Integer orderLineSequence, 064 final OrderLine parentOrderLine, final OrderShipmentGroup orderShipmentGroup, final Item item, final InventoryCondition inventoryCondition, 065 final UnitOfMeasureType unitOfMeasureType, final Long quantity, final Long unitAmount, final String description, 066 final CancellationPolicy cancellationPolicy, final ReturnPolicy returnPolicy, final Boolean taxable, final BasePK createdBy) { 067 OrderLine orderLine = null; 068 069 // Make sure any OrderPaymentPreferences associated with this order are OK with this Item. 070 orderLogic.checkItemAgainstOrderPaymentPreferences(session, eea, order, item, createdBy); 071 072 if(orderShipmentGroup != null) { 073 // Make sure the ShippingMethod associated with the OrderShipmentGroup is OK with this Item. 074 orderLogic.checkItemAgainstShippingMethod(session, eea, orderShipmentGroup, item, createdBy); 075 } 076 077 if(eea == null || !eea.hasExecutionErrors()) { 078 var orderStatus = orderControl.getOrderStatusForUpdate(order); 079 080 if(orderLineSequence == null) { 081 orderLineSequence = orderStatus.getOrderLineSequence() + 1; 082 orderStatus.setOrderLineSequence(orderLineSequence); 083 } else { 084 orderLine = orderLineControl.getOrderLineBySequence(order, orderLineSequence); 085 086 if(orderLine == null) { 087 // If the orderLineSequence is > the last one that was recorded in the OrderStatus, jump the 088 // one in OrderStatus forward - it should always record the greatest orderLineSequence used. 089 if(orderLineSequence > orderStatus.getOrderLineSequence()) { 090 orderStatus.setOrderLineSequence(orderLineSequence); 091 } 092 } else { 093 handleExecutionError(DuplicateOrderLineSequenceException.class, eea, ExecutionErrors.DuplicateOrderLineSequence.name(), 094 order.getLastDetail().getOrderName(), orderLineSequence.toString()); 095 } 096 } 097 098 if(orderLine == null) { 099 orderLine = orderLineControl.createOrderLine(order, orderLineSequence, parentOrderLine, orderShipmentGroup, item, inventoryCondition, 100 unitOfMeasureType, quantity, unitAmount, description, cancellationPolicy, returnPolicy, taxable, createdBy); 101 } 102 } 103 104 return orderLine; 105 } 106 107 private OrderLine getOrderLineByName(final ExecutionErrorAccumulator eea, final String orderTypeName, final String orderName, final String orderLineSequence, 108 final EntityPermission entityPermission) { 109 var order = orderLogic.getOrderByName(eea, orderTypeName, orderName); 110 OrderLine orderLine = null; 111 112 if(eea == null || !eea.hasExecutionErrors()) { 113 orderLine = orderLineControl.getOrderLineBySequence(order, Integer.valueOf(orderLineSequence), entityPermission); 114 115 if(orderLine == null) { 116 handleExecutionError(UnknownOrderLineSequenceException.class, eea, ExecutionErrors.UnknownOrderLineSequence.name(), orderTypeName, orderName, orderLineSequence); 117 } 118 } 119 120 return orderLine; 121 } 122 123 public OrderLine getOrderLineByName(final ExecutionErrorAccumulator eea, final String orderTypeName, final String orderName, final String orderLineSequence) { 124 return getOrderLineByName(eea, orderTypeName, orderName, orderLineSequence, EntityPermission.READ_ONLY); 125 } 126 127 public OrderLine getOrderLineByNameForUpdate(final ExecutionErrorAccumulator eea, final String orderTypeName, final String orderName, final String orderLineSequence) { 128 return getOrderLineByName(eea, orderTypeName, orderName, orderLineSequence, EntityPermission.READ_WRITE); 129 } 130 131 public Long getOrderTotalWithAdjustments(final Order order) { 132 long total = 0; 133 var orderAdjustments = orderAdjustmentControl.getOrderAdjustmentsByOrder(order); 134 135 total = orderAdjustments.stream().map((orderAdjustment) -> orderAdjustment.getLastDetail().getAmount()).reduce(total, (accumulator, _item) -> accumulator + _item); 136 137 return total + getOrderLineTotalsWithAdjustments(order); 138 } 139 140 public Long getOrderLineTotalsWithAdjustments(final Order order) { 141 var orderLines = orderLineControl.getOrderLinesByOrder(order); 142 long total = 0; 143 144 total = orderLines.stream().map((orderLine) -> getOrderLineTotalWithAdjustments(orderLine)).reduce(total, (accumulator, _item) -> accumulator + _item); 145 146 return total; 147 } 148 149 public Long getOrderLineTotalWithAdjustments(final OrderLine orderLine) { 150 var orderLineDetail = orderLine.getLastDetail(); 151 var total = orderLineDetail.getQuantity() * orderLineDetail.getUnitAmount(); 152 var orderLineAdjustments = orderLineAdjustmentControl.getOrderLineAdjustmentsByOrderLine(orderLine); 153 154 total = orderLineAdjustments.stream().map((orderLineAdjustment) -> orderLineAdjustment.getLastDetail().getAmount()).reduce(total, (accumulator, _item) -> accumulator + _item); 155 156 return total; 157 } 158 159}