根据更改的订阅费计算总订阅费
Calculate total subsciption fee based on changing subscription fees
我正在尝试计算我工作场所的罚款罐的总订阅费。每个月每个人都要在罚款之外支付一定的费用。一开始是 20 丹麦克朗,现在是 25 丹麦克朗。我有两个 json 对象中的 tdata - 一个是人,一个是订阅费
看起来像这样:
subscriptionFees = [
{
"id":2,
"date":"1900-01-01T00:00:00",
"amount":20.0
},
{
"id":1,
"date":"2018-05-01T00:00:00",
"amount":25.0
}
]
persons = [
{
"id":11,
"name":"Camilla",
"active":true,
"startDate":"2017-01-01",
"endDate":"1900-01-01"
},
{
"id":6,
"name":"Cathrine",
"active":true,
"startDate":"2019-03-01",
"endDate":"1900-01-01"
},
{
"id":1,
"name":"John",
"active":true,
"startDate":"2020-03-01",
"endDate":"2021-03-01"
}
]
我的大部分 js 函数都使用 jquery。我想象一个函数 运行 通过 persons-object 并计算每个人的总订阅费。
可能是这样的:
$.each(persons, function (id, obj) {
totalSubscriptionfee = calculateSubscriptionfee(obj.startDate, obj.endDate);
})
function calculateSubscriptionfee(startDate, endDate){
???
}
有人可以帮我计算订阅费功能吗?订阅费以后可能会再次发生变化,所以功能需要能够相应地进行调整。
谢谢,
彼得
我可能把它弄得太复杂了,但不确定还有什么方法可以解决它。这将
- 首先使用
reduce
创建一个包含开始、结束和数量的 ranges
数组
map
persons 数组,遍历 ranges
以获取该范围内的应付金额(如果有)
- 获取总持续时间(以毫秒为单位),转换为粗略的月数近似值,然后使用模数向下舍入。
最后你得到一个新的人员数组 (npersons),其中包含到期总数。
const subscriptionFees = [{
"id": 2,
"date": "1900-01-01T00:00:00",
"amount": 20.0
},
{
"id": 1,
"date": "2018-05-01T00:00:00",
"amount": 25.0
}
]
const persons = [{
"id": 11,
"name": "Camilla",
"active": true,
"startDate": "2017-01-01",
"endDate": "1900-01-01"
},
{
"id": 6,
"name": "Cathrine",
"active": true,
"startDate": "2019-03-01",
"endDate": "1900-01-01"
},
{
"id": 1,
"name": "John",
"active": true,
"startDate": "2020-03-01",
"endDate": "2021-03-01"
}
]
let ranges = subscriptionFees.reduce((acc, a) => {
if (acc.length === 0 || Object.hasOwnProperty(acc[acc.length - 1].end)) {
let tmp = {
start: a.date,
amount: a.amount
};
acc.push(tmp)
} else {
acc[acc.length - 1].end = a.date;
acc.push({
start: a.date,
amount: a.amount
})
}
return acc;
}, [])
ranges[ranges.length - 1].end = new Date();
//console.log('ranges', ranges);
const npersons = persons.map(person => {
let ttl = 0;
// fix endDate
if (new Date(person.endDate).getTime() < new Date(person.startDate).getTime()) person.endDate = new Date();
// iterate ranges
ranges.forEach(a => {
let end = Math.min(new Date(a.end).getTime(), new Date(person.endDate).getTime())
let start = Math.max(new Date(a.start).getTime(), new Date(person.startDate).getTime())
// console.log('calculating', person.name, 'start', new Date(start), 'end', new Date(end));
let interval = end - start;
if (interval > 0){
let tmpttl = Math.floor( (interval / 1000 / 60 / 60 / 24 / 30) * +a.amount)
tmpttl -= tmpttl % a.amount
ttl += tmpttl;
}
})
person.total = ttl
return person
})
console.log(persons)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
我正在尝试计算我工作场所的罚款罐的总订阅费。每个月每个人都要在罚款之外支付一定的费用。一开始是 20 丹麦克朗,现在是 25 丹麦克朗。我有两个 json 对象中的 tdata - 一个是人,一个是订阅费
看起来像这样:
subscriptionFees = [
{
"id":2,
"date":"1900-01-01T00:00:00",
"amount":20.0
},
{
"id":1,
"date":"2018-05-01T00:00:00",
"amount":25.0
}
]
persons = [
{
"id":11,
"name":"Camilla",
"active":true,
"startDate":"2017-01-01",
"endDate":"1900-01-01"
},
{
"id":6,
"name":"Cathrine",
"active":true,
"startDate":"2019-03-01",
"endDate":"1900-01-01"
},
{
"id":1,
"name":"John",
"active":true,
"startDate":"2020-03-01",
"endDate":"2021-03-01"
}
]
我的大部分 js 函数都使用 jquery。我想象一个函数 运行 通过 persons-object 并计算每个人的总订阅费。
可能是这样的:
$.each(persons, function (id, obj) {
totalSubscriptionfee = calculateSubscriptionfee(obj.startDate, obj.endDate);
})
function calculateSubscriptionfee(startDate, endDate){
???
}
有人可以帮我计算订阅费功能吗?订阅费以后可能会再次发生变化,所以功能需要能够相应地进行调整。
谢谢,
彼得
我可能把它弄得太复杂了,但不确定还有什么方法可以解决它。这将
- 首先使用
reduce
创建一个包含开始、结束和数量的 map
persons 数组,遍历ranges
以获取该范围内的应付金额(如果有)- 获取总持续时间(以毫秒为单位),转换为粗略的月数近似值,然后使用模数向下舍入。
ranges
数组
最后你得到一个新的人员数组 (npersons),其中包含到期总数。
const subscriptionFees = [{
"id": 2,
"date": "1900-01-01T00:00:00",
"amount": 20.0
},
{
"id": 1,
"date": "2018-05-01T00:00:00",
"amount": 25.0
}
]
const persons = [{
"id": 11,
"name": "Camilla",
"active": true,
"startDate": "2017-01-01",
"endDate": "1900-01-01"
},
{
"id": 6,
"name": "Cathrine",
"active": true,
"startDate": "2019-03-01",
"endDate": "1900-01-01"
},
{
"id": 1,
"name": "John",
"active": true,
"startDate": "2020-03-01",
"endDate": "2021-03-01"
}
]
let ranges = subscriptionFees.reduce((acc, a) => {
if (acc.length === 0 || Object.hasOwnProperty(acc[acc.length - 1].end)) {
let tmp = {
start: a.date,
amount: a.amount
};
acc.push(tmp)
} else {
acc[acc.length - 1].end = a.date;
acc.push({
start: a.date,
amount: a.amount
})
}
return acc;
}, [])
ranges[ranges.length - 1].end = new Date();
//console.log('ranges', ranges);
const npersons = persons.map(person => {
let ttl = 0;
// fix endDate
if (new Date(person.endDate).getTime() < new Date(person.startDate).getTime()) person.endDate = new Date();
// iterate ranges
ranges.forEach(a => {
let end = Math.min(new Date(a.end).getTime(), new Date(person.endDate).getTime())
let start = Math.max(new Date(a.start).getTime(), new Date(person.startDate).getTime())
// console.log('calculating', person.name, 'start', new Date(start), 'end', new Date(end));
let interval = end - start;
if (interval > 0){
let tmpttl = Math.floor( (interval / 1000 / 60 / 60 / 24 / 30) * +a.amount)
tmpttl -= tmpttl % a.amount
ttl += tmpttl;
}
})
person.total = ttl
return person
})
console.log(persons)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>