All files / src/domains/inventory/adjustments/services adjustment.service.ts

0% Statements 0/24
0% Branches 0/22
0% Functions 0/4
0% Lines 0/21

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                                                                                                                         
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { StockAdjustment } from '../schemas/adjustment.schema';
import { LedgerService } from '../../stock-ledger/services/ledger.service';
 
@Injectable()
export class AdjustmentService {
  constructor(
    @InjectModel(StockAdjustment.name)
    private readonly adjustmentModel: Model<StockAdjustment>,
    private readonly ledgerService: LedgerService
  ) {}
 
  async createAdjustment(tenantId: string, data: any): Promise<StockAdjustment> {
    const count = await this.adjustmentModel.countDocuments({ tenantId }).exec();
    const adjustmentNumber = `ADJ-${new Date().getFullYear()}-${(count + 1).toString().padStart(5, '0')}`;
 
    return this.adjustmentModel.create({
      ...data,
      tenantId,
      adjustmentNumber,
      status: 'approved',
    });
  }
 
  async approveAdjustment(tenantId: string, id: string, userId: string): Promise<StockAdjustment> {
    const adj = await this.adjustmentModel.findOne({ _id: id, tenantId, status: 'approved' }).exec();
    if (!adj) throw new NotFoundException('Adjustment request not found or not in draft/approved');
 
    // Post to Stock Ledger
    for (const line of adj.lines) {
      await this.ledgerService.postLedgerEntry(tenantId, {
        itemCode: line.itemCode,
        warehouseId: line.warehouseId,
        locationId: line.locationId || null,
        transactionType: line.quantityChange > 0 ? 'Stock Adjustment Increase' : 'Stock Adjustment Decrease',
        quantityChange: line.quantityChange,
        unitCost: line.unitCost || 0,
        totalCost: line.quantityChange * (line.unitCost || 0),
        batchNumber: line.batchNumber || null,
        serialNumber: line.serialNumber || null,
        sourceEntityId: adj._id.toString(),
        sourceEntityType: 'StockAdjustment',
        correlationId: `${adj._id.toString()}-${line.itemCode}`,
      }, userId);
    }
 
    adj.status = 'approved';
    adj.approvedBy = userId;
    adj.approvalDate = new Date();
    await adj.save();
 
    return adj;
  }
 
  async getAdjustments(tenantId: string): Promise<StockAdjustment[]> {
    return this.adjustmentModel.find({ tenantId }).exec();
  }
}