add: title to bill
This commit is contained in:
@@ -321,6 +321,15 @@
|
|||||||
"length": 6,
|
"length": 6,
|
||||||
"mappedType": "datetime"
|
"mappedType": "datetime"
|
||||||
},
|
},
|
||||||
|
"title": {
|
||||||
|
"name": "title",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"name": "type",
|
"name": "type",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Migration } from "@mikro-orm/migrations";
|
||||||
|
|
||||||
|
export class Migration20250218120000_add_bill_title extends Migration {
|
||||||
|
override async up(): Promise<void> {
|
||||||
|
this.addSql(`alter table "bill" add column "title" text not null default '';`);
|
||||||
|
this.addSql(`alter table "bill" alter column "title" drop default;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
override async down(): Promise<void> {
|
||||||
|
this.addSql(`alter table "bill" drop column "title";`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,9 @@ import { IFile } from "../utils/interfaces/IFile";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BillsService {
|
export class BillsService {
|
||||||
|
readonly SEWAGE_RATE = 0.3;
|
||||||
|
readonly TAX_RATE = 0.1;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly em: EntityManager,
|
private readonly em: EntityManager,
|
||||||
private readonly companiesService: CompaniesService,
|
private readonly companiesService: CompaniesService,
|
||||||
@@ -40,7 +43,7 @@ export class BillsService {
|
|||||||
try {
|
try {
|
||||||
await em.begin();
|
await em.begin();
|
||||||
|
|
||||||
const bill = em.create(Bill, { type: BillType.WATER_BILL, business });
|
const bill = em.create(Bill, { type: BillType.WATER_BILL, business, title: dto.title });
|
||||||
em.persist(bill);
|
em.persist(bill);
|
||||||
const dueDate = dayjs().add(dueDays, "day").toDate();
|
const dueDate = dayjs().add(dueDays, "day").toDate();
|
||||||
|
|
||||||
@@ -50,10 +53,10 @@ export class BillsService {
|
|||||||
|
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
const waterCost = new Decimal(waterRate).mul(value.waterUsage);
|
const waterCost = new Decimal(waterRate).mul(value.waterUsage);
|
||||||
const sewageCost = waterCost.mul(0.3);
|
const sewageCost = waterCost.mul(this.SEWAGE_RATE);
|
||||||
const subtotal = waterCost.plus(sewageCost);
|
const subtotal = waterCost.plus(sewageCost);
|
||||||
|
|
||||||
const tax = subtotal.mul(0.1);
|
const tax = subtotal.mul(this.TAX_RATE);
|
||||||
const totalPrice = subtotal.plus(tax);
|
const totalPrice = subtotal.plus(tax);
|
||||||
const company = companyMap.get(value.companyId);
|
const company = companyMap.get(value.companyId);
|
||||||
if (!company) {
|
if (!company) {
|
||||||
@@ -72,7 +75,7 @@ export class BillsService {
|
|||||||
|
|
||||||
const invoiceItem = em.create(InvoiceItem, {
|
const invoiceItem = em.create(InvoiceItem, {
|
||||||
name: "قبض آب",
|
name: "قبض آب",
|
||||||
count: value.waterUsage,
|
count: 1,
|
||||||
unitPrice: totalPrice,
|
unitPrice: totalPrice,
|
||||||
discount: new Decimal(0),
|
discount: new Decimal(0),
|
||||||
totalPrice,
|
totalPrice,
|
||||||
@@ -83,9 +86,13 @@ export class BillsService {
|
|||||||
em.persist(invoice);
|
em.persist(invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
|
||||||
await em.commit();
|
await em.commit();
|
||||||
|
|
||||||
|
// Ensure bill.id is available
|
||||||
|
if (!bill.id) {
|
||||||
|
await em.refresh(bill);
|
||||||
|
}
|
||||||
|
|
||||||
await this.addInvoiceReminderJobs(bill.id);
|
await this.addInvoiceReminderJobs(bill.id);
|
||||||
|
|
||||||
return bill;
|
return bill;
|
||||||
@@ -159,7 +166,7 @@ export class BillsService {
|
|||||||
try {
|
try {
|
||||||
await em.begin();
|
await em.begin();
|
||||||
|
|
||||||
const bill = em.create(Bill, { type: BillType.MONTHLY_CHARGE, business });
|
const bill = em.create(Bill, { type: BillType.MONTHLY_CHARGE, business, title: dto.title });
|
||||||
em.persist(bill);
|
em.persist(bill);
|
||||||
const dueDate = dayjs().add(dueDays, "day").toDate();
|
const dueDate = dayjs().add(dueDays, "day").toDate();
|
||||||
|
|
||||||
@@ -192,8 +199,11 @@ export class BillsService {
|
|||||||
em.persist(invoice);
|
em.persist(invoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
await em.flush();
|
|
||||||
await em.commit();
|
await em.commit();
|
||||||
|
// Ensure bill.id is available
|
||||||
|
if (!bill.id) {
|
||||||
|
await em.refresh(bill);
|
||||||
|
}
|
||||||
|
|
||||||
await this.addInvoiceReminderJobs(bill.id);
|
await this.addInvoiceReminderJobs(bill.id);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { ApiProperty } from "@nestjs/swagger";
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
import { IsInt } from "class-validator";
|
import { IsInt, IsNotEmpty, IsString } from "class-validator";
|
||||||
|
|
||||||
export class CreateChargeBillDto {
|
export class CreateChargeBillDto {
|
||||||
|
@ApiProperty({ description: "Bill title" })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
title: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
chargeRate: number;
|
chargeRate: number;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ApiProperty } from "@nestjs/swagger";
|
import { ApiProperty } from "@nestjs/swagger";
|
||||||
import { Type } from "class-transformer";
|
import { Type } from "class-transformer";
|
||||||
import { ArrayMinSize, IsArray, IsInt, IsNotEmpty, IsUUID, ValidateNested } from "class-validator";
|
import { ArrayMinSize, IsArray, IsInt, IsNotEmpty, IsString, IsUUID, ValidateNested } from "class-validator";
|
||||||
|
|
||||||
export class ValueDto {
|
export class ValueDto {
|
||||||
@IsNotEmpty({ message: " BillMessage.COMPANY_ID_REQUIRED" })
|
@IsNotEmpty({ message: " BillMessage.COMPANY_ID_REQUIRED" })
|
||||||
@@ -16,6 +16,11 @@ export class ValueDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CreateWaterBillDto {
|
export class CreateWaterBillDto {
|
||||||
|
@ApiProperty({ description: "Bill title" })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
title: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@IsInt()
|
@IsInt()
|
||||||
waterRate: number;
|
waterRate: number;
|
||||||
@@ -33,6 +38,11 @@ export class CreateWaterBillDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CreateWaterBillFromExcelDto {
|
export class CreateWaterBillFromExcelDto {
|
||||||
|
@ApiProperty({ description: "Bill title" })
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
title: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Type(() => Number)
|
@Type(() => Number)
|
||||||
@IsInt()
|
@IsInt()
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import { BillsRepository } from "../repositories/bill.repository";
|
|||||||
|
|
||||||
@Entity({ repository: () => BillsRepository })
|
@Entity({ repository: () => BillsRepository })
|
||||||
export class Bill extends BaseEntity {
|
export class Bill extends BaseEntity {
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
title!: string;
|
||||||
|
|
||||||
@Enum({ items: () => BillType })
|
@Enum({ items: () => BillType })
|
||||||
type: BillType;
|
type: BillType;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user