Add Tahesab jewelry accounting integration with multi-DB connections.
Encrypt tokens server-side, sync customers both ways, show balances/documents on the person Assets tab, and push sanads with idempotent Factor_Code logging. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Patch,
|
||||
Post,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../auth/jwt-auth.guard';
|
||||
import { CurrentUser } from '../../auth/current-user.decorator';
|
||||
import { Roles } from '../../auth/roles.decorator';
|
||||
import { RolesGuard } from '../../auth/roles.guard';
|
||||
import { TahesabConnectionsService } from './connections.service';
|
||||
import { TahesabPersonLinkService } from './person-link.service';
|
||||
import { TahesabBalanceService } from './balance.service';
|
||||
import { TahesabDocumentsService } from './documents.service';
|
||||
import {
|
||||
CreateInTahesabDto,
|
||||
CreateTahesabConnectionDto,
|
||||
ImportFromTahesabDto,
|
||||
ManualLinkDto,
|
||||
MatchPersonDto,
|
||||
PushSanadDto,
|
||||
SearchTahesabDto,
|
||||
UpdateTahesabConnectionDto,
|
||||
} from './dto';
|
||||
|
||||
@Controller('integrations/tahesab')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class TahesabController {
|
||||
constructor(
|
||||
private readonly connections: TahesabConnectionsService,
|
||||
private readonly links: TahesabPersonLinkService,
|
||||
private readonly balance: TahesabBalanceService,
|
||||
private readonly documents: TahesabDocumentsService,
|
||||
) {}
|
||||
|
||||
// —— Connections ——
|
||||
/** لیست اتصالات برای انتخاب در پروفایل (بدون توکن خام) */
|
||||
@Get('connections/public')
|
||||
listPublicConnections(@CurrentUser() user: { organizationId: string }) {
|
||||
return this.connections.list(user.organizationId);
|
||||
}
|
||||
|
||||
@Get('connections')
|
||||
@Roles('owner', 'admin')
|
||||
listConnections(@CurrentUser() user: { organizationId: string }) {
|
||||
return this.connections.list(user.organizationId);
|
||||
}
|
||||
|
||||
@Post('connections')
|
||||
@Roles('owner', 'admin')
|
||||
createConnection(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Body() dto: CreateTahesabConnectionDto,
|
||||
) {
|
||||
return this.connections.create(user.organizationId, dto);
|
||||
}
|
||||
|
||||
@Patch('connections/:id')
|
||||
@Roles('owner', 'admin')
|
||||
updateConnection(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('id') id: string,
|
||||
@Body() dto: UpdateTahesabConnectionDto,
|
||||
) {
|
||||
return this.connections.update(user.organizationId, id, dto);
|
||||
}
|
||||
|
||||
@Delete('connections/:id')
|
||||
@Roles('owner', 'admin')
|
||||
removeConnection(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('id') id: string,
|
||||
) {
|
||||
return this.connections.remove(user.organizationId, id);
|
||||
}
|
||||
|
||||
@Post('connections/:id/test')
|
||||
@Roles('owner', 'admin')
|
||||
testConnection(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('id') id: string,
|
||||
) {
|
||||
return this.connections.test(user.organizationId, id);
|
||||
}
|
||||
|
||||
// —— Person links (all authenticated CRM users in org) ——
|
||||
@Get('people/:personId/links')
|
||||
listLinks(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
) {
|
||||
return this.links.listLinks(user.organizationId, personId);
|
||||
}
|
||||
|
||||
@Post('people/:personId/links')
|
||||
manualLink(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Body() dto: ManualLinkDto,
|
||||
) {
|
||||
return this.links.manualLink(user.organizationId, personId, dto);
|
||||
}
|
||||
|
||||
@Delete('people/:personId/links/:connectionId')
|
||||
unlink(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Param('connectionId') connectionId: string,
|
||||
) {
|
||||
return this.links.unlink(user.organizationId, personId, connectionId);
|
||||
}
|
||||
|
||||
@Post('people/:personId/match')
|
||||
match(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Body() dto: MatchPersonDto,
|
||||
) {
|
||||
return this.links.match(user.organizationId, personId, dto);
|
||||
}
|
||||
|
||||
@Post('people/:personId/create-in-tahesab')
|
||||
createInTahesab(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Body() dto: CreateInTahesabDto,
|
||||
) {
|
||||
return this.links.createInTahesab(user.organizationId, personId, dto);
|
||||
}
|
||||
|
||||
@Get('people/:personId/assets')
|
||||
getAssets(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Query('connectionId') connectionId?: string,
|
||||
@Query('refresh') refresh?: string,
|
||||
) {
|
||||
return this.balance.getCachedOrFetch(
|
||||
user.organizationId,
|
||||
personId,
|
||||
connectionId,
|
||||
refresh !== '0',
|
||||
);
|
||||
}
|
||||
|
||||
@Get('people/:personId/asnad')
|
||||
listAsnad(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Query('from') from: string,
|
||||
@Query('to') to: string,
|
||||
@Query('connectionId') connectionId?: string,
|
||||
) {
|
||||
return this.documents.listAsnad(
|
||||
user.organizationId,
|
||||
personId,
|
||||
from,
|
||||
to,
|
||||
connectionId,
|
||||
);
|
||||
}
|
||||
|
||||
@Get('lookups')
|
||||
lookups(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Query('connectionId') connectionId?: string,
|
||||
) {
|
||||
return this.documents.listLookups(user.organizationId, connectionId);
|
||||
}
|
||||
|
||||
@Post('people/:personId/sanad')
|
||||
@Roles('owner', 'admin', 'sales')
|
||||
pushSanad(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Param('personId') personId: string,
|
||||
@Body() dto: PushSanadDto,
|
||||
) {
|
||||
return this.documents.pushSanad(user.organizationId, personId, dto);
|
||||
}
|
||||
|
||||
@Post('sync/search')
|
||||
@Roles('owner', 'admin', 'sales')
|
||||
search(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Body() dto: SearchTahesabDto,
|
||||
) {
|
||||
return this.links.search(user.organizationId, dto);
|
||||
}
|
||||
|
||||
@Post('sync/import')
|
||||
@Roles('owner', 'admin', 'sales')
|
||||
importFromTahesab(
|
||||
@CurrentUser() user: { organizationId: string },
|
||||
@Body() dto: ImportFromTahesabDto,
|
||||
) {
|
||||
return this.links.importFromTahesab(user.organizationId, dto);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user