mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 06:10:31 +00:00
Compare commits
62 Commits
api-rate-e
...
fix-spelli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
508054b594 | ||
|
|
34efd58f34 | ||
|
|
f898acdb8b | ||
|
|
f7b53692f5 | ||
|
|
b665d05526 | ||
|
|
de5300b186 | ||
|
|
abc5631ac2 | ||
|
|
9e7b906c86 | ||
|
|
d5decbbd0b | ||
|
|
fbeb489128 | ||
|
|
5bf8a9e0ff | ||
|
|
68fa5cf5c5 | ||
|
|
b1662c3175 | ||
|
|
0fcee0eaa7 | ||
|
|
5b2be2ac19 | ||
|
|
5bb80fde34 | ||
|
|
58f90a0bcd | ||
|
|
e1a3510f0b | ||
|
|
172eea0ad1 | ||
|
|
74c4418549 | ||
|
|
6b6e19f53b | ||
|
|
01f7effc71 | ||
|
|
26c6ca9e36 | ||
|
|
ffef627dc3 | ||
|
|
f105980f08 | ||
|
|
efad38fcdc | ||
|
|
d84568e43a | ||
|
|
ed6517c0e1 | ||
|
|
0fd256c801 | ||
|
|
f0285560aa | ||
|
|
7a33f79268 | ||
|
|
ef5ef647d4 | ||
|
|
ce62a0524c | ||
|
|
278c8a01c5 | ||
|
|
f22dc9a18b | ||
|
|
b224a2c313 | ||
|
|
d4a933ef18 | ||
|
|
1411f64cf6 | ||
|
|
2c9739ac91 | ||
|
|
e214b86a62 | ||
|
|
b01b7010c0 | ||
|
|
e7cd035206 | ||
|
|
f82b78c4eb | ||
|
|
847b4380be | ||
|
|
271011cb3c | ||
|
|
b6d8766173 | ||
|
|
efffdc021b | ||
|
|
01dd0ffb8c | ||
|
|
d910985b37 | ||
|
|
d5799bf720 | ||
|
|
56cc1da034 | ||
|
|
ef9b4ebad6 | ||
|
|
29af788dcd | ||
|
|
b2510145dc | ||
|
|
5f3a309a8f | ||
|
|
e2fdc13b3e | ||
|
|
34cd21cced | ||
|
|
0e589ace82 | ||
|
|
f46f595e96 | ||
|
|
53ef940b05 | ||
|
|
65495775d4 | ||
|
|
1cf11e020f |
@@ -42,6 +42,24 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"bug"
|
"bug"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "suhaibaffan",
|
||||||
|
"name": "Suhaib Affan",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/18115937?v=4",
|
||||||
|
"profile": "https://github.com/suhaibaffan",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "KalliopiPliogka",
|
||||||
|
"name": "Kalliopi Pliogka",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/81677549?v=4",
|
||||||
|
"profile": "https://github.com/KalliopiPliogka",
|
||||||
|
"contributions": [
|
||||||
|
"bug"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
All notable changes to Bigcapital server-side will be in this file.
|
All notable changes to Bigcapital server-side will be in this file.
|
||||||
|
|
||||||
|
# [0.9.11] - 23-07-2023
|
||||||
|
|
||||||
|
* added: Restart policy to docker compose files. by @suhaibaffan in https://github.com/bigcapitalhq/bigcapital/pull/198
|
||||||
|
* fix: Expose and expand the rate limit to the env variables by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/195
|
||||||
|
|
||||||
|
# [0.9.10] - 18-07-2023
|
||||||
|
|
||||||
|
* feat(e2e): E2E onboarding process by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/176
|
||||||
|
* fix(webapp): Show loading message of cost computing job on financial reports by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/196
|
||||||
|
* fix(webapp): Change the currency code of sales and purchases transactions with foreign contacts.
|
||||||
|
|
||||||
# [0.9.9] - 28-06-2023
|
# [0.9.9] - 28-06-2023
|
||||||
|
|
||||||
* refactor: Customer and vendor select component by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/171
|
* refactor: Customer and vendor select component by @abouolia in https://github.com/bigcapitalhq/bigcapital/pull/171
|
||||||
@@ -86,7 +97,7 @@ All notable changes to Bigcapital server-side will be in this file.
|
|||||||
- fix: delete invoice transaction issue.
|
- fix: delete invoice transaction issue.
|
||||||
|
|
||||||
`@bigcapital/webapp`
|
`@bigcapital/webapp`
|
||||||
- fix: general, accoutant and items preferences.
|
- fix: general, accountant and items preferences.
|
||||||
- fix: auto-increment sale invoices, estiamtes, credit notes, payments and manual journals.
|
- fix: auto-increment sale invoices, estiamtes, credit notes, payments and manual journals.
|
||||||
- refactor: the setup organization form to use binded Formik components.
|
- refactor: the setup organization form to use binded Formik components.
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Please read through this document before submitting any issues or pull requests
|
|||||||
## Sections
|
## Sections
|
||||||
|
|
||||||
- [General Instructions](#general-instructions)
|
- [General Instructions](#general-instructions)
|
||||||
|
- [Local Setup Prerequisites](#local-setup-prerequisites)
|
||||||
- [Contribute to Backend](#contribute-to-backend)
|
- [Contribute to Backend](#contribute-to-backend)
|
||||||
- [Contribute to Frontend](#contribute-to-frontend)
|
- [Contribute to Frontend](#contribute-to-frontend)
|
||||||
- [Other Ways to Contribute](#other-ways-to-contribute)
|
- [Other Ways to Contribute](#other-ways-to-contribute)
|
||||||
@@ -31,9 +32,18 @@ Contributions via pull requests are much appreciated. Once the approach is agree
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Local Setup Prerequisites
|
||||||
|
- The application currently supports **Node.js v14.x**. Please ensure that you are using this version of Node.js when developing. (use [nvm](https://github.com/nvm-sh/nvm#installing-and-updating) to switch between node versions)
|
||||||
|
|
||||||
## Contribute to Backend
|
## Contribute to Backend
|
||||||
|
|
||||||
- Clone the `bigcapital` repository and `cd` into `bigcapital` directory.
|
- Clone the `bigcapital` repository and `cd` into `bigcapital` directory.
|
||||||
|
- Create `.env` file by copying `.env.example` file to `.env`. (The ``.env.example`` file has all the necessary values of variables to start development directly).
|
||||||
|
|
||||||
|
```
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
- 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.
|
- 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.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -69,9 +69,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abouolia"><img src="https://avatars.githubusercontent.com/u/2197422?v=4?s=100" width="100px;" alt="Ahmed Bouhuolia"/><br /><sub><b>Ahmed Bouhuolia</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=abouolia" title="Code">💻</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/abouolia"><img src="https://avatars.githubusercontent.com/u/2197422?v=4?s=100" width="100px;" alt="Ahmed Bouhuolia"/><br /><sub><b>Ahmed Bouhuolia</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=abouolia" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elforjani13"><img src="https://avatars.githubusercontent.com/u/39470382?v=4?s=100" width="100px;" alt="ElforJani13"/><br /><sub><b>ElforJani13</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=elforjani13" title="Code">💻</a></td>
|
|
||||||
<td align="center" valign="top" width="14.28%"><a href="http://ameir.net"><img src="https://avatars.githubusercontent.com/u/374330?v=4?s=100" width="100px;" alt="Ameir Abdeldayem"/><br /><sub><b>Ameir Abdeldayem</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aameir" title="Bug reports">🐛</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="http://ameir.net"><img src="https://avatars.githubusercontent.com/u/374330?v=4?s=100" width="100px;" alt="Ameir Abdeldayem"/><br /><sub><b>Ameir Abdeldayem</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Aameir" title="Bug reports">🐛</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/elforjani13"><img src="https://avatars.githubusercontent.com/u/39470382?v=4?s=100" width="100px;" alt="ElforJani13"/><br /><sub><b>ElforJani13</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=elforjani13" title="Code">💻</a></td>
|
||||||
<td align="center" valign="top" width="14.28%"><a href="https://scheibling.se"><img src="https://avatars.githubusercontent.com/u/24367830?v=4?s=100" width="100px;" alt="Lars Scheibling"/><br /><sub><b>Lars Scheibling</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Ascheibling" title="Bug reports">🐛</a></td>
|
<td align="center" valign="top" width="14.28%"><a href="https://scheibling.se"><img src="https://avatars.githubusercontent.com/u/24367830?v=4?s=100" width="100px;" alt="Lars Scheibling"/><br /><sub><b>Lars Scheibling</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3Ascheibling" title="Bug reports">🐛</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/suhaibaffan"><img src="https://avatars.githubusercontent.com/u/18115937?v=4?s=100" width="100px;" alt="Suhaib Affan"/><br /><sub><b>Suhaib Affan</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/commits?author=suhaibaffan" title="Code">💻</a></td>
|
||||||
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/KalliopiPliogka"><img src="https://avatars.githubusercontent.com/u/81677549?v=4?s=100" width="100px;" alt="Kalliopi Pliogka"/><br /><sub><b>Kalliopi Pliogka</b></sub></a><br /><a href="https://github.com/bigcapitalhq/bigcapital/issues?q=author%3AKalliopiPliogka" title="Bug reports">🐛</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -21,10 +21,16 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- server
|
- server
|
||||||
- webapp
|
- webapp
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
|
|
||||||
webapp:
|
webapp:
|
||||||
container_name: bigcapital-webapp
|
container_name: bigcapital-webapp
|
||||||
image: ghcr.io/bigcapitalhq/webapp:latest
|
image: ghcr.io/bigcapitalhq/webapp:latest
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
|
|
||||||
server:
|
server:
|
||||||
container_name: bigcapital-server
|
container_name: bigcapital-server
|
||||||
@@ -37,6 +43,9 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- mongo
|
- mongo
|
||||||
- redis
|
- redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
# Mail
|
# Mail
|
||||||
- MAIL_HOST=${MAIL_HOST}
|
- MAIL_HOST=${MAIL_HOST}
|
||||||
@@ -93,6 +102,9 @@ services:
|
|||||||
|
|
||||||
mysql:
|
mysql:
|
||||||
container_name: bigcapital-mysql
|
container_name: bigcapital-mysql
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
build:
|
build:
|
||||||
context: ./docker/mariadb
|
context: ./docker/mariadb
|
||||||
environment:
|
environment:
|
||||||
@@ -107,6 +119,9 @@ services:
|
|||||||
|
|
||||||
mongo:
|
mongo:
|
||||||
container_name: bigcapital-mongo
|
container_name: bigcapital-mongo
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
build: ./docker/mongo
|
build: ./docker/mongo
|
||||||
expose:
|
expose:
|
||||||
- '27017'
|
- '27017'
|
||||||
@@ -115,6 +130,9 @@ services:
|
|||||||
|
|
||||||
redis:
|
redis:
|
||||||
container_name: bigcapital-redis
|
container_name: bigcapital-redis
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
build:
|
build:
|
||||||
context: ./docker/redis
|
context: ./docker/redis
|
||||||
expose:
|
expose:
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ services:
|
|||||||
- '3306'
|
- '3306'
|
||||||
ports:
|
ports:
|
||||||
- '3306:3306'
|
- '3306:3306'
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
|
|
||||||
mongo:
|
mongo:
|
||||||
build: ./docker/mongo
|
build: ./docker/mongo
|
||||||
@@ -29,6 +32,9 @@ services:
|
|||||||
- mongo:/var/lib/mongodb
|
- mongo:/var/lib/mongodb
|
||||||
ports:
|
ports:
|
||||||
- '27017:27017'
|
- '27017:27017'
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
build:
|
build:
|
||||||
@@ -37,6 +43,9 @@ services:
|
|||||||
- "6379"
|
- "6379"
|
||||||
volumes:
|
volumes:
|
||||||
- redis:/data
|
- redis:/data
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: unless-stopped
|
||||||
|
|
||||||
# Volumes
|
# Volumes
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
7
e2e/items.spec.ts
Normal file
7
e2e/items.spec.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { test, expect, Page } from '@playwright/test';
|
||||||
|
|
||||||
|
test.describe('item', () => {
|
||||||
|
test('should validate all required fields.', () => {});
|
||||||
|
test('should save the item successfully.', () => {});
|
||||||
|
test('should item code be unqiue.', () => {});
|
||||||
|
});
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
"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 available 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.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",
|
||||||
|
|||||||
@@ -151,7 +151,7 @@
|
|||||||
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
||||||
"Loan": "Loan",
|
"Loan": "Loan",
|
||||||
"Owner A Drawings": "Owner A Drawings",
|
"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.",
|
"An account that holds valuation of products or goods that available for sale.": "An account that holds valuation of products or goods that available for sale.",
|
||||||
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
|
"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.",
|
"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.",
|
"The income activities are not associated to the core business.": "The income activities are not associated to the core business.",
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ export default class ManualJournalsController extends BaseController {
|
|||||||
errors: [{ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 300 }],
|
errors: [{ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 300 }],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (error.errorType === 'acccounts_ids_not_found') {
|
if (error.errorType === 'accounts_ids_not_found') {
|
||||||
return res.boom.badRequest(
|
return res.boom.badRequest(
|
||||||
'Journal entries some of accounts ids not exists.',
|
'Journal entries some of accounts ids not exists.',
|
||||||
{ errors: [{ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 400 }] }
|
{ errors: [{ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 400 }] }
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
|
import { Service, Inject } from 'typedi';
|
||||||
import { Router, Request, Response, NextFunction } from 'express';
|
import { Router, Request, Response, NextFunction } from 'express';
|
||||||
import { check, param, query } from 'express-validator';
|
import { check, param, query } from 'express-validator';
|
||||||
import { Service, Inject } from 'typedi';
|
import {
|
||||||
import { AbilitySubject, BillAction, IBillDTO, IBillEditDTO } from '@/interfaces';
|
AbilitySubject,
|
||||||
|
BillAction,
|
||||||
|
IBillDTO,
|
||||||
|
IBillEditDTO,
|
||||||
|
} from '@/interfaces';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import BillsService from '@/services/Purchases/Bills';
|
|
||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import BillPaymentsService from '@/services/Purchases/BillPaymentsService';
|
import { BillsApplication } from '@/services/Purchases/Bills/BillsApplication';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class BillsController extends BaseController {
|
export default class BillsController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
private billsService: BillsService;
|
private billsApplication: BillsApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private dynamicListService: DynamicListingService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private billPayments: BillPaymentsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
*/
|
*/
|
||||||
@@ -97,7 +98,7 @@ export default class BillsController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Common validation schema.
|
* Common validation schema.
|
||||||
*/
|
*/
|
||||||
get billValidationSchema() {
|
private get billValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('bill_number').exists().trim().escape(),
|
check('bill_number').exists().trim().escape(),
|
||||||
check('reference_no').optional().trim().escape(),
|
check('reference_no').optional().trim().escape(),
|
||||||
@@ -142,7 +143,7 @@ export default class BillsController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Common validation schema.
|
* Common validation schema.
|
||||||
*/
|
*/
|
||||||
get billEditValidationSchema() {
|
private get billEditValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('bill_number').optional().trim().escape(),
|
check('bill_number').optional().trim().escape(),
|
||||||
check('reference_no').optional().trim().escape(),
|
check('reference_no').optional().trim().escape(),
|
||||||
@@ -184,14 +185,14 @@ export default class BillsController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Bill validation schema.
|
* Bill validation schema.
|
||||||
*/
|
*/
|
||||||
get specificBillValidationSchema() {
|
private get specificBillValidationSchema() {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bills list validation schema.
|
* Bills list validation schema.
|
||||||
*/
|
*/
|
||||||
get billsListingValidationSchema() {
|
private get billsListingValidationSchema() {
|
||||||
return [
|
return [
|
||||||
query('view_slug').optional().isString().trim(),
|
query('view_slug').optional().isString().trim(),
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
@@ -203,7 +204,7 @@ export default class BillsController extends BaseController {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
get dueBillsListingValidationSchema() {
|
private get dueBillsListingValidationSchema() {
|
||||||
return [
|
return [
|
||||||
query('vendor_id').optional().trim().escape(),
|
query('vendor_id').optional().trim().escape(),
|
||||||
query('payment_made_id').optional().trim().escape(),
|
query('payment_made_id').optional().trim().escape(),
|
||||||
@@ -216,17 +217,16 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async newBill(req: Request, res: Response, next: NextFunction) {
|
private async newBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const billDTO: IBillDTO = this.matchedBodyData(req);
|
const billDTO: IBillDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const storedBill = await this.billsService.createBill(
|
const storedBill = await this.billsApplication.createBill(
|
||||||
tenantId,
|
tenantId,
|
||||||
billDTO,
|
billDTO,
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: storedBill.id,
|
id: storedBill.id,
|
||||||
message: 'The bill has been created successfully.',
|
message: 'The bill has been created successfully.',
|
||||||
@@ -241,13 +241,13 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async editBill(req: Request, res: Response, next: NextFunction) {
|
private async editBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const { id: billId } = req.params;
|
const { id: billId } = req.params;
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const billDTO: IBillEditDTO = this.matchedBodyData(req);
|
const billDTO: IBillEditDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.billsService.editBill(tenantId, billId, billDTO, user);
|
await this.billsApplication.editBill(tenantId, billId, billDTO, user);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: billId,
|
id: billId,
|
||||||
@@ -263,12 +263,12 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Request} req -
|
* @param {Request} req -
|
||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
*/
|
*/
|
||||||
async openBill(req: Request, res: Response, next: NextFunction) {
|
private async openBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const { id: billId } = req.params;
|
const { id: billId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.billsService.openBill(tenantId, billId);
|
await this.billsApplication.openBill(tenantId, billId);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: billId,
|
id: billId,
|
||||||
@@ -285,12 +285,12 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async getBill(req: Request, res: Response, next: NextFunction) {
|
private async getBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: billId } = req.params;
|
const { id: billId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const bill = await this.billsService.getBill(tenantId, billId);
|
const bill = await this.billsApplication.getBill(tenantId, billId);
|
||||||
|
|
||||||
return res.status(200).send(this.transfromToResponse({ bill }));
|
return res.status(200).send(this.transfromToResponse({ bill }));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -304,12 +304,12 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async deleteBill(req: Request, res: Response, next: NextFunction) {
|
private async deleteBill(req: Request, res: Response, next: NextFunction) {
|
||||||
const billId = req.params.id;
|
const billId = req.params.id;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.billsService.deleteBill(tenantId, billId);
|
await this.billsApplication.deleteBill(tenantId, billId);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: billId,
|
id: billId,
|
||||||
@@ -326,7 +326,7 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
public async billsList(req: Request, res: Response, next: NextFunction) {
|
private async billsList(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const filter = {
|
const filter = {
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -338,7 +338,7 @@ export default class BillsController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { bills, pagination, filterMeta } =
|
const { bills, pagination, filterMeta } =
|
||||||
await this.billsService.getBills(tenantId, filter);
|
await this.billsApplication.getBills(tenantId, filter);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
bills: this.transfromToResponse(bills),
|
bills: this.transfromToResponse(bills),
|
||||||
@@ -356,12 +356,13 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
public async getDueBills(req: Request, res: Response, next: NextFunction) {
|
private async getDueBills(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { vendorId } = this.matchedQueryData(req);
|
const { vendorId } = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const bills = await this.billsService.getDueBills(tenantId, vendorId);
|
const bills = await this.billsApplication.getDueBills(tenantId, vendorId);
|
||||||
|
|
||||||
return res.status(200).send({ bills });
|
return res.status(200).send({ bills });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@@ -374,7 +375,7 @@ export default class BillsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
public getBillPaymentsTransactions = async (
|
private getBillPaymentsTransactions = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -383,7 +384,7 @@ export default class BillsController extends BaseController {
|
|||||||
const { id: billId } = req.params;
|
const { id: billId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const billPayments = await this.billPayments.getBillPayments(
|
const billPayments = await this.billsApplication.getBillPayments(
|
||||||
tenantId,
|
tenantId,
|
||||||
billId
|
billId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { check, param, query, ValidationChain } from 'express-validator';
|
|||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import BillPaymentsService from '@/services/Purchases/BillPayments/BillPayments';
|
import { BillPaymentsApplication } from '@/services/Purchases/BillPayments/BillPaymentsApplication';
|
||||||
import BillPaymentsPages from '@/services/Purchases/BillPayments/BillPaymentsPages';
|
import BillPaymentsPages from '@/services/Purchases/BillPayments/BillPaymentsPages';
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
@@ -17,18 +17,18 @@ import { AbilitySubject, IPaymentMadeAction } from '@/interfaces';
|
|||||||
@Service()
|
@Service()
|
||||||
export default class BillsPayments extends BaseController {
|
export default class BillsPayments extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
billPaymentService: BillPaymentsService;
|
private billPaymentsApplication: BillPaymentsApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
dynamicListService: DynamicListingService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
billPaymentsPages: BillPaymentsPages;
|
private billPaymentsPages: BillPaymentsPages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
*/
|
*/
|
||||||
router() {
|
public router() {
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -106,7 +106,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* Bill payments schema validation.
|
* Bill payments schema validation.
|
||||||
* @return {ValidationChain[]}
|
* @return {ValidationChain[]}
|
||||||
*/
|
*/
|
||||||
get billPaymentSchemaValidation(): ValidationChain[] {
|
private get billPaymentSchemaValidation(): ValidationChain[] {
|
||||||
return [
|
return [
|
||||||
check('vendor_id').exists().isNumeric().toInt(),
|
check('vendor_id').exists().isNumeric().toInt(),
|
||||||
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
||||||
@@ -129,7 +129,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* Specific bill payment schema validation.
|
* Specific bill payment schema validation.
|
||||||
* @returns {ValidationChain[]}
|
* @returns {ValidationChain[]}
|
||||||
*/
|
*/
|
||||||
get specificBillPaymentValidateSchema(): ValidationChain[] {
|
private get specificBillPaymentValidateSchema(): ValidationChain[] {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* Bills payment list validation schema.
|
* Bills payment list validation schema.
|
||||||
* @returns {ValidationChain[]}
|
* @returns {ValidationChain[]}
|
||||||
*/
|
*/
|
||||||
get listingValidationSchema(): ValidationChain[] {
|
private get listingValidationSchema(): ValidationChain[] {
|
||||||
return [
|
return [
|
||||||
query('custom_view_id').optional().isNumeric().toInt(),
|
query('custom_view_id').optional().isNumeric().toInt(),
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
@@ -154,7 +154,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Request} req -
|
* @param {Request} req -
|
||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
*/
|
*/
|
||||||
async getBillPaymentNewPageEntries(req: Request, res: Response) {
|
private async getBillPaymentNewPageEntries(req: Request, res: Response) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { vendorId } = this.matchedQueryData(req);
|
const { vendorId } = this.matchedQueryData(req);
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async getBillPaymentEditPage(
|
private async getBillPaymentEditPage(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -205,16 +205,19 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async createBillPayment(req: Request, res: Response, next: NextFunction) {
|
private async createBillPayment(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const billPaymentDTO = this.matchedBodyData(req);
|
const billPaymentDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const billPayment = await this.billPaymentService.createBillPayment(
|
const billPayment = await this.billPaymentsApplication.createBillPayment(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentDTO
|
billPaymentDTO
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: billPayment.id,
|
id: billPayment.id,
|
||||||
message: 'Payment made has been created successfully.',
|
message: 'Payment made has been created successfully.',
|
||||||
@@ -229,13 +232,17 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async editBillPayment(req: Request, res: Response, next: NextFunction) {
|
private async editBillPayment(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const billPaymentDTO = this.matchedBodyData(req);
|
const billPaymentDTO = this.matchedBodyData(req);
|
||||||
const { id: billPaymentId } = req.params;
|
const { id: billPaymentId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const paymentMade = await this.billPaymentService.editBillPayment(
|
const paymentMade = await this.billPaymentsApplication.editBillPayment(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentId,
|
billPaymentId,
|
||||||
billPaymentDTO
|
billPaymentDTO
|
||||||
@@ -256,12 +263,19 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @return {Response} res -
|
* @return {Response} res -
|
||||||
*/
|
*/
|
||||||
async deleteBillPayment(req: Request, res: Response, next: NextFunction) {
|
private async deleteBillPayment(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: billPaymentId } = req.params;
|
const { id: billPaymentId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.billPaymentService.deleteBillPayment(tenantId, billPaymentId);
|
await this.billPaymentsApplication.deleteBillPayment(
|
||||||
|
tenantId,
|
||||||
|
billPaymentId
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: billPaymentId,
|
id: billPaymentId,
|
||||||
@@ -277,16 +291,19 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async getBillPayment(req: Request, res: Response, next: NextFunction) {
|
private async getBillPayment(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: billPaymentId } = req.params;
|
const { id: billPaymentId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const billPayment = await this.billPaymentService.getBillPayment(
|
const billPayment = await this.billPaymentsApplication.getBillPayment(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentId
|
billPaymentId
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
bill_payment: this.transfromToResponse(billPayment),
|
bill_payment: this.transfromToResponse(billPayment),
|
||||||
});
|
});
|
||||||
@@ -301,12 +318,16 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getPaymentBills(req: Request, res: Response, next: NextFunction) {
|
private async getPaymentBills(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: billPaymentId } = req.params;
|
const { id: billPaymentId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const bills = await this.billPaymentService.getPaymentBills(
|
const bills = await this.billPaymentsApplication.getPaymentBills(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentId
|
billPaymentId
|
||||||
);
|
);
|
||||||
@@ -322,7 +343,11 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async getBillsPayments(req: Request, res: Response, next: NextFunction) {
|
private async getBillsPayments(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const billPaymentsFilter = {
|
const billPaymentsFilter = {
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -335,7 +360,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { billPayments, pagination, filterMeta } =
|
const { billPayments, pagination, filterMeta } =
|
||||||
await this.billPaymentService.listBillPayments(
|
await this.billPaymentsApplication.getBillPayments(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPaymentsFilter
|
billPaymentsFilter
|
||||||
);
|
);
|
||||||
@@ -357,7 +382,7 @@ export default class BillsPayments extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
handleServiceError(
|
private handleServiceError(
|
||||||
error: Error,
|
error: Error,
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
|
|||||||
@@ -1,42 +1,29 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
import { Router, Request, Response, NextFunction } from 'express';
|
import { Router, Request, Response, NextFunction } from 'express';
|
||||||
import { check, param, query, ValidationChain } from 'express-validator';
|
import { check, param, query, ValidationChain } from 'express-validator';
|
||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import {
|
import {
|
||||||
AbilitySubject,
|
AbilitySubject,
|
||||||
IPaymentReceiveDTO,
|
IPaymentReceiveDTO,
|
||||||
PaymentReceiveAction,
|
PaymentReceiveAction,
|
||||||
SaleInvoiceAction,
|
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import PaymentReceiveService from '@/services/Sales/PaymentReceives/PaymentsReceives';
|
|
||||||
import PaymentReceivesPages from '@/services/Sales/PaymentReceives/PaymentReceivesPages';
|
import PaymentReceivesPages from '@/services/Sales/PaymentReceives/PaymentReceivesPages';
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { PaymentReceivesApplication } from '@/services/Sales/PaymentReceives/PaymentReceivesApplication';
|
||||||
import PaymentReceiveNotifyBySms from '@/services/Sales/PaymentReceives/PaymentReceiveSmsNotify';
|
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import GetPaymentReceivePdf from '@/services/Sales/PaymentReceives/GetPaymentReeceivePdf';
|
import { ServiceError } from '@/exceptions';
|
||||||
|
|
||||||
/**
|
|
||||||
* Payments receives controller.
|
|
||||||
* @service
|
|
||||||
*/
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class PaymentReceivesController extends BaseController {
|
export default class PaymentReceivesController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
paymentReceiveService: PaymentReceiveService;
|
private paymentReceiveApplication: PaymentReceivesApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
PaymentReceivesPages: PaymentReceivesPages;
|
private PaymentReceivesPages: PaymentReceivesPages;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
dynamicListService: DynamicListingService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
paymentReceiveSmsNotify: PaymentReceiveNotifyBySms;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
paymentReceivePdf: GetPaymentReceivePdf;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
@@ -137,7 +124,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* Payment receive schema.
|
* Payment receive schema.
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
get paymentReceiveSchema(): ValidationChain[] {
|
private get paymentReceiveSchema(): ValidationChain[] {
|
||||||
return [
|
return [
|
||||||
check('customer_id').exists().isNumeric().toInt(),
|
check('customer_id').exists().isNumeric().toInt(),
|
||||||
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
||||||
@@ -162,7 +149,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Payment receive list validation schema.
|
* Payment receive list validation schema.
|
||||||
*/
|
*/
|
||||||
get validatePaymentReceiveList(): ValidationChain[] {
|
private get validatePaymentReceiveList(): ValidationChain[] {
|
||||||
return [
|
return [
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
|
|
||||||
@@ -181,7 +168,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Validate payment receive parameters.
|
* Validate payment receive parameters.
|
||||||
*/
|
*/
|
||||||
get paymentReceiveValidation() {
|
private get paymentReceiveValidation() {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,14 +176,14 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* New payment receive validation schema.
|
* New payment receive validation schema.
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
get newPaymentReceiveValidation() {
|
private get newPaymentReceiveValidation() {
|
||||||
return [...this.paymentReceiveSchema];
|
return [...this.paymentReceiveSchema];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit payment receive validation.
|
* Edit payment receive validation.
|
||||||
*/
|
*/
|
||||||
get editPaymentReceiveValidation() {
|
private get editPaymentReceiveValidation() {
|
||||||
return [
|
return [
|
||||||
param('id').exists().isNumeric().toInt(),
|
param('id').exists().isNumeric().toInt(),
|
||||||
...this.paymentReceiveSchema,
|
...this.paymentReceiveSchema,
|
||||||
@@ -209,13 +196,17 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async newPaymentReceive(req: Request, res: Response, next: NextFunction) {
|
private async newPaymentReceive(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req);
|
const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const storedPaymentReceive =
|
const storedPaymentReceive =
|
||||||
await this.paymentReceiveService.createPaymentReceive(
|
await this.paymentReceiveApplication.createPaymentReceive(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceive,
|
paymentReceive,
|
||||||
user
|
user
|
||||||
@@ -235,14 +226,18 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async editPaymentReceive(req: Request, res: Response, next: NextFunction) {
|
private async editPaymentReceive(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req);
|
const paymentReceive: IPaymentReceiveDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.paymentReceiveService.editPaymentReceive(
|
await this.paymentReceiveApplication.editPaymentReceive(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
paymentReceive,
|
paymentReceive,
|
||||||
@@ -262,17 +257,20 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async deletePaymentReceive(req: Request, res: Response, next: NextFunction) {
|
private async deletePaymentReceive(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.paymentReceiveService.deletePaymentReceive(
|
await this.paymentReceiveApplication.deletePaymentReceive(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId,
|
paymentReceiveId,
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: paymentReceiveId,
|
id: paymentReceiveId,
|
||||||
message: 'The payment receive has been deleted successfully',
|
message: 'The payment receive has been deleted successfully',
|
||||||
@@ -288,7 +286,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getPaymentReceiveInvoices(
|
private async getPaymentReceiveInvoices(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -298,7 +296,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const saleInvoices =
|
const saleInvoices =
|
||||||
await this.paymentReceiveService.getPaymentReceiveInvoices(
|
await this.paymentReceiveApplication.getPaymentReceiveInvoices(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceiveId
|
paymentReceiveId
|
||||||
);
|
);
|
||||||
@@ -315,7 +313,11 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @return {Response}
|
* @return {Response}
|
||||||
*/
|
*/
|
||||||
async getPaymentReceiveList(req: Request, res: Response, next: NextFunction) {
|
private async getPaymentReceiveList(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const filter = {
|
const filter = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
@@ -327,7 +329,10 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { paymentReceives, pagination, filterMeta } =
|
const { paymentReceives, pagination, filterMeta } =
|
||||||
await this.paymentReceiveService.listPaymentReceives(tenantId, filter);
|
await this.paymentReceiveApplication.getPaymentReceives(
|
||||||
|
tenantId,
|
||||||
|
filter
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
payment_receives: this.transfromToResponse(paymentReceives),
|
payment_receives: this.transfromToResponse(paymentReceives),
|
||||||
@@ -344,7 +349,7 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Request} req - Request.
|
* @param {Request} req - Request.
|
||||||
* @param {Response} res - Response.
|
* @param {Response} res - Response.
|
||||||
*/
|
*/
|
||||||
async getPaymentReceiveNewPageEntries(
|
private async getPaymentReceiveNewPageEntries(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -367,11 +372,11 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the given payment receive details.
|
* Retrieve the given payment receive details.
|
||||||
* @asycn
|
* @async
|
||||||
* @param {Request} req -
|
* @param {Request} req -
|
||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
*/
|
*/
|
||||||
async getPaymentReceiveEditPage(
|
private async getPaymentReceiveEditPage(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -402,15 +407,20 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getPaymentReceive(req: Request, res: Response, next: NextFunction) {
|
private async getPaymentReceive(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const paymentReceive = await this.paymentReceiveService.getPaymentReceive(
|
const paymentReceive =
|
||||||
tenantId,
|
await this.paymentReceiveApplication.getPaymentReceive(
|
||||||
paymentReceiveId
|
tenantId,
|
||||||
);
|
paymentReceiveId
|
||||||
|
);
|
||||||
|
|
||||||
const ACCEPT_TYPE = {
|
const ACCEPT_TYPE = {
|
||||||
APPLICATION_PDF: 'application/pdf',
|
APPLICATION_PDF: 'application/pdf',
|
||||||
@@ -423,10 +433,11 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
||||||
const pdfContent = await this.paymentReceivePdf.getPaymentReceivePdf(
|
const pdfContent =
|
||||||
tenantId,
|
await this.paymentReceiveApplication.getPaymentReceivePdf(
|
||||||
paymentReceive
|
tenantId,
|
||||||
);
|
paymentReceive
|
||||||
|
);
|
||||||
res.set({
|
res.set({
|
||||||
'Content-Type': 'application/pdf',
|
'Content-Type': 'application/pdf',
|
||||||
'Content-Length': pdfContent.length,
|
'Content-Length': pdfContent.length,
|
||||||
@@ -454,10 +465,11 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const paymentReceive = await this.paymentReceiveSmsNotify.notifyBySms(
|
const paymentReceive =
|
||||||
tenantId,
|
await this.paymentReceiveApplication.notifyPaymentBySms(
|
||||||
paymentReceiveId
|
tenantId,
|
||||||
);
|
paymentReceiveId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: paymentReceive.id,
|
id: paymentReceive.id,
|
||||||
message: 'The payment notification has been sent successfully.',
|
message: 'The payment notification has been sent successfully.',
|
||||||
@@ -482,10 +494,11 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
const { id: paymentReceiveId } = req.params;
|
const { id: paymentReceiveId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const smsDetails = await this.paymentReceiveSmsNotify.smsDetails(
|
const smsDetails =
|
||||||
tenantId,
|
await this.paymentReceiveApplication.getPaymentSmsDetails(
|
||||||
paymentReceiveId
|
tenantId,
|
||||||
);
|
paymentReceiveId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
data: smsDetails,
|
data: smsDetails,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
import { Router, Request, Response, NextFunction } from 'express';
|
import { Router, Request, Response, NextFunction } from 'express';
|
||||||
import { check, param, query, matchedData } from 'express-validator';
|
import { check, param, query } from 'express-validator';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import {
|
import {
|
||||||
AbilitySubject,
|
AbilitySubject,
|
||||||
ISaleEstimateDTO,
|
ISaleEstimateDTO,
|
||||||
SaleEstimateAction,
|
SaleEstimateAction,
|
||||||
SaleInvoiceAction,
|
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import BaseController from '@/api/controllers/BaseController';
|
import BaseController from '@/api/controllers/BaseController';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import SaleEstimateService from '@/services/Sales/SalesEstimate';
|
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import SaleEstimatesPdfService from '@/services/Sales/Estimates/SaleEstimatesPdf';
|
|
||||||
import SaleEstimateNotifyBySms from '@/services/Sales/Estimates/SaleEstimateSmsNotify';
|
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
|
import { SaleEstimatesApplication } from '@/services/Sales/Estimates/SaleEstimatesApplication';
|
||||||
|
|
||||||
const ACCEPT_TYPE = {
|
const ACCEPT_TYPE = {
|
||||||
APPLICATION_PDF: 'application/pdf',
|
APPLICATION_PDF: 'application/pdf',
|
||||||
@@ -23,21 +20,15 @@ const ACCEPT_TYPE = {
|
|||||||
@Service()
|
@Service()
|
||||||
export default class SalesEstimatesController extends BaseController {
|
export default class SalesEstimatesController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
saleEstimateService: SaleEstimateService;
|
private saleEstimatesApplication: SaleEstimatesApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
dynamicListService: DynamicListingService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleEstimatesPdf: SaleEstimatesPdfService;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleEstimateNotifySms: SaleEstimateNotifyBySms;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
*/
|
*/
|
||||||
router() {
|
public router() {
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -136,7 +127,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Estimate validation schema.
|
* Estimate validation schema.
|
||||||
*/
|
*/
|
||||||
get estimateValidationSchema() {
|
private get estimateValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('customer_id').exists().isNumeric().toInt(),
|
check('customer_id').exists().isNumeric().toInt(),
|
||||||
check('estimate_date').exists().isISO8601().toDate(),
|
check('estimate_date').exists().isISO8601().toDate(),
|
||||||
@@ -177,14 +168,14 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Specific sale estimate validation schema.
|
* Specific sale estimate validation schema.
|
||||||
*/
|
*/
|
||||||
get validateSpecificEstimateSchema() {
|
private get validateSpecificEstimateSchema() {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sales estimates list validation schema.
|
* Sales estimates list validation schema.
|
||||||
*/
|
*/
|
||||||
get validateEstimateListSchema() {
|
private get validateEstimateListSchema() {
|
||||||
return [
|
return [
|
||||||
query('view_slug').optional().isString().trim(),
|
query('view_slug').optional().isString().trim(),
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
@@ -202,15 +193,16 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @return {Response} res -
|
* @return {Response} res -
|
||||||
*/
|
*/
|
||||||
async newEstimate(req: Request, res: Response, next: NextFunction) {
|
private async newEstimate(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req);
|
const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const storedEstimate = await this.saleEstimateService.createEstimate(
|
const storedEstimate =
|
||||||
tenantId,
|
await this.saleEstimatesApplication.createSaleEstimate(
|
||||||
estimateDTO
|
tenantId,
|
||||||
);
|
estimateDTO
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: storedEstimate.id,
|
id: storedEstimate.id,
|
||||||
@@ -226,19 +218,18 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async editEstimate(req: Request, res: Response, next: NextFunction) {
|
private async editEstimate(req: Request, res: Response, next: NextFunction) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req);
|
const estimateDTO: ISaleEstimateDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update estimate with associated estimate entries.
|
// Update estimate with associated estimate entries.
|
||||||
await this.saleEstimateService.editEstimate(
|
await this.saleEstimatesApplication.editSaleEstimate(
|
||||||
tenantId,
|
tenantId,
|
||||||
estimateId,
|
estimateId,
|
||||||
estimateDTO
|
estimateDTO
|
||||||
);
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
message: 'The sale estimate has been created successfully.',
|
message: 'The sale estimate has been created successfully.',
|
||||||
@@ -253,13 +244,19 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async deleteEstimate(req: Request, res: Response, next: NextFunction) {
|
private async deleteEstimate(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.saleEstimateService.deleteEstimate(tenantId, estimateId);
|
await this.saleEstimatesApplication.deleteSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
message: 'The sale estimate has been deleted successfully.',
|
message: 'The sale estimate has been deleted successfully.',
|
||||||
@@ -274,13 +271,19 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async deliverSaleEstimate(req: Request, res: Response, next: NextFunction) {
|
private async deliverSaleEstimate(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.saleEstimateService.deliverSaleEstimate(tenantId, estimateId);
|
await this.saleEstimatesApplication.deliverSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
message: 'The sale estimate has been delivered successfully.',
|
message: 'The sale estimate has been delivered successfully.',
|
||||||
@@ -296,12 +299,19 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async approveSaleEstimate(req: Request, res: Response, next: NextFunction) {
|
private async approveSaleEstimate(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.saleEstimateService.approveSaleEstimate(tenantId, estimateId);
|
await this.saleEstimatesApplication.approveSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
@@ -318,12 +328,19 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async rejectSaleEstimate(req: Request, res: Response, next: NextFunction) {
|
private async rejectSaleEstimate(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.saleEstimateService.rejectSaleEstimate(tenantId, estimateId);
|
await this.saleEstimatesApplication.rejectSaleEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: estimateId,
|
id: estimateId,
|
||||||
@@ -340,12 +357,12 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async getEstimate(req: Request, res: Response, next: NextFunction) {
|
private async getEstimate(req: Request, res: Response, next: NextFunction) {
|
||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const estimate = await this.saleEstimateService.getEstimate(
|
const estimate = await this.saleEstimatesApplication.getSaleEstimate(
|
||||||
tenantId,
|
tenantId,
|
||||||
estimateId
|
estimateId
|
||||||
);
|
);
|
||||||
@@ -357,10 +374,11 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
},
|
},
|
||||||
// PDF content type.
|
// PDF content type.
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
||||||
const pdfContent = await this.saleEstimatesPdf.saleEstimatePdf(
|
const pdfContent =
|
||||||
tenantId,
|
await this.saleEstimatesApplication.getSaleEstimatePdf(
|
||||||
estimate
|
tenantId,
|
||||||
);
|
estimate
|
||||||
|
);
|
||||||
res.set({
|
res.set({
|
||||||
'Content-Type': 'application/pdf',
|
'Content-Type': 'application/pdf',
|
||||||
'Content-Length': pdfContent.length,
|
'Content-Length': pdfContent.length,
|
||||||
@@ -378,7 +396,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async getEstimates(req: Request, res: Response, next: NextFunction) {
|
private async getEstimates(req: Request, res: Response, next: NextFunction) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const filter = {
|
const filter = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
@@ -390,7 +408,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { salesEstimates, pagination, filterMeta } =
|
const { salesEstimates, pagination, filterMeta } =
|
||||||
await this.saleEstimateService.estimatesList(tenantId, filter);
|
await this.saleEstimatesApplication.getSaleEstimates(tenantId, filter);
|
||||||
|
|
||||||
res.format({
|
res.format({
|
||||||
[ACCEPT_TYPE.APPLICATION_JSON]: () => {
|
[ACCEPT_TYPE.APPLICATION_JSON]: () => {
|
||||||
@@ -408,7 +426,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public saleEstimateNotifyBySms = async (
|
private saleEstimateNotifyBySms = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -417,10 +435,11 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleEstimate = await this.saleEstimateNotifySms.notifyBySms(
|
const saleEstimate =
|
||||||
tenantId,
|
await this.saleEstimatesApplication.notifySaleEstimateBySms(
|
||||||
estimateId
|
tenantId,
|
||||||
);
|
estimateId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleEstimate.id,
|
id: saleEstimate.id,
|
||||||
message:
|
message:
|
||||||
@@ -437,7 +456,7 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
public saleEstimateSmsDetails = async (
|
private saleEstimateSmsDetails = async (
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
next: NextFunction
|
next: NextFunction
|
||||||
@@ -446,10 +465,11 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
const { id: estimateId } = req.params;
|
const { id: estimateId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const estimateSmsDetails = await this.saleEstimateNotifySms.smsDetails(
|
const estimateSmsDetails =
|
||||||
tenantId,
|
await this.saleEstimatesApplication.getSaleEstimateSmsDetails(
|
||||||
estimateId
|
tenantId,
|
||||||
);
|
estimateId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
data: estimateSmsDetails,
|
data: estimateSmsDetails,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { check, param, query } from 'express-validator';
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import BaseController from '../BaseController';
|
import BaseController from '../BaseController';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import SaleInvoiceService from '@/services/Sales/SalesInvoices';
|
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import {
|
import {
|
||||||
@@ -12,11 +11,8 @@ import {
|
|||||||
SaleInvoiceAction,
|
SaleInvoiceAction,
|
||||||
AbilitySubject,
|
AbilitySubject,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import SaleInvoicePdf from '@/services/Sales/SaleInvoicePdf';
|
|
||||||
import SaleInvoiceWriteoff from '@/services/Sales/SaleInvoiceWriteoff';
|
|
||||||
import SaleInvoiceNotifyBySms from '@/services/Sales/SaleInvoiceNotifyBySms';
|
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import InvoicePaymentsService from '@/services/Sales/Invoices/InvoicePaymentsService';
|
import { SaleInvoiceApplication } from '@/services/Sales/Invoices/SaleInvoicesApplication';
|
||||||
|
|
||||||
const ACCEPT_TYPE = {
|
const ACCEPT_TYPE = {
|
||||||
APPLICATION_PDF: 'application/pdf',
|
APPLICATION_PDF: 'application/pdf',
|
||||||
@@ -25,27 +21,15 @@ const ACCEPT_TYPE = {
|
|||||||
@Service()
|
@Service()
|
||||||
export default class SaleInvoicesController extends BaseController {
|
export default class SaleInvoicesController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
saleInvoiceService: SaleInvoiceService;
|
private saleInvoiceApplication: SaleInvoiceApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
dynamicListService: DynamicListingService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleInvoicePdf: SaleInvoicePdf;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleInvoiceWriteoff: SaleInvoiceWriteoff;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleInvoiceSmsNotify: SaleInvoiceNotifyBySms;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
invoicePaymentsSerivce: InvoicePaymentsService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
*/
|
*/
|
||||||
router() {
|
public router() {
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -167,7 +151,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Sale invoice validation schema.
|
* Sale invoice validation schema.
|
||||||
*/
|
*/
|
||||||
get saleInvoiceValidationSchema() {
|
private get saleInvoiceValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('customer_id').exists().isNumeric().toInt(),
|
check('customer_id').exists().isNumeric().toInt(),
|
||||||
check('invoice_date').exists().isISO8601().toDate(),
|
check('invoice_date').exists().isISO8601().toDate(),
|
||||||
@@ -227,14 +211,14 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Specific sale invoice validation schema.
|
* Specific sale invoice validation schema.
|
||||||
*/
|
*/
|
||||||
get specificSaleInvoiceValidation() {
|
private get specificSaleInvoiceValidation() {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sales invoices list validation schema.
|
* Sales invoices list validation schema.
|
||||||
*/
|
*/
|
||||||
get saleInvoiceListValidationSchema() {
|
private get saleInvoiceListValidationSchema() {
|
||||||
return [
|
return [
|
||||||
query('view_slug').optional({ nullable: true }).isString().trim(),
|
query('view_slug').optional({ nullable: true }).isString().trim(),
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
@@ -249,7 +233,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Due sale invoice list validation schema.
|
* Due sale invoice list validation schema.
|
||||||
*/
|
*/
|
||||||
get dueSalesInvoicesListValidationSchema() {
|
private get dueSalesInvoicesListValidationSchema() {
|
||||||
return [query('customer_id').optional().isNumeric().toInt()];
|
return [query('customer_id').optional().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,17 +243,22 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async newSaleInvoice(req: Request, res: Response, next: NextFunction) {
|
private async newSaleInvoice(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const saleInvoiceDTO: ISaleInvoiceCreateDTO = this.matchedBodyData(req);
|
const saleInvoiceDTO: ISaleInvoiceCreateDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Creates a new sale invoice with associated entries.
|
// Creates a new sale invoice with associated entries.
|
||||||
const storedSaleInvoice = await this.saleInvoiceService.createSaleInvoice(
|
const storedSaleInvoice =
|
||||||
tenantId,
|
await this.saleInvoiceApplication.createSaleInvoice(
|
||||||
saleInvoiceDTO,
|
tenantId,
|
||||||
user
|
saleInvoiceDTO,
|
||||||
);
|
user
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: storedSaleInvoice.id,
|
id: storedSaleInvoice.id,
|
||||||
message: 'The sale invoice has been created successfully.',
|
message: 'The sale invoice has been created successfully.',
|
||||||
@@ -285,14 +274,18 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async editSaleInvoice(req: Request, res: Response, next: NextFunction) {
|
private async editSaleInvoice(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: saleInvoiceId } = req.params;
|
const { id: saleInvoiceId } = req.params;
|
||||||
const saleInvoiceOTD: ISaleInvoiceDTO = this.matchedBodyData(req);
|
const saleInvoiceOTD: ISaleInvoiceDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update the given sale invoice details.
|
// Update the given sale invoice details.
|
||||||
await this.saleInvoiceService.editSaleInvoice(
|
await this.saleInvoiceApplication.editSaleInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
saleInvoiceOTD,
|
saleInvoiceOTD,
|
||||||
@@ -313,12 +306,16 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
* @param {NextFunction} next -
|
* @param {NextFunction} next -
|
||||||
*/
|
*/
|
||||||
async deliverSaleInvoice(req: Request, res: Response, next: NextFunction) {
|
private async deliverSaleInvoice(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
const { id: saleInvoiceId } = req.params;
|
const { id: saleInvoiceId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.saleInvoiceService.deliverSaleInvoice(
|
await this.saleInvoiceApplication.deliverSaleInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
user
|
user
|
||||||
@@ -338,13 +335,17 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {Function} next
|
* @param {Function} next
|
||||||
*/
|
*/
|
||||||
async deleteSaleInvoice(req: Request, res: Response, next: NextFunction) {
|
private async deleteSaleInvoice(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: saleInvoiceId } = req.params;
|
const { id: saleInvoiceId } = req.params;
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Deletes the sale invoice with associated entries and journal transaction.
|
// Deletes the sale invoice with associated entries and journal transaction.
|
||||||
await this.saleInvoiceService.deleteSaleInvoice(
|
await this.saleInvoiceApplication.deleteSaleInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
user
|
user
|
||||||
@@ -364,12 +365,16 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
* @param {Request} req - Request object.
|
* @param {Request} req - Request object.
|
||||||
* @param {Response} res - Response object.
|
* @param {Response} res - Response object.
|
||||||
*/
|
*/
|
||||||
async getSaleInvoice(req: Request, res: Response, next: NextFunction) {
|
private async getSaleInvoice(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { id: saleInvoiceId } = req.params;
|
const { id: saleInvoiceId } = req.params;
|
||||||
const { tenantId, user } = req;
|
const { tenantId, user } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleInvoice = await this.saleInvoiceService.getSaleInvoice(
|
const saleInvoice = await this.saleInvoiceApplication.getSaleInvoice(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
user
|
user
|
||||||
@@ -384,7 +389,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
},
|
},
|
||||||
// PDF content type.
|
// PDF content type.
|
||||||
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
[ACCEPT_TYPE.APPLICATION_PDF]: async () => {
|
||||||
const pdfContent = await this.saleInvoicePdf.saleInvoicePdf(
|
const pdfContent = await this.saleInvoiceApplication.saleInvoicePdf(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoice
|
saleInvoice
|
||||||
);
|
);
|
||||||
@@ -420,7 +425,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const { salesInvoices, filterMeta, pagination } =
|
const { salesInvoices, filterMeta, pagination } =
|
||||||
await this.saleInvoiceService.salesInvoicesList(tenantId, filter);
|
await this.saleInvoiceApplication.getSaleInvoices(tenantId, filter);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
sales_invoices: this.transfromToResponse(salesInvoices),
|
sales_invoices: this.transfromToResponse(salesInvoices),
|
||||||
@@ -448,10 +453,11 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const { customerId } = this.matchedQueryData(req);
|
const { customerId } = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const salesInvoices = await this.saleInvoiceService.getPayableInvoices(
|
const salesInvoices =
|
||||||
tenantId,
|
await this.saleInvoiceApplication.getReceivableSaleInvoices(
|
||||||
customerId
|
tenantId,
|
||||||
);
|
customerId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
sales_invoices: this.transfromToResponse(salesInvoices),
|
sales_invoices: this.transfromToResponse(salesInvoices),
|
||||||
});
|
});
|
||||||
@@ -477,7 +483,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const writeoffDTO = this.matchedBodyData(req);
|
const writeoffDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleInvoice = await this.saleInvoiceWriteoff.writeOff(
|
const saleInvoice = await this.saleInvoiceApplication.writeOff(
|
||||||
tenantId,
|
tenantId,
|
||||||
invoiceId,
|
invoiceId,
|
||||||
writeoffDTO
|
writeoffDTO
|
||||||
@@ -485,7 +491,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleInvoice.id,
|
id: saleInvoice.id,
|
||||||
message: 'The given sale invoice has been writte-off successfully.',
|
message: 'The given sale invoice has been written-off successfully.',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@@ -507,7 +513,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const { id: invoiceId } = req.params;
|
const { id: invoiceId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleInvoice = await this.saleInvoiceWriteoff.cancelWrittenoff(
|
const saleInvoice = await this.saleInvoiceApplication.cancelWrittenoff(
|
||||||
tenantId,
|
tenantId,
|
||||||
invoiceId
|
invoiceId
|
||||||
);
|
);
|
||||||
@@ -538,11 +544,12 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const invoiceNotifySmsDTO = this.matchedBodyData(req);
|
const invoiceNotifySmsDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleInvoice = await this.saleInvoiceSmsNotify.notifyBySms(
|
const saleInvoice =
|
||||||
tenantId,
|
await this.saleInvoiceApplication.notifySaleInvoiceBySms(
|
||||||
invoiceId,
|
tenantId,
|
||||||
invoiceNotifySmsDTO.notificationKey
|
invoiceId,
|
||||||
);
|
invoiceNotifySmsDTO.notificationKey
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleInvoice.id,
|
id: saleInvoice.id,
|
||||||
message:
|
message:
|
||||||
@@ -569,11 +576,12 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
const smsDetailsDTO = this.matchedQueryData(req);
|
const smsDetailsDTO = this.matchedQueryData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const invoiceSmsDetails = await this.saleInvoiceSmsNotify.smsDetails(
|
const invoiceSmsDetails =
|
||||||
tenantId,
|
await this.saleInvoiceApplication.getSaleInvoiceSmsDetails(
|
||||||
invoiceId,
|
tenantId,
|
||||||
smsDetailsDTO
|
invoiceId,
|
||||||
);
|
smsDetailsDTO
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
data: invoiceSmsDetails,
|
data: invoiceSmsDetails,
|
||||||
});
|
});
|
||||||
@@ -599,7 +607,7 @@ export default class SaleInvoicesController extends BaseController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const invoicePayments =
|
const invoicePayments =
|
||||||
await this.invoicePaymentsSerivce.getInvoicePayments(
|
await this.saleInvoiceApplication.getInvoicePayments(
|
||||||
tenantId,
|
tenantId,
|
||||||
invoiceId
|
invoiceId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,34 +2,26 @@ import { Router, Request, Response, NextFunction } from 'express';
|
|||||||
import { check, param, query } from 'express-validator';
|
import { check, param, query } from 'express-validator';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
import asyncMiddleware from '@/api/middleware/asyncMiddleware';
|
||||||
import SaleReceiptService from '@/services/Sales/SalesReceipts';
|
|
||||||
import SaleReceiptsPdfService from '@/services/Sales/Receipts/SaleReceiptsPdfService';
|
|
||||||
import BaseController from '../BaseController';
|
import BaseController from '../BaseController';
|
||||||
import { ISaleReceiptDTO } from '@/interfaces/SaleReceipt';
|
import { ISaleReceiptDTO } from '@/interfaces/SaleReceipt';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
||||||
import SaleReceiptNotifyBySms from '@/services/Sales/SaleReceiptNotifyBySms';
|
|
||||||
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
import CheckPolicies from '@/api/middleware/CheckPolicies';
|
||||||
import { AbilitySubject, SaleReceiptAction } from '@/interfaces';
|
import { AbilitySubject, SaleReceiptAction } from '@/interfaces';
|
||||||
|
import { SaleReceiptApplication } from '@/services/Sales/Receipts/SaleReceiptApplication';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SalesReceiptsController extends BaseController {
|
export default class SalesReceiptsController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
saleReceiptService: SaleReceiptService;
|
private saleReceiptsApplication: SaleReceiptApplication;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
saleReceiptsPdf: SaleReceiptsPdfService;
|
private dynamicListService: DynamicListingService;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
dynamicListService: DynamicListingService;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
saleReceiptSmsNotify: SaleReceiptNotifyBySms;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Router constructor.
|
* Router constructor.
|
||||||
*/
|
*/
|
||||||
router() {
|
public router() {
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -105,7 +97,7 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* Sales receipt validation schema.
|
* Sales receipt validation schema.
|
||||||
* @return {Array}
|
* @return {Array}
|
||||||
*/
|
*/
|
||||||
get salesReceiptsValidationSchema() {
|
private get salesReceiptsValidationSchema() {
|
||||||
return [
|
return [
|
||||||
check('customer_id').exists().isNumeric().toInt(),
|
check('customer_id').exists().isNumeric().toInt(),
|
||||||
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
check('exchange_rate').optional().isFloat({ gt: 0 }).toFloat(),
|
||||||
@@ -146,14 +138,14 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* Specific sale receipt validation schema.
|
* Specific sale receipt validation schema.
|
||||||
*/
|
*/
|
||||||
get specificReceiptValidationSchema() {
|
private get specificReceiptValidationSchema() {
|
||||||
return [param('id').exists().isNumeric().toInt()];
|
return [param('id').exists().isNumeric().toInt()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List sales receipts validation schema.
|
* List sales receipts validation schema.
|
||||||
*/
|
*/
|
||||||
get listSalesReceiptsValidationSchema() {
|
private get listSalesReceiptsValidationSchema() {
|
||||||
return [
|
return [
|
||||||
query('view_slug').optional().isString().trim(),
|
query('view_slug').optional().isString().trim(),
|
||||||
query('stringified_filter_roles').optional().isJSON(),
|
query('stringified_filter_roles').optional().isJSON(),
|
||||||
@@ -170,16 +162,21 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async newSaleReceipt(req: Request, res: Response, next: NextFunction) {
|
private async newSaleReceipt(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const saleReceiptDTO: ISaleReceiptDTO = this.matchedBodyData(req);
|
const saleReceiptDTO: ISaleReceiptDTO = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Store the given sale receipt details with associated entries.
|
// Store the given sale receipt details with associated entries.
|
||||||
const storedSaleReceipt = await this.saleReceiptService.createSaleReceipt(
|
const storedSaleReceipt =
|
||||||
tenantId,
|
await this.saleReceiptsApplication.createSaleReceipt(
|
||||||
saleReceiptDTO
|
tenantId,
|
||||||
);
|
saleReceiptDTO
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: storedSaleReceipt.id,
|
id: storedSaleReceipt.id,
|
||||||
message: 'Sale receipt has been created successfully.',
|
message: 'Sale receipt has been created successfully.',
|
||||||
@@ -194,13 +191,20 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async deleteSaleReceipt(req: Request, res: Response, next: NextFunction) {
|
private async deleteSaleReceipt(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: saleReceiptId } = req.params;
|
const { id: saleReceiptId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Deletes the sale receipt.
|
// Deletes the sale receipt.
|
||||||
await this.saleReceiptService.deleteSaleReceipt(tenantId, saleReceiptId);
|
await this.saleReceiptsApplication.deleteSaleReceipt(
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleReceiptId,
|
id: saleReceiptId,
|
||||||
@@ -217,14 +221,18 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Request} req -
|
* @param {Request} req -
|
||||||
* @param {Response} res -
|
* @param {Response} res -
|
||||||
*/
|
*/
|
||||||
async editSaleReceipt(req: Request, res: Response, next: NextFunction) {
|
private async editSaleReceipt(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: saleReceiptId } = req.params;
|
const { id: saleReceiptId } = req.params;
|
||||||
const saleReceipt = this.matchedBodyData(req);
|
const saleReceipt = this.matchedBodyData(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update the given sale receipt details.
|
// Update the given sale receipt details.
|
||||||
await this.saleReceiptService.editSaleReceipt(
|
await this.saleReceiptsApplication.editSaleReceipt(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleReceiptId,
|
saleReceiptId,
|
||||||
saleReceipt
|
saleReceipt
|
||||||
@@ -244,13 +252,20 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
* @param {NextFunction} next
|
* @param {NextFunction} next
|
||||||
*/
|
*/
|
||||||
async closeSaleReceipt(req: Request, res: Response, next: NextFunction) {
|
private async closeSaleReceipt(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const { id: saleReceiptId } = req.params;
|
const { id: saleReceiptId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update the given sale receipt details.
|
// Update the given sale receipt details.
|
||||||
await this.saleReceiptService.closeSaleReceipt(tenantId, saleReceiptId);
|
await this.saleReceiptsApplication.closeSaleReceipt(
|
||||||
|
tenantId,
|
||||||
|
saleReceiptId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleReceiptId,
|
id: saleReceiptId,
|
||||||
message: 'Sale receipt has been closed successfully.',
|
message: 'Sale receipt has been closed successfully.',
|
||||||
@@ -265,7 +280,11 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
* @param {Request} req
|
* @param {Request} req
|
||||||
* @param {Response} res
|
* @param {Response} res
|
||||||
*/
|
*/
|
||||||
async getSalesReceipts(req: Request, res: Response, next: NextFunction) {
|
private async getSalesReceipts(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
next: NextFunction
|
||||||
|
) {
|
||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
const filter = {
|
const filter = {
|
||||||
sortOrder: 'desc',
|
sortOrder: 'desc',
|
||||||
@@ -274,10 +293,9 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
pageSize: 12,
|
pageSize: 12,
|
||||||
...this.matchedQueryData(req),
|
...this.matchedQueryData(req),
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { data, pagination, filterMeta } =
|
const { data, pagination, filterMeta } =
|
||||||
await this.saleReceiptService.salesReceiptsList(tenantId, filter);
|
await this.saleReceiptsApplication.getSaleReceipts(tenantId, filter);
|
||||||
|
|
||||||
const response = this.transfromToResponse({
|
const response = this.transfromToResponse({
|
||||||
data,
|
data,
|
||||||
@@ -301,11 +319,10 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleReceipt = await this.saleReceiptService.getSaleReceipt(
|
const saleReceipt = await this.saleReceiptsApplication.getSaleReceipt(
|
||||||
tenantId,
|
tenantId,
|
||||||
saleReceiptId
|
saleReceiptId
|
||||||
);
|
);
|
||||||
|
|
||||||
res.format({
|
res.format({
|
||||||
'application/json': () => {
|
'application/json': () => {
|
||||||
return res
|
return res
|
||||||
@@ -313,10 +330,11 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
.send(this.transfromToResponse({ saleReceipt }));
|
.send(this.transfromToResponse({ saleReceipt }));
|
||||||
},
|
},
|
||||||
'application/pdf': async () => {
|
'application/pdf': async () => {
|
||||||
const pdfContent = await this.saleReceiptsPdf.saleReceiptPdf(
|
const pdfContent =
|
||||||
tenantId,
|
await this.saleReceiptsApplication.getSaleReceiptPdf(
|
||||||
saleReceipt
|
tenantId,
|
||||||
);
|
saleReceipt
|
||||||
|
);
|
||||||
res.set({
|
res.set({
|
||||||
'Content-Type': 'application/pdf',
|
'Content-Type': 'application/pdf',
|
||||||
'Content-Length': pdfContent.length,
|
'Content-Length': pdfContent.length,
|
||||||
@@ -344,10 +362,11 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
const { id: receiptId } = req.params;
|
const { id: receiptId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const saleReceipt = await this.saleReceiptSmsNotify.notifyBySms(
|
const saleReceipt =
|
||||||
tenantId,
|
await this.saleReceiptsApplication.saleReceiptNotifyBySms(
|
||||||
receiptId
|
tenantId,
|
||||||
);
|
receiptId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
id: saleReceipt.id,
|
id: saleReceipt.id,
|
||||||
message:
|
message:
|
||||||
@@ -373,10 +392,11 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
const { id: receiptId } = req.params;
|
const { id: receiptId } = req.params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const smsDetails = await this.saleReceiptSmsNotify.smsDetails(
|
const smsDetails =
|
||||||
tenantId,
|
await this.saleReceiptsApplication.getSaleReceiptSmsDetails(
|
||||||
receiptId
|
tenantId,
|
||||||
);
|
receiptId
|
||||||
|
);
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
data: smsDetails,
|
data: smsDetails,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { Container, Service } from 'typedi';
|
import { Container, Service } from 'typedi';
|
||||||
|
import SalesInvoices from './SalesInvoices'
|
||||||
import SalesEstimates from './SalesEstimates';
|
import SalesEstimates from './SalesEstimates';
|
||||||
import SalesReceipts from './SalesReceipts';
|
import SalesReceipts from './SalesReceipts';
|
||||||
import SalesInvoices from './SalesInvoices'
|
|
||||||
import PaymentReceives from './PaymentReceives';
|
|
||||||
import CreditNotes from './CreditNotes';
|
import CreditNotes from './CreditNotes';
|
||||||
|
import PaymentReceives from './PaymentReceives';
|
||||||
@Service()
|
@Service()
|
||||||
export default class SalesController {
|
export default class SalesController {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export default [
|
|||||||
parent_account_id: null,
|
parent_account_id: null,
|
||||||
index: 1,
|
index: 1,
|
||||||
active: 1,
|
active: 1,
|
||||||
description:'An account that holds valuation of products or goods that availiable for sale.',
|
description:'An account that holds valuation of products or goods that available for sale.',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Libilities
|
// Libilities
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export interface IAccountTransaction {
|
|||||||
date: string | Date;
|
date: string | Date;
|
||||||
|
|
||||||
referenceType: string;
|
referenceType: string;
|
||||||
|
referenceTypeFormatted: string;
|
||||||
referenceId: number;
|
referenceId: number;
|
||||||
|
|
||||||
referenceNumber?: string;
|
referenceNumber?: string;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export interface IBillCreatedPayload {
|
|||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IBillCreatingPayload{
|
export interface IBillCreatingPayload {
|
||||||
tenantId: number;
|
tenantId: number;
|
||||||
billDTO: IBillDTO;
|
billDTO: IBillDTO;
|
||||||
trx: Knex.Transaction;
|
trx: Knex.Transaction;
|
||||||
@@ -138,3 +138,16 @@ export enum BillAction {
|
|||||||
View = 'View',
|
View = 'View',
|
||||||
NotifyBySms = 'NotifyBySms',
|
NotifyBySms = 'NotifyBySms',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IBillOpeningPayload {
|
||||||
|
trx: Knex.Transaction;
|
||||||
|
tenantId: number;
|
||||||
|
oldBill: IBill;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IBillOpenedPayload {
|
||||||
|
trx: Knex.Transaction;
|
||||||
|
bill: IBill;
|
||||||
|
oldBill: IBill;
|
||||||
|
tenantId: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export interface ICashFlowStatementAccountMeta {
|
|||||||
code: string;
|
code: string;
|
||||||
total: ICashFlowStatementTotal;
|
total: ICashFlowStatementTotal;
|
||||||
accountType: string;
|
accountType: string;
|
||||||
adjusmentType: string;
|
adjustmentType: string;
|
||||||
sectionType: ICashFlowStatementSectionType.ACCOUNT;
|
sectionType: ICashFlowStatementSectionType.ACCOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ISystemUser } from '@/interfaces';
|
|
||||||
import { Knex } from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { pick } from 'lodash';
|
import { ISystemUser } from '@/interfaces';
|
||||||
import { ILedgerEntry } from './Ledger';
|
import { ILedgerEntry } from './Ledger';
|
||||||
import { ISaleInvoice } from './SaleInvoice';
|
import { ISaleInvoice } from './SaleInvoice';
|
||||||
|
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ export interface ISaleInvoiceEventDeliveredPayload {
|
|||||||
tenantId: number;
|
tenantId: number;
|
||||||
saleInvoiceId: number;
|
saleInvoiceId: number;
|
||||||
saleInvoice: ISaleInvoice;
|
saleInvoice: ISaleInvoice;
|
||||||
|
trx: Knex.Transaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISaleInvoiceDeliveringPayload {
|
export interface ISaleInvoiceDeliveringPayload {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Container } from 'typedi';
|
import { Container } from 'typedi';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import SalesInvoicesCost from '@/services/Sales/SalesInvoicesCost';
|
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import { SaleInvoicesCost } from '@/services/Sales/Invoices/SalesInvoicesCost';
|
||||||
|
|
||||||
export default class WriteInvoicesJournalEntries {
|
export default class WriteInvoicesJournalEntries {
|
||||||
eventPublisher: EventPublisher;
|
eventPublisher: EventPublisher;
|
||||||
@@ -26,7 +26,7 @@ export default class WriteInvoicesJournalEntries {
|
|||||||
*/
|
*/
|
||||||
public async handler(job, done: Function): Promise<void> {
|
public async handler(job, done: Function): Promise<void> {
|
||||||
const { startingDate, tenantId } = job.attrs.data;
|
const { startingDate, tenantId } = job.attrs.data;
|
||||||
const salesInvoicesCost = Container.get(SalesInvoicesCost);
|
const salesInvoicesCost = Container.get(SaleInvoicesCost);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await salesInvoicesCost.writeCostLotsGLEntries(tenantId, startingDate);
|
await salesInvoicesCost.writeCostLotsGLEntries(tenantId, startingDate);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { forEach, uniqBy } from 'lodash';
|
import { forEach, uniqBy } from 'lodash';
|
||||||
import DynamicFilterAbstructor from './DynamicFilterAbstructor';
|
import DynamicFilterAbstractor from './DynamicFilterAbstractor';
|
||||||
import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces';
|
import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces';
|
||||||
|
|
||||||
export default class DynamicFilter extends DynamicFilterAbstructor{
|
export default class DynamicFilter extends DynamicFilterAbstractor{
|
||||||
private model: IModel;
|
private model: IModel;
|
||||||
private tableName: string;
|
private tableName: string;
|
||||||
private dynamicFilters: IDynamicFilter[];
|
private dynamicFilters: IDynamicFilter[];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
export default class DynamicFilterAbstructor {
|
export default class DynamicFilterAbstractor {
|
||||||
/**
|
/**
|
||||||
* Extract relation table name from relation.
|
* Extract relation table name from relation.
|
||||||
* @param {String} column -
|
* @param {String} column -
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
|
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
|
||||||
import { IFilterRole } from '@/interfaces';
|
import { IFilterRole } from '@/interfaces';
|
||||||
|
|
||||||
export default class FilterRoles extends DynamicFilterRoleAbstructor {
|
export default class FilterRoles extends DynamicFilterRoleAbstractor {
|
||||||
private filterRoles: IFilterRole[];
|
private filterRoles: IFilterRole[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import DynamicFilterQueryParser from './DynamicFilterQueryParser';
|
|||||||
import { Lexer } from '../LogicEvaluation/Lexer';
|
import { Lexer } from '../LogicEvaluation/Lexer';
|
||||||
import { COMPARATOR_TYPE, FIELD_TYPE } from './constants';
|
import { COMPARATOR_TYPE, FIELD_TYPE } from './constants';
|
||||||
|
|
||||||
export default abstract class DynamicFilterAbstructor
|
export default abstract class DynamicFilterAbstractor
|
||||||
implements IDynamicFilter
|
implements IDynamicFilter
|
||||||
{
|
{
|
||||||
protected filterRoles: IFilterRole[] = [];
|
protected filterRoles: IFilterRole[] = [];
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
|
||||||
import { FIELD_TYPE } from './constants';
|
import { FIELD_TYPE } from './constants';
|
||||||
|
|
||||||
interface ISortRole {
|
interface ISortRole {
|
||||||
@@ -6,7 +6,7 @@ interface ISortRole {
|
|||||||
order: string;
|
order: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstructor {
|
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstractor {
|
||||||
private sortRole: ISortRole = {};
|
private sortRole: ISortRole = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { omit } from 'lodash';
|
import { omit } from 'lodash';
|
||||||
import { IView, IViewRole } from '@/interfaces';
|
import { IView, IViewRole } from '@/interfaces';
|
||||||
import DynamicFilterRoleAbstructor from './DynamicFilterRoleAbstructor';
|
import DynamicFilterRoleAbstractor from './DynamicFilterRoleAbstractor';
|
||||||
|
|
||||||
export default class DynamicFilterViews extends DynamicFilterRoleAbstructor {
|
export default class DynamicFilterViews extends DynamicFilterRoleAbstractor {
|
||||||
private viewSlug: string;
|
private viewSlug: string;
|
||||||
private logicExpression: string;
|
private logicExpression: string;
|
||||||
private filterRoles: IViewRole[];
|
private filterRoles: IViewRole[];
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
import DynamicFilterRoleAbstractor from '@/lib/DynamicFilter/DynamicFilterRoleAbstractor';
|
||||||
import {
|
import {
|
||||||
validateViewRoles,
|
validateViewRoles,
|
||||||
buildFilterQuery,
|
buildFilterQuery,
|
||||||
} from '@/lib/ViewRolesBuilder';
|
} from '@/lib/ViewRolesBuilder';
|
||||||
|
|
||||||
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstructor {
|
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstractor {
|
||||||
/**
|
/**
|
||||||
* Constructor method.
|
* Constructor method.
|
||||||
* @param {*} filterRoles -
|
* @param {*} filterRoles -
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
|
||||||
import ItemSubscriber from '@/subscribers/Items/ItemSubscriber';
|
|
||||||
import InventoryAdjustmentsSubscriber from '@/subscribers/Inventory/InventoryAdjustment';
|
import InventoryAdjustmentsSubscriber from '@/subscribers/Inventory/InventoryAdjustment';
|
||||||
import BillWriteInventoryTransactionsSubscriber from '@/subscribers/Bills/WriteInventoryTransactions';
|
import BillWriteInventoryTransactionsSubscriber from '@/subscribers/Bills/WriteInventoryTransactions';
|
||||||
import PaymentSyncBillBalance from '@/subscribers/PaymentMades/PaymentSyncBillBalance';
|
import PaymentSyncBillBalance from '@/subscribers/PaymentMades/PaymentSyncBillBalance';
|
||||||
import SaleReceiptInventoryTransactionsSubscriber from '@/subscribers/SaleReceipt/WriteInventoryTransactions';
|
import SaleReceiptInventoryTransactionsSubscriber from '@/subscribers/SaleReceipt/WriteInventoryTransactions';
|
||||||
import SaleInvoiceWriteInventoryTransactions from '@/subscribers/SaleInvoices/WriteInventoryTransactions';
|
import SaleInvoiceWriteInventoryTransactions from '@/subscribers/SaleInvoices/WriteInventoryTransactions';
|
||||||
import SaleInvoiceWriteGLEntriesSubscriber from '@/subscribers/SaleInvoices/WriteJournalEntries';
|
import SaleInvoiceWriteGLEntriesSubscriber from '@/subscribers/SaleInvoices/WriteJournalEntries';
|
||||||
|
import SaleReceiptWriteGLEntriesSubscriber from '@/subscribers/SaleReceipt/WriteJournalEntries';
|
||||||
import PaymentReceiveSyncInvoices from '@/subscribers/PaymentReceive/PaymentReceiveSyncInvoices';
|
import PaymentReceiveSyncInvoices from '@/subscribers/PaymentReceive/PaymentReceiveSyncInvoices';
|
||||||
import CashflowTransactionSubscriber from '@/services/Cashflow/CashflowTransactionSubscriber';
|
import CashflowTransactionSubscriber from '@/services/Cashflow/CashflowTransactionSubscriber';
|
||||||
import PaymentReceivesWriteGLEntriesSubscriber from '@/subscribers/PaymentReceive/WriteGLEntries';
|
import PaymentReceivesWriteGLEntriesSubscriber from '@/subscribers/PaymentReceive/WriteGLEntries';
|
||||||
import InventorySubscriber from '@/subscribers/Inventory/Inventory';
|
import InventorySubscriber from '@/subscribers/Inventory/Inventory';
|
||||||
import SaleReceiptWriteGLEntriesSubscriber from '@/subscribers/SaleReceipt/WriteJournalEntries';
|
|
||||||
import { CustomerWriteGLOpeningBalanceSubscriber } from '@/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber';
|
import { CustomerWriteGLOpeningBalanceSubscriber } from '@/services/Contacts/Customers/Subscribers/CustomerGLEntriesSubscriber';
|
||||||
import { VendorsWriteGLOpeningSubscriber } from '@/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber';
|
import { VendorsWriteGLOpeningSubscriber } from '@/services/Contacts/Vendors/Subscribers/VendorGLEntriesSubscriber';
|
||||||
import SaleEstimateAutoSerialSubscriber from '@/subscribers/SaleEstimate/AutoIncrementSerial';
|
import SaleEstimateAutoSerialSubscriber from '@/subscribers/SaleEstimate/AutoIncrementSerial';
|
||||||
@@ -35,7 +34,7 @@ import PurgeAuthorizedUserOnceRoleMutate from '@/services/Roles/PurgeAuthorizedU
|
|||||||
import SendSmsNotificationToCustomer from '@/subscribers/SaleInvoices/SendSmsNotificationToCustomer';
|
import SendSmsNotificationToCustomer from '@/subscribers/SaleInvoices/SendSmsNotificationToCustomer';
|
||||||
import SendSmsNotificationSaleReceipt from '@/subscribers/SaleReceipt/SendSmsNotificationToCustomer';
|
import SendSmsNotificationSaleReceipt from '@/subscribers/SaleReceipt/SendSmsNotificationToCustomer';
|
||||||
import SendSmsNotificationPaymentReceive from '@/subscribers/PaymentReceive/SendSmsNotificationToCustomer';
|
import SendSmsNotificationPaymentReceive from '@/subscribers/PaymentReceive/SendSmsNotificationToCustomer';
|
||||||
import SaleInvoiceWriteoffSubscriber from '@/services/Sales/SaleInvoiceWriteoffSubscriber';
|
import SaleInvoiceWriteoffSubscriber from '@/services/Sales/Invoices/SaleInvoiceWriteoffSubscriber';
|
||||||
import LandedCostSyncCostTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber';
|
import LandedCostSyncCostTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostSyncCostTransactionsSubscriber';
|
||||||
import LandedCostInventoryTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber';
|
import LandedCostInventoryTransactionsSubscriber from '@/services/Purchases/LandedCost/LandedCostInventoryTransactionsSubscriber';
|
||||||
import CreditNoteGLEntriesSubscriber from '@/services/CreditNotes/CreditNoteGLEntriesSubscriber';
|
import CreditNoteGLEntriesSubscriber from '@/services/CreditNotes/CreditNoteGLEntriesSubscriber';
|
||||||
@@ -66,7 +65,6 @@ import { ActivateWarehousesSubscriber } from '@/services/Warehouses/ActivateWare
|
|||||||
import { ManualJournalWriteGLSubscriber } from '@/services/ManualJournals/ManualJournalGLEntriesSubscriber';
|
import { ManualJournalWriteGLSubscriber } from '@/services/ManualJournals/ManualJournalGLEntriesSubscriber';
|
||||||
import { BillGLEntriesSubscriber } from '@/services/Purchases/Bills/BillGLEntriesSubscriber';
|
import { BillGLEntriesSubscriber } from '@/services/Purchases/Bills/BillGLEntriesSubscriber';
|
||||||
import { PaymentWriteGLEntriesSubscriber } from '@/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber';
|
import { PaymentWriteGLEntriesSubscriber } from '@/services/Purchases/BillPayments/BillPaymentGLEntriesSubscriber';
|
||||||
|
|
||||||
import BranchesIntegrationsSubscribers from '@/services/Branches/EventsProvider';
|
import BranchesIntegrationsSubscribers from '@/services/Branches/EventsProvider';
|
||||||
import WarehousesIntegrationsSubscribers from '@/services/Warehouses/EventsProvider';
|
import WarehousesIntegrationsSubscribers from '@/services/Warehouses/EventsProvider';
|
||||||
import { WarehouseTransferAutoIncrementSubscriber } from '@/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber';
|
import { WarehouseTransferAutoIncrementSubscriber } from '@/services/Warehouses/WarehousesTransfers/WarehouseTransferAutoIncrementSubscriber';
|
||||||
@@ -88,7 +86,6 @@ export default () => {
|
|||||||
|
|
||||||
export const susbcribers = () => {
|
export const susbcribers = () => {
|
||||||
return [
|
return [
|
||||||
ItemSubscriber,
|
|
||||||
InventoryAdjustmentsSubscriber,
|
InventoryAdjustmentsSubscriber,
|
||||||
BillWriteInventoryTransactionsSubscriber,
|
BillWriteInventoryTransactionsSubscriber,
|
||||||
PaymentSyncBillBalance,
|
PaymentSyncBillBalance,
|
||||||
|
|||||||
@@ -152,7 +152,7 @@
|
|||||||
"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 available 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.": "لا ترتبط انشطة الدخل إلى الأعمال الأساسية.",
|
||||||
|
|||||||
@@ -151,7 +151,7 @@
|
|||||||
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
"Opening Balance Liabilities": "Opening Balance Liabilities",
|
||||||
"Loan": "Loan",
|
"Loan": "Loan",
|
||||||
"Owner A Drawings": "Owner A Drawings",
|
"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.",
|
"An account that holds valuation of products or goods that available for sale.": "An account that holds valuation of products or goods that available for sale.",
|
||||||
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
|
"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.",
|
"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.",
|
"The income activities are not associated to the core business.": "The income activities are not associated to the core business.",
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export default class Account extends mixin(TenantModel, [
|
|||||||
},
|
},
|
||||||
filterAccountTypes(query, typesIds) {
|
filterAccountTypes(query, typesIds) {
|
||||||
if (typesIds.length > 0) {
|
if (typesIds.length > 0) {
|
||||||
query.whereIn('account_types.accoun_type_id', typesIds);
|
query.whereIn('account_types.account_type_id', typesIds);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
viewRolesBuilder(query, conditionals, expression) {
|
viewRolesBuilder(query, conditionals, expression) {
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ import { Model, raw } from 'objection';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { isEmpty, castArray } from 'lodash';
|
import { isEmpty, castArray } from 'lodash';
|
||||||
import TenantModel from 'models/TenantModel';
|
import TenantModel from 'models/TenantModel';
|
||||||
|
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||||
|
|
||||||
export default class AccountTransaction extends TenantModel {
|
export default class AccountTransaction extends TenantModel {
|
||||||
|
referenceType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
*/
|
*/
|
||||||
@@ -30,40 +33,7 @@ export default class AccountTransaction extends TenantModel {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
get referenceTypeFormatted() {
|
get referenceTypeFormatted() {
|
||||||
return AccountTransaction.getReferenceTypeFormatted(this.referenceType);
|
return getTransactionTypeLabel(this.referenceType);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference type formatted.
|
|
||||||
*/
|
|
||||||
static getReferenceTypeFormatted(referenceType) {
|
|
||||||
const mapped = {
|
|
||||||
SaleInvoice: 'Sale invoice',
|
|
||||||
SaleReceipt: 'Sale receipt',
|
|
||||||
PaymentReceive: 'Payment receive',
|
|
||||||
Bill: 'Bill',
|
|
||||||
BillPayment: 'Payment made',
|
|
||||||
VendorOpeningBalance: 'Vendor opening balance',
|
|
||||||
CustomerOpeningBalance: 'Customer opening balance',
|
|
||||||
InventoryAdjustment: 'Inventory adjustment',
|
|
||||||
ManualJournal: 'Manual journal',
|
|
||||||
Journal: 'Manual journal',
|
|
||||||
Expense: 'Expense',
|
|
||||||
OwnerContribution: 'Owner contribution',
|
|
||||||
TransferToAccount: 'Transfer to account',
|
|
||||||
TransferFromAccount: 'Transfer from account',
|
|
||||||
OtherIncome: 'Other income',
|
|
||||||
OtherExpense: 'Other expense',
|
|
||||||
OwnerDrawing: 'Owner drawing',
|
|
||||||
InvoiceWriteOff: 'Invoice write-off',
|
|
||||||
|
|
||||||
CreditNote: 'transaction_type.credit_note',
|
|
||||||
VendorCredit: 'transaction_type.vendor_credit',
|
|
||||||
|
|
||||||
RefundCreditNote: 'transaction_type.refund_credit_note',
|
|
||||||
RefundVendorCredit: 'transaction_type.refund_vendor_credit',
|
|
||||||
};
|
|
||||||
return mapped[referenceType] || '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import TenantModel from 'models/TenantModel';
|
|||||||
import BillSettings from './Bill.Settings';
|
import BillSettings from './Bill.Settings';
|
||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from '@/services/Purchases/constants';
|
import { DEFAULT_VIEWS } from '@/services/Purchases/Bills/constants';
|
||||||
import ModelSearchable from './ModelSearchable';
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class Bill extends mixin(TenantModel, [
|
export default class Bill extends mixin(TenantModel, [
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ export default class Branch extends TenantModel {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Branch may belongs to assocaited bills.
|
* Branch may belongs to associated bills.
|
||||||
*/
|
*/
|
||||||
bills: {
|
bills: {
|
||||||
relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export default class CashflowTransaction extends TenantModel {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cashflow transaction may has assocaited cashflow account.
|
* Cashflow transaction may has associated cashflow account.
|
||||||
*/
|
*/
|
||||||
cashflowAccount: {
|
cashflowAccount: {
|
||||||
relation: Model.BelongsToOneRelation,
|
relation: Model.BelongsToOneRelation,
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
import { Model, raw } from 'objection';
|
import { Model, raw } from 'objection';
|
||||||
import { castArray, isEmpty } from 'lodash';
|
import { castArray } from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import TenantModel from 'models/TenantModel';
|
import TenantModel from 'models/TenantModel';
|
||||||
|
import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||||
|
|
||||||
export default class InventoryTransaction extends TenantModel {
|
export default class InventoryTransaction extends TenantModel {
|
||||||
|
transactionId: number;
|
||||||
|
transactionType: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table name
|
* Table name
|
||||||
*/
|
*/
|
||||||
@@ -23,27 +27,7 @@ export default class InventoryTransaction extends TenantModel {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
get transcationTypeFormatted() {
|
get transcationTypeFormatted() {
|
||||||
return InventoryTransaction.getReferenceTypeFormatted(this.transactionType);
|
return getTransactionTypeLabel(this.transactionType);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reference type formatted.
|
|
||||||
*/
|
|
||||||
static getReferenceTypeFormatted(referenceType) {
|
|
||||||
const mapped = {
|
|
||||||
SaleInvoice: 'Sale invoice',
|
|
||||||
SaleReceipt: 'Sale receipt',
|
|
||||||
PaymentReceive: 'Payment receive',
|
|
||||||
Bill: 'Bill',
|
|
||||||
BillPayment: 'Payment made',
|
|
||||||
VendorOpeningBalance: 'Vendor opening balance',
|
|
||||||
CustomerOpeningBalance: 'Customer opening balance',
|
|
||||||
InventoryAdjustment: 'Inventory adjustment',
|
|
||||||
ManualJournal: 'Manual journal',
|
|
||||||
Journal: 'Manual journal',
|
|
||||||
LandedCost: 'transaction_type.landed_cost',
|
|
||||||
};
|
|
||||||
return mapped[referenceType] || '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import TenantModel from 'models/TenantModel';
|
|||||||
import ModelSetting from './ModelSetting';
|
import ModelSetting from './ModelSetting';
|
||||||
import SaleInvoiceMeta from './SaleInvoice.Settings';
|
import SaleInvoiceMeta from './SaleInvoice.Settings';
|
||||||
import CustomViewBaseModel from './CustomViewBaseModel';
|
import CustomViewBaseModel from './CustomViewBaseModel';
|
||||||
import { DEFAULT_VIEWS } from '@/services/Sales/constants';
|
import { DEFAULT_VIEWS } from '@/services/Sales/Invoices/constants';
|
||||||
import ModelSearchable from './ModelSearchable';
|
import ModelSearchable from './ModelSearchable';
|
||||||
|
|
||||||
export default class SaleInvoice extends mixin(TenantModel, [
|
export default class SaleInvoice extends mixin(TenantModel, [
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export default class Warehouse extends TenantModel {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warehouse may belongs to assocaited bills.
|
* Warehouse may belongs to associated bills.
|
||||||
*/
|
*/
|
||||||
bills: {
|
bills: {
|
||||||
relation: Model.HasManyRelation,
|
relation: Model.HasManyRelation,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import { InventoryTransactionsWarehouses } from './AcountsTransactionsWarehouses';
|
import { InventoryTransactionsWarehouses } from './AccountsTransactionsWarehouses';
|
||||||
import { IBranchesActivatedPayload } from '@/interfaces';
|
import { IBranchesActivatedPayload } from '@/interfaces';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default class JournalPoster implements IJournalPoster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async initialize acccounts dependency graph.
|
* Async initialize accounts dependency graph.
|
||||||
* @private
|
* @private
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ export class LedgerContactsBalanceStorage {
|
|||||||
): Promise<(entry: ILedgerEntry) => boolean> => {
|
): Promise<(entry: ILedgerEntry) => boolean> => {
|
||||||
const { Account } = this.tenancy.models(tenantId);
|
const { Account } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
const ARAPAcounts = await Account.query(trx).whereIn('accountType', [
|
const ARAPAccounts = await Account.query(trx).whereIn('accountType', [
|
||||||
ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE,
|
ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE,
|
||||||
ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
|
ACCOUNT_TYPE.ACCOUNTS_PAYABLE,
|
||||||
]);
|
]);
|
||||||
const ARAPAcountsIds = ARAPAcounts.map((a) => a.id);
|
const ARAPAccountsIds = ARAPAccounts.map((a) => a.id);
|
||||||
|
|
||||||
return (entry: ILedgerEntry) => {
|
return (entry: ILedgerEntry) => {
|
||||||
return ARAPAcountsIds.indexOf(entry.accountId) !== -1;
|
return ARAPAccountsIds.indexOf(entry.accountId) !== -1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default class LedgerStorageService {
|
|||||||
// Saves the ledger entries.
|
// Saves the ledger entries.
|
||||||
this.ledgerEntriesService.saveEntries(tenantId, ledger, trx),
|
this.ledgerEntriesService.saveEntries(tenantId, ledger, trx),
|
||||||
|
|
||||||
// Mutates the assocaited accounts balances.
|
// Mutates the associated accounts balances.
|
||||||
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
||||||
|
|
||||||
// Mutates the associated contacts balances.
|
// Mutates the associated contacts balances.
|
||||||
@@ -60,7 +60,7 @@ export default class LedgerStorageService {
|
|||||||
// Deletes the ledger entries.
|
// Deletes the ledger entries.
|
||||||
this.ledgerEntriesService.deleteEntries(tenantId, ledger, trx),
|
this.ledgerEntriesService.deleteEntries(tenantId, ledger, trx),
|
||||||
|
|
||||||
// Mutates the assocaited accounts balances.
|
// Mutates the associated accounts balances.
|
||||||
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
this.ledgerAccountsBalance.saveAccountsBalance(tenantId, ledger, trx),
|
||||||
|
|
||||||
// Mutates the associated contacts balances.
|
// Mutates the associated contacts balances.
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export class LedegrAccountsStorage {
|
|||||||
const { Account } = this.tenancy.models(tenantId);
|
const { Account } = this.tenancy.models(tenantId);
|
||||||
const account = await Account.query(trx).findById(accountId);
|
const account = await Account.query(trx).findById(accountId);
|
||||||
|
|
||||||
// Filters the ledger entries by the current acount.
|
// Filters the ledger entries by the current account.
|
||||||
const accountLedger = ledger.whereAccountId(accountId);
|
const accountLedger = ledger.whereAccountId(accountId);
|
||||||
|
|
||||||
// Retrieves the given tenant metadata.
|
// Retrieves the given tenant metadata.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default class AccountTransactionTransformer extends Transformer {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
public transactionTypeFormatted(transaction: IAccountTransaction) {
|
public transactionTypeFormatted(transaction: IAccountTransaction) {
|
||||||
return transaction.referenceTypeFormatted;
|
return this.context.i18n.__(transaction.referenceTypeFormatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ export class DeleteAccount {
|
|||||||
// Authorize before delete account.
|
// Authorize before delete account.
|
||||||
await this.authorize(tenantId, accountId, oldAccount);
|
await this.authorize(tenantId, accountId, oldAccount);
|
||||||
|
|
||||||
// Deletes the account and assocaited transactions under UOW envirement.
|
// Deletes the account and associated transactions under UOW envirement.
|
||||||
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
||||||
// Triggers `onAccountDelete` event.
|
// Triggers `onAccountDelete` event.
|
||||||
await this.eventPublisher.emitAsync(events.accounts.onDelete, {
|
await this.eventPublisher.emitAsync(events.accounts.onDelete, {
|
||||||
|
|||||||
@@ -23,15 +23,6 @@ export class GetAccounts {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private transformer: TransformerInjectable;
|
private transformer: TransformerInjectable;
|
||||||
|
|
||||||
/**
|
|
||||||
* Parsees accounts list filter DTO.
|
|
||||||
* @param filterDTO
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
private parseListFilterDTO(filterDTO) {
|
|
||||||
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve accounts datatable list.
|
* Retrieve accounts datatable list.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -75,4 +66,13 @@ export class GetAccounts {
|
|||||||
filterMeta: dynamicList.getResponseMeta(),
|
filterMeta: dynamicList.getResponseMeta(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsees accounts list filter DTO.
|
||||||
|
* @param filterDTO
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private parseListFilterDTO(filterDTO) {
|
||||||
|
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export class AccountsReceivableRepository {
|
|
||||||
|
|
||||||
|
|
||||||
findOrCreateAccount = (currencyCode?: string) => {
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@ import { IBranchDeletedPayload, IBranchDeletePayload } from '@/interfaces';
|
|||||||
import { CURDBranch } from './CRUDBranch';
|
import { CURDBranch } from './CRUDBranch';
|
||||||
import { BranchValidator } from './BranchValidate';
|
import { BranchValidator } from './BranchValidate';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class DeleteBranch extends CURDBranch {
|
export class DeleteBranch extends CURDBranch {
|
||||||
@Inject()
|
@Inject()
|
||||||
|
|||||||
@@ -40,10 +40,8 @@ export class ValidateBranchExistance {
|
|||||||
tenantId: number,
|
tenantId: number,
|
||||||
branchId: number | null
|
branchId: number | null
|
||||||
) => {
|
) => {
|
||||||
//
|
|
||||||
this.validateBranchIdExistance(branchId);
|
this.validateBranchIdExistance(branchId);
|
||||||
|
|
||||||
//
|
|
||||||
await this.validateBranchExistance(tenantId, branchId);
|
await this.validateBranchExistance(tenantId, branchId);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +60,10 @@ export class ValidateBranchExistance {
|
|||||||
* @param tenantId
|
* @param tenantId
|
||||||
* @param branchId
|
* @param branchId
|
||||||
*/
|
*/
|
||||||
public validateBranchExistance = async (tenantId: number, branchId: number) => {
|
public validateBranchExistance = async (
|
||||||
|
tenantId: number,
|
||||||
|
branchId: number
|
||||||
|
) => {
|
||||||
const { Branch } = this.tenancy.models(tenantId);
|
const { Branch } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
const branch = await Branch.query().findById(branchId);
|
const branch = await Branch.query().findById(branchId);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export * from './CashflowBranchesActviateSubscriber';
|
export * from './CashflowBranchesActivateSubscriber';
|
||||||
export * from './CreditNoteBranchesActivateSubscriber';
|
export * from './CreditNoteBranchesActivateSubscriber';
|
||||||
export * from './PaymentMadeBranchesActivateSubscriber';
|
export * from './PaymentMadeBranchesActivateSubscriber';
|
||||||
export * from './PaymentReceiveBranchesActivateSubscriber';
|
export * from './PaymentReceiveBranchesActivateSubscriber';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the given transaction type to transformed to properiate format.
|
* Ensures the given transaction type to transformed to appropriate format.
|
||||||
* @param {string} type
|
* @param {string} type
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,16 +16,16 @@ import BaseCreditNotes from './CreditNotes';
|
|||||||
@Service()
|
@Service()
|
||||||
export default class CreateCreditNote extends BaseCreditNotes {
|
export default class CreateCreditNote extends BaseCreditNotes {
|
||||||
@Inject()
|
@Inject()
|
||||||
uow: UnitOfWork;
|
private uow: UnitOfWork;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
itemsEntriesService: ItemsEntriesService;
|
private itemsEntriesService: ItemsEntriesService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new credit note.
|
* Creates a new credit note.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import {
|
import {
|
||||||
IApplyCreditToInvoicesCreatedPayload,
|
IApplyCreditToInvoicesCreatedPayload,
|
||||||
@@ -10,15 +9,12 @@ import CreditNoteApplySyncInvoicesCreditedAmount from './CreditNoteApplySyncInvo
|
|||||||
@Service()
|
@Service()
|
||||||
export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber {
|
export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: HasTenancyService;
|
private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
|
||||||
|
|
||||||
@Inject()
|
|
||||||
syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches events with handlers.
|
* Attaches events with handlers.
|
||||||
*/
|
*/
|
||||||
attach(bus) {
|
public attach(bus) {
|
||||||
bus.subscribe(
|
bus.subscribe(
|
||||||
events.creditNote.onApplyToInvoicesCreated,
|
events.creditNote.onApplyToInvoicesCreated,
|
||||||
this.incrementAppliedInvoicesOnceCreditCreated
|
this.incrementAppliedInvoicesOnceCreditCreated
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import Knex from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { sumBy } from 'lodash';
|
import { sumBy } from 'lodash';
|
||||||
import {
|
import {
|
||||||
ICreditNote,
|
ICreditNote,
|
||||||
@@ -8,27 +8,31 @@ import {
|
|||||||
ISaleInvoice,
|
ISaleInvoice,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import PaymentReceiveService from '@/services/Sales/PaymentReceives/PaymentsReceives';
|
|
||||||
import UnitOfWork from '@/services/UnitOfWork';
|
import UnitOfWork from '@/services/UnitOfWork';
|
||||||
import events from '@/subscribers/events';
|
import { PaymentReceiveValidators } from '../Sales/PaymentReceives/PaymentReceiveValidators';
|
||||||
import BaseCreditNotes from './CreditNotes';
|
import BaseCreditNotes from './CreditNotes';
|
||||||
import {
|
import {
|
||||||
IApplyCreditToInvoicesDTO,
|
IApplyCreditToInvoicesDTO,
|
||||||
IApplyCreditToInvoicesCreatedPayload,
|
IApplyCreditToInvoicesCreatedPayload,
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class CreditNoteApplyToInvoices extends BaseCreditNotes {
|
export default class CreditNoteApplyToInvoices extends BaseCreditNotes {
|
||||||
@Inject('PaymentReceives')
|
@Inject()
|
||||||
paymentReceive: PaymentReceiveService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
uow: UnitOfWork;
|
private paymentReceiveValidators: PaymentReceiveValidators;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
eventPublisher: EventPublisher;
|
private uow: UnitOfWork;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply credit note to the given invoices.
|
* Apply credit note to the given invoices.
|
||||||
@@ -50,7 +54,7 @@ export default class CreditNoteApplyToInvoices extends BaseCreditNotes {
|
|||||||
);
|
);
|
||||||
// Retrieve the applied invoices that associated to the credit note customer.
|
// Retrieve the applied invoices that associated to the credit note customer.
|
||||||
const appliedInvoicesEntries =
|
const appliedInvoicesEntries =
|
||||||
await this.paymentReceive.validateInvoicesIDsExistance(
|
await this.paymentReceiveValidators.validateInvoicesIDsExistance(
|
||||||
tenantId,
|
tenantId,
|
||||||
creditNote.customerId,
|
creditNote.customerId,
|
||||||
applyCreditToInvoicesDTO.entries
|
applyCreditToInvoicesDTO.entries
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Attaches events with publisher.
|
* Attaches events with publisher.
|
||||||
*/
|
*/
|
||||||
attach(bus) {
|
public attach(bus) {
|
||||||
bus.subscribe(
|
bus.subscribe(
|
||||||
events.creditNote.onCreated,
|
events.creditNote.onCreated,
|
||||||
this.writeInventoryTranscationsOnceCreated
|
this.writeInventoryTranscationsOnceCreated
|
||||||
@@ -37,6 +37,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Writes inventory transactions once credit note created.
|
* Writes inventory transactions once credit note created.
|
||||||
* @param {ICreditNoteCreatedPayload} payload -
|
* @param {ICreditNoteCreatedPayload} payload -
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public writeInventoryTranscationsOnceCreated = async ({
|
public writeInventoryTranscationsOnceCreated = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -44,9 +45,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
trx,
|
trx,
|
||||||
}: ICreditNoteCreatedPayload) => {
|
}: ICreditNoteCreatedPayload) => {
|
||||||
// Can't continue if the credit note is open yet.
|
// Can't continue if the credit note is open yet.
|
||||||
if (!creditNote.isOpen) {
|
if (!creditNote.isOpen) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.inventoryTransactions.createInventoryTransactions(
|
await this.inventoryTransactions.createInventoryTransactions(
|
||||||
tenantId,
|
tenantId,
|
||||||
creditNote,
|
creditNote,
|
||||||
@@ -57,6 +57,7 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Rewrites inventory transactions once credit note edited.
|
* Rewrites inventory transactions once credit note edited.
|
||||||
* @param {ICreditNoteEditedPayload} payload -
|
* @param {ICreditNoteEditedPayload} payload -
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
public rewriteInventoryTransactionsOnceEdited = async ({
|
public rewriteInventoryTransactionsOnceEdited = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -65,9 +66,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
trx,
|
trx,
|
||||||
}: ICreditNoteEditedPayload) => {
|
}: ICreditNoteEditedPayload) => {
|
||||||
// Can't continue if the credit note is open yet.
|
// Can't continue if the credit note is open yet.
|
||||||
if (!creditNote.isOpen) {
|
if (!creditNote.isOpen) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.inventoryTransactions.editInventoryTransactions(
|
await this.inventoryTransactions.editInventoryTransactions(
|
||||||
tenantId,
|
tenantId,
|
||||||
creditNoteId,
|
creditNoteId,
|
||||||
@@ -87,9 +87,8 @@ export default class CreditNoteInventoryTransactionsSubscriber {
|
|||||||
trx,
|
trx,
|
||||||
}: ICreditNoteDeletedPayload) => {
|
}: ICreditNoteDeletedPayload) => {
|
||||||
// Can't continue if the credit note is open yet.
|
// Can't continue if the credit note is open yet.
|
||||||
if (!oldCreditNote.isOpen) {
|
if (!oldCreditNote.isOpen) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.inventoryTransactions.deleteInventoryTransactions(
|
await this.inventoryTransactions.deleteInventoryTransactions(
|
||||||
tenantId,
|
tenantId,
|
||||||
creditNoteId,
|
creditNoteId,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default class CreditNoteInventoryTransactions {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits vendor credit assocaited inventory transactions.
|
* Edits vendor credit associated inventory transactions.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {number} creditNoteId
|
* @param {number} creditNoteId
|
||||||
* @param {ICreditNote} creditNote
|
* @param {ICreditNote} creditNote
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
import { Service, Inject } from 'typedi';
|
import { Service, Inject } from 'typedi';
|
||||||
import Knex from 'knex';
|
import { Knex } from 'knex';
|
||||||
import { IApplyCreditToInvoicesDeletedPayload } from '@/interfaces';
|
import { IApplyCreditToInvoicesDeletedPayload } from '@/interfaces';
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import PaymentReceiveService from '@/services/Sales/PaymentReceives/PaymentsReceives';
|
|
||||||
import UnitOfWork from '@/services/UnitOfWork';
|
import UnitOfWork from '@/services/UnitOfWork';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import BaseCreditNotes from './CreditNotes';
|
import BaseCreditNotes from './CreditNotes';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
|
import HasTenancyService from '../Tenancy/TenancyService';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DeletreCreditNoteApplyToInvoices extends BaseCreditNotes {
|
export default class DeletreCreditNoteApplyToInvoices extends BaseCreditNotes {
|
||||||
@Inject('PaymentReceives')
|
@Inject()
|
||||||
paymentReceive: PaymentReceiveService;
|
private uow: UnitOfWork;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
uow: UnitOfWork;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
eventPublisher: EventPublisher;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply credit note to the given invoices.
|
* Apply credit note to the given invoices.
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export default class DeleteCustomerLinkedCreditSubscriber {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate vendor has no assocaited credit transaction once the vendor deleting.
|
* Validate vendor has no associated credit transaction once the vendor deleting.
|
||||||
* @param {IVendorEventDeletingPayload} payload -
|
* @param {IVendorEventDeletingPayload} payload -
|
||||||
*/
|
*/
|
||||||
public validateCustomerHasNoLinkedCreditsOnDeleting = async ({
|
public validateCustomerHasNoLinkedCreditsOnDeleting = async ({
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default class DynamicListAbstract {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default class DynamicListAbstruct {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
import DynamicListAbstract from './DynamicListAbstract';
|
||||||
import DynamicFilterViews from '@/lib/DynamicFilter/DynamicFilterViews';
|
import DynamicFilterViews from '@/lib/DynamicFilter/DynamicFilterViews';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
@@ -7,7 +7,7 @@ import { ERRORS } from './constants';
|
|||||||
import { IModel } from '@/interfaces';
|
import { IModel } from '@/interfaces';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DynamicListCustomView extends DynamicListAbstruct {
|
export default class DynamicListCustomView extends DynamicListAbstract {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: HasTenancyService;
|
tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { Service } from 'typedi';
|
|||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import validator from 'is-my-json-valid';
|
import validator from 'is-my-json-valid';
|
||||||
import { IFilterRole, IModel } from '@/interfaces';
|
import { IFilterRole, IModel } from '@/interfaces';
|
||||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
import DynamicListAbstract from './DynamicListAbstract';
|
||||||
import DynamicFilterAdvancedFilter from '@/lib/DynamicFilter/DynamicFilterAdvancedFilter';
|
import DynamicFilterAdvancedFilter from '@/lib/DynamicFilter/DynamicFilterAdvancedFilter';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DynamicListFilterRoles extends DynamicListAbstruct {
|
export default class DynamicListFilterRoles extends DynamicListAbstract {
|
||||||
/**
|
/**
|
||||||
* Validates filter roles schema.
|
* Validates filter roles schema.
|
||||||
* @param {IFilterRole[]} filterRoles - Filter roles.
|
* @param {IFilterRole[]} filterRoles - Filter roles.
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import { IFilterRole, IModel } from '@/interfaces';
|
import { IFilterRole, IModel } from '@/interfaces';
|
||||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
import DynamicListAbstract from './DynamicListAbstract';
|
||||||
import DynamicFilterFilterRoles from '@/lib/DynamicFilter/DynamicFilterFilterRoles';
|
import DynamicFilterFilterRoles from '@/lib/DynamicFilter/DynamicFilterFilterRoles';
|
||||||
import DynamicFilterSearch from '@/lib/DynamicFilter/DynamicFilterSearch';
|
import DynamicFilterSearch from '@/lib/DynamicFilter/DynamicFilterSearch';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DynamicListSearch extends DynamicListAbstruct {
|
export default class DynamicListSearch extends DynamicListAbstract {
|
||||||
/**
|
/**
|
||||||
* Dynamic list filter roles.
|
* Dynamic list filter roles.
|
||||||
* @param {IModel} model
|
* @param {IModel} model
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
import DynamicListAbstruct from './DynamicListAbstruct';
|
import DynamicListAbstract from './DynamicListAbstract';
|
||||||
import DynamicFilterSortBy from '@/lib/DynamicFilter/DynamicFilterSortBy';
|
import DynamicFilterSortBy from '@/lib/DynamicFilter/DynamicFilterSortBy';
|
||||||
import { IModel, ISortOrder } from '@/interfaces';
|
import { IModel, ISortOrder } from '@/interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class DynamicListSortBy extends DynamicListAbstruct {
|
export default class DynamicListSortBy extends DynamicListAbstract {
|
||||||
/**
|
/**
|
||||||
* Dynamic list sort by.
|
* Dynamic list sort by.
|
||||||
* @param {IModel} model
|
* @param {IModel} model
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export class ExpensesWriteGLSubscriber {
|
|||||||
* Attaches events with handlers.
|
* Attaches events with handlers.
|
||||||
* @param bus
|
* @param bus
|
||||||
*/
|
*/
|
||||||
attach(bus) {
|
public attach(bus) {
|
||||||
bus.subscribe(
|
bus.subscribe(
|
||||||
events.expenses.onCreated,
|
events.expenses.onCreated,
|
||||||
this.handleWriteGLEntriesOnceCreated
|
this.handleWriteGLEntriesOnceCreated
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export class FeaturesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detarmines the given feature name is accessiable.
|
* Detarmines the given feature name is accessible.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {string} feature
|
* @param {string} feature
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export class FeaturesSettingsDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detarmines the given feature name is accessiable.
|
* Detarmines the given feature name is accessible.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {string} feature
|
* @param {string} feature
|
||||||
* @returns {Promise<boolean|null|undefined>}
|
* @returns {Promise<boolean|null|undefined>}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ export default class CashFlowStatement extends compose(
|
|||||||
code: account.code,
|
code: account.code,
|
||||||
label: account.name,
|
label: account.name,
|
||||||
accountType: account.accountType,
|
accountType: account.accountType,
|
||||||
adjusmentType: relation.direction,
|
adjustmentType: relation.direction,
|
||||||
total: this.getAmountMeta(closingBalance),
|
total: this.getAmountMeta(closingBalance),
|
||||||
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
||||||
};
|
};
|
||||||
@@ -362,14 +362,14 @@ export default class CashFlowStatement extends compose(
|
|||||||
/**
|
/**
|
||||||
* Retrieve the total section from the eqauation parser.
|
* Retrieve the total section from the eqauation parser.
|
||||||
* @param {ICashFlowSchemaTotalSection} sectionSchema
|
* @param {ICashFlowSchemaTotalSection} sectionSchema
|
||||||
* @param {ICashFlowSchemaSection[]} accumlatedSections
|
* @param {ICashFlowSchemaSection[]} accumulatedSections
|
||||||
* @returns {ICashFlowStatementTotalSection}
|
* @returns {ICashFlowStatementTotalSection}
|
||||||
*/
|
*/
|
||||||
private totalEquationSectionParser = (
|
private totalEquationSectionParser = (
|
||||||
accumlatedSections: ICashFlowSchemaSection[],
|
accumulatedSections: ICashFlowSchemaSection[],
|
||||||
sectionSchema: ICashFlowSchemaTotalSection
|
sectionSchema: ICashFlowSchemaTotalSection
|
||||||
): ICashFlowStatementTotalSection => {
|
): ICashFlowStatementTotalSection => {
|
||||||
const mappedSectionsById = this.transformSectionsToMap(accumlatedSections);
|
const mappedSectionsById = this.transformSectionsToMap(accumulatedSections);
|
||||||
const nodesTotalById = this.sectionsMapToTotal(mappedSectionsById);
|
const nodesTotalById = this.sectionsMapToTotal(mappedSectionsById);
|
||||||
|
|
||||||
const total = this.evaluateEquation(sectionSchema.equation, nodesTotalById);
|
const total = this.evaluateEquation(sectionSchema.equation, nodesTotalById);
|
||||||
@@ -421,7 +421,7 @@ export default class CashFlowStatement extends compose(
|
|||||||
code: account.code,
|
code: account.code,
|
||||||
label: account.name,
|
label: account.name,
|
||||||
accountType: account.accountType,
|
accountType: account.accountType,
|
||||||
adjusmentType: relation.direction,
|
adjustmentType: relation.direction,
|
||||||
total: this.getAmountMeta(closingBalance),
|
total: this.getAmountMeta(closingBalance),
|
||||||
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
sectionType: ICashFlowStatementSectionType.ACCOUNT,
|
||||||
};
|
};
|
||||||
@@ -524,7 +524,7 @@ export default class CashFlowStatement extends compose(
|
|||||||
* @param {ICashFlowSchemaSection | ICashFlowStatementSection} section
|
* @param {ICashFlowSchemaSection | ICashFlowStatementSection} section
|
||||||
* @param {number} key
|
* @param {number} key
|
||||||
* @param {ICashFlowSchemaSection[]} parentValue
|
* @param {ICashFlowSchemaSection[]} parentValue
|
||||||
* @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumlatedSections
|
* @param {(ICashFlowSchemaSection | ICashFlowStatementSection)[]} accumulatedSections
|
||||||
* @returns {ICashFlowSchemaSection}
|
* @returns {ICashFlowSchemaSection}
|
||||||
*/
|
*/
|
||||||
private schemaSectionTotalParser = (
|
private schemaSectionTotalParser = (
|
||||||
@@ -532,13 +532,13 @@ export default class CashFlowStatement extends compose(
|
|||||||
key: number,
|
key: number,
|
||||||
parentValue: ICashFlowSchemaSection[],
|
parentValue: ICashFlowSchemaSection[],
|
||||||
context,
|
context,
|
||||||
accumlatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
|
accumulatedSections: (ICashFlowSchemaSection | ICashFlowStatementSection)[]
|
||||||
): ICashFlowSchemaSection | ICashFlowStatementSection => {
|
): ICashFlowSchemaSection | ICashFlowStatementSection => {
|
||||||
return R.compose(
|
return R.compose(
|
||||||
// Total equation section.
|
// Total equation section.
|
||||||
R.when(
|
R.when(
|
||||||
this.isSchemaSectionType(ICashFlowStatementSectionType.TOTAL),
|
this.isSchemaSectionType(ICashFlowStatementSectionType.TOTAL),
|
||||||
R.curry(this.totalEquationSectionParser)(accumlatedSections)
|
R.curry(this.totalEquationSectionParser)(accumulatedSections)
|
||||||
)
|
)
|
||||||
)(section);
|
)(section);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
|
|||||||
.whereAccountId(node.id)
|
.whereAccountId(node.id)
|
||||||
.getClosingBalance();
|
.getClosingBalance();
|
||||||
|
|
||||||
return this.amountAdjustment(node.adjusmentType, closingBalance);
|
return this.amountAdjustment(node.adjustmentType, closingBalance);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,7 +322,7 @@ export const CashFlowStatementDatePeriods = (Base) =>
|
|||||||
// Cash at beginning ----------------------
|
// Cash at beginning ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the date preioods of the given node and accumlated function.
|
* Retrieve the date preioods of the given node and accumulated function.
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @param {}
|
* @param {}
|
||||||
* @return {}
|
* @return {}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default class CashflowAccountTransactionsService extends FinancialSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the cashflow accouynt transactions report data.
|
* Retrieve the cashflow account transactions report data.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
* @param {ICashflowAccountTransactionsQuery} query -
|
* @param {ICashflowAccountTransactionsQuery} query -
|
||||||
* @return {Promise<IInvetoryItemDetailDOO>}
|
* @return {Promise<IInvetoryItemDetailDOO>}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export const FinancialDatePeriods = (Base) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the date preioods of the given node and accumlated function.
|
* Retrieve the date preioods of the given node and accumulated function.
|
||||||
* @param {IBalanceSheetAccountNode} node
|
* @param {IBalanceSheetAccountNode} node
|
||||||
* @param {(fromDate: Date, toDate: Date, index: number) => any}
|
* @param {(fromDate: Date, toDate: Date, index: number) => any}
|
||||||
* @return {}
|
* @return {}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default class InventoryDetails extends FinancialSheet {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accumlate and mapping running quantity on transactions.
|
* Accumulate and mapping running quantity on transactions.
|
||||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||||
* @returns {IInventoryDetailsItemTransaction[]}
|
* @returns {IInventoryDetailsItemTransaction[]}
|
||||||
*/
|
*/
|
||||||
@@ -150,7 +150,7 @@ export default class InventoryDetails extends FinancialSheet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accumlate and mapping running valuation on transactions.
|
* Accumulate and mapping running valuation on transactions.
|
||||||
* @param {IInventoryDetailsItemTransaction[]} transactions
|
* @param {IInventoryDetailsItemTransaction[]} transactions
|
||||||
* @returns {IInventoryDetailsItemTransaction}
|
* @returns {IInventoryDetailsItemTransaction}
|
||||||
*/
|
*/
|
||||||
@@ -160,8 +160,8 @@ export default class InventoryDetails extends FinancialSheet {
|
|||||||
const initial = this.getNumberMeta(0);
|
const initial = this.getNumberMeta(0);
|
||||||
|
|
||||||
const mapAccumAppender = (a, b) => {
|
const mapAccumAppender = (a, b) => {
|
||||||
const adjusmtent = b.direction === 'OUT' ? -1 : 1;
|
const adjustment = b.direction === 'OUT' ? -1 : 1;
|
||||||
const total = a.runningValuation.number + b.cost.number * adjusmtent;
|
const total = a.runningValuation.number + b.cost.number * adjustment;
|
||||||
const totalMeta = this.getNumberMeta(total, { excerptZero: false });
|
const totalMeta = this.getNumberMeta(total, { excerptZero: false });
|
||||||
const accum = { ...b, runningValuation: totalMeta };
|
const accum = { ...b, runningValuation: totalMeta };
|
||||||
|
|
||||||
|
|||||||
@@ -129,9 +129,9 @@ export class ProjectProfitabilitySummaryRespository {
|
|||||||
*/
|
*/
|
||||||
public getIncomeAccountsGroupedEntries = async () => {
|
public getIncomeAccountsGroupedEntries = async () => {
|
||||||
const incomeAccounts = await this.getIncomeAccounts();
|
const incomeAccounts = await this.getIncomeAccounts();
|
||||||
const incomeAcountssIds = map(incomeAccounts, 'id');
|
const incomeAccountsIds = map(incomeAccounts, 'id');
|
||||||
|
|
||||||
return this.getAccountsGroupedEntries(incomeAcountssIds);
|
return this.getAccountsGroupedEntries(incomeAccountsIds);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ export default class InventoryService {
|
|||||||
) {
|
) {
|
||||||
const { Item } = this.tenancy.models(tenantId);
|
const { Item } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
// Fetches the item with assocaited item category.
|
// Fetches the item with associated item category.
|
||||||
const item = await Item.query().findById(itemId);
|
const item = await Item.query().findById(itemId);
|
||||||
|
|
||||||
// Cannot continue if the given item was not inventory item.
|
// Cannot continue if the given item was not inventory item.
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ export default class InventoryAdjustmentService {
|
|||||||
quickAdjustmentDTO,
|
quickAdjustmentDTO,
|
||||||
} as IInventoryAdjustmentCreatingPayload
|
} as IInventoryAdjustmentCreatingPayload
|
||||||
);
|
);
|
||||||
// Saves the inventory adjustment with assocaited entries to the storage.
|
// Saves the inventory adjustment with associated entries to the storage.
|
||||||
const inventoryAdjustment = await InventoryAdjustment.query(
|
const inventoryAdjustment = await InventoryAdjustment.query(
|
||||||
trx
|
trx
|
||||||
).upsertGraph({
|
).upsertGraph({
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default class InventoryAverageCostMethod
|
|||||||
public async computeItemCost() {
|
public async computeItemCost() {
|
||||||
const { InventoryTransaction } = this.tenantModels;
|
const { InventoryTransaction } = this.tenantModels;
|
||||||
const { averageCost, openingQuantity, openingCost } =
|
const { averageCost, openingQuantity, openingCost } =
|
||||||
await this.getOpeningAvaregeCost(this.startingDate, this.itemId);
|
await this.getOpeningAverageCost(this.startingDate, this.itemId);
|
||||||
|
|
||||||
const afterInvTransactions: IInventoryTransaction[] =
|
const afterInvTransactions: IInventoryTransaction[] =
|
||||||
await InventoryTransaction.query()
|
await InventoryTransaction.query()
|
||||||
@@ -75,12 +75,12 @@ export default class InventoryAverageCostMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get items Avarege cost from specific date from inventory transactions.
|
* Get items Average cost from specific date from inventory transactions.
|
||||||
* @async
|
* @async
|
||||||
* @param {Date} closingDate
|
* @param {Date} closingDate
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
public async getOpeningAvaregeCost(closingDate: Date, itemId: number) {
|
public async getOpeningAverageCost(closingDate: Date, itemId: number) {
|
||||||
const { InventoryCostLotTracker } = this.tenantModels;
|
const { InventoryCostLotTracker } = this.tenantModels;
|
||||||
|
|
||||||
const commonBuilder = (builder: any) => {
|
const commonBuilder = (builder: any) => {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetched inventory transactions that has date from the starting date and
|
* Fetched inventory transactions that has date from the starting date and
|
||||||
* fetches availiable IN LOTs transactions that has remaining bigger than zero.
|
* fetches available IN LOTs transactions that has remaining bigger than zero.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private async fetchInvINTransactions() {
|
private async fetchInvINTransactions() {
|
||||||
@@ -97,7 +97,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
|||||||
.orderBy('lot_number', (this.costMethod === 'LIFO') ? 'DESC' : 'ASC')
|
.orderBy('lot_number', (this.costMethod === 'LIFO') ? 'DESC' : 'ASC')
|
||||||
.withGraphFetched('item');
|
.withGraphFetched('item');
|
||||||
|
|
||||||
const availiableINLots: IInventoryLotCost[] =
|
const availableINLots: IInventoryLotCost[] =
|
||||||
await InventoryLotCostTracker.query()
|
await InventoryLotCostTracker.query()
|
||||||
.modify('filterDateRange', null, this.startingDate)
|
.modify('filterDateRange', null, this.startingDate)
|
||||||
.orderBy('date', 'ASC')
|
.orderBy('date', 'ASC')
|
||||||
@@ -107,7 +107,7 @@ export default class InventoryCostLotTracker extends InventoryCostMethod impleme
|
|||||||
.whereNot('remaining', 0);
|
.whereNot('remaining', 0);
|
||||||
|
|
||||||
this.inTransactions = [
|
this.inTransactions = [
|
||||||
...availiableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
|
...availableINLots.map((trans) => ({ lotTransId: trans.id, ...trans })),
|
||||||
...afterInvTransactions.map((trans) => ({ invTransId: trans.id, ...trans })),
|
...afterInvTransactions.map((trans) => ({ invTransId: trans.id, ...trans })),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
|||||||
@Service()
|
@Service()
|
||||||
export default class SyncSystemSendInvite {
|
export default class SyncSystemSendInvite {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches events with handlers.
|
* Attaches events with handlers.
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ export default class ItemCategoriesService implements IItemCategoriesService {
|
|||||||
);
|
);
|
||||||
// Items categories.
|
// Items categories.
|
||||||
const itemCategories = await ItemCategory.query().onBuild((query) => {
|
const itemCategories = await ItemCategory.query().onBuild((query) => {
|
||||||
// Subquery to calculate sumation of assocaited items to the item category.
|
// Subquery to calculate sumation of associated items to the item category.
|
||||||
query.select('*', ItemCategory.relatedQuery('items').count().as('count'));
|
query.select('*', ItemCategory.relatedQuery('items').count().as('count'));
|
||||||
|
|
||||||
dynamicList.buildQuery()(query);
|
dynamicList.buildQuery()(query);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export class ItemInvoicesTransactionsTransformer extends Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Formatted invoice date.
|
||||||
* @param item
|
* @param item
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
@@ -36,16 +36,17 @@ export class ItemInvoicesTransactionsTransformer extends Transformer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Formatted item quantity.
|
||||||
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
public formattedQuantity = (entry): string => {
|
public formattedQuantity = (entry): string => {
|
||||||
return entry.quantity;
|
return entry.quantity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Formatted date.
|
||||||
* @param entry
|
* @param entry
|
||||||
* @returns
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
public formattedRate = (entry): string => {
|
public formattedRate = (entry): string => {
|
||||||
return formatNumber(entry.rate, {
|
return formatNumber(entry.rate, {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ export class ItemsValidators {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the item inventory account whether modified and item
|
* Validate the item inventory account whether modified and item
|
||||||
* has assocaited inventory transactions.
|
* has associated inventory transactions.
|
||||||
* @param {numnber} tenantId
|
* @param {numnber} tenantId
|
||||||
* @param {IItem} oldItem
|
* @param {IItem} oldItem
|
||||||
* @param {IItemDTO} newItemDTO
|
* @param {IItemDTO} newItemDTO
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { Inject, Service } from 'typedi';
|
|||||||
import { IItemEntry, IItemEntryDTO, IItem } from '@/interfaces';
|
import { IItemEntry, IItemEntryDTO, IItem } from '@/interfaces';
|
||||||
import { ServiceError } from '@/exceptions';
|
import { ServiceError } from '@/exceptions';
|
||||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||||
|
import { ItemEntry } from '@/models';
|
||||||
import { entriesAmountDiff } from 'utils';
|
import { entriesAmountDiff } from 'utils';
|
||||||
import { ItemEntry } from 'models';
|
|
||||||
|
|
||||||
const ERRORS = {
|
const ERRORS = {
|
||||||
ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND',
|
ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND',
|
||||||
@@ -16,7 +16,7 @@ const ERRORS = {
|
|||||||
@Service()
|
@Service()
|
||||||
export default class ItemsEntriesService {
|
export default class ItemsEntriesService {
|
||||||
@Inject()
|
@Inject()
|
||||||
tenancy: TenancyService;
|
private tenancy: TenancyService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the inventory items entries of the reference id and type.
|
* Retrieve the inventory items entries of the reference id and type.
|
||||||
@@ -235,7 +235,7 @@ export default class ItemsEntriesService {
|
|||||||
/**
|
/**
|
||||||
* Sets the cost/sell accounts to the invoice entries.
|
* Sets the cost/sell accounts to the invoice entries.
|
||||||
*/
|
*/
|
||||||
setItemsEntriesDefaultAccounts(tenantId: number) {
|
public setItemsEntriesDefaultAccounts(tenantId: number) {
|
||||||
return async (entries: IItemEntry[]) => {
|
return async (entries: IItemEntry[]) => {
|
||||||
const { Item } = this.tenancy.models(tenantId);
|
const { Item } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ export default class ItemsEntriesService {
|
|||||||
* @param entries
|
* @param entries
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
getTotalItemsEntries(entries: ItemEntry[]): number {
|
public getTotalItemsEntries(entries: ItemEntry[]): number {
|
||||||
return sumBy(entries, (e) => ItemEntry.calcAmount(e));
|
return sumBy(entries, (e) => ItemEntry.calcAmount(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export class CommandManualJournalValidators {
|
|||||||
const storedAccountsIds = accounts.map((account) => account.id);
|
const storedAccountsIds = accounts.map((account) => account.id);
|
||||||
|
|
||||||
if (difference(manualAccountsIds, storedAccountsIds).length > 0) {
|
if (difference(manualAccountsIds, storedAccountsIds).length > 0) {
|
||||||
throw new ServiceError(ERRORS.ACCCOUNTS_IDS_NOT_FOUND);
|
throw new ServiceError(ERRORS.ACCOUNTS_IDS_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export class GetManualJournal {
|
|||||||
private transformer: TransformerInjectable;
|
private transformer: TransformerInjectable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve manual journal details with assocaited journal transactions.
|
* Retrieve manual journal details with associated journal transactions.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
* @param {number} manualJournalId
|
* @param {number} manualJournalId
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export class ManualJournalWriteGLSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Handle manual journal created event.
|
* Handle manual journal created event.
|
||||||
* @param {IManualJournalEventCreatedPayload} payload -
|
* @param {IManualJournalEventCreatedPayload} payload -
|
||||||
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
private handleWriteJournalEntriesOnCreated = async ({
|
private handleWriteJournalEntriesOnCreated = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -55,18 +56,19 @@ export class ManualJournalWriteGLSubscriber {
|
|||||||
trx,
|
trx,
|
||||||
}: IManualJournalEventCreatedPayload) => {
|
}: IManualJournalEventCreatedPayload) => {
|
||||||
// Ingore writing manual journal journal entries in case was not published.
|
// Ingore writing manual journal journal entries in case was not published.
|
||||||
if (manualJournal.publishedAt) {
|
if (!manualJournal.publishedAt) return;
|
||||||
await this.manualJournalGLEntries.createManualJournalGLEntries(
|
|
||||||
tenantId,
|
await this.manualJournalGLEntries.createManualJournalGLEntries(
|
||||||
manualJournal.id,
|
tenantId,
|
||||||
trx
|
manualJournal.id,
|
||||||
);
|
trx
|
||||||
}
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the manual journal next number increment once the journal be created.
|
* Handles the manual journal next number increment once the journal be created.
|
||||||
* @param {IManualJournalEventCreatedPayload} payload -
|
* @param {IManualJournalEventCreatedPayload} payload -
|
||||||
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
private handleJournalNumberIncrement = async ({
|
private handleJournalNumberIncrement = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -77,6 +79,7 @@ export class ManualJournalWriteGLSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Handle manual journal edited event.
|
* Handle manual journal edited event.
|
||||||
* @param {IManualJournalEventEditedPayload}
|
* @param {IManualJournalEventEditedPayload}
|
||||||
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
private handleRewriteJournalEntriesOnEdited = async ({
|
private handleRewriteJournalEntriesOnEdited = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -96,6 +99,7 @@ export class ManualJournalWriteGLSubscriber {
|
|||||||
/**
|
/**
|
||||||
* Handles writing journal entries once the manula journal publish.
|
* Handles writing journal entries once the manula journal publish.
|
||||||
* @param {IManualJournalEventPublishedPayload} payload -
|
* @param {IManualJournalEventPublishedPayload} payload -
|
||||||
|
* @return {Promise<void>}
|
||||||
*/
|
*/
|
||||||
private handleWriteJournalEntriesOnPublished = async ({
|
private handleWriteJournalEntriesOnPublished = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export const ERRORS = {
|
|||||||
NOT_FOUND: 'manual_journal_not_found',
|
NOT_FOUND: 'manual_journal_not_found',
|
||||||
CREDIT_DEBIT_NOT_EQUAL_ZERO: 'credit_debit_not_equal_zero',
|
CREDIT_DEBIT_NOT_EQUAL_ZERO: 'credit_debit_not_equal_zero',
|
||||||
CREDIT_DEBIT_NOT_EQUAL: 'credit_debit_not_equal',
|
CREDIT_DEBIT_NOT_EQUAL: 'credit_debit_not_equal',
|
||||||
ACCCOUNTS_IDS_NOT_FOUND: 'acccounts_ids_not_found',
|
ACCOUNTS_IDS_NOT_FOUND: 'accounts_ids_not_found',
|
||||||
JOURNAL_NUMBER_EXISTS: 'journal_number_exists',
|
JOURNAL_NUMBER_EXISTS: 'journal_number_exists',
|
||||||
ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT',
|
ENTRIES_SHOULD_ASSIGN_WITH_CONTACT: 'ENTRIES_SHOULD_ASSIGN_WITH_CONTACT',
|
||||||
CONTACTS_NOT_FOUND: 'contacts_not_found',
|
CONTACTS_NOT_FOUND: 'contacts_not_found',
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class SyncActualTimeTaskSubscriber {
|
|||||||
);
|
);
|
||||||
bus.subscribe(
|
bus.subscribe(
|
||||||
events.projectTime.onDeleted,
|
events.projectTime.onDeleted,
|
||||||
this.handleDecreaseActaulTimeOnTimeDelete
|
this.handleDecreaseActualTimeOnTimeDelete
|
||||||
);
|
);
|
||||||
bus.subscribe(
|
bus.subscribe(
|
||||||
events.projectTime.onEdited,
|
events.projectTime.onEdited,
|
||||||
@@ -52,7 +52,7 @@ export class SyncActualTimeTaskSubscriber {
|
|||||||
* Handle decreasing the actual time of the tsak once time entry be deleted.
|
* Handle decreasing the actual time of the tsak once time entry be deleted.
|
||||||
* @param {IProjectTimeDeletedEventPayload} payload
|
* @param {IProjectTimeDeletedEventPayload} payload
|
||||||
*/
|
*/
|
||||||
private handleDecreaseActaulTimeOnTimeDelete = async ({
|
private handleDecreaseActualTimeOnTimeDelete = async ({
|
||||||
tenantId,
|
tenantId,
|
||||||
oldTime,
|
oldTime,
|
||||||
trx,
|
trx,
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { Knex } from 'knex';
|
||||||
|
import { IBillPaymentEntryDTO } from '@/interfaces';
|
||||||
|
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||||
|
import { entriesAmountDiff } from '@/utils';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class BillPaymentBillSync {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves bills payment amount changes different.
|
||||||
|
* @param {number} tenantId -
|
||||||
|
* @param {IBillPaymentEntryDTO[]} paymentMadeEntries -
|
||||||
|
* @param {IBillPaymentEntryDTO[]} oldPaymentMadeEntries -
|
||||||
|
*/
|
||||||
|
public async saveChangeBillsPaymentAmount(
|
||||||
|
tenantId: number,
|
||||||
|
paymentMadeEntries: IBillPaymentEntryDTO[],
|
||||||
|
oldPaymentMadeEntries?: IBillPaymentEntryDTO[],
|
||||||
|
trx?: Knex.Transaction
|
||||||
|
): Promise<void> {
|
||||||
|
const { Bill } = this.tenancy.models(tenantId);
|
||||||
|
const opers: Promise<void>[] = [];
|
||||||
|
|
||||||
|
const diffEntries = entriesAmountDiff(
|
||||||
|
paymentMadeEntries,
|
||||||
|
oldPaymentMadeEntries,
|
||||||
|
'paymentAmount',
|
||||||
|
'billId'
|
||||||
|
);
|
||||||
|
diffEntries.forEach(
|
||||||
|
(diffEntry: { paymentAmount: number; billId: number }) => {
|
||||||
|
if (diffEntry.paymentAmount === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const oper = Bill.changePaymentAmount(
|
||||||
|
diffEntry.billId,
|
||||||
|
diffEntry.paymentAmount,
|
||||||
|
trx
|
||||||
|
);
|
||||||
|
opers.push(oper);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await Promise.all(opers);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -99,7 +99,7 @@ export class BillPaymentGLEntries {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the payment common entry.
|
* Retrieves the payment common entry.
|
||||||
* @param {IBillPayment} billPayment
|
* @param {IBillPayment} billPayment
|
||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
private getPaymentCommonEntry = (billPayment: IBillPayment) => {
|
private getPaymentCommonEntry = (billPayment: IBillPayment) => {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export class PaymentWriteGLEntriesSubscriber {
|
|||||||
trx,
|
trx,
|
||||||
}: IBillPaymentEventCreatedPayload) => {
|
}: IBillPaymentEventCreatedPayload) => {
|
||||||
// Records the journal transactions after bills payment
|
// Records the journal transactions after bills payment
|
||||||
// and change diff acoount balance.
|
// and change diff account balance.
|
||||||
await this.billPaymentGLEntries.writePaymentGLEntries(
|
await this.billPaymentGLEntries.writePaymentGLEntries(
|
||||||
tenantId,
|
tenantId,
|
||||||
billPayment.id,
|
billPayment.id,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export class BillPaymentTransactionTransformer extends Transformer {
|
|||||||
/**
|
/**
|
||||||
* Retrieve formatted bill payment date.
|
* Retrieve formatted bill payment date.
|
||||||
* @param entry
|
* @param entry
|
||||||
* @returns
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
protected formattedPaymentDate = (entry): string => {
|
protected formattedPaymentDate = (entry): string => {
|
||||||
return this.formatDate(entry.payment.paymentDate);
|
return this.formatDate(entry.payment.paymentDate);
|
||||||
|
|||||||
@@ -0,0 +1,278 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { sumBy, difference } from 'lodash';
|
||||||
|
import {
|
||||||
|
IBill,
|
||||||
|
IBillPaymentDTO,
|
||||||
|
IBillPaymentEntryDTO,
|
||||||
|
IBillPayment,
|
||||||
|
IBillPaymentEntry,
|
||||||
|
} from '@/interfaces';
|
||||||
|
import TenancyService from '@/services/Tenancy/TenancyService';
|
||||||
|
import { ServiceError } from '@/exceptions';
|
||||||
|
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
||||||
|
import { BillPayment } from '@/models';
|
||||||
|
import { ERRORS } from './constants';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class BillPaymentValidators {
|
||||||
|
@Inject()
|
||||||
|
private tenancy: TenancyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the payment existance.
|
||||||
|
* @param {BillPayment | undefined | null} payment
|
||||||
|
* @throws {ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND)}
|
||||||
|
*/
|
||||||
|
public async validateBillPaymentExistance(
|
||||||
|
payment: BillPayment | undefined | null
|
||||||
|
) {
|
||||||
|
if (!payment) {
|
||||||
|
throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the bill payment existance.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {Function} next
|
||||||
|
*/
|
||||||
|
public async getPaymentMadeOrThrowError(
|
||||||
|
tenantid: number,
|
||||||
|
paymentMadeId: number
|
||||||
|
) {
|
||||||
|
const { BillPayment } = this.tenancy.models(tenantid);
|
||||||
|
const billPayment = await BillPayment.query()
|
||||||
|
.withGraphFetched('entries')
|
||||||
|
.findById(paymentMadeId);
|
||||||
|
|
||||||
|
if (!billPayment) {
|
||||||
|
throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return billPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the payment account.
|
||||||
|
* @param {number} tenantId -
|
||||||
|
* @param {number} paymentAccountId
|
||||||
|
* @return {Promise<IAccountType>}
|
||||||
|
*/
|
||||||
|
public async getPaymentAccountOrThrowError(
|
||||||
|
tenantId: number,
|
||||||
|
paymentAccountId: number
|
||||||
|
) {
|
||||||
|
const { accountRepository } = this.tenancy.repositories(tenantId);
|
||||||
|
|
||||||
|
const paymentAccount = await accountRepository.findOneById(
|
||||||
|
paymentAccountId
|
||||||
|
);
|
||||||
|
if (!paymentAccount) {
|
||||||
|
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// Validate the payment account type.
|
||||||
|
if (
|
||||||
|
!paymentAccount.isAccountType([
|
||||||
|
ACCOUNT_TYPE.BANK,
|
||||||
|
ACCOUNT_TYPE.CASH,
|
||||||
|
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
||||||
|
])
|
||||||
|
) {
|
||||||
|
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE);
|
||||||
|
}
|
||||||
|
return paymentAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the payment number uniqness.
|
||||||
|
* @param {number} tenantId -
|
||||||
|
* @param {string} paymentMadeNumber -
|
||||||
|
* @return {Promise<IBillPayment>}
|
||||||
|
*/
|
||||||
|
public async validatePaymentNumber(
|
||||||
|
tenantId: number,
|
||||||
|
paymentMadeNumber: string,
|
||||||
|
notPaymentMadeId?: number
|
||||||
|
) {
|
||||||
|
const { BillPayment } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const foundBillPayment = await BillPayment.query().onBuild(
|
||||||
|
(builder: any) => {
|
||||||
|
builder.findOne('payment_number', paymentMadeNumber);
|
||||||
|
|
||||||
|
if (notPaymentMadeId) {
|
||||||
|
builder.whereNot('id', notPaymentMadeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (foundBillPayment) {
|
||||||
|
throw new ServiceError(ERRORS.BILL_PAYMENT_NUMBER_NOT_UNQIUE);
|
||||||
|
}
|
||||||
|
return foundBillPayment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate whether the entries bills ids exist on the storage.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {NextFunction} next
|
||||||
|
*/
|
||||||
|
public async validateBillsExistance(
|
||||||
|
tenantId: number,
|
||||||
|
billPaymentEntries: { billId: number }[],
|
||||||
|
vendorId: number
|
||||||
|
) {
|
||||||
|
const { Bill } = this.tenancy.models(tenantId);
|
||||||
|
const entriesBillsIds = billPaymentEntries.map((e: any) => e.billId);
|
||||||
|
|
||||||
|
const storedBills = await Bill.query()
|
||||||
|
.whereIn('id', entriesBillsIds)
|
||||||
|
.where('vendor_id', vendorId);
|
||||||
|
|
||||||
|
const storedBillsIds = storedBills.map((t: IBill) => t.id);
|
||||||
|
const notFoundBillsIds = difference(entriesBillsIds, storedBillsIds);
|
||||||
|
|
||||||
|
if (notFoundBillsIds.length > 0) {
|
||||||
|
throw new ServiceError(ERRORS.BILL_ENTRIES_IDS_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// Validate the not opened bills.
|
||||||
|
const notOpenedBills = storedBills.filter((bill) => !bill.openedAt);
|
||||||
|
|
||||||
|
if (notOpenedBills.length > 0) {
|
||||||
|
throw new ServiceError(ERRORS.BILLS_NOT_OPENED_YET, null, {
|
||||||
|
notOpenedBills,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return storedBills;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate wether the payment amount bigger than the payable amount.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {NextFunction} next
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
public async validateBillsDueAmount(
|
||||||
|
tenantId: number,
|
||||||
|
billPaymentEntries: IBillPaymentEntryDTO[],
|
||||||
|
oldPaymentEntries: IBillPaymentEntry[] = []
|
||||||
|
) {
|
||||||
|
const { Bill } = this.tenancy.models(tenantId);
|
||||||
|
const billsIds = billPaymentEntries.map(
|
||||||
|
(entry: IBillPaymentEntryDTO) => entry.billId
|
||||||
|
);
|
||||||
|
|
||||||
|
const storedBills = await Bill.query().whereIn('id', billsIds);
|
||||||
|
const storedBillsMap = new Map(
|
||||||
|
storedBills.map((bill) => {
|
||||||
|
const oldEntries = oldPaymentEntries.filter(
|
||||||
|
(entry) => entry.billId === bill.id
|
||||||
|
);
|
||||||
|
const oldPaymentAmount = sumBy(oldEntries, 'paymentAmount') || 0;
|
||||||
|
|
||||||
|
return [
|
||||||
|
bill.id,
|
||||||
|
{ ...bill, dueAmount: bill.dueAmount + oldPaymentAmount },
|
||||||
|
];
|
||||||
|
})
|
||||||
|
);
|
||||||
|
interface invalidPaymentAmountError {
|
||||||
|
index: number;
|
||||||
|
due_amount: number;
|
||||||
|
}
|
||||||
|
const hasWrongPaymentAmount: invalidPaymentAmountError[] = [];
|
||||||
|
|
||||||
|
billPaymentEntries.forEach((entry: IBillPaymentEntryDTO, index: number) => {
|
||||||
|
const entryBill = storedBillsMap.get(entry.billId);
|
||||||
|
const { dueAmount } = entryBill;
|
||||||
|
|
||||||
|
if (dueAmount < entry.paymentAmount) {
|
||||||
|
hasWrongPaymentAmount.push({ index, due_amount: dueAmount });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (hasWrongPaymentAmount.length > 0) {
|
||||||
|
throw new ServiceError(ERRORS.INVALID_BILL_PAYMENT_AMOUNT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the payment receive entries IDs existance.
|
||||||
|
* @param {Request} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @return {Response}
|
||||||
|
*/
|
||||||
|
public async validateEntriesIdsExistance(
|
||||||
|
tenantId: number,
|
||||||
|
billPaymentId: number,
|
||||||
|
billPaymentEntries: IBillPaymentEntry[]
|
||||||
|
) {
|
||||||
|
const { BillPaymentEntry } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const entriesIds = billPaymentEntries
|
||||||
|
.filter((entry: any) => entry.id)
|
||||||
|
.map((entry: any) => entry.id);
|
||||||
|
|
||||||
|
const storedEntries = await BillPaymentEntry.query().where(
|
||||||
|
'bill_payment_id',
|
||||||
|
billPaymentId
|
||||||
|
);
|
||||||
|
|
||||||
|
const storedEntriesIds = storedEntries.map((entry: any) => entry.id);
|
||||||
|
const notFoundEntriesIds = difference(entriesIds, storedEntriesIds);
|
||||||
|
|
||||||
|
if (notFoundEntriesIds.length > 0) {
|
||||||
|
throw new ServiceError(ERRORS.BILL_PAYMENT_ENTRIES_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * Validate the payment vendor whether modified.
|
||||||
|
* @param {string} billPaymentNo
|
||||||
|
*/
|
||||||
|
public validateVendorNotModified(
|
||||||
|
billPaymentDTO: IBillPaymentDTO,
|
||||||
|
oldBillPayment: IBillPayment
|
||||||
|
) {
|
||||||
|
if (billPaymentDTO.vendorId !== oldBillPayment.vendorId) {
|
||||||
|
throw new ServiceError(ERRORS.PAYMENT_NUMBER_SHOULD_NOT_MODIFY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the payment account currency code. The deposit account curreny
|
||||||
|
* should be equals the customer currency code or the base currency.
|
||||||
|
* @param {string} paymentAccountCurrency
|
||||||
|
* @param {string} customerCurrency
|
||||||
|
* @param {string} baseCurrency
|
||||||
|
* @throws {ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID)}
|
||||||
|
*/
|
||||||
|
public validateWithdrawalAccountCurrency = (
|
||||||
|
paymentAccountCurrency: string,
|
||||||
|
customerCurrency: string,
|
||||||
|
baseCurrency: string
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
paymentAccountCurrency !== customerCurrency &&
|
||||||
|
paymentAccountCurrency !== baseCurrency
|
||||||
|
) {
|
||||||
|
throw new ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the given vendor has no associated payments.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} vendorId
|
||||||
|
*/
|
||||||
|
public async validateVendorHasNoPayments(tenantId: number, vendorId: number) {
|
||||||
|
const { BillPayment } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const payments = await BillPayment.query().where('vendor_id', vendorId);
|
||||||
|
|
||||||
|
if (payments.length > 0) {
|
||||||
|
throw new ServiceError(ERRORS.VENDOR_HAS_PAYMENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,713 +0,0 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
|
||||||
import { sumBy, difference } from 'lodash';
|
|
||||||
import * as R from 'ramda';
|
|
||||||
import { Knex } from 'knex';
|
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import {
|
|
||||||
IBill,
|
|
||||||
IBillPaymentDTO,
|
|
||||||
IBillPaymentEntryDTO,
|
|
||||||
IBillPayment,
|
|
||||||
IBillPaymentsFilter,
|
|
||||||
IPaginationMeta,
|
|
||||||
IFilterMeta,
|
|
||||||
IBillPaymentEntry,
|
|
||||||
IBillPaymentEventCreatedPayload,
|
|
||||||
IBillPaymentEventEditedPayload,
|
|
||||||
IBillPaymentEventDeletedPayload,
|
|
||||||
IBillPaymentCreatingPayload,
|
|
||||||
IBillPaymentEditingPayload,
|
|
||||||
IBillPaymentDeletingPayload,
|
|
||||||
IVendor,
|
|
||||||
} from '@/interfaces';
|
|
||||||
import JournalPosterService from '@/services/Sales/JournalPosterService';
|
|
||||||
import TenancyService from '@/services/Tenancy/TenancyService';
|
|
||||||
import DynamicListingService from '@/services/DynamicListing/DynamicListService';
|
|
||||||
import { entriesAmountDiff, formatDateFields } from 'utils';
|
|
||||||
import { ServiceError } from '@/exceptions';
|
|
||||||
import { ACCOUNT_TYPE } from '@/data/AccountTypes';
|
|
||||||
import { BillPaymentTransformer } from './BillPaymentTransformer';
|
|
||||||
import { ERRORS } from './constants';
|
|
||||||
import UnitOfWork from '@/services/UnitOfWork';
|
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
|
||||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
|
||||||
import { TenantMetadata } from '@/system/models';
|
|
||||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bill payments service.
|
|
||||||
* @service
|
|
||||||
*/
|
|
||||||
@Service('BillPayments')
|
|
||||||
export default class BillPaymentsService implements IBillPaymentsService {
|
|
||||||
@Inject()
|
|
||||||
tenancy: TenancyService;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
journalService: JournalPosterService;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
dynamicListService: DynamicListingService;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
eventPublisher: EventPublisher;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private transformer: TransformerInjectable;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
uow: UnitOfWork;
|
|
||||||
|
|
||||||
@Inject()
|
|
||||||
private branchDTOTransform: BranchTransactionDTOTransform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the bill payment existance.
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @param {Function} next
|
|
||||||
*/
|
|
||||||
private async getPaymentMadeOrThrowError(
|
|
||||||
tenantid: number,
|
|
||||||
paymentMadeId: number
|
|
||||||
) {
|
|
||||||
const { BillPayment } = this.tenancy.models(tenantid);
|
|
||||||
const billPayment = await BillPayment.query()
|
|
||||||
.withGraphFetched('entries')
|
|
||||||
.findById(paymentMadeId);
|
|
||||||
|
|
||||||
if (!billPayment) {
|
|
||||||
throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND);
|
|
||||||
}
|
|
||||||
return billPayment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the payment account.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {number} paymentAccountId
|
|
||||||
* @return {Promise<IAccountType>}
|
|
||||||
*/
|
|
||||||
private async getPaymentAccountOrThrowError(
|
|
||||||
tenantId: number,
|
|
||||||
paymentAccountId: number
|
|
||||||
) {
|
|
||||||
const { accountRepository } = this.tenancy.repositories(tenantId);
|
|
||||||
|
|
||||||
const paymentAccount = await accountRepository.findOneById(
|
|
||||||
paymentAccountId
|
|
||||||
);
|
|
||||||
if (!paymentAccount) {
|
|
||||||
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_FOUND);
|
|
||||||
}
|
|
||||||
// Validate the payment account type.
|
|
||||||
if (
|
|
||||||
!paymentAccount.isAccountType([
|
|
||||||
ACCOUNT_TYPE.BANK,
|
|
||||||
ACCOUNT_TYPE.CASH,
|
|
||||||
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
|
||||||
])
|
|
||||||
) {
|
|
||||||
throw new ServiceError(ERRORS.PAYMENT_ACCOUNT_NOT_CURRENT_ASSET_TYPE);
|
|
||||||
}
|
|
||||||
return paymentAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the payment number uniqness.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {string} paymentMadeNumber -
|
|
||||||
* @return {Promise<IBillPayment>}
|
|
||||||
*/
|
|
||||||
private async validatePaymentNumber(
|
|
||||||
tenantId: number,
|
|
||||||
paymentMadeNumber: string,
|
|
||||||
notPaymentMadeId?: number
|
|
||||||
) {
|
|
||||||
const { BillPayment } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const foundBillPayment = await BillPayment.query().onBuild(
|
|
||||||
(builder: any) => {
|
|
||||||
builder.findOne('payment_number', paymentMadeNumber);
|
|
||||||
|
|
||||||
if (notPaymentMadeId) {
|
|
||||||
builder.whereNot('id', notPaymentMadeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (foundBillPayment) {
|
|
||||||
throw new ServiceError(ERRORS.BILL_PAYMENT_NUMBER_NOT_UNQIUE);
|
|
||||||
}
|
|
||||||
return foundBillPayment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate whether the entries bills ids exist on the storage.
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @param {NextFunction} next
|
|
||||||
*/
|
|
||||||
public async validateBillsExistance(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentEntries: { billId: number }[],
|
|
||||||
vendorId: number
|
|
||||||
) {
|
|
||||||
const { Bill } = this.tenancy.models(tenantId);
|
|
||||||
const entriesBillsIds = billPaymentEntries.map((e: any) => e.billId);
|
|
||||||
|
|
||||||
const storedBills = await Bill.query()
|
|
||||||
.whereIn('id', entriesBillsIds)
|
|
||||||
.where('vendor_id', vendorId);
|
|
||||||
|
|
||||||
const storedBillsIds = storedBills.map((t: IBill) => t.id);
|
|
||||||
const notFoundBillsIds = difference(entriesBillsIds, storedBillsIds);
|
|
||||||
|
|
||||||
if (notFoundBillsIds.length > 0) {
|
|
||||||
throw new ServiceError(ERRORS.BILL_ENTRIES_IDS_NOT_FOUND);
|
|
||||||
}
|
|
||||||
// Validate the not opened bills.
|
|
||||||
const notOpenedBills = storedBills.filter((bill) => !bill.openedAt);
|
|
||||||
|
|
||||||
if (notOpenedBills.length > 0) {
|
|
||||||
throw new ServiceError(ERRORS.BILLS_NOT_OPENED_YET, null, {
|
|
||||||
notOpenedBills,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return storedBills;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate wether the payment amount bigger than the payable amount.
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @param {NextFunction} next
|
|
||||||
* @return {void}
|
|
||||||
*/
|
|
||||||
private async validateBillsDueAmount(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentEntries: IBillPaymentEntryDTO[],
|
|
||||||
oldPaymentEntries: IBillPaymentEntry[] = []
|
|
||||||
) {
|
|
||||||
const { Bill } = this.tenancy.models(tenantId);
|
|
||||||
const billsIds = billPaymentEntries.map(
|
|
||||||
(entry: IBillPaymentEntryDTO) => entry.billId
|
|
||||||
);
|
|
||||||
|
|
||||||
const storedBills = await Bill.query().whereIn('id', billsIds);
|
|
||||||
const storedBillsMap = new Map(
|
|
||||||
storedBills.map((bill) => {
|
|
||||||
const oldEntries = oldPaymentEntries.filter(
|
|
||||||
(entry) => entry.billId === bill.id
|
|
||||||
);
|
|
||||||
const oldPaymentAmount = sumBy(oldEntries, 'paymentAmount') || 0;
|
|
||||||
|
|
||||||
return [
|
|
||||||
bill.id,
|
|
||||||
{ ...bill, dueAmount: bill.dueAmount + oldPaymentAmount },
|
|
||||||
];
|
|
||||||
})
|
|
||||||
);
|
|
||||||
interface invalidPaymentAmountError {
|
|
||||||
index: number;
|
|
||||||
due_amount: number;
|
|
||||||
}
|
|
||||||
const hasWrongPaymentAmount: invalidPaymentAmountError[] = [];
|
|
||||||
|
|
||||||
billPaymentEntries.forEach((entry: IBillPaymentEntryDTO, index: number) => {
|
|
||||||
const entryBill = storedBillsMap.get(entry.billId);
|
|
||||||
const { dueAmount } = entryBill;
|
|
||||||
|
|
||||||
if (dueAmount < entry.paymentAmount) {
|
|
||||||
hasWrongPaymentAmount.push({ index, due_amount: dueAmount });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (hasWrongPaymentAmount.length > 0) {
|
|
||||||
throw new ServiceError(ERRORS.INVALID_BILL_PAYMENT_AMOUNT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the payment receive entries IDs existance.
|
|
||||||
* @param {Request} req
|
|
||||||
* @param {Response} res
|
|
||||||
* @return {Response}
|
|
||||||
*/
|
|
||||||
private async validateEntriesIdsExistance(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentId: number,
|
|
||||||
billPaymentEntries: IBillPaymentEntry[]
|
|
||||||
) {
|
|
||||||
const { BillPaymentEntry } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const entriesIds = billPaymentEntries
|
|
||||||
.filter((entry: any) => entry.id)
|
|
||||||
.map((entry: any) => entry.id);
|
|
||||||
|
|
||||||
const storedEntries = await BillPaymentEntry.query().where(
|
|
||||||
'bill_payment_id',
|
|
||||||
billPaymentId
|
|
||||||
);
|
|
||||||
|
|
||||||
const storedEntriesIds = storedEntries.map((entry: any) => entry.id);
|
|
||||||
const notFoundEntriesIds = difference(entriesIds, storedEntriesIds);
|
|
||||||
|
|
||||||
if (notFoundEntriesIds.length > 0) {
|
|
||||||
throw new ServiceError(ERRORS.BILL_PAYMENT_ENTRIES_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* * Validate the payment vendor whether modified.
|
|
||||||
* @param {string} billPaymentNo
|
|
||||||
*/
|
|
||||||
private validateVendorNotModified(
|
|
||||||
billPaymentDTO: IBillPaymentDTO,
|
|
||||||
oldBillPayment: IBillPayment
|
|
||||||
) {
|
|
||||||
if (billPaymentDTO.vendorId !== oldBillPayment.vendorId) {
|
|
||||||
throw new ServiceError(ERRORS.PAYMENT_NUMBER_SHOULD_NOT_MODIFY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the payment account currency code. The deposit account curreny
|
|
||||||
* should be equals the customer currency code or the base currency.
|
|
||||||
* @param {string} paymentAccountCurrency
|
|
||||||
* @param {string} customerCurrency
|
|
||||||
* @param {string} baseCurrency
|
|
||||||
* @throws {ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID)}
|
|
||||||
*/
|
|
||||||
public validateWithdrawalAccountCurrency = (
|
|
||||||
paymentAccountCurrency: string,
|
|
||||||
customerCurrency: string,
|
|
||||||
baseCurrency: string
|
|
||||||
) => {
|
|
||||||
if (
|
|
||||||
paymentAccountCurrency !== customerCurrency &&
|
|
||||||
paymentAccountCurrency !== baseCurrency
|
|
||||||
) {
|
|
||||||
throw new ServiceError(ERRORS.WITHDRAWAL_ACCOUNT_CURRENCY_INVALID);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms create/edit DTO to model.
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {IBillPaymentDTO} billPaymentDTO - Bill payment.
|
|
||||||
* @param {IBillPayment} oldBillPayment - Old bill payment.
|
|
||||||
* @return {Promise<IBillPayment>}
|
|
||||||
*/
|
|
||||||
async transformDTOToModel(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentDTO: IBillPaymentDTO,
|
|
||||||
vendor: IVendor,
|
|
||||||
oldBillPayment?: IBillPayment
|
|
||||||
): Promise<IBillPayment> {
|
|
||||||
const initialDTO = {
|
|
||||||
...formatDateFields(billPaymentDTO, ['paymentDate']),
|
|
||||||
amount: sumBy(billPaymentDTO.entries, 'paymentAmount'),
|
|
||||||
currencyCode: vendor.currencyCode,
|
|
||||||
exchangeRate: billPaymentDTO.exchangeRate || 1,
|
|
||||||
entries: billPaymentDTO.entries,
|
|
||||||
};
|
|
||||||
return R.compose(
|
|
||||||
this.branchDTOTransform.transformDTO<IBillPayment>(tenantId)
|
|
||||||
)(initialDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new bill payment transcations and store it to the storage
|
|
||||||
* with associated bills entries and journal transactions.
|
|
||||||
*
|
|
||||||
* Precedures:-
|
|
||||||
* ------
|
|
||||||
* - Records the bill payment transaction.
|
|
||||||
* - Records the bill payment associated entries.
|
|
||||||
* - Increment the payment amount of the given vendor bills.
|
|
||||||
* - Decrement the vendor balance.
|
|
||||||
* - Records payment journal entries.
|
|
||||||
* ------
|
|
||||||
* @param {number} tenantId - Tenant id.
|
|
||||||
* @param {BillPaymentDTO} billPayment - Bill payment object.
|
|
||||||
*/
|
|
||||||
public async createBillPayment(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentDTO: IBillPaymentDTO
|
|
||||||
): Promise<IBillPayment> {
|
|
||||||
const { BillPayment, Contact } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const tenantMeta = await TenantMetadata.query().findOne({ tenantId });
|
|
||||||
|
|
||||||
// Retrieves the payment vendor or throw not found error.
|
|
||||||
const vendor = await Contact.query()
|
|
||||||
.findById(billPaymentDTO.vendorId)
|
|
||||||
.modify('vendor')
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
// Transform create DTO to model object.
|
|
||||||
const billPaymentObj = await this.transformDTOToModel(
|
|
||||||
tenantId,
|
|
||||||
billPaymentDTO,
|
|
||||||
vendor
|
|
||||||
);
|
|
||||||
// Validate the payment account existance and type.
|
|
||||||
const paymentAccount = await this.getPaymentAccountOrThrowError(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.paymentAccountId
|
|
||||||
);
|
|
||||||
// Validate the payment number uniquiness.
|
|
||||||
if (billPaymentObj.paymentNumber) {
|
|
||||||
await this.validatePaymentNumber(tenantId, billPaymentObj.paymentNumber);
|
|
||||||
}
|
|
||||||
// Validates the bills existance and associated to the given vendor.
|
|
||||||
await this.validateBillsExistance(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.entries,
|
|
||||||
billPaymentDTO.vendorId
|
|
||||||
);
|
|
||||||
// Validates the bills due payment amount.
|
|
||||||
await this.validateBillsDueAmount(tenantId, billPaymentObj.entries);
|
|
||||||
|
|
||||||
// Validates the withdrawal account currency code.
|
|
||||||
this.validateWithdrawalAccountCurrency(
|
|
||||||
paymentAccount.currencyCode,
|
|
||||||
vendor.currencyCode,
|
|
||||||
tenantMeta.baseCurrency
|
|
||||||
);
|
|
||||||
// Writes bill payment transacation with associated transactions
|
|
||||||
// under unit-of-work envirement.
|
|
||||||
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
|
||||||
// Triggers `onBillPaymentCreating` event.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onCreating, {
|
|
||||||
tenantId,
|
|
||||||
billPaymentDTO,
|
|
||||||
trx,
|
|
||||||
} as IBillPaymentCreatingPayload);
|
|
||||||
|
|
||||||
// Writes the bill payment graph to the storage.
|
|
||||||
const billPayment = await BillPayment.query(trx).insertGraphAndFetch({
|
|
||||||
...billPaymentObj,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Triggers `onBillPaymentCreated` event.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onCreated, {
|
|
||||||
tenantId,
|
|
||||||
billPayment,
|
|
||||||
billPaymentId: billPayment.id,
|
|
||||||
trx,
|
|
||||||
} as IBillPaymentEventCreatedPayload);
|
|
||||||
|
|
||||||
return billPayment;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edits the details of the given bill payment.
|
|
||||||
*
|
|
||||||
* Preceducres:
|
|
||||||
* ------
|
|
||||||
* - Update the bill payment transaction.
|
|
||||||
* - Insert the new bill payment entries that have no ids.
|
|
||||||
* - Update the bill paymeny entries that have ids.
|
|
||||||
* - Delete the bill payment entries that not presented.
|
|
||||||
* - Re-insert the journal transactions and update the diff accounts balance.
|
|
||||||
* - Update the diff vendor balance.
|
|
||||||
* - Update the diff bill payment amount.
|
|
||||||
* ------
|
|
||||||
* @param {number} tenantId - Tenant id
|
|
||||||
* @param {Integer} billPaymentId
|
|
||||||
* @param {BillPaymentDTO} billPayment
|
|
||||||
* @param {IBillPayment} oldBillPayment
|
|
||||||
*/
|
|
||||||
public async editBillPayment(
|
|
||||||
tenantId: number,
|
|
||||||
billPaymentId: number,
|
|
||||||
billPaymentDTO
|
|
||||||
): Promise<IBillPayment> {
|
|
||||||
const { BillPayment, Contact } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const tenantMeta = await TenantMetadata.query().findOne({ tenantId });
|
|
||||||
|
|
||||||
//
|
|
||||||
const oldBillPayment = await this.getPaymentMadeOrThrowError(
|
|
||||||
tenantId,
|
|
||||||
billPaymentId
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
const vendor = await Contact.query()
|
|
||||||
.modify('vendor')
|
|
||||||
.findById(billPaymentDTO.vendorId)
|
|
||||||
.throwIfNotFound();
|
|
||||||
|
|
||||||
// Transform bill payment DTO to model object.
|
|
||||||
const billPaymentObj = await this.transformDTOToModel(
|
|
||||||
tenantId,
|
|
||||||
billPaymentDTO,
|
|
||||||
vendor,
|
|
||||||
oldBillPayment
|
|
||||||
);
|
|
||||||
// Validate vendor not modified.
|
|
||||||
this.validateVendorNotModified(billPaymentDTO, oldBillPayment);
|
|
||||||
|
|
||||||
// Validate the payment account existance and type.
|
|
||||||
const paymentAccount = await this.getPaymentAccountOrThrowError(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.paymentAccountId
|
|
||||||
);
|
|
||||||
// Validate the items entries IDs existance on the storage.
|
|
||||||
await this.validateEntriesIdsExistance(
|
|
||||||
tenantId,
|
|
||||||
billPaymentId,
|
|
||||||
billPaymentObj.entries
|
|
||||||
);
|
|
||||||
// Validate the bills existance and associated to the given vendor.
|
|
||||||
await this.validateBillsExistance(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.entries,
|
|
||||||
billPaymentDTO.vendorId
|
|
||||||
);
|
|
||||||
// Validates the bills due payment amount.
|
|
||||||
await this.validateBillsDueAmount(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.entries,
|
|
||||||
oldBillPayment.entries
|
|
||||||
);
|
|
||||||
// Validate the payment number uniquiness.
|
|
||||||
if (billPaymentObj.paymentNumber) {
|
|
||||||
await this.validatePaymentNumber(
|
|
||||||
tenantId,
|
|
||||||
billPaymentObj.paymentNumber,
|
|
||||||
billPaymentId
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Validates the withdrawal account currency code.
|
|
||||||
this.validateWithdrawalAccountCurrency(
|
|
||||||
paymentAccount.currencyCode,
|
|
||||||
vendor.currencyCode,
|
|
||||||
tenantMeta.baseCurrency
|
|
||||||
);
|
|
||||||
// Edits the bill transactions with associated transactions
|
|
||||||
// under unit-of-work envirement.
|
|
||||||
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
|
||||||
// Triggers `onBillPaymentEditing` event.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onEditing, {
|
|
||||||
tenantId,
|
|
||||||
oldBillPayment,
|
|
||||||
billPaymentDTO,
|
|
||||||
trx,
|
|
||||||
} as IBillPaymentEditingPayload);
|
|
||||||
|
|
||||||
// Deletes the bill payment transaction graph from the storage.
|
|
||||||
const billPayment = await BillPayment.query(trx).upsertGraphAndFetch({
|
|
||||||
id: billPaymentId,
|
|
||||||
...billPaymentObj,
|
|
||||||
});
|
|
||||||
// Triggers `onBillPaymentEdited` event.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onEdited, {
|
|
||||||
tenantId,
|
|
||||||
billPaymentId,
|
|
||||||
billPayment,
|
|
||||||
oldBillPayment,
|
|
||||||
trx,
|
|
||||||
} as IBillPaymentEventEditedPayload);
|
|
||||||
|
|
||||||
return billPayment;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the bill payment and associated transactions.
|
|
||||||
* @param {number} tenantId - Tenant id.
|
|
||||||
* @param {Integer} billPaymentId - The given bill payment id.
|
|
||||||
* @return {Promise}
|
|
||||||
*/
|
|
||||||
public async deleteBillPayment(tenantId: number, billPaymentId: number) {
|
|
||||||
const { BillPayment, BillPaymentEntry } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
// Retrieve the bill payment or throw not found service error.
|
|
||||||
const oldBillPayment = await this.getPaymentMadeOrThrowError(
|
|
||||||
tenantId,
|
|
||||||
billPaymentId
|
|
||||||
);
|
|
||||||
// Deletes the bill transactions with associated transactions under
|
|
||||||
// unit-of-work envirement.
|
|
||||||
return this.uow.withTransaction(tenantId, async (trx: Knex.Transaction) => {
|
|
||||||
// Triggers `onBillPaymentDeleting` payload.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onDeleting, {
|
|
||||||
tenantId,
|
|
||||||
trx,
|
|
||||||
oldBillPayment,
|
|
||||||
} as IBillPaymentDeletingPayload);
|
|
||||||
|
|
||||||
// Deletes the bill payment assocaited entries.
|
|
||||||
await BillPaymentEntry.query(trx)
|
|
||||||
.where('bill_payment_id', billPaymentId)
|
|
||||||
.delete();
|
|
||||||
|
|
||||||
// Deletes the bill payment transaction.
|
|
||||||
await BillPayment.query(trx).where('id', billPaymentId).delete();
|
|
||||||
|
|
||||||
// Triggers `onBillPaymentDeleted` event.
|
|
||||||
await this.eventPublisher.emitAsync(events.billPayment.onDeleted, {
|
|
||||||
tenantId,
|
|
||||||
billPaymentId,
|
|
||||||
oldBillPayment,
|
|
||||||
trx,
|
|
||||||
} as IBillPaymentEventDeletedPayload);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve payment made associated bills.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {number} billPaymentId -
|
|
||||||
*/
|
|
||||||
public async getPaymentBills(tenantId: number, billPaymentId: number) {
|
|
||||||
const { Bill } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const billPayment = await this.getPaymentMadeOrThrowError(
|
|
||||||
tenantId,
|
|
||||||
billPaymentId
|
|
||||||
);
|
|
||||||
const paymentBillsIds = billPayment.entries.map((entry) => entry.id);
|
|
||||||
|
|
||||||
const bills = await Bill.query().whereIn('id', paymentBillsIds);
|
|
||||||
|
|
||||||
return bills;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve bill payment.
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} billPyamentId
|
|
||||||
* @return {Promise<IBillPayment>}
|
|
||||||
*/
|
|
||||||
public async getBillPayment(
|
|
||||||
tenantId: number,
|
|
||||||
billPyamentId: number
|
|
||||||
): Promise<IBillPayment> {
|
|
||||||
const { BillPayment } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const billPayment = await BillPayment.query()
|
|
||||||
.withGraphFetched('entries.bill')
|
|
||||||
.withGraphFetched('vendor')
|
|
||||||
.withGraphFetched('paymentAccount')
|
|
||||||
.withGraphFetched('transactions')
|
|
||||||
.withGraphFetched('branch')
|
|
||||||
.findById(billPyamentId);
|
|
||||||
|
|
||||||
if (!billPayment) {
|
|
||||||
throw new ServiceError(ERRORS.PAYMENT_MADE_NOT_FOUND);
|
|
||||||
}
|
|
||||||
return this.transformer.transform(
|
|
||||||
tenantId,
|
|
||||||
billPayment,
|
|
||||||
new BillPaymentTransformer()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseListFilterDTO(filterDTO) {
|
|
||||||
return R.compose(this.dynamicListService.parseStringifiedFilter)(filterDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve bill payment paginted and filterable list.
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {IBillPaymentsFilter} billPaymentsFilter
|
|
||||||
*/
|
|
||||||
public async listBillPayments(
|
|
||||||
tenantId: number,
|
|
||||||
filterDTO: IBillPaymentsFilter
|
|
||||||
): Promise<{
|
|
||||||
billPayments: IBillPayment;
|
|
||||||
pagination: IPaginationMeta;
|
|
||||||
filterMeta: IFilterMeta;
|
|
||||||
}> {
|
|
||||||
const { BillPayment } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
// Parses filter DTO.
|
|
||||||
const filter = this.parseListFilterDTO(filterDTO);
|
|
||||||
|
|
||||||
// Dynamic list service.
|
|
||||||
const dynamicList = await this.dynamicListService.dynamicList(
|
|
||||||
tenantId,
|
|
||||||
BillPayment,
|
|
||||||
filter
|
|
||||||
);
|
|
||||||
|
|
||||||
const { results, pagination } = await BillPayment.query()
|
|
||||||
.onBuild((builder) => {
|
|
||||||
builder.withGraphFetched('vendor');
|
|
||||||
builder.withGraphFetched('paymentAccount');
|
|
||||||
|
|
||||||
dynamicList.buildQuery()(builder);
|
|
||||||
})
|
|
||||||
.pagination(filter.page - 1, filter.pageSize);
|
|
||||||
|
|
||||||
// Transformes the bill payments models to POJO.
|
|
||||||
const billPayments = await this.transformer.transform(
|
|
||||||
tenantId,
|
|
||||||
results,
|
|
||||||
new BillPaymentTransformer()
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
billPayments,
|
|
||||||
pagination,
|
|
||||||
filterMeta: dynamicList.getResponseMeta(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves bills payment amount changes different.
|
|
||||||
* @param {number} tenantId -
|
|
||||||
* @param {IBillPaymentEntryDTO[]} paymentMadeEntries -
|
|
||||||
* @param {IBillPaymentEntryDTO[]} oldPaymentMadeEntries -
|
|
||||||
*/
|
|
||||||
public async saveChangeBillsPaymentAmount(
|
|
||||||
tenantId: number,
|
|
||||||
paymentMadeEntries: IBillPaymentEntryDTO[],
|
|
||||||
oldPaymentMadeEntries?: IBillPaymentEntryDTO[],
|
|
||||||
trx?: Knex.Transaction
|
|
||||||
): Promise<void> {
|
|
||||||
const { Bill } = this.tenancy.models(tenantId);
|
|
||||||
const opers: Promise<void>[] = [];
|
|
||||||
|
|
||||||
const diffEntries = entriesAmountDiff(
|
|
||||||
paymentMadeEntries,
|
|
||||||
oldPaymentMadeEntries,
|
|
||||||
'paymentAmount',
|
|
||||||
'billId'
|
|
||||||
);
|
|
||||||
diffEntries.forEach(
|
|
||||||
(diffEntry: { paymentAmount: number; billId: number }) => {
|
|
||||||
if (diffEntry.paymentAmount === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const oper = Bill.changePaymentAmount(
|
|
||||||
diffEntry.billId,
|
|
||||||
diffEntry.paymentAmount,
|
|
||||||
trx
|
|
||||||
);
|
|
||||||
opers.push(oper);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await Promise.all(opers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the given vendor has no associated payments.
|
|
||||||
* @param {number} tenantId
|
|
||||||
* @param {number} vendorId
|
|
||||||
*/
|
|
||||||
public async validateVendorHasNoPayments(tenantId: number, vendorId: number) {
|
|
||||||
const { BillPayment } = this.tenancy.models(tenantId);
|
|
||||||
|
|
||||||
const payments = await BillPayment.query().where('vendor_id', vendorId);
|
|
||||||
|
|
||||||
if (payments.length > 0) {
|
|
||||||
throw new ServiceError(ERRORS.VENDOR_HAS_PAYMENTS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { IBillPaymentDTO, IBillPayment } from '@/interfaces';
|
||||||
|
import { CreateBillPayment } from './CreateBillPayment';
|
||||||
|
import { DeleteBillPayment } from './DeleteBillPayment';
|
||||||
|
import { EditBillPayment } from './EditBillPayment';
|
||||||
|
import { GetBillPayments } from './GetBillPayments';
|
||||||
|
import { GetBillPayment } from './GetBillPayment';
|
||||||
|
import { GetPaymentBills } from './GetPaymentBills';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill payments application.
|
||||||
|
* @service
|
||||||
|
*/
|
||||||
|
@Service()
|
||||||
|
export class BillPaymentsApplication {
|
||||||
|
@Inject()
|
||||||
|
private createBillPaymentService: CreateBillPayment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private deleteBillPaymentService: DeleteBillPayment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private editBillPaymentService: EditBillPayment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getBillPaymentsService: GetBillPayments;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getBillPaymentService: GetBillPayment;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getPaymentBillsService: GetPaymentBills;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a bill payment with associated GL entries.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {IBillPaymentDTO} billPaymentDTO
|
||||||
|
* @returns {Promise<IBillPayment>}
|
||||||
|
*/
|
||||||
|
public createBillPayment(
|
||||||
|
tenantId: number,
|
||||||
|
billPaymentDTO: IBillPaymentDTO
|
||||||
|
): Promise<IBillPayment> {
|
||||||
|
return this.createBillPaymentService.createBillPayment(
|
||||||
|
tenantId,
|
||||||
|
billPaymentDTO
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delets the given bill payment with associated GL entries.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} billPaymentId
|
||||||
|
*/
|
||||||
|
public deleteBillPayment(tenantId: number, billPaymentId: number) {
|
||||||
|
return this.deleteBillPaymentService.deleteBillPayment(
|
||||||
|
tenantId,
|
||||||
|
billPaymentId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the given bill payment with associated GL entries.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} billPaymentId
|
||||||
|
* @param billPaymentDTO
|
||||||
|
* @returns {Promise<IBillPayment>}
|
||||||
|
*/
|
||||||
|
public editBillPayment(
|
||||||
|
tenantId: number,
|
||||||
|
billPaymentId: number,
|
||||||
|
billPaymentDTO
|
||||||
|
): Promise<IBillPayment> {
|
||||||
|
return this.editBillPaymentService.editBillPayment(
|
||||||
|
tenantId,
|
||||||
|
billPaymentId,
|
||||||
|
billPaymentDTO
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves bill payments list.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param filterDTO
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getBillPayments(tenantId: number, filterDTO: IBillPaymentsFilter) {
|
||||||
|
return this.getBillPaymentsService.getBillPayments(tenantId, filterDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve specific bill payment.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} billPyamentId
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getBillPayment(tenantId: number, billPyamentId: number) {
|
||||||
|
return this.getBillPaymentService.getBillPayment(tenantId, billPyamentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve payment made associated bills.
|
||||||
|
* @param {number} tenantId -
|
||||||
|
* @param {number} billPaymentId -
|
||||||
|
*/
|
||||||
|
public getPaymentBills(tenantId: number, billPaymentId: number) {
|
||||||
|
return this.getPaymentBillsService.getPaymentBills(tenantId, billPaymentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user