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