Skip to content

Commit

Permalink
5522-app - Commission calculation
Browse files Browse the repository at this point in the history
- enable to be serializable and derserializable to/from JSON
  - CommissionInstances
  - Percent
- add tests for CommissionInstanceRepository
#5522
  • Loading branch information
metas-ts committed Sep 17, 2019
1 parent 9f1f52d commit df45a71
Show file tree
Hide file tree
Showing 25 changed files with 736 additions and 42 deletions.
@@ -1,5 +1,9 @@
package de.metas.contracts.commission.businesslogic;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.NonNull;

import de.metas.bpartner.BPartnerId;
import lombok.Value;

Expand Down Expand Up @@ -29,5 +33,22 @@
@Value
public class Beneficiary
{
@JsonCreator
public static Beneficiary of(@JsonProperty("bPartnerId") @NonNull final BPartnerId bPartnerId)
{
return new Beneficiary(bPartnerId);
}

BPartnerId bPartnerId;

private Beneficiary(BPartnerId bPartnerId)
{
this.bPartnerId = bPartnerId;
}

@JsonProperty("bPartnerId")
public BPartnerId getBPartnerId()
{
return bPartnerId;
}
}
@@ -1,6 +1,13 @@
package de.metas.contracts.commission.businesslogic;

import com.fasterxml.jackson.annotation.JsonTypeInfo;

import de.metas.contracts.commission.businesslogic.algorithms.HierarchyConfig;
import de.metas.contracts.commission.businesslogic.hierarchy.Hierarchy;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME;

import com.fasterxml.jackson.annotation.JsonSubTypes;

/*
* #%L
Expand All @@ -25,6 +32,10 @@
*/

/** Defines how a {@link CommissionInstance} is created for a given {@link CommissionTrigger} and {@link Hierarchy}. */
@JsonTypeInfo(use = NAME, include = PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = HierarchyConfig.class, name = "HierarchyConfig"),
})
public interface CommissionConfig
{
CommissionType getCommissionType();
Expand Down
@@ -1,5 +1,13 @@
package de.metas.contracts.commission.businesslogic;

import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import de.metas.contracts.commission.businesslogic.algorithms.HierarchyContract;

/*
* #%L
* de.metas.commission
Expand All @@ -23,6 +31,10 @@
*/

/** Contains settings that can vary between different {@link Beneficiary} even within the same commission instance. */
@JsonTypeInfo(use = NAME, include = PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(value = HierarchyContract.class, name = "HierarchyContract"),
})
public interface CommissionContract
{
CommissionConfig getConfig();
Expand Down
Expand Up @@ -2,6 +2,9 @@

import java.time.Instant;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
Expand All @@ -19,26 +22,35 @@
*
* This program 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
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/

@Value
@Builder

public class CommissionFact
{
/** This fact's timestamp; note that we need chronology, but don't care for a particular timezone. */
@NonNull
Instant timestamp;

@NonNull
CommissionState state;

@NonNull
CommissionPoints points;

@JsonCreator
@Builder
private CommissionFact(
@JsonProperty("timestamp") @NonNull final Instant timestamp,
@JsonProperty("state") @NonNull final CommissionState state,
@JsonProperty("points") @NonNull final CommissionPoints points)
{
this.timestamp = timestamp;
this.state = state;
this.points = points;
}
}
@@ -1,7 +1,11 @@
package de.metas.contracts.commission.businesslogic;

import java.util.List;

import javax.annotation.Nullable;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;

import lombok.Builder;
Expand Down Expand Up @@ -32,20 +36,31 @@
*/

@Value
@Builder
public class CommissionInstance
{
/** null if this instance was not (yet) persisted */
@Nullable
CommissionInstanceId id;

@NonNull
CommissionTriggerData currentTriggerData;

@NonNull
CommissionConfig config;

/** Each instance means that commission will be paid to some {@link Beneficiary} in accordance to some commission contract and hierarchy. */
@Singular

ImmutableList<CommissionShare> shares;

@JsonCreator
@Builder(toBuilder = true)
private CommissionInstance(
@JsonProperty("id") @Nullable final CommissionInstanceId id,
@JsonProperty("currentTriggerData") @NonNull final CommissionTriggerData currentTriggerData,
@JsonProperty("config") @NonNull final CommissionConfig config,
@JsonProperty("shares") @Singular final List<CommissionShare> shares)
{
this.id = id;
this.currentTriggerData = currentTriggerData;
this.config = config;
this.shares = ImmutableList.copyOf(shares);
}

}
Expand Up @@ -5,6 +5,10 @@
import java.math.BigDecimal;
import java.util.Collection;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonValue;

import de.metas.util.lang.Percent;
import lombok.NonNull;
import lombok.Value;
Expand Down Expand Up @@ -44,6 +48,7 @@ public static CommissionPoints of(@NonNull final String points)
return of(new BigDecimal(points));
}

@JsonCreator
public static CommissionPoints of(@NonNull final BigDecimal points)
{
return new CommissionPoints(points);
Expand All @@ -63,6 +68,7 @@ private CommissionPoints(@NonNull final BigDecimal points)
this.points = points;
}

@JsonValue
public BigDecimal toBigDecimal()
{
return points;
Expand Down Expand Up @@ -95,6 +101,7 @@ public CommissionPoints subtract(@NonNull final CommissionPoints augent)
return CommissionPoints.of(toBigDecimal().subtract(augent.toBigDecimal()));
}

@JsonIgnore
public boolean isZero()
{
final boolean isZero = points.signum() == 0;
Expand Down
@@ -1,9 +1,12 @@
package de.metas.contracts.commission.businesslogic;

import java.util.ArrayList;
import java.util.List;

import org.adempiere.exceptions.AdempiereException;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;

import de.metas.contracts.commission.businesslogic.hierarchy.HierarchyLevel;
Expand Down Expand Up @@ -57,12 +60,13 @@ public class CommissionShare
/** Chronological list of facts that make it clear what happened when */
private final ArrayList<CommissionFact> facts;

@JsonCreator
@Builder
private CommissionShare(
@NonNull final CommissionContract contract,
@NonNull final HierarchyLevel level,
@NonNull final Beneficiary beneficiary,
@NonNull @Singular final ImmutableList<CommissionFact> facts)
@JsonProperty("contract") @NonNull final CommissionContract contract,
@JsonProperty("level") @NonNull final HierarchyLevel level,
@JsonProperty("beneficiary") @NonNull final Beneficiary beneficiary,
@JsonProperty("facts") @NonNull @Singular final List<CommissionFact> facts)
{
this.contract = contract;
this.level = level;
Expand Down
Expand Up @@ -4,6 +4,9 @@

import java.time.Instant;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import de.metas.invoicecandidate.InvoiceCandidateId;
import lombok.Builder;
import lombok.NonNull;
Expand Down Expand Up @@ -46,12 +49,13 @@ public class CommissionTriggerData
CommissionPoints invoicedPoints;

@Builder
@JsonCreator
private CommissionTriggerData(
@NonNull final InvoiceCandidateId invoiceCandidateId,
@NonNull final Instant timestamp,
@NonNull final CommissionPoints forecastedPoints,
@NonNull final CommissionPoints invoiceablePoints,
@NonNull final CommissionPoints invoicedPoints)
@JsonProperty("invoiceCandidateId") @NonNull final InvoiceCandidateId invoiceCandidateId,
@JsonProperty("timestamp") @NonNull final Instant timestamp,
@JsonProperty("forecastedPoints") @NonNull final CommissionPoints forecastedPoints,
@JsonProperty("invoiceablePoints") @NonNull final CommissionPoints invoiceablePoints,
@JsonProperty("invoicedPoints") @NonNull final CommissionPoints invoicedPoints)
{
this.invoiceCandidateId = invoiceCandidateId;
this.timestamp = timestamp;
Expand Down
@@ -1,6 +1,9 @@
package de.metas.contracts.commission.businesslogic;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.metas.bpartner.BPartnerId;
import lombok.NonNull;
import lombok.Value;

/*
Expand Down Expand Up @@ -29,5 +32,22 @@
@Value
public class Customer
{
@JsonCreator
public static Customer of(@JsonProperty("bPartnerId") @NonNull final BPartnerId bPartnerId)
{
return new Customer(bPartnerId);
}

BPartnerId bPartnerId;

private Customer(BPartnerId bPartnerId)
{
this.bPartnerId = bPartnerId;
}

@JsonProperty("bPartnerId")
public BPartnerId getBPartnerId()
{
return bPartnerId;
}
}
Expand Up @@ -46,7 +46,6 @@ public static HierarchyConfig cast(@NonNull final CommissionConfig config)
.setParameter("config", config);
}


public boolean isSubtractLowerLevelCommissionFromBase()
{
return true;
Expand Down
Expand Up @@ -2,6 +2,9 @@

import org.adempiere.exceptions.AdempiereException;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import de.metas.contracts.commission.businesslogic.CommissionContract;
import de.metas.util.lang.Percent;
import lombok.NonNull;
Expand Down Expand Up @@ -46,6 +49,12 @@ public static HierarchyContract cast(@NonNull final CommissionContract contract)
.setParameter("contract", contract);
}

@JsonCreator
public HierarchyContract(@JsonProperty("config") @NonNull final HierarchyConfig config)
{
this.config = config;
}

/** Note: add "Hierarchy" as method parameters if and when we have a commission type where it makes a difference. */
public Percent getCommissionPercent()
{
Expand All @@ -56,4 +65,7 @@ public int getPointsPrecision()
{
return 2;
}



}
Expand Up @@ -2,6 +2,9 @@

import static de.metas.util.Check.assumeGreaterOrEqualToZero;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Value;
Expand Down Expand Up @@ -33,6 +36,7 @@ public class HierarchyLevel
{
public static final HierarchyLevel ZERO = of(0);

@JsonCreator
public static HierarchyLevel of(int level)
{
return new HierarchyLevel(level);
Expand All @@ -41,6 +45,7 @@ public static HierarchyLevel of(int level)
@Getter(AccessLevel.NONE)
int level;

@JsonValue
public int toInt()
{
return level;
Expand Down
Expand Up @@ -66,6 +66,6 @@ private Hierarchy createFor(final BPartnerId bPartnerId, final HierarchyBuilder

private HierarchyNode node(final BPartnerId bPartnerId)
{
return HierarchyNode.of(new Beneficiary(bPartnerId));
return HierarchyNode.of(Beneficiary.of(bPartnerId));
}
}
Expand Up @@ -69,9 +69,9 @@ private Optional<CommissionTrigger> createForRecord(@NonNull final I_C_Invoice_C
}

final CommissionTrigger trigger = CommissionTrigger.builder()
.customer(new Customer(BPartnerId.ofRepoId(icRecord.getBill_BPartner_ID())))
.customer(Customer.of(BPartnerId.ofRepoId(icRecord.getBill_BPartner_ID())))
.timestamp(TimeUtil.asInstant(icRecord.getUpdated()))
.beneficiary(new Beneficiary(salesRepId))
.beneficiary(Beneficiary.of(salesRepId))
.commissionTriggerData(commissionTriggerDataRepository.getForInvoiceCandiateId(invoiceCandidateId))
.build();

Expand Down

0 comments on commit df45a71

Please sign in to comment.