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