Compare commits

...

876 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
7bf008a9cb fix(server): filter ledger entries that effect contact balance to AR/AP accounts only 2023-06-11 19:23:31 +02:00
Ahmed Bouhuolia
4d9e3ccfb4 fix(server): disable webpack minification for class name reading 2023-06-08 22:38:43 +02:00
Ahmed Bouhuolia
1bfe19f26c fix: change the default charset value 2023-06-08 13:19:58 +02:00
Ahmed Bouhuolia
a371cedb67 Merge pull request #130 from bigcapitalhq/normalized
fix docker-compose line-ending issue on Windows
2023-06-06 20:40:42 +02:00
Ahmed Bouhuolia
4ed9c36ebd feat: set default value to env vars 2023-06-06 20:37:42 +02:00
ElforJani13
e24b23ce7e 🐛 FIX: 2023-06-06 19:49:25 +02:00
Ahmed Bouhuolia
19fe6e2423 fix: normalize nginx bash the line endings 2023-06-06 18:37:21 +02:00
Ahmed Bouhuolia
aec09f178b Merge pull request #128 from bigcapitalhq/BIG-435-migrate-to-maria-db-v-11
feat: migrate the server to MariaDB
2023-06-04 14:45:47 +02:00
Ahmed Bouhuolia
ffe51bae07 feat: migrate the server to MariaDB 2023-06-04 14:38:53 +02:00
Ahmed Bouhuolia
68231d5edb Merge pull request #125 from bigcapitalhq/docker-compose-env-variables
feat: add env variable to customize the proxy public ports
2023-05-31 20:30:44 +02:00
a.bouhuolia
e1ea5c402c feat: add env variable to customize the proxy public ports 2023-05-31 20:29:37 +02:00
a.bouhuolia
34b2c2c8b4 fix: copy package-lock.json inside the container 2023-05-31 13:07:30 +02:00
a.bouhuolia
5d96fe6aa0 chore(webapp): remove Sentry from webapp 2023-05-31 09:59:35 +02:00
Ameir Abdeldayem
d2b5084b42 chore: fix typo in README file (#124) 2023-05-30 10:46:51 +02:00
a.bouhuolia
81fb0734d5 update CHANGELOG 2023-05-28 15:04:31 +02:00
a.bouhuolia
3639ce44e5 chore: bump CHANGELOG v0.9.1 2023-05-28 15:02:14 +02:00
Ahmed Bouhuolia
a7c00d60d5 Merge pull request #121 from bigcapitalhq/BIG-429-clean-up-the-auto-increment-of-transactions
fix: the auto-increment of transactions.
2023-05-28 14:50:43 +02:00
a.bouhuolia
932750b62d fix(webapp): fix credit note and receipt auto-increment 2023-05-28 14:45:34 +02:00
a.bouhuolia
c90ffed67f fix(webapp): payment receive auto-increment 2023-05-26 00:02:47 +02:00
a.bouhuolia
e92c4486aa fix(webapp): auto-increment estimate transactions 2023-05-25 22:04:21 +02:00
a.bouhuolia
aaceea5338 fix(webapp): warehouse and branch reset on invoice form 2023-05-24 23:52:05 +02:00
a.bouhuolia
4d54d180bc fix(webapp): invoice transactions increment 2023-05-24 23:28:09 +02:00
Ahmed Bouhuolia
8fdd98e34d Merge pull request #122 from bigcapitalhq/BIG-434-delete-invoice-transaction-issue
fix(server): delete invoice transaction
2023-05-23 15:12:43 +02:00
a.bouhuolia
d53c5ee5e6 fix(server): delete invoice transaction 2023-05-23 15:11:56 +02:00
a.bouhuolia
4082e4e2b8 fix: auto-increment transaction field 2023-05-23 14:39:57 +02:00
a.bouhuolia
0c689459cb fix: auto-increment cashflow transactions 2023-05-23 13:56:35 +02:00
a.bouhuolia
40ef02f215 fix: auto-increment settings 2023-05-22 21:57:43 +02:00
a.bouhuolia
d369f0bb17 fix: the auto-increment of transactions. 2023-05-19 00:29:35 +02:00
Ahmed Bouhuolia
425d0293cc Merge pull request #120 from bigcapitalhq/BIG-433-fix-base-currency-should-be-enabled-with-account-model
BIG-433-fix-base-currency-should-be-enabled-with-account-model
2023-05-12 15:58:48 +02:00
a.bouhuolia
b621650975 fix(server): base currency should be enabled with account model. 2023-05-12 15:58:01 +02:00
a.bouhuolia
40948160fe fix(webapp): localization 2023-05-12 12:46:59 +02:00
Ahmed Bouhuolia
aa6b9dd295 Merge pull request #118 from bigcapitalhq/BIG-428-clean-up-the-preferences-pages
fix(webapp): general, accoutant and items preferences
2023-05-12 12:36:19 +02:00
a.bouhuolia
05c2232b97 chore(webapp): refactor the setup organization form to use Formik binded component 2023-05-12 12:31:55 +02:00
Ahmed Bouhuolia
8f6325d529 Merge pull request #119 from bigcapitalhq/fix-delete-journals-manual-journal
fix(server): deleting ledger entries of manual journal
2023-05-12 00:14:36 +02:00
a.bouhuolia
0aa681043d fix(server): deleting ledger entries of manual journal 2023-05-11 22:46:34 +02:00
a.bouhuolia
40bddfdfeb fix(webapp): accrual typo 2023-05-11 21:07:49 +02:00
a.bouhuolia
d6e2f01d70 fix(server): accrual typo 2023-05-11 21:07:01 +02:00
a.bouhuolia
2344d3d34d fix(webapp): general, accoutant and items preferences 2023-05-11 01:47:09 +02:00
a.bouhuolia
883c5dcb41 Merge branch 'signup-restrictions' into develop 2023-05-08 00:36:50 +02:00
a.bouhuolia
be10b8934d fix(webapp): change the error code handler 2023-05-08 00:35:44 +02:00
a.bouhuolia
ce38c71fa7 fix(server): should allowed email addresses and domain be irrespective. 2023-05-08 00:35:28 +02:00
Ahmed Bouhuolia
1162fbc7c3 Merge pull request #117 from bigcapitalhq/signup-restrictions
Sign-up restrictions for self-hosted
2023-05-08 00:18:56 +02:00
a.bouhuolia
18b9e25f2b chore: update .env.example 2023-05-07 23:59:41 +02:00
a.bouhuolia
dd26bdc482 feat(webapp): sign-up restrictions 2023-05-07 23:54:42 +02:00
a.bouhuolia
ad3c9ebfe9 feat(server): sign-up restrictions for self-hosted 2023-05-07 17:22:18 +02:00
a.bouhuolia
36611652da fix(webapp): resource meta of vendors list 2023-05-05 15:41:32 +02:00
a.bouhuolia
06c7ee71b4 fix(webapp): display transactions count in cashflow account 2023-05-05 13:54:45 +02:00
Ahmed Bouhuolia
54d3188666 Merge pull request #116 from bigcapitalhq/BIG-427-fix-sending-invite-email
fix(server): sending invite email
2023-05-05 00:30:24 +02:00
a.bouhuolia
3ceb9adda2 fix(server): sending invite email 2023-05-05 00:28:57 +02:00
Ahmed Bouhuolia
1249415054 Merge pull request #115 from bigcapitalhq/BIG-409-some-flag-icons-are-missing
fix(webapp): some flag icons are missing
2023-05-04 21:32:10 +02:00
a.bouhuolia
4d44ce4c7f fix(webapp): some flag icons are missing 2023-05-04 21:29:12 +02:00
Ahmed Bouhuolia
6c96c371c5 Merge pull request #114 from bigcapitalhq/BIG-279-select-specific-accounts-in-general-ledger-does-not-working
`BIG-279` Select specific accounts in general ledger does not working.
2023-05-04 14:29:35 +02:00
a.bouhuolia
6c61a69f10 feat(webapp): handle create item on Accounts select components 2023-05-04 14:24:45 +02:00
a.bouhuolia
981b65349d feat(webapp): allow to create a new account item in accounts list component. 2023-05-03 22:41:54 +02:00
a.bouhuolia
a7d29a31c8 refactor(webapp): all services with new AccountSelect and AccountMultiSelect components. 2023-05-01 00:13:23 +02:00
a.bouhuolia
c1d92b74f0 chore(Select):style the Select button. 2023-04-30 21:13:33 +02:00
a.bouhuolia
6f0f47f38a refactor(webapp): Accounts Select and MultiSelect components 2023-04-30 17:33:15 +02:00
a.bouhuolia
83510cfa70 feat(server): add structure query flat or tree to accounts chart endpoint 2023-04-30 17:24:49 +02:00
a.bouhuolia
903dc0522a chore: add CONTRIBUTING.md file 2023-04-27 01:56:46 +02:00
Ahmed Bouhuolia
eecbcacb90 Merge pull request #112 from bigcapitalhq/BIG-417-fcy-bcy-cashflow-accounts-transactions-api
Add FCY/BCY transactions to the account drawer.
2023-04-20 06:14:25 +02:00
a.bouhuolia
cfbe4cfea0 fix(webapp): FCY/BCY typo 2023-04-20 06:10:25 +02:00
a.bouhuolia
8f039b77e7 fix(server): foreign currency in account transactions transformer 2023-04-19 06:16:21 +02:00
a.bouhuolia
672a1bbb82 feat(webapp): add FCY/BCY switch to the account transactions 2023-04-19 06:15:13 +02:00
Ahmed Bouhuolia
b2f3585047 Merge pull request #111 from bigcapitalhq/improve-webapp-users
refactor(webapp): invite and user form with new blueprintjs-formik components
2023-04-14 03:53:11 +02:00
Ahmed Bouhuolia
e6434ea2d1 Merge pull request #110 from bigcapitalhq/avoid-delete-base-currency
fix(server): prevent delete base currency
2023-04-14 03:51:10 +02:00
Ahmed Bouhuolia
a21d6a37e4 Merge pull request #109 from bigcapitalhq/BIG-419-delete-invited-user
fix(server): prevent deleting last user in the tenant
2023-04-14 03:50:28 +02:00
a.bouhuolia
e9fdffa9d9 refactor(webapp): invite and user form with new blueprintjs-formik components 2023-04-14 03:48:43 +02:00
a.bouhuolia
6bd30abddb fix(server): prevent delete base currency 2023-04-14 03:45:09 +02:00
a.bouhuolia
920c8ea95c feat(server): add user transformer 2023-04-14 03:43:39 +02:00
a.bouhuolia
8de3717587 fix(server): prevent deleting last user in the tenant 2023-04-14 03:41:11 +02:00
Ahmed Bouhuolia
cc863f774a Merge pull request #108 from bigcapitalhq/e2e-init
feat: setup e2e
2023-04-13 02:56:16 +02:00
a.bouhuolia
bcd08284b4 chore: add vercel rewrite 2023-04-13 02:50:55 +02:00
a.bouhuolia
8e8161f207 feat: add playwright base url 2023-04-13 02:38:22 +02:00
a.bouhuolia
7b4b50cf4b feat: setup e2e 2023-04-13 02:31:56 +02:00
Lars Scheibling
bca3e51fdf fix: typo in docker-compose.prod.yml (#107)
MAIL_USERNAME instead of MAIL_USERNAM
2023-04-12 19:29:04 +02:00
Ahmed Bouhuolia
6faa378577 Merge pull request #105 from bigcapitalhq/docker-compose-user-permissions
fix: docker-compose environment values
2023-04-07 18:57:47 +02:00
a.bouhuolia
012b13ad4a add comments 2023-04-07 18:50:45 +02:00
a.bouhuolia
ad8770f12c fix: docker-compose enviroment values 2023-04-07 18:41:03 +02:00
a.bouhuolia
c6cdbe11e6 fix(server): initalize root dirs on CLI 2023-04-06 05:11:20 +02:00
a.bouhuolia
308980604a chore: dump v0.8.3 CHANGELOG 2023-04-06 04:35:37 +02:00
a.bouhuolia
32148a3207 fix(webapp): change intent type of reset password success toast 2023-04-06 04:32:26 +02:00
Ahmed Bouhuolia
fe270b3703 Merge pull request #104 from bigcapitalhq/auth-pages-tweaks
Fix issues in authentication process.
2023-04-06 03:13:03 +02:00
a.bouhuolia
950b5407c3 feat(server): remove the phone number from users management 2023-04-06 03:08:51 +02:00
a.bouhuolia
e4a647376c feat(server): remove the phone number from users service 2023-04-06 03:08:06 +02:00
a.bouhuolia
85b24c7a4f feat(server): remove phone number from authentication endpoints 2023-04-05 23:57:26 +02:00
a.bouhuolia
4a22576d88 Merge branch 'develop' into auth-pages-tweaks 2023-04-05 23:44:41 +02:00
Ahmed Bouhuolia
d1ab64e9bd Merge pull request #102 from bigcapitalhq/named-docker-volumes
feat: configure named docker volumes
2023-04-05 04:39:48 +02:00
Ahmed Bouhuolia
110fdbaa4e Merge pull request #103 from bigcapitalhq/agpl
chore: switch to AGPL to protect networks
2023-04-05 04:39:18 +02:00
a.bouhuolia
dedd3460a8 chore: switch to AGPL to protect networks 2023-04-05 04:38:06 +02:00
a.bouhuolia
961ff74880 feat(server): remove phone number from authentication process 2023-04-05 04:18:12 +02:00
a.bouhuolia
da20b7c837 feat(webapp): add all countries to the setup organization page 2023-04-05 01:30:36 +02:00
a.bouhuolia
a5c190e094 feat(webapp): from phone number fields from authentication pages 2023-04-04 23:51:36 +02:00
a.bouhuolia
7177276b12 feat(webapp): style tweaks to authentication pages 2023-04-04 23:38:04 +02:00
a.bouhuolia
65bb3a1cb8 feat: configure named docker volumes 2023-04-04 00:31:41 +02:00
Ahmed Bouhuolia
b24a367438 fix(server): fix migrations and seeds dir (#101) 2023-03-31 02:26:23 +02:00
Ahmed Bouhuolia
1ffa3a4b8b Merge pull request #100 from bigcapitalhq/migration-container-server-layer
fix: use the docker server image layer in migration image
2023-03-30 04:18:29 +02:00
a.bouhuolia
bc7a016fcc fix: use the server image layer in migration image 2023-03-30 04:17:39 +02:00
Ahmed Bouhuolia
0445eaedb3 feat: dockernize webapp and server packages
Dockernize webapp and server packages and configure CI/CD for automated dockerization.
2023-03-30 03:58:22 +02:00
a.bouhuolia
03753384d3 feat: dockernize webapp and server packages 2023-03-30 03:55:59 +02:00
Ahmed Bouhuolia
bd80e7f7be Merge pull request #96 from bigcapitalhq/linces-software-GPL2
chore: license the software to GPLv2
2023-03-27 18:08:17 +02:00
a.bouhuolia
b38eeec600 chore: license the software to GPLv2 2023-03-27 18:06:27 +02:00
Ahmed Bouhuolia
faefd0b91d Update README.md 2023-03-26 18:51:30 +02:00
a.bouhuolia
aa89a83a83 chore: update CHANGELOG 2023-03-26 18:40:20 +02:00
a.bouhuolia
3fbb809e3d Merge branch 'develop' into main 2023-03-26 18:25:00 +02:00
a.bouhuolia
a17ef17d56 fix(webapp): content typo 2023-03-26 18:20:29 +02:00
a.bouhuolia
04cdd7c989 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2023-03-26 17:35:23 +02:00
a.bouhuolia
10fd576c38 fix(webapp): login page tweaks. 2023-03-26 17:35:08 +02:00
Ahmed Bouhuolia
54e6478211 Merge pull request #94 from bigcapitalhq/dependabot/npm_and_yarn/webpack-5.76.0
chore(deps-dev): bump webpack from 5.75.0 to 5.76.0
2023-03-19 01:13:34 +02:00
dependabot[bot]
a4d101fae9 chore(deps-dev): bump webpack from 5.75.0 to 5.76.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.75.0 to 5.76.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.75.0...v5.76.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 10:55:30 +00:00
Ahmed Bouhuolia
41a68cf5e8 Merge pull request #90 from bigcapitalhq/docker-dev-prod
feat: add docker compose for development env.
2023-03-09 00:45:42 +02:00
Ahmed Bouhuolia
3076bc2684 Update vercel.json 2023-03-09 00:26:38 +02:00
Ahmed Bouhuolia
d244227023 Update vercel.json 2023-03-09 00:24:33 +02:00
Ahmed Bouhuolia
9007aca856 Update index.tsx 2023-03-09 00:12:56 +02:00
a.bouhuolia
061fc4fc18 chore: add vercel config file 2023-03-09 00:07:52 +02:00
a.bouhuolia
65c23949e6 chore: update frozen package-lock.json 2023-03-08 23:17:36 +02:00
Ahmed Bouhuolia
efa56624a9 Delete .vercelignore 2023-03-08 22:19:11 +02:00
Ahmed Bouhuolia
123573f022 Delete vercel.json 2023-03-08 22:12:12 +02:00
Ahmed Bouhuolia
7302ec4464 Update vercel.json 2023-03-08 22:11:58 +02:00
a.bouhuolia
2d9859cde0 Merge branch 'develop' into docker-dev-prod 2023-03-07 21:14:34 +02:00
a.bouhuolia
8c3d6b61d6 fix(webapp): import issue. 2023-03-07 21:13:49 +02:00
Ahmed Bouhuolia
0ce9c93077 Merge pull request #92 from bigcapitalhq/BIG-423-optimize-the-setup-pages-design
feat(webapp): optimize the setup organization page design
2023-03-07 20:43:44 +02:00
Ahmed Bouhuolia
c3a2ea5064 Merge pull request #89 from bigcapitalhq/BIG-422-deprecated-the-subscription-module
feat(server): deprecate the subscription module.
2023-03-07 20:42:11 +02:00
a.bouhuolia
28de827a99 chore(webapp): remove the un-used import 2023-03-07 20:41:09 +02:00
a.bouhuolia
b4559703f9 feat(webapp): optimize the setup organization page design 2023-03-06 23:05:21 +02:00
Ahmed Bouhuolia
7532b44a57 Merge pull request #91 from bigcapitalhq/vercel-ignore
fix: remove the ignore script from vercel.
2023-03-06 01:55:34 +02:00
Ahmed Bouhuolia
a142b734d3 fix: remove the ignore script from vercel. 2023-03-06 01:54:51 +02:00
a.bouhuolia
f26ced97fe feat(webapp): deprecate the subscription from webapp. 2023-03-05 13:21:06 +02:00
a.bouhuolia
25fb280e29 feat: add docker compose for development env. 2023-03-04 23:10:09 +02:00
a.bouhuolia
0c1bf302e5 feat(webapp): deprecate the subscription step in onboarding process 2023-03-04 23:08:02 +02:00
a.bouhuolia
57e3f68219 feat(server): deprecated the subscription module. 2023-03-02 22:49:46 +02:00
a.bouhuolia
3b79ac66ae feat(server): deprecated the subscription module. 2023-03-02 22:44:14 +02:00
a.bouhuolia
44fc26b156 feat(server): deprecated the subscription module. 2023-03-02 21:34:06 +02:00
Ahmed Bouhuolia
d46f8faf26 Merge pull request #88 from bigcapitalhq/BIG-411-no-icon-on-the-duplicate-item-menu
fix(webapp): add icon to duplicate item of items context menu
2023-02-16 22:34:58 +02:00
a.bouhuolia
2263cf5657 fix(webapp): add icon to duplicate item of items context menu 2023-02-16 22:34:14 +02:00
Ahmed Bouhuolia
058d525afc Merge pull request #87 from bigcapitalhq/BIG-412-inconsistent-style-of-quick-customer-vendor-drawer
fix(webapp): inconsistent style of quick customer/vendor drawer
2023-02-16 22:10:37 +02:00
a.bouhuolia
490b8e09f2 fix(webapp): inconsistent style of quick customer/vendor drawer 2023-02-16 22:09:18 +02:00
Ahmed Bouhuolia
e488c0eea9 Merge pull request #86 from bigcapitalhq/BIG-421-account-form-issues
fix: BIG-421 account form issues
2023-02-15 21:55:03 +02:00
a.bouhuolia
f093239a15 fix(webapp): retrieve nested graph accounts 2023-02-15 21:53:50 +02:00
a.bouhuolia
5c537e094d fix(server): retrieve nested graph accounts 2023-02-15 21:53:13 +02:00
a.bouhuolia
a371fd44f7 chore: update package-lock.json 2023-02-15 00:01:46 +02:00
Ahmed Bouhuolia
59cb168331 Merge pull request #85 from bigcapitalhq/BIG-414-control-max-nested-accounts-to-be-6-levels
feat(server): validate the max depth level of the parent account.
2023-02-14 23:48:45 +02:00
a.bouhuolia
8a5fbfc041 feat(server): validate the max depth level of the parent account. 2023-02-14 23:47:24 +02:00
Ahmed Bouhuolia
e3a072e267 Merge pull request #84 from bigcapitalhq/BIG-406-accounts-chart-lags-scroll-down
fix(webapp): accounts chart lags scroll down
2023-02-14 23:25:43 +02:00
a.bouhuolia
b03606406e fix(webapp): accounts chart lags scroll down 2023-02-14 23:20:01 +02:00
a.bouhuolia
a1a7ee2b5b chore: add ignoreCommand to vercel configure 2023-02-13 21:38:37 +02:00
a.bouhuolia
228ae71a1c Merge https://github.com/bigcapitalhq/client into develop 2023-02-13 21:26:59 +02:00
a.bouhuolia
71a8d3e77f chore: add file to vercel 2023-02-13 21:26:46 +02:00
Ahmed Bouhuolia
4ddeb927cc Merge pull request #83 from bigcapitalhq/bigcapital-cli
feat(server): bigcapital cli commands
2023-02-13 20:51:03 +02:00
a.bouhuolia
72c1685fa6 feat(server): move all cli commands codebase to be TS based. 2023-02-13 20:47:09 +02:00
a.bouhuolia
7e7ee24109 feat(server): bigcapital cli commands 2023-02-09 23:38:13 +02:00
Ahmed Bouhuolia
708d971717 ci: change webapp package name. 2023-02-08 23:35:41 +02:00
Ahmed Bouhuolia
7781d092ca ci: webapp Github actions (#81) 2023-02-08 23:33:03 +02:00
a.bouhuolia
d0e84fb51a chore: update vercel config 2023-02-08 00:02:43 +02:00
a.bouhuolia
0e673ffa7c chore: update Vercel config 2023-02-08 00:00:49 +02:00
a.bouhuolia
4c4c73db2d chore: add Vercel config file. 2023-02-07 23:57:52 +02:00
a.bouhuolia
0086ee5186 chore: change build script 2023-02-07 23:30:46 +02:00
a.bouhuolia
bb49fcb42b WIP 2023-02-07 23:07:19 +02:00
a.bouhuolia
d47b1165c4 chore: change supported node engine version. 2023-02-07 21:35:21 +02:00
a.bouhuolia
f2e1efcb45 chore(server): prettify files 2023-02-07 20:25:22 +02:00
a.bouhuolia
2e3b2cbf92 chore: add husky for commit message lint 2023-02-07 20:24:44 +02:00
a.bouhuolia
68e61429aa chore: update README.md 2023-02-07 19:30:13 +02:00
a.bouhuolia
646be4bb20 chore: add .gitkeep directory 2023-02-07 19:28:38 +02:00
a.bouhuolia
dfd8b0ca4e chore: remove the bin from the server. 2023-02-07 19:27:57 +02:00
a.bouhuolia
2ab1a5606a chore: update package-lock.json 2023-02-07 01:20:24 +02:00
Ahmed Bouhuolia
c33370d4d2 Merge pull request #75 from bigcapitalhq/lerna
Lerna
2023-02-06 23:39:28 +02:00
Ahmed Bouhuolia
c83e248648 Update README.md 2023-02-06 23:38:35 +02:00
a.bouhuolia
903fdc601a chore: update CHANGELOG.md 2023-02-06 22:06:44 +02:00
a.bouhuolia
d1a9b2aa00 chore: add CHANGLOG.md 2023-02-06 22:05:27 +02:00
a.bouhuolia
ff036b78b3 chore: add supported node version. 2023-02-06 21:50:08 +02:00
a.bouhuolia
b9f730e5b3 Merge branch 'lerna' of https://github.com/bigcapitalhq/client into lerna 2023-02-06 21:45:32 +02:00
a.bouhuolia
ec8b67452d feat: add README. 2023-02-06 21:45:24 +02:00
Ahmed Bouhuolia
37ab05768f Add files via upload 2023-02-05 22:47:21 +02:00
a.bouhuolia
995abbcc29 chore: change mono package scripts. 2023-02-03 15:14:30 +02:00
a.bouhuolia
32543b8762 fix: change root directory. 2023-02-03 15:13:16 +02:00
a.bouhuolia
80b97b5fdc add server to monorepo. 2023-02-03 11:57:50 +02:00
a.bouhuolia
28e309981b fix: move github build configure out. 2023-02-03 01:13:03 +02:00
a.bouhuolia
7a0a13f9d5 re-structure to monorepo. 2023-02-03 01:02:31 +02:00
a.bouhuolia
8242ec64ba dumo changelog. 2023-02-02 20:01:24 +02:00
a.bouhuolia
e900966cb2 fix: customer/vendor drawer new transaction link. 2023-01-26 23:08:19 +02:00
Ahmed Bouhuolia
24407bd744 Merge pull request #72 from bigcapitalhq/BIG-403-labels-of-add-money-in-out-menu-do-not-work
fix(cashflow): labels of Add money in/out don't appear.
2023-01-26 22:39:08 +02:00
Ahmed Bouhuolia
2176a8be1e Merge branch 'develop' into BIG-403-labels-of-add-money-in-out-menu-do-not-work 2023-01-26 22:38:44 +02:00
a.bouhuolia
9ca2aab58f fix(account-drawer): description placeholder. 2023-01-26 22:34:01 +02:00
a.bouhuolia
036180695f fix(financial-statement): BIG-405 reports filter from/to dates out of the range. 2023-01-26 22:25:51 +02:00
a.bouhuolia
dc99b1f128 fix(account-form): BIG-401 Edit account form initial values do not fill up automatically. 2023-01-26 22:11:26 +02:00
a.bouhuolia
21199c45fa fix(projects): disappear the info button in case the feature was not enabled. 2023-01-26 00:45:35 +02:00
Ahmed Bouhuolia
729fce9c70 Merge pull request #73 from bigcapitalhq/BIG-408-hide-the-project-name-entry-if-the-feature-was-not-enabled
fix(projects): hide the project name entry if the feature was not ena…
2023-01-26 00:07:13 +02:00
a.bouhuolia
7689e5bbe7 fix(projects): hide the project name entry if the feature was not enabled. 2023-01-26 00:05:58 +02:00
a.bouhuolia
96ac46ca64 fix(cashflow): labels of Add money in/out don't appear. 2023-01-25 00:14:11 +02:00
a.bouhuolia
806e4fb54c fix(FinancialStatements): Hide filtering by branches/warehouses if the feature is not enabled. 2023-01-23 22:52:45 +02:00
a.bouhuolia
49f3465265 fix(DataTable): text style of table header. 2023-01-23 22:45:59 +02:00
a.bouhuolia
31d665e91e fix(projects): fetch projects if the feature was enabled. 2023-01-23 16:38:36 +02:00
a.bouhuolia
130008168a Merge branch 'develop' into main 2022-11-06 16:14:41 +02:00
a.bouhuolia
7de66f16ce fix: change the default sidebar width of the dashboard. 2022-11-06 16:08:39 +02:00
Ahmed Bouhuolia
9b9b43d065 Merge pull request #62 from bigcapitalhq/feature/projects
feat: add project.
2022-11-06 16:03:01 +02:00
a.bouhuolia
048fcda9dc fix(projects): optimize style time entry form. 2022-10-05 23:29:13 +02:00
a.bouhuolia
f9a7021f55 feat: Add Box, Group and Stack layout components. 2022-10-04 00:29:48 +02:00
a.bouhuolia
41db96d958 feat(projects): WIP projects service. 2022-10-02 21:33:23 +02:00
elforjani13
900a237a52 feat: project detail 2022-09-26 01:05:28 +02:00
elforjani13
6363576c5e feat: project detail. 2022-09-25 22:57:53 +02:00
elforjani13
3c3f8c6731 fix: project task dialog. 2022-09-25 22:29:51 +02:00
elforjani13
8ac881cfd7 feat: add project billable entries link & alert. 2022-09-25 22:27:40 +02:00
elforjani13
6055184084 feat: add api project billable entries dialog. 2022-09-25 22:24:06 +02:00
elforjani13
b83faef167 feat: add project billable entries cell. 2022-09-21 05:19:21 +02:00
elforjani13
d102f33698 Merge branch 'feature/projects' of https://github.com/bigcapitalhq/client into feature/projects 2022-09-20 18:58:25 +02:00
elforjani13
942644f8d5 feat: project billable entries dialog 2022-09-20 18:57:22 +02:00
elforjani13
20d9a23260 feat: project billable entries dialog. 2022-09-20 18:56:03 +02:00
elforjani13
7ac9f78366 fix: project billable entries dilaog 2022-09-20 01:24:23 +02:00
elforjani13
777f6a11cd fix: add ignore Ts errors to project billable 2022-09-20 01:13:27 +02:00
elforjani13
785c407a73 Merge branch 'feature/projects' of https://github.com/bigcapitalhq/client into feature/projects 2022-09-19 22:38:31 +02:00
elforjani13
860378f00d fix: project task form dialog. 2022-09-19 22:37:48 +02:00
elforjani13
01e2c24387 feat: add project billable entries dialog. 2022-09-19 22:37:11 +02:00
a.bouhuolia
84a903361e fix: ignore TS errors to speed up the TS compiling. 2022-09-19 21:16:02 +02:00
elforjani13
2ae720821e feat: add project invoicing cell. 2022-09-08 21:44:16 +02:00
elforjani13
c75f46d8a4 feat: add Project invoicing form dialog. 2022-09-08 21:43:34 +02:00
elforjani13
d77fcb7c89 feat: add project ability. 2022-08-30 19:18:19 +02:00
elforjani13
7c6a85d1d4 feat: add project to expenses 2022-08-30 18:50:28 +02:00
elforjani13
dd264eed65 feat: add project to journal 2022-08-30 18:49:05 +02:00
elforjani13
6b37dcd8ae feat: add project list field cell 2022-08-30 18:48:08 +02:00
elforjani13
5c3a7effc1 feat: add project profitability summary. 2022-08-22 19:56:27 +02:00
elforjani13
69c4519647 feat: add project select to sales & purchases 2022-08-11 11:20:52 +02:00
elforjani13
95137f4fcd feat: add project select. 2022-08-07 21:31:57 +02:00
elforjani13
7c0aa9b353 fix: project time entry form. 2022-08-06 22:16:03 +02:00
elforjani13
3753097ea6 fix: add projects status 2022-08-06 12:37:40 +02:00
elforjani13
93da3ed41d fix: edit project task form. 2022-08-06 12:37:08 +02:00
elforjani13
c5a6a72fa5 fix: project timesheet table. 2022-08-06 12:35:41 +02:00
elforjani13
4cb7a50a1d fix: edit project time entry. 2022-08-06 12:34:41 +02:00
elforjani13
5c8c3586e0 fix: project task form. 2022-07-31 18:43:32 +02:00
elforjani13
2e7ba59beb feat: add project time entry. 2022-07-31 18:32:50 +02:00
elforjani13
7350fef5c4 feat: add currency code to project task form. 2022-07-30 15:12:25 +02:00
elforjani13
1b13b98899 feat: add api project timesheet. 2022-07-30 15:10:23 +02:00
elforjani13
72c893c255 fix: project tasks. 2022-07-29 23:42:37 +02:00
elforjani13
fcf001a831 feat: add api project tasks. 2022-07-28 21:14:36 +02:00
elforjani13
a17843ddbe feat: add project. 2022-07-16 04:20:17 +02:00
a.bouhuolia
399ba8fb8e chores: remove unnecessary stories. 2022-07-15 23:36:03 +02:00
a.bouhuolia
f00097f6c8 chore: Refactoring all import directories to alias and all .js|.jsx renamed to be .ts|.tsx 2022-07-15 23:25:23 +02:00
elforjani13
cd08d0ee16 feat: add transaction select. 2022-06-23 21:51:34 +02:00
elforjani13
f268b8a95a feat: project status. 2022-06-23 19:41:09 +02:00
elforjani13
6a06950654 feat: project status. 2022-06-23 19:37:29 +02:00
elforjani13
d9de3341fe feat: add timesheet header. 2022-06-23 17:50:14 +02:00
elforjani13
6b6081e32e feat: add project & timesheet table. 2022-06-23 00:15:47 +02:00
elforjani13
7be568b8ac feat: time entry dialog. 2022-06-23 00:14:49 +02:00
elforjani13
50522af72d fix: task form dialog. 2022-06-23 00:13:46 +02:00
elforjani13
0b454d6d4d feat: project table. 2022-06-23 00:12:17 +02:00
elforjani13
4ba64cc4ff feat: add project timesheet. 2022-06-23 00:10:06 +02:00
elforjani13
5128c021b0 fix: project form. 2022-06-23 00:07:21 +02:00
elforjani13
5a8fcc8fb5 feat: add time entry form. 2022-06-15 16:09:21 +02:00
elforjani13
9cf1b993dd feat: add time entry form. 2022-06-15 16:08:50 +02:00
elforjani13
f443a1b106 fix: project detail tabs. 2022-06-15 11:38:20 +02:00
elforjani13
0eb0aee1ef feat: project detail tabs. 2022-06-14 17:19:59 +02:00
elforjani13
4b992c4bb4 fix: project details. 2022-06-13 17:55:52 +02:00
elforjani13
051681e6f3 feat: add timesheet & project details. 2022-06-13 17:33:54 +02:00
Ahmed Bouhuolia
629c790430 Merge pull request #57 from bigcapitalhq/BIG-379-create-a-project
`BIG-379` Add project & task dialog & projects list.
2022-06-12 13:07:29 +02:00
elforjani13
bdadc5d795 fix: remove the inner container. 2022-06-12 12:55:37 +02:00
elforjani13
23bb9c4cc3 fix: rename project & task form dialog. 2022-06-12 12:43:03 +02:00
elforjani13
8136378725 fix: project & task dialog. 2022-06-12 11:56:06 +02:00
elforjani13
4eac2239b1 feat: add projects view tabs. 2022-06-12 09:43:19 +02:00
elforjani13
a44f548ff9 feat: projects actions bar. 2022-06-11 15:30:11 +02:00
elforjani13
327916da4b fix: add FDateInput 2022-06-11 13:58:04 +02:00
elforjani13
bee7896279 fix: project form. 2022-06-11 13:29:33 +02:00
elforjani13
cb0a315ca6 feat: add task form dialog. 2022-06-11 00:45:31 +02:00
elforjani13
d2c907541a feat: add project form dialog. 2022-06-11 00:38:00 +02:00
elforjani13
928d4d3f00 feat: add projects list. 2022-06-11 00:36:18 +02:00
a.bouhuolia
4d00f53600 feat: release v1.7.6-rc.2 version. 2022-04-23 00:46:16 +02:00
a.bouhuolia
5e293e4f19 Merge branch 'develop' into main 2022-04-23 00:42:23 +02:00
Ahmed Bouhuolia
01038136f2 Update CHANGELOG.md 2022-04-23 00:41:18 +02:00
a.bouhuolia
6bc5eec8b6 Merge branch 'develop' into main 2022-04-23 00:38:28 +02:00
a.bouhuolia
1172e69d96 chore: add 1.7.4-rc.2 CHANGELOG. 2022-04-23 00:37:18 +02:00
a.bouhuolia
87758bf773 chore(Sidebar): docs. 2022-04-23 00:28:26 +02:00
a.bouhuolia
5cbb3c84e6 Merge branch 'BIG-374-refactoring-sidebar-menu-with-feature-and-permissions-control' into develop 2022-04-22 23:42:45 +02:00
a.bouhuolia
52924383bd feat(Sidebar): filter sidebar items based on subscription state. 2022-04-18 01:24:11 +02:00
a.bouhuolia
8d1825a065 feature(Sidebar): BIG-374 filtering the sidebar items based on each item feature support. 2022-04-18 00:16:37 +02:00
a.bouhuolia
5e4e9c37c3 feat(Sidebar): add the missing sidebar items. 2022-04-17 05:19:23 +02:00
a.bouhuolia
944bc29f4d feat(Sidebar): Refactoring sidebar menu with feature and permissions abilities control. 2022-04-17 05:05:35 +02:00
a.bouhuolia
682b296f7c fix(FlexGrid): BIG-378 Reports drawers columns css conflict. 2022-04-15 22:33:08 +02:00
Ahmed Bouhuolia
e662bf7af9 Update CHANGELOG.md 2022-04-15 06:34:18 +02:00
a.bouhuolia
a829ceb709 Merge branch 'develop' into main 2022-04-15 06:29:34 +02:00
a.bouhuolia
cdce00187b Merge branch 'feature/tooltip-oneline' into develop 2022-04-15 06:26:42 +02:00
a.bouhuolia
91a38b34cc feat: add readonly entriese details as oneline with tooltip for more details. 2022-04-15 06:24:24 +02:00
a.bouhuolia
1b97a162e8 Merge branch 'BIG-entries-columns' of https://github.com/bigcapitalhq/client into develop 2022-04-15 04:36:08 +02:00
elforjani13
e8e12e63ea feat: add tooltip cell to detail. 2022-04-10 13:46:05 +02:00
elforjani13
80feba6005 feat(sales/purchases): add tooltip cell to detail. 2022-04-09 02:04:31 +02:00
elforjani13
cc457e1e43 feat: estimate tooltip. 2022-04-09 00:42:34 +02:00
a.bouhuolia
2ced5dc013 feat(TextOverlayTooltip): WIP 2022-04-08 06:04:12 +02:00
Ahmed Bouhuolia
dd86c2993e Merge pull request #50 from bigcapitalhq/BIG-372-activate-branches-and-warehouses-dialog-reloading-once-activating
BIG-372: activate branches & warehouses reloading.
2022-04-08 05:21:31 +02:00
a.bouhuolia
bd05a4a188 fix(GeneralLedger): BIG-373 Issue general ledger report select specific account. 2022-04-08 05:19:11 +02:00
elforjani13
8160cbe402 feat: add entries-columns. 2022-04-06 16:52:44 +02:00
elforjani13
0ef6bebfb8 BIG-372: activate branches & warehouses reloading. 2022-04-06 15:00:30 +02:00
a.bouhuolia
91ff3fdccb Merge branch 'main' into develop 2022-04-05 06:08:54 +02:00
a.bouhuolia
edd37fff78 fix(PaymaentViaVocher): make the plan is fixed. 2022-04-05 06:06:02 +02:00
a.bouhuolia
679f7ce96c Merge branch 'develop' into main 2022-04-05 05:27:28 +02:00
Ahmed Bouhuolia
79b3ab9ec7 Update CHANGELOG.md 2022-04-05 05:26:48 +02:00
a.bouhuolia
e7158b7ba7 feat(i18n): add the missing arabic localization. 2022-04-05 05:25:26 +02:00
Ahmed Bouhuolia
569bc1c4a4 Merge pull request #49 from bigcapitalhq/billingplans
Billingplans
2022-04-05 05:16:28 +02:00
elforjani13
b880732087 feat: add billing plans. 2022-04-04 23:52:29 +02:00
elforjani13
b1e7720bd9 BIG-378: add Localize to invoice. 2022-04-04 17:58:39 +02:00
a.bouhuolia
5eb9968095 Merge branch 'develop' into main 2022-03-31 15:09:25 +02:00
Ahmed Bouhuolia
b0cf8f723f Merge pull request #47 from bigcapitalhq/BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero
BIG-354: Validate the warehouse transfer.
2022-03-31 15:05:34 +02:00
Ahmed Bouhuolia
b0a826e62a Merge branch 'develop' into BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero 2022-03-31 15:05:27 +02:00
elforjani13
6daa9f09a5 BIG-354: fix validate the warehouse transfer. 2022-03-31 14:58:36 +02:00
Ahmed Bouhuolia
f828d85880 Merge pull request #45 from bigcapitalhq/BIG-344-add-branch-details-to-manual-journal-and-expense-drawer-details
BIG-344: add branch to manual journal & expense.
2022-03-31 14:56:35 +02:00
elforjani13
46d895bef9 BIG-354: Validate the warehouse transfer. 2022-03-31 14:50:40 +02:00
Ahmed Bouhuolia
1fa26c7cb7 Merge pull request #46 from bigcapitalhq/BIG-278-fix-created-at-in-expense-details
BIG-278: add created_at in expense details.
2022-03-31 14:30:21 +02:00
a.bouhuolia
41d2fc63cb chore(Changelog): add the missing logs. 2022-03-31 14:08:22 +02:00
a.bouhuolia
4814a40fa9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-31 14:07:21 +02:00
a.bouhuolia
b903aa3eb2 dump v1.7.2 version with changelogs. 2022-03-31 14:07:17 +02:00
elforjani13
872b98fb0d BIG-278: add created_at in expense details. 2022-03-31 13:57:07 +02:00
elforjani13
b849bfaa95 BIG-344: add branch to manual journal & expense. 2022-03-31 13:39:15 +02:00
Ahmed Bouhuolia
756af3c4d3 Merge pull request #43 from bigcapitalhq/BIG-141-add-inactive-status-to-item-drawer-details
Big 141 add inactive status to item drawer details
2022-03-31 00:52:51 +02:00
Ahmed Bouhuolia
b935d13918 Merge branch 'develop' into BIG-141-add-inactive-status-to-item-drawer-details 2022-03-31 00:52:41 +02:00
Ahmed Bouhuolia
4aea9cb19b Merge pull request #41 from bigcapitalhq/BIG-356-add-localize-remove-line-entries
Big 356 add localize remove line entries
2022-03-31 00:51:38 +02:00
Ahmed Bouhuolia
d22212e6e3 Merge branch 'develop' into BIG-356-add-localize-remove-line-entries 2022-03-31 00:51:28 +02:00
Ahmed Bouhuolia
6a6ff16c48 Merge pull request #44 from bigcapitalhq/BIG-238-validate-bill-due-date-should-be-equal-or-bigger-than-bill-date
Big 238 validate bill due date should be equal or bigger than bill date
2022-03-31 00:49:31 +02:00
Ahmed Bouhuolia
d08894820d Merge pull request #39 from bigcapitalhq/BIG-354-validate-the-warehouse-transfer-quantity-should-be-above-zero
BIG-354: warehouse transfer validate.
2022-03-31 00:49:07 +02:00
elforjani13
2db32b8ee8 BIG-141: add inactive status to item details. 2022-03-30 17:17:23 +02:00
elforjani13
86c6de361b BIG-356: add localize remove line entries. 2022-03-30 16:34:51 +02:00
elforjani13
9bd13b0d46 BIG-355: remove expandable in item categories. 2022-03-30 16:31:34 +02:00
elforjani13
30b17d697f BIG-355: remove expandable in item categories. 2022-03-30 16:28:42 +02:00
elforjani13
ce674466fe BIG-238: Validate bill due date. 2022-03-30 15:09:11 +02:00
elforjani13
373a695c4c BIG-236: Validate estimate expiration date. 2022-03-30 15:06:58 +02:00
elforjani13
3f4ffdc995 BIG-237: Validate invoice due date. 2022-03-30 15:04:55 +02:00
elforjani13
a9c2a5c5f0 BIG-354: warehouse transfer validate. 2022-03-28 21:38:56 +02:00
a.bouhuolia
908d232cb9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-28 19:26:09 +02:00
a.bouhuolia
10af33f1dc fix: BIG-352 Add terms and conditions/notes field to a warehouse transfer. 2022-03-28 19:25:06 +02:00
a.bouhuolia
767d807490 fix: BIG-352 Add terms and conditions/notes field to a warehouse transfer. 2022-03-28 19:06:38 +02:00
Ahmed Bouhuolia
ba1d945dca Merge pull request #38 from bigcapitalhq/BIG-284-cash-flow-statement-loading-bar-not-working
BIG-284: cash flow statement loading bar.
2022-03-28 16:23:42 +02:00
elforjani13
03ea8643e7 BIG-284: cash flow statment loading bar. 2022-03-28 16:18:54 +02:00
Ahmed Bouhuolia
3d78e5d397 Merge pull request #36 from bigcapitalhq/BIG-301-fix-navbar-divider-in-action-bar-detail-casl-ability
fix: navbar divider.
2022-03-28 16:07:20 +02:00
Ahmed Bouhuolia
fffd255eb1 Merge pull request #37 from bigcapitalhq/BIG-add-keepPreviousData
BIG: add keepPreviousData option on use query.
2022-03-28 16:05:42 +02:00
Ahmed Bouhuolia
d0f09a0164 Merge pull request #34 from bigcapitalhq/BIG-351-invalid-date-in-the-inventory-adjustment-detail
Big 351 invalid date in the inventory adjustment detail
2022-03-28 16:01:37 +02:00
elforjani13
7774d9f5ab BIG: add keepPreviousData . 2022-03-28 16:01:07 +02:00
Ahmed Bouhuolia
e5ab240dfd Merge pull request #33 from bigcapitalhq/BIG-221-remove-non-inventory-radio-choice-on-item-form
BIG-221: remove non inventory radio.
2022-03-28 15:54:59 +02:00
elforjani13
2b07917399 BIG-352: invalid date. 2022-03-28 15:48:36 +02:00
elforjani13
79099e1abc BIG-280: optimize select. 2022-03-28 15:46:37 +02:00
elforjani13
e87b22801b BIG-221: remove non inventory radio. 2022-03-28 13:46:41 +02:00
elforjani13
e0eaa56b5c fix: navbar divider. 2022-03-28 13:26:21 +02:00
a.bouhuolia
d842722183 fix: add the missed imported warehouse transfers. 2022-03-28 12:08:53 +02:00
a.bouhuolia
9c14f10edf Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-03-28 12:01:39 +02:00
a.bouhuolia
6a8137729f fix(Account): BIG-296 Issue when creating a new child account from chart of accounts list. 2022-03-28 12:01:29 +02:00
a.bouhuolia
5c601fcf2d fix(Account): BIG-296 Issue when creating a new child account from chart of accounts list. 2022-03-28 11:58:12 +02:00
a.bouhuolia
df4c4a832b Merge branch 'develop' into main 2022-03-24 15:32:30 +02:00
elforjani13
86cab7988c feat: handle item error. 2022-03-24 15:03:25 +02:00
Ahmed Bouhuolia
8404fee10a dump v1.7.0-rc.1 2022-03-24 13:12:14 +02:00
elforjani13
99a23889bc feat: add warehouses transfers query. 2022-03-24 12:19:46 +02:00
elforjani13
5e2000d252 feat: add invalidate item warehouses. 2022-03-24 11:50:06 +02:00
a.bouhuolia
73cb0ec32e feat(InventoryItemDetail): Location query. 2022-03-23 21:28:13 +02:00
a.bouhuolia
8fc11b3237 feat(InventoryValuation): location query. 2022-03-23 21:26:19 +02:00
a.bouhuolia
eecb81e882 feat(JournalSheet): location query. 2022-03-23 18:34:19 +02:00
a.bouhuolia
2e743f2232 feat(GeneralLedger): location query. 2022-03-23 18:18:34 +02:00
a.bouhuolia
3faa765a07 feat(TrialBalance): location query. 2022-03-23 18:18:08 +02:00
a.bouhuolia
a6d93170df fix(BalanceSheet): filter by branches.
fix(ProfitLossSheet): filter by branches.
fix(CashflowStatement): filter by branches.
2022-03-23 16:47:22 +02:00
Ahmed Bouhuolia
3d9b95cbcf Merge pull request #31 from bigcapitalhq/feature/multi-dimensions
Implement foreign currency and multiply warehouses, branches.
2022-03-23 12:12:50 +02:00
Ahmed Bouhuolia
4882afd63f Merge branch 'develop' into feature/multi-dimensions 2022-03-23 12:12:20 +02:00
elforjani13
8dac7e3d98 fix: localization. 2022-03-23 00:30:21 +02:00
elforjani13
6e6b005fc9 fix: reports. 2022-03-23 00:11:04 +02:00
elforjani13
68323486e2 fix: items query. 2022-03-23 00:10:45 +02:00
elforjani13
fd357196a8 fix: warehouse transfer. 2022-03-23 00:10:05 +02:00
elforjani13
5a508dd789 fix: customer/vendor opening balance . 2022-03-23 00:09:08 +02:00
elforjani13
bac6812d36 fix: branch & warehouse activate. 2022-03-23 00:08:16 +02:00
elforjani13
ba71679b55 Fix: expenses. 2022-03-23 00:07:16 +02:00
elforjani13
bc0f4f4cd9 Fix: make journal. 2022-03-23 00:04:13 +02:00
elforjani13
4e53b3a2d5 Fix: purchases. 2022-03-22 23:59:05 +02:00
elforjani13
a913b84723 Fix: sales. 2022-03-22 23:58:03 +02:00
elforjani13
50f1979c9f Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-21 20:13:34 +02:00
elforjani13
3722afdc47 feat(customer & vendor detail): localization. 2022-03-21 20:13:07 +02:00
a.bouhuolia
5711fb8366 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-21 20:10:20 +02:00
a.bouhuolia
09f4d0fbe0 feat(Warehouses|Branches): highlight the primary warehouses and branches. 2022-03-21 20:10:10 +02:00
elforjani13
918780bf4c Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-21 20:03:52 +02:00
elforjani13
8b78fbdb86 feat(branch & warehouse activate): localization. 2022-03-21 20:03:18 +02:00
a.bouhuolia
2c0291da84 fix(ExchangeRateMutatedField): optimize style. 2022-03-21 19:46:30 +02:00
a.bouhuolia
a17fafbc90 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-21 18:32:05 +02:00
a.bouhuolia
701c32debd feat(Warehouses|Branches): empty status text. 2022-03-21 18:31:31 +02:00
elforjani13
70e1e94a4a fix(form footer):missing. 2022-03-21 17:58:20 +02:00
a.bouhuolia
90c77d80eb fix(ItemEntries): align checkbox. 2022-03-21 16:13:50 +02:00
a.bouhuolia
932afddf11 fix: remote line min lines. 2022-03-21 13:41:07 +02:00
a.bouhuolia
a533c3cb76 fix(Datatable): actions cell align center. 2022-03-21 13:27:59 +02:00
a.bouhuolia
2f36594459 fix(DataTable): cells type. 2022-03-21 13:15:10 +02:00
a.bouhuolia
a093c0d335 fix(PaymentMadeForm|PaymentReceiveForm): keep previous data of due invoices. 2022-03-20 20:54:07 +02:00
elforjani13
120f8d15ec feat: add warehouse transfer 2022-03-20 20:17:29 +02:00
elforjani13
65bb05d498 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-20 20:14:23 +02:00
elforjani13
64d73fa7b9 feat: add warehouse transfer & expenses & journal. 2022-03-20 20:13:49 +02:00
a.bouhuolia
928e903fe0 fix(WarehouseTransfer): set item cost to form entries. 2022-03-20 19:00:50 +02:00
elforjani13
23261e975d Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-20 17:58:15 +02:00
elforjani13
e51f203ca8 feat(purchases): add purchases. 2022-03-20 17:56:37 +02:00
a.bouhuolia
35f40503f3 feat(ExpenseForm): optimize style fo expense form. 2022-03-20 17:23:35 +02:00
a.bouhuolia
f86845ea91 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-20 16:45:24 +02:00
a.bouhuolia
29fbcf1f1c fix(WarehouseTransfer). 2022-03-20 16:43:49 +02:00
elforjani13
39a68f5c25 feat(Sales): add sales. 2022-03-20 16:16:22 +02:00
a.bouhuolia
89b28903fa fix: change the min lines of entries. 2022-03-20 12:21:16 +02:00
a.bouhuolia
4f7e9caedb Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-20 12:04:24 +02:00
a.bouhuolia
ef91afe041 feat(InvoiceFormat): invoice footer totals. 2022-03-20 12:04:17 +02:00
elforjani13
dd5e10ef83 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-03-20 11:21:59 +02:00
elforjani13
acdec70385 feat(S&P): Form Footer. 2022-03-20 11:20:13 +02:00
a.bouhuolia
05126253db fix(InvoiceForm): control display exchange rate input for foreign customers. 2022-03-20 11:03:48 +02:00
a.bouhuolia
cc637471d9 feat(ExchangeRateInput): optimize style. 2022-03-19 23:19:30 +02:00
a.bouhuolia
321d206670 feat(TotalLine): add extra border style. 2022-03-19 23:16:41 +02:00
a.bouhuolia
69c47aee4d feat(InvoiceForm): remove the entries table footer. 2022-03-19 23:15:37 +02:00
a.bouhuolia
ad149c1b18 feat(FormTopbar): optimize style. 2022-03-19 23:15:04 +02:00
a.bouhuolia
7df4cbdf54 fix(InvoiceFormHeader): remove terms select field. 2022-03-19 23:14:27 +02:00
a.bouhuolia
ca0672509b feat(InvoiceFormFooter): add invoice form footer the total lines. 2022-03-19 23:13:32 +02:00
a.bouhuolia
966d1100aa fix(CustomerDrawerLink): prevent the default JS behaivour. 2022-03-19 23:13:05 +02:00
a.bouhuolia
0e263437e1 feat(DatatableEditable): restyle datatable editable component. 2022-03-19 23:12:40 +02:00
a.bouhuolia
e1977dbe07 feat(FTextArea): add TextArea component binded with Formik. 2022-03-19 23:11:50 +02:00
a.bouhuolia
e6d7d6aa1c feat(ExchangeRateInput): depend on currency code instead of country code. 2022-03-19 23:11:30 +02:00
a.bouhuolia
8e7955bc7e feat(Paper): add Paper icon. 2022-03-19 23:08:41 +02:00
a.bouhuolia
379d033344 feat(Icons): rename icons from country code to currency code. 2022-03-19 23:08:12 +02:00
a.bouhuolia
378110f6b3 feat: update @blueprintjs-formik/core package. 2022-03-19 23:07:16 +02:00
elforjani13
888c3a11e0 feat: fix journal. 2022-03-17 17:31:40 +02:00
elforjani13
b0407168a0 feat(payment receive & made): handle error. 2022-03-17 14:34:24 +02:00
elforjani13
7f3a494c8d fix: branch & warehouse multi select. 2022-03-16 22:59:26 +02:00
elforjani13
d85133b35e feat: fix make journal. 2022-03-16 19:55:27 +02:00
elforjani13
a360f8a62b feat(warehouses&branches): empty status localizations. 2022-03-15 17:01:29 +02:00
elforjani13
a91f303111 feat(warehouses transfer): warehouse transfer auto-increment. 2022-03-15 13:46:27 +02:00
elforjani13
f45d5ecf42 feat: localization. 2022-03-15 13:17:12 +02:00
elforjani13
3d49ebd1e7 feat: fix localization. 2022-03-15 13:16:49 +02:00
elforjani13
f84023f399 fix: missaing 2022-03-14 16:57:49 +02:00
elforjani13
dd46180d87 feat: add localizations. 2022-03-14 15:14:19 +02:00
elforjani13
3e91b01b61 fix:localization. 2022-03-14 15:13:53 +02:00
elforjani13
bd3059ecd8 feat(branches & warehouses): handle errors. 2022-03-13 15:20:00 +02:00
elforjani13
0bbd31dcce feat(branches & warehouses): fix Context menu. 2022-03-13 14:30:52 +02:00
elforjani13
c5c490d7ce feat(expenses): add expense form top bar. 2022-03-13 13:15:04 +02:00
elforjani13
733f198dcb feat(expenses): add exchange rate to details. 2022-03-13 13:10:01 +02:00
elforjani13
c17234f245 feat(branches & warehouses): fix features hooks. 2022-03-13 13:09:07 +02:00
elforjani13
a2bf37d5cd feat(branch & warehouse): handle error. 2022-03-12 20:01:32 +02:00
elforjani13
a75451cee7 feat(branches): fix branches provider. 2022-03-10 17:42:31 +02:00
elforjani13
c1ad349f6b feat(customer & vendor): add branch. 2022-03-09 22:03:21 +02:00
elforjani13
37f8662cc5 feat(vendor): add vendor opening balance dialog. 2022-03-09 20:59:19 +02:00
elforjani13
c5e360ffa2 feat(customer): add customer opening balance dialog. 2022-03-09 20:49:57 +02:00
elforjani13
098429d31a feat(badDebt): fix currency code. 2022-03-09 20:48:47 +02:00
elforjani13
433b611188 feat(inventoryadjustment): add branch & warehouse. 2022-03-09 13:05:07 +02:00
elforjani13
6638accae6 feat(warehouses transfer): fix table state change. 2022-03-08 16:33:51 +02:00
elforjani13
2d34baa7a5 feat(branches & warehouses): fix api. 2022-03-08 15:47:28 +02:00
elforjani13
0f4176ae79 feat(exchangrate muted): fix style. 2022-03-08 12:05:37 +02:00
elforjani13
4f630d8365 feat(qucikpayment):fix currency code. 2022-03-08 12:05:30 +02:00
elforjani13
e38b96c528 feat(account): handle error. 2022-03-07 22:12:34 +02:00
elforjani13
e03dee2a9f feat(warehouse & Branch): handle error. 2022-03-07 21:53:54 +02:00
elforjani13
a8311f1798 feat(refund vendor):add exchange rate muted & branch. 2022-03-07 20:57:39 +02:00
elforjani13
b8b95c7929 feat(refund credit):add exchange rate muted & branch. 2022-03-07 20:57:20 +02:00
elforjani13
2501626d70 feat(qucikpayment):add exchange rate muted & branch. 2022-03-07 20:46:48 +02:00
elforjani13
87a56dcd95 feat(S&P): fix navigation bar if warehouses or branches feature. 2022-03-07 18:43:21 +02:00
elforjani13
b26b4c5491 feat(qucikpayment):add exchange rate muted. 2022-03-07 18:35:11 +02:00
elforjani13
d12e35f649 feat(cashflow): exchange rate muted. 2022-03-07 16:38:14 +02:00
elforjani13
51c7a0fcd8 feat(dashboard): add features api. 2022-03-07 00:18:58 +02:00
elforjani13
a639101e28 feat(cashflow): add exchange rate muted. 2022-03-06 23:26:09 +02:00
elforjani13
7467b63e54 feat(cashflow): add ExchangeRateMutedField. 2022-03-06 20:20:25 +02:00
elforjani13
5c52f80536 feat(branch & warehouse): fix EmptyStatus. 2022-03-06 15:11:04 +02:00
elforjani13
94c88a7003 feat(Bill): fix bill . 2022-03-03 19:12:22 +02:00
elforjani13
7f4ee26979 feat( S&P ): add branch name to details. 2022-03-02 19:07:09 +02:00
elforjani13
e46609e3f1 fix(invoice details): add branch name. 2022-03-02 16:56:41 +02:00
elforjani13
f814374279 feat(invoicedetail ): Add branch name to detial. 2022-03-02 14:23:28 +02:00
elforjani13
cfbc59280e feat( S&P ): Add currency code in conversion to invoice & credit. 2022-03-01 19:50:49 +02:00
elforjani13
0923c69c16 feat(Sales & Purchases ): add currency code in edit mode. 2022-03-01 15:57:47 +02:00
elforjani13
151e72a76d feat(Sales & Purchases ): add exchange rate in details. 2022-03-01 14:51:34 +02:00
elforjani13
ff2c74344a feat(OwnerContributionForm): add branch select. 2022-02-28 16:37:44 +02:00
elforjani13
eb340269c0 feat(Journal): add branch to topbar & entries columns. 2022-02-28 14:29:56 +02:00
elforjani13
cb9c7fcdb6 feat(OwnerContributionForm): add exchange rate. 2022-02-27 14:38:47 +02:00
elforjani13
31a5ee6dda feat(moneyIn): add exchange rate detail. 2022-02-27 14:26:10 +02:00
elforjani13
01db5a2faa feat(invoice detail): add exchange rate detail. 2022-02-27 14:23:57 +02:00
elforjani13
a3c79d98b0 feat(account): add currency select. 2022-02-27 14:10:22 +02:00
elforjani13
deddbea752 feat (warehouseTransfer): add status in details. 2022-02-23 19:47:30 +02:00
elforjani13
e0126018b8 feat (invoice detail): deatil exhange rate item. 2022-02-23 18:35:54 +02:00
elforjani13
22eb7a1cc1 feat(Sales & Purchases ): add currency in header & entries. 2022-02-23 14:47:12 +02:00
elforjani13
e6a7c7bc58 feat(Sales & Purchases ): add setfieldvalue exchange rate. 2022-02-23 12:22:27 +02:00
elforjani13
cf7d032aae feat(warehousetTransfer): fix warehouse alert. 2022-02-22 15:59:47 +02:00
elforjani13
faea111f46 feat(warehousetTransfer): add warehouse transfer views. 2022-02-22 15:56:30 +02:00
elforjani13
836be59cbf feat(warehousetTransfer): warehouse floating actions. 2022-02-22 15:47:42 +02:00
elforjani13
ffd6629b80 feat(warehousetTransfer ): add warehouse status. 2022-02-22 15:37:03 +02:00
elforjani13
9ff91e27e5 feat(Sales & Purchases ): add currency tag. 2022-02-21 19:30:00 +02:00
elforjani13
b15437c88e feat(manual journal): add exchange rate input. 2022-02-21 16:03:57 +02:00
elforjani13
7c9ad8438c feat(Sales & Purchases ): add exchange rate input. 2022-02-21 15:25:32 +02:00
a.bouhuolia
98a02396a9 Merge branch 'develop' into main 2022-02-21 15:02:35 +02:00
a.bouhuolia
c7673f57cd dump v1.6.3. 2022-02-21 15:02:08 +02:00
a.bouhuolia
aa39aab93a fix(Billing): display payment methods only if subscription is not active. 2022-02-21 14:56:55 +02:00
a.bouhuolia
8e6b0b496f fix: BIG-337 Display billing page once the organization subscription is inactive. 2022-02-21 14:38:41 +02:00
elforjani13
914e1de79f feat(Sales & Purchases ): add FormTopBar. 2022-02-20 22:31:52 +02:00
elforjani13
f6f949bcbc Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-02-20 18:56:09 +02:00
elforjani13
f7790ef440 fix(Branches): min height. 2022-02-20 18:49:18 +02:00
elforjani13
05b0f5caac fix(Branches & warehouses ): mark primary. 2022-02-20 18:38:19 +02:00
a.bouhuolia
f5983937b0 fix: warehouse transfer. 2022-02-20 17:45:50 +02:00
a.bouhuolia
3a4c1adbd4 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-02-20 17:08:36 +02:00
a.bouhuolia
e9d379c623 fix: organize the warehouses preferences. 2022-02-20 17:08:30 +02:00
elforjani13
b46c3f4843 feat(Sales & Purchases ): add branch & warehouse. 2022-02-20 13:54:31 +02:00
a.bouhuolia
3ed2393cf1 feat: migrate to @blueprintjs-formik/select and @blueprintjs-formik/core. 2022-02-19 21:05:29 +02:00
a.bouhuolia
041014dc72 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-02-19 17:15:58 +02:00
a.bouhuolia
1f70bcfa1f feat: add auto set for primary warehouse and branch of invoice form. 2022-02-19 17:15:49 +02:00
a.bouhuolia
96635ffa84 Merge branch 'develop' into main 2022-02-18 20:44:42 +02:00
a.bouhuolia
e874b89d2d fix: try to fix styled-components. 2022-02-18 20:32:21 +02:00
a.bouhuolia
60d37e3424 Revert "fix: try to comment FinancialSkeletonTable component."
This reverts commit e3f2c82a38.
2022-02-18 20:10:53 +02:00
a.bouhuolia
8ae39bf04c fix: styled-components components. 2022-02-18 19:52:37 +02:00
a.bouhuolia
e3f2c82a38 fix: try to comment FinancialSkeletonTable component. 2022-02-18 19:29:12 +02:00
elforjani13
a6ec3f1be7 feat(currencies): add currency select. 2022-02-17 21:10:54 +02:00
elforjani13
7a27ea9a65 feat(inventory item & valuation): warehouse multi select. 2022-02-17 20:30:16 +02:00
elforjani13
cd663d99b7 fix(invoice): foreign customer. 2022-02-17 19:07:58 +02:00
a.bouhuolia
29ab6ee09e fix: flag icon. 2022-02-17 14:07:43 +02:00
a.bouhuolia
faf6963a36 feat(InvoiceForm): skeleton loading on branch and warehouse select button. 2022-02-17 13:51:37 +02:00
a.bouhuolia
68c0678dc3 Merge branch 'develop' into main 2022-02-17 12:10:20 +02:00
a.bouhuolia
030be9652c feat: add BS and PL reports to page of financial reports list. 2022-02-17 11:40:40 +02:00
elforjani13
1c5c632578 feat(AP/ARAgin summary): add branch multi select. 2022-02-16 21:02:38 +02:00
elforjani13
cffcef6f43 feat(financial reports): add branch multi select. 2022-02-16 20:43:00 +02:00
elforjani13
c01fa85198 feat(trial balance sheet): branch multi select. 2022-02-16 19:35:35 +02:00
elforjani13
c7f6b70d14 feat(cashflow & journal sheet): add branch multi select. 2022-02-16 19:28:03 +02:00
a.bouhuolia
554527f17d fix(VendorTransaction): column accessor/id. 2022-02-16 18:47:36 +02:00
a.bouhuolia
79144ad4a5 fix: re-structure the system tables reports. 2022-02-16 18:44:10 +02:00
elforjani13
e9933031ae feat(balance sheet): add branch multi select. 2022-02-16 18:07:04 +02:00
a.bouhuolia
e6fcbfeea6 fix: control report drawer header. 2022-02-16 17:49:28 +02:00
a.bouhuolia
3b642540f1 fix: multi-select branches error. 2022-02-16 16:56:35 +02:00
elforjani13
953d37b20f feat(balance): add FMultiSelect. 2022-02-16 16:25:58 +02:00
a.bouhuolia
9630fecd7c feat: add blueprint-formik package. 2022-02-16 13:36:23 +02:00
a.bouhuolia
574f596eea refactor: invoice topbar. 2022-02-15 16:08:48 +02:00
a.bouhuolia
bb56790ce9 feat: auto-complete warehouse transfer row. 2022-02-14 23:30:52 +02:00
a.bouhuolia
913245d202 feat: abstruct exchange rate input group component. 2022-02-14 15:22:07 +02:00
a.bouhuolia
7eacaa0660 fix: financial report data tables. 2022-02-14 14:09:17 +02:00
elforjani13
bd63e35489 feat(invoice): fix invoice currency tag. 2022-02-14 12:06:58 +02:00
elforjani13
9f466ba4df feat(item): add item warehouse locations. 2022-02-14 09:32:31 +02:00
elforjani13
005cb4344d feat(warehouse): Skeleton warehouses. 2022-02-14 00:27:16 +02:00
elforjani13
c77009b921 fix(invoice): Skeleton warehouses & branch loading & style action top bar. 2022-02-13 22:13:03 +02:00
elforjani13
a86b831e93 Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-02-13 18:50:12 +02:00
elforjani13
fd42af42cd fix(warehouse transfer): close the sidebar. 2022-02-13 18:29:34 +02:00
elforjani13
69f086cfae feat(invoice ): add foreign customer. 2022-02-13 18:28:06 +02:00
elforjani13
b272ddf23a feat(warehouse ): warehouses skeleton. 2022-02-13 18:26:59 +02:00
a.bouhuolia
673808cceb feat: add sticky table head to specific item transactions table. 2022-02-13 17:22:29 +02:00
a.bouhuolia
f27ef2c9b0 fix: style of vendor/customer balance summary. 2022-02-13 17:17:09 +02:00
a.bouhuolia
9b7befc544 feat: add feature guard as hook and component. 2022-02-13 16:29:50 +02:00
a.bouhuolia
fdd52f1ecf Merge branch 'feature/multi-dimensions' of https://github.com/bigcapitalhq/client into feature/multi-dimensions 2022-02-13 15:19:01 +02:00
a.bouhuolia
9463d8dc1c fix: realized and unrealized report. 2022-02-13 15:12:50 +02:00
elforjani13
dd7516f6b2 feat(warehouse ): warehouse style. 2022-02-13 14:50:11 +02:00
elforjani13
91c7d746b1 fix(warehouse ) fix mark primary warehouse alert. 2022-02-13 14:50:11 +02:00
elforjani13
5aae2c849d feat(branche & warehouse ) add mark primary alert. 2022-02-13 14:49:40 +02:00
elforjani13
76a15c3f4e feat(branche & warehouse activate) add api. 2022-02-13 14:48:38 +02:00
elforjani13
28a9fd2390 feat(branches& warehouses): fix EmptyStatus. 2022-02-13 14:48:38 +02:00
elforjani13
f0dc39eeaf feat(branches& warehouses): add api. 2022-02-13 14:48:38 +02:00
elforjani13
4a56743af1 feat(branches& warehouses): add empty status. 2022-02-13 14:48:38 +02:00
elforjani13
7e4208da81 feat(branches& warehouses): add branches & warehouses activate dialog. 2022-02-13 14:48:38 +02:00
elforjani13
e05f51dec8 feat(invoice): add branch & warehouse schema. 2022-02-13 14:48:38 +02:00
elforjani13
03782efe88 feat(invoice): add branch & warehouse. 2022-02-13 14:48:38 +02:00
elforjani13
2a61a3de47 Revert "feat(warehouse) add warehouse propover."
This reverts commit 2aa26959e9.
2022-02-13 14:48:37 +02:00
elforjani13
e1fe28736e feat(UnrealizedGainorLoss): add Unrealized gain or loss. 2022-02-13 14:48:37 +02:00
elforjani13
3036b232b5 feat(RealizedGainorLoss): add realized gain or loss. 2022-02-13 14:48:37 +02:00
elforjani13
4f5dcb3609 feat(branche): add crud branches. 2022-02-13 14:48:11 +02:00
elforjani13
defa5bb8de feat(warehouse): add warehouse fields. 2022-02-13 14:46:34 +02:00
elforjani13
769d8fa548 feat(branches): add branches. 2022-02-13 14:46:30 +02:00
elforjani13
b5ebcca12d feat(warehouseTransfer): handle error. 2022-02-13 14:42:56 +02:00
elforjani13
a50d6358f4 feat(warehouseTransfer): warehouse transfer detail. 2022-02-13 14:42:56 +02:00
elforjani13
731ecaeeb3 feat(warehouseTransfer): add crud warehouse transfer. 2022-02-13 14:42:56 +02:00
elforjani13
0db252c862 feat(warehouseTransfer): fix warehouse transfer style. 2022-02-13 14:42:56 +02:00
elforjani13
d6b781a14c feat(warehouseTransfer): add create & delete transfer & details. 2022-02-13 14:42:56 +02:00
elforjani13
9089e3d120 feat(warehousetransfer): add api. 2022-02-13 14:42:55 +02:00
elforjani13
de2a71433b feat(warehouseTransfer): add warehouseTransfer. 2022-02-13 14:42:54 +02:00
elforjani13
7109f301d8 feat(warehouse): add crud warehouse. 2022-02-13 14:37:04 +02:00
elforjani13
28a1cdfa3e feat(warehouse): add credit & edit & delete warehouse. 2022-02-13 14:37:04 +02:00
elforjani13
8be3f23d65 feat(warehouse) add warehouse grid item style. 2022-02-13 14:37:03 +02:00
elforjani13
8c594b991c feat(warehouse) add warehouse propover. 2022-02-13 14:37:03 +02:00
elforjani13
86710b3ba8 feat(warehouse) add warehouse gird. 2022-02-13 14:37:03 +02:00
elforjani13
a89ceffaca feat(warehouses): add Item quantity for each warehouse. 2022-02-13 14:37:02 +02:00
elforjani13
84a1a551f1 feat(warehouse): add warehouse. 2022-02-13 14:37:02 +02:00
a.bouhuolia
2986b537d0 fix: financial reports. 2022-02-13 13:21:59 +02:00
a.bouhuolia
b1f07d281f fix: remove un-used stylesheet files. 2022-02-12 20:41:40 +02:00
a.bouhuolia
1b0ffb5574 refactor(CustomerTransaction). 2022-02-12 20:31:14 +02:00
a.bouhuolia
b249335a73 refactor(Cashflow)
refactor(InventoryValuation)
2022-02-12 18:59:34 +02:00
a.bouhuolia
4cc0a8c41e refactor(APAgingSummary)
refactor(ARAgingSummary)
2022-02-12 18:49:48 +02:00
a.bouhuolia
2e7061260e refactor((CustomerTransaction).
refactor(VendorTransaction).
refactor(VendorBalanceSummary).
refactor(CustomerBalanceSummary)
2022-02-12 18:12:08 +02:00
a.bouhuolia
46570c5218 refactor(InventoryValuation).
refactor(InventoryItemDetails).
2022-02-12 17:03:15 +02:00
a.bouhuolia
72a7c4890e refactor(SaleByItem) 2022-02-12 16:41:07 +02:00
a.bouhuolia
a9a877f4fc refactor(PurchaseByItem) 2022-02-12 16:26:36 +02:00
a.bouhuolia
cc42c21f24 refactor(JournalSheet) 2022-02-12 16:07:26 +02:00
a.bouhuolia
2f0322b4fc refactor(GeneralLedger) 2022-02-12 13:17:38 +02:00
a.bouhuolia
b9418d3eb6 refactor(TrialBalanceSheet). 2022-02-12 12:53:23 +02:00
a.bouhuolia
526181aa68 refactor: re-structure financial reports components. 2022-02-12 12:21:05 +02:00
a.bouhuolia
d445fec8c0 refactor(CashflowSheet): refactor the body sheet. 2022-02-10 11:45:27 +02:00
a.bouhuolia
1f81fd213d refactor(TrialBalanceSheet): refactor with body sheet. 2022-02-10 11:44:50 +02:00
a.bouhuolia
83cd7ca893 Merge branch 'feature/comparisons' into develop 2022-02-09 21:51:18 +02:00
a.bouhuolia
d22143c97e Revert "feat(BS|PL): sticky columns in RTL mode."
This reverts commit 200a59d6da.
2022-02-09 21:32:36 +02:00
a.bouhuolia
200a59d6da feat(BS|PL): sticky columns in RTL mode. 2022-02-09 21:26:33 +02:00
a.bouhuolia
8b4d841023 feat(BS|PL): integrate report query with location query. 2022-02-09 21:12:32 +02:00
a.bouhuolia
c361a5852c fix(BS|PL): report query. 2022-02-09 19:50:49 +02:00
a.bouhuolia
b759d7327e feat(App): Horjar code on production envirement only. 2022-02-09 17:11:55 +02:00
elforjani13
893ebb838e feat(warehouse ): warehouse style. 2022-02-09 00:23:50 +02:00
elforjani13
3e8f281d0c fix(warehouse ) fix mark primary warehouse alert. 2022-02-08 21:18:52 +02:00
elforjani13
49f8cce54b feat(branche & warehouse ) add mark primary alert. 2022-02-08 20:31:15 +02:00
elforjani13
09d5771481 feat(branche & warehouse activate) add api. 2022-02-08 20:16:46 +02:00
elforjani13
93df479c05 feat(PL & PL): add localizing. 2022-02-08 16:54:57 +02:00
elforjani13
781dd9457e feat(branches& warehouses): fix EmptyStatus. 2022-02-08 16:05:40 +02:00
elforjani13
287939e093 feat(branches& warehouses): add api. 2022-02-07 23:01:12 +02:00
elforjani13
19a3de3122 feat(branches& warehouses): add empty status. 2022-02-07 23:00:56 +02:00
elforjani13
be2d84577e feat(branches& warehouses): add branches & warehouses activate dialog. 2022-02-07 23:00:15 +02:00
elforjani13
3b7e2ce812 feat(invoice): add branch & warehouse schema. 2022-02-07 13:45:00 +02:00
elforjani13
fe3314b5cb feat(invoice): add branch & warehouse. 2022-02-07 13:16:46 +02:00
elforjani13
a368e5572b Revert "feat(warehouse) add warehouse propover."
This reverts commit 2aa26959e9.
2022-02-06 09:58:38 +02:00
a.bouhuolia
d300231838 fix(DataTable): sticky column. 2022-02-05 11:31:57 +02:00
elforjani13
39d0e9c198 feat(UnrealizedGainorLoss): add Unrealized gain or loss. 2022-02-03 22:47:56 +02:00
elforjani13
164eebd6ae feat(RealizedGainorLoss): add realized gain or loss. 2022-02-03 22:47:38 +02:00
a.bouhuolia
47f6845633 feat(BS&PL): add sticky to account column. 2022-02-03 17:03:24 +02:00
a.bouhuolia
f204b81407 fix(BS|PL): date periods columns alignment. 2022-02-03 16:05:24 +02:00
elforjani13
66552a2d28 Merge branch 'BIG-316-crud-branches' into feature/multi-dimensions 2022-02-03 12:39:11 +02:00
elforjani13
9d5440961b feat(warehouseTransfer): handle error. 2022-02-03 01:03:00 +02:00
elforjani13
e7024955dd feat(warehouseTransfer): warehouse transfer detail. 2022-02-03 01:02:31 +02:00
elforjani13
8bf64c68e0 feat(warehouseTransfer): add crud warehouse transfer. 2022-02-03 00:27:42 +02:00
elforjani13
a81f1e7a9c feat(warehouseTransfer): fix warehouse transfer style. 2022-02-02 16:09:55 +02:00
elforjani13
6e7c746d09 feat(warehouseTransfer): add create & delete transfer & details. 2022-02-02 15:53:09 +02:00
a.bouhuolia
2c2740ea73 fix(BalanceSheet): highlight total assets and libaiities. 2022-02-02 13:33:54 +02:00
a.bouhuolia
c72802d683 feat(FinancialSheet): add skeleton view. 2022-02-02 12:08:57 +02:00
elforjani13
dc491281aa feat(warehousetransfer): add api. 2022-02-02 00:46:02 +02:00
elforjani13
f845711983 Merge remote-tracking branch 'origin/BIG-308-crud-warehouses-transfers' into BIG-310-crud-warehouses 2022-02-01 23:59:20 +02:00
elforjani13
dea4fe0e79 feat(branche): add crud branches. 2022-02-01 23:18:32 +02:00
elforjani13
8d2bede3d4 feat(warehouse): add crud warehouse. 2022-02-01 21:07:28 +02:00
elforjani13
fc097378cb feat(warehouse): add credit & edit & delete warehouse. 2022-02-01 21:05:54 +02:00
a.bouhuolia
b4f6d2c7f1 Merge branch 'feature/comparisons' of https://github.com/bigcapitalhq/client into feature/comparisons 2022-02-01 16:59:51 +02:00
a.bouhuolia
4456343eb6 Merge https://github.com/bigcapitalhq/client into feature/comparisons 2022-02-01 16:53:53 +02:00
elforjani13
a3d250cdc8 fix(Balance & P/L Sheet): fix comparison panel. 2022-02-01 00:29:50 +02:00
a.bouhuolia
ce223e7e2f feat(BalanceSheet|P&L): account name min-width. 2022-01-31 01:04:23 +02:00
elforjani13
0d11ea7c5e feat(warehouse) add warehouse grid item style. 2022-01-30 18:29:10 +02:00
elforjani13
2aa26959e9 feat(warehouse) add warehouse propover. 2022-01-30 18:04:56 +02:00
elforjani13
e4af460c0d feat(warehouse) add warehouse gird. 2022-01-30 18:04:36 +02:00
a.bouhuolia
8d6ed9be41 fix: balance sheet. 2022-01-30 16:05:59 +02:00
a.bouhuolia
e296507a96 chore: remove dubugger point. 2022-01-30 16:01:59 +02:00
a.bouhuolia
3d78d2d051 feat: integrate balance sheet and P&L sheet with new API. 2022-01-30 15:57:27 +02:00
a.bouhuolia
fa455152a3 feat(ProfitLoss): WIP 2022-01-29 21:57:39 +02:00
a.bouhuolia
34501a9a61 fix(BalanceSheet): dynamic columns width. 2022-01-29 21:35:31 +02:00
a.bouhuolia
066df28257 fix(BalanceSheet): columns width based in cells contents. 2022-01-29 21:32:20 +02:00
a.bouhuolia
77d826e6d4 feat(BalanceSheet|ProfitLoss): comparions feature. 2022-01-29 20:46:41 +02:00
elforjani13
5b0cb0c8be feat(warehouses): add Item quantity for each warehouse. 2022-01-27 16:48:55 +02:00
elforjani13
735803f1a5 feat(balancesheet): balance sheet comparisons. 2022-01-25 20:12:13 +02:00
elforjani13
354d1e8f75 feat(P&L Comparisons): add P&L comparisons. 2022-01-24 13:55:44 +02:00
elforjani13
dcac1053be feat(warehouse): add warehouse fields. 2022-01-24 01:44:46 +02:00
elforjani13
bcb67c7142 feat(warehouse): add warehouse. 2022-01-24 01:35:45 +02:00
elforjani13
45d9e2cc15 feat(branches): add branches. 2022-01-23 23:23:40 +02:00
elforjani13
13da985864 feat(warehouseTransfer): add warehouseTransfer. 2022-01-23 14:07:23 +02:00
elforjani13
225619be60 fix(balanceSheet) balance sheet header. 2022-01-13 16:33:32 +02:00
elforjani13
85a78b3809 feat: style balance sheet comparison. 2022-01-13 16:25:46 +02:00
a.bouhuolia
da699a766a Merge branch 'develop' into main 2022-01-13 15:40:55 +02:00
a.bouhuolia
a958c6088a chore: dump version. 2022-01-13 15:35:40 +02:00
a.bouhuolia
572d59577c chore: dump version changlogs. 2022-01-13 15:34:54 +02:00
elforjani13
7a0d506395 feat: balance sheet comparison 2022-01-13 15:25:04 +02:00
Ahmed Bouhuolia
21ae8aabfc Merge pull request #22 from bigcapitalhq/BIG-261-hide-convert-to-invoice-button-on-the-context-menu-if-already-converted
fix: `BIG-261` Hide convert to invoice button on the context menu if invoice already converted.
2022-01-13 15:18:49 +02:00
a.bouhuolia
8f267b98e4 fix(ContactBalanceSummary): BIG-288 percentage of column. 2022-01-12 20:15:00 +02:00
a.bouhuolia
dcfe92076b Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-01-11 18:10:23 +02:00
a.bouhuolia
79cb7f1a1d fix(PaymentReceive): depend on loading state instead fetching. 2022-01-11 18:10:17 +02:00
a.bouhuolia
1380e288e0 fix(BalanceSheet): BIG-281 report alerts re-positioning. 2022-01-11 18:09:12 +02:00
Ahmed Bouhuolia
b055908e12 Merge pull request #19 from bigcapitalhq/BIG-274-duplicated-description-in-payment-receive-details
`BIG-274` Duplicated description in payment receive details.
2022-01-11 17:29:19 +02:00
Ahmed Bouhuolia
20c140474b Merge pull request #20 from bigcapitalhq/BIG-277-separate-customer-and-vendor-activate-inactivate-alerts
BIG-277 Separate customer and vendor.
2022-01-11 17:28:47 +02:00
Ahmed Bouhuolia
9ee5eba92b Merge branch 'develop' into BIG-277-separate-customer-and-vendor-activate-inactivate-alerts 2022-01-11 17:28:30 +02:00
Ahmed Bouhuolia
e755a2a318 Merge pull request #21 from bigcapitalhq/BIG-263-optimize-sales-print-templates
`Big 263` optimize sales print templates
2022-01-11 17:25:44 +02:00
elforjani13
1656691940 feat(PaymentReceivePdf): payment pdf preview. 2022-01-11 14:34:41 +02:00
elforjani13
dd7d11ffb7 feat(CreditNotePdf): credit note pdf preview. 2022-01-11 14:33:51 +02:00
elforjani13
5c847be420 BIG-277 Separate customer and vendor. 2022-01-09 21:18:45 +02:00
a.bouhuolia
da3193195c fix: BIG-274 Duplicated description in payment receive details. 2022-01-09 21:12:54 +02:00
a.bouhuolia
e3141250b6 fix: BIG-261 Hide convert to invoice button on the context menu if already converted. 2022-01-09 13:07:32 +02:00
a.bouhuolia
f1899e1ce1 Merge branch 'develop' into main 2022-01-08 18:20:08 +02:00
elforjani13
76d6cd0eaa fix(MoneyOutForm): BIG-270 publish & draft cashflow. 2022-01-08 18:14:39 +02:00
elforjani13
90b4f86a0d fix(MoneyInForm): BIG-270 publish & draft cashflow. 2022-01-08 18:14:17 +02:00
Ahmed Bouhuolia
5766d25bd1 Merge pull request #18 from bigcapitalhq/BIG-271-hotjar-client-application-integration
`BIG-271` Hotjar client application integration.
2022-01-08 18:06:54 +02:00
elforjani13
6a5d96e869 BIG-271 Hotjar client application integration. 2022-01-08 17:59:30 +02:00
Ahmed Bouhuolia
69f16d1977 Merge pull request #17 from bigcapitalhq/BIG-270-publish-and-draft-cashflow-transaction-should-be-always-publish
BIG-270 Publish and draft cashflow transaction.
2022-01-08 17:02:54 +02:00
elforjani13
9973693a86 BIG-270 Publish and draft cashflow transaction. 2022-01-08 16:59:31 +02:00
Ahmed Bouhuolia
11851d114d Merge pull request #16 from bigcapitalhq/develop
Release 1.5.5
2022-01-04 22:35:49 +02:00
elforjani13
3a3dd7a565 fix(VendorForm): placeholder phone number. 2022-01-04 22:31:01 +02:00
elforjani13
687dda1e7c fix(inviteUserFrom): fix localiztion. 2022-01-04 21:31:58 +02:00
elforjani13
bfa809c831 feat(VendorList): add note accessor & personal phone. 2022-01-04 20:47:43 +02:00
elforjani13
07145e92ab feat(CustomerList): add note accessor & personal phone. 2022-01-04 20:47:28 +02:00
a.bouhuolia
21779007be fix: application version. 2022-01-03 23:14:11 +02:00
a.bouhuolia
4fc1ecdc2d Merge branch 'main' of https://github.com/bigcapitalhq/client into main 2022-01-03 19:42:48 +02:00
a.bouhuolia
c9b5cecf7a Merge branch 'develop' into main 2022-01-03 19:42:23 +02:00
a.bouhuolia
4a46c00a07 chore: bump version. 2022-01-03 19:42:05 +02:00
a.bouhuolia
5c7ac0593d feat(GlobalErrors): localize the global errors. 2022-01-03 18:31:52 +02:00
a.bouhuolia
fa25fb4ede fix(TrialBalanceSheet): expand account name column. 2022-01-03 18:02:24 +02:00
elforjani13
c31e9dcd29 fix: inventory adjustment & contacts drawer. 2022-01-03 14:35:50 +02:00
a.bouhuolia
3566d3b855 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-01-03 13:53:40 +02:00
a.bouhuolia
c5da97bce0 chore: changlog. 2022-01-03 13:53:04 +02:00
a.bouhuolia
0cfbe633bd feat: add .env.example file. 2022-01-03 13:53:02 +02:00
a.bouhuolia
55098d7b78 chore: remove repo logo. 2022-01-03 13:53:00 +02:00
a.bouhuolia
78610cd519 chore: upload repo logo. 2022-01-03 13:52:59 +02:00
a.bouhuolia
828a28b976 chore: update package-lock.json. 2022-01-03 13:52:58 +02:00
a.bouhuolia
daf5fc8aba feat: add version numebr on sidebar footer. 2022-01-03 13:49:55 +02:00
elforjani13
430ab95dc3 landed cost localiztion. 2022-01-03 13:38:22 +02:00
Ahmed Bouhuolia
8100a57195 Merge pull request #15 from bigcapitalhq/develop
Merge `develop` to `main`
2022-01-03 12:31:14 +02:00
a.bouhuolia
97d890bcef chore: remove repo logo. 2022-01-03 12:30:15 +02:00
a.bouhuolia
521df8511d chore: upload repo logo. 2022-01-03 12:24:28 +02:00
a.bouhuolia
73ec49b36a chore: update package-lock.json. 2022-01-03 12:06:07 +02:00
a.bouhuolia
cfc625edf9 Merge branch 'develop' 2022-01-03 11:46:00 +02:00
elforjani13
e1b6f0d879 fix:APAging summary stye. 2022-01-02 18:39:53 +02:00
a.bouhuolia
ecda9296b8 fix(FinancialReport): BIG-205 Financial reports missing border final border bottom. 2022-01-02 17:24:35 +02:00
a.bouhuolia
aba732724b Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-01-02 16:37:46 +02:00
a.bouhuolia
40bc7d4e99 fix: BIG-222 Manual journal details entries table footer. 2022-01-02 16:37:37 +02:00
elforjani13
7f1844aa6b BIG-231 Transactions number on drawer title. 2022-01-02 13:38:40 +02:00
a.bouhuolia
7ab7456d08 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2022-01-01 18:11:15 +02:00
a.bouhuolia
de53a24d58 fix: BIG-209 Account details such as normal, account type not localized. 2022-01-01 18:11:06 +02:00
a.bouhuolia
e0c565388a fix: BIG-196 Bill landed cost transactions formatted allocate type. 2022-01-01 18:06:46 +02:00
elforjani13
3c73540b4e BIG-210 Refund credit & vendor drawer detail. 2022-01-01 15:34:04 +02:00
elforjani13
a4a2d0c888 BIG-225 Optimize style of refund vendor form. 2022-01-01 11:00:08 +02:00
elforjani13
e9797fd9a0 BIG-214 Min width submit button on edit mode. 2022-01-01 10:27:32 +02:00
elforjani13
40ae1aeb52 BIG-225 Add menu divider before delete on contextMenu. 2021-12-30 21:54:32 +02:00
elforjani13
b2c08d5645 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-30 21:33:31 +02:00
elforjani13
ee6f4028eb BIG-232 customer and vendor drawer link. 2021-12-30 21:33:18 +02:00
a.bouhuolia
cdb8ea6721 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-30 15:39:26 +02:00
a.bouhuolia
0173630e80 fix: BIG-206 Reconcilate credit note and vendor credit with invoices should amount to credit be max the invoice remaining amount. 2021-12-30 15:39:22 +02:00
elforjani13
4403bf2b06 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-30 12:54:41 +02:00
elforjani13
f8e44c4f4e BIG-220 Avoid display empty status. 2021-12-30 12:54:22 +02:00
a.bouhuolia
0bd11419bb fix: BIG-199 Purchase invoice partial payment status progress height not consistent with sell invoice style. 2021-12-30 12:50:27 +02:00
a.bouhuolia
c1e229814f Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-30 12:38:12 +02:00
a.bouhuolia
871dcb62c4 fix: BIG-213 Landed cost checkbox disable with inventory items not service in purchase invoice. 2021-12-30 12:38:03 +02:00
elforjani13
5bf591d8c9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-30 12:36:21 +02:00
elforjani13
75b1cce380 BIG-211 Invalidate reconciliation credit & vendor transaction. 2021-12-30 12:35:28 +02:00
a.bouhuolia
119e6fa216 fix: BIG-195 Allocate landed cost amount max number should be transaction remaining amount. 2021-12-30 12:30:02 +02:00
elforjani13
6b98e1f1c2 BIG-204 payment transactions context menu actions. 2021-12-30 12:28:42 +02:00
elforjani13
fa23aa67d3 BIG-202 Remove the allocate actions bar. 2021-12-30 12:15:23 +02:00
elforjani13
9474a4fcd1 BIG-197 Bill landed amount text right align. 2021-12-30 11:56:58 +02:00
elforjani13
81c81bd09f fix: add ability credit & vendor tabs. 2021-12-29 14:37:03 +02:00
elforjani13
1492c24cfb fix: formatted_type in inventory adjustment. 2021-12-29 12:34:12 +02:00
a.bouhuolia
b4e9ee7ff3 feat(GLTable): columns text overflow. 2021-12-28 19:52:21 +02:00
elforjani13
e97bf56adb feat: isLoading state. 2021-12-28 18:32:55 +02:00
elforjani13
11d44c128b Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-28 17:58:53 +02:00
elforjani13
e615f62ef5 fix: customer & inventory adjustment. 2021-12-28 17:57:50 +02:00
a.bouhuolia
c69d29fb22 feat(TransactionsLocking): localization. 2021-12-28 17:53:47 +02:00
a.bouhuolia
1e472d278a fix(Estimate): estimate status. 2021-12-28 17:01:35 +02:00
elforjani13
1688f49bc1 fix: fix localiztion. 2021-12-28 13:43:53 +02:00
elforjani13
9182e13c07 feat: estimate & cashflow. 2021-12-28 13:10:15 +02:00
elforjani13
f2150a982a fix: add type_formatted in item detail. 2021-12-28 12:30:47 +02:00
elforjani13
d8efb17651 feat: add notes. 2021-12-28 12:21:56 +02:00
elforjani13
1e361dac66 feat: notes. 2021-12-27 22:23:41 +02:00
elforjani13
a6cd483eb9 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-27 22:05:32 +02:00
elforjani13
765f00d203 feat: permissions localiztion. 2021-12-27 22:05:17 +02:00
a.bouhuolia
088d7d4b1d feat(TransactionsLocking): modify AR localization. 2021-12-27 18:59:01 +02:00
a.bouhuolia
92c9001c52 feat(AccountDetail): more transactions icon in RTL mode. 2021-12-27 18:43:02 +02:00
a.bouhuolia
93bd2af1d7 feat(Card): card footer actions. 2021-12-27 18:29:52 +02:00
a.bouhuolia
f261555b86 feat(InvoiceDetails): invoice payment transactions ability access control. 2021-12-27 16:19:13 +02:00
a.bouhuolia
62ab31efd2 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-27 16:02:16 +02:00
a.bouhuolia
96cb3177aa feat: WIP role form localization. 2021-12-27 16:01:22 +02:00
elforjani13
d5f7cdf131 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-27 15:20:48 +02:00
elforjani13
6ad3065f1f feat: landed hint. 2021-12-27 15:19:16 +02:00
a.bouhuolia
0860db87fb Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-27 15:05:17 +02:00
a.bouhuolia
2707415319 feat: Role form permissions dependecies. 2021-12-27 15:04:57 +02:00
elforjani13
99716e99a9 feat: localiztion. 2021-12-27 14:44:04 +02:00
a.bouhuolia
d1a67ca2ed Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-27 11:08:10 +02:00
a.bouhuolia
a1ed9bf4da feat: add rtlcss to styled components. 2021-12-27 11:08:05 +02:00
elforjani13
99df627633 feat: empty status in credit & vednor. 2021-12-26 20:56:25 +02:00
a.bouhuolia
e1646e92a8 fix: BIG-160 Remove expense default resource type on universal search. 2021-12-26 20:07:11 +02:00
a.bouhuolia
d4138fdf4e feat(RoleForm): service full access. 2021-12-26 19:09:20 +02:00
a.bouhuolia
49b6deed6d Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-26 18:26:22 +02:00
a.bouhuolia
0dddf3d1d0 feat: permissions service full access. 2021-12-26 18:26:05 +02:00
elforjani13
d5acb3696e feat: add convert to vendor credit in drawer. 2021-12-26 17:11:04 +02:00
elforjani13
2a9c1a9833 feat: add convert to credit note in drawer. 2021-12-26 16:34:05 +02:00
elforjani13
80d86b01de feat: add payment receive & bill detail footer. 2021-12-26 13:28:25 +02:00
elforjani13
4a42fa4edc feat: credit note detail footer. 2021-12-26 13:26:53 +02:00
elforjani13
8ea92513fe feat: receipt detail footer. 2021-12-26 13:26:10 +02:00
elforjani13
a075b998d3 feat: estimate detail footer. 2021-12-26 13:25:52 +02:00
elforjani13
93aa60124b feat: add convert to vendor credit. 2021-12-26 13:25:07 +02:00
elforjani13
f9a7306e47 feat: add convert to credit note. 2021-12-26 13:24:38 +02:00
elforjani13
10f0d47b54 fix: BIG-145 rename product/service to product. 2021-12-26 13:22:27 +02:00
a.bouhuolia
1d505db7bf fix: BIG-193 purchase item description does fill on item entries table. 2021-12-25 19:40:14 +02:00
a.bouhuolia
6975ebb9e7 feat: styled preferences page cards. 2021-12-25 19:35:07 +02:00
a.bouhuolia
5defb5a279 feat: credit note and vendor credit universal search. 2021-12-25 18:52:46 +02:00
a.bouhuolia
1497a27e7d feat: add terms and conditions to invoice details. 2021-12-25 12:10:29 +02:00
elforjani13
af9f4c45fc feat: add inventory adjustment entries. 2021-12-23 17:58:26 +02:00
elforjani13
d719ac60bd feat: add ability credit & vendor & item transactions. 2021-12-23 17:27:28 +02:00
elforjani13
789c8db693 feat: localization. 2021-12-23 13:33:02 +02:00
a.bouhuolia
7eea202f9d feat(CommercialDoc): tweak in style. 2021-12-23 11:16:28 +02:00
a.bouhuolia
5b581b86f4 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-23 11:10:28 +02:00
a.bouhuolia
1ad2117c37 feat: optimize style of card component. 2021-12-23 11:10:07 +02:00
elforjani13
b1afa88c16 feat: add localization. 2021-12-22 22:02:38 +02:00
elforjani13
4b7af1c634 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-22 20:43:07 +02:00
elforjani13
29a4ab7590 feat: add locking localization. 2021-12-22 20:42:41 +02:00
a.bouhuolia
7150f12a01 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-22 19:17:46 +02:00
a.bouhuolia
934b0abbe6 feat: optimize style of role permissions form. 2021-12-22 19:17:41 +02:00
elforjani13
b36468ff7f feat: add localization. 2021-12-22 15:59:16 +02:00
a.bouhuolia
10c421dea0 feat: optimize account details. 2021-12-21 20:29:51 +02:00
a.bouhuolia
661cbaf11e feat: optimize landed cost entries table style. 2021-12-21 20:18:34 +02:00
a.bouhuolia
1e5b394575 feat: optimize style of reconcile customer/vendor credit table. 2021-12-21 20:09:32 +02:00
a.bouhuolia
dd7b44eb29 feat: display expense formatted amount. 2021-12-21 18:36:45 +02:00
a.bouhuolia
a456b9d942 feat: optimize expense and manual journal details status. 2021-12-21 18:10:58 +02:00
a.bouhuolia
5429643db5 feat: optimize expense and manual journal details. 2021-12-21 17:57:03 +02:00
a.bouhuolia
13310b1aac feat: optimize table of item associated transactions. 2021-12-21 17:11:41 +02:00
a.bouhuolia
7987f68aa3 refactor: payment made details total lines. 2021-12-21 16:55:35 +02:00
a.bouhuolia
1d159c2757 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-21 16:51:54 +02:00
a.bouhuolia
588995e759 refactor: Total lines of commercial documents. 2021-12-21 16:51:47 +02:00
a.bouhuolia
e2349f1951 feat: changelog. 2021-12-21 16:47:15 +02:00
elforjani13
e80901c7a6 fix: itemPerfernce. 2021-12-21 12:24:25 +02:00
elforjani13
c87a98a5e4 fix: accountant. 2021-12-21 12:12:06 +02:00
elforjani13
da3564d315 fix: handle switch button item transaction. 2021-12-21 10:43:04 +02:00
elforjani13
0d924464ea feat: add style of payment made. 2021-12-20 16:47:48 +02:00
elforjani13
961082c50b Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-20 16:11:21 +02:00
elforjani13
828c33bee1 feat: add style of vendor credit. 2021-12-20 16:11:10 +02:00
a.bouhuolia
1540a20a6e Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-20 16:08:30 +02:00
a.bouhuolia
2a37497648 feat: optimize style of sale receipt details. 2021-12-20 16:08:25 +02:00
elforjani13
dbe067a27c Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-20 15:31:15 +02:00
elforjani13
3511348d04 feat: add style of bill. 2021-12-20 15:31:03 +02:00
a.bouhuolia
ace3fdc569 feat: optmize style of payment receive details. 2021-12-20 14:33:48 +02:00
a.bouhuolia
a0098382e7 feat: optimize style of sale estimate details. 2021-12-20 14:12:19 +02:00
a.bouhuolia
a953236bff Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-20 13:28:22 +02:00
a.bouhuolia
4dda2a37aa feat: optimize style of invoice details.
feat: optimize style of credit note details.
feat: optimize global style checkbox  of the application.
2021-12-20 13:19:59 +02:00
elforjani13
0e79dceae8 feat: add journal entries credit & vendor. 2021-12-20 11:47:01 +02:00
elforjani13
0ca0a2ee0b feat: add context menu. 2021-12-20 11:12:38 +02:00
elforjani13
7095903653 feat: add contextMenu in item transactions. 2021-12-19 19:29:42 +02:00
elforjani13
30841d57dc feat: add item payment transactions. 2021-12-19 18:25:41 +02:00
elforjani13
d0f889850c feat: add contextMenu in invoice & bill transactions. 2021-12-19 17:30:16 +02:00
elforjani13
f9fe3506c5 feat: item payment transactions. 2021-12-19 17:29:25 +02:00
elforjani13
8390e5ea6b fix: fix errors. 2021-12-16 21:11:21 +02:00
a.bouhuolia
fcd1a8849d fix(Invoice|Bill): draft status round tag. 2021-12-16 14:48:38 +02:00
a.bouhuolia
9bd047917d feat(EstimatesList): optimize status tags. 2021-12-16 12:49:11 +02:00
a.bouhuolia
2108666f3a Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-15 22:31:28 +02:00
a.bouhuolia
0f10b71604 feat(Changelog): release v1.5.0 logs. 2021-12-15 22:31:24 +02:00
elforjani13
09e739a5a9 feat: edit locking transactions. 2021-12-15 20:45:42 +02:00
elforjani13
a7a94ba201 fix: fix format. 2021-12-15 20:19:04 +02:00
a.bouhuolia
3466828b65 feat(VendorCredit): optimize data table style. 2021-12-15 19:55:47 +02:00
a.bouhuolia
cfed874182 feat(RefundCreditNote): optimize style. 2021-12-15 19:54:17 +02:00
a.bouhuolia
c688b8700e feat(TextStatus): new component. 2021-12-15 19:53:21 +02:00
a.bouhuolia
7a608d2ee3 feat: transactions locking content. 2021-12-15 19:53:04 +02:00
a.bouhuolia
33b998cbda Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-15 12:01:44 +02:00
a.bouhuolia
d7da0ad24e feat: architect transactions locking. 2021-12-15 11:59:39 +02:00
elforjani13
92cff82184 feat: add edit locking transactions. 2021-12-14 22:05:17 +02:00
a.bouhuolia
7cd2b1c533 feat: transactions list container dynamic width. 2021-12-14 19:09:41 +02:00
a.bouhuolia
29a34f826a feat: controlled transactions locking type. 2021-12-14 19:01:15 +02:00
a.bouhuolia
bd97a73c65 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-14 18:04:07 +02:00
a.bouhuolia
eebe4c46fa feat: handle transactions locking request error. 2021-12-14 18:03:58 +02:00
elforjani13
6aba694518 feat: add payment trasnactions. 2021-12-14 17:56:42 +02:00
elforjani13
ae7d37a0e0 Merge branch 'feature/associated-payment-transactions' into develop 2021-12-14 13:06:05 +02:00
elforjani13
897e674912 feat add localization & auto focus. 2021-12-13 20:14:16 +02:00
a.bouhuolia
a52f00eeb2 feat: optimize transactions locking. 2021-12-13 19:22:56 +02:00
a.bouhuolia
0ee9b54a9b fix: cancel partial locking. 2021-12-13 17:46:26 +02:00
a.bouhuolia
dd8bb9cb18 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-13 17:37:32 +02:00
a.bouhuolia
86762d2dc8 feat: add little space between items of transactions locking. 2021-12-13 17:37:26 +02:00
elforjani13
c124002605 feat: add cancel unlocking alert. 2021-12-13 17:36:48 +02:00
a.bouhuolia
8e18d4a0dc feat: modify the locked transactions module. 2021-12-13 16:47:52 +02:00
a.bouhuolia
21e075b479 feat: validate before move to full and partial transactions locking. 2021-12-13 16:28:36 +02:00
a.bouhuolia
51dfee699f Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-13 15:23:49 +02:00
a.bouhuolia
a6a10ef6b8 feat: switch betweel full and partial transactions locking. 2021-12-13 15:22:33 +02:00
elforjani13
fba46e2479 feat: add module in payload. 2021-12-13 15:20:16 +02:00
elforjani13
c4650f5d31 fix: name list. 2021-12-13 14:03:34 +02:00
a.bouhuolia
a441f78e61 Merge branch 'develop' of https://github.com/bigcapitalhq/client into develop 2021-12-13 13:58:13 +02:00
a.bouhuolia
280d991567 feat: add lock all transactions at once callout. 2021-12-13 13:53:21 +02:00
elforjani13
62e5db86a5 feat: locking transaction page. 2021-12-13 13:48:21 +02:00
a.bouhuolia
4fe4178090 feat: optimize transactions locking style. 2021-12-13 12:12:48 +02:00
elforjani13
dfc0fbbb71 feat: add transactions locking query. 2021-12-12 19:15:31 +02:00
elforjani13
295fff4746 feat: add unlocking transactions dialog. 2021-12-12 19:10:58 +02:00
elforjani13
c671fcd011 feat: add unlocking partail transactions dialog. 2021-12-12 19:06:55 +02:00
elforjani13
a6141d9f73 feat: add transactions locking. 2021-12-12 19:01:52 +02:00
elforjani13
91d1dddfed fix: add credited_amount & calculate remaining. 2021-12-09 16:55:29 +02:00
elforjani13
ca746df86d feat: add quick create & sortable. 2021-12-09 14:01:53 +02:00
elforjani13
02330c84b1 feat: invalidate query. 2021-12-08 22:59:48 +02:00
elforjani13
c89b8b131d fix: fix notes. 2021-12-08 22:43:44 +02:00
elforjani13
3690c88c04 fix: loading state on submit button. 2021-12-08 20:11:09 +02:00
elforjani13
6573f19ff8 fix: notes. 2021-12-08 18:53:14 +02:00
elforjani13
a948dd4236 feat: add delete reconcile & handle error. 2021-12-08 18:51:21 +02:00
a.bouhuolia
56b1c36c9d Merge branch 'feature/credit-memo' into develop 2021-12-08 15:43:49 +02:00
a.bouhuolia
bc7ec834c0 Merge branch 'feature/credit-memo' into develop 2021-12-08 15:21:39 +02:00
elforjani13
5963d14fdd feat: add reconcile vendor credit. 2021-12-08 14:33:33 +02:00
elforjani13
80b8083059 feat: add reconcile credit style. 2021-12-07 21:12:56 +02:00
elforjani13
ecaf23d269 feat: add reconcile credit transactions table. 2021-12-07 20:58:17 +02:00
elforjani13
14f33c667b feat: handle error message. 2021-12-07 20:56:54 +02:00
elforjani13
78c42acb17 feat: add reconcile credit note. 2021-12-07 20:55:47 +02:00
elforjani13
192bcdc696 feat: add filterByTypes 2021-12-07 11:00:57 +02:00
elforjani13
ac99a6ca75 feat: add status & opened alert in credit & vendor. 2021-12-06 16:28:42 +02:00
elforjani13
2a48d9be51 feat: add refund transactions. 2021-12-05 19:30:52 +02:00
elforjani13
ab48e6092a feat: add refund credit & vendor dialogs. 2021-12-05 19:29:39 +02:00
elforjani13
bf99bda616 fix: credit & vendor reducer. 2021-12-04 22:16:36 +02:00
elforjani13
e1a3f471cb feat: add Invalidate landed cost in bill. 2021-12-04 18:59:01 +02:00
elforjani13
07e52bef7a feat: add payment transaction & style 2021-12-04 18:08:20 +02:00
a.bouhuolia
d3c5131020 fix: allocate landed cost on inventory items. 2021-12-04 16:32:37 +02:00
elforjani13
58a0ed4ecd fix: formatted amount & lang in credit view. 2021-12-04 12:41:08 +02:00
elforjani13
26cf1d20f3 feat: add formatted amount & date in credit view. 2021-12-02 17:04:24 +02:00
elforjani13
0fedd2479d feat: add formatted amount & data in credit. 2021-12-02 16:07:18 +02:00
elforjani13
ba585271b0 feat: landed cost fields & style. 2021-12-02 15:36:29 +02:00
elforjani13
0c4259a05b feat: style journal entries. 2021-12-02 15:34:26 +02:00
elforjani13
31e0bbc187 feat: add View detail. 2021-12-01 16:59:37 +02:00
elforjani13
43b91503d2 feat: add auto increment in vendor credit number. 2021-12-01 14:02:54 +02:00
elforjani13
432e2d202a feat: add Auto increment in credit note number. 2021-12-01 14:02:31 +02:00
elforjani13
eeb16f4362 feat: add create & edit & delete in credit note. 2021-11-30 21:04:36 +02:00
elforjani13
15fa1729a2 feat: add create & edit & delete in vendor credit. 2021-11-30 16:34:13 +02:00
elforjani13
119d0b2839 feat: Vendor Credit note. 2021-11-29 16:33:43 +02:00
elforjani13
0a9798e7a7 feat: Credit note. 2021-11-29 16:14:22 +02:00
a.bouhuolia
008faaece6 Merge branch 'master' of https://github.com/bigcapitalhq/client 2021-11-28 09:05:55 +02:00
elforjani13
346696f673 fix: ability option key. 2021-11-27 20:23:40 +02:00
elforjani13
68227b81e8 fix: pause transactions locaking. 2021-11-27 19:44:06 +02:00
elforjani13
0c806366cd feat: handle error delete role. 2021-11-27 18:51:35 +02:00
elforjani13
802f7cc442 fix: add note to customer & vendor details. 2021-11-23 13:13:23 +02:00
elforjani13
0ad5a9ed03 feat: item payment transactions. 2021-11-15 21:45:24 +02:00
elforjani13
bd282acae4 feat: invoice payment transactions. 2021-11-15 21:44:46 +02:00
elforjani13
377fb07c70 feat: bill payment transactions. 2021-11-15 21:43:39 +02:00
13191 changed files with 335423 additions and 118355 deletions

49
.env.example Normal file
View File

@@ -0,0 +1,49 @@
# Mail
MAIL_HOST=
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_PORT=
MAIL_SECURE=
MAIL_FROM_NAME=
MAIL_FROM_ADDRESS=
# Database
DB_HOST=mysql
DB_USER=bigcapital
DB_PASSWORD=bigcapital
DB_ROOT_PASSWORD=root
DB_CHARSET=utf8
# System database
SYSTEM_DB_NAME=bigcapital_system
# SYSTEM_DB_USER=
# SYSTEM_DB_PASSWORD=
# SYSTEM_DB_NAME=
# SYSTEM_DB_CHARSET=
# Tenant databases
TENANT_DB_NAME_PERFIX=bigcapital_tenant_
# TENANT_DB_HOST=
# TENANT_DB_USER=
# TENANT_DB_PASSWORD=
# TENANT_DB_CHARSET=
# Application
BASE_URL=https://bigcapital.ly
JWT_SECRET=b0JDZW56RnV6aEthb0RGPXVEcUI
# Jobs MongoDB
MONGODB_DATABASE_URL=mongodb://localhost/bigcapital
# App proxy
PUBLIC_PROXY_PORT=80
PUBLIC_PROXY_SSL_PORT=443
# Agendash
AGENDASH_AUTH_USER=agendash
AGENDASH_AUTH_PASSWORD=123123
# Sign-up restrictions
SIGNUP_DISABLED=true
SIGNUP_ALLOWED_DOMAINS=
SIGNUP_ALLOWED_EMAILS=

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
docker/nginx/scripts/build-nginx.sh text eol=lf
docker/mariadb/docker-entrypoint.sh text eol=lf

View File

@@ -0,0 +1,81 @@
# This workflow will build a docker container, publish it to Github Registry.
name: Build and Deploy Docker Container
on:
release:
types: [created]
workflow_dispatch:
env:
REGISTRY: ghcr.io
WEBAPP_IMAGE_NAME: bigcapital/bigcapital-webapp
SERVER_IMAGE_NAME: bigcapital/bigcapital-server
jobs:
build-publish-webapp:
name: Build and deploy webapp container
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v2
# Login to Container registry.
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GH_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.WEBAPP_IMAGE_NAME }}
# Builds and push the Docker image.
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
file: ./packages/webapp/Dockerfile
push: true
tags: ghcr.io/bigcapitalhq/webapp:latest
labels: ${{ steps.meta.outputs.labels }}
# Send notification to Slack channel.
- name: Slack Notification built and published webapp container successfully.
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
build-publish-server:
name: Build and deploy server container
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
# Login to Container registry.
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GH_TOKEN }}
# Builds and push the Docker image.
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: ./
file: ./packages/server/Dockerfile
push: true
tags: ghcr.io/bigcapitalhq/server:latest
labels: ${{ steps.meta.outputs.labels }}
# Send notification to Slack channel.
- name: Slack Notification built and published server container successfully.
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -1,63 +0,0 @@
# This workflow will build a docker container, publish it to Google Container Registry, and deploy it to GKE when a release is created
#
# To configure this workflow:
#
# 1. Ensure that your repository contains the necessary configuration for your Google Kubernetes Engine cluster, including deployment.yml, kustomization.yml, service.yml, etc.
#
# 2. Set up secrets in your workspace: GKE_PROJECT with the name of the project and GKE_SA_KEY with the Base64 encoded JSON service account key (https://github.com/GoogleCloudPlatform/github-actions/tree/docs/service-account-key/setup-gcloud#inputs).
#
# 3. Change the values for the GKE_ZONE, GKE_CLUSTER, IMAGE, and DEPLOYMENT_NAME environment variables (below).
#
# For more support on how to run the workflow, please visit https://github.com/google-github-actions/setup-gcloud/tree/master/example-workflows/gke
name: Build and Deploy Docker Container
on:
release:
types: [created]
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: abouhuolia/bigcapital-client
jobs:
setup-build-publish-deploy:
name: Setup, Build, Publish, and Deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v2
# Login to Container registry.
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GH_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# Builds and push the Docker image.
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ghcr.io/bigcapitalhq/client:latest
labels: ${{ steps.meta.outputs.labels }}
# Send notification to Slack channel.
- name: Slack Notification built and published successfully.
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

68
.github/workflows/e2e.yml vendored Normal file
View File

@@ -0,0 +1,68 @@
name: E2E
on:
push:
branches:
- main
- develop
paths:
- '**.ts'
- '**.tsx'
- '**/tsconfig.json'
- 'yarn.lock'
- '.github/workflows/e2e.yml'
pull_request:
paths:
- '**.ts'
- '**.tsx'
- '**/tsconfig.json'
- 'yarn.lock'
- '.github/workflows/e2e.yml'
defaults:
run:
shell: 'bash'
jobs:
test_setup:
name: Test setup
runs-on: ubuntu-latest
outputs:
preview_url: ${{ steps.waitForVercelPreviewDeployment.outputs.url }}
steps:
- name: Wait for Vercel preview deployment to be ready
uses: patrickedqvist/wait-for-vercel-preview@v1.3.1
id: waitForVercelPreviewDeployment
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 3000
test_e2e:
runs-on: ubuntu-latest
needs: test_setup
name: Playwright tests
timeout-minutes: 15
environment: ${{ vars.ENVIRONMENT_STAGE }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 14 # Need for npm >=7.7
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Install Playwright with deps
run: npx playwright install --with-deps
- name: Run tests
run: npm run test:e2e
env:
PLAYWRIGHT_TEST_BASE_URL: ${{ needs.test_setup.outputs.preview_url }}
- uses: actions/upload-artifact@v2
if: always()
with:
name: playwright-report
path: test-results/
retention-days: 30

26
.gitignore vendored
View File

@@ -1,22 +1,4 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
node_modules/
data
.env
test-results/

4
.husky/commit-msg Normal file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
yarn commitlint --edit

2
.husky/pre-commit Normal file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
v14.20

View File

@@ -2,7 +2,284 @@
All notable changes to Bigcapital server-side will be in this file.
## [1.2.0-RC] - 03-09-2021
## [0.9.1] - 28-05-2023
`@bigcapital/server`
- fix: deleting ledger entries of manual journal.
- fix: base currency should be enabled.
- fix: delete invoice transaction issue.
`@bigcapital/webapp`
- fix: general, accoutant and items preferences.
- fix: auto-increment sale invoices, estiamtes, credit notes, payments and manual journals.
- refactor: the setup organization form to use binded Formik components.
## [0.9.0] - 06-05-2023
`@bigcapital/server`
- [Sign-up restrictions](https://docs.bigcapital.ly/docs/deployment/signup_restriction) for self-hosting instances to disable signup or control the allowed email addresses and domains that can sign-up.
## [0.8.3] - 06-04-2023
`@bigcaptial/monorepo`
- Switch to AGPL license to protect application's networks. by @abouolia
`@bigcapital/webapp`
### Added
- Improve the style of authentication pages. by @abouolia
- Remove the phone number field from the authentication pages. by @abouolia
- Remove the phone number field from the users management. by @abouolia
- Add all countries options to the setup page. by @abouolia
### Fixed
- Fix intent type of reset password success toast.
`@bigcapital/server`
### Added
- Remove the phone number field from the authentication service. by @abouolia
- Remove the phone number field from the users service. by @abouolia
## [0.8.1] - 26-03-2023
`@bigcaptial/monorepo`
### Added
* add docker compose for development env. by @abouolia
`@bigcapital/webapp`
### Fixes
* fix: hide the project name entry if the feature was not enabled. by @abouolia
* fix: labels of add money in/out don't appear. by @abouolia
* fix: accounts chart lags when scrolling down. by @abouolia
* fix: the inconsistent style of quick customer/vendor drawer. by @abouolia
* fix: add an icon to duplicate item of items context menu. by @abouolia
* fix: account form issues. by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/86
### Added
* Optimize the design of setup organization page. by @abouolia
`@bigcapital/server`
### Added
* bigcapital CLI commands by @abouolia
* deprecate the subscription module. @abouolia
### Fixes
* fix: Validate the max depth level of the parent account. by @abouolia
## [0.7.6] - 23-04-2022
`@bigcapital/webapp`
### Fixed
- `BIG-374` Refactoring sidebar men with ability permissions and feature control on each item.
## [0.7.5] - 20-04-2022
### Fixed.
- `BIG-378` Reports drawers columns css conflict.
## [0.7.3] - 15-04-2022
`@bigcapital/webapp`
### Fixed
- `BIG-372` Activate branches and warehouses dialog reloading once activating.
- `BIG-373` Issue general ledger report select specific account.
- `BIG-377` Make readonly details entries as oneline with tooltip for more details.
## [0.7.2] - 04-04-2022
`@bigcapital/webapp`
### Fixed
- Add the missing Arabic localization.
- Subscription plans modifications.
## [0.7.1] - 30-03-2022
`@bigcapital/webapp`
### Added
- `BIG-141` Add inactive status to item drawer details.
- `BIG-278` Add created at date on expense details.
- `BIG-350` Add empty status content of warehouse transfers service.
- `BIG-344` Add branch details to manual journal and expense details.
### Fixed
- `BIG-221` Remove Non-inventory radio choice on item form.
- `BIG-236` Validate estimate expiration date should be equal or bigger than estimate date.
- `BIG-237` Validate invoice due date should be equal or bigger than invoice date.
- `BIG-238` Validate bill due date should be equal or bigger than bill date.
- `BIG-280` Optimize style of multi-select accounts menu.
- `BIG-284` Cashflow statement loading bar.
- `BIG-296` Creating a new child account from accounts list.
- `BIG-301` Navigation bar divider on actions bar hide with permissions control.
- `BIG-304` Adding cash or bank account from cash flow service.
- `BIG-351` Invalid date in the inventory adjustment detail.
- `BIG-352` Fix terms and notes fields on footer of all services.
- `BIG-354` Validate the warehouse transfer quantity should be above zero.
`@bigcapital/server`
### Fixed
- `BIG-354` Validate the warehouse transfer quantity should be above zero.
- `BIG-358` Refactoring customers/vendors services for smaller classes.
- `BIG-341` Refactoring expenses services for smaller classes.
- `BIG-342` Assign default currency as base currency when create customer, vendor or expense transaction.
## [0.7.0] - 24-03-2022
`@bigcapital/webapp`
### Added
- Multiply currencies with foreign currencies.
- Multiply warehouses to track inventory items.
- Multiply branches to track organization transactions.
- Transfer orders between warehouses.
- Integrate financial reports with multiply branches.
- Integrate inventory reports with multiply warehouses.
### Changes
- Optimize style of sale invoice form.
- Optimize style of sale receipt form.
- Optimize style of credit note form.
- Optimize style of payment receive form.
- Optimize style of bill form.
- Optimize style of payment made form.
- Optimize style of manual journal form.
- Optimize style of expense form.
`@bigcapital/server`
### Added
- Multiply currencies with foreign currencies.
- Multiply warehouses to track inventory items.
- Multiply branches to track organization transactions.
- Transfer orders between warehouses.
- Integrate financial reports with multiply branches.
- Integrate inventory reports with multiply warehouses.
## [0.6.3] - 21-02-2022
`@bigcapital/webapp`
### Fixed
- `BIG-337` Display billing page once the organization subscription is inactive.
## [0.6.2] - 19-02-2022
### Fixed
- fix syled components dependency with imported as default components.
## [0.6.0] - 18-02-2022
`@bigcapital/webapp`
### Added
- Balance sheet comparison of previous period (PP).
- Balance sheet comparison of previous year (PY).
- Balance sheet percentage analysis columns and rows basis.
- Profit & loss sheet comparison of preivous period (PP).
- Profit & loss sheet comparison of previous year (PY).
- Profit & loss sheet percentage analysis columns, rows, income and expenses basis.
## [0.5.8] - 13-01-2022
`@bigcapital/webapp`
### Added
- Add payment receive PDF print.
- Add credit note PDF print.
### Fixed
- Payment receive initial loading state depends on request loading state instead fetching.
- Balance sheet report alert positioning.
- Separate customer and vendor inactivate and activate alerts.
- Hide convert to invoice button if the invoice is already converted.
- Customer and vendor balance summary percentage of column option.
- Remove duplicated details in sales and purchases details drawers.
`@bigcapital/server`
### Fixed
- Balance sheet comparison of previous period (PP).
- Balance sheet comparison of previous year (PY).
- Balance sheet percentage analysis columns and rows basis.
- Profit & loss sheet comparison of preivous period (PP).
- Profit & loss sheet comparison of previous year (PY).
- Profit & loss sheet percentage analysis columns, rows, income and expenses basis.
## [0.5.3] - 03-01-2020
`@bigcapital/webapp`
### Fixed
- Localize the global errors.
- Expand account name column on trial balance sheet.
## [0.5.0] - 20-12-2021
`@bigcapital/webapp`
### Added
- Add credit note on sales module.
- Add vendor credit on purchases module.
- Optimize landed costs on purchase invoices.
- Display associated payment transactions on sale invoice drawer.
- Display associated pamyment transactions on purchase invoice drawer.
- Display item associate invoice, bill, estimate and receipt transactions.
- Transactions locking on all transactions or individual modules.
- Roles and permissions access control module.
- Optimize readonly details style of invoice, receipt, estimate, payment receive,
purchase invoice, expense, manual journal, inventory adjustment and cashflow transaction.
### Changed
- Dashboard meta boot and authenticated user request query.
- Optimize Arabic localization.
## [0.4.0] - 11-09-2021
`@bigcapital/webapp`
### Added
- Add SMS notification on sale invoice, receipt, customers payments modules.
- Customer quick create in customers list.
- Item quick create in items list.
### Changes
change: BIG-171 alerts in global scope and lazy loading.
### Fixed
fix: BIG-140 - Reordering sell, cost and inventory account on item details.
fix: BIG-144 - Typo adjustment dialog success message.
fix: BIG-148 - Items entries ordered by index.
fix: BIG-132 AR/AP aging summary report filter by none transactions/zero contacts.
## [0.2.0] - 03-09-2021
`@bigcapital/webapp`
Here we write upgrading notes for brands. It's a team effort to make them as
straightforward as possible.
@@ -32,7 +309,7 @@ straightforward as possible.
- Inventory adjustment publish action.
- Customers and vendors activate and inactivate action.
- Add refresh button on dashboard actions bar to all datatables resources.
- Add clickable datatable rows to display each row details.
- Add clickable datatable rows to display each row details.
### Changed

132
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,132 @@
# Contributing Guidelines
Thank you for considering contributing to our project! We appreciate your interest and welcome any contributions you may have.
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution.
## Sections
- [General Instructions](#general-instructions)
- [Contribute to Backend](#contribute-to-backend)
- [Contribute to Frontend](#contribute-to-frontend)
- [Other Ways to Contribute](#other-ways-to-contribute)
## General Instructions
## For Pull Request(s)
Contributions via pull requests are much appreciated. Once the approach is agreed upon ✅, make your changes and open a Pull Request(s). Before sending us a pull request, please ensure that,
- Fork the repo on GitHub, clone it on your machine.
- Create a branch with your changes.
- You are working against the latest source on the `develop` branch.
- Modify the source; please focus only on the specific change.
- Ensure local tests pass.
- Commit to your fork using clear commit messages.
- Send us a pull request.
- Pay attention to any automated CI failures reported in the pull request.
- Stay involved in the conversation
⚠️ Please note: If you want to work on an issue, please ask the maintainers to assign the issue to you before starting work on it. This would help us understand who is working on an issue and prevent duplicate work. 🙏🏻
---
## Contribute to Backend
- Clone the `bigcapital` repository and `cd` into `bigcapital` directory.
- Install all npm dependencies of the monorepo, you don't have to change directory to the `backend` package. just hit these command on root directory and it will install dependencies of all packages.
```
npm install
npm run bootstrap
```
- Run all required docker containers in the development, we already configured all containers under `docker-compose.yml`.
```
docker-compose up -d
```
Wait some seconds, and hit `docker-compose ps` and you should see the same result below.
```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d974edfab9df bigcapital-mysql "docker-entrypoint.s…" 7 seconds ago Up 1 second 0.0.0.0:3306->3306/tcp, 33060/tcp bigcapital-mysql-1
cefa73fe2881 bigcapital-redis "docker-entrypoint.s…" 7 seconds ago Up 1 second 6379/tcp bigcapital-redis-1
1ea059198cb4 bigcapital-mongo "docker-entrypoint.s…" 7 seconds ago Up 1 second 0.0.0.0:27017->27017/tcp bigcapital-mongo-1
```
- There're some CLI commands we should run before running the server like databaase migration, so we need to build the `server` app first.
```
npm run build:server
```
- Run the database migration for system database.
```
node packages/server/build/commands.js system:migrate:latest
```
And you should get something like that.
```
Batch 1 run: 6 migrations
```
- Next, start the webapp application.
```
npm run dev:server
```
**[`^top^`](#)**
----
## Contribute to Frontend
- Clone the `bigcapital` repository and cd into `bigcapital` directory.
```
git clone https://github.com/bigcapital/bigcapital.git && cd bigcaptial
```
- Install all npm dependencies of the monorepo, you don't have to change directory to the `frontend` package. just hit that command and will install all packages across all application.
```
npm install
npm run bootstrap
```
- Next, start the webapp application.
```
npm run dev:webapp
```
**[`^top^`](#)**
---
## Code Review
We welcome constructive criticism and feedback on code submitted by contributors. All feedback should be constructive and respectful, and should focus on the code rather than the contributor. Code review may include suggestions for improvement or changes to the code.
---
## Other Ways to Contribute
There are many other ways to get involved with the community and to participate in this project:
- Use the product, submitting GitHub issues when a problem is found.
- Help code review pull requests and participate in issue threads.
- Submit a new feature request as an issue.
- Help answer questions on forums such as Bigcapital Community Discord Channel.
- Tell others about the project on Twitter, your blog, etc.
**[`^top^`](#)**
Again, Feel free to ping us on [`#contributing`](https://discord.com/invite/c8nPBJafeb) on our Discord community if you need any help on this :)
Thank You!

3
DISCLAIMER Normal file
View File

@@ -0,0 +1,3 @@
This software is provided "as is" and without any express or implied warranties, including, without limitation, the implied warranties of merchantability and fitness for a particular purpose.
In no event shall the authors or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.

View File

@@ -1,20 +0,0 @@
FROM node:14.15.0 as build
USER root
WORKDIR /app
COPY ./package.json /app/package.json
COPY ./package-lock.json /app/package-lock.json
RUN npm install
COPY . .
RUN npm run build
FROM nginx
COPY ./nginx/sites/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html

660
LICENSE Normal file
View File

@@ -0,0 +1,660 @@
### GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc.
<https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
### Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains
free software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing
under this license.
The precise terms and conditions for copying, distribution and
modification follow.
### TERMS AND CONDITIONS
#### 0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public
License.
"Copyright" also means copyright-like laws that apply to other kinds
of works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of
an exact copy. The resulting work is called a "modified version" of
the earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user
through a computer network, with no transfer of a copy, is not
conveying.
An interactive user interface displays "Appropriate Legal Notices" to
the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
#### 1. Source Code.
The "source code" for a work means the preferred form of the work for
making modifications to it. "Object code" means any non-source form of
a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users can
regenerate automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same
work.
#### 2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not convey,
without conditions so long as your license otherwise remains in force.
You may convey covered works to others for the sole purpose of having
them make modifications exclusively for you, or provide you with
facilities for running those works, provided that you comply with the
terms of this License in conveying all material for which you do not
control copyright. Those thus making or running the covered works for
you must do so exclusively on your behalf, under your direction and
control, on terms that prohibit them from making any copies of your
copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the
conditions stated below. Sublicensing is not allowed; section 10 makes
it unnecessary.
#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such
circumvention is effected by exercising rights under this License with
respect to the covered work, and you disclaim any intention to limit
operation or modification of the work as a means of enforcing, against
the work's users, your or third parties' legal rights to forbid
circumvention of technological measures.
#### 4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
#### 5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these
conditions:
- a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
- b) The work must carry prominent notices stating that it is
released under this License and any conditions added under
section 7. This requirement modifies the requirement in section 4
to "keep intact all notices".
- c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
- d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
#### 6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of
sections 4 and 5, provided that you also convey the machine-readable
Corresponding Source under the terms of this License, in one of these
ways:
- a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
- b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding
Source from a network server at no charge.
- c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
- d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
- e) Convey the object code using peer-to-peer transmission,
provided you inform other peers where the object code and
Corresponding Source of the work are being offered to the general
public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal,
family, or household purposes, or (2) anything designed or sold for
incorporation into a dwelling. In determining whether a product is a
consumer product, doubtful cases shall be resolved in favor of
coverage. For a particular product received by a particular user,
"normally used" refers to a typical or common use of that class of
product, regardless of the status of the particular user or of the way
in which the particular user actually uses, or expects or is expected
to use, the product. A product is a consumer product regardless of
whether the product has substantial commercial, industrial or
non-consumer uses, unless such uses represent the only significant
mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to
install and execute modified versions of a covered work in that User
Product from a modified version of its Corresponding Source. The
information must suffice to ensure that the continued functioning of
the modified object code is in no case prevented or interfered with
solely because modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or
updates for a work that has been modified or installed by the
recipient, or for the User Product in which it has been modified or
installed. Access to a network may be denied when the modification
itself materially and adversely affects the operation of the network
or violates the rules and protocols for communication across the
network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
#### 7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders
of that material) supplement the terms of this License with terms:
- a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
- b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
- c) Prohibiting misrepresentation of the origin of that material,
or requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
- d) Limiting the use for publicity purposes of names of licensors
or authors of the material; or
- e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
- f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions
of it) with contractual assumptions of liability to the recipient,
for any liability that these contractual assumptions directly
impose on those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions; the
above requirements apply either way.
#### 8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your license
from a particular copyright holder is reinstated (a) provisionally,
unless and until the copyright holder explicitly and finally
terminates your license, and (b) permanently, if the copyright holder
fails to notify you of the violation by some reasonable means prior to
60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
#### 9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run
a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
#### 10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
#### 11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims owned
or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within the
scope of its coverage, prohibits the exercise of, or is conditioned on
the non-exercise of one or more of the rights that are specifically
granted under this License. You may not convey a covered work if you
are a party to an arrangement with a third party that is in the
business of distributing software, under which you make payment to the
third party based on the extent of your activity of conveying the
work, and under which the third party grants, to any of the parties
who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by
you (or copies made from those copies), or (b) primarily for and in
connection with specific products or compilations that contain the
covered work, unless you entered into that arrangement, or that patent
license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
#### 12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under
this License and any other pertinent obligations, then as a
consequence you may not convey it at all. For example, if you agree to
terms that obligate you to collect a royalty for further conveying
from those to whom you convey the Program, the only way you could
satisfy both those terms and this License would be to refrain entirely
from conveying the Program.
#### 13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your
version supports such interaction) an opportunity to receive the
Corresponding Source of your version by providing access to the
Corresponding Source from a network server at no charge, through some
standard or customary means of facilitating copying of software. This
Corresponding Source shall include the Corresponding Source for any
work covered by version 3 of the GNU General Public License that is
incorporated pursuant to the following paragraph.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.
#### 14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Affero General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever
published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions
of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
#### 15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
#### 16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#### 17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
### How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively state
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper
mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for
the specific requirements.
You should also get your employer (if you work as a programmer) or
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. For more information on this, and how to apply and follow
the GNU AGPL, see <https://www.gnu.org/licenses/>.

View File

@@ -1,68 +1,31 @@
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
<p align="center">
<p align="center">
<a href="https://bigcapital.ly" target="_blank">
<img src="https://raw.githubusercontent.com/abouolia/blog/main/public/bigcapital.svg" alt="Bigcapital" width="280" height="75">
</a>
</p>
<p align="center">
Simple, smart online accounting software for small and medium businesses.
</p>
</p>
## Available Scripts
# What's Bigcapital?
In the project directory, you can run:
Bigcapital is a smart and open-source accounting and inventory software, Bigcapital keeps all business finances in right place and automates accounting processes to give the business powerful and intelligent financial statements and reports to help in making decisions.
### `npm start`
<p align="center">
<img src="https://raw.githubusercontent.com/abouolia/blog/main/public/screenshot-2.png" width="270">
<img src="https://raw.githubusercontent.com/abouolia/blog/main/public/screenshot-1.png" width="270">
<img src="https://raw.githubusercontent.com/abouolia/blog/main/public/screenshot-3.png" width="270">
</p>
Runs the app in the development mode.<br />
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
# Resources
The page will reload if you make edits.<br />
You will also see any lint errors in the console.
- [Documentation](https://docs.bigcapital.ly/) - Learn how to use.
- [Discord](https://discord.com/invite/c8nPBJafeb) - Ask for help.
- [Bug Tracker](https://github.com/bigcapitalhq/bigcapital/issues) - Notify us new bugs.
- [Source Code](https://github.com/bigcapitalhq/bigcapital) - Github repo.
### `npm test`
# Changelog
Launches the test runner in the interactive watch mode.<br />
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.<br />
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.<br />
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
### Analyzing the Bundle Size
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
### Making a Progressive Web App
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
### Advanced Configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
### Deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
### `npm run build` fails to minify
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
Please see [Releases](https://github.com/bigcapitalhq/bigcapital/releases) for more information what has changed recently.

1
commitlint.config.js Normal file
View File

@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-lerna-scopes'] };

View File

@@ -1,101 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];
const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
throw new Error(
'The NODE_ENV environment variable is required but was not specified.'
);
}
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
const dotenvFiles = [
`${paths.dotenv}.${NODE_ENV}.local`,
`${paths.dotenv}.${NODE_ENV}`,
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
paths.dotenv,
].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,
})
);
}
});
// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebook/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory, folder))
.join(path.delimiter);
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in webpack configuration.
const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
.filter(key => REACT_APP.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
return env;
},
{
// Useful for determining whether were running in production mode.
// Most importantly, it switches React into the correct mode.
NODE_ENV: process.env.NODE_ENV || 'development',
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
PUBLIC_URL: publicUrl,
// We support configuring the sockjs pathname during development.
// These settings let a developer run multiple simultaneous projects.
// They are used as the connection `hostname`, `pathname` and `port`
// in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
// and `sockPort` options in webpack-dev-server.
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
}
);
// Stringify all values so we can feed into webpack DefinePlugin
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};
return { raw, stringified };
}
module.exports = getClientEnvironment;

View File

@@ -1,66 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const chalk = require('react-dev-utils/chalk');
const paths = require('./paths');
// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
let encrypted;
try {
// publicEncrypt will throw an error with an invalid cert
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
throw new Error(
`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
);
}
try {
// privateDecrypt will throw an error with an invalid key
crypto.privateDecrypt(key, encrypted);
} catch (err) {
throw new Error(
`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
err.message
}`
);
}
}
// Read file and throw an error if it doesn't exist
function readEnvFile(file, type) {
if (!fs.existsSync(file)) {
throw new Error(
`You specified ${chalk.cyan(
type
)} in your env, but the file "${chalk.yellow(file)}" can't be found.`
);
}
return fs.readFileSync(file);
}
// Get the https config
// Return cert files if provided in env, otherwise just true or false
function getHttpsConfig() {
const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
const isHttps = HTTPS === 'true';
if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
const config = {
cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
};
validateKeyAndCerts({ ...config, keyFile, crtFile });
return config;
}
return isHttps;
}
module.exports = getHttpsConfig;

View File

@@ -1,14 +0,0 @@
'use strict';
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process() {
return 'module.exports = {};';
},
getCacheKey() {
// The output is always the same.
return 'cssTransform';
},
};

View File

@@ -1,40 +0,0 @@
'use strict';
const path = require('path');
const camelcase = require('camelcase');
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
const assetFilename = JSON.stringify(path.basename(filename));
if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase(path.parse(filename).name, {
pascalCase: true,
});
const componentName = `Svg${pascalCaseFilename}`;
return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
return {
$$typeof: Symbol.for('react.element'),
type: 'svg',
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${assetFilename}
})
};
}),
};`;
}
return `module.exports = ${assetFilename};`;
},
};

View File

@@ -1,141 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
const chalk = require('react-dev-utils/chalk');
const resolve = require('resolve');
/**
* Get additional module paths based on the baseUrl of a compilerOptions object.
*
* @param {Object} options
*/
function getAdditionalModulePaths(options = {}) {
const baseUrl = options.baseUrl;
// We need to explicitly check for null and undefined (and not a falsy value) because
// TypeScript treats an empty string as `.`.
if (baseUrl == null) {
// If there's no baseUrl set we respect NODE_PATH
// Note that NODE_PATH is deprecated and will be removed
// in the next major release of create-react-app.
const nodePath = process.env.NODE_PATH || '';
return nodePath.split(path.delimiter).filter(Boolean);
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
// We don't need to do anything if `baseUrl` is set to `node_modules`. This is
// the default behavior.
if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
return null;
}
// Allow the user set the `baseUrl` to `appSrc`.
if (path.relative(paths.appSrc, baseUrlResolved) === '') {
return [paths.appSrc];
}
// If the path is equal to the root directory we ignore it here.
// We don't want to allow importing from the root directly as source files are
// not transpiled outside of `src`. We do allow importing them with the
// absolute path (e.g. `src/Components/Button.js`) but we set that up with
// an alias.
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return null;
}
// Otherwise, throw an error.
throw new Error(
chalk.red.bold(
"Your project's `baseUrl` can only be set to `src` or `node_modules`." +
' Create React App does not support other values at this time.'
)
);
}
/**
* Get webpack aliases based on the baseUrl of a compilerOptions object.
*
* @param {*} options
*/
function getWebpackAliases(options = {}) {
const baseUrl = options.baseUrl;
if (!baseUrl) {
return {};
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
src: paths.appSrc,
};
}
}
/**
* Get jest aliases based on the baseUrl of a compilerOptions object.
*
* @param {*} options
*/
function getJestAliases(options = {}) {
const baseUrl = options.baseUrl;
if (!baseUrl) {
return {};
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
'^src/(.*)$': '<rootDir>/src/$1',
};
}
}
function getModules() {
// Check if TypeScript is setup
const hasTsConfig = fs.existsSync(paths.appTsConfig);
const hasJsConfig = fs.existsSync(paths.appJsConfig);
if (hasTsConfig && hasJsConfig) {
throw new Error(
'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
);
}
let config;
// If there's a tsconfig.json we assume it's a
// TypeScript project and set up the config
// based on tsconfig.json
if (hasTsConfig) {
const ts = require(resolve.sync('typescript', {
basedir: paths.appNodeModules,
}));
config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
// Otherwise we'll check if there is jsconfig.json
// for non TS projects.
} else if (hasJsConfig) {
config = require(paths.appJsConfig);
}
config = config || {};
const options = config.compilerOptions || {};
const additionalModulePaths = getAdditionalModulePaths(options);
return {
additionalModulePaths: additionalModulePaths,
webpackAliases: getWebpackAliases(options),
jestAliases: getJestAliases(options),
hasTsConfig,
};
}
module.exports = getModules();

View File

@@ -1,72 +0,0 @@
'use strict';
const path = require('path');
const fs = require('fs');
const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath');
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebook/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
// webpack needs to know it to put the right <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
const publicUrlOrPath = getPublicUrlOrPath(
process.env.NODE_ENV === 'development',
require(resolveApp('package.json')).homepage,
process.env.PUBLIC_URL
);
const moduleFileExtensions = [
'web.mjs',
'mjs',
'web.js',
'js',
'web.ts',
'ts',
'web.tsx',
'tsx',
'json',
'web.jsx',
'jsx',
];
// Resolve file paths in the same order as webpack
const resolveModule = (resolveFn, filePath) => {
const extension = moduleFileExtensions.find(extension =>
fs.existsSync(resolveFn(`${filePath}.${extension}`))
);
if (extension) {
return resolveFn(`${filePath}.${extension}`);
}
return resolveFn(`${filePath}.js`);
};
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
appTsConfig: resolveApp('tsconfig.json'),
appJsConfig: resolveApp('jsconfig.json'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
publicUrlOrPath,
};
module.exports.moduleFileExtensions = moduleFileExtensions;

View File

@@ -1,35 +0,0 @@
'use strict';
const { resolveModuleName } = require('ts-pnp');
exports.resolveModuleName = (
typescript,
moduleName,
containingFile,
compilerOptions,
resolutionHost
) => {
return resolveModuleName(
moduleName,
containingFile,
compilerOptions,
resolutionHost,
typescript.resolveModuleName
);
};
exports.resolveTypeReferenceDirective = (
typescript,
moduleName,
containingFile,
compilerOptions,
resolutionHost
) => {
return resolveModuleName(
moduleName,
containingFile,
compilerOptions,
resolutionHost,
typescript.resolveTypeReferenceDirective
);
};

View File

@@ -1,691 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const CompressionPlugin = require("compression-webpack-plugin");
const postcssNormalize = require('postcss-normalize');
const { postcssRTLCSS} = require('postcss-rtlcss');
const appPackageJson = require(paths.appPackageJson);
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function(webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
// Variable used for enabling profiling in Production
// passed into alias object. Uses a flag if passed into the build command
const isEnvProductionProfile =
isEnvProduction && process.argv.includes('--profile');
// We will provide `paths.publicUrlOrPath` to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
// Get environment variables to inject into our app.
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
// css is located in `static/css`, use '../../' to locate index.html folder
// in production `paths.publicUrlOrPath` can be a relative path
options: paths.publicUrlOrPath.startsWith('.')
? { publicPath: '../../' }
: {},
},
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
// Postcss rtlcss plugin.
// require( 'postcss-rtl' )({
// // options here.
// removeComments: false,
// }),
postcssRTLCSS({
}),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
postcssNormalize(),
],
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
].filter(Boolean);
if (preProcessor) {
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
{
loader: require.resolve(preProcessor),
options: {
sourceMap: true,
sassOptions: {
sourceComments: true,
outputStyle: 'expanded'
}
},
}
);
}
return loaders;
};
return {
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
// Stop compilation early in production
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry: [
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
// of CSS changes), or refresh the page (in case of JS changes). When you
// make a syntax error, this client will display a syntax error overlay.
// Note: instead of the default WebpackDevServer client, we use a custom one
// to bring better experience for Create React App users. You can replace
// the line below with these two lines if you prefer the stock client:
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
isEnvDevelopment &&
require.resolve('react-dev-utils/webpackHotDevClient'),
// Finally, this is your app's code:
paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
].filter(Boolean),
output: {
// The build folder.
path: isEnvProduction ? paths.appBuild : undefined,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
// Prevents conflicts when multiple webpack runtimes (from different apps)
// are used on the same page.
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
// this defaults to 'window', but by setting it to 'this' then
// module chunks which are built will work in web workers as well.
globalObject: 'this',
},
optimization: {
minimize: isEnvProduction,
minimizer: [
// This is only used in production mode
new TerserPlugin({
terserOptions: {
parse: {
// We want terser to parse ecma 8 code. However, we don't want it
// to apply any minification steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending further investigation:
// https://github.com/terser-js/terser/issues/120
inline: 2,
},
mangle: {
safari10: true,
},
// Added for profiling in devtools
keep_classnames: isEnvProductionProfile,
keep_fnames: isEnvProductionProfile,
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
sourceMap: shouldUseSourceMap,
}),
// This is only used in production mode
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
parser: safePostCssParser,
map: shouldUseSourceMap
? {
// `inline: false` forces the sourcemap to be output into a
// separate file
inline: false,
// `annotation: true` appends the sourceMappingURL to the end of
// the css file, helping the browser find the sourcemap
annotation: true,
}
: false,
},
cssProcessorPluginOptions: {
preset: ['default', { minifyFontValues: { removeQuotes: false } }],
},
}),
],
// Automatically split vendor and commons
// https://twitter.com/wSokra/status/969633336732905474
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
splitChunks: {
chunks: 'all',
name: false,
},
// Keep the runtime chunk separated to enable long term caching
// https://twitter.com/wSokra/status/969679223278505985
// https://github.com/facebook/create-react-app/issues/5358
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`,
},
},
resolve: {
// This allows you to set a fallback for where webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
modules.additionalModulePaths || []
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebook/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
plugins: [
// Adds support for installing with Plug'n'Play, leading to faster installs and adding
// guards against forgotten dependencies and such.
PnpWebpackPlugin,
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
resolveLoader: {
plugins: [
// Also related to Plug'n'Play, but this time it tells webpack to load its loaders
// from the current package.
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
// First, run the linter.
// It's important to do this before Babel processes the JS.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
enforce: 'pre',
use: [
{
options: {
cache: true,
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
resolvePluginsRelativeTo: __dirname,
},
loader: require.resolve('eslint-loader'),
},
],
include: paths.appSrc,
},
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent:
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
},
},
],
],
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
compact: isEnvProduction,
},
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
// Babel sourcemaps are needed for debugging into node_modules
// code. Without the options below, debuggers like VSCode
// show incorrect code and set breakpoints on the wrong lines.
sourceMaps: shouldUseSourceMap,
inputSourceMap: shouldUseSourceMap,
},
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use MiniCSSExtractPlugin to extract that CSS
// to a file, but in development "style" loader enables hot editing
// of CSS.
// By default we support CSS Modules with the extension .module.css
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
}),
},
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
],
},
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
)
),
// Inlines the webpack runtime script. This script is too small to warrant
// a network request.
// https://github.com/facebook/create-react-app/issues/5358
isEnvProduction &&
shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// It will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// This gives some necessary context to module not found errors, such as
// the requesting resource.
new ModuleNotFoundPlugin(paths.appPath),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV is set to production
// during a production build.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
// This is necessary to emit hot updates (currently CSS only):
isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240
isEnvDevelopment && new CaseSensitivePathsPlugin(),
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebook/create-react-app/issues/186
isEnvDevelopment &&
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
isEnvProduction &&
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding
// output file so that tools can pick it up without having to parse
// `index.html`
// - "entrypoints" key: Array of files which are included in `index.html`,
// can be used to reconstruct the HTML if necessary
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
const entrypointFiles = entrypoints.main.filter(
fileName => !fileName.endsWith('.map')
);
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the webpack build.
isEnvProduction &&
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/],
importWorkboxFrom: 'cdn',
navigateFallback: paths.publicUrlOrPath + 'index.html',
navigateFallbackBlacklist: [
// Exclude URLs starting with /_, as they're likely an API call
new RegExp('^/_'),
// Exclude any URLs whose last part seems to be a file extension
// as they're likely a resource and not a SPA route.
// URLs containing a "?" character won't be blacklisted as they're likely
// a route with query params (e.g. auth callbacks).
new RegExp('/[^/?]+\\.[^/]+$'),
],
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync('typescript', {
basedir: paths.appNodeModules,
}),
async: isEnvDevelopment,
useTypescriptIncrementalApi: true,
checkSyntacticErrors: true,
resolveModuleNameModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
resolveTypeReferenceDirectiveModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
tsconfig: paths.appTsConfig,
reportFiles: [
'**',
'!**/__tests__/**',
'!**/?(*.)(spec|test).*',
'!**/src/setupProxy.*',
'!**/src/setupTests.*',
],
silent: true,
// The formatter is invoked directly in WebpackDevServerUtils during development
formatter: isEnvProduction ? typescriptFormatter : undefined,
}),
// Gzip compression.
isEnvProduction &&
new CompressionPlugin({
// asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
].filter(Boolean),
// Some libraries import Node modules but don't use them in the browser.
// Tell webpack to provide empty mocks for them so importing them works.
node: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
http2: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
// Turn off performance processing because we utilize
// our own hints via the FileSizeReporter
performance: false,
};
};

View File

@@ -1,130 +0,0 @@
'use strict';
const fs = require('fs');
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
const paths = require('./paths');
const getHttpsConfig = require('./getHttpsConfig');
const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node'
const sockPort = process.env.WDS_SOCKET_PORT;
module.exports = function(proxy, allowedHost) {
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebook/create-react-app/issues/2271
// https://github.com/facebook/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files wont automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
contentBasePublicPath: paths.publicUrlOrPath,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// Use 'ws' instead of 'sockjs-node' on server since we're using native
// websockets in `webpackHotDevClient`.
transportMode: 'ws',
// Prevent a WS client from getting injected as we're already including
// `webpackHotDevClient`.
injectClient: false,
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
sockHost,
sockPath,
sockPort,
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
},
https: getHttpsConfig(),
host,
overlay: false,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
index: paths.publicUrlOrPath,
},
public: allowedHost,
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
before(app, server) {
// Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
},
after(app) {
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
app.use(redirectServedPath(paths.publicUrlOrPath));
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
},
};
};

137
docker-compose.prod.yml Normal file
View File

@@ -0,0 +1,137 @@
# This is a production version of the Bigcapital docker-compose.yml file.
version: '3.3'
services:
nginx:
container_name: bigcapital-nginx-gateway
build:
context: ./docker/nginx
args:
- SERVER_PROXY_PORT=3000
- WEB_SSL=false
- SELF_SIGNED=false
volumes:
- ./data/logs/nginx/:/var/log/nginx
- ./docker/certbot/certs/:/var/certs
ports:
- "${PUBLIC_PROXY_PORT:-80}:80"
- "${PUBLIC_PROXY_SSL_PORT:-443}:443"
tty: true
depends_on:
- server
- webapp
webapp:
container_name: bigcapital-webapp
image: ghcr.io/bigcapitalhq/webapp:latest
server:
container_name: bigcapital-server
image: ghcr.io/bigcapitalhq/server:latest
links:
- mysql
- mongo
- redis
depends_on:
- mysql
- mongo
- redis
environment:
# Mail
- MAIL_HOST=${MAIL_HOST}
- MAIL_USERNAME=${MAIL_USERNAME}
- MAIL_PASSWORD=${MAIL_PASSWORD}
- MAIL_PORT=${MAIL_PORT}
- MAIL_SECURE=${MAIL_SECURE}
- MAIL_FROM_NAME=${MAIL_FROM_NAME}
- MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS}
# Database
- DB_HOST=mysql
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_CHARSET=${DB_CHARSET}
# System database
- SYSTEM_DB_NAME=${SYSTEM_DB_NAME}
# Tenants databases
- TENANT_DB_NAME_PERFIX=${TENANT_DB_NAME_PERFIX}
# Authentication
- JWT_SECRET=${JWT_SECRET}
# MongoDB
- MONGODB_DATABASE_URL=mongodb://mongo/bigcapital
# Application
- BASE_URL=${BASE_URL}
# Agendash
- AGENDASH_AUTH_USER=${AGENDASH_AUTH_USER}
- AGENDASH_AUTH_PASSWORD=${AGENDASH_AUTH_PASSWORD}
# Sign-up restrictions
- SIGNUP_DISABLED=${SIGNUP_DISABLED}
- SIGNUP_ALLOWED_DOMAINS=${SIGNUP_ALLOWED_DOMAINS}
- SIGNUP_ALLOWED_EMAILS=${SIGNUP_ALLOWED_EMAILS}
database_migration:
container_name: bigcapital-database-migration
build:
context: ./
dockerfile: docker/migration/Dockerfile
environment:
- DB_HOST=mysql
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_CHARSET=${DB_CHARSET}
- SYSTEM_DB_NAME=${SYSTEM_DB_NAME}
depends_on:
- mysql
mysql:
container_name: bigcapital-mysql
build:
context: ./docker/mariadb
environment:
- MYSQL_DATABASE=${SYSTEM_DB_NAME}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
volumes:
- mysql:/var/lib/mysql
expose:
- '3306'
mongo:
container_name: bigcapital-mongo
build: ./docker/mongo
expose:
- '27017'
volumes:
- mongo:/var/lib/mongodb
redis:
container_name: bigcapital-redis
build:
context: ./docker/redis
expose:
- "6379"
volumes:
- redis:/data
# Volumes
volumes:
mysql:
name: bigcapital_prod_mysql
driver: local
mongo:
name: bigcapital_prod_mongo
driver: local
redis:
name: bigcapital_prod_redis
driver: local

53
docker-compose.yml Normal file
View File

@@ -0,0 +1,53 @@
# WARNING!
# This is a development version of THE Bigcapital docker-compose.yml file.
# Avoid using this file in your production environment.
# We're exposing here sensitive ports and mounting code volumes for rapid development and debugging of the server stack.
version: '3.3'
services:
mariadb:
build:
context: ./docker/mariadb
environment:
- MYSQL_DATABASE=${SYSTEM_DB_NAME}
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
volumes:
- mysql:/var/lib/mysql
expose:
- '3306'
ports:
- '3306:3306'
mongo:
build: ./docker/mongo
expose:
- '27017'
volumes:
- mongo:/var/lib/mongodb
ports:
- '27017:27017'
redis:
build:
context: ./docker/redis
expose:
- "6379"
volumes:
- redis:/data
# Volumes
volumes:
mysql:
name: bigcapital_dev_mysql
driver: local
mongo:
name: bigcapital_dev_mongo
driver: local
redis:
name: bigcapital_dev_redis
driver: local

26
docker/mariadb/Dockerfile Normal file
View File

@@ -0,0 +1,26 @@
FROM mariadb:10.2
USER root
ADD my.cnf /etc/mysql/conf.d/my.cnf
ARG MYSQL_DATABASE=default_database
ARG MYSQL_USER=default_user
ARG MYSQL_PASSWORD=secret
ARG MYSQL_ROOT_PASSWORD=root
ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
# Copy init sql file with env vars and then the script will substitute the variables.
COPY ./init.sql /scripts/init.template.sql
COPY ./docker-entrypoint.sh /docker-entrypoint-initdb.d/docker-initialize.sh
# The scripts in the `docker-entrypoint-initdb.d/` directory are executed as
# the mysql user inside the MySQL Docker container.
RUN chown -R mysql:root /docker-entrypoint-initdb.d
RUN chown -R mysql:root /scripts
CMD ["mysqld"]
EXPOSE 3306

View File

@@ -0,0 +1,18 @@
#!/bin/bash
# chmod u+rwx /scripts/init.template.sql
cp /scripts/init.template.sql /scripts/init.sql
# Replace environment variables in SQL files with their values
if [ -n "$MYSQL_USER" ]; then
sed -i "s/{MYSQL_USER}/$MYSQL_USER/g" /scripts/init.sql
fi
if [ -n "$MYSQL_PASSWORD" ]; then
sed -i "s/{MYSQL_PASSWORD}/$MYSQL_PASSWORD/g" /scripts/init.sql
fi
if [ -n "$MYSQL_DATABASE" ]; then
sed -i "s/{MYSQL_DATABASE}/$MYSQL_DATABASE/g" /scripts/init.sql
fi
# Execute SQL file
mysql -u root -p$MYSQL_ROOT_PASSWORD < /scripts/init.sql

3
docker/mariadb/init.sql Normal file
View File

@@ -0,0 +1,3 @@
GRANT ALL PRIVILEGES ON *.* TO '{MYSQL_USER}'@'%' IDENTIFIED BY '{MYSQL_PASSWORD}' WITH GRANT OPTION;
FLUSH PRIVILEGES;

2
docker/mariadb/my.cnf Normal file
View File

@@ -0,0 +1,2 @@
[mysqld]
bind-address = 0.0.0.0

View File

@@ -0,0 +1,38 @@
FROM ghcr.io/bigcapitalhq/server:latest as build
ARG DB_HOST= \
DB_USER= \
DB_PASSWORD= \
DB_CHARSET= \
# System database.
SYSTEM_DB_NAME= \
SYSTEM_DB_PASSWORD= \
SYSTEM_DB_USER= \
SYSTEM_DB_HOST= \
SYSTEM_DB_CHARSET=
ENV DB_HOST=$DB_HOST \
DB_USER=$DB_USER \
DB_PASSWORD=$DB_PASSWORD \
DB_CHARSET=$DB_CHARSET \
# System database.
SYSTEM_DB_HOST=$SYSTEM_DB_HOST \
SYSTEM_DB_USER=$SYSTEM_DB_USER \
SYSTEM_DB_PASSWORD=$SYSTEM_DB_PASSWORD \
SYSTEM_DB_NAME=$SYSTEM_DB_NAME \
SYSTEM_DB_CHARSET=$SYSTEM_DB_CHARSET
USER root
RUN apk update && \
apk upgrade && \
apk add git
RUN apk add --no-cache bash
# Change working dir to the server package.
WORKDIR /app/packages/server
RUN git clone https://github.com/vishnubob/wait-for-it.git
# Once we listen the mysql port run the migration task.
CMD ["./wait-for-it/wait-for-it.sh", "mysql:3306", "--", "node", "./build/commands.js", "system:migrate:latest"]

1
docker/mongo/Dockerfile Normal file
View File

@@ -0,0 +1 @@
FROM mongo:5.0

21
docker/nginx/Dockerfile Normal file
View File

@@ -0,0 +1,21 @@
FROM nginx:1.11
RUN mkdir /etc/nginx/sites-available && rm /etc/nginx/conf.d/default.conf
ADD nginx.conf /etc/nginx/
COPY scripts /root/scripts/
COPY certs /etc/ssl/
COPY sites /etc/nginx/templates
ARG SERVER_PROXY_PORT=3000
ARG WEB_SSL=false
ARG SELF_SIGNED=false
ENV SERVER_PROXY_PORT=$SERVER_PROXY_PORT
ENV WEB_SSL=$WEB_SSL
ENV SELF_SIGNED=$SELF_SIGNED
RUN /bin/bash /root/scripts/build-nginx.sh
CMD nginx

33
docker/nginx/nginx.conf Normal file
View File

@@ -0,0 +1,33 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;
daemon off;
events {
worker_connections 2048;
use epoll;
}
http {
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
types_hash_max_size 2048;
client_max_body_size 20M;
open_file_cache max=100;
gzip on;
gzip_disable "msie6";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-available/*;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}

View File

@@ -0,0 +1,9 @@
#!/bin/bash
for conf in /etc/nginx/templates/*.conf; do
mv $conf "/etc/nginx/sites-available/"$(basename $conf) > /dev/null
done
for template in /etc/nginx/templates/*.template; do
envsubst < $template > "/etc/nginx/sites-available/"$(basename $template)".conf"
done

View File

@@ -0,0 +1,16 @@
server {
listen 80 default_server;
location /api {
proxy_pass http://server:${SERVER_PROXY_PORT};
}
location / {
proxy_pass http://webapp;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
log_not_found off;
}
}

5
docker/redis/Dockerfile Normal file
View File

@@ -0,0 +1,5 @@
FROM redis:4.0
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

48
docker/redis/redis.conf Normal file
View File

@@ -0,0 +1,48 @@
daemonize no
pidfile /var/run/redis.pid
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile ""
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

View File

@@ -0,0 +1,68 @@
import { test, expect, Page } from '@playwright/test';
let authPage: Page;
test.describe('authentication', () => {
test.beforeAll(async ({ browser }) => {
authPage = await browser.newPage();
});
test.describe('login', () => {
test.beforeAll(async () => {
await authPage.goto('/auth/login');
});
test('should show the login page.', async () => {
await expect(authPage.locator('body')).toContainText(
"Don't have an account? Sign up"
);
});
test('should email and password be required.', async () => {
await authPage.getByRole('button', { name: 'Log in' }).click();
await expect(authPage.locator('form')).toContainText(
'Email is a required field'
);
await expect(authPage.locator('form')).toContainText(
'Password is a required field'
);
});
test('should go to the register page when click on sign up link', async () => {
await authPage.getByRole('link', { name: 'Sign up' }).click();
await expect(authPage.url()).toContain('/auth/register');
});
});
test.describe('register', () => {
test.beforeAll(async () => {
await authPage.goto('/auth/register');
});
test('should first name, last name, email and password be required.', async () => {
await authPage.getByRole('button', { name: 'Register' }).click();
await expect(authPage.locator('form')).toContainText(
'First name is a required field'
);
await expect(authPage.locator('form')).toContainText(
'Last name is a required field'
);
await expect(authPage.locator('form')).toContainText(
'Email is a required field'
);
await expect(authPage.locator('form')).toContainText(
'Password is a required field'
);
});
});
test.describe('reset password', () => {
test.beforeAll(async () => {
await authPage.goto('/auth/send_reset_password');
});
test('should email be required.', async () => {
await authPage.getByRole('button', { name: 'Reset Password' }).click();
await expect(authPage.locator('form')).toContainText(
'Email is a required field'
);
});
});
});

6
lerna.json Normal file
View File

@@ -0,0 +1,6 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "0.0.0",
"npmClient": "npm"
}

21140
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,214 +1,36 @@
{
"name": "bigcapital-client",
"version": "1.2.0",
"name": "bigcapital-monorepo",
"private": true,
"dependencies": {
"@babel/core": "7.8.4",
"@blueprintjs/core": "^3.50.2",
"@blueprintjs/datetime": "^3.23.12",
"@blueprintjs/popover2": "^0.11.1",
"@blueprintjs/select": "^3.11.2",
"@blueprintjs/table": "^3.8.3",
"@blueprintjs/timezone": "^3.6.2",
"@casl/ability": "^5.4.3",
"@casl/react": "^2.3.0",
"@reduxjs/toolkit": "^1.2.5",
"@sentry/react": "^6.13.2",
"@sentry/tracing": "^6.13.2",
"@svgr/webpack": "4.3.3",
"@tanem/react-nprogress": "^3.0.24",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.4.0",
"@testing-library/user-event": "^7.2.1",
"@types/lodash": "^4.14.172",
"@typescript-eslint/eslint-plugin": "^2.10.0",
"@typescript-eslint/parser": "^2.10.0",
"accounting": "^0.4.1",
"axios": "^0.21.2",
"babel-eslint": "10.0.3",
"babel-jest": "^24.9.0",
"babel-loader": "8.0.6",
"babel-plugin-named-asset-import": "^0.3.6",
"babel-preset-react-app": "^9.1.1",
"basscss": "^8.0.2",
"camelcase": "^5.3.1",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"cross-env": "^7.0.2",
"css-loader": "3.4.2",
"deep-map-keys": "^2.0.1",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^6.6.0",
"eslint-config-react-app": "^5.2.0",
"eslint-loader": "3.0.3",
"eslint-plugin-flowtype": "4.6.0",
"eslint-plugin-import": "2.20.0",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-react": "7.18.0",
"eslint-plugin-react-hooks": "^1.6.1",
"file-loader": "4.3.0",
"flow-bin": "^0.123.0",
"formik": "^2.2.5",
"fs-extra": "^8.1.0",
"html-webpack-plugin": "4.0.0-beta.11",
"identity-obj-proxy": "3.0.0",
"jest": "24.9.0",
"jest-environment-jsdom-fourteen": "1.0.1",
"jest-resolve": "24.9.0",
"jest-watch-typeahead": "0.4.2",
"js-money": "^0.6.3",
"lodash": "^4.17.15",
"mini-css-extract-plugin": "0.9.0",
"moment": "^2.24.0",
"moment-timezone": "^0.5.33",
"node-sass": "^4.13.1",
"optimize-css-assets-webpack-plugin": "5.0.3",
"pnp-webpack-plugin": "1.6.0",
"postcss-flexbugs-fixes": "4.1.0",
"postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0",
"postcss-rtl": "^1.7.3",
"postcss-safe-parser": "4.0.1",
"ramda": "^0.27.1",
"react": "^16.12.0",
"react-app-polyfill": "^1.0.6",
"react-body-classname": "^1.3.1",
"react-content-loader": "^6.0.1",
"react-dev-utils": "^11.0.4",
"react-dom": "^16.12.0",
"react-dropzone": "^11.0.1",
"react-error-boundary": "^3.0.2",
"react-hotkeys-hook": "^3.0.3",
"react-intl-universal": "^2.4.7",
"react-loadable": "^5.5.0",
"react-query": "^3.6.0",
"react-redux": "^7.1.3",
"react-router-breadcrumbs-hoc": "^3.2.10",
"react-router-dom": "^5.2.0",
"react-scroll-sync": "^0.7.1",
"react-scrollbars-custom": "^4.0.21",
"react-sortablejs": "^2.0.11",
"react-split-pane": "^0.1.91",
"react-table": "^7.6.3",
"react-table-sticky": "^1.1.2",
"react-transition-group": "^4.4.1",
"react-use": "^13.26.1",
"react-use-context-menu": "^0.1.4",
"react-virtualized": "^9.22.3",
"redux": "^4.0.5",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0",
"resolve": "1.15.0",
"resolve-url-loader": "3.1.1",
"rtl-detect": "^1.0.3",
"sass-loader": "8.0.2",
"semver": "6.3.0",
"style-loader": "0.23.1",
"styled-components": "^5.3.1",
"terser-webpack-plugin": "2.3.4",
"ts-pnp": "1.1.5",
"url-loader": "2.3.0",
"webpack": "4.41.5",
"webpack-dev-server": "3.10.2",
"webpack-manifest-plugin": "2.2.0",
"workbox-webpack-plugin": "4.3.1",
"yup": "^0.28.1"
},
"scripts": {
"start": "PORT=8000 node scripts/start.js",
"start-win": "cross-env PORT=8000 node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js",
"flow": "flow"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
"bootstrap": "lerna exec npm install",
"dev": "lerna run dev",
"build": "lerna run build",
"dev:webapp": "lerna run dev --scope \"@bigcapital/webapp\"",
"build:webapp": "lerna run build --scope \"@bigcapital/webapp\"",
"dev:server": "lerna run dev --scope \"@bigcapital/server\"",
"build:server": "lerna run build --scope \"@bigcapital/server\"",
"serve:server": "lerna run serve --scope \"@bigcapital/server\"",
"test:e2e": "playwright test",
"prepare": "husky install"
},
"workspaces": [
"packages/*",
"shared/*"
],
"devDependencies": {
"@babel/preset-flow": "^7.9.0",
"@types/jest": "^26.0.15",
"@types/node": "^14.14.9",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-router-dom": "^5.1.8",
"@types/yup": "^0.29.13",
"@welldone-software/why-did-you-render": "^6.0.0-rc.1",
"compression-webpack-plugin": "^6.1.0",
"http-proxy-middleware": "^1.0.0",
"postcss-rtlcss": "^1.7.2",
"react-query-devtools": "^2.1.1",
"redux-devtools": "^3.5.0",
"typescript": "^4.1.2"
"@commitlint/config-conventional": "^17.4.2",
"@commitlint/config-lerna-scopes": "^17.4.2",
"husky": "^8.0.3",
"lerna": "^6.4.1",
"@commitlint/cli": "^17.4.2",
"@playwright/test": "^1.32.3"
},
"jest": {
"roots": [
"<rootDir>/src"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
],
"setupFiles": [
"react-app-polyfill/jsdom"
],
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
],
"modulePaths": [
"/Users/ahmed/Documents/Ratteb/client/src"
],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
},
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
],
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
]
"engines": {
"node": "14.x"
},
"babel": {
"presets": [
"react-app"
]
},
"proxy": "http://localhost:3000/"
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}

8
packages/server/.babelrc Normal file
View File

@@ -0,0 +1,8 @@
{
"presets": ["@babel/preset-env"],
"retainLines": true,
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-syntax-dynamic-import"
]
}

View File

@@ -0,0 +1,34 @@
module.exports = {
env: {
browser: true,
es6: true,
},
extends: ['airbnb-base', 'airbnb-typescript'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
project: 'tsconfig.json',
tsconfigRootDir: './',
},
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
plugins: ['import'],
rules: {
'import/no-unresolved': 'error',
'import/prefer-default-export': 'off',
},
settings: {
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
'import/resolver': {
typescript: {
alwaysTryTypes: true,
project: 'tsconfig.json',
},
},
},
};

7
packages/server/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
/node_modules/
/.env
/storage
package-lock.json
stdout.log
/dist
/build

101
packages/server/Dockerfile Normal file
View File

@@ -0,0 +1,101 @@
FROM node:14.20-alpine as build
USER root
ARG MAIL_HOST= \
MAIL_USERNAME= \
MAIL_PASSWORD= \
MAIL_PORT= \
MAIL_SECURE= \
MAIL_FROM_NAME= \
MAIL_FROM_ADDRESS= \
# Database
DB_HOST= \
DB_USER= \
DB_PASSWORD= \
DB_CHARSET= \
# System database.
SYSTEM_DB_NAME= \
SYSTEM_DB_PASSWORD= \
SYSTEM_DB_USER= \
SYSTEM_DB_HOST= \
SYSTEM_DB_CHARSET= \
# Tenant databases.
TENANT_DB_USER= \
TENANT_DB_PASSWORD= \
TENANT_DB_HOST= \
TENANT_DB_NAME_PERFIX= \
TENANT_DB_CHARSET= \
# MongoDB
MONGODB_DATABASE_URL= \
# Authentication
JWT_SECRET= \
# Application
BASE_URL= \
# Agendash
AGENDASH_AUTH_USER=agendash \
AGENDASH_AUTH_PASSWORD=123123 \
# Sign-up restriction
SIGNUP_DISABLED= \
SIGNUP_ALLOWED_DOMAINS= \
SIGNUP_ALLOWED_EMAILS=
ENV MAIL_HOST=$MAIL_HOST \
MAIL_USERNAME=$MAIL_USERNAME \
MAIL_PASSWORD=$MAIL_PASSWORD \
MAIL_PORT=$MAIL_PORT \
MAIL_SECURE=$MAIL_SECURE \
MAIL_FROM_NAME=$MAIL_FROM_NAME \
MAIL_FROM_ADDRESS=$MAIL_FROM_ADDRESS \
# Database
DB_HOST=$DB_HOST \
DB_USER=$DB_USER \
DB_PASSWORD=$DB_PASSWORD \
DB_CHARSET=$DB_CHARSET \
# System database.
SYSTEM_DB_HOST=$SYSTEM_DB_HOST \
SYSTEM_DB_USER=$SYSTEM_DB_USER \
SYSTEM_DB_PASSWORD=$SYSTEM_DB_PASSWORD \
SYSTEM_DB_NAME=$SYSTEM_DB_NAME \
SYSTEM_DB_CHARSET=$SYSTEM_DB_CHARSET \
# Tenant databases.
TENANT_DB_NAME_PERFIX=$TENANT_DB_NAME_PERFIX \
TENANT_DB_HOST=$TENANT_DB_HOST \
TENANT_DB_PASSWORD=$TENANT_DB_PASSWORD \
TENANT_DB_USER=$TENANT_DB_USER \
TENANT_DB_CHARSET=$TENANT_DB_CHARSET \
# Authentication
JWT_SECRET=$JWT_SECRET \
# Agendash
AGENDASH_AUTH_USER=$AGENDASH_AUTH_USER \
AGENDASH_AUTH_PASSWORD=$AGENDASH_AUTH_PASSWORD \
# MongoDB
MONGODB_DATABASE_URL=$MONGODB_DATABASE_URL \
# Application
BASE_URL=$BASE_URL \
# Sign-up restriction
SIGNUP_DISABLED=$SIGNUP_DISABLED \
SIGNUP_ALLOWED_DOMAINS=$SIGNUP_ALLOWED_DOMAINS \
SIGNUP_ALLOWED_EMAILS=$SIGNUP_ALLOWED_EMAILS
# Create app directory.
WORKDIR /app
RUN chown node:node /
# Copy application dependency manifests to the container image.
COPY ./package*.json ./
COPY ./packages/server/package*.json ./packages/server/
COPY ./lerna.json ./lerna.json
# Install app dependencies for production.
RUN npm install
RUN npm run bootstrap
COPY --chown=node:node ./packages/server ./packages/server
# # Creates a "dist" folder with the production build
RUN npm run build:server --skip-nx-cache
CMD [ "node", "./packages/server/build/index.js" ]

View File

@@ -0,0 +1 @@
# @bigcapital/server

View File

@@ -0,0 +1,17 @@
const { knexSnakeCaseMappers } = require('objection');
module.exports = {
client: 'mysql',
connection: {
host: '127.0.0.1',
user: 'root',
password: 'root',
database: 'bigcapital_tenant_hqde5zqkylsho06',
charset: 'utf8',
},
migrations: {
directory: './src/database/migrations',
},
pool: { min: 0, max: 7 },
...knexSnakeCaseMappers({ upperCase: true }),
};

View File

@@ -0,0 +1,147 @@
{
"name": "@bigcapital/server",
"version": "1.7.1",
"description": "",
"main": "src/server.ts",
"scripts": {
"inspect": "cross-env NODE_PATH=./src nodemon src/server.ts",
"clear": "rimraf build",
"dev": "cross-env NODE_ENV=development webpack --config scripts/webpack.config.js",
"build:resources": "gulp --gulpfile=scripts/gulpfile.js styles styles-rtl",
"build:app": "cross-env NODE_ENV=production webpack --config scripts/webpack.config.js",
"build:commands": "cross-env NODE_ENV=production webpack --config scripts/webpack.cli.js",
"build": "npm-run-all build:*",
"serve": "node ./build/index.js",
"lint:fix": "eslint --fix ./**/*.ts"
},
"author": "Ahmed Bouhuolia, <a.bouhuolia@gmail.com>",
"license": "ISC",
"bin": {
"bigcapital": "./bin/bigcapital.js"
},
"dependencies": {
"@casl/ability": "^5.4.3",
"@hapi/boom": "^7.4.3",
"@types/i18n": "^0.8.7",
"@types/knex": "^0.16.1",
"@types/mathjs": "^6.0.12",
"accepts": "^1.3.7",
"accounting": "^0.4.1",
"agenda": "^4.2.1",
"agendash": "^3.1.0",
"app-root-path": "^3.0.0",
"async": "^3.2.0",
"axios": "^0.20.0",
"babel-loader": "^9.1.2",
"bcryptjs": "^2.4.3",
"bluebird": "^3.7.2",
"compression": "^1.7.4",
"country-codes-list": "^1.6.8",
"cpy": "^8.1.2",
"cpy-cli": "^3.1.1",
"crypto-random-string": "^3.2.0",
"csurf": "^1.10.0",
"deep-map": "^2.0.0",
"deepdash": "^5.3.7",
"dotenv": "^8.1.0",
"errorhandler": "^1.5.1",
"es6-weak-map": "^2.0.3",
"esm": "^3.2.25",
"event-dispatch": "^0.4.1",
"eventemitter2": "^6.4.5",
"express": "^4.17.1",
"express-basic-auth": "^1.2.0",
"express-boom": "^3.0.0",
"express-fileupload": "^1.1.7-alpha.3",
"express-oauth-server": "^2.0.0",
"express-validator": "^6.12.2",
"gulp": "^4.0.2",
"gulp-sass": "^5.0.0",
"helmet": "^3.21.0",
"i18n": "^0.13.3",
"is-my-json-valid": "^2.20.5",
"js-money": "^0.6.3",
"jsonwebtoken": "^8.5.1",
"knex": "^0.95.15",
"knex-cleaner": "^1.3.0",
"knex-db-manager": "^0.6.1",
"libphonenumber-js": "^1.9.6",
"lodash": "^4.17.15",
"lru-cache": "^6.0.0",
"mathjs": "^9.4.0",
"memory-cache": "^0.2.0",
"moment": "^2.24.0",
"moment-range": "^4.0.2",
"mongoose": "^5.10.0",
"mustache": "^3.0.3",
"mysql": "^2.17.1",
"mysql2": "^1.6.5",
"node-cache": "^4.2.1",
"nodemailer": "^6.3.0",
"nodemon": "^1.19.1",
"object-hash": "^2.0.3",
"objection": "^3.0.0",
"objection-filter": "^4.0.1",
"objection-soft-delete": "^1.0.7",
"objection-unique": "^1.2.2",
"pluralize": "^8.0.0",
"pug": "^3.0.2",
"puppeteer": "^10.2.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",
"ts-transformer-keys": "^0.4.2",
"tsyringe": "^4.3.0",
"typedi": "^0.8.0",
"uniqid": "^5.2.0",
"winston": "^3.2.1"
},
"devDependencies": {
"@types/lodash": "^4.14.158",
"@types/ramda": "^0.27.64",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"chai-things": "^0.2.0",
"colorette": "^1.2.0",
"commander": "^5.0.0",
"cross-env": "^5.2.0",
"eslint": "^8.33.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-import-resolver-typescript": "^3.5.3",
"eslint-import-resolver-webpack": "^0.11.1",
"eslint-loader": "^2.2.1",
"eslint-plugin-import": "^2.27.5",
"faker": "^4.1.0",
"getopts": "^2.2.5",
"gulp-postcss": "^9.0.0",
"gulp-rename": "^2.0.0",
"knex-factory": "0.0.6",
"merge-stream": "^2.0.0",
"mocha": "^5.2.0",
"npm-run-all": "^4.1.5",
"nyc": "^14.1.1",
"progress-bar-webpack-plugin": "^2.1.0",
"regenerator-runtime": "^0.13.7",
"rimraf": "^3.0.2",
"rtlcss": "^3.3.0",
"run-script-webpack-plugin": "^0.1.1",
"sass": "^1.37.5",
"sinon": "^7.4.2",
"start-server-webpack-plugin": "^2.2.5",
"ts-loader": "^9.4.2",
"ts-node": "^9.0.0",
"tsconfig-paths-webpack-plugin": "^4.0.0",
"typescript": "^3.9.7",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-merge": "^5.8.0",
"webpack-node-externals": "^3.0.0",
"webpack-watch-changed": "^1.0.0"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,640 @@
{
"Petty Cash": "العهدة",
"Cash": "النقدية",
"Bank": "المصرف",
"Other Income": "إيرادات اخري",
"Interest Income": "إيرادات الفوائد",
"Depreciation Expense": "مصاريف الاهلاك",
"Interest Expense": "مصروفات الفوائد",
"Sales of Product Income": "مبيعات دخل المنتجات",
"Inventory Asset": "المخزون",
"Cost of Goods Sold (COGS)": "تكلفة البضائع المباعة (COGS)",
"Cost of Goods Sold": "تكلفة البضاعة المباعة",
"Accounts Payable": "الذمم الدائنة",
"Other Expense": "مصاريف أخرى",
"Payroll Expenses": "مصاريف المرتبات",
"Fixed Asset": "أصول ثابتة",
"Credit Card": "بطاقة إئتمان",
"Non-Current Asset": "أصول غير متداولة",
"Current Asset": "أصول متداولة",
"Other Asset": "أصول اخري",
"Long Term Liability": "التزامات طويلة الاجل",
"Current Liability": "التزامات قصيرة الاجل",
"Other Liability": "التزمات اخري",
"Equity": "حقوق الملكية",
"Expense": "مصروف",
"Income": "إيراد",
"Accounts Receivable (A/R)": "الذمم المدينة",
"Accounts Receivable": "الذمم المدينة",
"Accounts Payable (A/P)": "الذمم الدائنة",
"Inactive": "غير نشط",
"Other Current Asset": "أصول متداولة اخرى",
"Tax Payable": "الضريبة المستحقة",
"Other Current Liability": "التزامات قصيرة الأجر اخرى",
"Non-Current Liability": "التزامات طويلة الأجر",
"Assets": "أصول",
"Liabilities": "الالتزمات",
"Account name": "أسم الحساب",
"Account type": "نوع الحساب",
"Account normal": "حساب عادي",
"Description": "وصف",
"Account code": "رمز الحساب",
"Currency": "عملة",
"Balance": "توازن",
"Active": "نشيط",
"Created at": "أنشئت في",
"fixed_asset": "أصل ثابت",
"Journal": "قيد",
"Reconciliation": "تسوية",
"Credit": "دائن",
"Debit": "مدين",
"Interest": "فائدة",
"Depreciation": "اهلاك",
"Payroll": "كشف رواتب",
"Type": "نوع",
"Name": "الأسم",
"Sellable": "قابل للبيع",
"Purchasable": "قابل للشراء",
"Sell price": "سعر البيع",
"Cost price": "سعر الكلفة",
"User": "المستخدم",
"Category": "تصنيف",
"Note": "ملحوظة",
"Quantity on hand": "كمية في اليد",
"Purchase description": "وصف الشراء",
"Sell description": "وصف البيع",
"Sell account": "حساب البيع",
"Cost account": "حساب التكلفة",
"Inventory account": "حساب المخزون",
"Payment date": "تاريخ الدفع",
"Payment account": "حساب الدفع",
"Amount": "كمية",
"Reference No.": "رقم المرجع.",
"Published": "نشرت",
"Journal number": "رقم القيد",
"Status": "حالة",
"Journal type": "نوع القيد",
"Date": "تاريخ",
"Asset": "أصل",
"Liability": "التزام",
"First-in first-out (FIFO)": "الوارد أولاً يصرف أولاً (FIFO)",
"Last-in first-out (LIFO)": "الوارد أخيرًا يصرف أولاً (LIFO)",
"Average rate": "المعدل المتوسط",
"Total": "الإجمالي",
"Transaction type": "نوع المعاملة",
"Transaction #": "عملية #",
"Running Value": "القيمة الجارية",
"Running quantity": "الكمية الجارية",
"Profit Margin": "هامش الربح",
"Value": "القيمة",
"Rate": "السعر",
"OPERATING ACTIVITIES": "الأنشطة التشغيلية",
"FINANCIAL ACTIVITIES": "الأنشطة التمويلية",
"INVESTMENT ACTIVITIES": "الانشطة الاستثمارية",
"Net income": "صافي الدخل",
"Adjustments net income by operating activities.": "تسويات صافي الدخل من الأنشطة التشغيلية.",
"Net cash provided by operating activities": "صافي التدفقات النقدية من أنشطة التشغيل",
"Net cash provided by investing activities": "صافي التدفقات النقدية من أنشطة الاستثمار",
"Net cash provided by financing activities": "صافي التدفقات النقدية من أنشطة التمويلية",
"Cash at beginning of period": "التدفقات النقدية في بداية الفترة",
"NET CASH INCREASE FOR PERIOD": "زيادة التدفقات النقدية للفترة",
"CASH AT END OF PERIOD": "صافي التدفقات النقدية في نهاية الفترة",
"Expenses": "مصاريف",
"Services": "خدمات",
"Inventory": "المخزون",
"Non Inventory": "غير المخزون",
"Draft": "مسودة",
"Delivered": "تم التوصيل",
"Overdue": "متأخر",
"Partially paid": "المدفوعة جزئيا",
"Paid": "مدفوع",
"Opened": "افتتح",
"Unpaid": "غير مدفوعة",
"Approved": "وافق",
"Rejected": "مرفوض",
"Invoiced": "مفوترة",
"Expired": "منتهي الصلاحية",
"Closed": "مغلق",
"Manual journal": "قيد اليدوي",
"Owner contribution": "زيادة رأس المال",
"Transfer to account": "تحويل إلى الحساب",
"Transfer from account": "تحويل من الحساب",
"Other income": "إيراد اخر",
"Other expense": "مصاريف أخرى",
"Owner drawing": "سحب رأس المال",
"Inventory adjustment": "تسوية المخزون",
"Customer opening balance": "الرصيد الافتتاحي للزبون",
"Vendor opening balance": "رصيد افتتاحي للمورد",
"Payment made": "سند الزبون",
"Bill": "فاتورة الشراء",
"Payment receive": "استلام الدفع",
"Sale receipt": "إيصال البيع",
"Sale invoice": "فاتورة البيع",
"Quantity": "الكمية",
"Bank Account": "حساب البنك",
"Saving Bank Account": "حساب التوفير البنكي",
"Undeposited Funds": "الأموال غير المودعة",
"Computer Equipment": "معدات كمبيوتر",
"Office Equipment": "معدات مكتبية",
"Uncategorized Income": "الدخل غير مصنف",
"Sales of Service Income": "دخل مبيعات الخدمات",
"Bank Fees and Charges": "رسوم المصرفية",
"Exchange Gain or Loss": "ربح أو خسارة فروقات الصرف",
"Rent": "إيجار",
"Office expenses": "مصاريف المكتب",
"Other Expenses": "مصاريف اخري",
"Drawings": "السحوبات",
"Owner's Equity": "حقوق الملكية",
"Opening Balance Equity": "الارصدة الافتتاحية ",
"Retained Earnings": "الأرباح المحتجزة",
"Sales Tax Payable": "ضريبة المبيعات المستحقة",
"Revenue Received in Advance": "الإيرادات المقبوضة مقدما",
"Opening Balance Liabilities": "رصيد الالتزامات الافتتاحي",
"Loan": "اقراض",
"Owner A Drawings": "مسحوبات المالك",
"An account that holds valuation of products or goods that availiable for sale.": "حساب يحمل قيم مخزون البضاعة أو السلع المتاحة للبيع.",
"Tracks the gain and losses of the exchange differences.": "يسجل مكاسب وخسائر فروق الصرف.",
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "يتم تسجيل أي رسوم مصرفية يتم فرضها في حساب الرسوم والمصروفات البنكية. ومن الأمثلة على ذلك رسوم صيانة الحساب المصرفي ورسوم المعاملات ورسوم الدفع المتأخر.",
"The income activities are not associated to the core business.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",
"Cash and cash equivalents": "النقد والنقد المكافئ",
"Inventories": "مخزون البضاعة",
"Other current assets": "الأصول متداولة الأخرى",
"Non-Current Assets": "أصول غير المتداولة",
"Current Liabilties": "التزامات متداولة",
"Long-Term Liabilities": "التزامات طويلة الاجل",
"Non-Current Liabilities": "التزامات غير متداولة",
"Liabilities and Equity": "التزامات وحقوق الملكية",
"Closing balance": "الرصيد الختامي",
"Opening balance": "الرصيد الفتاحي",
"Total {{accountName}}": "إجمالي {{accountName}}",
"invoice.paper.invoice": "فاتورة",
"invoice.paper.due_amount": "القيمة المستحقة",
"invoice.paper.billed_to": "فاتورة إلي",
"invoice.paper.invoice_date": "تاريخ الفاتورة",
"invoice.paper.invoice_number": "رقم الفاتورة",
"invoice.paper.due_date": "تاريخ الاستحقاق",
"invoice.paper.conditions_title": "الشروط والأحكام",
"invoice.paper.notes_title": "ملاحظات",
"invoice.paper.total": "المجموع",
"invoice.paper.balance_due": "مبلغ المستحق",
"invoice.paper.payment_amount": "مبلغ المدفوع",
"invoice.paper.invoice_amount": "قيمة الفاتورة",
"item_entry.paper.item_name": "اسم الصنف",
"item_entry.paper.rate": "السعر",
"item_entry.paper.quantity": "الكمية",
"item_entry.paper.total": "إجمالي",
"estimate.paper.estimate": "عرض أسعار",
"estimate.paper.billed_to": "عرض أسعار إلي",
"estimate.paper.estimate_date": "تاريخ العرض",
"estimate.paper.estimate_number": "رقم العرض",
"estimate.paper.expiration_date": "تاريخ انتهاء الصلاحية",
"estimate.paper.conditions_title": "الشروط والأحكام",
"estimate.paper.notes_title": "ملاحظات",
"estimate.paper.amount": "قيمة العرض",
"estimate.paper.subtotal": "المجموع",
"estimate.paper.total": "إجمالي",
"estimate.paper.estimate_amount": "قيمة العرض",
"receipt.paper.receipt": "إيصال",
"receipt.paper.billed_to": "الإيصال إلي",
"receipt.paper.receipt_date": "تاريخ الإيصال",
"receipt.paper.receipt_number": "رقم الإيصال",
"receipt.paper.conditions_title": "الشروط والأحكام",
"receipt.paper.notes_title": "ملاحظات",
"receipt.paper.receipt_amount": "قيمة الإيصال",
"receipt.paper.total": "إجمالي",
"receipt.paper.payment_amount": "مبلغ المدفوع",
"receipt.paper.balance_due": "مبلغ المستحق",
"receipt.paper.statement": "البيان",
"receipt.paper.notes": "ملاحظات",
"payment.paper.payment_receipt": "إيصال قبض",
"payment.paper.amount_received": "القيمة المستلمه",
"payment.paper.billed_to": "إيصال إلي",
"payment.paper.payment_date": "تاريخ الدفع",
"payment.paper.invoice_number": "رقم الفاتورة",
"payment.paper.invoice_date": "تاريخ الفاتورة",
"payment.paper.invoice_amount": "قيمة الفاتورة",
"payment.paper.payment_amount": "قيمة الدفع",
"payment.paper.balance_due": "المبلغ المستحق",
"payment.paper.statement": "البيان",
"credit.paper.credit_note": "اشعار دائن",
"credit.paper.amount": "قيمة الاشعار",
"credit.paper.remaining": "رصيد المتبقي",
"credit.paper.billed_to": "إيصال إلي",
"credit.paper.credit_date": "تاريخ الاشعار",
"credit.paper.terms_conditions": "الشروط والاحكام",
"credit.paper.notes": "ملاحظات",
"credit.paper.total": "إجمالي",
"credit.paper.credits_used": "قيمة المستخدمه",
"credit.paper.credits_remaining": "قيمة المتبقية",
"account.field.name": "إسم الحساب",
"account.field.description": "الوصف",
"account.field.slug": "Account slug",
"account.field.code": "رقم الحساب",
"account.field.root_type": "جذر الحساب",
"account.field.normal": "طبيعة الحساب",
"account.field.normal.credit": "دائن",
"account.field.normal.debit": "مدين",
"account.field.type": "نوع الحساب",
"account.field.active": "Activity",
"account.field.balance": "الرصيد",
"account.field.created_at": "أنشئت في",
"item.field.type": "نوع الصنف",
"item.field.type.inventory": "مخزون",
"item.field.type.service": "خدمة",
"item.field.type.non-inventory": "غير مخزون",
"item.field.name": "اسم الصنف",
"item.field.code": "رمز الصنف",
"item.field.sellable": "قابل للبيع",
"item.field.purchasable": "قابل للشراء",
"item.field.cost_price": "سعر التكلفة",
"item.field.cost_account": "حساب التكلفة",
"item.field.sell_account": "حساب البيع",
"item.field.sell_description": "وصف البيع",
"item.field.inventory_account": "حساب المخزون",
"item.field.purchase_description": "وصف الشراء",
"item.field.quantity_on_hand": "الكمية",
"item.field.note": "ملاحظة",
"item.field.category": "التصنيف",
"item.field.active": "Active",
"item.field.created_at": "أنشئت في",
"item_category.field.name": "الاسم",
"item_category.field.description": "الوصف",
"item_category.field.count": "العدد",
"item_category.field.created_at": "أنشئت في",
"invoice.field.customer": "الزبون",
"invoice.field.invoice_date": "تاريخ الفاتورة",
"invoice.field.due_date": "تاريخ الاستحقاق",
"invoice.field.invoice_no": "رقم الفاتورة",
"invoice.field.reference_no": "رقم الإشاري",
"invoice.field.invoice_message": "رسالة الفاتورة",
"invoice.field.terms_conditions": "الشروط والأحكام",
"invoice.field.amount": "القيمة",
"invoice.field.payment_amount": "القيمة المدفوعة",
"invoice.field.due_amount": "القيمة المستحقة",
"invoice.field.status": "الحالة",
"invoice.field.status.paid": "مدفوعة",
"invoice.field.status.partially-paid": "المدفوعة جزئيا",
"invoice.field.status.overdue": "متأخرة",
"invoice.field.status.unpaid": "غير مدفوعة",
"invoice.field.status.delivered": "تم تسليمها",
"invoice.field.status.draft": "مسودة",
"invoice.field.created_at": "أنشئت في",
"estimate.field.amount": "القيمة",
"estimate.field.estimate_number": "رقم العرض",
"estimate.field.customer": "الزبون",
"estimate.field.estimate_date": "تاريخ العرض",
"estimate.field.expiration_date": "تاريخ انتهاء الصلاحية",
"estimate.field.reference_no": "رقم الإشاري",
"estimate.field.note": "ملاحظة",
"estimate.field.terms_conditions": "الشروط والأحكام",
"estimate.field.status": "الحالة",
"estimate.field.status.delivered": "تم تسليمها",
"estimate.field.status.rejected": "مرفوضة",
"estimate.field.status.approved": "تم الموافقة",
"estimate.field.status.draft": "مسودة",
"estimate.field.created_at": "أنشئت في",
"payment_receive.field.customer": "الزبون",
"payment_receive.field.payment_date": "تاريخ الدفع",
"payment_receive.field.amount": "القيمة",
"payment_receive.field.reference_no": "رقم الإشاري",
"payment_receive.field.deposit_account": "حساب الإيداع",
"payment_receive.field.payment_receive_no": "رقم عملية الدفع",
"payment_receive.field.statement": "البيان",
"payment_receive.field.created_at": "أنشئت في",
"bill_payment.field.vendor": "المورد",
"bill_payment.field.amount": "القيمة",
"bill_payment.field.due_amount": "قيمة المستحقة",
"bill_payment.field.payment_account": "حساب الدفع",
"bill_payment.field.payment_number": "قيمة الدفع",
"bill_payment.field.payment_date": "تاريخ الدفع",
"bill_payment.field.reference_no": "رقم الإشاري",
"bill_payment.field.description": "الوصف",
"bill_payment.field.created_at": "أنشئت في",
"bill.field.vendor": "المورد",
"bill.field.bill_number": "رقم الفاتورة",
"bill.field.bill_date": "تاريخ الفاتورة",
"bill.field.due_date": "تاريخ الاستحقاق",
"bill.field.reference_no": "رقم الإشاري",
"bill.field.status": "الحالة",
"bill.field.status.paid": "مدفوعة",
"bill.field.status.partially-paid": "مدفوعة جزئيا",
"bill.field.status.unpaid": "غير مدفوعة",
"bill.field.status.opened": "مفتوحة",
"bill.field.status.draft": "مسودة",
"bill.field.status.overdue": "متأخرة",
"bill.field.amount": "القيمة",
"bill.field.payment_amount": "قيم الدفع",
"bill.field.note": "ملاحظة",
"bill.field.created_at": "أنشئت في",
"inventory_adjustment.field.date": "التاريخ",
"inventory_adjustment.field.type": "النوع",
"inventory_adjustment.field.type.increment": "زيادة",
"inventory_adjustment.field.type.decrement": "نقصان",
"inventory_adjustment.field.adjustment_account": "حساب التسوية",
"inventory_adjustment.field.reason": "السبب",
"inventory_adjustment.field.reference_no": "رقم الإشاري",
"inventory_adjustment.field.description": "الوصف",
"inventory_adjustment.field.published_at": "نشرت في",
"inventory_adjustment.field.created_at": "أنشئت في",
"expense.field.payment_date": "تاريخ الدفع",
"expense.field.payment_account": "حساب الدفع",
"expense.field.amount": "القيمة",
"expense.field.reference_no": "رقم الإشاري",
"expense.field.description": "الوصف",
"expense.field.published": "Published",
"expense.field.status": "الحالة",
"expense.field.status.draft": "مسودة",
"expense.field.status.published": "نشرت",
"expense.field.created_at": "أنشئت في",
"manual_journal.field.date": "التاريخ",
"manual_journal.field.journal_number": "رقم القيد",
"manual_journal.field.reference": "رقم الإشاري",
"manual_journal.field.journal_type": "نوع القيد",
"manual_journal.field.amount": "القيمة",
"manual_journal.field.description": "الوصف",
"manual_journal.field.status": "الحالة",
"manual_journal.field.created_at": "أنشئت في",
"receipt.field.amount": "القيمة",
"receipt.field.deposit_account": "حساب الإيداع",
"receipt.field.customer": "الزبون",
"receipt.field.receipt_date": "تاريخ الإيصال",
"receipt.field.receipt_number": "رقم الإيصال",
"receipt.field.reference_no": "رقم الإشاري",
"receipt.field.receipt_message": "رسالة الإيصال",
"receipt.field.statement": "البيان",
"receipt.field.created_at": "أنشئت في",
"receipt.field.status": "الحالة",
"receipt.field.status.draft": "مسودة",
"receipt.field.status.closed": "مغلقة",
"customer.field.first_name": "الاسم الأول",
"customer.field.last_name": "الاسم الاخير",
"customer.field.display_name": "اسم العرض",
"customer.field.email": "بريد الالكتروني",
"customer.field.work_phone": "هاتف عمل",
"customer.field.personal_phone": "هاتف شخصي",
"customer.field.company_name": "اسم الشركة",
"customer.field.website": "موقع الكتروني",
"customer.field.opening_balance_at": "الرصيد الافتتاحي في",
"customer.field.opening_balance": "الرصيد الافتتاحي",
"customer.field.created_at": "أنشئت في",
"customer.field.balance": "الرصيد",
"customer.field.status": "الحالة",
"customer.field.currency": "العملة",
"customer.field.status.active": "مفعل",
"customer.field.status.inactive": "غير مفعل",
"customer.field.status.overdue": "متأخر",
"customer.field.status.unpaid": "غير دافع",
"vendor.field.first_name": "الاسم الأول",
"vendor.field.last_name": "الاسم الاخير",
"vendor.field.display_name": "اسم العرض",
"vendor.field.email": "بريد الالكتروني",
"vendor.field.work_phone": "هاتف عمل",
"vendor.field.personal_phone": "هاتف شخصي",
"vendor.field.company_name": "اسم الشركة",
"vendor.field.website": "موقع الكتروني",
"vendor.field.opening_balance_at": "الرصيد الافتتاحي في",
"vendor.field.opening_balance": "الرصيد الافتتاحي",
"vendor.field.created_at": "أنشئت في",
"vendor.field.balance": "الرصيد",
"vendor.field.status": "الحالة",
"vendor.field.currency": "العملة",
"vendor.field.status.active": "مفعل",
"vendor.field.status.inactive": "غير مفعل",
"vendor.field.status.overdue": "متأخر",
"vendor.field.status.unpaid": "غير دافع",
"Invoice write-off": "شطب فاتورة",
"transaction_type.credit_note": "اشعار دائن",
"transaction_type.refund_credit_note": "استرجاع اموال اشعار دائن",
"transaction_type.vendor_credit": "اشعار مدين",
"transaction_type.refund_vendor_credit": "استرجاع اموال اشعار مدين",
"transaction_type.landed_cost": "تحميل تكلفة",
"sms_notification.invoice_details.label": "تفاصيل فاتورة البيع ",
"sms_notification.invoice_reminder.label": "تذكير بفاتورة البيع ",
"sms_notification.receipt_details.label": "تفاصيل إيصال البيع ",
"sms_notification.sale_estimate_details.label": "تفاصيل فاتورة عرض اسعار ",
"sms_notification.payment_receive_details.label": "تفاصيل سند الزبون",
"sms_notification.customer_balance.label": "رصيد الزبون",
"sms_notification.invoice_details.description": "سيتم إرسال إشعار عبر الرسائل القصيرة إلى العميل بمجرد إنشاء الفاتورة ونشرها أو عند إشعار العميل عبر رسالة نصية قصيرة بالفاتورة. ",
"sms_notification.payment_receive.description": "سيتم إرسال إشعار رسالة شكر للدفع إلى العميل بمجرد إنشاء الدفعة ونشرها أو إشعار العميل بالدفع يدويًا. ",
"sms_notification.receipt_details.description": "سيتم إرسال إشعار عبر الرسائل القصيرة إلى العميل بمجرد إنشاء ونشر الإيصال أو عند إشعار العميل بالإيصال يدويًا.",
"sms_notification.customer_balance.description": "إرسال رسالة نصية قصيرة إشعار العملاء برصيدهم الحالي المستحق. ",
"sms_notification.estimate_details.description": "سيتم إرسال إشعار عبر الرسائل القصيرة إلى عميلك بمجرد نشر العرض أو إشعار العميل بالعرض يدويًا.",
"sms_notification.invoice_reminder.description": "سيتم ارسال إشعار SMS لتذكير الزبون بالدفع باكراً ، سواء ارسال بشكل تلقائي او يدوي.",
"sms_notification.customer_balance.default_message": "عزيزي {CustomerName} ، هذا تذكير بشأن رصيد الحالي المستحق {Balance} ، يُرجى الدفع في أقرب وقت ممكن. - {CompanyName}",
"sms_notification.payment_receive.default_message": "مرحبًا {CustomerName} ، تم القبض بقيمة {Amount} للفاتورة - {InvoiceNumber}. نحن نتطلع إلى خدمتك مرة أخرى. شكرا لك. - {CompanyName}",
"sms_notification.estimate.default_message": "مرحبًا , {CustomerName} ، تم أنشاء فاتورة عرض اسعار - {EstimateNumber} لك. يرجى إلقاء نظرة وقبوله للمضي قدما. بانتظار ردك. - {CompanyName}",
"sms_notification.invoice_details.default_message": "مرحبًا {CustomerName}, لديك مبلغ مستحق قدره {DueAmount} للفاتورة {InvoiceNumber}. - {CompanyName}",
"sms_notification.receipt_details.default_message": "مرحبًا {CustomerName} ، لقد تم إنشاء إيصال - {ReceiptNumber} من أجلك. نتطلع إلى خدمتك مرة أخرى. شكرًا لك - {CompanyName}",
"sms_notification.invoice_reminder.default_message": "عزيزي {CustomerName} ، يرجي سداد فاتورة - {InvoiceNumber} المستحقة. يرجى الدفع قبل تاريخ {DueDate}. شكرا لك. - {CompanyName}",
"module.sale_invoices.label": "فواتير البيع",
"module.sale_receipts.label": "إيصالات البيع",
"module.sale_estimates.label": "فاتورة عرض اسعار ",
"module.payment_receives.label": "سندات الزبائن ",
"module.customers.label": "العملاء",
"sms_notification.invoice.var.invoice_number": "يشير إلى رقم الفاتورة.",
"sms_notification.invoice.var.reference_number": "يشير إلى رقم إشاري للفاتورة.",
"sms_notification.invoice.var.customer_name": "يشير إلى اسم العميل الفاتورة",
"sms_notification.invoice.var.due_amount": "يشير إلى مبلغ الفاتورة المستحق",
"sms_notification.invoice.var.amount": "يشير إلى مبلغ الفاتورة.",
"sms_notification.invoice.var.company_name": "يشير إلي اسم الشركة.",
"sms_notification.invoice.var.due_date": "يشير إلي تاريخ استحقاق الفاتورة.",
"sms_notification.receipt.var.receipt_number": "يشير إلى رقم الإيصال.",
"sms_notification.receipt.var.reference_number": "يشير إلى رقم الإشاري للإيصال.",
"sms_notification.receipt.var.customer_name": "يشير إلى اسم العميل الإيصال.",
"sms_notification.receipt.var.amount": "يشير إلى مبلغ الإيصال. ",
"sms_notification.receipt.var.company_name": "يشير إلي اسم الشركة.",
"sms_notification.payment.var.payment_number": "يشير إلى رقم معاملة الدفع.",
"sms_notification.payment.var.reference_number": "يشير إلى رقم الإشاري لعملية الدفع ",
"sms_notification.payment.var.customer_name": "يشير إلى اسم العميل الدفع",
"sms_notification.payment.var.amount": "يشير إلى مبلغ معاملة الدفع.",
"sms_notification.payment.company_name": "يشير إلي اسم الشركة.",
"sms_notification.payment.var.invoice_number": "يشير إلي رقم فاتورة التي تم دفعها.",
"sms_notification.estimate.var.estimate_number": "يشير إلى رقم فاتورة عرض اسعار.",
"sms_notification.estimate.var.reference_number": "يشير إلى رقم الإشاري لفاتورة عرض اسعار.",
"sms_notification.estimate.var.customer_name": "يشير إلى اسم العميل الفاتورة",
"sms_notification.estimate.var.amount": "يشير إلى قيمة الفاتورة",
"sms_notification.estimate.var.company_name": "يشير إلي اسم الشركة.",
"sms_notification.estimate.var.expiration_date": "يشير إلي تاريخ الصلاحية الفاتورة.",
"sms_notification.estimate.var.estimate_date": "يشير إلي تاريخ الفاتورة.",
"sms_notification.customer.var.customer_name": "يشير إلي اسم الزبون",
"sms_notification.customer.var.balance": "يشير إلي رصيد زبون المستحق.",
"sms_notification.customer.var.company_name": "يشير إلي اسم الشركة.",
"ability.accounts": "شجرة الحسابات",
"ability.manual_journal": "القيود اليدوية",
"ability.cashflow": "التدفقات النقدية",
"ability.inventory_adjustment": "تسويات المخزون",
"ability.customers": "الزبائن",
"ability.vendors": "الموردين",
"ability.sale_estimates": "فواتير عرض الاسعار",
"ability.sale_invoices": "فواتير البيع",
"ability.sale_receipts": "إيصالات البيع",
"ability.expenses": "المصاريف",
"ability.payments_receive": "سندات الزبائن",
"ability.purchase_invoices": "فواتير الشراء",
"ability.all_reports": "كل التقارير",
"ability.payments_made": "سندات الموردين",
"ability.preferences": "التفضيلات",
"ability.mutate_system_preferences": "تعديل تفضيلات النظام.",
"ability.items": "الأصناف",
"ability.view": "عرض",
"ability.create": "إضافة",
"ability.edit": "تعديل",
"ability.delete": "حذف",
"ability.transactions_locking": "إمكانية اغلاق المعاملات.",
"ability.balance_sheet_report": "ميزانية العمومية",
"ability.profit_loss_sheet": "قائمة الدخل",
"ability.journal": "اليومية العامة",
"ability.general_ledger": "دفتر الأستاذ العام",
"ability.cashflow_report": "تقرير التدفقات النقدية",
"ability.AR_aging_summary_report": "ملخص اعمار الديون للذمم المدينة",
"ability.AP_aging_summary_report": "ملخص اعمار الديون للذمم الدائنة",
"ability.purchases_by_items": "المشتريات حسب المنتجات",
"ability.sales_by_items_report": "المبيعات حسب المنتجات",
"ability.customers_transactions_report": "معاملات الزبائن",
"ability.vendors_transactions_report": "معاملات الموردين",
"ability.customers_summary_balance_report": "ملخص أرصدة الزبائن",
"ability.vendors_summary_balance_report": "ملخص أرصدة الموردين",
"ability.inventory_valuation_summary": "ملخص تقييم المخزون",
"ability.inventory_items_details": "تفاصيل منتج المخزون",
"vendor_credit.field.vendor": "المورد",
"vendor_credit.field.amount": "القيمة",
"vendor_credit.field.currency_code": "العملة",
"vendor_credit.field.credit_date": "تاريخ الاشعار",
"vendor_credit.field.credit_number": "رقم الاشعار",
"vendor_credit.field.note": "ملاحظة",
"vendor_credit.field.created_at": "أنشئت في",
"vendor_credit.field.reference_no": "رقم الإشاري",
"vendor_credit.field.status": "الحالة",
"vendor_credit.field.status.draft": "مسودة",
"vendor_credit.field.status.published": "تم نشرها",
"vendor_credit.field.status.open": "مفتوحة",
"vendor_credit.field.status.closed": "مغلقة",
"credit_note.field.terms_conditions": "الشروط والاحكام",
"credit_note.field.note": "ملاحظة",
"credit_note.field.currency_code": "العملة",
"credit_note.field.created_at": "أنشئت في",
"credit_note.field.amount": "القيمة",
"credit_note.field.credit_note_number": "رقم الاشعار",
"credit_note.field.credit_note_date": "تاريخ الاشعار",
"credit_note.field.customer": "الزبون",
"credit_note.field.reference_no": "رقم الإشاري",
"credit_note.field.status": "الحالة",
"credit_note.field.status.draft": "مسودة",
"credit_note.field.status.published": "تم نشرها",
"credit_note.field.status.open": "مفتوحة",
"credit_note.field.status.closed": "مغلقة",
"transactions_locking.module.sales.label": "المبيعات",
"transactions_locking.module.purchases.label": "المشتريات",
"transactions_locking.module.financial.label": "المالية",
"transactions_locking.module.all_transactions": "كل المعاملات",
"transactions_locking.module.sales.desc": "فواتير البيع ، والإيصالات ، والإشعارات الدائنة ، واستلام مدفوعات الزبائن ، والأرصدة الافتتاحية للزبائن.",
"transactions_locking.module.purchases.desc": "فواتير الشراء ومدفوعات الموردين وإشعارات المدينة والأرصدة الافتتاحية للموردين.",
"transactions_locking.module.financial.desc": "القيود اليدوية والمصروفات وتسويات المخزون.",
"inventory_adjustment.type.increment": "زيادة",
"inventory_adjustment.type.decrement": "نقصان",
"customer.type.individual": "فرد",
"customer.type.business": "اعمال",
"credit_note.view.draft": "مسودة",
"credit_note.view.closed": "مغلقة",
"credit_note.view.open": "مفتوحة",
"credit_note.view.published": "نشرت",
"vendor_credit.view.draft": "مسودة",
"vendor_credit.view.closed": "مغلقة",
"vendor_credit.view.open": "مفتوحة",
"vendor_credit.view.published": "نشرت",
"allocation_method.value.label": "القيمة",
"allocation_method.quantity.label": "الكمية",
"balance_sheet.assets": "الأصول",
"balance_sheet.current_asset": "الأصول المتداولة",
"balance_sheet.cash_and_cash_equivalents": "النقدية وما يعادلها",
"balance_sheet.accounts_receivable": "الذمم المدينة",
"balance_sheet.inventory": "المخزون",
"balance_sheet.other_current_assets": "اصول متداولة اخرى",
"balance_sheet.fixed_asset": "الأصول الثابتة",
"balance_sheet.non_current_assets": "الاصول غير المتداولة",
"balance_sheet.liabilities_and_equity": "الالتزامات وحقوق الملكية",
"balance_sheet.liabilities": "الإلتزامات",
"balance_sheet.current_liabilties": "الالتزامات المتداولة",
"balance_sheet.long_term_liabilities": "الالتزامات طويلة الاجل",
"balance_sheet.non_current_liabilities": "الالتزامات غير المتداولة",
"balance_sheet.equity": "حقوق الملكية",
"balance_sheet.account_name": "اسم الحساب",
"balance_sheet.total": "إجمالي",
"balance_sheet.percentage_of_column": "٪ التغير العمودي",
"balance_sheet.percentage_of_row": "٪ التغير الأفقي",
"financial_sheet.previoud_period_date": "(ف.س) {{date}}",
"fianncial_sheet.previous_period_change": "التغيرات (ف.س)",
"financial_sheet.previous_period_percentage": "٪ التغير (ف.س)",
"financial_sheet.previous_year_date": "(س.س) {{date}}",
"financial_sheet.previous_year_change": "التغيرات (س.س)",
"financial_sheet.previous_year_percentage": "٪ التغير (س.س)",
"financial_sheet.total_row": "إجمالي {{value}}",
"profit_loss_sheet.income": "الإيرادات",
"profit_loss_sheet.cost_of_sales": "تكلفة المبيعات",
"profit_loss_sheet.gross_profit": "إجمالي الدخل",
"profit_loss_sheet.expenses": "المصروفات",
"profit_loss_sheet.net_operating_income": "صافي الدخل التشغيلي",
"profit_loss_sheet.other_income": "إيرادات اخري",
"profit_loss_sheet.other_expenses": "مصاريف اخري",
"profit_loss_sheet.net_income": "صافي الدخل",
"profit_loss_sheet.account_name": "اسم الحساب",
"profit_loss_sheet.total": "إجمالي",
"profit_loss_sheet.percentage_of_income": "٪ التغير في الإيرادات",
"profit_loss_sheet.percentage_of_expenses": "٪ التغير في المصاريف",
"profit_loss_sheet.percentage_of_column": "٪ التغير العمودي",
"profit_loss_sheet.percentage_of_row": "٪ التغير الأفقي",
"warehouses.primary_warehouse": "المستودع الرئيسي",
"branches.head_branch": "الفرع الرئيسي",
"account.accounts_payable.currency": "الذمم الدائنة - {{currency}}",
"account.accounts_receivable.currency": "الذمم المدينة - {{currency}}",
"role.admin.name": "الادارة",
"role.admin.desc": "وصول غير مقيد لجميع الوحدات.",
"role.staff.name": "العاملين",
"role.staff.desc": "الوصول إلى جميع الوحدات باستثناء التقارير والإعدادات والمحاسبة.",
"warehouse_transfer.view.draft.name": "مسودة",
"warehouse_transfer.view.in_transit.name": "في النقل",
"warehouse_transfer.view.transferred.name": "تم النقل"
}

View File

@@ -0,0 +1,641 @@
{
"Petty Cash": "Petty Cash",
"Cash": "Cash",
"Bank": "Bank",
"Other Income": "Other Income",
"Interest Income": "Interest Income",
"Depreciation Expense": "Depreciation Expense",
"Interest Expense": "Interest Expense",
"Sales of Product Income": "Sales of Product Income",
"Inventory Asset": "Inventory Asset",
"Cost of Goods Sold (COGS)": "Cost of Goods Sold (COGS)",
"Cost of Goods Sold": "Cost of Goods Sold",
"Accounts Payable": "Accounts Payable",
"Other Expense": "Other Expense",
"Payroll Expenses": "Payroll Expenses",
"Fixed Asset": "Fixed Asset",
"Credit Card": "Credit Card",
"Non-Current Asset": "Non-Current Asset",
"Current Asset": "Current Asset",
"Other Asset": "Other Asset",
"Long Term Liability": "Long Term Liability",
"Current Liability": "Current Liability",
"Other Liability": "Other Liability",
"Equity": "Equity",
"Expense": "Expense",
"Income": "Income",
"Accounts Receivable (A/R)": "Accounts Receivable (A/R)",
"Accounts Receivable": "Accounts Receivable",
"Accounts Payable (A/P)": "Accounts Payable (A/P)",
"Inactive": "Inactive",
"Other Current Asset": "Other Current Asset",
"Tax Payable": "Tax Payable",
"Other Current Liability": "Other Current Liability",
"Non-Current Liability": "Non-Current Liability",
"Assets": "Assets",
"Liabilities": "Liabilities",
"Account name": "Account name",
"Account type": "Account type",
"Account normal": "Account normal",
"Description": "Description",
"Account code": "Account code",
"Currency": "Currency",
"Balance": "Balance",
"Active": "Active",
"Created at": "Created at",
"fixed_asset": "Fixed asset",
"Journal": "Journal",
"Reconciliation": "Reconciliation",
"Credit": "Credit",
"Debit": "Debit",
"Interest": "Interest",
"Depreciation": "Depreciation",
"Payroll": "Payroll",
"Type": "Type",
"Name": "Name",
"Sellable": "Sellable",
"Purchasable": "Purchasable",
"Sell price": "Sell price",
"Cost price": "Cost price",
"User": "User",
"Category": "Category",
"Note": "Note",
"Quantity on hand": "Quantity on hand",
"Quantity": "Quantity",
"Purchase description": "Purchase description",
"Sell description": "Sell description",
"Sell account": "Sell account",
"Cost account": "Cost account",
"Inventory account": "Inventory account",
"Payment date": "Payment date",
"Payment account": "Payment account",
"Amount": "Amount",
"Reference No.": "Reference No.",
"Journal number": "Journal number",
"Status": "Status",
"Journal type": "Journal type",
"Date": "Date",
"Asset": "Asset",
"Liability": "Liability",
"First-in first-out (FIFO)": "First-in first-out (FIFO)",
"Last-in first-out (LIFO)": "Last-in first-out (LIFO)",
"Average rate": "Average rate",
"Total": "Total",
"Transaction type": "Transaction type",
"Transaction #": "Transaction #",
"Running Value": "Running Value",
"Running quantity": "Running quantity",
"Profit Margin": "Profit Margin",
"Value": "Value",
"Rate": "Rate",
"OPERATING ACTIVITIES": "OPERATING ACTIVITIES",
"FINANCIAL ACTIVITIES": "FINANCIAL ACTIVITIES",
"Net income": "Net income",
"Adjustments net income by operating activities.": "Adjustments net income by operating activities.",
"Net cash provided by operating activities": "Net cash provided by operating activities",
"Net cash provided by investing activities": "Net cash provided by investing activities",
"Net cash provided by financing activities": "Net cash provided by financing activities",
"Cash at beginning of period": "Cash at beginning of period",
"NET CASH INCREASE FOR PERIOD": "NET CASH INCREASE FOR PERIOD",
"CASH AT END OF PERIOD": "CASH AT END OF PERIOD",
"Expenses": "Expenses",
"Services": "Services",
"Inventory": "Inventory",
"Non Inventory": "Non Inventory",
"Draft": "Draft",
"Published": "Published",
"Delivered": "Delivered",
"Overdue": "Overdue",
"Partially paid": "Partially paid",
"Paid": "Paid",
"Opened": "Opened",
"Unpaid": "Unpaid",
"Approved": "Approved",
"Rejected": "Rejected",
"Invoiced": "Invoiced",
"Expired": "Expired",
"Closed": "Closed",
"Manual journal": "Manual journal",
"Owner contribution": "Owner contribution",
"Transfer to account": "Transfer to account",
"Transfer from account": "Transfer from account",
"Other income": "Other income",
"Other expense": "Other expense",
"Owner drawing": "Owner drawing",
"Inventory adjustment": "Inventory adjustment",
"Customer opening balance": "Customer opening balance",
"Vendor opening balance": "Vendor opening balance",
"Payment made": "Payment made",
"Bill": "Bill",
"Payment receive": "Payment receive",
"Sale receipt": "Sale receipt",
"Sale invoice": "Sale invoice",
"Bank Account": "Bank Account",
"Saving Bank Account": "Saving Bank Account",
"Undeposited Funds": "Undeposited Funds",
"Computer Equipment": "Computer Equipment",
"Office Equipment": "Office Equipment",
"Uncategorized Income": "Uncategorized Income",
"Sales of Service Income": "Sales of Service Income",
"Bank Fees and Charges": "Bank Fees and Charges",
"Exchange Gain or Loss": "Exchange Gain or Loss",
"Rent": "Rent",
"Office expenses": "Office expenses",
"Other Expenses": "Other Expenses",
"Drawings": "Drawings",
"Owner's Equity": "Owner's Equity",
"Opening Balance Equity": "Opening Balance Equity",
"Retained Earnings": "Retained Earnings",
"Sales Tax Payable": "Sales Tax Payable",
"Revenue Received in Advance": "Revenue Received in Advance",
"Opening Balance Liabilities": "Opening Balance Liabilities",
"Loan": "Loan",
"Owner A Drawings": "Owner A Drawings",
"An account that holds valuation of products or goods that availiable for sale.": "An account that holds valuation of products or goods that availiable for sale.",
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.",
"The income activities are not associated to the core business.": "The income activities are not associated to the core business.",
"Cash and cash equivalents": "Cash and cash equivalents",
"Inventories": "Inventories",
"Other current assets": "Other current assets",
"Non-Current Assets": "Non-Current Assets",
"Current Liabilties": "Current Liabilties",
"Long-Term Liabilities": "Long-Term Liabilities",
"Non-Current Liabilities": "Non-Current Liabilities",
"Liabilities and Equity": "Liabilities and Equity",
"Closing balance": "Closing balance",
"Opening Balance": "Opening balance",
"Total {{accountName}}": "Total {{accountName}}",
"invoice.paper.invoice": "Invoice",
"invoice.paper.invoice_amount": "Invoice amount",
"invoice.paper.due_amount": "Due amount",
"invoice.paper.billed_to": "Billed to",
"invoice.paper.invoice_date": "Invoice date",
"invoice.paper.invoice_number": "Invoice No.",
"invoice.paper.due_date": "Due date",
"invoice.paper.conditions_title": "Conditions & terms",
"invoice.paper.notes_title": "Notes",
"invoice.paper.total": "Total",
"invoice.paper.payment_amount": "Payment Amount",
"invoice.paper.balance_due": "Balance Due",
"item_entry.paper.item_name": "Item name",
"item_entry.paper.rate": "Rate",
"item_entry.paper.quantity": "Quantity",
"item_entry.paper.total": "Total",
"estimate.paper.estimate": "Estimate",
"estimate.paper.estimate_amount": "Estimate amount",
"estimate.paper.billed_to": "Billed to",
"estimate.paper.estimate_date": "Estimate date",
"estimate.paper.estimate_number": "Estimate number",
"estimate.paper.expiration_date": "Expiration date",
"estimate.paper.conditions_title": "Conditions & terms",
"estimate.paper.notes_title": "Notes",
"estimate.paper.amount": "Estimate amount",
"estimate.paper.subtotal": "Subtotal",
"estimate.paper.total": "Total",
"receipt.paper.receipt": "Receipt",
"receipt.paper.billed_to": "Billed to",
"receipt.paper.receipt_date": "Receipt date",
"receipt.paper.receipt_number": "Receipt number",
"receipt.paper.expiration_date": "Expiration date",
"receipt.paper.conditions_title": "Conditions & terms",
"receipt.paper.notes": "Notes",
"receipt.paper.statement": "Statement",
"receipt.paper.receipt_amount": "Receipt amount",
"receipt.paper.total": "Total",
"receipt.paper.balance_due": "Balance Due",
"receipt.paper.payment_amount": "Payment Amount",
"credit.paper.credit_note": "Credit Note",
"credit.paper.remaining": "Credit remaining",
"credit.paper.amount": "Credit amount",
"credit.paper.billed_to": "Bill to",
"credit.paper.credit_date": "Credit date",
"credit.paper.total": "Total",
"credit.paper.credits_used": "Credits used",
"credit.paper.credits_remaining": "Credits remaining",
"credit.paper.conditions_title": "Conditions & terms",
"credit.paper.notes": "Notes",
"payment.paper.payment_receipt": "Payment Receipt",
"payment.paper.amount_received": "Amount received",
"payment.paper.billed_to": "Billed to",
"payment.paper.payment_date": "Payment date",
"payment.paper.invoice_number": "Invoice number",
"payment.paper.invoice_date": "Invoice date",
"payment.paper.invoice_amount": "Invoice amount",
"payment.paper.payment_amount": "Payment amount",
"payment.paper.balance_due": "Balance Due",
"payment.paper.statement": "Statement",
"account.field.name": "Account name",
"account.field.description": "Description",
"account.field.slug": "Account slug",
"account.field.code": "Account code",
"account.field.root_type": "Root type",
"account.field.normal": "Account normal",
"account.field.normal.credit": "Credit",
"account.field.normal.debit": "Debit",
"account.field.type": "Type",
"account.field.active": "Activity",
"account.field.balance": "Balance",
"account.field.created_at": "Created at",
"item.field.type": "Item type",
"item.field.type.inventory": "Inventory",
"item.field.type.service": "Service",
"item.field.type.non-inventory": "Non inventory",
"item.field.name": "Name",
"item.field.code": "Code",
"item.field.sellable": "Sellable",
"item.field.purchasable": "Purchasable",
"item.field.cost_price": "Cost price",
"item.field.cost_account": "Cost account",
"item.field.sell_account": "Sell account",
"item.field.sell_description": "Sell description",
"item.field.inventory_account": "Inventory account",
"item.field.purchase_description": "Purchase description",
"item.field.quantity_on_hand": "Quantity on hand",
"item.field.note": "Note",
"item.field.category": "Category",
"item.field.active": "Active",
"item.field.created_at": "Created at",
"item_category.field.name": "Name",
"item_category.field.description": "Description",
"item_category.field.count": "Count",
"item_category.field.created_at": "Created at",
"invoice.field.customer": "Customer",
"invoice.field.invoice_date": "Invoice date",
"invoice.field.due_date": "Due date",
"invoice.field.invoice_no": "Invoice No.",
"invoice.field.reference_no": "Reference No.",
"invoice.field.invoice_message": "Invoice message",
"invoice.field.terms_conditions": "Terms & conditions",
"invoice.field.amount": "Amount",
"invoice.field.payment_amount": "Payment amount",
"invoice.field.due_amount": "Due amount",
"invoice.field.status": "Status",
"invoice.field.status.paid": "Paid",
"invoice.field.status.partially-paid": "Partially paid",
"invoice.field.status.overdue": "Overdue",
"invoice.field.status.unpaid": "Unpaid",
"invoice.field.status.delivered": "Delivered",
"invoice.field.status.draft": "Draft",
"invoice.field.created_at": "Created at",
"estimate.field.amount": "Amount",
"estimate.field.estimate_number": "Estimate number",
"estimate.field.customer": "Customer",
"estimate.field.estimate_date": "Estimate date",
"estimate.field.expiration_date": "Expiration date",
"estimate.field.reference_no": "Reference No.",
"estimate.field.note": "Note",
"estimate.field.terms_conditions": "Terms & conditions",
"estimate.field.status": "Status",
"estimate.field.status.delivered": "Delivered",
"estimate.field.status.rejected": "Rejected",
"estimate.field.status.approved": "Approved",
"estimate.field.status.draft": "Draft",
"estimate.field.created_at": "Created at",
"payment_receive.field.customer": "Customer",
"payment_receive.field.payment_date": "Payment date",
"payment_receive.field.amount": "Amount",
"payment_receive.field.reference_no": "Reference No.",
"payment_receive.field.deposit_account": "Deposit account",
"payment_receive.field.payment_receive_no": "Payment receive No.",
"payment_receive.field.statement": "Statement",
"payment_receive.field.created_at": "Created at",
"bill_payment.field.vendor": "Vendor",
"bill_payment.field.amount": "Amount",
"bill_payment.field.due_amount": "Due amount",
"bill_payment.field.payment_account": "Payment account",
"bill_payment.field.payment_number": "Payment number",
"bill_payment.field.payment_date": "Payment date",
"bill_payment.field.reference_no": "Reference No.",
"bill_payment.field.description": "Description",
"bill_payment.field.created_at": "Created at",
"bill.field.vendor": "Vendor",
"bill.field.bill_number": "Bill number",
"bill.field.bill_date": "Bill date",
"bill.field.due_date": "Due date",
"bill.field.reference_no": "Reference No.",
"bill.field.status": "Status",
"bill.field.status.paid": "Paid",
"bill.field.status.partially-paid": "Partially paid",
"bill.field.status.unpaid": "Unpaid",
"bill.field.status.opened": "Opened",
"bill.field.status.draft": "Draft",
"bill.field.status.overdue": "overdue",
"bill.field.amount": "Amount",
"bill.field.payment_amount": "Payment amount",
"bill.field.note": "Note",
"bill.field.created_at": "Created at",
"inventory_adjustment.field.date": "Date",
"inventory_adjustment.field.type": "Type",
"inventory_adjustment.field.type.increment": "Increment",
"inventory_adjustment.field.type.decrement": "Decrement",
"inventory_adjustment.field.adjustment_account": "Adjustment account",
"inventory_adjustment.field.reason": "Reason",
"inventory_adjustment.field.reference_no": "Reference No.",
"inventory_adjustment.field.description": "Description",
"inventory_adjustment.field.published_at": "Published at",
"inventory_adjustment.field.created_at": "Created at",
"expense.field.payment_date": "Payment date",
"expense.field.payment_account": "Payment account",
"expense.field.amount": "Amount",
"expense.field.reference_no": "Reference No.",
"expense.field.description": "Description",
"expense.field.published": "Published",
"expense.field.status": "Status",
"expense.field.status.draft": "Draft",
"expense.field.status.published": "Published",
"expense.field.created_at": "Created at",
"manual_journal.field.date": "Date",
"manual_journal.field.journal_number": "Journal number",
"manual_journal.field.reference": "Reference No.",
"manual_journal.field.journal_type": "Journal type",
"manual_journal.field.amount": "Amount",
"manual_journal.field.description": "Description",
"manual_journal.field.status": "Status",
"manual_journal.field.created_at": "Created at",
"receipt.field.amount": "Amount",
"receipt.field.deposit_account": "Deposit account",
"receipt.field.customer": "Customer",
"receipt.field.receipt_date": "Receipt date",
"receipt.field.receipt_number": "Receipt number",
"receipt.field.reference_no": "Reference No.",
"receipt.field.receipt_message": "Receipt message",
"receipt.field.statement": "Statement",
"receipt.field.created_at": "Created at",
"receipt.field.status": "Status",
"receipt.field.status.draft": "Draft",
"receipt.field.status.closed": "Closed",
"customer.field.first_name": "First name",
"customer.field.last_name": "Last name",
"customer.field.display_name": "Display name",
"customer.field.email": "Email",
"customer.field.work_phone": "Work phone",
"customer.field.personal_phone": "Personal phone",
"customer.field.company_name": "Company name",
"customer.field.website": "Website",
"customer.field.opening_balance_at": "Opening balance at",
"customer.field.opening_balance": "Opening balance",
"customer.field.created_at": "Created at",
"customer.field.balance": "Balance",
"customer.field.status": "Status",
"customer.field.currency": "Curreny",
"customer.field.status.active": "Active",
"customer.field.status.inactive": "Inactive",
"customer.field.status.overdue": "Overdue",
"customer.field.status.unpaid": "Unpaid",
"vendor.field.first_name": "First name",
"vendor.field.last_name": "Last name",
"vendor.field.display_name": "Display name",
"vendor.field.email": "Email",
"vendor.field.work_phone": "Work phone",
"vendor.field.personal_phone": "Personal phone",
"vendor.field.company_name": "Company name",
"vendor.field.website": "Website",
"vendor.field.opening_balance_at": "Opening balance at",
"vendor.field.opening_balance": "Opening balance",
"vendor.field.created_at": "Created at",
"vendor.field.balance": "Balance",
"vendor.field.status": "Status",
"vendor.field.currency": "Curreny",
"vendor.field.status.active": "Active",
"vendor.field.status.inactive": "Inactive",
"vendor.field.status.overdue": "Overdue",
"vendor.field.status.unpaid": "Unpaid",
"Invoice write-off": "Invoice write-off",
"transaction_type.credit_note": "Credit note",
"transaction_type.refund_credit_note": "Refund credit note",
"transaction_type.vendor_credit": "Vendor credit",
"transaction_type.refund_vendor_credit": "Refund vendor credit",
"transaction_type.landed_cost": "Landed cost",
"sms_notification.invoice_details.label": "Sale invoice details",
"sms_notification.invoice_reminder.label": "Sale invoice reminder",
"sms_notification.receipt_details.label": "Sale receipt details",
"sms_notification.sale_estimate_details.label": "Sale estimate details",
"sms_notification.payment_receive_details.label": "Payment receive details",
"sms_notification.customer_balance.label": "Customer balance",
"sms_notification.invoice_details.description": "SMS notification will be sent to your customer once invoice created and published or when notify customer via SMS about the invoice.",
"sms_notification.payment_receive.description": "Payment thank you message notification will be sent to customer once the payment created and published or notify customer about payment manually.",
"sms_notification.receipt_details.description": "SMS notification will be sent to your cusotmer once receipt created and published or when notify customer about the receipt manually.",
"sms_notification.customer_balance.description": "Send SMS to notify customers about their current outstanding balance.",
"sms_notification.estimate_details.description": "SMS notification will be sent to your customer once estimate publish or notify customer about estimate manually.",
"sms_notification.invoice_reminder.description": "SMS notification will be sent to remind the customer to pay earliest, either automatically or manually.",
"sms_notification.customer_balance.default_message": "Dear {CustomerName}, This is reminder about your current outstanding balance of {Balance}, Please pay at the earliest. - {CompanyName}",
"sms_notification.payment_receive.default_message": "'Hi, {CustomerName}, We have received your payment for the invoice - {InvoiceNumber}. We look forward to serving you again. Thank you. - {CompanyName}'",
"sms_notification.estimate.default_message": "Hi, {CustomerName}, We have created an estimate - {EstimateNumber} for you. Please take a look and accept it to proceed further. Looking forward to hearing from you. - {CompanyName}",
"sms_notification.invoice_details.default_message": "Hi, {CustomerName}, You have an outstanding amount of {DueAmount} for the invoice {InvoiceNumber}. - {CompanyName}",
"sms_notification.receipt_details.default_message": "Hi, {CustomerName}, We have created receipt - {ReceiptNumber} for you. we look forward to serveing you again. Thank your - {CompanyName}",
"sms_notification.invoice_reminder.default_message": "Dear {CustomerName}, The payment towards the invoice - {InvoiceNumber} is due. Please pay before {DueDate}. Thank you. - {CompanyName}",
"module.sale_invoices.label": "Sale invoices",
"module.sale_receipts.label": "Sale receipts",
"module.sale_estimates.label": "Sale estimates",
"module.payment_receives.label": "Payment receive",
"module.customers.label": "Customers",
"sms_notification.invoice.var.invoice_number": "References to invoice number.",
"sms_notification.invoice.var.reference_number": "References to invoice reference number.",
"sms_notification.invoice.var.customer_name": "References to invoice customer name.",
"sms_notification.invoice.var.due_amount": "References to invoice due amount.",
"sms_notification.invoice.var.amount": "References to invoice amount.",
"sms_notification.invoice.var.company_name": "References to company name.",
"sms_notification.invoice.var.due_date": "References to invoice due date.",
"sms_notification.receipt.var.receipt_number": "References to receipt number.",
"sms_notification.receipt.var.reference_number": "References to receipt reference number.",
"sms_notification.receipt.var.customer_name": "References to receipt customer name.",
"sms_notification.receipt.var.amount": "References to receipt amount.",
"sms_notification.receipt.var.company_name": "References to company name.",
"sms_notification.payment.var.payment_number": "References to payment transaction number.",
"sms_notification.payment.var.reference_number": "References to payment reference number",
"sms_notification.payment.var.customer_name": "References to payment customer name.",
"sms_notification.payment.var.amount": "References to payment transaction amount.",
"sms_notification.payment.company_name": "References to company name",
"sms_notification.payment.var.invoice_number": "Reference to payment invoice number.",
"sms_notification.estimate.var.estimate_number": "References to estimate number.",
"sms_notification.estimate.var.reference_number": "References to estimate reference number.",
"sms_notification.estimate.var.customer_name": "References to estimate customer name.",
"sms_notification.estimate.var.amount": "References to estimate amount.",
"sms_notification.estimate.var.company_name": "References to company name.",
"sms_notification.estimate.var.expiration_date": "References to estimate expirtaion date.",
"sms_notification.estimate.var.estimate_date": "References to estimate date.",
"sms_notification.customer.var.customer_name": "References to customer name.",
"sms_notification.customer.var.balance": "References to customer outstanding balance.",
"sms_notification.customer.var.company_name": "References to company name.",
"ability.accounts": "Chart of accounts",
"ability.manual_journal": "Manual journals",
"ability.cashflow": "Cash flow",
"ability.inventory_adjustment": "Inventory adjustments",
"ability.customers": "Customers",
"ability.vendors": "vendors",
"ability.sale_estimates": "Sale estimates",
"ability.sale_invoices": "Sale invoices",
"ability.sale_receipts": "Sale receipts",
"ability.expenses": "Expenses",
"ability.payments_receive": "Payments receive",
"ability.purchase_invoices": "Purchase invoices",
"ability.all_reports": "All reports",
"ability.payments_made": "Payments made",
"ability.preferences": "Preferences",
"ability.mutate_system_preferences": "Mutate the system preferences.",
"ability.items": "Items",
"ability.view": "View",
"ability.create": "Create",
"ability.edit": "Edit",
"ability.delete": "Delete",
"ability.transactions_locking": "Ability to transactions locking.",
"ability.balance_sheet_report": "Balance sheet.",
"ability.profit_loss_sheet": "Profit/loss sheet",
"ability.journal": "Journal",
"ability.general_ledger": "General ledger",
"ability.cashflow_report": "Cashflow",
"ability.AR_aging_summary_report": "A/R aging summary",
"ability.AP_aging_summary_report": "A/P aging summary",
"ability.purchases_by_items": "Purchases by items",
"ability.sales_by_items_report": "Sales by items",
"ability.customers_transactions_report": "Customers transactions",
"ability.vendors_transactions_report": "Vendors transactions",
"ability.customers_summary_balance_report": "Customers summary balance",
"ability.vendors_summary_balance_report": "Vendors summary balance",
"ability.inventory_valuation_summary": "Inventory valuation summary",
"ability.inventory_items_details": "Inventory items details",
"vendor_credit.field.vendor": "Vendor name",
"vendor_credit.field.amount": "Amount",
"vendor_credit.field.currency_code": "Currency code",
"vendor_credit.field.credit_date": "Credit date",
"vendor_credit.field.credit_number": "Credit number",
"vendor_credit.field.note": "Note",
"vendor_credit.field.created_at": "Created at",
"vendor_credit.field.reference_no": "Reference No.",
"credit_note.field.terms_conditions": "Terms and conditions",
"credit_note.field.note": "Note",
"credit_note.field.currency_code": "Currency code",
"credit_note.field.created_at": "Created at",
"credit_note.field.amount": "Amount",
"credit_note.field.credit_note_number": "Credit note number",
"credit_note.field.credit_note_date": "Credit date",
"credit_note.field.customer": "Customer",
"credit_note.field.reference_no": "Reference No.",
"Credit note": "Credit note",
"Vendor credit": "Vendor credit",
"Refund credit note": "Refund credit note",
"Refund vendor credit": "Refund vendor credit",
"credit_note.field.status": "Status",
"credit_note.field.status.draft": "Draft",
"credit_note.field.status.published": "Published",
"credit_note.field.status.open": "Open",
"credit_note.field.status.closed": "Closed",
"transactions_locking.module.sales.label": "Sales",
"transactions_locking.module.purchases.label": "Purchases",
"transactions_locking.module.financial.label": "Financial",
"transactions_locking.module.all_transactions": "All transactions",
"transactions_locking.module.sales.desc": "Sale invoices, Receipts, credit notes, customers payment receive and customers opening balances.",
"transactions_locking.module.purchases.desc": "Purchase invoices, vendors payments, vendor credit notes and vendors opening balances.",
"transactions_locking.module.financial.desc": "Manual journal, expenses and inventory adjustments.",
"inventory_adjustment.type.increment": "Increment",
"inventory_adjustment.type.decrement": "Decrement",
"customer.type.individual": "Individual",
"customer.type.business": "Business",
"credit_note.view.draft": "Draft",
"credit_note.view.closed": "Closed",
"credit_note.view.open": "Open",
"credit_note.view.published": "Published",
"vendor_credit.view.draft": "Draft",
"vendor_credit.view.closed": "Closed",
"vendor_credit.view.open": "Open",
"vendor_credit.view.published": "Published",
"allocation_method.value.label": "Value",
"allocation_method.quantity.label": "Quantity",
"balance_sheet.assets": "Assets",
"balance_sheet.current_asset": "Current Asset",
"balance_sheet.cash_and_cash_equivalents": "Cash and cash equivalents",
"balance_sheet.accounts_receivable": "Accounts Receivable",
"balance_sheet.inventory": "Inventory",
"balance_sheet.other_current_assets": "Other current assets",
"balance_sheet.fixed_asset": "Fixed Asset",
"balance_sheet.non_current_assets": "Non-Current Assets",
"balance_sheet.liabilities_and_equity": "Liabilities and Equity",
"balance_sheet.liabilities": "Liabilities",
"balance_sheet.current_liabilties": "Current Liabilties",
"balance_sheet.long_term_liabilities": "Long-Term Liabilities",
"balance_sheet.non_current_liabilities": "Non-Current Liabilities",
"balance_sheet.equity": "Equity",
"balance_sheet.account_name": "Account name",
"balance_sheet.total": "Total",
"balance_sheet.percentage_of_column": "% of Column",
"balance_sheet.percentage_of_row": "% of Row",
"financial_sheet.previoud_period_date": "{{date}} (PP)",
"fianncial_sheet.previous_period_change": "Change (PP)",
"financial_sheet.previous_period_percentage": "% Change (PP)",
"financial_sheet.previous_year_date": "{{date}} (PY)",
"financial_sheet.previous_year_change": "Change (PY)",
"financial_sheet.previous_year_percentage": "% Change (PY)",
"financial_sheet.total_row": "Total {{value}}",
"profit_loss_sheet.income": "Income",
"profit_loss_sheet.cost_of_sales": "Cost of sales",
"profit_loss_sheet.gross_profit": "GROSS PROFIT",
"profit_loss_sheet.expenses": "Expenses",
"profit_loss_sheet.net_operating_income": "NET OPERATING INCOME",
"profit_loss_sheet.other_income": "Other income",
"profit_loss_sheet.other_expenses": "Other expenses",
"profit_loss_sheet.net_income": "NET INCOME",
"profit_loss_sheet.account_name": "Account name",
"profit_loss_sheet.total": "Total",
"profit_loss_sheet.percentage_of_income": "% of Income",
"profit_loss_sheet.percentage_of_expenses": "% of Expenses",
"profit_loss_sheet.percentage_of_column": "% of Column",
"profit_loss_sheet.percentage_of_row": "% of Row",
"contact_summary_balance.account_name": "Account name",
"contact_summary_balance.total": "Total",
"contact_summary_balance.percentage_column": "% of Column",
"warehouses.primary_warehouse": "Primary warehouse",
"branches.head_branch": "Head Branch",
"account.accounts_payable.currency": "Accounts Payable (A/P) - {{currency}}",
"account.accounts_receivable.currency": "Accounts Receivable (A/R) - {{currency}}",
"role.admin.name": "Admin",
"role.admin.desc": "Unrestricted access to all modules.",
"role.staff.name": "Staff",
"role.staff.desc": "Access to all modules except reports, settings and accountant.",
"warehouse_transfer.view.draft.name": "Draft",
"warehouse_transfer.view.in_transit.name": "In Transit",
"warehouse_transfer.view.transferred.name": "Transferred"
}

View File

@@ -0,0 +1,35 @@
@import "./normalize.scss";
*,
*::before,
*::after {
box-sizing: border-box;
}
th {
text-align: inherit; // 2
text-align: -webkit-match-parent; // 3
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
body{
margin: 0;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
background-color: #fff;
direction: ltr;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
@import "../base.scss";
@import "../fonts.scss";
body {
background: #f8f9fa;
text-align: left;
-webkit-print-color-adjust: exact;
html[lang^='ar'] & {
font-family: "Segoe UI";
}
html[lang^='en'] & {
font-family: "Noto Sans";
}
@media print {
background: #fff;
}
}

View File

@@ -0,0 +1,193 @@
@import "../layouts/paper-layout.scss";
.credit {
text-align: left;
padding: 45px 40px;
&__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin: 0 0 30px;
.organization {
.title {
margin: 0 0 4px;
}
.creditNumber {
font-size: 12px;
}
}
.paper {
.title {
font-weight: 400;
text-transform: uppercase;
margin: 0 0 2px;
font-size: 32px;
line-height: 1;
}
}
}
&__full-amount {
margin-bottom: 18px;
.label {
font-size: 12px;
}
.amount {
font-size: 18px;
font-weight: 800;
}
}
&__meta {
display: flex;
flex-direction: column;
margin-bottom: 20px;
font-size: 13px;
&-item {
padding-right: 10px;
font-weight: 400;
margin-bottom: 10px;
display: flex;
flex-direction: row;
.value {
color: #000;
}
.label {
color: #444;
margin-bottom: 2px;
width: 180px;
}
}
}
&__table {
display: flex;
flex-direction: column;
table {
font-size: 12px;
color: #000;
text-align: left;
border-spacing: 0;
thead th,
tbody tr td {
margin-bottom: 15px;
background: transparent;
}
thead th {
font-weight: 400;
border-bottom: none;
padding: 8px;
color: #fff;
background-color: #333;
}
tbody tr td {
padding: 8px;
border-bottom: 1px solid #cecbcb;
}
thead tr th,
tbody tr td {
&.item {
width: 45%;
}
&.rate {
width: 18%;
text-align: right;
}
&.quantity {
width: 16%;
text-align: right;
}
&.total {
width: 21%;
text-align: right;
}
}
.description {
color: #666;
}
}
}
&__table-after {
display: flex;
}
&__table-total {
margin-bottom: 20px;
width: 50%;
float: right;
margin-left: auto;
table {
border-spacing: 0;
width: 100%;
font-size: 12px;
tbody tr td {
padding: 8px 10px 8px 0;
border-top: 1px solid #d5d5d5;
&:last-child {
width: 140px;
text-align: right;
}
}
tbody tr:first-child td {
border-top: 0;
}
tbody tr.payment-amount td:last-child {
color: red
}
tbody tr.blanace-due td {
border-top: 3px double #666;
font-weight: bold;
}
}
}
&__footer {
font-size: 12px;
}
&__conditions,
&__notes {
h3 {
color: #666;
font-size: 12px;
margin-top: 0;
margin-bottom: 10px;
}
p {
margin: 0;
}
}
&__conditions+&__notes {
margin-top: 20px;
}
}

View File

@@ -0,0 +1,174 @@
@import "../layouts/paper-layout.scss";
.estimate {
text-align: left;
padding: 45px;
&__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin: 0 0 30px;
.organization {
.title {
margin: 0 0 4px;
}
}
.paper {
.title {
font-weight: 400;
text-transform: uppercase;
margin: 0 0 2px;
font-size: 32px;
line-height: 1;
}
}
}
&__estimate-amount {
margin-bottom: 18px;
.label {
font-size: 12px;
}
.amount {
font-size: 18px;
font-weight: 800;
}
}
&__meta {
display: flex;
flex-direction: column;
margin-bottom: 20px;
font-size: 13px;
&-item {
padding-right: 10px;
margin-bottom: 10px;
display: flex;
flex-direction: row;
.value {
color: #000;
}
.label {
color: #444;
margin-bottom: 2px;
width: 180px;
}
}
}
&__table {
display: flex;
flex-direction: column;
table {
font-size: 12px;
color: #000;
text-align: left;
border-spacing: 0;
thead th,
tbody tr td {
margin-bottom: 15px;
background: transparent;
}
thead th {
font-weight: 400;
border-bottom: none;
padding: 8px;
color: #fff;
background-color: #333;
}
tbody tr td {
padding: 8px;
border-bottom: 1px solid #cecbcb;
}
thead tr th,
tbody tr td {
&.item {
width: 45%;
}
&.rate {
width: 18%;
text-align: right;
}
&.quantity {
width: 16%;
text-align: right;
}
&.total {
width: 21%;
text-align: right;
}
.description {
color: #666;
}
}
}
}
&__table-after {
display: flex;
}
&__table-total {
margin-bottom: 20px;
width: 50%;
float: right;
margin-left: auto;
table {
border-spacing: 0;
width: 100%;
font-size: 12px;
tbody tr td {
padding: 8px 10px 8px 0;
border-top: 1px solid #d5d5d5;
&:last-child {
width: 140px;
text-align: right;
}
}
tbody tr:first-child td {
border-top: 0;
}
tbody tr.total td {
border-top: 3px double #666;
font-weight: bold;
}
}
}
&__footer{
font-size: 12px;
}
&__conditions,
&__notes {
h3 {
color: #666;
font-size: 12px;
margin-top: 0;
margin-bottom: 10px;
}
p {
margin: 0 0 20px;
}
}
}

View File

@@ -0,0 +1,179 @@
@import "../layouts/paper-layout.scss";
.invoice {
text-align: left;
padding: 45px 40px;
&__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin: 0 0 30px;
.organization {
.title {
margin: 0 0 4px;
}
.invoiceNo {
font-size: 12px;
}
}
.paper {
.title {
font-weight: 400;
text-transform: uppercase;
margin: 0 0 2px;
font-size: 32px;
line-height: 1;
}
}
}
&__meta {
display: flex;
flex-direction: column;
margin-bottom: 20px;
font-size: 13px;
&-item {
padding-right: 10px;
font-weight: 400;
margin-bottom: 10px;
display: flex;
flex-direction: row;
.value {
color: #000;
}
.label {
color: #444;
margin-bottom: 2px;
width: 180px;
}
}
}
&__table {
display: flex;
flex-direction: column;
table {
font-size: 12px;
color: #000;
text-align: left;
border-spacing: 0;
thead th,
tbody tr td {
margin-bottom: 15px;
background: transparent;
}
thead th {
font-weight: 400;
border-bottom: none;
padding: 8px;
color: #fff;
background-color: #333;
}
tbody tr td {
padding: 8px;
border-bottom: 1px solid #cecbcb;
}
thead tr th,
tbody tr td {
&.item {
width: 45%;
}
&.rate {
width: 18%;
text-align: right;
}
&.quantity {
width: 16%;
text-align: right;
}
&.total {
width: 21%;
text-align: right;
}
}
.description {
color: #666;
}
}
}
&__table-after{
display: flex;
}
&__table-total {
margin-bottom: 20px;
width: 50%;
float: right;
margin-left: auto;
table {
border-spacing: 0;
width: 100%;
font-size: 12px;
tbody tr td {
padding: 8px 10px 8px 0;
border-top: 1px solid #d5d5d5;
&:last-child {
width: 140px;
text-align: right;
}
}
tbody tr:first-child td {
border-top: 0;
}
tbody tr.payment-amount td:last-child {
color: red
}
tbody tr.blanace-due td {
border-top: 3px double #666;
font-weight: bold;
}
}
}
&__due-amount {
margin-bottom: 18px;
.label {
font-size: 12px;
}
.amount {
font-size: 18px;
font-weight: 800;
}
}
&__footer{
font-size: 12px;
}
&__conditions,
&__notes {
h3 {
color: #666;
font-size: 12px;
margin-top: 0;
margin-bottom: 10px;
}
p{
margin: 0;
}
}
&__conditions + &__notes{
margin-top: 20px;
}
}

View File

@@ -0,0 +1,178 @@
@import "../layouts/paper-layout.scss";
.payment {
text-align: left;
padding: 45px 40px;
&__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin: 0 0 30px;
.organization {
.title {
margin: 0 0 4px;
}
.paymentNumber {
font-size: 12px;
}
}
.paper {
.title {
font-weight: 400;
text-transform: uppercase;
margin: 0 0 2px;
font-size: 32px;
line-height: 1;
}
}
}
&__meta {
display: flex;
flex-direction: column;
margin-bottom: 20px;
font-size: 13px;
&-item {
padding-right: 10px;
font-weight: 400;
margin-bottom: 10px;
display: flex;
flex-direction: row;
.value {
color: #000;
}
.label {
color: #444;
margin-bottom: 2px;
width: 180px;
}
}
}
&__table {
display: flex;
flex-direction: column;
table {
font-size: 12px;
color: #000;
text-align: left;
border-spacing: 0;
thead th,
tbody tr td {
margin-bottom: 15px;
background: transparent;
}
thead th {
font-weight: 400;
border-bottom: none;
padding: 8px;
color: #fff;
background-color: #333;
}
tbody tr td {
padding: 8px;
border-bottom: 1px solid #cecbcb;
}
thead tr th,
tbody tr td {
&.item {
width: 34%;
}
&.date {
width: 22%;
text-align: right;
}
&.invoiceAmount {
width: 22%;
text-align: right;
}
&.paymentAmount {
width: 22%;
text-align: right;
}
}
.description {
color: #666;
}
}
}
&__table-after{
display: flex;
}
&__table-total {
margin-bottom: 20px;
width: 50%;
float: right;
margin-left: auto;
table {
border-spacing: 0;
width: 100%;
font-size: 12px;
tbody tr td {
padding: 8px 10px 8px 0;
border-top: 1px solid #d5d5d5;
&:last-child {
width: 140px;
text-align: right;
}
}
tbody tr:first-child td {
border-top: 0;
}
tbody tr.payment-amount td:last-child {
color: red
}
tbody tr.blanace-due td {
border-top: 3px double #666;
font-weight: bold;
}
}
}
&__received-amount {
margin-bottom: 18px;
.label {
font-size: 12px;
}
.amount {
font-size: 18px;
font-weight: 800;
}
}
&__footer{
font-size: 12px;
}
&__conditions,
&__notes {
h3 {
color: #666;
font-size: 12px;
margin-top: 0;
margin-bottom: 10px;
}
p{
margin: 0;
}
}
&__conditions + &__notes{
margin-top: 20px;
}
}

View File

@@ -0,0 +1,185 @@
@import "../layouts/paper-layout.scss";
.receipt {
text-align: left;
padding: 45px;
&__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin: 0 0 30px;
.organization {
.title {
margin: 0 0 4px;
}
.receiptNumber {
margin: 0 0 12px;
}
}
.paper {
.title {
font-weight: 400;
text-transform: uppercase;
margin: 0 0 2px;
font-size: 32px;
line-height: 1;
}
}
}
&__receipt-amount {
margin-bottom: 18px;
.label {
font-size: 12px;
}
.amount {
font-size: 18px;
font-weight: 800;
}
}
&__meta {
display: flex;
flex-direction: column;
margin-bottom: 20px;
font-size: 13px;
&-item {
padding-right: 10px;
margin-bottom: 10px;
display: flex;
flex-direction: row;
.value {
color: #000;
}
.label {
color: #444;
margin-bottom: 2px;
width: 180px;
}
}
}
&__table {
display: flex;
flex-direction: column;
table {
font-size: 12px;
color: #000;
text-align: left;
border-spacing: 0;
thead th,
tbody tr td {
margin-bottom: 15px;
background: transparent;
}
thead th {
font-weight: 400;
border-bottom: none;
padding: 8px;
color: #fff;
background-color: #333;
}
tbody tr td {
padding: 10px;
border-bottom: 1px solid #cecbcb;
}
thead tr th,
tbody tr td {
&.item {
width: 45%;
}
&.rate {
width: 18%;
text-align: right;
}
&.quantity {
width: 16%;
text-align: right;
}
&.total {
width: 21%;
text-align: right;
}
}
}
}
&__table-after {
display: flex;
}
&__table-total {
margin-bottom: 20px;
width: 50%;
float: right;
margin-left: auto;
table {
border-spacing: 0;
width: 100%;
font-size: 12px;
tbody tr td {
padding: 8px 10px 8px 0;
border-top: 1px solid #d5d5d5;
&:last-child {
width: 140px;
text-align: right;
}
}
tbody tr:first-child td {
border-top: 0;
}
tbody tr.payment-amount td:last-child {
color: red
}
tbody tr.blanace-due td {
border-top: 3px double #666;
font-weight: bold;
}
}
}
&__footer {
font-size: 12px;
}
&__conditions,
&__notes {
h3 {
color: #666;
font-size: 12px;
margin-top: 0;
margin-bottom: 10px;
}
p {
margin: 0 0 20px;
}
}
}

View File

@@ -0,0 +1,379 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15;
/* 1 */
-webkit-text-size-adjust: 100%;
/* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box;
/* 1 */
height: 0;
/* 1 */
overflow: visible;
/* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace;
/* 1 */
font-size: 1em;
/* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none;
/* 1 */
text-decoration: underline;
/* 2 */
text-decoration: underline dotted;
/* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace;
/* 1 */
font-size: 1em;
/* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
/* 1 */
font-size: 100%;
/* 1 */
line-height: 1.15;
/* 1 */
margin: 0;
/* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box;
/* 1 */
color: inherit;
/* 2 */
display: table;
/* 1 */
max-width: 100%;
/* 1 */
padding: 0;
/* 3 */
white-space: normal;
/* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box;
/* 1 */
padding: 0;
/* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield;
/* 1 */
outline-offset: -2px;
/* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button;
/* 1 */
font: inherit;
/* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@@ -0,0 +1,7 @@
html(lang=locale)
head
title My Site - #{title}
block head
body
div.paper-template
block content

View File

@@ -0,0 +1,81 @@
extends ../PaperTemplateLayout.pug
block head
style
if (isRtl)
include ../../css/modules/credit-rtl.css
else
include ../../css/modules/credit.css
block content
div.credit
div.credit__header
div.paper
h1.title #{__('credit.paper.credit_note')}
if creditNote.creditNoteNumber
span.creditNoteNumber #{creditNote.creditNoteNumber}
div.organization
h3.title #{organizationName}
if organizationEmail
span.email #{organizationEmail}
div.credit__full-amount
div.label #{__('credit.paper.amount')}
div.amount #{creditNote.formattedAmount}
div.credit__meta
div.credit__meta-item.credit__meta-item--amount
span.label #{__('credit.paper.remaining')}
span.value #{creditNote.formattedCreditsRemaining}
div.credit__meta-item.credit__meta-item--billed-to
span.label #{__("credit.paper.billed_to")}
span.value #{creditNote.customer.displayName}
div.credit__meta-item.credit__meta-item--credit-date
span.label #{__("credit.paper.credit_date")}
span.value #{creditNote.formattedCreditNoteDate}
div.credit__table
table
thead
tr
th.item #{__("item_entry.paper.item_name")}
th.rate #{__("item_entry.paper.rate")}
th.quantity #{__("item_entry.paper.quantity")}
th.total #{__("item_entry.paper.total")}
tbody
each entry in creditNote.entries
tr
td.item
div.title=entry.item.name
span.description=entry.description
td.rate=entry.rate
td.quantity=entry.quantity
td.total=entry.amount
div.credit__table-after
div.credit__table-total
table
tbody
tr.total
td #{__('credit.paper.total')}
td #{creditNote.formattedAmount}
tr.payment-amount
td #{__('credit.paper.credits_used')}
td #{creditNote.formattedCreditsUsed}
tr.blanace-due
td #{__('credit.paper.credits_remaining')}
td #{creditNote.formattedCreditsRemaining}
div.credit__footer
if creditNote.termsConditions
div.credit__conditions
h3 #{__("credit.paper.terms_conditions")}
p #{creditNote.termsConditions}
if creditNote.note
div.credit__notes
h3 #{__("credit.paper.notes")}
p #{creditNote.note}

View File

@@ -0,0 +1,82 @@
extends ../PaperTemplateLayout.pug
block head
style
if (isRtl)
include ../../css/modules/estimate-rtl.css
else
include ../../css/modules/estimate.css
block content
div.estimate
div.estimate__header
div.paper
h1.title #{__("estimate.paper.estimate")}
span.email #{saleEstimate.estimateNumber}
div.organization
h3.title #{organizationName}
if organizationEmail
span.email #{organizationEmail}
div.estimate__estimate-amount
div.label #{__('estimate.paper.estimate_amount')}
div.amount #{saleEstimate.formattedAmount}
div.estimate__meta
if saleEstimate.estimateNumber
div.estimate__meta-item.estimate__meta-item--estimate-number
span.label #{__("estimate.paper.estimate_number")}
span.value #{saleEstimate.estimateNumber}
div.estimate__meta-item.estimate__meta-item--billed-to
span.label #{__("estimate.paper.billed_to")}
span.value #{saleEstimate.customer.displayName}
div.estimate__meta-item.estimate__meta-item--estimate-date
span.label #{__("estimate.paper.estimate_date")}
span.value #{saleEstimate.formattedEstimateDate}
div.estimate__meta-item.estimate__meta-item--due-date
span.label #{__("estimate.paper.expiration_date")}
span.value #{saleEstimate.formattedExpirationDate}
div.estimate__table
table
thead
tr
th.item #{__("item_entry.paper.item_name")}
th.rate #{__("item_entry.paper.rate")}
th.quantity #{__("item_entry.paper.quantity")}
th.total #{__("item_entry.paper.total")}
tbody
each entry in saleEstimate.entries
tr
td.item
div.title=entry.item.name
span.description=entry.description
td.rate=entry.rate
td.quantity=entry.quantity
td.total=entry.amount
div.estimate__table-after
div.estimate__table-total
table
tbody
tr.subtotal
td #{__('estimate.paper.subtotal')}
td #{saleEstimate.formattedAmount}
tr.total
td #{__('estimate.paper.total')}
td #{saleEstimate.formattedAmount}
div.estimate__footer
if saleEstimate.termsConditions
div.estimate__conditions
h3 #{__("estimate.paper.conditions_title")}
p #{saleEstimate.termsConditions}
if saleEstimate.note
div.estimate__notes
h3 #{__("estimate.paper.notes_title")}
p #{saleEstimate.note}

View File

@@ -0,0 +1,85 @@
extends ../PaperTemplateLayout.pug
block head
style
if (isRtl)
include ../../css/modules/invoice-rtl.css
else
include ../../css/modules/invoice.css
block content
div.invoice
div.invoice__header
div.paper
h1.title #{__("invoice.paper.invoice")}
if saleInvoice.invoiceNo
span.invoiceNo #{saleInvoice.invoiceNo}
div.organization
h3.title #{organizationName}
if organizationEmail
span.email #{organizationEmail}
div.invoice__due-amount
div.label #{__('invoice.paper.invoice_amount')}
div.amount #{saleInvoice.formattedAmount}
div.invoice__meta
div.invoice__meta-item.invoice__meta-item--amount
span.label #{__('invoice.paper.due_amount')}
span.value #{saleInvoice.formattedDueAmount}
div.invoice__meta-item.invoice__meta-item--billed-to
span.label #{__("invoice.paper.billed_to")}
span.value #{saleInvoice.customer.displayName}
div.invoice__meta-item.invoice__meta-item--invoice-date
span.label #{__("invoice.paper.invoice_date")}
span.value #{saleInvoice.formattedInvoiceDate}
div.invoice__meta-item.invoice__meta-item--due-date
span.label #{__("invoice.paper.due_date")}
span.value #{saleInvoice.formattedDueDate}
div.invoice__table
table
thead
tr
th.item #{__("item_entry.paper.item_name")}
th.rate #{__("item_entry.paper.rate")}
th.quantity #{__("item_entry.paper.quantity")}
th.total #{__("item_entry.paper.total")}
tbody
each entry in saleInvoice.entries
tr
td.item
div.title=entry.item.name
span.description=entry.description
td.rate=entry.rate
td.quantity=entry.quantity
td.total=entry.amount
div.invoice__table-after
div.invoice__table-total
table
tbody
tr.total
td #{__('invoice.paper.total')}
td #{saleInvoice.formattedAmount}
tr.payment-amount
td #{__('invoice.paper.payment_amount')}
td #{saleInvoice.formattedPaymentAmount}
tr.blanace-due
td #{__('invoice.paper.balance_due')}
td #{saleInvoice.formattedDueAmount}
div.invoice__footer
if saleInvoice.termsConditions
div.invoice__conditions
h3 #{__("invoice.paper.conditions_title")}
p #{saleInvoice.termsConditions}
if saleInvoice.invoiceMessage
div.invoice__notes
h3 #{__("invoice.paper.notes_title")}
p #{saleInvoice.invoiceMessage}

View File

@@ -0,0 +1,67 @@
extends ../PaperTemplateLayout.pug
block head
style
if (isRtl)
include ../../css/modules/payment-rtl.css
else
include ../../css/modules/payment.css
block content
div.payment
div.payment__header
div.paper
h1.title #{__("payment.paper.payment_receipt")}
if paymentReceive.paymentReceiveNo
span.paymentNumber #{paymentReceive.paymentReceiveNo}
div.organization
h3.title #{organizationName}
if organizationEmail
span.email #{organizationEmail}
div.payment__received-amount
div.label #{__('payment.paper.amount_received')}
div.amount #{paymentReceive.formattedAmount}
div.payment__meta
div.payment__meta-item.payment__meta-item--billed-to
span.label #{__("payment.paper.billed_to")}
span.value #{paymentReceive.customer.displayName}
div.payment__meta-item.payment__meta-item--payment-date
span.label #{__("payment.paper.payment_date")}
span.value #{paymentReceive.formattedPaymentDate}
div.payment__table
table
thead
tr
th.item #{__("payment.paper.invoice_number")}
th.date #{__("payment.paper.invoice_date")}
th.invoiceAmount #{__("payment.paper.invoice_amount")}
th.paymentAmount #{__("payment.paper.payment_amount")}
tbody
each entry in paymentReceive.entries
tr
td.item=entry.invoice.invoiceNo
td.date=entry.invoice.formattedInvoiceDate
td.invoiceAmount=entry.invoice.formattedAmount
td.paymentAmount=entry.invoice.formattedPaymentAmount
div.payment__table-after
div.payment__table-total
table
tbody
tr.payment-amount
td #{__('payment.paper.payment_amount')}
td #{paymentReceive.formattedAmount}
tr.blanace-due
td #{__('payment.paper.balance_due')}
td #{paymentReceive.customer.closingBalance}
div.payment__footer
if paymentReceive.statement
div.payment__notes
h3 #{__("payment.paper.statement")}
p #{paymentReceive.statement}

View File

@@ -0,0 +1,77 @@
extends ../PaperTemplateLayout.pug
block head
style
if (isRtl)
include ../../css/modules/receipt-rtl.css
else
include ../../css/modules/receipt.css
block content
div.receipt
div.receipt__header
div.paper
h1.title #{__("receipt.paper.receipt")}
span.receiptNumber #{saleReceipt.receiptNumber}
div.organization
h3.title #{organizationName}
div.receipt__receipt-amount
div.label #{__('receipt.paper.receipt_amount')}
div.amount #{saleReceipt.formattedAmount}
div.receipt__meta
div.receipt__meta-item.receipt__meta-item--billed-to
span.label #{__("receipt.paper.billed_to")}
span.value #{saleReceipt.customer.displayName}
div.receipt__meta-item.receipt__meta-item--invoice-date
span.label #{__("receipt.paper.receipt_date")}
span.value #{saleReceipt.formattedReceiptDate}
if saleReceipt.receiptNumber
div.receipt__meta-item.receipt__meta-item--invoice-number
span.label #{__("receipt.paper.receipt_number")}
span.value #{saleReceipt.receiptNumber}
div.receipt__table
table
thead
tr
th.item #{__("item_entry.paper.item_name")}
th.rate #{__("item_entry.paper.rate")}
th.quantity #{__("item_entry.paper.quantity")}
th.total #{__("item_entry.paper.total")}
tbody
each entry in saleReceipt.entries
tr
td.item=entry.item.name
td.rate=entry.rate
td.quantity=entry.quantity
td.total=entry.amount
div.receipt__table-after
div.receipt__table-total
table
tbody
tr.total
td #{__('receipt.paper.total')}
td #{saleReceipt.formattedAmount}
tr.payment-amount
td #{__('receipt.paper.payment_amount')}
td #{saleReceipt.formattedAmount}
tr.blanace-due
td #{__('receipt.paper.balance_due')}
td #{'$0'}
div.receipt__footer
if saleReceipt.statement
div.receipt__conditions
h3 #{__("receipt.paper.statement")}
p #{saleReceipt.statement}
if saleReceipt.receiptMessage
div.receipt__notes
h3 #{__("receipt.paper.notes")}
p #{saleReceipt.receiptMessage}

View File

@@ -0,0 +1,145 @@
/**
* # Gulp Configuration.
* ------------------------------------------------------------------
*/
const RESOURCES_PATH = '../resources/';
module.exports = {
banner: [
'/**',
' * <%= pkg.name %> - <%= pkg.description %>',
' * @version v<%= pkg.version %>',
' * @link <%= pkg.homepage %>',
' * @author <%= pkg.author %>',
' * @license <%= pkg.license %>',
'**/',
'',
].join('\n'),
// Browser Sync
browsersync: {
files: ['**/*', '!**.map', '!**.css'], // Exclude map files.
notify: false, //
open: true, // Set it to false if you don't like the broser window opening automatically.
port: 8080, //
proxy: 'localhost/customatic', //
watchOptions: {
debounceDelay: 2000, // This introduces a small delay when watching for file change events to avoid triggering too many reloads
},
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**'],
},
},
// Style Related.
style: {
clean: ['style.css', 'style.min.css', 'style-rtl.css', 'style-rtl.min.css'],
build: [
{
src: `${RESOURCES_PATH}/scss/modules/invoice.scss`,
dest: `${RESOURCES_PATH}/css/modules`,
// sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it.
// minify: true, // Allow to enable/disable minify the source.
},
{
src: `${RESOURCES_PATH}/scss/modules/estimate.scss`,
dest: `${RESOURCES_PATH}/css/modules`,
// sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it.
// minify: true, // Allow to enable/disable minify the source.
},
{
src: `${RESOURCES_PATH}/scss/modules/receipt.scss`,
dest: `${RESOURCES_PATH}/css/modules`,
// sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it.
// minify: true, // Allow to enable/disable minify the source.
},
{
src: `${RESOURCES_PATH}/scss/modules/credit.scss`,
dest: `${RESOURCES_PATH}/css/modules`,
// sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it.
// minify: true, // Allow to enable/disable minify the source.
},
{
src: `${RESOURCES_PATH}/scss/modules/payment.scss`,
dest: `${RESOURCES_PATH}/css/modules`,
// sourcemaps: true, // Allow to enable/disable sourcemaps or pass object to configure it.
// minify: true, // Allow to enable/disable minify the source.
},
// {
// src: './assets/sass/editor-style.scss',
// dest: './assets/css',
// sourcemaps: true,
// minify: true,
// },
],
// RTL builds.
rtl: [
{
src: `${RESOURCES_PATH}/css/modules/invoice.css`,
dest: `${RESOURCES_PATH}/css/modules`,
},
{
src: `${RESOURCES_PATH}/css/modules/estimate.css`,
dest: `${RESOURCES_PATH}/css/modules`,
},
{
src: `${RESOURCES_PATH}/css/modules/receipt.css`,
dest: `${RESOURCES_PATH}/css/modules`,
},
{
src: `${RESOURCES_PATH}/css/modules/credit.css`,
dest: `${RESOURCES_PATH}/css/modules`,
},
{
src: `${RESOURCES_PATH}/css/modules/payment.css`,
dest: `${RESOURCES_PATH}/css/modules`,
},
],
// Browsers you care about for auto-prefixing.
autoprefixer: {
browsers: [
'Android 2.3',
'Android >= 4',
'Chrome >= 20',
'Firefox >= 24',
'Explorer >= 9',
'iOS >= 6',
'Opera >= 12',
'Safari >= 6',
],
},
// SASS Configuration for all builds.
sass: {
errLogToConsole: true,
// outputStyle: 'compact',
},
// CSS MQ Packer configuration for all builds and style tasks.
cssMqpacker: {},
// CSS nano configuration for all builds.
cssnano: {},
// rtlcss configuration for all builds.
rtlcss: {},
},
// Clean specific files.
clean: [
'**/.DS_Store',
'./assets/js/**/*.min.js',
'**/*.map',
'**/*.min.css',
'assets/js/hypernews.js',
],
// Watch related.
watch: {
css: ['./assets/sass/**/*'],
js: ['assets/js/**/*.js', '!assets/js/**/*.min.js'],
images: ['./assets/images/**/*'],
},
};

View File

@@ -0,0 +1,50 @@
const gulp = require('gulp');
const sass = require('sass');
const gulpSass = require('gulp-sass')(sass); // Gulp pluign for Sass compilation.
const mergeStream = require('merge-stream');
const rename = require('gulp-rename'); // Renames files E.g. style.css -> style.min.css
// Style related.
const postcss = require('gulp-postcss'); // Transforming styles with JS plugins
const rtlcss = require('rtlcss'); // Convert LTR CSS to RTL.
const config = require('./gulpConfig');
gulp.task('styles', () => {
const builds = config.style.build.map((build) => {
return gulp
.src(build.src)
.pipe(gulpSass(config.style.sass))
.pipe(gulp.dest(build.dest));
});
return mergeStream(builds);
});
/**
* Task: `styles-rtl`
*
* This task does the following.
* 1. Gets the source css files.
* 2. Covert LTR CSS to RTL.
* 3. Suffix all CSS files to `-rtl`.
* 4. Reloads css files via browser sync stream.
* 5. Combine matching media queries for `.min.css` version.
* 6. Minify all CSS files.
* 7. Reload minified css files via browser sync stream.
*/
gulp.task('styles-rtl', () => {
const builds = config.style.rtl.map((build) => {
return gulp
.src(build.src)
.pipe(
postcss([
rtlcss(config.style.rtlcss), // Convert LTR CSS to RTL.
]),
)
.pipe(rename({ suffix: '-rtl' })) // Append "-rtl" to the filename.
.pipe(gulp.dest(build.dest));
});
return mergeStream(builds);
});

View File

@@ -0,0 +1,4 @@
npm install
npm run build
npm run copy-i18n

View File

@@ -0,0 +1,31 @@
MYSQL_USER="ratteb"
MYSQL_DATABASE="ratteb"
MYSQL_CONTAINER_NAME="ratteb_test"
MYSQL_ROOT_PASSWORD="root"
MYSQL_PASSWORD="root"
echo "Start the testing MySql database..."
docker \
run \
--detach \
--env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
--env MYSQL_USER=${MYSQL_USER} \
--env MYSQL_PASSWORD=${MYSQL_PASSWORD} \
--env MYSQL_DATABASE=${MYSQL_DATABASE} \
--name ${MYSQL_CONTAINER_NAME} \
--publish 3306:3306 \
--tmpfs /var/lib/mysql:rw \
mysql:5.7;
echo "Sleeping for 10 seconds to allow time for the DB to be provisioned:"
for i in `seq 1 10`;
do
echo "."
sleep 1
done
echo "Database '${MYSQL_DATABASE}' running."
echo " Username: ${MYSQL_USER}"
echo " Password: ${MYSQL_PASSWORD}"

View File

@@ -0,0 +1,11 @@
const { getCommonWebpackOptions } = require('./webpack.common');
const inputEntry = './src/commands/index.ts';
const outputDir = '../build';
const outputFilename = 'commands.js';
module.exports = getCommonWebpackOptions({
inputEntry,
outputDir,
outputFilename,
});

View File

@@ -0,0 +1,79 @@
const path = require('path');
const { NormalModuleReplacementPlugin } = require('webpack');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const isDev = process.env.NODE_ENV === 'development';
exports.getCommonWebpackOptions = ({
inputEntry,
outputDir,
outputFilename,
}) => {
const webpackOptions = {
entry: ['regenerator-runtime/runtime', inputEntry],
target: 'node',
mode: isDev ? 'development' : 'production',
watch: isDev,
watchOptions: {
aggregateTimeout: 200,
poll: 1000,
},
output: {
path: path.resolve(__dirname, outputDir),
filename: outputFilename,
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
extensionAlias: {
'.ts': ['.js', '.ts'],
'.cts': ['.cjs', '.cts'],
'.mts': ['.mjs', '.mts'],
},
plugins: [
new TsconfigPathsPlugin({
configFile: './tsconfig.json',
extensions: ['.ts', '.tsx', '.js'],
}),
],
},
plugins: [
// Ignore knex dynamic required dialects that we don't use
new NormalModuleReplacementPlugin(
/m[sy]sql2?|oracle(db)?|sqlite3|pg-(native|query)/,
'noop2'
),
new ProgressBarPlugin(),
],
externals: [nodeExternals(), 'aws-sdk', 'prettier'],
module: {
rules: [
{
test: /\.([cm]?ts|tsx|js)$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true,
configFile: 'tsconfig.json',
},
},
],
exclude: /(node_modules)/,
},
],
},
optimization: {
minimize: false,
},
};
if (isDev) {
webpackOptions.plugins.push(
new RunScriptWebpackPlugin({ name: outputFilename })
);
}
return webpackOptions;
};

View File

@@ -0,0 +1,11 @@
const { getCommonWebpackOptions } = require('./webpack.common');
const inputEntry = './src/server.ts';
const outputDir = '../build';
const outputFilename = 'index.js';
module.exports = getCommonWebpackOptions({
inputEntry,
outputDir,
outputFilename,
});

View File

@@ -0,0 +1,52 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Service, Inject } from 'typedi';
import BaseController from '@/api/controllers/BaseController';
import AuthenticatedAccount from '@/services/AuthenticatedAccount';
import TenancyMiddleware from '@/api/middleware/TenancyMiddleware';
import AttachCurrentTenantUser from '@/api/middleware/AttachCurrentTenantUser';
import JWTAuth from '@/api/middleware/jwtAuth';
@Service()
export default class AccountController extends BaseController {
@Inject()
accountService: AuthenticatedAccount;
/**
* Router constructor method.
*/
public router() {
const router = Router();
// Should before build tenant database the user be authorized and
// most important than that, should be subscribed to any plan.
router.use(JWTAuth);
router.use(AttachCurrentTenantUser);
router.use(TenancyMiddleware);
router.get('/', this.getAccount);
return router;
}
/**
* Creates a new account.
* @param {Request} req -
* @param {Response} res -
* @param {NextFunction} next -
*/
private getAccount = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId, user } = req;
try {
const account = await this.accountService.getAccount(tenantId, user);
return res.status(200).send({ data: account });
} catch (error) {
next(error);
}
};
}

View File

@@ -0,0 +1,42 @@
import { Service, Inject } from 'typedi';
import { Request, Response, Router, NextFunction } from 'express';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
import BaseController from '@/api/controllers/BaseController';
import AccountsTypesService from '@/services/Accounts/AccountsTypesServices';
@Service()
export default class AccountsTypesController extends BaseController {
@Inject()
accountsTypesService: AccountsTypesService;
/**
* Router constructor.
*/
router() {
const router = Router();
router.get('/', asyncMiddleware(this.getAccountTypesList.bind(this)));
return router;
}
/**
* Retrieve accounts types list.
* @param {Request} req - Request.
* @param {Response} res - Response.
* @return {Response}
*/
getAccountTypesList(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
try {
const accountTypes = this.accountsTypesService.getAccountsTypes(tenantId);
return res.status(200).send({
account_types: this.transfromToResponse(accountTypes, ['label'], req),
});
} catch (error) {
next(error);
}
}
}

View File

@@ -0,0 +1,528 @@
import { Router, Request, Response, NextFunction } from 'express';
import { check, param, query } from 'express-validator';
import { Service, Inject } from 'typedi';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
import BaseController from '@/api/controllers/BaseController';
import {
AbilitySubject,
AccountAction,
IAccountDTO,
IAccountsStructureType,
} from '@/interfaces';
import { ServiceError } from '@/exceptions';
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
import { DATATYPES_LENGTH } from '@/data/DataTypes';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AccountsApplication } from '@/services/Accounts/AccountsApplication';
import { MAX_ACCOUNTS_CHART_DEPTH } from 'services/Accounts/constants';
@Service()
export default class AccountsController extends BaseController {
@Inject()
private accountsApplication: AccountsApplication;
@Inject()
private dynamicListService: DynamicListingService;
/**
* Router constructor method.
*/
router() {
const router = Router();
router.get(
'/transactions',
CheckPolicies(AccountAction.VIEW, AbilitySubject.Account),
[query('account_id').optional().isInt().toInt()],
this.asyncMiddleware(this.accountTransactions.bind(this)),
this.catchServiceErrors
);
router.post(
'/:id/activate',
CheckPolicies(AccountAction.EDIT, AbilitySubject.Account),
[...this.accountParamSchema],
asyncMiddleware(this.activateAccount.bind(this)),
this.catchServiceErrors
);
router.post(
'/:id/inactivate',
CheckPolicies(AccountAction.EDIT, AbilitySubject.Account),
[...this.accountParamSchema],
asyncMiddleware(this.inactivateAccount.bind(this)),
this.catchServiceErrors
);
router.post(
'/:id',
CheckPolicies(AccountAction.EDIT, AbilitySubject.Account),
[...this.editAccountDTOSchema, ...this.accountParamSchema],
this.validationResult,
asyncMiddleware(this.editAccount.bind(this)),
this.catchServiceErrors
);
router.post(
'/',
CheckPolicies(AccountAction.CREATE, AbilitySubject.Account),
[...this.createAccountDTOSchema],
this.validationResult,
asyncMiddleware(this.newAccount.bind(this)),
this.catchServiceErrors
);
router.get(
'/:id',
CheckPolicies(AccountAction.VIEW, AbilitySubject.Account),
[...this.accountParamSchema],
this.validationResult,
asyncMiddleware(this.getAccount.bind(this)),
this.catchServiceErrors
);
router.get(
'/',
CheckPolicies(AccountAction.VIEW, AbilitySubject.Account),
[...this.accountsListSchema],
this.validationResult,
asyncMiddleware(this.getAccountsList.bind(this)),
this.dynamicListService.handlerErrorsToResponse,
this.catchServiceErrors
);
router.delete(
'/:id',
CheckPolicies(AccountAction.DELETE, AbilitySubject.Account),
[...this.accountParamSchema],
this.validationResult,
asyncMiddleware(this.deleteAccount.bind(this)),
this.catchServiceErrors
);
return router;
}
/**
* Create account DTO Schema validation.
*/
get createAccountDTOSchema() {
return [
check('name')
.exists()
.isLength({ min: 3, max: DATATYPES_LENGTH.STRING })
.trim()
.escape(),
check('code')
.optional({ nullable: true })
.isLength({ min: 3, max: 6 })
.trim()
.escape(),
check('currency_code').optional(),
check('account_type')
.exists()
.isLength({ min: 3, max: DATATYPES_LENGTH.STRING })
.trim()
.escape(),
check('description')
.optional({ nullable: true })
.isLength({ max: DATATYPES_LENGTH.TEXT })
.trim()
.escape(),
check('parent_account_id')
.optional({ nullable: true })
.isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 })
.toInt(),
];
}
/**
* Account DTO Schema validation.
*/
get editAccountDTOSchema() {
return [
check('name')
.exists()
.isLength({ min: 3, max: DATATYPES_LENGTH.STRING })
.trim()
.escape(),
check('code')
.optional({ nullable: true })
.isLength({ min: 3, max: 6 })
.trim()
.escape(),
check('account_type')
.exists()
.isLength({ min: 3, max: DATATYPES_LENGTH.STRING })
.trim()
.escape(),
check('description')
.optional({ nullable: true })
.isLength({ max: DATATYPES_LENGTH.TEXT })
.trim()
.escape(),
check('parent_account_id')
.optional({ nullable: true })
.isInt({ min: 0, max: DATATYPES_LENGTH.INT_10 })
.toInt(),
];
}
get accountParamSchema() {
return [param('id').exists().isNumeric().toInt()];
}
/**
* Accounts list validation schema.
*/
get accountsListSchema() {
return [
query('view_slug').optional({ nullable: true }).isString().trim(),
query('stringified_filter_roles').optional().isJSON(),
query('column_sort_by').optional(),
query('sort_order').optional().isIn(['desc', 'asc']),
query('inactive_mode').optional().isBoolean().toBoolean(),
query('search_keyword').optional({ nullable: true }).isString().trim(),
query('structure')
.optional()
.isString()
.isIn([IAccountsStructureType.Tree, IAccountsStructureType.Flat]),
];
}
get closingAccountSchema() {
return [
check('to_account_id').exists().isNumeric().toInt(),
check('delete_after_closing').exists().isBoolean(),
];
}
/**
* Creates a new account.
* @param {Request} req -
* @param {Response} res -
* @param {NextFunction} next -
*/
async newAccount(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const accountDTO: IAccountDTO = this.matchedBodyData(req);
try {
const account = await this.accountsApplication.createAccount(
tenantId,
accountDTO
);
return res.status(200).send({
id: account.id,
message: 'The account has been created successfully.',
});
} catch (error) {
next(error);
}
}
/**
* Edit account details.
* @param {Request} req
* @param {Response} res
* @return {Response}
*/
async editAccount(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: accountId } = req.params;
const accountDTO: IAccountDTO = this.matchedBodyData(req);
try {
const account = await this.accountsApplication.editAccount(
tenantId,
accountId,
accountDTO
);
return res.status(200).send({
id: account.id,
message: 'The account has been edited successfully',
});
} catch (error) {
next(error);
}
}
/**
* Get details of the given account.
* @param {Request} req
* @param {Response} res
* @return {Response}
*/
async getAccount(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const { id: accountId } = req.params;
try {
const account = await this.accountsApplication.getAccount(
tenantId,
accountId
);
return res
.status(200)
.send({ account: this.transfromToResponse(account) });
} catch (error) {
next(error);
}
}
/**
* Delete the given account.
* @param {Request} req
* @param {Response} res
* @return {Response}
*/
async deleteAccount(req: Request, res: Response, next: NextFunction) {
const { id: accountId } = req.params;
const { tenantId } = req;
try {
await this.accountsApplication.deleteAccount(tenantId, accountId);
return res.status(200).send({
id: accountId,
message: 'The deleted account has been deleted successfully.',
});
} catch (error) {
next(error);
}
}
/**
* Activate the given account.
* @param {Response} res -
* @param {Request} req -
* @return {Response}
*/
async activateAccount(req: Request, res: Response, next: Function) {
const { id: accountId } = req.params;
const { tenantId } = req;
try {
await this.accountsApplication.activateAccount(tenantId, accountId);
return res.status(200).send({
id: accountId,
message: 'The account has been activated successfully.',
});
} catch (error) {
next(error);
}
}
/**
* Inactive the given account.
* @param {Response} res -
* @param {Request} req -
* @return {Response}
*/
async inactivateAccount(req: Request, res: Response, next: Function) {
const { id: accountId } = req.params;
const { tenantId } = req;
try {
await this.accountsApplication.inactivateAccount(tenantId, accountId);
return res.status(200).send({
id: accountId,
message: 'The account has been inactivated successfully.',
});
} catch (error) {
next(error);
}
}
/**
* Retrieve accounts datatable list.
* @param {Request} req
* @param {Response} res
* @param {Response}
*/
public async getAccountsList(
req: Request,
res: Response,
next: NextFunction
) {
const { tenantId } = req;
// Filter query.
const filter = {
sortOrder: 'desc',
columnSortBy: 'created_at',
inactiveMode: false,
structure: IAccountsStructureType.Tree,
...this.matchedQueryData(req),
};
try {
const { accounts, filterMeta } =
await this.accountsApplication.getAccounts(tenantId, filter);
return res.status(200).send({
accounts: this.transfromToResponse(accounts, 'accountTypeLabel', req),
filter_meta: this.transfromToResponse(filterMeta),
});
} catch (error) {
next(error);
}
}
/**
* Retrieve accounts transactions list.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
async accountTransactions(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
const transactionsFilter = this.matchedQueryData(req);
try {
const transactions =
await this.accountsApplication.getAccountsTransactions(
tenantId,
transactionsFilter
);
return res.status(200).send({
transactions: this.transfromToResponse(transactions),
});
} catch (error) {
next(error);
}
}
/**
* Transforms service errors to response.
* @param {Error}
* @param {Request} req
* @param {Response} res
* @param {ServiceError} error
*/
private catchServiceErrors(
error,
req: Request,
res: Response,
next: NextFunction
) {
if (error instanceof ServiceError) {
if (error.errorType === 'account_not_found') {
return res.boom.notFound('The given account not found.', {
errors: [{ type: 'ACCOUNT.NOT.FOUND', code: 100 }],
});
}
if (error.errorType === 'account_name_not_unqiue') {
return res.boom.badRequest('The given account not unique.', {
errors: [{ type: 'ACCOUNT.NAME.NOT.UNIQUE', code: 150 }],
});
}
if (error.errorType === 'account_type_not_found') {
return res.boom.badRequest('The given account type not found.', {
errors: [{ type: 'ACCOUNT_TYPE_NOT_FOUND', code: 200 }],
});
}
if (error.errorType === 'account_type_not_allowed_to_changed') {
return res.boom.badRequest(
'Not allowed to change account type of the account.',
{
errors: [{ type: 'NOT.ALLOWED.TO.CHANGE.ACCOUNT.TYPE', code: 300 }],
}
);
}
if (error.errorType === 'parent_account_not_found') {
return res.boom.badRequest('The parent account not found.', {
errors: [{ type: 'PARENT_ACCOUNT_NOT_FOUND', code: 400 }],
});
}
if (error.errorType === 'parent_has_different_type') {
return res.boom.badRequest('The parent account has different type.', {
errors: [
{ type: 'PARENT.ACCOUNT.HAS.DIFFERENT.ACCOUNT.TYPE', code: 500 },
],
});
}
if (error.errorType === 'account_code_not_unique') {
return res.boom.badRequest('The given account code is not unique.', {
errors: [{ type: 'NOT_UNIQUE_CODE', code: 600 }],
});
}
if (error.errorType === 'account_has_associated_transactions') {
return res.boom.badRequest(
'You could not delete account has associated transactions.',
{
errors: [
{ type: 'ACCOUNT.HAS.ASSOCIATED.TRANSACTIONS', code: 800 },
],
}
);
}
if (error.errorType === 'account_predefined') {
return res.boom.badRequest('You could not delete predefined account', {
errors: [{ type: 'ACCOUNT.PREDEFINED', code: 900 }],
});
}
if (error.errorType === 'accounts_not_found') {
return res.boom.notFound('Some of the given accounts not found.', {
errors: [{ type: 'SOME.ACCOUNTS.NOT_FOUND', code: 1000 }],
});
}
if (error.errorType === 'predefined_accounts') {
return res.boom.badRequest(
'Some of the given accounts are predefined.',
{ errors: [{ type: 'ACCOUNTS_PREDEFINED', code: 1100 }] }
);
}
if (error.errorType === 'close_account_and_to_account_not_same_type') {
return res.boom.badRequest(
'The close account has different root type with to account.',
{
errors: [
{
type: 'CLOSE_ACCOUNT_AND_TO_ACCOUNT_NOT_SAME_TYPE',
code: 1200,
},
],
}
);
}
if (error.errorType === 'ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY') {
return res.boom.badRequest(
'The given account type does not support multi-currency.',
{
errors: [
{ type: 'ACCOUNT_TYPE_NOT_SUPPORTS_MULTI_CURRENCY', code: 1300 },
],
}
);
}
if (error.errorType === 'ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT') {
return res.boom.badRequest(
'You could not add account has currency different on the parent account.',
{
errors: [
{ type: 'ACCOUNT_CURRENCY_NOT_SAME_PARENT_ACCOUNT', code: 1400 },
],
}
);
}
if (error.errorType === 'PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL') {
return res.boom.badRequest(
'The parent account exceeded the depth level of accounts chart.',
{
errors: [
{
type: 'PARENT_ACCOUNT_EXCEEDED_THE_DEPTH_LEVEL',
code: 1500,
data: {
maxDepth: MAX_ACCOUNTS_CHART_DEPTH,
},
},
],
}
);
}
}
next(error);
}
}

View File

@@ -0,0 +1,24 @@
import { Router } from 'express';
import basicAuth from 'express-basic-auth';
import agendash from 'agendash';
import { Container } from 'typedi';
import config from '@/config';
export default class AgendashController {
static router() {
const router = Router();
const agendaInstance = Container.get('agenda');
router.use(
'/dash',
basicAuth({
users: {
[config.agendash.user]: config.agendash.password,
},
challenge: true,
}),
agendash(agendaInstance)
);
return router;
}
}

View File

@@ -0,0 +1,295 @@
import { Request, Response, Router } from 'express';
import { check, ValidationChain } from 'express-validator';
import { Service, Inject } from 'typedi';
import BaseController from '@/api/controllers/BaseController';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
import { ILoginDTO, ISystemUser, IRegisterDTO } from '@/interfaces';
import { ServiceError, ServiceErrors } from '@/exceptions';
import { DATATYPES_LENGTH } from '@/data/DataTypes';
import LoginThrottlerMiddleware from '@/api/middleware/LoginThrottlerMiddleware';
import AuthenticationApplication from '@/services/Authentication/AuthApplication';
@Service()
export default class AuthenticationController extends BaseController {
@Inject()
private authApplication: AuthenticationApplication;
/**
* Constructor method.
*/
public router() {
const router = Router();
router.post(
'/login',
this.loginSchema,
this.validationResult,
LoginThrottlerMiddleware,
asyncMiddleware(this.login.bind(this)),
this.handlerErrors
);
router.post(
'/register',
this.registerSchema,
this.validationResult,
asyncMiddleware(this.register.bind(this)),
this.handlerErrors
);
router.post(
'/send_reset_password',
this.sendResetPasswordSchema,
this.validationResult,
asyncMiddleware(this.sendResetPassword.bind(this)),
this.handlerErrors
);
router.post(
'/reset/:token',
this.resetPasswordSchema,
this.validationResult,
asyncMiddleware(this.resetPassword.bind(this)),
this.handlerErrors
);
router.get('/meta', asyncMiddleware(this.getAuthMeta.bind(this)));
return router;
}
/**
* Login validation schema.
* @returns {ValidationChain[]}
*/
private get loginSchema(): ValidationChain[] {
return [
check('crediential').exists().isEmail(),
check('password').exists().isLength({ min: 5 }),
];
}
/**
* Register validation schema.
* @returns {ValidationChain[]}
*/
private get registerSchema(): ValidationChain[] {
return [
check('first_name')
.exists()
.isString()
.trim()
.escape()
.isLength({ max: DATATYPES_LENGTH.STRING }),
check('last_name')
.exists()
.isString()
.trim()
.escape()
.isLength({ max: DATATYPES_LENGTH.STRING }),
check('email')
.exists()
.isString()
.isEmail()
.trim()
.escape()
.isLength({ max: DATATYPES_LENGTH.STRING }),
check('password')
.exists()
.isString()
.trim()
.escape()
.isLength({ max: DATATYPES_LENGTH.STRING }),
];
}
/**
* Reset password schema.
* @returns {ValidationChain[]}
*/
private get resetPasswordSchema(): ValidationChain[] {
return [
check('password')
.exists()
.isLength({ min: 5 })
.custom((value, { req }) => {
if (value !== req.body.confirm_password) {
throw new Error("Passwords don't match");
} else {
return value;
}
}),
];
}
/**
* Send reset password validation schema.
* @returns {ValidationChain[]}
*/
private get sendResetPasswordSchema(): ValidationChain[] {
return [check('email').exists().isEmail().trim().escape()];
}
/**
* Handle user login.
* @param {Request} req
* @param {Response} res
*/
private async login(req: Request, res: Response, next: Function): Response {
const userDTO: ILoginDTO = this.matchedBodyData(req);
try {
const { token, user, tenant } = await this.authApplication.signIn(
userDTO.crediential,
userDTO.password
);
return res.status(200).send({ token, user, tenant });
} catch (error) {
next(error);
}
}
/**
* Organization register handler.
* @param {Request} req
* @param {Response} res
*/
private async register(req: Request, res: Response, next: Function) {
const registerDTO: IRegisterDTO = this.matchedBodyData(req);
try {
await this.authApplication.signUp(registerDTO);
return res.status(200).send({
type: 'success',
code: 'REGISTER.SUCCESS',
message: 'Register organization has been success.',
});
} catch (error) {
next(error);
}
}
/**
* Send reset password handler
* @param {Request} req
* @param {Response} res
*/
private async sendResetPassword(req: Request, res: Response, next: Function) {
const { email } = this.matchedBodyData(req);
try {
await this.authApplication.sendResetPassword(email);
return res.status(200).send({
code: 'SEND_RESET_PASSWORD_SUCCESS',
message: 'The reset password message has been sent successfully.',
});
} catch (error) {
if (error instanceof ServiceError) {
}
next(error);
}
}
/**
* Reset password handler
* @param {Request} req
* @param {Response} res
*/
private async resetPassword(req: Request, res: Response, next: Function) {
const { token } = req.params;
const { password } = req.body;
try {
await this.authApplication.resetPassword(token, password);
return res.status(200).send({
type: 'RESET_PASSWORD_SUCCESS',
message: 'The password has been reset successfully.',
});
} catch (error) {
next(error);
}
}
/**
* Retrieves the authentication meta for SPA.
* @param {Request} req
* @param {Response} res
* @param {Function} next
* @returns {Response|void}
*/
private async getAuthMeta(req: Request, res: Response, next: Function) {
try {
const meta = await this.authApplication.getAuthMeta();
return res.status(200).send({ meta });
} catch (error) {
next(error);
}
}
/**
* Handles the service errors.
*/
private handlerErrors(error, req: Request, res: Response, next: Function) {
if (error instanceof ServiceError) {
if (
['INVALID_DETAILS', 'invalid_password'].indexOf(error.errorType) !== -1
) {
return res.boom.badRequest(null, {
errors: [{ type: 'INVALID_DETAILS', code: 100 }],
});
}
if (error.errorType === 'USER_INACTIVE') {
return res.boom.badRequest(null, {
errors: [{ type: 'USER_INACTIVE', code: 200 }],
});
}
if (
error.errorType === 'TOKEN_INVALID' ||
error.errorType === 'TOKEN_EXPIRED'
) {
return res.boom.badRequest(null, {
errors: [{ type: 'TOKEN_INVALID', code: 300 }],
});
}
if (error.errorType === 'USER_NOT_FOUND') {
return res.boom.badRequest(null, {
errors: [{ type: 'USER_NOT_FOUND', code: 400 }],
});
}
if (error.errorType === 'EMAIL_NOT_FOUND') {
return res.status(400).send({
errors: [{ type: 'EMAIL.NOT.REGISTERED', code: 500 }],
});
}
if (error.errorType === 'EMAIL_EXISTS') {
return res.status(400).send({
errors: [{ type: 'EMAIL.EXISTS', code: 600 }],
});
}
if (error.errorType === 'SIGNUP_RESTRICTED') {
return res.status(400).send({
errors: [
{
type: 'SIGNUP_RESTRICTED',
message:
'Sign-up is restricted no one can sign-up to the system.',
code: 700,
},
],
});
}
if (error.errorType === 'SIGNUP_RESTRICTED_NOT_ALLOWED') {
return res.status(400).send({
errors: [
{
type: 'SIGNUP_RESTRICTED_NOT_ALLOWED',
message:
'Sign-up is restricted the given email address is not allowed to sign-up.',
code: 710,
},
],
});
}
}
next(error);
}
}

View File

@@ -0,0 +1,140 @@
import { Response, Request, NextFunction } from 'express';
import { matchedData, validationResult } from 'express-validator';
import accepts from 'accepts';
import { isArray, drop, first, camelCase, snakeCase, omit, set, get } from 'lodash';
import { mapKeysDeep } from 'utils';
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
export default class BaseController {
/**
* Converts plain object keys to cameCase style.
* @param {Object} data
*/
protected dataToCamelCase(data) {
return mapKeysDeep(data, (v, k) => camelCase(k));
}
/**
* Matches the body data from validation schema.
* @param {Request} req
* @param options
*/
protected matchedBodyData(req: Request, options: any = {}) {
const data = matchedData(req, {
locations: ['body'],
includeOptionals: true,
...omit(options, ['locations']), // override any propery except locations.
});
return this.dataToCamelCase(data);
}
/**
* Matches the query data from validation schema.
* @param {Request} req
*/
protected matchedQueryData(req: Request) {
const data = matchedData(req, {
locations: ['query'],
});
return this.dataToCamelCase(data);
}
/**
* Validate validation schema middleware.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
protected validationResult(req: Request, res: Response, next: NextFunction) {
const validationErrors = validationResult(req);
if (!validationErrors.isEmpty()) {
return res.boom.badData(null, {
code: 'validation_error',
...validationErrors,
});
}
next();
}
/**
* Sets localization to response object by the given path.
* @param {Response} response -
* @param {string} path -
* @param {Request} req -
*/
private setLocalizationByPath(
response: any,
path: string,
req: Request,
) {
const DOT = '.';
if (isArray(response)) {
response.forEach((va) => {
const currentPath = first(path.split(DOT));
const value = get(va, currentPath);
if (isArray(value)) {
const nextPath = drop(path.split(DOT)).join(DOT);
this.setLocalizationByPath(value, nextPath, req);
} else {
set(va, path, req.__(value));
}
})
} else {
const value = get(response, path);
set(response, path, req.__(value));
}
}
/**
* Transform the given data to response.
* @param {any} data
*/
protected transfromToResponse(
data: any,
translatable?: string | string[],
req?: Request
) {
const response = mapKeysDeep(data, (v, k) => snakeCase(k));
if (translatable) {
const translatables = Array.isArray(translatable)
? translatable
: [translatable];
translatables.forEach((path) => {
this.setLocalizationByPath(response, path, req);
});
}
return response;
}
/**
* Async middleware.
* @param {function} callback
*/
protected asyncMiddleware(callback) {
return asyncMiddleware(callback);
}
/**
*
* @param {Request} req
* @returns
*/
protected accepts(req) {
return accepts(req);
}
/**
*
* @param {Request} req
* @param {string[]} types
* @returns {string}
*/
protected acceptTypes(req: Request, types: string[]) {
return this.accepts(req).types(types);
}
}

View File

@@ -0,0 +1,335 @@
import { Service, Inject } from 'typedi';
import { Request, Response, Router, NextFunction } from 'express';
import { check, param } from 'express-validator';
import BaseController from '@/api/controllers/BaseController';
import { Features, ICreateBranchDTO, IEditBranchDTO } from '@/interfaces';
import { BranchesApplication } from '@/services/Branches/BranchesApplication';
import { ServiceError } from '@/exceptions';
import { FeatureActivationGuard } from '@/api/middleware/FeatureActivationGuard';
@Service()
export class BranchesController extends BaseController {
@Inject()
branchesApplication: BranchesApplication;
/**
* Branches routes.
* @returns {Router}
*/
router() {
const router = Router();
router.post(
'/activate',
[],
this.validationResult,
this.asyncMiddleware(this.activateBranches),
this.handlerServiceErrors
);
router.post(
'/',
FeatureActivationGuard(Features.BRANCHES),
[
check('name').exists(),
check('code').optional({ nullable: true }),
check('address').optional({ nullable: true }),
check('city').optional({ nullable: true }),
check('country').optional({ nullable: true }),
check('phone_number').optional({ nullable: true }),
check('email').optional({ nullable: true }).isEmail(),
check('website').optional({ nullable: true }).isURL(),
],
this.validationResult,
this.asyncMiddleware(this.createBranch),
this.handlerServiceErrors
);
router.post(
'/:id',
FeatureActivationGuard(Features.BRANCHES),
[
param('id').exists().isInt().toInt(),
check('name').exists(),
check('code').optional({ nullable: true }),
check('address').optional({ nullable: true }),
check('city').optional({ nullable: true }),
check('country').optional({ nullable: true }),
check('phone_number').optional({ nullable: true }),
check('email').optional({ nullable: true }).isEmail(),
check('website').optional({ nullable: true }).isURL(),
],
this.validationResult,
this.asyncMiddleware(this.editBranch),
this.handlerServiceErrors
);
router.post(
'/:id/mark-primary',
FeatureActivationGuard(Features.BRANCHES),
[],
this.validationResult,
this.asyncMiddleware(this.markBranchAsPrimary),
this.handlerServiceErrors
);
router.delete(
'/:id',
FeatureActivationGuard(Features.BRANCHES),
[param('id').exists().isInt().toInt()],
this.validationResult,
this.asyncMiddleware(this.deleteBranch),
this.handlerServiceErrors
);
router.get(
'/:id',
FeatureActivationGuard(Features.BRANCHES),
[param('id').exists().isInt().toInt()],
this.validationResult,
this.asyncMiddleware(this.getBranch),
this.handlerServiceErrors
);
router.get(
'/',
FeatureActivationGuard(Features.BRANCHES),
[],
this.validationResult,
this.asyncMiddleware(this.getBranches),
this.handlerServiceErrors
);
return router;
}
/**
* Creates a new branch.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public createBranch = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const createBranchDTO: ICreateBranchDTO = this.matchedBodyData(req);
try {
const branch = await this.branchesApplication.createBranch(
tenantId,
createBranchDTO
);
return res.status(200).send({
id: branch.id,
message: 'The branch has been created successfully.',
});
} catch (error) {
next(error);
}
};
/**
* Edits the given branch.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public editBranch = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { id: branchId } = req.params;
const editBranchDTO: IEditBranchDTO = this.matchedBodyData(req);
try {
const branch = await this.branchesApplication.editBranch(
tenantId,
branchId,
editBranchDTO
);
return res.status(200).send({
id: branch.id,
message: 'The branch has been edited successfully.',
});
} catch (error) {
next(error);
}
};
/**
* Deletes the given branch.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public deleteBranch = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { id: branchId } = req.params;
try {
await this.branchesApplication.deleteBranch(tenantId, branchId);
return res.status(200).send({
id: branchId,
message: 'The branch has been deleted successfully.',
});
} catch (error) {
next(error);
}
};
/**
* Retrieves specific branch.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public getBranch = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { id: branchId } = req.params;
try {
const branch = await this.branchesApplication.getBranch(
tenantId,
branchId
);
return res.status(200).send({ branch });
} catch (error) {
next(error);
}
};
/**
* Retrieves branches list.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public getBranches = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
try {
const branches = await this.branchesApplication.getBranches(tenantId);
return res.status(200).send({ branches });
} catch (error) {
next(error);
}
};
/**
* Activates the multi-branches feature.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public activateBranches = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
try {
await this.branchesApplication.activateBranches(tenantId);
return res.status(200).send({
message: 'Multi-branches feature has been activated successfully.',
});
} catch (error) {
next(error);
}
};
/**
* Marks the given branch as primary.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
* @returns {Response}
*/
public markBranchAsPrimary = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { id: branchId } = req.params;
try {
await this.branchesApplication.markBranchAsPrimary(tenantId, branchId);
return res.status(200).send({
id: branchId,
message: 'The branch has been marked as primary.',
});
} catch (error) {
next(error);
}
};
/**
* Handles service errors.
* @param {Error} error
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
private handlerServiceErrors(
error: Error,
req: Request,
res: Response,
next: NextFunction
) {
if (error instanceof ServiceError) {
if (error.errorType === 'BRANCH_NOT_FOUND') {
return res.status(400).send({
errors: [{ type: 'BRANCH_NOT_FOUND', code: 100 }],
});
}
if (error.errorType === 'MUTLI_BRANCHES_ALREADY_ACTIVATED') {
return res.status(400).send({
errors: [{ type: 'MUTLI_BRANCHES_ALREADY_ACTIVATED', code: 100 }],
});
}
if (error.errorType === 'COULD_NOT_DELETE_ONLY_BRANCH') {
return res.status(400).send({
errors: [{ type: 'COULD_NOT_DELETE_ONLY_BRANCH', code: 300 }],
});
}
if (error.errorType === 'BRANCH_CODE_NOT_UNIQUE') {
return res.status(400).send({
errors: [{ type: 'BRANCH_CODE_NOT_UNIQUE', code: 400 }],
});
}
if (error.errorType === 'BRANCH_HAS_ASSOCIATED_TRANSACTIONS') {
return res.status(400).send({
errors: [
{ type: 'BRANCH_HAS_ASSOCIATED_TRANSACTIONS', code: 500 },
],
});
}
}
next(error);
}
}

View File

@@ -0,0 +1,23 @@
import { Service, Inject, Container } from 'typedi';
import { Router } from 'express';
import CommandCashflowTransaction from './NewCashflowTransaction';
import DeleteCashflowTransaction from './DeleteCashflowTransaction';
import GetCashflowTransaction from './GetCashflowTransaction';
import GetCashflowAccounts from './GetCashflowAccounts';
@Service()
export default class CashflowController {
/**
* Constructor method.
*/
router() {
const router = Router();
router.use(Container.get(GetCashflowTransaction).router());
router.use(Container.get(GetCashflowAccounts).router());
router.use(Container.get(CommandCashflowTransaction).router());
router.use(Container.get(DeleteCashflowTransaction).router());
return router;
}
}

View File

@@ -0,0 +1,98 @@
import { Service, Inject } from 'typedi';
import { Router, Request, Response, NextFunction } from 'express';
import { param } from 'express-validator';
import BaseController from '../BaseController';
import { ServiceError } from '@/exceptions';
import DeleteCashflowTransactionService from '../../../services/Cashflow/DeleteCashflowTransactionService';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
@Service()
export default class DeleteCashflowTransaction extends BaseController {
@Inject()
deleteCashflowService: DeleteCashflowTransactionService;
/**
* Controller router.
*/
public router() {
const router = Router();
router.delete(
'/transactions/:transactionId',
CheckPolicies(CashflowAction.Delete, AbilitySubject.Cashflow),
[param('transactionId').exists().isInt().toInt()],
this.asyncMiddleware(this.deleteCashflowTransaction),
this.catchServiceErrors
);
return router;
}
/**
* Retrieve the cashflow account transactions.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
private deleteCashflowTransaction = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { transactionId } = req.params;
try {
const { oldCashflowTransaction } =
await this.deleteCashflowService.deleteCashflowTransaction(
tenantId,
transactionId
);
return res.status(200).send({
id: oldCashflowTransaction.id,
message: 'The cashflow transaction has been deleted successfully.',
});
} catch (error) {
next(error);
}
};
/**
* Catches the service errors.
* @param error
* @param req
* @param res
* @param next
* @returns
*/
private catchServiceErrors(
error,
req: Request,
res: Response,
next: NextFunction
) {
if (error instanceof ServiceError) {
if (error.errorType === 'CASHFLOW_TRANSACTION_NOT_FOUND') {
return res.boom.badRequest(
'The given cashflow transaction not found.',
{
errors: [{ type: 'CASHFLOW_TRANSACTION_NOT_FOUND', code: 100 }],
}
);
}
if (error.errorType === 'TRANSACTIONS_DATE_LOCKED') {
return res.boom.badRequest(null, {
errors: [
{
type: 'TRANSACTIONS_DATE_LOCKED',
code: 4000,
data: { ...error.payload },
},
],
});
}
}
next(error);
}
}

View File

@@ -0,0 +1,95 @@
import { Service, Inject } from 'typedi';
import { Router, Request, Response, NextFunction } from 'express';
import { param, query } from 'express-validator';
import GetCashflowAccountsService from '@/services/Cashflow/GetCashflowAccountsService';
import BaseController from '../BaseController';
import GetCashflowTransactionsService from '@/services/Cashflow/GetCashflowTransactionsService';
import { ServiceError } from '@/exceptions';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
@Service()
export default class GetCashflowAccounts extends BaseController {
@Inject()
getCashflowAccountsService: GetCashflowAccountsService;
@Inject()
getCashflowTransactionsService: GetCashflowTransactionsService;
/**
* Controller router.
*/
public router() {
const router = Router();
router.get(
'/accounts',
CheckPolicies(CashflowAction.View, AbilitySubject.Cashflow),
[
query('stringified_filter_roles').optional().isJSON(),
query('column_sort_by').optional(),
query('sort_order').optional().isIn(['desc', 'asc']),
query('inactive_mode').optional().isBoolean().toBoolean(),
query('search_keyword').optional({ nullable: true }).isString().trim(),
],
this.asyncMiddleware(this.getCashflowAccounts),
this.catchServiceErrors
);
return router;
}
/**
* Retrieve the cashflow accounts.
* @param {Request} req
* @param {Response} res
* @param {NextFunction} next
*/
private getCashflowAccounts = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
// Filter query.
const filter = {
sortOrder: 'desc',
columnSortBy: 'created_at',
inactiveMode: false,
...this.matchedQueryData(req),
};
try {
const cashflowAccounts =
await this.getCashflowAccountsService.getCashflowAccounts(
tenantId,
filter
);
return res.status(200).send({
cashflow_accounts: this.transfromToResponse(cashflowAccounts),
});
} catch (error) {
next(error);
}
};
/**
* Catches the service errors.
* @param {Error} error - Error.
* @param {Request} req - Request.
* @param {Response} res - Response.
* @param {NextFunction} next -
*/
private catchServiceErrors(
error,
req: Request,
res: Response,
next: NextFunction
) {
if (error instanceof ServiceError) {
}
next(error);
}
}

View File

@@ -0,0 +1,98 @@
import { Service, Inject } from 'typedi';
import { Router, Request, Response, NextFunction } from 'express';
import { param } from 'express-validator';
import BaseController from '../BaseController';
import GetCashflowTransactionsService from '@/services/Cashflow/GetCashflowTransactionsService';
import { ServiceError } from '@/exceptions';
import CheckPolicies from '@/api/middleware/CheckPolicies';
import { AbilitySubject, CashflowAction } from '@/interfaces';
@Service()
export default class GetCashflowAccounts extends BaseController {
@Inject()
getCashflowTransactionsService: GetCashflowTransactionsService;
/**
* Controller router.
*/
public router() {
const router = Router();
router.get(
'/transactions/:transactionId',
CheckPolicies(CashflowAction.View, AbilitySubject.Cashflow),
[param('transactionId').exists().isInt().toInt()],
this.asyncMiddleware(this.getCashflowTransaction),
this.catchServiceErrors
);
return router;
}
/**
* Retrieve the cashflow account transactions.
* @param {Request} req - Request object.
* @param {Response} res - Response object.
* @param {NextFunction} next
*/
private getCashflowTransaction = async (
req: Request,
res: Response,
next: NextFunction
) => {
const { tenantId } = req;
const { transactionId } = req.params;
try {
const cashflowTransaction =
await this.getCashflowTransactionsService.getCashflowTransaction(
tenantId,
transactionId
);
return res.status(200).send({
cashflow_transaction: this.transfromToResponse(cashflowTransaction),
});
} catch (error) {
next(error);
}
};
/**
* Catches the service errors.
* @param {Error} error - Error.
* @param {Request} req - Request.
* @param {Response} res - Response.
* @param {NextFunction} next -
*/
private catchServiceErrors(
error,
req: Request,
res: Response,
next: NextFunction
) {
if (error instanceof ServiceError) {
if (error.errorType === 'CASHFLOW_TRANSACTION_NOT_FOUND') {
return res.boom.badRequest(
'The given cashflow tranasction not found.',
{
errors: [{ type: 'CASHFLOW_TRANSACTION_NOT_FOUND', code: 200 }],
}
);
}
if (error.errorType === 'ACCOUNT_ID_HAS_INVALID_TYPE') {
return res.boom.badRequest(
'The given cashflow account has invalid type.',
{
errors: [{ type: 'ACCOUNT_ID_HAS_INVALID_TYPE', code: 300 }],
}
);
}
if (error.errorType === 'ACCOUNT_NOT_FOUND') {
return res.boom.badRequest('The given account not found.', {
errors: [{ type: 'ACCOUNT_NOT_FOUND', code: 400 }],
});
}
}
next(error);
}
}

Some files were not shown because too many files have changed in this diff Show More