fix: bill
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20260217121029_meterageREquired extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`select 1`);
|
||||
}
|
||||
|
||||
override async down(): Promise<void> {
|
||||
this.addSql(`select 1`);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -30,7 +30,8 @@
|
||||
"seed:run": "mikro-orm seeder:run --config=database/mikro-orm.config.ts",
|
||||
"seed:test-companies": "mikro-orm seeder:run --config=database/mikro-orm.config.ts -- --class=TestCompaniesSeeder",
|
||||
"seed:cleanup-test-companies": "mikro-orm seeder:run --config=database/mikro-orm.config.ts -- --class=CleanupTestCompaniesSeeder",
|
||||
"db:dump": "node scripts/db-dump.js"
|
||||
"db:dump": "node scripts/db-dump.js",
|
||||
"db:restore": "node scripts/db-restore.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.826.0",
|
||||
@@ -43,6 +44,7 @@
|
||||
"@langchain/openai": "^0.5.12",
|
||||
"@mikro-orm/cli": "^6.4.16",
|
||||
"@mikro-orm/core": "^6.4.16",
|
||||
"@mikro-orm/migrations": "6.4.16",
|
||||
"@mikro-orm/nestjs": "^6.1.1",
|
||||
"@mikro-orm/postgresql": "^6.4.16",
|
||||
"@mikro-orm/seeder": "^6.4.16",
|
||||
|
||||
Generated
+165
@@ -38,6 +38,9 @@ importers:
|
||||
'@mikro-orm/core':
|
||||
specifier: ^6.4.16
|
||||
version: 6.4.16
|
||||
'@mikro-orm/migrations':
|
||||
specifier: 6.4.16
|
||||
version: 6.4.16(@mikro-orm/core@6.4.16)(@types/node@22.15.30)(pg@8.16.0)
|
||||
'@mikro-orm/nestjs':
|
||||
specifier: ^6.1.1
|
||||
version: 6.1.1(@mikro-orm/core@6.4.16)(@nestjs/common@11.1.3(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3)
|
||||
@@ -1607,6 +1610,12 @@ packages:
|
||||
mariadb:
|
||||
optional: true
|
||||
|
||||
'@mikro-orm/migrations@6.4.16':
|
||||
resolution: {integrity: sha512-cyyI7QILGksGzUq67DxIFQ+C2+peLaVv9IlGboOl4dFFo2D7AdvKM8fL+k6ErnCZWfTidivy/+lUk0Z1R/kQDw==}
|
||||
engines: {node: '>= 18.12.0'}
|
||||
peerDependencies:
|
||||
'@mikro-orm/core': ^6.0.0
|
||||
|
||||
'@mikro-orm/nestjs@6.1.1':
|
||||
resolution: {integrity: sha512-aluD3eTeuCvIePDk5UBanHIhu1zAJQXqWAg47MZdHJmFkNuXn62DCXbD2c4X5TCpKW/m0zjba22ilyZ/AFG9qg==}
|
||||
engines: {node: '>= 18.12.0'}
|
||||
@@ -2047,6 +2056,25 @@ packages:
|
||||
'@rtsao/scc@1.1.0':
|
||||
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
|
||||
|
||||
'@rushstack/node-core-library@5.13.0':
|
||||
resolution: {integrity: sha512-IGVhy+JgUacAdCGXKUrRhwHMTzqhWwZUI+qEPcdzsb80heOw0QPbhhoVsoiMF7Klp8eYsp7hzpScMXmOa3Uhfg==}
|
||||
peerDependencies:
|
||||
'@types/node': '*'
|
||||
peerDependenciesMeta:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
'@rushstack/terminal@0.15.2':
|
||||
resolution: {integrity: sha512-7Hmc0ysK5077R/IkLS9hYu0QuNafm+TbZbtYVzCMbeOdMjaRboLKrhryjwZSRJGJzu+TV1ON7qZHeqf58XfLpA==}
|
||||
peerDependencies:
|
||||
'@types/node': '*'
|
||||
peerDependenciesMeta:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
'@rushstack/ts-command-line@4.23.7':
|
||||
resolution: {integrity: sha512-Gr9cB7DGe6uz5vq2wdr89WbVDKz0UeuFEn5H2CfWDe7JvjFFaiV15gi6mqDBTbHhHCWS7w8mF1h3BnIfUndqdA==}
|
||||
|
||||
'@scarf/scarf@1.4.0':
|
||||
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
|
||||
|
||||
@@ -2396,6 +2424,9 @@ packages:
|
||||
'@tybys/wasm-util@0.9.0':
|
||||
resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
|
||||
|
||||
'@types/argparse@1.0.38':
|
||||
resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
|
||||
|
||||
@@ -2856,6 +2887,14 @@ packages:
|
||||
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
|
||||
ajv-draft-04@1.0.0:
|
||||
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
|
||||
peerDependencies:
|
||||
ajv: ^8.5.0
|
||||
peerDependenciesMeta:
|
||||
ajv:
|
||||
optional: true
|
||||
|
||||
ajv-formats@2.1.1:
|
||||
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
|
||||
peerDependencies:
|
||||
@@ -2885,6 +2924,9 @@ packages:
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
ajv@8.13.0:
|
||||
resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
|
||||
|
||||
ajv@8.17.1:
|
||||
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
|
||||
|
||||
@@ -4292,6 +4334,10 @@ packages:
|
||||
resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
fs-extra@11.3.3:
|
||||
resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
fs-minipass@2.1.0:
|
||||
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -4625,6 +4671,10 @@ packages:
|
||||
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
import-lazy@4.0.0:
|
||||
resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
import-local@3.2.0:
|
||||
resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -5047,6 +5097,9 @@ packages:
|
||||
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
|
||||
hasBin: true
|
||||
|
||||
jju@1.4.0:
|
||||
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
|
||||
|
||||
js-beautify@1.15.4:
|
||||
resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -5450,6 +5503,10 @@ packages:
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
lru-cache@6.0.0:
|
||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
luxon@3.6.1:
|
||||
resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -6204,6 +6261,10 @@ packages:
|
||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pony-cause@2.1.11:
|
||||
resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -6601,6 +6662,11 @@ packages:
|
||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||
hasBin: true
|
||||
|
||||
semver@7.5.4:
|
||||
resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
semver@7.7.2:
|
||||
resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -7166,6 +7232,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
umzug@3.8.2:
|
||||
resolution: {integrity: sha512-BEWEF8OJjTYVC56GjELeHl/1XjFejrD7aHzn+HldRJTx+pL1siBrKHZC8n4K/xL3bEzVA9o++qD1tK2CpZu4KA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -9081,6 +9151,25 @@ snapshots:
|
||||
- supports-color
|
||||
- tedious
|
||||
|
||||
'@mikro-orm/migrations@6.4.16(@mikro-orm/core@6.4.16)(@types/node@22.15.30)(pg@8.16.0)':
|
||||
dependencies:
|
||||
'@mikro-orm/core': 6.4.16
|
||||
'@mikro-orm/knex': 6.4.16(@mikro-orm/core@6.4.16)(pg@8.16.0)
|
||||
fs-extra: 11.3.0
|
||||
umzug: 3.8.2(@types/node@22.15.30)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- better-sqlite3
|
||||
- libsql
|
||||
- mariadb
|
||||
- mysql
|
||||
- mysql2
|
||||
- pg
|
||||
- pg-native
|
||||
- sqlite3
|
||||
- supports-color
|
||||
- tedious
|
||||
|
||||
'@mikro-orm/nestjs@6.1.1(@mikro-orm/core@6.4.16)(@nestjs/common@11.1.3(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.3)':
|
||||
dependencies:
|
||||
'@mikro-orm/core': 6.4.16
|
||||
@@ -9516,6 +9605,35 @@ snapshots:
|
||||
|
||||
'@rtsao/scc@1.1.0': {}
|
||||
|
||||
'@rushstack/node-core-library@5.13.0(@types/node@22.15.30)':
|
||||
dependencies:
|
||||
ajv: 8.13.0
|
||||
ajv-draft-04: 1.0.0(ajv@8.13.0)
|
||||
ajv-formats: 3.0.1(ajv@8.13.0)
|
||||
fs-extra: 11.3.3
|
||||
import-lazy: 4.0.0
|
||||
jju: 1.4.0
|
||||
resolve: 1.22.10
|
||||
semver: 7.5.4
|
||||
optionalDependencies:
|
||||
'@types/node': 22.15.30
|
||||
|
||||
'@rushstack/terminal@0.15.2(@types/node@22.15.30)':
|
||||
dependencies:
|
||||
'@rushstack/node-core-library': 5.13.0(@types/node@22.15.30)
|
||||
supports-color: 8.1.1
|
||||
optionalDependencies:
|
||||
'@types/node': 22.15.30
|
||||
|
||||
'@rushstack/ts-command-line@4.23.7(@types/node@22.15.30)':
|
||||
dependencies:
|
||||
'@rushstack/terminal': 0.15.2(@types/node@22.15.30)
|
||||
'@types/argparse': 1.0.38
|
||||
argparse: 1.0.10
|
||||
string-argv: 0.3.2
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
'@scarf/scarf@1.4.0': {}
|
||||
|
||||
'@sec-ant/readable-stream@0.4.1': {}
|
||||
@@ -9967,6 +10085,8 @@ snapshots:
|
||||
tslib: 2.8.1
|
||||
optional: true
|
||||
|
||||
'@types/argparse@1.0.38': {}
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
dependencies:
|
||||
'@babel/parser': 7.27.5
|
||||
@@ -10520,10 +10640,18 @@ snapshots:
|
||||
dependencies:
|
||||
humanize-ms: 1.2.1
|
||||
|
||||
ajv-draft-04@1.0.0(ajv@8.13.0):
|
||||
optionalDependencies:
|
||||
ajv: 8.13.0
|
||||
|
||||
ajv-formats@2.1.1(ajv@8.17.1):
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.13.0):
|
||||
optionalDependencies:
|
||||
ajv: 8.13.0
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.17.1):
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
@@ -10544,6 +10672,13 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
ajv@8.13.0:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
uri-js: 4.4.1
|
||||
|
||||
ajv@8.17.1:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
@@ -12242,6 +12377,12 @@ snapshots:
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.1
|
||||
|
||||
fs-extra@11.3.3:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
jsonfile: 6.1.0
|
||||
universalify: 2.0.1
|
||||
|
||||
fs-minipass@2.1.0:
|
||||
dependencies:
|
||||
minipass: 3.3.6
|
||||
@@ -12672,6 +12813,8 @@ snapshots:
|
||||
parent-module: 1.0.1
|
||||
resolve-from: 4.0.0
|
||||
|
||||
import-lazy@4.0.0: {}
|
||||
|
||||
import-local@3.2.0:
|
||||
dependencies:
|
||||
pkg-dir: 4.2.0
|
||||
@@ -13285,6 +13428,8 @@ snapshots:
|
||||
|
||||
jiti@2.4.2: {}
|
||||
|
||||
jju@1.4.0: {}
|
||||
|
||||
js-beautify@1.15.4:
|
||||
dependencies:
|
||||
config-chain: 1.1.13
|
||||
@@ -13664,6 +13809,10 @@ snapshots:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
|
||||
lru-cache@6.0.0:
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
|
||||
luxon@3.6.1: {}
|
||||
|
||||
magic-string@0.30.17:
|
||||
@@ -14620,6 +14769,8 @@ snapshots:
|
||||
|
||||
pluralize@8.0.0: {}
|
||||
|
||||
pony-cause@2.1.11: {}
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
postgres-array@2.0.0: {}
|
||||
@@ -15074,6 +15225,10 @@ snapshots:
|
||||
|
||||
semver@6.3.1: {}
|
||||
|
||||
semver@7.5.4:
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
|
||||
semver@7.7.2: {}
|
||||
|
||||
send@1.2.0:
|
||||
@@ -15714,6 +15869,16 @@ snapshots:
|
||||
|
||||
uint8array-extras@1.4.0: {}
|
||||
|
||||
umzug@3.8.2(@types/node@22.15.30):
|
||||
dependencies:
|
||||
'@rushstack/ts-command-line': 4.23.7(@types/node@22.15.30)
|
||||
emittery: 0.13.1
|
||||
fast-glob: 3.3.3
|
||||
pony-cause: 2.1.11
|
||||
type-fest: 4.41.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
@@ -21,12 +21,14 @@ export class BillsController {
|
||||
|
||||
@ApiOperation({ summary: "Create water bill" })
|
||||
@Post("water")
|
||||
@ApiHeader({ name: "x-business-id" })
|
||||
createWaterBill(@Body() dto: CreateWaterBillDto, @BusinessDec() business: Business) {
|
||||
return this.billsService.createWaterBill(dto, business);
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Create water bill from excel file" })
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@ApiHeader({ name: "x-business-id" })
|
||||
@UseInterceptors(FileInterceptor("file"))
|
||||
@ApiBody({ type: CreateWaterBillFromExcelDto })
|
||||
@Post("water/excel")
|
||||
@@ -39,6 +41,7 @@ export class BillsController {
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: "Create charge bill" })
|
||||
@ApiHeader({ name: "x-business-id" })
|
||||
@Post("charge")
|
||||
createChargeBill(@Body() dto: CreateChargeBillDto, @BusinessDec() business: Business) {
|
||||
return this.billsService.createChargeBill(dto, business);
|
||||
|
||||
@@ -8,9 +8,14 @@ import { BusinessesModule } from "../businesses/businesses.module";
|
||||
import { CompaniesModule } from "../companies/companies.module";
|
||||
import { NotificationModule } from "../notifications/notifications.module";
|
||||
import { InvoicesModule } from "../invoices/invoices.module";
|
||||
import { BullModule } from "@nestjs/bullmq";
|
||||
import { INVOICE } from "../invoices/constants";
|
||||
|
||||
@Module({
|
||||
imports: [MikroOrmModule.forFeature([Bill]), CompaniesModule, BusinessesModule,NotificationModule,InvoicesModule],
|
||||
imports: [
|
||||
BullModule.registerQueue({ name: INVOICE.QUEUE_NAME }),
|
||||
MikroOrmModule.forFeature([Bill]), CompaniesModule, BusinessesModule
|
||||
, NotificationModule, InvoicesModule],
|
||||
controllers: [BillsController],
|
||||
providers: [BillsService],
|
||||
})
|
||||
|
||||
@@ -19,7 +19,10 @@ import { CompaniesService } from "../companies/services/companies.service";
|
||||
import { InvoiceItem } from "../invoices/entities/invoice-item.entity";
|
||||
import { Invoice } from "../invoices/entities/invoice.entity";
|
||||
import { NotificationQueue } from "../notifications/queue/notification.queue";
|
||||
import { InvoicesService } from "../invoices/providers/invoices.service";
|
||||
import { InjectQueue } from "@nestjs/bullmq";
|
||||
import { INVOICE } from "../invoices/constants";
|
||||
import { Queue } from "bullmq";
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class BillsService {
|
||||
@@ -27,8 +30,9 @@ export class BillsService {
|
||||
private readonly em: EntityManager,
|
||||
private readonly companiesService: CompaniesService,
|
||||
private readonly billRepository: BillsRepository,
|
||||
@InjectQueue(INVOICE.QUEUE_NAME)
|
||||
private readonly invoiceQueue: Queue,
|
||||
private readonly notificationQueue: NotificationQueue,
|
||||
private readonly invoicesService: InvoicesService,
|
||||
|
||||
) { }
|
||||
|
||||
@@ -76,35 +80,14 @@ export class BillsService {
|
||||
});
|
||||
|
||||
invoice.items.add(invoiceItem);
|
||||
|
||||
await this.notificationQueue.addInvoiceCreationNotification(company.user.id, {
|
||||
invoiceId: invoice.numericId.toString(),
|
||||
dueDate: invoice.dueDate,
|
||||
createDate: invoice.createdAt,
|
||||
price: new Decimal(invoice.totalPrice).toNumber(),
|
||||
userPhone: company.user.phone,
|
||||
userEmail: company.user.email,
|
||||
items: invoiceItem.name,
|
||||
paidAt: invoice.paidAt,
|
||||
});
|
||||
|
||||
await this.invoicesService.scheduleInvoiceJobs(invoice, {
|
||||
companyId: company.id,
|
||||
items: [
|
||||
{
|
||||
name: invoiceItem.name,
|
||||
count: invoiceItem.count,
|
||||
unitPrice: new Decimal(invoiceItem.unitPrice).toNumber(),
|
||||
discount: new Decimal(invoiceItem.discount).toNumber(),
|
||||
},
|
||||
],
|
||||
});
|
||||
em.persist(invoice);
|
||||
}
|
||||
|
||||
await em.flush();
|
||||
await em.commit();
|
||||
|
||||
await this.addInvoiceReminderJobs(bill.id);
|
||||
|
||||
return bill;
|
||||
} catch (error) {
|
||||
await em.rollback();
|
||||
@@ -112,6 +95,34 @@ export class BillsService {
|
||||
}
|
||||
}
|
||||
|
||||
private async addInvoiceReminderJobs(billId: string) {
|
||||
const invoices = await this.em.find(Invoice, { bill: { id: billId } }, { populate: ["items", "company","company.user"] });
|
||||
|
||||
for (const invoice of invoices) {
|
||||
await this.notificationQueue.addInvoiceCreationNotification(invoice.company.user.id, {
|
||||
invoiceId: invoice.numericId.toString(),
|
||||
dueDate: invoice.dueDate,
|
||||
createDate: invoice.createdAt,
|
||||
price: new Decimal(invoice.totalPrice).toNumber(),
|
||||
userPhone: invoice.company.user.phone,
|
||||
userEmail: invoice.company.user.email,
|
||||
items: invoice.items[0].name,
|
||||
paidAt: invoice.paidAt,
|
||||
});
|
||||
|
||||
await this.invoiceQueue.add(
|
||||
INVOICE.REMINDER_JOB_NAME,
|
||||
{ invoiceId: invoice.id },
|
||||
{
|
||||
delay: dayjs(invoice.dueDate).subtract(INVOICE.DAYS_BEFORE_OVERDUE, "day").diff(dayjs()),
|
||||
attempts: INVOICE.REMINDER_JOB_ATTEMPTS,
|
||||
backoff: { type: "exponential", delay: INVOICE.REMINDER_JOB_BACKOFF },
|
||||
priority: INVOICE.REMINDER_JOB_PRIORITY,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async createWaterBillByExcel(file: IFile, dto: CreateWaterBillFromExcelDto, business: Business) {
|
||||
const values = await this.parseWaterBillExcel(file.buffer);
|
||||
if (values.length === 0) {
|
||||
@@ -155,7 +166,7 @@ export class BillsService {
|
||||
const companies = await this.companiesService.findAllBybusinessId(business.id, em);
|
||||
|
||||
for (const company of companies) {
|
||||
const subtotal = new Decimal(chargeRate);
|
||||
const subtotal = new Decimal(chargeRate).mul(company.metrage);
|
||||
const tax = subtotal.mul(0.1);
|
||||
const totalPrice = subtotal.add(tax);
|
||||
|
||||
@@ -185,6 +196,8 @@ export class BillsService {
|
||||
await em.flush();
|
||||
await em.commit();
|
||||
|
||||
await this.addInvoiceReminderJobs(bill.id)
|
||||
|
||||
return bill;
|
||||
} catch (error) {
|
||||
await em.rollback();
|
||||
|
||||
@@ -76,11 +76,10 @@ export class CreateCompanyDto extends PickType(CompleteRegistrationDto, ["phone"
|
||||
@ApiProperty({ description: "آدرس تصویر کاور", example: "https://www.example.com/cover.jpg" })
|
||||
coverImageUrl: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt({ message: CompanyMessage.METRAGE_MUST_BE_INT })
|
||||
@Min(1, { message: CompanyMessage.METRAGE_MUST_BE_POSITIVE })
|
||||
@ApiProperty({ description: "متراژ شرکت (متر مربع)", example: 500 })
|
||||
metrage?: number;
|
||||
metrage: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNotEmpty({ message: CompanyMessage.IS_ACTIVE_REQUIRED })
|
||||
@@ -126,6 +125,7 @@ export class CreateCompanyRequestDto extends PickType(CreateCompanyDto, [
|
||||
"industryId",
|
||||
"products",
|
||||
"services",
|
||||
"metrage"
|
||||
]) {
|
||||
@IsNotEmpty({ message: CompanyMessage.CHIEF_EXECUTIVE_REQUIRED })
|
||||
@IsString({ message: CompanyMessage.CHIEF_EXECUTIVE_MUST_BE_STRING })
|
||||
|
||||
@@ -48,8 +48,8 @@ export class Company extends BaseEntity {
|
||||
@Property({ type: "varchar", length: 255 })
|
||||
coverImageUrl!: string;
|
||||
|
||||
@Property({ type: "int", nullable: true })
|
||||
metrage?: number;
|
||||
@Property({ type: "int", nullable: false })
|
||||
metrage!: number;
|
||||
|
||||
@Property({ type: "boolean", default: true })
|
||||
isActive!: boolean & Opt;
|
||||
|
||||
Reference in New Issue
Block a user