@coursebuilder/core
Version:
Core package for Course Builder
1 lines • 5.67 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/lib/pricing/props-for-commerce.ts"],"sourcesContent":["'use server'\n\nimport { ParsedUrlQuery } from 'querystring'\nimport { isBefore } from 'date-fns'\nimport { Product } from 'src/schemas/product-schema'\nimport { Purchase } from 'src/schemas/purchase-schema'\n\nimport { CourseBuilderAdapter } from '../../adapters'\nimport { Coupon } from '../../schemas'\n\nexport const validateCoupon = async (\n\tcoupon: Coupon | null,\n\tproductIds: string[] = [],\n) => {\n\tif (!coupon) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\tisRedeemable: false,\n\t\t\terror: 'coupon-not-found',\n\t\t}\n\t}\n\n\tconst isUsedUp =\n\t\tcoupon.maxUses > 0 ? coupon.usedCount >= coupon.maxUses : false\n\n\tconst isExpired = coupon.expires\n\t\t? isBefore(new Date(coupon.expires), new Date())\n\t\t: false\n\n\tif (\n\t\tcoupon.restrictedToProductId &&\n\t\t!productIds.includes(coupon.restrictedToProductId)\n\t) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\tisRedeemable: false,\n\t\t\terror: 'coupon-not-valid-for-product',\n\t\t}\n\t}\n\n\tconst isValid = !isUsedUp && !isExpired\n\n\treturn {\n\t\tisExpired,\n\t\tisUsedUp,\n\t\tisRedeemable:\n\t\t\tisValid && Number(coupon.percentageDiscount) >= 1 && !coupon.default,\n\t\tisValid,\n\t}\n}\n\nexport async function getCouponForCode(\n\tcode: string | null,\n\tproductIds: string[] = [],\n\tadapter: CourseBuilderAdapter,\n) {\n\tif (!code) return undefined\n\n\tlet couponFromCode = code && (await adapter.getCoupon(code))\n\n\tif (couponFromCode) {\n\t\tif (\n\t\t\tproductIds.length === 0 &&\n\t\t\tcouponFromCode.restrictedToProductId &&\n\t\t\tcouponFromCode.percentageDiscount === 1\n\t\t) {\n\t\t\tproductIds = [couponFromCode?.restrictedToProductId]\n\t\t}\n\t\tconst validatedCoupon = await validateCoupon(couponFromCode, productIds)\n\t\treturn {\n\t\t\t...couponFromCode,\n\t\t\t...validatedCoupon,\n\t\t}\n\t}\n\n\treturn undefined\n}\n\nexport type PropsForCommerce = {\n\tproducts: Product[]\n\tallowPurchase: boolean\n\tpurchases?: Purchase[] | undefined\n\tcouponIdFromCoupon?: string | undefined\n\tcouponFromCode?: any\n\tuserId?: string | undefined\n\tcountry?: string\n}\n\nexport async function propsForCommerce(\n\t{\n\t\tquery,\n\t\tuserId,\n\t\tproducts,\n\t\tcountryCode = 'US',\n\t}: {\n\t\tquery: ParsedUrlQuery\n\t\tuserId: string | null | undefined\n\t\tproducts: Product[]\n\t\tcountryCode?: string\n\t},\n\tadapter: CourseBuilderAdapter,\n): Promise<PropsForCommerce> {\n\tconst productIds = products.map((product) => product.id)\n\n\tconst couponFromCode = await getCouponForCode(\n\t\t(query.code || query.coupon) as string,\n\t\tproductIds,\n\t\tadapter,\n\t)\n\tconst allowPurchase = true\n\n\tconst purchases = userId ? await adapter.getPurchasesForUser(userId) : false\n\n\tconst couponIdFromCoupon =\n\t\t(query.coupon as string) || (couponFromCode?.isValid && couponFromCode.id)\n\n\treturn {\n\t\t...(userId ? { userId } : {}),\n\t\t...(couponFromCode && {\n\t\t\tcouponFromCode: couponFromCode,\n\t\t}),\n\t\t...(couponIdFromCoupon && { couponIdFromCoupon }),\n\t\t...(purchases && {\n\t\t\tpurchases: [\n\t\t\t\t...purchases.map((purchase) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...purchase,\n\t\t\t\t\t\ttotalAmount:\n\t\t\t\t\t\t\t// because serializer doesnt handle 0.00\n\t\t\t\t\t\t\ttypeof purchase.totalAmount === 'object'\n\t\t\t\t\t\t\t\t? Number(purchase.totalAmount)\n\t\t\t\t\t\t\t\t: purchase.totalAmount,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t],\n\t\t}),\n\t\tproducts,\n\t\tallowPurchase,\n\t\tcountry: countryCode,\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AAGA,sBAAyB;AAOlB,IAAMA,iBAAiB,8BAC7BC,QACAC,aAAuB,CAAA,MAAE;AAEzB,MAAI,CAACD,QAAQ;AACZ,WAAO;MACNE,SAAS;MACTC,cAAc;MACdC,OAAO;IACR;EACD;AAEA,QAAMC,WACLL,OAAOM,UAAU,IAAIN,OAAOO,aAAaP,OAAOM,UAAU;AAE3D,QAAME,YAAYR,OAAOS,cACtBC,0BAAS,IAAIC,KAAKX,OAAOS,OAAO,GAAG,oBAAIE,KAAAA,CAAAA,IACvC;AAEH,MACCX,OAAOY,yBACP,CAACX,WAAWY,SAASb,OAAOY,qBAAqB,GAChD;AACD,WAAO;MACNV,SAAS;MACTC,cAAc;MACdC,OAAO;IACR;EACD;AAEA,QAAMF,UAAU,CAACG,YAAY,CAACG;AAE9B,SAAO;IACNA;IACAH;IACAF,cACCD,WAAWY,OAAOd,OAAOe,kBAAkB,KAAK,KAAK,CAACf,OAAOgB;IAC9Dd;EACD;AACD,GAvC8B;AAyC9B,eAAsBe,iBACrBC,MACAjB,aAAuB,CAAA,GACvBkB,SAA6B;AAE7B,MAAI,CAACD;AAAM,WAAOE;AAElB,MAAIC,iBAAiBH,QAAS,MAAMC,QAAQG,UAAUJ,IAAAA;AAEtD,MAAIG,gBAAgB;AACnB,QACCpB,WAAWsB,WAAW,KACtBF,eAAeT,yBACfS,eAAeN,uBAAuB,GACrC;AACDd,mBAAa;QAACoB,gBAAgBT;;IAC/B;AACA,UAAMY,kBAAkB,MAAMzB,eAAesB,gBAAgBpB,UAAAA;AAC7D,WAAO;MACN,GAAGoB;MACH,GAAGG;IACJ;EACD;AAEA,SAAOJ;AACR;AAzBsBH;AAqCtB,eAAsBQ,iBACrB,EACCC,OACAC,QACAC,UACAC,cAAc,KAAI,GAOnBV,SAA6B;AAE7B,QAAMlB,aAAa2B,SAASE,IAAI,CAACC,YAAYA,QAAQC,EAAE;AAEvD,QAAMX,iBAAiB,MAAMJ,iBAC3BS,MAAMR,QAAQQ,MAAM1B,QACrBC,YACAkB,OAAAA;AAED,QAAMc,gBAAgB;AAEtB,QAAMC,YAAYP,SAAS,MAAMR,QAAQgB,oBAAoBR,MAAAA,IAAU;AAEvE,QAAMS,qBACJV,MAAM1B,UAAsBqB,gBAAgBnB,WAAWmB,eAAeW;AAExE,SAAO;IACN,GAAIL,SAAS;MAAEA;IAAO,IAAI,CAAC;IAC3B,GAAIN,kBAAkB;MACrBA;IACD;IACA,GAAIe,sBAAsB;MAAEA;IAAmB;IAC/C,GAAIF,aAAa;MAChBA,WAAW;WACPA,UAAUJ,IAAI,CAACO,aAAAA;AACjB,iBAAO;YACN,GAAGA;YACHC;;cAEC,OAAOD,SAASC,gBAAgB,WAC7BxB,OAAOuB,SAASC,WAAW,IAC3BD,SAASC;;UACd;QACD,CAAA;;IAEF;IACAV;IACAK;IACAM,SAASV;EACV;AACD;AApDsBJ;","names":["validateCoupon","coupon","productIds","isValid","isRedeemable","error","isUsedUp","maxUses","usedCount","isExpired","expires","isBefore","Date","restrictedToProductId","includes","Number","percentageDiscount","default","getCouponForCode","code","adapter","undefined","couponFromCode","getCoupon","length","validatedCoupon","propsForCommerce","query","userId","products","countryCode","map","product","id","allowPurchase","purchases","getPurchasesForUser","couponIdFromCoupon","purchase","totalAmount","country"]}