import { TERRITORY_PERIOD_COST } from '@/lib/constants' import { satsToMsats } from '@/lib/format' import { proratedBillingCost } from '@/lib/territory' import { datePivot } from '@/lib/time' export const anonable = false export const supportsPessimism = true export const supportsOptimism = false export async function getCost ({ oldName, billingType }, { models }) { const oldSub = await models.sub.findUnique({ where: { name: oldName } }) const cost = proratedBillingCost(oldSub, billingType) if (!cost) { return 0n } return satsToMsats(cost) } export async function perform ({ oldName, invoiceId, ...data }, { me, cost, tx }) { const oldSub = await tx.sub.findUnique({ where: { name: oldName } }) data.billingCost = TERRITORY_PERIOD_COST(data.billingType) // we never want to bill them again if they are changing to ONCE if (data.billingType === 'ONCE') { data.billPaidUntil = null data.billingAutoRenew = false } // if they are changing to YEARLY, bill them in a year // if they are changing to MONTHLY from YEARLY, do nothing if (oldSub.billingType === 'MONTHLY' && data.billingType === 'YEARLY') { data.billPaidUntil = datePivot(new Date(oldSub.billedLastAt), { years: 1 }) } // if this billing change makes their bill paid up, set them to active if (data.billPaidUntil === null || data.billPaidUntil >= new Date()) { data.status = 'ACTIVE' } if (cost > 0n) { await tx.subAct.create({ data: { userId: me.id, subName: oldName, msats: cost, type: 'BILLING' } }) } return await tx.sub.update({ data, where: { // optimistic concurrency control // make sure none of the relevant fields have changed since we fetched the sub ...oldSub, postTypes: { equals: oldSub.postTypes }, name: oldName, userId: me.id } }) } export async function describe ({ name }, context) { return `SN: update territory billing ${name}` }