invoice item total and subtotal
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
*.md
|
||||||
|
.env*
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
+3
-4
@@ -1,9 +1,8 @@
|
|||||||
# Stage 1: Base
|
# Stage 1: Base
|
||||||
FROM node:22-alpine AS base
|
FROM node:22-alpine AS base
|
||||||
|
|
||||||
# Install timezone support
|
# Set timezone (Node.js respects TZ env variable natively)
|
||||||
RUN apk add --no-cache tzdata
|
ENV TZ=Asia/Tehran
|
||||||
RUN cp /usr/share/zoneinfo/Asia/Tehran /etc/localtime && echo "Asia/Tehran" > /etc/timezone
|
|
||||||
|
|
||||||
# Set workdir for clarity
|
# Set workdir for clarity
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
@@ -12,7 +11,7 @@ WORKDIR /app
|
|||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
WORKDIR /temp-deps
|
WORKDIR /temp-deps
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm ci --ignore-scripts
|
RUN npm ci --ignore-scripts --no-fund --no-audit
|
||||||
|
|
||||||
# Stage 3: Build
|
# Stage 3: Build
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
|
|||||||
@@ -2831,6 +2831,16 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "integer"
|
"mappedType": "integer"
|
||||||
},
|
},
|
||||||
|
"sub_total": {
|
||||||
|
"name": "sub_total",
|
||||||
|
"type": "int",
|
||||||
|
"generated": "(COALESCE(unit_price, 0) * quantity) STORED",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "integer"
|
||||||
|
},
|
||||||
"discount": {
|
"discount": {
|
||||||
"name": "discount",
|
"name": "discount",
|
||||||
"type": "int",
|
"type": "int",
|
||||||
@@ -2840,6 +2850,16 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"mappedType": "integer"
|
"mappedType": "integer"
|
||||||
},
|
},
|
||||||
|
"total": {
|
||||||
|
"name": "total",
|
||||||
|
"type": "int",
|
||||||
|
"generated": "((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "integer"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"name": "description",
|
"name": "description",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { Migration } from '@mikro-orm/migrations';
|
||||||
|
|
||||||
|
export class Migration20260516121012 extends Migration {
|
||||||
|
|
||||||
|
override async up(): Promise<void> {
|
||||||
|
this.addSql(`alter table "invoice_items" add column "sub_total" int generated always as (COALESCE(unit_price, 0) * quantity) STORED not null, add column "total" int generated always as ((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED not null;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -88,7 +88,8 @@ export class CreateInvoiceDto {
|
|||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
|
@IsOptional()
|
||||||
@Type(() => IAttachmentDto)
|
@Type(() => IAttachmentDto)
|
||||||
@ApiProperty({ type: [IAttachmentDto] })
|
@ApiProperty({ type: [IAttachmentDto] })
|
||||||
attachments: IAttachmentDto[];
|
attachments?: IAttachmentDto[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ export class InvoiceItem extends BaseEntity {
|
|||||||
@Property({
|
@Property({
|
||||||
type: 'int',
|
type: 'int',
|
||||||
columnType: 'int GENERATED ALWAYS AS (COALESCE(unit_price, 0) * quantity) STORED',
|
columnType: 'int GENERATED ALWAYS AS (COALESCE(unit_price, 0) * quantity) STORED',
|
||||||
persist: false,
|
|
||||||
})
|
})
|
||||||
subTotal!: number & Opt;
|
subTotal!: number & Opt;
|
||||||
|
|
||||||
@@ -42,7 +41,6 @@ export class InvoiceItem extends BaseEntity {
|
|||||||
@Property({
|
@Property({
|
||||||
type: 'int',
|
type: 'int',
|
||||||
columnType: 'int GENERATED ALWAYS AS ((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED',
|
columnType: 'int GENERATED ALWAYS AS ((COALESCE(unit_price, 0) * quantity) - COALESCE(discount, 0)) STORED',
|
||||||
persist: false
|
|
||||||
})
|
})
|
||||||
total!: number & Opt;
|
total!: number & Opt;
|
||||||
|
|
||||||
|
|||||||
@@ -59,13 +59,16 @@ export class InvoiceService {
|
|||||||
...(request && { request }),
|
...(request && { request }),
|
||||||
enableTax,
|
enableTax,
|
||||||
approvalDeadline,
|
approvalDeadline,
|
||||||
// discount,
|
discount: 0,
|
||||||
paidAmount: 0,
|
paidAmount: 0,
|
||||||
// balance: 0,
|
balance: 0,
|
||||||
attachments: [],
|
attachments: dto.attachments ?? [],
|
||||||
paymentMethod: dto.paymentMethod,
|
paymentMethod: dto.paymentMethod,
|
||||||
invoiceNumber: 20, // TODO : invoice number
|
invoiceNumber: 20, // TODO : invoice number
|
||||||
description: dto.description
|
description: dto.description,
|
||||||
|
subTotal: 0,
|
||||||
|
taxAmount: 0,
|
||||||
|
total: 0,
|
||||||
});
|
});
|
||||||
em.persist(invoice);
|
em.persist(invoice);
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ export class InvoiceService {
|
|||||||
// const total = Math.max(0, subTotal - discount + taxAmount);
|
// const total = Math.max(0, subTotal - discount + taxAmount);
|
||||||
|
|
||||||
// invoice.subTotal = subTotal;
|
// invoice.subTotal = subTotal;
|
||||||
invoice.attachments = dto.attachments;
|
// invoice.attachments = dto.attachments;
|
||||||
// invoice.taxAmount = taxAmount;
|
// invoice.taxAmount = taxAmount;
|
||||||
// invoice.total = total;
|
// invoice.total = total;
|
||||||
// invoice.balance = total - invoice.paidAmount;
|
// invoice.balance = total - invoice.paidAmount;
|
||||||
|
|||||||
Reference in New Issue
Block a user