Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; import { InventoryCountSession } from '../schemas/count.schema'; import { LedgerService } from '../../stock-ledger/services/ledger.service'; @Injectable() export class CountService { constructor( @InjectModel(InventoryCountSession.name) private readonly countModel: Model<InventoryCountSession>, private readonly ledgerService: LedgerService ) {} async createCountSession(tenantId: string, data: any): Promise<InventoryCountSession> { const count = await this.countModel.countDocuments({ tenantId }).exec(); const sessionNumber = `CNT-${new Date().getFullYear()}-${(count + 1).toString().padStart(5, '0')}`; return this.countModel.create({ ...data, tenantId, sessionNumber, status: 'active', }); } async enterCount(tenantId: string, id: string, countedLines: any[]): Promise<InventoryCountSession> { const session = await this.countModel.findOne({ _id: id, tenantId, status: 'active' }).exec(); if (!session) throw new NotFoundException('Active count session not found'); session.lines = countedLines; session.status = 'completed'; await session.save(); return session; } async approveCountSession(tenantId: string, id: string, userId: string): Promise<InventoryCountSession> { const session = await this.countModel.findOne({ _id: id, tenantId, status: 'completed' }).exec(); if (!session) throw new NotFoundException('Completed count session not found'); // Post variance adjustments to ledger for (const line of session.lines) { const variance = line.countedQuantity - line.systemQuantity; if (variance !== 0) { await this.ledgerService.postLedgerEntry(tenantId, { itemCode: line.itemCode, warehouseId: line.warehouseId, locationId: line.locationId || null, transactionType: 'Cycle Count Adjustment', quantityChange: variance, unitCost: 0, totalCost: 0, batchNumber: line.batchNumber || null, serialNumber: line.serialNumber || null, sourceEntityId: session._id.toString(), sourceEntityType: 'InventoryCountSession', correlationId: `${session._id.toString()}-${line.itemCode}`, }, userId); } } session.status = 'approved'; session.approvedBy = userId; session.approvalDate = new Date(); await session.save(); return session; } async getCountSessions(tenantId: string): Promise<InventoryCountSession[]> { return this.countModel.find({ tenantId }).exec(); } } |