<commit_before>/*
    jBilling - The Enterprise Open Source Billing System
    Copyright (C) 2003-2009 Enterprise jBilling Software Ltd. and <NAME>

    This file is part of jbilling.

    jbilling is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    jbilling is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with jbilling.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.sapienter.jbilling.server.item;

import com.sapienter.jbilling.common.SessionInternalError;
import com.sapienter.jbilling.server.item.db.ItemDAS;
import com.sapienter.jbilling.server.item.db.ItemDTO;
import com.sapienter.jbilling.server.item.db.ItemTypeDTO;
import com.sapienter.jbilling.server.item.tasks.IPricing;
import com.sapienter.jbilling.server.item.tasks.PricingResult;
import com.sapienter.jbilling.server.order.db.OrderLineDAS;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskManager;
import com.sapienter.jbilling.server.pricing.PriceModelBL;
import com.sapienter.jbilling.server.pricing.db.PriceModelDTO;
import com.sapienter.jbilling.server.user.EntityBL;
import com.sapienter.jbilling.server.user.UserBL;
import com.sapienter.jbilling.server.user.db.CompanyDAS;
import com.sapienter.jbilling.server.user.db.CompanyDTO;
import com.sapienter.jbilling.server.util.Constants;
import com.sapienter.jbilling.server.util.Context;
import com.sapienter.jbilling.server.util.audit.EventLogger;
import com.sapienter.jbilling.server.util.db.CurrencyDAS;
import org.apache.log4j.Logger;
import org.springmodules.cache.CachingModel;
import org.springmodules.cache.FlushingModel;
import org.springmodules.cache.provider.CacheProviderFacade;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class ItemBL {
    private ItemDAS itemDas = null;
    private ItemDTO item = null;
    private static final Logger LOG = Logger.getLogger(ItemBL.class);
    private EventLogger eLogger = null;
    private String priceCurrencySymbol = null;
    private List<PricingField> pricingFields = null;

    public ItemBL(Integer itemId) 
            throws SessionInternalError {
        try {
            init();
            set(itemId);
        } catch (Exception e) {
            throw new SessionInternalError("Setting item", ItemBL.class, e);
        } 
    }
    
    public ItemBL() {
        init();
    }
    
    public ItemBL(ItemDTO item) {
        this.item = item;
        init();
    }
    
    public void set(Integer itemId) {
        item = itemDas.find(itemId);
    }
    
    private void init() {
        eLogger = EventLogger.getInstance();        
        itemDas = new ItemDAS();
    }
    
    public ItemDTO getEntity() {
        return item;
    }

    public Integer create(ItemDTO dto, Integer languageId) {
        EntityBL entity = new EntityBL(dto.getEntityId());
        if (languageId == null) {
            languageId = entity.getEntity().getLanguageId();
        }

        if (dto.getHasDecimals() != null) {
            dto.setHasDecimals(dto.getHasDecimals());
        } else {
            dto.setHasDecimals(0);
        }

        if (dto.getDefaultPrice() != null) {
            dto.getDefaultPrice().setCurrency(entity.getEntity().getCurrency());
        }
                 
        dto.setDeleted(0);

        item = itemDas.save(dto);

        item.setDescription(dto.getDescription(), languageId);
        updateTypes(dto);
        
        return item.getId();
    }
    
    public void update(Integer executorId, ItemDTO dto, Integer languageId)  {

        eLogger.audit(executorId, null, Constants.TABLE_ITEM, item.getId(),
                EventLogger.MODULE_ITEM_MAINTENANCE, 
                EventLogger.ROW_UPDATED, null, null, null);
        
        item.setNumber(dto.getNumber());
        item.setPriceManual(dto.getPriceManual());
        item.setDescription(dto.getDescription(), languageId);
        item.setPercentage(dto.getPercentage());
        item.setHasDecimals(dto.getHasDecimals());

        if (dto.getDefaultPrice() != null) {
            if (item.getDefaultPrice() != null) {
                item.getDefaultPrice().setType(dto.getDefaultPrice().getType());
                item.getDefaultPrice().setAttributes(dto.getDefaultPrice().getAttributes());
                item.getDefaultPrice().setRate(dto.getDefaultPrice().getRate());
                item.getDefaultPrice().setIncludedQuantity(dto.getDefaultPrice().getIncludedQuantity());

            } else {
                item.setDefaultPrice(dto.getDefaultPrice());
            }

            // default price currency should always be the entity currency
            if (item.getDefaultPrice().getCurrency() == null) {
                item.getDefaultPrice().setCurrency(item.getEntity().getCurrency());
            }
        }

        updateTypes(dto);
    }
    
    private void updateTypes(ItemDTO dto) 
            {
        // update the types relationship        
        Collection types = item.getItemTypes();
        types.clear();
        ItemTypeBL typeBl = new ItemTypeBL();
        // TODO verify that all the categories belong to the same
        // order_line_type_id
        for (int f=0; f < dto.getTypes().length; f++) {
            typeBl.set(dto.getTypes()[f]);
            types.add(typeBl.getEntity());
        }
    }
        
    public void delete(Integer executorId) {
        item.setDeleted(new Integer(1));
        eLogger.audit(executorId, null, Constants.TABLE_ITEM, item.getId(),
                EventLogger.MODULE_ITEM_MAINTENANCE, 
                EventLogger.ROW_DELETED, null, null, null);
        
    }

    public static boolean validate(ItemDTO dto) {
        boolean retValue = true;
        
        if (dto.getDescription() == null || dto.getPrice() == null ||
                dto.getPriceManual() == null || 
                dto.getTypes() == null) {
            retValue = false;
        }
        
        return retValue;
    }
    <commit_msg>Allow item create/update using ItemDTO#setPrice()<commit_after>/*
    jBilling - The Enterprise Open Source Billing System
    Copyright (C) 2003-2009 Enterprise jBilling Software Ltd. and <NAME>

    This file is part of jbilling.

    jbilling is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    jbilling is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with jbilling.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.sapienter.jbilling.server.item;

import com.sapienter.jbilling.common.SessionInternalError;
import com.sapienter.jbilling.server.item.db.ItemDAS;
import com.sapienter.jbilling.server.item.db.ItemDTO;
import com.sapienter.jbilling.server.item.db.ItemTypeDTO;
import com.sapienter.jbilling.server.item.tasks.IPricing;
import com.sapienter.jbilling.server.item.tasks.PricingResult;
import com.sapienter.jbilling.server.order.db.OrderLineDAS;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskManager;
import com.sapienter.jbilling.server.pricing.PriceModelBL;
import com.sapienter.jbilling.server.pricing.db.PriceModelDTO;
import com.sapienter.jbilling.server.pricing.strategy.PriceModelStrategy;
import com.sapienter.jbilling.server.user.EntityBL;
import com.sapienter.jbilling.server.user.UserBL;
import com.sapienter.jbilling.server.user.db.CompanyDAS;
import com.sapienter.jbilling.server.user.db.CompanyDTO;
import com.sapienter.jbilling.server.util.Constants;
import com.sapienter.jbilling.server.util.Context;
import com.sapienter.jbilling.server.util.audit.EventLogger;
import com.sapienter.jbilling.server.util.db.CurrencyDAS;
import org.apache.log4j.Logger;
import org.springmodules.cache.CachingModel;
import org.springmodules.cache.FlushingModel;
import org.springmodules.cache.provider.CacheProviderFacade;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class ItemBL {
    private ItemDAS itemDas = null;
    private ItemDTO item = null;
    private static final Logger LOG = Logger.getLogger(ItemBL.class);
    private EventLogger eLogger = null;
    private String priceCurrencySymbol = null;
    private List<PricingField> pricingFields = null;

    public ItemBL(Integer itemId) 
            throws SessionInternalError {
        try {
            init();
            set(itemId);
        } catch (Exception e) {
            throw new SessionInternalError("Setting item", ItemBL.class, e);
        } 
    }
    
    public ItemBL() {
        init();
    }
    
    public ItemBL(ItemDTO item) {
        this.item = item;
        init();
    }
    
    public void set(Integer itemId) {
        item = itemDas.find(itemId);
    }
    
    private void init() {
        eLogger = EventLogger.getInstance();        
        itemDas = new ItemDAS();
    }
    
    public ItemDTO getEntity() {
        return item;
    }

    public Integer create(ItemDTO dto, Integer languageId) {
        EntityBL entity = new EntityBL(dto.getEntityId());
        if (languageId == null) {
            languageId = entity.getEntity().getLanguageId();
        }

        if (dto.getHasDecimals() != null) {
            dto.setHasDecimals(dto.getHasDecimals());
        } else {
            dto.setHasDecimals(0);
        }

        // Backwards compatible with the old ItemDTOEx Web Service API, use the
        // transient price field as the rate for a default pricing model.
        if (dto.getPrice() != null) {    
            dto.setDefaultPrice(getDefaultPrice(dto.getPrice()));
        }

        if (dto.getDefaultPrice() != null) {
            dto.getDefaultPrice().setCurrency(entity.getEntity().getCurrency());
        }
                 
        dto.setDeleted(0);

        item = itemDas.save(dto);

        item.setDescription(dto.getDescription(), languageId);
        updateTypes(dto);
        
        return item.getId();
    }
    
    public void update(Integer executorId, ItemDTO dto, Integer languageId)  {
        eLogger.audit(executorId, null, Constants.TABLE_ITEM, item.getId(),
                EventLogger.MODULE_ITEM_MAINTENANCE, 
                EventLogger.ROW_UPDATED, null, null, null);
        
        item.setNumber(dto.getNumber());
        item.setPriceManual(dto.getPriceManual());
        item.setDescription(dto.getDescription(), languageId);
        item.setPercentage(dto.getPercentage());
        item.setHasDecimals(dto.getHasDecimals());

        updateDefaultPrice(dto);
        updateTypes(dto);
    }

    /**
     * Constructs a METERED PriceModelDTO with the given rate to be used as
     * the default price for items. This type of price model matches the old
     * "$ per unit" style pricing for basic items.
     *
     * @param rate rate per unit
     * @return price model
     */
    private PriceModelDTO getDefaultPrice(BigDecimal rate) {
        PriceModelDTO model = new PriceModelDTO();
        model.setRate(rate);
        model.setType(PriceModelStrategy.METERED);

        return model;
    }

    /**
     * Updates the price of this item to that of the given ItemDTO. This method
     * handles updates to the price using both the items default price model, and
     * the transient price attribute.
     *
     * If the given dto has a price through {@link ItemDTO#getPrice()}, then the
     * default price model rate will be set to the price. Otherwise the given dto's
     * price model is used to update. 
     *
     * @param dto item holding the updates to apply to this item
     */
    private void updateDefaultPrice(ItemDTO dto) {
        if (item.getDefaultPrice() == null) {
            // new default price
            if (dto.getDefaultPrice() != null) {
                item.setDefaultPrice(dto.getDefaultPrice());
            } else if (dto.getPrice() != null) {
                item.setDefaultPrice(getDefaultPrice(dto.getPrice()));
            }
        } else {
            // update existing default price
            if (dto.getDefaultPrice() != null) {
                item.getDefaultPrice().setType(dto.getDefaultPrice().getType());
                item.getDefaultPrice().setAttributes(dto.getDefaultPrice().getAttributes());
                item.getDefaultPrice().setRate(dto.getDefaultPrice().getRate());
                item.getDefaultPrice().setIncludedQuantity(dto.getDefaultPrice().getIncludedQuantity());
            } else if (dto.getPrice() != null) {
                item.getDefaultPrice().setRate(dto.getPrice());
            }
        }

        // default price currency should always be the entity currency
        if (item.getDefaultPrice() != null && item.getDefaultPrice().getCurrency() == null) {
            item.getDefaultPrice().setCurrency(item.getEntity().getCurrency());
        }
    }

    private void updateTypes(ItemDTO dto) 
            {
        // update the types relationship        
        Collection types = item.getItemTypes();
        types.clear();
        ItemTypeBL typeBl = new ItemTypeBL();
        // TODO verify that all the categories belong to the same
        // order_line_type_id
        for (int f=0; f < dto.getTypes().length; f++) {
            typeBl.set(dto.getTypes()[f]);
            types.add(typeBl.getEntity());
        }
    }
        
    public void delete(Integer executorId) {
        item.setDeleted(new Integer(1));
        eLogger.audit(executorId, null, Constants.TABLE_ITEM, item.getId(),
                EventLogger.MODULE_ITEM_MAINTENANCE, 
                EventLogger.ROW_DELETED, null, null, null);
        
    }

    public static boolean validate(ItemDTO dto) {
        if ((dto.getPrice() == null && dto.getDefaultPrice() == null && dto.getPercentage() == null)
            || dto.getDescription() == null 
            || dto.getPriceManual() == null
            || dto.getTypes() == null) {

            return false;
        }
        
        return true;
    }
    
{'fraction_non_alphanumeric': 0.10132039881433576, 'fraction_numerical': 0.001886284020479655, 'mean_word_length': 2.548040152963671, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7146303', 'n_tokens_mistral': 4316, 'n_tokens_neox': 4293, 'n_words': 996}