Add new lib functions
This commit is contained in:
parent
62f6228f81
commit
22ecae5887
6 changed files with 183 additions and 0 deletions
63
javascripts/src/lib/date.ts
Normal file
63
javascripts/src/lib/date.ts
Normal file
|
@ -0,0 +1,63 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
import * as moment from 'moment';
|
||||
import 'moment-timezone'
|
||||
|
||||
function momentTz(date:string, timezone:string='UTC'):moment.Moment {
|
||||
return moment.tz(date, "YYYY-MM-DD HH:mm:ss", 'UTC').tz(timezone)
|
||||
}
|
||||
|
||||
// Return a date in the format MM/DD/YY for a given date string or moment obj
|
||||
export function readable_date(date?:string, timezone:string='UTC'):string {
|
||||
if(!date) return
|
||||
return momentTz(date,timezone).format("MM/DD/YYYY")
|
||||
}
|
||||
|
||||
// Given a created_at string (eg. Charge.last.created_at.to_s), convert it to a readable date-time string
|
||||
export function readable_date_time(date?:string, timezone:string='UTC'):string {
|
||||
if(!date) return
|
||||
return momentTz(date,timezone).format("MM/DD/YYYY H:mma z")
|
||||
}
|
||||
|
||||
|
||||
// converts the return value of readable_date_time to it's ISO equivalent
|
||||
export function readable_date_time_to_iso(date?:string, timezone:string='UTC') {
|
||||
if(!date) return
|
||||
return moment.tz(date, 'MM/DD/YYYY H:mma z', timezone)
|
||||
.tz('UTC')
|
||||
.toISOString()
|
||||
}
|
||||
|
||||
// Get the month number (eg 01,02...) for the given date string (or moment obj)
|
||||
export function get_month(date:string|moment.Moment) {
|
||||
var monthNum = moment(date).month()
|
||||
return moment().month(monthNum).format('MMM')
|
||||
}
|
||||
|
||||
// Get the year (eg 2017) for the given date string (or moment obj)
|
||||
export function get_year(date:string|moment.Moment) {
|
||||
return moment(date).year()
|
||||
}
|
||||
|
||||
// Get the day (number in the month) for the given date string (or moment obj)
|
||||
export function get_day(date:string|moment.Moment) {
|
||||
return moment(date).date()
|
||||
}
|
||||
|
||||
|
||||
export class NonprofitTimezonedDates {
|
||||
constructor(readonly nonprofitTimezone:string){
|
||||
|
||||
}
|
||||
|
||||
readable_date(date?:string):string{
|
||||
return readable_date(date, this.nonprofitTimezone || 'UTC')
|
||||
}
|
||||
|
||||
readable_date_time(date?:string):string {
|
||||
return readable_date_time(date, this.nonprofitTimezone || 'UTC')
|
||||
}
|
||||
|
||||
readable_date_time_to_iso(date?:string):string {
|
||||
return readable_date_time_to_iso(date, this.nonprofitTimezone || 'UTC')
|
||||
}
|
||||
}
|
22
javascripts/src/lib/dedication.ts
Normal file
22
javascripts/src/lib/dedication.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
export interface Dedication {
|
||||
type?:'honor'|'memory',
|
||||
supporter_id?: number,
|
||||
name?:string
|
||||
contact?: string,
|
||||
note?:string
|
||||
}
|
||||
|
||||
export function parseDedication(dedication?:string) : Dedication {
|
||||
if (!dedication || dedication == "")
|
||||
return {}
|
||||
return JSON.parse(dedication)
|
||||
}
|
||||
|
||||
export function serializeDedication(dedication:Dedication) : string {
|
||||
return JSON.stringify(dedication)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
15
javascripts/src/lib/deprecated_format.ts
Normal file
15
javascripts/src/lib/deprecated_format.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
|
||||
export function pluralize(quantity:number, plural_word:string) : string{
|
||||
var str = String(quantity) + ' '
|
||||
if(quantity !== 1) return str+plural_word
|
||||
else return str + to_singular(plural_word)
|
||||
}
|
||||
|
||||
|
||||
export function to_singular(plural_word:string) : string {
|
||||
return plural_word
|
||||
.replace(/ies$/, 'y')
|
||||
.replace(/oes$/, 'o')
|
||||
.replace(/s$/, '')
|
||||
}
|
22
javascripts/src/lib/format.spec.ts
Normal file
22
javascripts/src/lib/format.spec.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
import * as Format from './format'
|
||||
import 'jest';
|
||||
|
||||
|
||||
describe('Format.dollarsToCents', () => {
|
||||
|
||||
const expectedAmount = 120
|
||||
|
||||
test("accepts negative amounts",() =>
|
||||
expect(Format.dollarsToCents("-1.20")).toBe(expectedAmount* -1)
|
||||
)
|
||||
|
||||
test("strips commas and dollar signs",() =>
|
||||
expect(Format.dollarsToCents("$1,20")).toBe(expectedAmount* 100)
|
||||
)
|
||||
|
||||
test("properly handles slightly shorter than normal decimals",() =>
|
||||
expect(Format.dollarsToCents("$1.2")).toBe(expectedAmount)
|
||||
)
|
||||
|
||||
})
|
57
javascripts/src/lib/format.ts
Normal file
57
javascripts/src/lib/format.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
|
||||
import * as deprecated_format from './deprecated_format'
|
||||
|
||||
export function centsToDollars(cents:string|number|undefined, options:{noCents?:boolean}={}):string {
|
||||
if(cents === undefined) return '0'
|
||||
let centsAsNumber:number = undefined
|
||||
if (typeof cents === 'string')
|
||||
{
|
||||
centsAsNumber = Number(cents)
|
||||
}
|
||||
else {
|
||||
centsAsNumber = cents
|
||||
}
|
||||
return numberWithCommas((centsAsNumber / 100.0).toFixed(options.noCents ? 0 : 2).toString()).replace(/\.00$/,'')
|
||||
}
|
||||
|
||||
export function dollarsToCents(dollars:string) {
|
||||
//strips
|
||||
dollars = dollars.toString().replace(/[$,]/g, '')
|
||||
if(dollars.match(/^-?\d+\.\d$/)) {
|
||||
// could we use toFixed instead? Probably but this is straightforward.
|
||||
dollars = dollars + "0"
|
||||
}
|
||||
if(!dollars.match(/^-?\d+(\.\d\d)?$/)) throw "Invalid dollar amount: " + dollars
|
||||
return Math.round(Number(dollars) * 100)
|
||||
}
|
||||
|
||||
export function numberWithCommas(n:string|number):string {
|
||||
return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ",")
|
||||
}
|
||||
|
||||
export function camelToWords(str:string, os?:any) {
|
||||
if(!str) return str
|
||||
return str.replace(/([A-Z])/g, " $1")
|
||||
}
|
||||
|
||||
export function readableKind(kind:string) {
|
||||
if (kind === "Donation") return "One-Time Donation"
|
||||
else if (kind === "OffsitePayment") return "Offsite Donation"
|
||||
else if (kind === "Ticket") return "Ticket Purchase"
|
||||
else return camelToWords(kind)
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function readableInterval(interval:number, time_unit:string) {
|
||||
if(interval === 1) return time_unit + 'ly'
|
||||
if(interval === 4 && time_unit === 'year') return 'quarterly'
|
||||
if(interval === 2 && time_unit === 'year') return 'biannually'
|
||||
if(interval === 2 && time_unit === 'week') return 'biweekly'
|
||||
if(interval === 2 && time_unit === 'month') return 'bimonthly'
|
||||
else return 'every ' + deprecated_format.pluralize(Number(interval), time_unit + 's')
|
||||
}
|
||||
|
||||
|
||||
|
4
javascripts/src/lib/utils.ts
Normal file
4
javascripts/src/lib/utils.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
// License: LGPL-3.0-or-later
|
||||
export function castToNullIfUndef<T>(i:T): T | null{
|
||||
return i === undefined ? null : i
|
||||
}
|
Loading…
Reference in a new issue