taxtank-core 0.28.70 → 0.28.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,26 +3,40 @@ import { CollectionDictionary } from '../collection-dictionary';
3
3
  import { Dictionary } from '../../models/dictionary/dictionary';
4
4
  export class SoleBusinessLossesCollection extends Collection {
5
5
  /**
6
- * Calculate business losses applied to the current year
6
+ * Business loss applied in current year, includes previous year losses and current year losses for businesses matching offset rule
7
7
  */
8
8
  calculateBusinessLossApplied(transactions) {
9
- const transactionsByBusinessIds = new CollectionDictionary(transactions, 'business.id');
10
- // Dictionary with pairs key = business id, value = business claim amount
9
+ // claim amounts for businesses that can be applied to be reduced by prior year business losses
10
+ const claimAmountsByBusinessId = this.getClaimAmountsByBusinessId(transactions);
11
+ return Object.keys(claimAmountsByBusinessId.items).reduce((sum, businessId) => {
12
+ const loss = this.findBy('business.id', +businessId);
13
+ const lossOpenBalance = (loss === null || loss === void 0 ? void 0 : loss.openBalance) || 0;
14
+ // business loss can be applied to business profit or other income types profit in case in offset rule met
15
+ return sum + (loss.offsetRule ? lossOpenBalance : Math.min(lossOpenBalance, claimAmountsByBusinessId.get(businessId)));
16
+ }, 0);
17
+ }
18
+ /**
19
+ * Get business claim amounts that can be applied to be reduced by prior year business losses:
20
+ * businesses with income or businesses with a loss, but which met the non-commercial loss rules
21
+ * https://www.ato.gov.au/Business/Non-commercial-losses/
22
+ */
23
+ getClaimAmountsByBusinessId(transactions) {
11
24
  const claimAmountsByBusinessId = new Dictionary([]);
12
- transactionsByBusinessIds.keys.forEach((businessId) => {
13
- const businessClaimAmount = transactionsByBusinessIds
25
+ const transactionsByBusinessId = new CollectionDictionary(transactions, 'business.id');
26
+ transactionsByBusinessId.keys.forEach((businessId) => {
27
+ var _a;
28
+ // business loss may not exist if, when creating a business, user didn't add losses for previous years
29
+ const lossOffsetRule = (_a = this.findBy('business.id', +businessId)) === null || _a === void 0 ? void 0 : _a.offsetRule;
30
+ const businessClaimAmount = transactionsByBusinessId
14
31
  .get(businessId)
15
32
  .getClaimAmountByBusinessId(+businessId);
16
- // only businesses with positive income are included in the calculation
17
- if (businessClaimAmount > 0) {
18
- claimAmountsByBusinessId.add(businessId, businessClaimAmount);
33
+ // no way to apply loss for business without profit if offset rules not met
34
+ if (businessClaimAmount < 0 && !lossOffsetRule) {
35
+ return;
19
36
  }
37
+ claimAmountsByBusinessId.add(businessId, businessClaimAmount);
20
38
  });
21
- return Object.keys(claimAmountsByBusinessId.items).reduce((sum, businessId) => {
22
- var _a;
23
- const lossOpenBalance = ((_a = this.findBy('business.id', +businessId)) === null || _a === void 0 ? void 0 : _a.openBalance) || 0;
24
- return sum + Math.min(lossOpenBalance, claimAmountsByBusinessId.get(businessId));
25
- }, 0);
39
+ return claimAmountsByBusinessId;
26
40
  }
27
41
  }
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sZS1idXNpbmVzcy1sb3NzZXMuY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3R0LWNvcmUvc3JjL2xpYi9jb2xsZWN0aW9ucy9zb2xlL3NvbGUtYnVzaW5lc3MtbG9zc2VzLmNvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFaEUsTUFBTSxPQUFPLDRCQUE2QixTQUFRLFVBQTRCO0lBQzVFOztPQUVHO0lBQ0gsNEJBQTRCLENBQUMsWUFBdUM7UUFDbEUsTUFBTSx5QkFBeUIsR0FDN0IsSUFBSSxvQkFBb0IsQ0FDdEIsWUFBWSxFQUNaLGFBQWEsQ0FDZCxDQUFDO1FBRUoseUVBQXlFO1FBQ3pFLE1BQU0sd0JBQXdCLEdBQXVCLElBQUksVUFBVSxDQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRWhGLHlCQUF5QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFrQixFQUFFLEVBQUU7WUFDNUQsTUFBTSxtQkFBbUIsR0FBVyx5QkFBeUI7aUJBQzFELEdBQUcsQ0FBQyxVQUFVLENBQUM7aUJBQ2YsMEJBQTBCLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUUzQyx1RUFBdUU7WUFDdkUsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLEVBQUU7Z0JBQzNCLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsbUJBQW1CLENBQUMsQ0FBQzthQUMvRDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVcsRUFBRSxVQUFrQixFQUFFLEVBQUU7O1lBQzVGLE1BQU0sZUFBZSxHQUFXLENBQUEsTUFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDLFVBQVUsQ0FBQywwQ0FBRSxXQUFXLEtBQUksQ0FBQyxDQUFDO1lBRTFGLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFBO1FBQ2xGLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUNQLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbGxlY3Rpb24gfSBmcm9tICcuLi9jb2xsZWN0aW9uJztcbmltcG9ydCB7IFNvbGVCdXNpbmVzc0xvc3MgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbiB9IGZyb20gJy4uL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7IENvbGxlY3Rpb25EaWN0aW9uYXJ5IH0gZnJvbSAnLi4vY29sbGVjdGlvbi1kaWN0aW9uYXJ5JztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi8uLi9tb2RlbHMvZGljdGlvbmFyeS9kaWN0aW9uYXJ5JztcblxuZXhwb3J0IGNsYXNzIFNvbGVCdXNpbmVzc0xvc3Nlc0NvbGxlY3Rpb24gZXh0ZW5kcyBDb2xsZWN0aW9uPFNvbGVCdXNpbmVzc0xvc3M+IHtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBidXNpbmVzcyBsb3NzZXMgYXBwbGllZCB0byB0aGUgY3VycmVudCB5ZWFyXG4gICAqL1xuICBjYWxjdWxhdGVCdXNpbmVzc0xvc3NBcHBsaWVkKHRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbik6IG51bWJlciB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25zQnlCdXNpbmVzc0lkczogQ29sbGVjdGlvbkRpY3Rpb25hcnk8VHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbj4gPVxuICAgICAgbmV3IENvbGxlY3Rpb25EaWN0aW9uYXJ5PFRyYW5zYWN0aW9uQmFzZUNvbGxlY3Rpb24+KFxuICAgICAgICB0cmFuc2FjdGlvbnMsXG4gICAgICAgICdidXNpbmVzcy5pZCdcbiAgICAgICk7XG5cbiAgICAvLyBEaWN0aW9uYXJ5IHdpdGggcGFpcnMga2V5ID0gYnVzaW5lc3MgaWQsIHZhbHVlID0gYnVzaW5lc3MgY2xhaW0gYW1vdW50XG4gICAgY29uc3QgY2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkOiBEaWN0aW9uYXJ5PG51bWJlcj4gPSBuZXcgRGljdGlvbmFyeTxudW1iZXI+KFtdKTtcblxuICAgIHRyYW5zYWN0aW9uc0J5QnVzaW5lc3NJZHMua2V5cy5mb3JFYWNoKChidXNpbmVzc0lkOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGJ1c2luZXNzQ2xhaW1BbW91bnQ6IG51bWJlciA9IHRyYW5zYWN0aW9uc0J5QnVzaW5lc3NJZHNcbiAgICAgICAgLmdldChidXNpbmVzc0lkKVxuICAgICAgICAuZ2V0Q2xhaW1BbW91bnRCeUJ1c2luZXNzSWQoK2J1c2luZXNzSWQpO1xuXG4gICAgICAvLyBvbmx5IGJ1c2luZXNzZXMgd2l0aCBwb3NpdGl2ZSBpbmNvbWUgYXJlIGluY2x1ZGVkIGluIHRoZSBjYWxjdWxhdGlvblxuICAgICAgaWYgKGJ1c2luZXNzQ2xhaW1BbW91bnQgPiAwKSB7XG4gICAgICAgIGNsYWltQW1vdW50c0J5QnVzaW5lc3NJZC5hZGQoYnVzaW5lc3NJZCwgYnVzaW5lc3NDbGFpbUFtb3VudCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoY2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkLml0ZW1zKS5yZWR1Y2UoKHN1bTogbnVtYmVyLCBidXNpbmVzc0lkOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGxvc3NPcGVuQmFsYW5jZTogbnVtYmVyID0gdGhpcy5maW5kQnkoJ2J1c2luZXNzLmlkJywgK2J1c2luZXNzSWQpPy5vcGVuQmFsYW5jZSB8fCAwO1xuXG4gICAgICByZXR1cm4gc3VtICsgTWF0aC5taW4obG9zc09wZW5CYWxhbmNlLCBjbGFpbUFtb3VudHNCeUJ1c2luZXNzSWQuZ2V0KGJ1c2luZXNzSWQpKVxuICAgIH0sIDApXG4gIH1cbn1cbiJdfQ==
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sZS1idXNpbmVzcy1sb3NzZXMuY29sbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3R0LWNvcmUvc3JjL2xpYi9jb2xsZWN0aW9ucy9zb2xlL3NvbGUtYnVzaW5lc3MtbG9zc2VzLmNvbGxlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUczQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFaEUsTUFBTSxPQUFPLDRCQUE2QixTQUFRLFVBQTRCO0lBQzVFOztPQUVHO0lBQ0gsNEJBQTRCLENBQUMsWUFBdUM7UUFDbEUsK0ZBQStGO1FBQy9GLE1BQU0sd0JBQXdCLEdBQXVCLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVwRyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBVyxFQUFFLFVBQWtCLEVBQUUsRUFBRTtZQUM1RixNQUFNLElBQUksR0FBcUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN2RSxNQUFNLGVBQWUsR0FBVyxDQUFBLElBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxXQUFXLEtBQUksQ0FBQyxDQUFDO1lBRXZELDBHQUEwRztZQUMxRyxPQUFPLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsd0JBQXdCLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6SCxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDUCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLDJCQUEyQixDQUFDLFlBQXVDO1FBQ3pFLE1BQU0sd0JBQXdCLEdBQXVCLElBQUksVUFBVSxDQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRWhGLE1BQU0sd0JBQXdCLEdBQzVCLElBQUksb0JBQW9CLENBQ3RCLFlBQVksRUFDWixhQUFhLENBQ2QsQ0FBQztRQUVKLHdCQUF3QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFrQixFQUFFLEVBQUU7O1lBQzNELHNHQUFzRztZQUN0RyxNQUFNLGNBQWMsR0FBK0IsTUFBQSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDLFVBQVUsQ0FBQywwQ0FBRSxVQUFVLENBQUM7WUFDdkcsTUFBTSxtQkFBbUIsR0FBVyx3QkFBd0I7aUJBQ3pELEdBQUcsQ0FBQyxVQUFVLENBQUM7aUJBQ2YsMEJBQTBCLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUUzQywyRUFBMkU7WUFDM0UsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUU7Z0JBQzlDLE9BQU87YUFDUjtZQUVELHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sd0JBQXdCLENBQUM7SUFDbEMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4uL2NvbGxlY3Rpb24nO1xuaW1wb3J0IHsgU29sZUJ1c2luZXNzTG9zcywgU29sZUJ1c2luZXNzTG9zc09mZnNldFJ1bGUgfSBmcm9tICcuLi8uLi9tb2RlbHMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbiB9IGZyb20gJy4uL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7IENvbGxlY3Rpb25EaWN0aW9uYXJ5IH0gZnJvbSAnLi4vY29sbGVjdGlvbi1kaWN0aW9uYXJ5JztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi8uLi9tb2RlbHMvZGljdGlvbmFyeS9kaWN0aW9uYXJ5JztcblxuZXhwb3J0IGNsYXNzIFNvbGVCdXNpbmVzc0xvc3Nlc0NvbGxlY3Rpb24gZXh0ZW5kcyBDb2xsZWN0aW9uPFNvbGVCdXNpbmVzc0xvc3M+IHtcbiAgLyoqXG4gICAqIEJ1c2luZXNzIGxvc3MgYXBwbGllZCBpbiBjdXJyZW50IHllYXIsIGluY2x1ZGVzIHByZXZpb3VzIHllYXIgbG9zc2VzIGFuZCBjdXJyZW50IHllYXIgbG9zc2VzIGZvciBidXNpbmVzc2VzIG1hdGNoaW5nIG9mZnNldCBydWxlXG4gICAqL1xuICBjYWxjdWxhdGVCdXNpbmVzc0xvc3NBcHBsaWVkKHRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbik6IG51bWJlciB7XG4gICAgLy8gY2xhaW0gYW1vdW50cyBmb3IgYnVzaW5lc3NlcyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGJlIHJlZHVjZWQgYnkgcHJpb3IgeWVhciBidXNpbmVzcyBsb3NzZXNcbiAgICBjb25zdCBjbGFpbUFtb3VudHNCeUJ1c2luZXNzSWQ6IERpY3Rpb25hcnk8bnVtYmVyPiA9IHRoaXMuZ2V0Q2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkKHRyYW5zYWN0aW9ucyk7XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoY2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkLml0ZW1zKS5yZWR1Y2UoKHN1bTogbnVtYmVyLCBidXNpbmVzc0lkOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGxvc3M6IFNvbGVCdXNpbmVzc0xvc3MgPSB0aGlzLmZpbmRCeSgnYnVzaW5lc3MuaWQnLCArYnVzaW5lc3NJZCk7XG4gICAgICBjb25zdCBsb3NzT3BlbkJhbGFuY2U6IG51bWJlciA9IGxvc3M/Lm9wZW5CYWxhbmNlIHx8IDA7XG5cbiAgICAgIC8vIGJ1c2luZXNzIGxvc3MgY2FuIGJlIGFwcGxpZWQgdG8gYnVzaW5lc3MgcHJvZml0IG9yIG90aGVyIGluY29tZSB0eXBlcyBwcm9maXQgaW4gY2FzZSBpbiBvZmZzZXQgcnVsZSBtZXRcbiAgICAgIHJldHVybiBzdW0gKyAobG9zcy5vZmZzZXRSdWxlID8gbG9zc09wZW5CYWxhbmNlIDogTWF0aC5taW4obG9zc09wZW5CYWxhbmNlLCBjbGFpbUFtb3VudHNCeUJ1c2luZXNzSWQuZ2V0KGJ1c2luZXNzSWQpKSk7XG4gICAgfSwgMClcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYnVzaW5lc3MgY2xhaW0gYW1vdW50cyB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGJlIHJlZHVjZWQgYnkgcHJpb3IgeWVhciBidXNpbmVzcyBsb3NzZXM6XG4gICAqIGJ1c2luZXNzZXMgd2l0aCBpbmNvbWUgb3IgYnVzaW5lc3NlcyB3aXRoIGEgbG9zcywgYnV0IHdoaWNoIG1ldCB0aGUgbm9uLWNvbW1lcmNpYWwgbG9zcyBydWxlc1xuICAgKiBodHRwczovL3d3dy5hdG8uZ292LmF1L0J1c2luZXNzL05vbi1jb21tZXJjaWFsLWxvc3Nlcy9cbiAgICovXG4gIHByaXZhdGUgZ2V0Q2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkKHRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbik6IERpY3Rpb25hcnk8bnVtYmVyPiB7XG4gICAgY29uc3QgY2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkOiBEaWN0aW9uYXJ5PG51bWJlcj4gPSBuZXcgRGljdGlvbmFyeTxudW1iZXI+KFtdKTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uc0J5QnVzaW5lc3NJZDogQ29sbGVjdGlvbkRpY3Rpb25hcnk8VHJhbnNhY3Rpb25CYXNlQ29sbGVjdGlvbj4gPVxuICAgICAgbmV3IENvbGxlY3Rpb25EaWN0aW9uYXJ5PFRyYW5zYWN0aW9uQmFzZUNvbGxlY3Rpb24+KFxuICAgICAgICB0cmFuc2FjdGlvbnMsXG4gICAgICAgICdidXNpbmVzcy5pZCdcbiAgICAgICk7XG5cbiAgICB0cmFuc2FjdGlvbnNCeUJ1c2luZXNzSWQua2V5cy5mb3JFYWNoKChidXNpbmVzc0lkOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIGJ1c2luZXNzIGxvc3MgbWF5IG5vdCBleGlzdCBpZiwgd2hlbiBjcmVhdGluZyBhIGJ1c2luZXNzLCB1c2VyIGRpZG4ndCBhZGQgbG9zc2VzIGZvciBwcmV2aW91cyB5ZWFyc1xuICAgICAgY29uc3QgbG9zc09mZnNldFJ1bGU6IFNvbGVCdXNpbmVzc0xvc3NPZmZzZXRSdWxlID0gdGhpcy5maW5kQnkoJ2J1c2luZXNzLmlkJywgK2J1c2luZXNzSWQpPy5vZmZzZXRSdWxlO1xuICAgICAgY29uc3QgYnVzaW5lc3NDbGFpbUFtb3VudDogbnVtYmVyID0gdHJhbnNhY3Rpb25zQnlCdXNpbmVzc0lkXG4gICAgICAgIC5nZXQoYnVzaW5lc3NJZClcbiAgICAgICAgLmdldENsYWltQW1vdW50QnlCdXNpbmVzc0lkKCtidXNpbmVzc0lkKTtcblxuICAgICAgLy8gbm8gd2F5IHRvIGFwcGx5IGxvc3MgZm9yIGJ1c2luZXNzIHdpdGhvdXQgcHJvZml0IGlmIG9mZnNldCBydWxlcyBub3QgbWV0XG4gICAgICBpZiAoYnVzaW5lc3NDbGFpbUFtb3VudCA8IDAgJiYgIWxvc3NPZmZzZXRSdWxlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY2xhaW1BbW91bnRzQnlCdXNpbmVzc0lkLmFkZChidXNpbmVzc0lkLCBidXNpbmVzc0NsYWltQW1vdW50KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjbGFpbUFtb3VudHNCeUJ1c2luZXNzSWQ7XG4gIH1cbn1cbiJdfQ==
@@ -4,6 +4,10 @@ import { SoleBusiness } from './sole-business';
4
4
  import { Type } from 'class-transformer';
5
5
  import { SoleBusinessLossOffsetRule } from './sole-business-loss-offset-rule';
6
6
  import { FinancialYear } from '../financial-year/financial-year';
7
+ /**
8
+ * If a sole trader business makes a tax loss in a current year, you can generally carry forward that loss and offset profit in future years.
9
+ * https://taxtank.atlassian.net/wiki/spaces/TAXTANK/pages/4641357930/Rules+when+a+business+makes+a+loss+Tax+Summary#Offsetting-current-year-business-losses
10
+ */
7
11
  export class SoleBusinessLoss extends SoleBusinessLossBase {
8
12
  constructor() {
9
13
  super(...arguments);
@@ -20,4 +24,4 @@ __decorate([
20
24
  __decorate([
21
25
  Type(() => SoleBusinessLossOffsetRule)
22
26
  ], SoleBusinessLoss.prototype, "offsetRule", void 0);
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sZS1idXNpbmVzcy1sb3NzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHQtY29yZS9zcmMvbGliL21vZGVscy9zb2xlL3NvbGUtYnVzaW5lc3MtbG9zcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLGdCQUFnQixJQUFJLG9CQUFvQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDbkcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFaEUsTUFBTSxPQUFPLGdCQUFpQixTQUFRLG9CQUFvQjtJQUExRDs7UUFPRSxnQkFBVyxHQUFXLENBQUMsQ0FBQztRQUN4QixrQkFBYSxHQUFXLElBQUksYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDO0lBS25ELENBQUM7SUFIQyxJQUFJLFNBQVM7UUFDWCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7Q0FDRjtBQVhDO0lBREMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQztrREFDRjtBQUd2QjtJQURDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQztvREFDQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNvbGVCdXNpbmVzc0xvc3MgYXMgU29sZUJ1c2luZXNzTG9zc0Jhc2UgfSBmcm9tICcuLi8uLi9kYi9Nb2RlbHMvc29sZS9zb2xlLWJ1c2luZXNzLWxvc3MnO1xuaW1wb3J0IHsgU29sZUJ1c2luZXNzIH0gZnJvbSAnLi9zb2xlLWJ1c2luZXNzJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5pbXBvcnQgeyBTb2xlQnVzaW5lc3NMb3NzT2Zmc2V0UnVsZSB9IGZyb20gJy4vc29sZS1idXNpbmVzcy1sb3NzLW9mZnNldC1ydWxlJztcbmltcG9ydCB7IEZpbmFuY2lhbFllYXJ9IGZyb20gJy4uL2ZpbmFuY2lhbC15ZWFyL2ZpbmFuY2lhbC15ZWFyJztcblxuZXhwb3J0IGNsYXNzIFNvbGVCdXNpbmVzc0xvc3MgZXh0ZW5kcyBTb2xlQnVzaW5lc3NMb3NzQmFzZSB7XG4gIEBUeXBlKCgpID0+IFNvbGVCdXNpbmVzcylcbiAgYnVzaW5lc3M6IFNvbGVCdXNpbmVzcztcblxuICBAVHlwZSgoKSA9PiBTb2xlQnVzaW5lc3NMb3NzT2Zmc2V0UnVsZSlcbiAgb2Zmc2V0UnVsZTogU29sZUJ1c2luZXNzTG9zc09mZnNldFJ1bGU7XG5cbiAgb3BlbkJhbGFuY2U6IG51bWJlciA9IDA7XG4gIGZpbmFuY2lhbFllYXI6IG51bWJlciA9IG5ldyBGaW5hbmNpYWxZZWFyKCkueWVhcjtcblxuICBnZXQgaGFzT2Zmc2V0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMub2Zmc2V0UnVsZTtcbiAgfVxufVxuIl19
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sZS1idXNpbmVzcy1sb3NzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHQtY29yZS9zcmMvbGliL21vZGVscy9zb2xlL3NvbGUtYnVzaW5lc3MtbG9zcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLGdCQUFnQixJQUFJLG9CQUFvQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDbkcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFaEU7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGdCQUFpQixTQUFRLG9CQUFvQjtJQUExRDs7UUFPRSxnQkFBVyxHQUFXLENBQUMsQ0FBQztRQUN4QixrQkFBYSxHQUFXLElBQUksYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDO0lBS25ELENBQUM7SUFIQyxJQUFJLFNBQVM7UUFDWCxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7Q0FDRjtBQVhDO0lBREMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQztrREFDRjtBQUd2QjtJQURDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQztvREFDQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNvbGVCdXNpbmVzc0xvc3MgYXMgU29sZUJ1c2luZXNzTG9zc0Jhc2UgfSBmcm9tICcuLi8uLi9kYi9Nb2RlbHMvc29sZS9zb2xlLWJ1c2luZXNzLWxvc3MnO1xuaW1wb3J0IHsgU29sZUJ1c2luZXNzIH0gZnJvbSAnLi9zb2xlLWJ1c2luZXNzJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICdjbGFzcy10cmFuc2Zvcm1lcic7XG5pbXBvcnQgeyBTb2xlQnVzaW5lc3NMb3NzT2Zmc2V0UnVsZSB9IGZyb20gJy4vc29sZS1idXNpbmVzcy1sb3NzLW9mZnNldC1ydWxlJztcbmltcG9ydCB7IEZpbmFuY2lhbFllYXJ9IGZyb20gJy4uL2ZpbmFuY2lhbC15ZWFyL2ZpbmFuY2lhbC15ZWFyJztcblxuLyoqXG4gKiBJZiBhIHNvbGUgdHJhZGVyIGJ1c2luZXNzIG1ha2VzIGEgdGF4IGxvc3MgaW4gYSBjdXJyZW50IHllYXIsIHlvdSBjYW4gZ2VuZXJhbGx5IGNhcnJ5IGZvcndhcmQgdGhhdCBsb3NzIGFuZCBvZmZzZXQgcHJvZml0IGluIGZ1dHVyZSB5ZWFycy5cbiAqIGh0dHBzOi8vdGF4dGFuay5hdGxhc3NpYW4ubmV0L3dpa2kvc3BhY2VzL1RBWFRBTksvcGFnZXMvNDY0MTM1NzkzMC9SdWxlcyt3aGVuK2ErYnVzaW5lc3MrbWFrZXMrYStsb3NzK1RheCtTdW1tYXJ5I09mZnNldHRpbmctY3VycmVudC15ZWFyLWJ1c2luZXNzLWxvc3Nlc1xuICovXG5leHBvcnQgY2xhc3MgU29sZUJ1c2luZXNzTG9zcyBleHRlbmRzIFNvbGVCdXNpbmVzc0xvc3NCYXNlIHtcbiAgQFR5cGUoKCkgPT4gU29sZUJ1c2luZXNzKVxuICBidXNpbmVzczogU29sZUJ1c2luZXNzO1xuXG4gIEBUeXBlKCgpID0+IFNvbGVCdXNpbmVzc0xvc3NPZmZzZXRSdWxlKVxuICBvZmZzZXRSdWxlOiBTb2xlQnVzaW5lc3NMb3NzT2Zmc2V0UnVsZTtcblxuICBvcGVuQmFsYW5jZTogbnVtYmVyID0gMDtcbiAgZmluYW5jaWFsWWVhcjogbnVtYmVyID0gbmV3IEZpbmFuY2lhbFllYXIoKS55ZWFyO1xuXG4gIGdldCBoYXNPZmZzZXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5vZmZzZXRSdWxlO1xuICB9XG59XG4iXX0=
@@ -2409,6 +2409,10 @@ __decorate([
2409
2409
  Type(() => SoleBusinessLossOffsetRule)
2410
2410
  ], SoleBusinessLossOffsetRule.prototype, "parent", void 0);
2411
2411
 
2412
+ /**
2413
+ * If a sole trader business makes a tax loss in a current year, you can generally carry forward that loss and offset profit in future years.
2414
+ * https://taxtank.atlassian.net/wiki/spaces/TAXTANK/pages/4641357930/Rules+when+a+business+makes+a+loss+Tax+Summary#Offsetting-current-year-business-losses
2415
+ */
2412
2416
  class SoleBusinessLoss extends SoleBusinessLoss$1 {
2413
2417
  constructor() {
2414
2418
  super(...arguments);
@@ -5991,26 +5995,40 @@ class Dictionary {
5991
5995
 
5992
5996
  class SoleBusinessLossesCollection extends Collection {
5993
5997
  /**
5994
- * Calculate business losses applied to the current year
5998
+ * Business loss applied in current year, includes previous year losses and current year losses for businesses matching offset rule
5995
5999
  */
5996
6000
  calculateBusinessLossApplied(transactions) {
5997
- const transactionsByBusinessIds = new CollectionDictionary(transactions, 'business.id');
5998
- // Dictionary with pairs key = business id, value = business claim amount
6001
+ // claim amounts for businesses that can be applied to be reduced by prior year business losses
6002
+ const claimAmountsByBusinessId = this.getClaimAmountsByBusinessId(transactions);
6003
+ return Object.keys(claimAmountsByBusinessId.items).reduce((sum, businessId) => {
6004
+ const loss = this.findBy('business.id', +businessId);
6005
+ const lossOpenBalance = (loss === null || loss === void 0 ? void 0 : loss.openBalance) || 0;
6006
+ // business loss can be applied to business profit or other income types profit in case in offset rule met
6007
+ return sum + (loss.offsetRule ? lossOpenBalance : Math.min(lossOpenBalance, claimAmountsByBusinessId.get(businessId)));
6008
+ }, 0);
6009
+ }
6010
+ /**
6011
+ * Get business claim amounts that can be applied to be reduced by prior year business losses:
6012
+ * businesses with income or businesses with a loss, but which met the non-commercial loss rules
6013
+ * https://www.ato.gov.au/Business/Non-commercial-losses/
6014
+ */
6015
+ getClaimAmountsByBusinessId(transactions) {
5999
6016
  const claimAmountsByBusinessId = new Dictionary([]);
6000
- transactionsByBusinessIds.keys.forEach((businessId) => {
6001
- const businessClaimAmount = transactionsByBusinessIds
6017
+ const transactionsByBusinessId = new CollectionDictionary(transactions, 'business.id');
6018
+ transactionsByBusinessId.keys.forEach((businessId) => {
6019
+ var _a;
6020
+ // business loss may not exist if, when creating a business, user didn't add losses for previous years
6021
+ const lossOffsetRule = (_a = this.findBy('business.id', +businessId)) === null || _a === void 0 ? void 0 : _a.offsetRule;
6022
+ const businessClaimAmount = transactionsByBusinessId
6002
6023
  .get(businessId)
6003
6024
  .getClaimAmountByBusinessId(+businessId);
6004
- // only businesses with positive income are included in the calculation
6005
- if (businessClaimAmount > 0) {
6006
- claimAmountsByBusinessId.add(businessId, businessClaimAmount);
6025
+ // no way to apply loss for business without profit if offset rules not met
6026
+ if (businessClaimAmount < 0 && !lossOffsetRule) {
6027
+ return;
6007
6028
  }
6029
+ claimAmountsByBusinessId.add(businessId, businessClaimAmount);
6008
6030
  });
6009
- return Object.keys(claimAmountsByBusinessId.items).reduce((sum, businessId) => {
6010
- var _a;
6011
- const lossOpenBalance = ((_a = this.findBy('business.id', +businessId)) === null || _a === void 0 ? void 0 : _a.openBalance) || 0;
6012
- return sum + Math.min(lossOpenBalance, claimAmountsByBusinessId.get(businessId));
6013
- }, 0);
6031
+ return claimAmountsByBusinessId;
6014
6032
  }
6015
6033
  }
6016
6034