Subversion Repositories SmartDukaan

Rev

Rev 37588 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
37588 amit 1
package com.spice.profitmandi.dao.entity.fofo;
2
 
3
import javax.persistence.Column;
4
import javax.persistence.Entity;
5
import javax.persistence.Id;
6
import javax.persistence.Table;
7
import java.io.Serializable;
8
import java.math.BigDecimal;
9
import java.math.RoundingMode;
10
import java.time.LocalDate;
11
import java.time.LocalDateTime;
12
 
13
/**
14
 * Current investment snapshot for one partner, maintained by the 2-minute sweep.
15
 *
16
 * <p>All the fast-moving columns are written in a single pass so that coupled terms can never be
17
 * read at different vintages. Wallet and utilised are coupled (an advance payment swept to a loan
18
 * moves both); in-stock and aged-Apple are coupled (the aged units are a subset of stock). Mixing
19
 * vintages between any such pair double-counts the money that moved between them.
20
 *
21
 * <p>{@link #getBaseValue()} is the single number the credit-limit tier consumes. The sweep
22
 * compares it at 2dp against the stored value to decide whether a partner's limit needs
23
 * recomputing, so it must never carry raw double noise.
24
 */
25
@Entity
26
@Table(name = "fofo.partner_investment")
27
public class PartnerInvestment implements Serializable {
28
 
29
    private static final long serialVersionUID = 1L;
30
 
31
    /** Money is rounded to paise everywhere; base_value is a comparison key, not an accumulator. */
32
    public static final int MONEY_SCALE = 2;
33
 
34
    @Id
35
    @Column(name = "fofo_id")
36
    private int fofoId;
37
 
38
    @Column(name = "wallet_amount")
39
    private BigDecimal walletAmount = BigDecimal.ZERO;
40
 
37592 amit 41
    /** Gross stock value; the live-demo haircut is applied by {@link #getNetInStockAmount()}. */
42
    @Column(name = "in_stock_gross_amount")
43
    private BigDecimal inStockGrossAmount = BigDecimal.ZERO;
37588 amit 44
 
45
    @Column(name = "unbilled_amount")
46
    private BigDecimal unbilledAmount = BigDecimal.ZERO;
47
 
48
    @Column(name = "grn_pending_amount")
49
    private BigDecimal grnPendingAmount = BigDecimal.ZERO;
50
 
51
    @Column(name = "activated_stock_amount")
52
    private BigDecimal activatedStockAmount = BigDecimal.ZERO;
53
 
54
    @Column(name = "activated_grn_pending_amount")
55
    private BigDecimal activatedGrnPendingAmount = BigDecimal.ZERO;
56
 
57
    @Column(name = "return_in_transit_amount")
58
    private BigDecimal returnInTransitAmount = BigDecimal.ZERO;
59
 
60
    @Column(name = "utilized_amount")
61
    private BigDecimal utilizedAmount = BigDecimal.ZERO;
62
 
63
    @Column(name = "aged_apple_stock_amount")
64
    private BigDecimal agedAppleStockAmount = BigDecimal.ZERO;
65
 
37592 amit 66
    /** Unit count behind {@link #agedAppleStockAmount}; maintained on the same daily cycle. */
67
    @Column(name = "aged_apple_qty")
68
    private int agedAppleQty;
69
 
37588 amit 70
    @Column(name = "demo_excluded_amount")
71
    private BigDecimal demoExcludedAmount = BigDecimal.ZERO;
72
 
73
    @Column(name = "aged_refreshed_on")
74
    private LocalDate agedRefreshedOn;
75
 
76
    @Column(name = "total_investment")
77
    private BigDecimal totalInvestment = BigDecimal.ZERO;
78
 
79
    @Column(name = "base_value")
80
    private BigDecimal baseValue = BigDecimal.ZERO;
81
 
82
    @Column(name = "snapshot_timestamp")
83
    private LocalDateTime snapshotTimestamp;
84
 
85
    public PartnerInvestment() {
86
    }
87
 
88
    public PartnerInvestment(int fofoId) {
89
        this.fofoId = fofoId;
90
    }
91
 
92
    private static BigDecimal scaled(BigDecimal value) {
93
        return (value == null ? BigDecimal.ZERO : value).setScale(MONEY_SCALE, RoundingMode.HALF_UP);
94
    }
95
 
96
    /**
97
     * Recomputes {@code totalInvestment} and {@code baseValue} from the component columns.
98
     *
99
     * <p>Mirrors PartnerDailyInvestment.getTotalInvestment() less the aged-Apple haircut, then less
100
     * utilisation — the same chain PartnerLimitHelper.getSuggestedAmount() applies before the tier
101
     * multiply. Keeping it here means the limit never has to re-derive it from separate reads.
102
     */
103
    public void recalculate() {
104
        BigDecimal total = scaled(walletAmount)
37592 amit 105
                .add(getNetInStockAmount())
37588 amit 106
                .add(scaled(unbilledAmount))
107
                .add(scaled(grnPendingAmount))
108
                .add(scaled(returnInTransitAmount))
109
                .subtract(scaled(activatedStockAmount))
110
                .subtract(scaled(activatedGrnPendingAmount));
111
        this.totalInvestment = scaled(total);
112
        this.baseValue = scaled(this.totalInvestment
113
                .subtract(scaled(agedAppleStockAmount))
114
                .subtract(scaled(utilizedAmount)));
115
    }
116
 
117
    /** True when the base has moved enough to matter, i.e. at all once rounded to paise. */
118
    public boolean baseDiffersFrom(PartnerInvestment other) {
119
        if (other == null) {
120
            return true;
121
        }
122
        return scaled(this.baseValue).compareTo(scaled(other.baseValue)) != 0;
123
    }
124
 
125
    public int getFofoId() {
126
        return fofoId;
127
    }
128
 
129
    public void setFofoId(int fofoId) {
130
        this.fofoId = fofoId;
131
    }
132
 
133
    public BigDecimal getWalletAmount() {
134
        return walletAmount;
135
    }
136
 
137
    public void setWalletAmount(BigDecimal walletAmount) {
138
        this.walletAmount = scaled(walletAmount);
139
    }
140
 
37592 amit 141
    public BigDecimal getInStockGrossAmount() {
142
        return inStockGrossAmount;
37588 amit 143
    }
144
 
37592 amit 145
    public void setInStockGrossAmount(BigDecimal inStockGrossAmount) {
146
        this.inStockGrossAmount = scaled(inStockGrossAmount);
37588 amit 147
    }
148
 
37592 amit 149
    /**
150
     * Stock as investment counts it: gross less live-demo units held past 90 days.
151
     *
152
     * <p>This is what {@code InventoryService.getTotalAmountInStock()} returns and what both
153
     * original investment paths assigned to {@code PartnerDailyInvestment.inStockAmount} — which is
154
     * why {@code getTotalInvestment()} carries no separate demo term. Derived rather than stored so
155
     * that the daily demo refresh flows through to stock and base with nothing to keep in sync.
156
     */
157
    public BigDecimal getNetInStockAmount() {
158
        return scaled(scaled(inStockGrossAmount).subtract(scaled(demoExcludedAmount)));
159
    }
160
 
37588 amit 161
    public BigDecimal getUnbilledAmount() {
162
        return unbilledAmount;
163
    }
164
 
165
    public void setUnbilledAmount(BigDecimal unbilledAmount) {
166
        this.unbilledAmount = scaled(unbilledAmount);
167
    }
168
 
169
    public BigDecimal getGrnPendingAmount() {
170
        return grnPendingAmount;
171
    }
172
 
173
    public void setGrnPendingAmount(BigDecimal grnPendingAmount) {
174
        this.grnPendingAmount = scaled(grnPendingAmount);
175
    }
176
 
177
    public BigDecimal getActivatedStockAmount() {
178
        return activatedStockAmount;
179
    }
180
 
181
    public void setActivatedStockAmount(BigDecimal activatedStockAmount) {
182
        this.activatedStockAmount = scaled(activatedStockAmount);
183
    }
184
 
185
    public BigDecimal getActivatedGrnPendingAmount() {
186
        return activatedGrnPendingAmount;
187
    }
188
 
189
    public void setActivatedGrnPendingAmount(BigDecimal activatedGrnPendingAmount) {
190
        this.activatedGrnPendingAmount = scaled(activatedGrnPendingAmount);
191
    }
192
 
193
    public BigDecimal getReturnInTransitAmount() {
194
        return returnInTransitAmount;
195
    }
196
 
197
    public void setReturnInTransitAmount(BigDecimal returnInTransitAmount) {
198
        this.returnInTransitAmount = scaled(returnInTransitAmount);
199
    }
200
 
201
    public BigDecimal getUtilizedAmount() {
202
        return utilizedAmount;
203
    }
204
 
205
    public void setUtilizedAmount(BigDecimal utilizedAmount) {
206
        this.utilizedAmount = scaled(utilizedAmount);
207
    }
208
 
209
    public BigDecimal getAgedAppleStockAmount() {
210
        return agedAppleStockAmount;
211
    }
212
 
213
    public void setAgedAppleStockAmount(BigDecimal agedAppleStockAmount) {
214
        this.agedAppleStockAmount = scaled(agedAppleStockAmount);
215
    }
216
 
37592 amit 217
    public int getAgedAppleQty() {
218
        return agedAppleQty;
219
    }
220
 
221
    public void setAgedAppleQty(int agedAppleQty) {
222
        this.agedAppleQty = agedAppleQty;
223
    }
224
 
37588 amit 225
    public BigDecimal getDemoExcludedAmount() {
226
        return demoExcludedAmount;
227
    }
228
 
229
    public void setDemoExcludedAmount(BigDecimal demoExcludedAmount) {
230
        this.demoExcludedAmount = scaled(demoExcludedAmount);
231
    }
232
 
233
    public LocalDate getAgedRefreshedOn() {
234
        return agedRefreshedOn;
235
    }
236
 
237
    public void setAgedRefreshedOn(LocalDate agedRefreshedOn) {
238
        this.agedRefreshedOn = agedRefreshedOn;
239
    }
240
 
241
    public BigDecimal getTotalInvestment() {
242
        return totalInvestment;
243
    }
244
 
245
    public void setTotalInvestment(BigDecimal totalInvestment) {
246
        this.totalInvestment = scaled(totalInvestment);
247
    }
248
 
249
    public BigDecimal getBaseValue() {
250
        return baseValue;
251
    }
252
 
253
    public void setBaseValue(BigDecimal baseValue) {
254
        this.baseValue = scaled(baseValue);
255
    }
256
 
257
    public LocalDateTime getSnapshotTimestamp() {
258
        return snapshotTimestamp;
259
    }
260
 
261
    public void setSnapshotTimestamp(LocalDateTime snapshotTimestamp) {
262
        this.snapshotTimestamp = snapshotTimestamp;
263
    }
264
 
265
    @Override
266
    public String toString() {
267
        return "PartnerInvestment{fofoId=" + fofoId
268
                + ", wallet=" + walletAmount
37592 amit 269
                + ", inStockGross=" + inStockGrossAmount
270
                + ", inStockNet=" + getNetInStockAmount()
37588 amit 271
                + ", unbilled=" + unbilledAmount
272
                + ", grnPending=" + grnPendingAmount
273
                + ", activatedStock=" + activatedStockAmount
274
                + ", activatedGrnPending=" + activatedGrnPendingAmount
275
                + ", agedApple=" + agedAppleStockAmount
276
                + ", demoExcluded=" + demoExcludedAmount
277
                + ", utilised=" + utilizedAmount
278
                + ", total=" + totalInvestment
279
                + ", base=" + baseValue
280
                + ", at=" + snapshotTimestamp + '}';
281
    }
282
}