根据更改的订阅费计算总订阅费

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>