Skip to content

Commit

Permalink
feat(mis): 增加配置消费记录精度、最小作业消费金额的功能,默认精度为 2 位小数,默认最小消费金额为 0.01 (#1388)
Browse files Browse the repository at this point in the history
## 做了什么
1、增加配置消费记录精度,默认精度为 2 位小数;
2、最小消费金额的功能默认最小消费金额为 0.01;
3、账户、租户的余额展示精度与消费记录精度一致;
4、充值金额展示的小数位与消费记录的精度保持一致;
5、充值时数值输入框精度与消费记录的精度保持一致。


## 注意
- 如果您想保持之前的版本中的计费逻辑,需要增加配置如下:

```yaml title="config/mis.yaml"
jobChargeDecimalPrecision: 3
jobMinCharge : 0
```

- 如果您设置的最小作业消费金额小于消费记录精度的最小值,scow在启动的时候会抛出错误

---------

Co-authored-by: Chen Junda <[email protected]>
  • Loading branch information
tongchong and ddadaal authored Aug 14, 2024
1 parent 6ab5659 commit 83df60b
Show file tree
Hide file tree
Showing 28 changed files with 1,193 additions and 96 deletions.
11 changes: 11 additions & 0 deletions .changeset/short-deers-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@scow/mis-server": patch
"@scow/mis-web": patch
---

增加配置消费记录精度,默认精度为 2 位小数;
增加最小作业消费金额的功能,默认最小作业消费金额为 0.01;
账户、租户的余额展示精度与消费记录精度一致;
充值金额展示的小数位与消费记录的精度保持一致;
充值时数值输入框精度与消费记录的精度保持一致。

11 changes: 11 additions & 0 deletions .changeset/yellow-sloths-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@scow/config": patch
---

增加配置消费记录精度、最小消费金额的功能,默认精度为 2 位小数,默认最小消费金额为 0.01。
### 注意:此更新必定影响作业计费结果(除非您以前所有计费项价格皆为0)如果您不想更改之前的版本中的计费逻辑,需要增加配置如下:

```yaml title="config/mis.yaml"
jobChargeDecimalPrecision: 3
jobMinCharge : 0
```
2 changes: 0 additions & 2 deletions apps/mis-server/config/mis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ db:

periodicSyncUserAccountBlockStatus:
enabled: false


13 changes: 11 additions & 2 deletions apps/mis-server/src/bl/jobPrice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,18 @@ export async function calculateJobPrice(

amount = amount.multipliedBy(time);

amount = amount.decimalPlaces(3, Decimal.ROUND_DOWN);
amount = amount.decimalPlaces(misConfig.jobChargeDecimalPrecision, Decimal.ROUND_DOWN);

// 如果单价大于0,且运行时间大于0,若结果算下来金额小于默认最低消费金额,按最低消费金额计算价格
if (priceItem.price.gt(0) && time.gt(0)) {
if (priceItem.price.multipliedBy(amount).gt(new Decimal(misConfig.jobMinCharge))) {
return priceItem.price.multipliedBy(amount)
.decimalPlaces(misConfig.jobChargeDecimalPrecision, Decimal.ROUND_HALF_CEIL);
}
return new Decimal(misConfig.jobMinCharge);
}

return priceItem.price.multipliedBy(amount).decimalPlaces(3, Decimal.ROUND_HALF_CEIL);
return new Decimal(0);
}
const accountBase = getPriceItem(path, info.tenant);
const tenantBase = getPriceItem(path);
Expand Down
32 changes: 26 additions & 6 deletions apps/mis-server/tests/job/billingItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
* See the Mulan PSL v2 for more details.
*/

import { after, before } from "node:test";

Check warning on line 13 in apps/mis-server/tests/job/billingItems.test.ts

View workflow job for this annotation

GitHub Actions / Test and version packages

'after' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 13 in apps/mis-server/tests/job/billingItems.test.ts

View workflow job for this annotation

GitHub Actions / Test and version packages

'before' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 13 in apps/mis-server/tests/job/billingItems.test.ts

View workflow job for this annotation

GitHub Actions / Test and version packages

'after' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 13 in apps/mis-server/tests/job/billingItems.test.ts

View workflow job for this annotation

GitHub Actions / Test and version packages

'before' is defined but never used. Allowed unused vars must match /^_/u

import { asyncClientCall } from "@ddadaal/tsgrpc-client";
import { Server } from "@ddadaal/tsgrpc-server";
import { ChannelCredentials } from "@grpc/grpc-js";
Expand All @@ -19,6 +21,7 @@ import { Decimal, decimalToMoney, numberToMoney } from "@scow/lib-decimal";
import { AddBillingItemRequest, JobBillingItem, JobServiceClient } from "@scow/protos/build/server/job";
import { createServer } from "src/app";
import { createPriceMap } from "src/bl/PriceMap";
import { misConfig } from "src/config/mis";
import { AmountStrategy, JobPriceItem } from "src/entities/JobPriceItem";
import { Tenant } from "src/entities/Tenant";
import { createPriceItems } from "src/tasks/createBillingItems";
Expand Down Expand Up @@ -236,15 +239,11 @@ it("adds billing item to another tenant", async () => {
expect(reply.historyItems.length).toBe(0);
});

it("calculates price", async () => {

const calculatePrice = async (testData: typeof import("./testData.json")) => {
const priceMap = await createPriceMap(orm.em.fork(), server.ext.clusters, server.logger);


// obtain test data by running the following data in db
const testData = (await import("./testData.json")).default;

const wrongPrices = [] as {
jobId: number,
tenantPrice: { expected: number; actual: number | undefined };
accountPrice: { expected: number; actual: number | undefined }
}[];
Expand All @@ -266,14 +265,35 @@ it("calculates price", async () => {
});
if (price.tenant?.price.toNumber() !== t.tenantPrice || price.account?.price.toNumber() !== t.accountPrice) {
wrongPrices.push({
jobId: t.jobId,
tenantPrice: { expected: t.tenantPrice, actual: price.tenant?.price.toNumber() },
accountPrice: { expected: t.accountPrice, actual: price.account?.price.toNumber() },
});
}
};

console.log(wrongPrices);

expect(wrongPrices).toBeArrayOfSize(0);
};

it("calculates job price in precision 3 and min charge 0", async () => {

const beforeJobChargeDecimalPrecision = misConfig.jobChargeDecimalPrecision;
const beforeJobMinCharge = misConfig.jobMinCharge;

misConfig.jobChargeDecimalPrecision = 3;
misConfig.jobMinCharge = 0;

await calculatePrice((await import("./testData-precision3.json")).default).finally(() => {

misConfig.jobChargeDecimalPrecision = beforeJobChargeDecimalPrecision;
misConfig.jobMinCharge = beforeJobMinCharge;
});
});

it.only("calculates job prices", async () => {
await calculatePrice((await import("./testData.json")).default);
});

it("gets missing price items in platform scope", async () => {
Expand Down
Loading

0 comments on commit 83df60b

Please sign in to comment.