mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
Compare commits
12 Commits
auto-subsc
...
v0.16.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1372a1f0a8 | ||
|
|
571a332658 | ||
|
|
b44c318a5d | ||
|
|
bd9717f4dc | ||
|
|
f48aea8e5a | ||
|
|
0ac3a5dea9 | ||
|
|
56b40ad4cb | ||
|
|
9b6f934990 | ||
|
|
80e3522f8a | ||
|
|
7975643765 | ||
|
|
2ac7f86bdb | ||
|
|
60248ec3f6 |
@@ -96,7 +96,6 @@ PLAID_LINK_WEBHOOK=
|
||||
PLAID_SANDBOX_REDIRECT_URI=
|
||||
PLAID_DEVELOPMENT_REDIRECT_URI=
|
||||
|
||||
|
||||
# https://docs.lemonsqueezy.com/guides/developer-guide/getting-started#create-an-api-key
|
||||
LEMONSQUEEZY_API_KEY=
|
||||
LEMONSQUEEZY_STORE_ID=
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
<img src="https://img.shields.io/twitter/follow/bigcapitalhq?style=social" alt="twitter" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://app.bigcapital.ly">Bigcapital Cloud</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
# What's Bigcapital?
|
||||
|
||||
@@ -21,16 +21,12 @@ services:
|
||||
depends_on:
|
||||
- server
|
||||
- webapp
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
|
||||
webapp:
|
||||
container_name: bigcapital-webapp
|
||||
image: ghcr.io/bigcapitalhq/webapp:latest
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
|
||||
server:
|
||||
container_name: bigcapital-server
|
||||
@@ -45,9 +41,7 @@ services:
|
||||
- mysql
|
||||
- mongo
|
||||
- redis
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
environment:
|
||||
# Mail
|
||||
- MAIL_HOST=${MAIL_HOST}
|
||||
@@ -92,6 +86,12 @@ services:
|
||||
- GOTENBERG_URL=${GOTENBERG_URL}
|
||||
- GOTENBERG_DOCS_URL=${GOTENBERG_DOCS_URL}
|
||||
|
||||
# Lemon Squeez
|
||||
- LEMONSQUEEZY_API_KEY=${LEMONSQUEEZY_API_KEY}
|
||||
- LEMONSQUEEZY_STORE_ID=${LEMONSQUEEZY_STORE_ID}
|
||||
- LEMONSQUEEZY_WEBHOOK_SECRET=${LEMONSQUEEZY_WEBHOOK_SECRET}
|
||||
- HOSTED_ON_BIGCAPITAL_CLOUD=${HOSTED_ON_BIGCAPITAL_CLOUD}
|
||||
|
||||
database_migration:
|
||||
container_name: bigcapital-database-migration
|
||||
build:
|
||||
@@ -111,9 +111,7 @@ services:
|
||||
|
||||
mysql:
|
||||
container_name: bigcapital-mysql
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
build:
|
||||
context: ./docker/mariadb
|
||||
environment:
|
||||
@@ -128,9 +126,7 @@ services:
|
||||
|
||||
mongo:
|
||||
container_name: bigcapital-mongo
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
build: ./docker/mongo
|
||||
expose:
|
||||
- '27017'
|
||||
@@ -139,9 +135,7 @@ services:
|
||||
|
||||
redis:
|
||||
container_name: bigcapital-redis
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: unless-stopped
|
||||
restart: on-failure
|
||||
build:
|
||||
context: ./docker/redis
|
||||
expose:
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"dependencies": {
|
||||
"@casl/ability": "^5.4.3",
|
||||
"@hapi/boom": "^7.4.3",
|
||||
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",
|
||||
"@types/i18n": "^0.8.7",
|
||||
"@types/knex": "^0.16.1",
|
||||
"@types/mathjs": "^6.0.12",
|
||||
@@ -89,17 +90,17 @@
|
||||
"objection-filter": "^4.0.1",
|
||||
"objection-soft-delete": "^1.0.7",
|
||||
"objection-unique": "^1.2.2",
|
||||
"plaid": "^10.3.0",
|
||||
"pluralize": "^8.0.0",
|
||||
"pug": "^3.0.2",
|
||||
"puppeteer": "^10.2.0",
|
||||
"plaid": "^10.3.0",
|
||||
"qim": "0.0.52",
|
||||
"ramda": "^0.27.1",
|
||||
"rate-limiter-flexible": "^2.1.14",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rtl-detect": "^1.0.4",
|
||||
"source-map-loader": "^4.0.1",
|
||||
"socket.io": "^4.7.4",
|
||||
"source-map-loader": "^4.0.1",
|
||||
"tmp-promise": "^3.0.3",
|
||||
"ts-transformer-keys": "^0.4.2",
|
||||
"tsyringe": "^4.3.0",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Multer from 'multer';
|
||||
import { ServiceError } from '@/exceptions';
|
||||
import { getImportsStoragePath } from '@/services/Import/_utils';
|
||||
|
||||
export function allowSheetExtensions(req, file, cb) {
|
||||
if (
|
||||
@@ -16,7 +17,8 @@ export function allowSheetExtensions(req, file, cb) {
|
||||
|
||||
const storage = Multer.diskStorage({
|
||||
destination: function (req, file, cb) {
|
||||
cb(null, './public/imports');
|
||||
const path = getImportsStoragePath();
|
||||
cb(null, path);
|
||||
},
|
||||
filename: function (req, file, cb) {
|
||||
// Add the creation timestamp to clean up temp files later.
|
||||
|
||||
@@ -38,8 +38,6 @@ export class ImportFileUploadService {
|
||||
filename: string,
|
||||
params: Record<string, number | string>
|
||||
): Promise<ImportFileUploadPOJO> {
|
||||
console.log(filename, 'filename');
|
||||
|
||||
try {
|
||||
return await this.importUnhandled(
|
||||
tenantId,
|
||||
|
||||
@@ -3,6 +3,7 @@ import moment from 'moment';
|
||||
import * as R from 'ramda';
|
||||
import { Knex } from 'knex';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import {
|
||||
defaultTo,
|
||||
upperFirst,
|
||||
@@ -353,7 +354,6 @@ export const parseKey = R.curry(
|
||||
_key = `${fieldKey}`;
|
||||
}
|
||||
}
|
||||
console.log(_key);
|
||||
return _key;
|
||||
}
|
||||
);
|
||||
@@ -432,13 +432,19 @@ export const sanitizeSheetData = (json) => {
|
||||
export const getMapToPath = (to: string, group = '') =>
|
||||
group ? `${group}.${to}` : to;
|
||||
|
||||
export const getImportsStoragePath = () => {
|
||||
return path.join(global.__storage_dir, `/imports`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the imported file from the storage and database.
|
||||
* @param {string} filename
|
||||
*/
|
||||
export const deleteImportFile = async (filename: string) => {
|
||||
const filePath = getImportsStoragePath();
|
||||
|
||||
// Deletes the imported file.
|
||||
await fs.unlink(`public/imports/${filename}`);
|
||||
await fs.unlink(`${filePath}/${filename}`);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -447,5 +453,7 @@ export const deleteImportFile = async (filename: string) => {
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
export const readImportFile = (filename: string) => {
|
||||
return fs.readFile(`public/imports/${filename}`);
|
||||
const filePath = getImportsStoragePath();
|
||||
|
||||
return fs.readFile(`${filePath}/${filename}`);
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ export class LemonSqueezyWebhooks {
|
||||
const variantId = attributes.variant_id as string;
|
||||
|
||||
// We assume that the Plan table is up to date.
|
||||
const plan = await Plan.query().findOne('slug', 'essentials-yearly');
|
||||
const plan = await Plan.query().findOne('slug', 'early-adaptor');
|
||||
|
||||
if (!plan) {
|
||||
throw new Error(`Plan with variantId ${variantId} not found.`);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import moment, { type unitOfTime } from 'moment';
|
||||
import moment, { unitOfTime } from 'moment';
|
||||
|
||||
export default class SubscriptionPeriod {
|
||||
private start: Date;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
exports.up = function (knex) {
|
||||
return knex.seed.run({
|
||||
specific: 'seed_tenants_free_subscription.js',
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex) {};
|
||||
@@ -194,7 +194,12 @@ export default class Tenant extends BaseModel {
|
||||
* @param {*} subscriptionSlug
|
||||
* @returns
|
||||
*/
|
||||
public newSubscription(planId, invoiceInterval, invoicePeriod, subscriptionSlug) {
|
||||
public newSubscription(
|
||||
planId,
|
||||
invoiceInterval,
|
||||
invoicePeriod,
|
||||
subscriptionSlug
|
||||
) {
|
||||
return Tenant.newSubscription(
|
||||
this.id,
|
||||
planId,
|
||||
@@ -202,7 +207,6 @@ export default class Tenant extends BaseModel {
|
||||
invoicePeriod,
|
||||
subscriptionSlug
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
exports.seed = (knex) => {
|
||||
// Deletes ALL existing entries
|
||||
return knex('subscription_plan_subscriptions')
|
||||
.then(async () => {
|
||||
const tenants = await knex('tenants');
|
||||
|
||||
for (const tenant of tenants) {
|
||||
const existingSubscription = await knex('subscription_plan_subscriptions')
|
||||
.where('tenantId', tenant.id)
|
||||
.first();
|
||||
|
||||
if (!existingSubscription) {
|
||||
const freePlan = await knex('subscription_plans').where('slug', 'free').first();
|
||||
|
||||
await knex('subscription_plan_subscriptions').insert({
|
||||
tenantId: tenant.id,
|
||||
planId: freePlan.id,
|
||||
slug: 'main',
|
||||
startsAt: knex.fn.now(),
|
||||
endsAt: null,
|
||||
createdAt: knex.fn.now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
1
packages/server/storage/.gitignore
vendored
1
packages/server/storage/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
*
|
||||
!pdf/
|
||||
!imports/
|
||||
!.gitignore
|
||||
2
packages/server/storage/imports/.gitignore
vendored
Normal file
2
packages/server/storage/imports/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
||||
'@hapi/boom':
|
||||
specifier: ^7.4.3
|
||||
version: 7.4.11
|
||||
'@lemonsqueezy/lemonsqueezy.js':
|
||||
specifier: ^2.2.0
|
||||
version: 2.2.0
|
||||
'@types/i18n':
|
||||
specifier: ^0.8.7
|
||||
version: 0.8.8
|
||||
@@ -4623,6 +4626,11 @@ packages:
|
||||
resolution: {integrity: sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==}
|
||||
dev: false
|
||||
|
||||
/@lemonsqueezy/lemonsqueezy.js@2.2.0:
|
||||
resolution: {integrity: sha512-DsZTeowehSLTESUZ6xxoYPDhoE8BYepWsj3TCqibG7FvB8X1HERPXQlc6E/IeGj22SOfIM997b7GfFkeLWY8pA==}
|
||||
engines: {node: '>=18'}
|
||||
dev: false
|
||||
|
||||
/@lerna/add@6.4.1:
|
||||
resolution: {integrity: sha512-YSRnMcsdYnQtQQK0NSyrS9YGXvB3jzvx183o+JTH892MKzSlBqwpBHekCknSibyxga1HeZ0SNKQXgsHAwWkrRw==}
|
||||
engines: {node: ^14.15.0 || >=16.0.0}
|
||||
|
||||
Reference in New Issue
Block a user