package com.trywildcard.pair.model.product; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import com.trywildcard.pair.exception.CardBuilderException; import com.trywildcard.pair.model.Builder; import com.trywildcard.pair.extraction.MetaTagModel; import com.trywildcard.pair.validation.ValidationTool; import org.apache.commons.lang3.StringUtils; import java.util.*; @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "") public class OfferBuilder implements Builder<Offer> { private ValidationTool v = new ValidationTool(); // required fields protected Price price; // optional fields protected Price originalPrice; protected Price shippingCost; protected String description; protected Availability availability; protected Integer quantity; protected Date saleStartDate; protected Date saleEndDate; protected Date expirationDate; protected List<String> geographicAvailability = new ArrayList<String>(); protected Float weight; protected String weightUnits; /** * Construct an <code>OfferBuilder</code> provided a Price object. * @param price */ public OfferBuilder(Price price) throws CardBuilderException { price(price); } /** * Construct an <code>OfferBuilder</code> with only a price value, using USD as the default currency. * @param price the price value. */ public OfferBuilder(Float price) throws CardBuilderException { price(new Price(price, Currency.getInstance(Locale.US))); } public OfferBuilder(MetaTagModel metaTagModel) throws CardBuilderException { if (metaTagModel == null) { throw new CardBuilderException("MetaTagModel is required"); } if (StringUtils.isEmpty(metaTagModel.getPrice())) { throw new CardBuilderException("Product Price is not contained in meta tags and is required to create a OfferBuilder"); } try { price(new Price(Float.valueOf(metaTagModel.getPrice()), Currency.getInstance(Locale.US))); } catch (NumberFormatException nfe) { throw new CardBuilderException("The price value captured in the meta tag model is not a valid float object", nfe); } } public OfferBuilder weightUnits(String weightUnits){ boolean isValid = v.optional(v.notEmpty(weightUnits), "Tried to set weightUnits to an empty string."); if (isValid) { this.weightUnits = weightUnits; } return this; } public OfferBuilder weight(Float weight) { boolean isValid = v.optional(v.notNegative(weight), "Weight must be a positive Float."); if (isValid) { this.weight = weight; } return this; } public OfferBuilder saleStartDate(Date saleStartDate){ this.saleStartDate = saleStartDate; return this; } public OfferBuilder shippingCost(Price shippingCost) { this.shippingCost = shippingCost; return this; } public OfferBuilder saleEndDate(Date saleEndDate){ this.saleEndDate = saleEndDate; return this; } public OfferBuilder expirationDate(Date expirationDate){ this.expirationDate = expirationDate; return this; } public OfferBuilder geographicAvailability(List<Locale> geographicAvailability){ boolean isValid = v.optional(v.notNull(geographicAvailability), "geographicAvailability must not be null."); if (isValid) { for (Locale locale : geographicAvailability){ this.geographicAvailability.add(locale.getCountry()); } } return this; } public OfferBuilder quantity(Integer quantity){ boolean isValid = v.optional(v.notNegative(quantity), "quantity must be a positive Integer."); if (isValid) { this.quantity = quantity; } return this; } public OfferBuilder availability(Availability availability){ this.availability = availability; return this; } public OfferBuilder description(String description){ boolean isValid = v.optional(v.notEmpty(description), "Tried to set description to an empty string."); if (isValid) { this.description = description; } return this; } public OfferBuilder originalPrice(Price originalPrice){ this.originalPrice = originalPrice; return this; } /** * Instantiate an <code>Offer</code> with the data in this builder. * @return the constructed offer */ public Offer build(){ return new Offer(this); } /** * Get a list of validation errors. * @return the list of errors. */ public List<String> getErrors(){ return v.getErrors(); } /** * Private constructor to allow for Jackson deserialization. */ private OfferBuilder(){} private OfferBuilder price(Price price) throws CardBuilderException { v.required(v.notNull(price), "Price must not be null."); v.required(v.notNegative(price.getPrice()), "Price must be a positive Float."); this.price = price; return this; } @JsonProperty("geographic_availability") private OfferBuilder setGeographicAvailability(List<String> geographicAvailability){ boolean isValid = v.optional(v.notNull(geographicAvailability), "geographicAvailability must not be null."); this.geographicAvailability = geographicAvailability; return this; } }