001/* 002 * Copyright 2010-2014 Ning, Inc. 003 * Copyright 2014-2018 The Billing Project, LLC 004 * 005 * The Billing Project licenses this file to you under the Apache License, version 2.0 006 * (the "License"); you may not use this file except in compliance with the 007 * License. You may obtain a copy of the License at: 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package com.ning.billing.recurly.model; 019 020import javax.xml.bind.annotation.XmlElement; 021import javax.xml.bind.annotation.XmlElementWrapper; 022import javax.xml.bind.annotation.XmlRootElement; 023import javax.xml.bind.annotation.XmlTransient; 024 025import org.joda.time.DateTime; 026import com.google.common.base.Objects; 027 028/** 029 * Class that represents the Concept of a Coupon within the Recurly API. 030 */ 031@XmlRootElement(name = "coupon") 032public class Coupon extends RecurlyObject { 033 public enum DiscountType { 034 percent, dollars, free_trial 035 } 036 037 public enum Duration { 038 forever, single_use, temporal 039 } 040 041 public enum FreeTrialUnit { 042 day, week, month 043 } 044 045 public enum RedemptionResource { 046 account, subscription 047 } 048 049 public enum TemporalUnit { 050 day, week, month, year; 051 } 052 053 public enum Type { 054 single_code, bulk, unique_code 055 } 056 057 @XmlTransient 058 public static final String COUPON_RESOURCE = "/coupons"; 059 060 @XmlTransient 061 public static final String GENERATE_RESOURCE = "/generate"; 062 063 @XmlTransient 064 public static final String UNIQUE_CODES_RESOURCE = "/unique_coupon_codes"; 065 066 @XmlElement(name = "id") 067 private Long id; 068 069 @XmlElement(name = "name") 070 private String name; 071 072 @XmlElement(name = "coupon_code") 073 private String couponCode; 074 075 /** 076 * Description of the coupon on the hosted payment pages. 077 */ 078 @XmlElement(name = "description") 079 private String description; 080 081 /** 082 * Description of the coupon on the invoice. 083 */ 084 @XmlElement(name = "invoice_description") 085 private String invoiceDescription; 086 087 /** 088 * Last date to redeem the coupon, defaults to no date 089 */ 090 @XmlElement(name = "redeem_by_date") 091 private DateTime redeemByDate; 092 093 /** 094 * Number of months after redemption that the coupon is valid, defaults to no date 095 * @deprecated Please use temporal_unit and temporal_amount 096 */ 097 @XmlElement(name = "applies_for_months") 098 private Integer appliesForMonths; 099 100 /** 101 * Maximum number of accounts that may use the coupon before it can no longer be redeemed 102 */ 103 @XmlElement(name = "max_redemptions") 104 private Integer maxRedemptions; 105 106 /** 107 * The coupon is valid for all plans if true, defaults to true 108 */ 109 @XmlElement(name = "applies_to_all_plans") 110 private Boolean appliesToAllPlans; 111 112 /** 113 * If true, the coupon applies to the first invoice only 114 * @deprecated Please use duration 115 */ 116 @XmlElement(name = "single_use") 117 private Boolean singleUse; 118 119 @XmlElement(name = "discount_type") 120 private DiscountType discountType; 121 122 @XmlElement(name = "free_trial_unit") 123 private FreeTrialUnit freeTrialUnit; 124 125 @XmlElement(name = "free_trial_amount") 126 private Integer freeTrialAmount; 127 128 /** 129 * Discount percentage if discount_type is "percent" 130 */ 131 @XmlElement(name = "discount_percent") 132 private Integer discountPercent; 133 134 @XmlElement(name = "discount_in_cents") 135 private RecurlyUnitCurrency discountInCents; 136 137 @XmlElement(name = "state") 138 private String state; 139 140 @XmlElement(name = "created_at") 141 private DateTime createdAt; 142 143 @XmlElement(name = "updated_at") 144 private DateTime updatedAt; 145 146 public PlanCodes getPlanCodes() { 147 return planCodes; 148 } 149 150 public void setPlanCodes(final PlanCodes planCodes) { 151 this.planCodes = planCodes; 152 } 153 154 @XmlElement(name = "plan_code") 155 @XmlElementWrapper(name = "plan_codes") 156 private PlanCodes planCodes; 157 158 /** 159 * forever, single_use, or temporal. If single_use, the coupon applies to 160 * the first invoice only. If temporal the coupon will apply to invoices for 161 * the duration determined by the temporal_unit and temporal_amount 162 * attributes. 163 */ 164 @XmlElement(name = "duration") 165 private Duration duration; 166 167 /** 168 * day, week, month, or year. If duration is temporal then temporal_unit is 169 * multiplied by temporal_amount to define the duration that the coupon will 170 * be applied to invoices for. 171 */ 172 @XmlElement(name = "temporal_unit") 173 private TemporalUnit temporalUnit; 174 175 /** 176 * If duration is temporal then temporal_amount is an integer which is 177 * multiplied by temporal_unit to define the duration that the coupon will 178 * be applied to invoices for. 179 */ 180 @XmlElement(name = "temporal_amount") 181 private Integer temporalAmount; 182 183 /** 184 * The coupon is valid for one-time, non-plan charges if true, defaults to 185 * false. 186 */ 187 @XmlElement(name = "applies_to_non_plan_charges") 188 private Boolean appliesToNonPlanCharges; 189 190 /** 191 * Whether the discount is for all eligible charges on the account, or only 192 * a specific subscription. Values are account or subscription. 193 */ 194 @XmlElement(name = "redemption_resource") 195 private RedemptionResource redemptionResource; 196 197 /** 198 * The number of times the coupon can be redeemed on a specific account 199 */ 200 @XmlElement(name = "max_redemptions_per_account") 201 private Integer maxRedemptionsPerAccount; 202 203 /** 204 * Whether the coupon is single_code or bulk. Bulk coupons will require a 205 * unique_code_template and will generate unique codes through the generate 206 * endpoint. 207 */ 208 @XmlElement(name = "coupon_type") 209 private Type type; 210 211 /** 212 * The template for generating unique codes. 213 * 214 * @see <a href= 215 * "https://dev.recurly.com/docs/create-coupon">https://dev.recurly.com/docs/create-coupon</a> 216 */ 217 @XmlElement(name = "unique_code_template") 218 private String uniqueCodeTemplate; 219 220 /** 221 * The number of unique codes to generate. 222 * 223 * @see <a href= 224 * "https://dev.recurly.com/docs/generate-unique-codes">https://dev.recurly.com/docs/generate-unique-codes</a> 225 */ 226 @XmlElement(name = "number_of_unique_codes") 227 private Integer numberOfUniqueCodes; 228 229 public void setId(final Object id) { 230 this.id = longOrNull(id); 231 } 232 233 public Long getId() { 234 return this.id; 235 } 236 237 public String getState() { 238 return state; 239 } 240 241 public void setState(final Object state) { 242 this.state = stringOrNull(state); 243 } 244 245 /** 246 * Gets the name of the {@link Coupon} 247 * 248 * @return The {@link Coupon} name 249 */ 250 public String getName() { 251 return name; 252 } 253 254 /** 255 * Sets the name of the {@link Coupon} 256 * 257 * @param name The Name that is to be given to the {@link Coupon} 258 */ 259 public void setName(final Object name) { 260 this.name = stringOrNull(name); 261 } 262 263 /** 264 * Gets the coupon code for a {@link Coupon} 265 * 266 * @return The coupon code for the {@link Coupon} 267 */ 268 public String getCouponCode() { 269 return couponCode; 270 } 271 272 /** 273 * Sets the coupon code for the {@link Coupon} 274 * 275 * @param couponCode The coupon code 276 */ 277 public void setCouponCode(final Object couponCode) { 278 this.couponCode = stringOrNull(couponCode); 279 } 280 281 /** 282 * Sets the discount type for a {@link Coupon} 283 * 284 * @param discountType 285 */ 286 public void setDiscountType(final Object discountType) { 287 this.discountType = enumOrNull(DiscountType.class, discountType); 288 } 289 290 /** 291 * Gets the discount type associated with the {@link Coupon} 292 * 293 * @return the DiscountType 294 */ 295 public DiscountType getDiscountType() { 296 return discountType; 297 } 298 299 /** 300 * Gets the percentage discount for a coupon 301 * 302 * @return The percentage 303 */ 304 public Integer getDiscountPercent() { 305 return discountPercent; 306 } 307 308 public void setDiscountPercent(final Object discountPercent) { 309 this.discountPercent = integerOrNull(discountPercent); 310 } 311 312 public DateTime getRedeemByDate() { 313 return redeemByDate; 314 } 315 316 public void setRedeemByDate(final Object redeemByDate) { 317 this.redeemByDate = dateTimeOrNull(redeemByDate); 318 } 319 320 public Integer getAppliesForMonths() { 321 return appliesForMonths; 322 } 323 324 public void setAppliesForMonths(final Object appliesForMonths) { 325 this.appliesForMonths = integerOrNull(appliesForMonths); 326 } 327 328 public Integer getMaxRedemptions() { 329 return maxRedemptions; 330 } 331 332 public void setMaxRedemptions(final Object maxRedemptions) { 333 this.maxRedemptions = integerOrNull(maxRedemptions); 334 } 335 336 public Boolean getSingleUse() { 337 return singleUse; 338 } 339 340 public void setSingleUse(final Object singleUse) { 341 this.singleUse = booleanOrNull(singleUse); 342 } 343 344 public RecurlyUnitCurrency getDiscountInCents() { 345 return discountInCents; 346 } 347 348 public void setDiscountInCents(final Object discountInCents) { 349 this.discountInCents = RecurlyUnitCurrency.build(discountInCents); 350 } 351 352 public Boolean getAppliesToAllPlans() { 353 return appliesToAllPlans; 354 } 355 356 public void setAppliesToAllPlans(final Object appliesToAllPlans) { 357 this.appliesToAllPlans = booleanOrNull(appliesToAllPlans); 358 } 359 360 public FreeTrialUnit getFreeTrialUnit() { 361 return freeTrialUnit; 362 } 363 364 public void setFreeTrialUnit(final Object freeTrialUnit) { 365 this.freeTrialUnit = enumOrNull(FreeTrialUnit.class, freeTrialUnit); 366 } 367 368 public Integer getFreeTrialAmount() { 369 return freeTrialAmount; 370 } 371 372 public void setFreeTrialAmount(final Object freeTrialAmount) { 373 this.freeTrialAmount = integerOrNull(freeTrialAmount); 374 } 375 376 public DateTime getCreatedAt() { 377 return createdAt; 378 } 379 380 public void setCreatedAt(final Object createdAt) { 381 this.createdAt = dateTimeOrNull(createdAt); 382 } 383 384 public DateTime getUpdatedAt() { 385 return updatedAt; 386 } 387 388 public void setUpdatedAt(final Object updatedAt) { 389 this.updatedAt = dateTimeOrNull(updatedAt); 390 } 391 392 public String getDescription() { 393 return description; 394 } 395 396 public void setDescription(Object description) { 397 this.description = stringOrNull(description); 398 } 399 400 public String getInvoiceDescription() { 401 return invoiceDescription; 402 } 403 404 public void setInvoiceDescription(Object invoiceDescription) { 405 this.invoiceDescription = stringOrNull(invoiceDescription); 406 } 407 408 public Duration getDuration() { 409 return duration; 410 } 411 412 public void setDuration(Object duration) { 413 this.duration = enumOrNull(Duration.class, duration); 414 } 415 416 public TemporalUnit getTemporalUnit() { 417 return temporalUnit; 418 } 419 420 public void setTemporalUnit(Object temporalUnit) { 421 this.temporalUnit = enumOrNull(TemporalUnit.class, temporalUnit); 422 } 423 424 public Integer getTemporalAmount() { 425 return temporalAmount; 426 } 427 428 public void setTemporalAmount(Object temporalAmount) { 429 this.temporalAmount = integerOrNull(temporalAmount); 430 } 431 432 public Boolean getAppliesToNonPlanCharges() { 433 return appliesToNonPlanCharges; 434 } 435 436 public void setAppliesToNonPlanCharges(Object appliesToNonPlanCharges) { 437 this.appliesToNonPlanCharges = booleanOrNull(appliesToNonPlanCharges); 438 } 439 440 public RedemptionResource getRedemptionResource() { 441 return redemptionResource; 442 } 443 444 public void setRedemptionResource(Object redemptionResource) { 445 this.redemptionResource = enumOrNull(RedemptionResource.class, redemptionResource); 446 } 447 448 public Integer getMaxRedemptionsPerAccount() { 449 return maxRedemptionsPerAccount; 450 } 451 452 public void setMaxRedemptionsPerAccount(Object maxRedemptionsPerAccount) { 453 this.maxRedemptionsPerAccount = integerOrNull(maxRedemptionsPerAccount); 454 } 455 456 public Type getType() { 457 return type; 458 } 459 460 public void setType(Type type) { 461 this.type = enumOrNull(Type.class, type); 462 } 463 464 public String getUniqueCodeTemplate() { 465 return uniqueCodeTemplate; 466 } 467 468 public void setUniqueCodeTemplate(Object uniqueCodeTemplate) { 469 this.uniqueCodeTemplate = stringOrNull(uniqueCodeTemplate); 470 } 471 472 public Integer getNumberOfUniqueCodes() { 473 return numberOfUniqueCodes; 474 } 475 476 public void setNumberOfUniqueCodes(Integer numberOfUniqueCodes) { 477 this.numberOfUniqueCodes = numberOfUniqueCodes; 478 } 479 480 @Override 481 public String toString() { 482 final StringBuilder sb = new StringBuilder(); 483 sb.append("Coupon"); 484 sb.append("{name='").append(name).append('\''); 485 sb.append(", id=").append(id); 486 sb.append(", couponCode='").append(couponCode).append('\''); 487 sb.append(", discountType='").append(discountType).append('\''); 488 sb.append(", discountPercent='").append(discountPercent).append('\''); 489 sb.append(", createdAt=").append(createdAt); 490 sb.append(", updatedAt=").append(updatedAt); 491 sb.append('}'); 492 return sb.toString(); 493 } 494 495 @Override 496 public boolean equals(final Object o) { 497 if (this == o) return true; 498 if (o == null || getClass() != o.getClass()) return false; 499 500 final Coupon coupon = (Coupon) o; 501 502 if (appliesForMonths != null ? !appliesForMonths.equals(coupon.appliesForMonths) : coupon.appliesForMonths != null) { 503 return false; 504 } 505 if (appliesToNonPlanCharges != null ? !appliesToNonPlanCharges.equals(coupon.appliesToNonPlanCharges) : coupon.appliesToNonPlanCharges != null) { 506 return false; 507 } 508 if (appliesToAllPlans != null ? !appliesToAllPlans.equals(coupon.appliesToAllPlans) : coupon.appliesToAllPlans != null) { 509 return false; 510 } 511 if (couponCode != null ? !couponCode.equals(coupon.couponCode) : coupon.couponCode != null) { 512 return false; 513 } 514 if (planCodes != null ? !planCodes.equals(coupon.planCodes) : coupon.planCodes != null) { 515 return false; 516 } 517 if (createdAt != null ? createdAt.compareTo(coupon.createdAt) != 0 : coupon.createdAt != null) { 518 return false; 519 } 520 if (description != null ? !description.equals(coupon.description) : coupon.description != null) { 521 return false; 522 } 523 if (discountInCents != null ? !discountInCents.equals(coupon.discountInCents) : coupon.discountInCents != null) { 524 return false; 525 } 526 if (discountPercent != null ? !discountPercent.equals(coupon.discountPercent) : coupon.discountPercent != null) { 527 return false; 528 } 529 if (discountType != null ? !discountType.equals(coupon.discountType) : coupon.discountType != null) { 530 return false; 531 } 532 if (duration != null ? !duration.equals(coupon.duration) : coupon.duration != null) { 533 return false; 534 } 535 if (id != null ? !id.equals(coupon.id) : coupon.id != null) { 536 return false; 537 } 538 if (invoiceDescription != null ? !invoiceDescription.equals(coupon.invoiceDescription) : coupon.invoiceDescription != null) { 539 return false; 540 } 541 if (maxRedemptions != null ? !maxRedemptions.equals(coupon.maxRedemptions) : coupon.maxRedemptions != null) { 542 return false; 543 } 544 if (name != null ? !name.equals(coupon.name) : coupon.name != null) { 545 return false; 546 } 547 if (redeemByDate != null ? redeemByDate.compareTo(coupon.redeemByDate) != 0 : coupon.redeemByDate != null) { 548 return false; 549 } 550 if (redemptionResource != null ? redemptionResource.compareTo(coupon.redemptionResource) != 0 : coupon.redemptionResource != null) { 551 return false; 552 } 553 if (singleUse != null ? singleUse.compareTo(coupon.singleUse) != 0 : coupon.singleUse != null) { 554 return false; 555 } 556 if (temporalAmount != null ? temporalAmount.compareTo(coupon.temporalAmount) != 0 : coupon.temporalAmount != null) { 557 return false; 558 } 559 if (temporalUnit != null ? temporalUnit.compareTo(coupon.temporalUnit) != 0 : coupon.temporalUnit != null) { 560 return false; 561 } 562 if (type != null ? type.compareTo(coupon.type) != 0 : coupon.type != null) { 563 return false; 564 } 565 if (uniqueCodeTemplate != null ? uniqueCodeTemplate.compareTo(coupon.uniqueCodeTemplate) != 0 : coupon.uniqueCodeTemplate != null) { 566 return false; 567 } 568 if (freeTrialUnit != null ? !freeTrialUnit.equals(coupon.freeTrialUnit) : coupon.freeTrialUnit != null) { 569 return false; 570 } 571 if (freeTrialAmount != null ? !freeTrialAmount.equals(coupon.freeTrialAmount) : coupon.freeTrialAmount != null) { 572 return false; 573 } 574 if (updatedAt != null ? updatedAt.compareTo(coupon.updatedAt) != 0 : coupon.updatedAt != null) { 575 return false; 576 } 577 578 return true; 579 } 580 581 @Override 582 public int hashCode() { 583 return Objects.hashCode( 584 appliesForMonths, 585 appliesToAllPlans, 586 appliesToNonPlanCharges, 587 name, 588 couponCode, 589 planCodes, 590 description, 591 discountType, 592 discountPercent, 593 discountInCents, 594 duration, 595 id, 596 invoiceDescription, 597 redeemByDate, 598 singleUse, 599 maxRedemptions, 600 freeTrialUnit, 601 freeTrialAmount, 602 createdAt, 603 redemptionResource, 604 temporalAmount, 605 temporalUnit, 606 type, 607 uniqueCodeTemplate, 608 updatedAt 609 ); 610 } 611}