120 lines
3.4 KiB
TypeScript
120 lines
3.4 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
|
|
@Injectable()
|
|
export class AddressesService {
|
|
constructor(private readonly prisma: PrismaService) {}
|
|
|
|
async list(customerId: string) {
|
|
const rows = await this.prisma.customerAddress.findMany({
|
|
where: { customerId },
|
|
orderBy: [{ isDefault: 'desc' }, { createdAt: 'asc' }],
|
|
});
|
|
if (rows.length) return rows.map(mapAddress);
|
|
|
|
const legacy = await this.legacyAddress(customerId);
|
|
if (!legacy) return [];
|
|
const created = await this.prisma.customerAddress.create({
|
|
data: { customerId, text: legacy, isDefault: true },
|
|
});
|
|
return [mapAddress(created)];
|
|
}
|
|
|
|
async create(customerId: string, text: string, label?: string) {
|
|
const trimmed = text.trim();
|
|
const count = await this.prisma.customerAddress.count({ where: { customerId } });
|
|
const row = await this.prisma.customerAddress.create({
|
|
data: {
|
|
customerId,
|
|
text: trimmed,
|
|
label: label?.trim() || null,
|
|
isDefault: count === 0,
|
|
},
|
|
});
|
|
if (row.isDefault) await this.syncLegacy(customerId, trimmed);
|
|
return mapAddress(row);
|
|
}
|
|
|
|
async makeDefault(customerId: string, id: string) {
|
|
const row = await this.own(customerId, id);
|
|
await this.prisma.$transaction([
|
|
this.prisma.customerAddress.updateMany({
|
|
where: { customerId },
|
|
data: { isDefault: false },
|
|
}),
|
|
this.prisma.customerAddress.update({
|
|
where: { id: row.id },
|
|
data: { isDefault: true },
|
|
}),
|
|
]);
|
|
await this.syncLegacy(customerId, row.text);
|
|
return this.list(customerId);
|
|
}
|
|
|
|
async remove(customerId: string, id: string) {
|
|
const row = await this.own(customerId, id);
|
|
await this.prisma.customerAddress.delete({ where: { id: row.id } });
|
|
if (row.isDefault) {
|
|
const next = await this.prisma.customerAddress.findFirst({
|
|
where: { customerId },
|
|
orderBy: { createdAt: 'asc' },
|
|
});
|
|
if (next) {
|
|
await this.prisma.customerAddress.update({
|
|
where: { id: next.id },
|
|
data: { isDefault: true },
|
|
});
|
|
await this.syncLegacy(customerId, next.text);
|
|
} else {
|
|
await this.syncLegacy(customerId, null);
|
|
}
|
|
}
|
|
return this.list(customerId);
|
|
}
|
|
|
|
private async own(customerId: string, id: string) {
|
|
const row = await this.prisma.customerAddress.findFirst({
|
|
where: { id, customerId },
|
|
});
|
|
if (!row) throw new NotFoundException('آدرس پیدا نشد');
|
|
return row;
|
|
}
|
|
|
|
private async legacyAddress(customerId: string): Promise<string | null> {
|
|
try {
|
|
const customer = await this.prisma.customer.findUnique({
|
|
where: { id: customerId },
|
|
select: { address: true },
|
|
});
|
|
return customer?.address?.trim() || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private async syncLegacy(customerId: string, text: string | null) {
|
|
try {
|
|
await this.prisma.customer.update({
|
|
where: { id: customerId },
|
|
data: { address: text },
|
|
});
|
|
} catch {
|
|
/* ستون قدیمی آدرس روی بعضی دیتابیسها هنوز نیست */
|
|
}
|
|
}
|
|
}
|
|
|
|
function mapAddress(row: {
|
|
id: string;
|
|
label: string | null;
|
|
text: string;
|
|
isDefault: boolean;
|
|
}) {
|
|
return {
|
|
id: row.id,
|
|
label: row.label,
|
|
text: row.text,
|
|
isDefault: row.isDefault,
|
|
};
|
|
}
|