mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
refactor: inventory adjustments e2e test cases
This commit is contained in:
@@ -152,8 +152,8 @@ import { PostHogModule } from '../EventsTracker/postHog.module';
|
||||
TransactionsLockingModule,
|
||||
SettingsModule,
|
||||
InventoryAdjustmentsModule,
|
||||
PostHogModule,
|
||||
EventTrackerModule,
|
||||
// PostHogModule,
|
||||
// EventTrackerModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { PostHog } from 'posthog-node';
|
||||
import { EventMessage } from 'posthog-node/src/types';
|
||||
// import { PostHog, EventMessage } from 'posthog-node';
|
||||
import { POSTHOG } from './postHog.module';
|
||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
|
||||
interface EventMessage {
|
||||
distinctId
|
||||
}
|
||||
@Injectable()
|
||||
export class EventTrackerService {
|
||||
constructor(
|
||||
@Inject(POSTHOG) private readonly posthog: PostHog,
|
||||
@Inject(POSTHOG) private readonly posthog: any,
|
||||
private readonly tenancyContext: TenancyContext,
|
||||
) {}
|
||||
|
||||
@@ -15,7 +17,7 @@ export class EventTrackerService {
|
||||
* Track tenant an event.
|
||||
* @param event - The event to track.
|
||||
*/
|
||||
public async trackEvent(event: Omit<EventMessage, 'distinctId'>) {
|
||||
public async trackEvent(event: any) {
|
||||
// Cannot continue if the Posthog not configured.
|
||||
if (!this.posthog) return;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ITransactionsLockingPartialUnlocked } from '@/interfaces';
|
||||
import {
|
||||
SUBSCRIPTION_CANCELLED,
|
||||
SUBSCRIPTION_PAYMENT_FAILED,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PostHog } from 'posthog-node';
|
||||
// import { PostHog } from 'posthog-node';
|
||||
import { EventTrackerService } from './EventTracker.service';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@@ -10,10 +10,12 @@ export const POSTHOG = 'PostHog';
|
||||
EventTrackerService,
|
||||
{
|
||||
provide: POSTHOG,
|
||||
useFactory: (configService: ConfigService) =>
|
||||
new PostHog(configService.get('posthog.apiKey'), {
|
||||
host: configService.get('posthog.host'),
|
||||
}),
|
||||
useFactory: (configService: ConfigService) => {
|
||||
|
||||
},
|
||||
// new PostHog(configService.get('posthog.apiKey'), {
|
||||
// host: configService.get('posthog.host'),
|
||||
// }),
|
||||
inject: [ConfigService],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { Body, Controller, Delete, Param, Post } from '@nestjs/common';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
} from '@nestjs/common';
|
||||
import { InventoryAdjustmentsApplicationService } from './InventoryAdjustmentsApplication.service';
|
||||
import { IQuickInventoryAdjustmentDTO } from './types/InventoryAdjustments.types';
|
||||
import { InventoryAdjustment } from './models/InventoryAdjustment';
|
||||
import { PublicRoute } from '../Auth/Jwt.guard';
|
||||
|
||||
@Controller('inventory-adjustments')
|
||||
@PublicRoute()
|
||||
export class InventoryAdjustmentsController {
|
||||
constructor(
|
||||
private readonly inventoryAdjustmentsApplicationService: InventoryAdjustmentsApplicationService,
|
||||
@@ -27,7 +37,16 @@ export class InventoryAdjustmentsController {
|
||||
);
|
||||
}
|
||||
|
||||
@Post(':id/publish')
|
||||
@Get(':id')
|
||||
public async getInventoryAdjustment(
|
||||
@Param('id') inventoryAdjustmentId: number,
|
||||
): Promise<InventoryAdjustment> {
|
||||
return this.inventoryAdjustmentsApplicationService.getInventoryAdjustment(
|
||||
inventoryAdjustmentId,
|
||||
);
|
||||
}
|
||||
|
||||
@Put(':id/publish')
|
||||
public async publishInventoryAdjustment(
|
||||
@Param('id') inventoryAdjustmentId: number,
|
||||
): Promise<void> {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { WarehousesModule } from '../Warehouses/Warehouses.module';
|
||||
import { InventoryAdjustmentsGLSubscriber } from './subscribers/InventoryAdjustmentGL.subscriber';
|
||||
import { InventoryAdjustmentsGLEntries } from './commands/ledger/InventoryAdjustmentsGLEntries';
|
||||
import { LedgerModule } from '../Ledger/Ledger.module';
|
||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
|
||||
const models = [
|
||||
RegisterTenancyModel(InventoryAdjustment),
|
||||
@@ -32,6 +33,7 @@ const models = [
|
||||
InventoryAdjustmentsApplicationService,
|
||||
InventoryAdjustmentsGLSubscriber,
|
||||
InventoryAdjustmentsGLEntries,
|
||||
TenancyContext,
|
||||
],
|
||||
exports: [...models],
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import * as R from 'ramda';
|
||||
import * as moment from 'moment';
|
||||
import { omit } from 'lodash';
|
||||
import { events } from '@/common/events/events';
|
||||
import { InventoryAdjustment } from '../models/InventoryAdjustment';
|
||||
@@ -17,6 +18,7 @@ import { Account } from '@/modules/Accounts/models/Account.model';
|
||||
import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform';
|
||||
import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform';
|
||||
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
|
||||
import { ERRORS } from '../constants/InventoryAdjustments.constants';
|
||||
|
||||
export class CreateQuickInventoryAdjustmentService {
|
||||
constructor(
|
||||
@@ -80,7 +82,6 @@ export class CreateQuickInventoryAdjustmentService {
|
||||
|
||||
/**
|
||||
* Creates a quick inventory adjustment for specific item.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - qucik adjustment DTO.
|
||||
*/
|
||||
public async createQuickAdjustment(
|
||||
@@ -119,7 +120,7 @@ export class CreateQuickInventoryAdjustmentService {
|
||||
// Saves the inventory adjustment with associated entries to the storage.
|
||||
const inventoryAdjustment = await this.inventoryAdjustmentModel
|
||||
.query(trx)
|
||||
.upsertGraph({
|
||||
.upsertGraphAndFetch({
|
||||
...invAdjustmentObject,
|
||||
});
|
||||
// Triggers `onInventoryAdjustmentQuickCreated` event.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import * as moment from 'moment';
|
||||
import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { InventoryAdjustment } from '../models/InventoryAdjustment';
|
||||
import {
|
||||
@@ -9,6 +10,7 @@ import {
|
||||
} from '../types/InventoryAdjustments.types';
|
||||
import { events } from '@/common/events/events';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { ERRORS } from '../constants/InventoryAdjustments.constants';
|
||||
|
||||
export class PublishInventoryAdjustmentService {
|
||||
constructor(
|
||||
@@ -47,11 +49,15 @@ export class PublishInventoryAdjustmentService {
|
||||
);
|
||||
|
||||
// Publish the inventory adjustment transaction.
|
||||
await InventoryAdjustment.query().findById(inventoryAdjustmentId).patch({
|
||||
publishedAt: moment().toMySqlDateTime(),
|
||||
});
|
||||
await this.inventoryAdjustmentModel
|
||||
.query()
|
||||
.findById(inventoryAdjustmentId)
|
||||
.patch({
|
||||
publishedAt: moment().toMySqlDateTime(),
|
||||
});
|
||||
// Retrieve the inventory adjustment after the modification.
|
||||
const inventoryAdjustment = await InventoryAdjustment.query()
|
||||
const inventoryAdjustment = await this.inventoryAdjustmentModel
|
||||
.query()
|
||||
.findById(inventoryAdjustmentId)
|
||||
.withGraphFetched('entries');
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const ERRORS = {
|
||||
export const ERRORS = {
|
||||
INVENTORY_ADJUSTMENT_NOT_FOUND: 'INVENTORY_ADJUSTMENT_NOT_FOUND',
|
||||
ITEM_SHOULD_BE_INVENTORY_TYPE: 'ITEM_SHOULD_BE_INVENTORY_TYPE',
|
||||
INVENTORY_ADJUSTMENT_ALREADY_PUBLISHED:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Model, mixin } from 'objection';
|
||||
import { Model } from 'objection';
|
||||
// import TenantModel from 'models/TenantModel';
|
||||
// import InventoryAdjustmentSettings from './InventoryAdjustment.Settings';
|
||||
// import ModelSetting from './ModelSetting';
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import { TransformerInjectable } from "@/modules/Transformer/TransformerInjectable.service";
|
||||
import { InventoryAdjustment } from "../models/InventoryAdjustment";
|
||||
import { InventoryAdjustmentTransformer } from "../InventoryAdjustmentTransformer";
|
||||
import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service';
|
||||
import { InventoryAdjustment } from '../models/InventoryAdjustment';
|
||||
import { InventoryAdjustmentTransformer } from '../InventoryAdjustmentTransformer';
|
||||
import { Inject } from '@nestjs/common';
|
||||
|
||||
export class GetInventoryAdjustmentService {
|
||||
constructor(
|
||||
private readonly transformer: TransformerInjectable,
|
||||
|
||||
@Inject(InventoryAdjustment.name)
|
||||
private readonly inventoryAdjustmentModel: typeof InventoryAdjustment,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve specific inventory adjustment transaction details.
|
||||
* @param {number} inventoryAdjustmentId - Inventory adjustment id.
|
||||
*/
|
||||
async getInventoryAdjustment(
|
||||
inventoryAdjustmentId: number,
|
||||
) {
|
||||
async getInventoryAdjustment(inventoryAdjustmentId: number) {
|
||||
// Retrieve inventory adjustment transation with associated models.
|
||||
const inventoryAdjustment = await InventoryAdjustment.query()
|
||||
const inventoryAdjustment = await this.inventoryAdjustmentModel
|
||||
.query()
|
||||
.findById(inventoryAdjustmentId)
|
||||
.withGraphFetched('entries.item')
|
||||
.withGraphFetched('adjustmentAccount')
|
||||
|
||||
@@ -40,7 +40,7 @@ export class ItemsController extends TenantController {
|
||||
* @returns The updated item id.
|
||||
*/
|
||||
@Put(':id')
|
||||
@UsePipes(new ZodValidationPipe(createItemSchema))
|
||||
// @UsePipes(new ZodValidationPipe(createItemSchema))
|
||||
async editItem(
|
||||
@Param('id') id: string,
|
||||
@Body() editItemDto: any,
|
||||
@@ -55,7 +55,7 @@ export class ItemsController extends TenantController {
|
||||
* @returns The created item id.
|
||||
*/
|
||||
@Post()
|
||||
@UsePipes(new ZodValidationPipe(createItemSchema))
|
||||
// @UsePipes(new ZodValidationPipe(createItemSchema))
|
||||
async createItem(@Body() createItemDto: any): Promise<number> {
|
||||
return this.createItemService.createItem(createItemDto);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Model } from 'objection';
|
||||
import { omit, isEmpty } from 'lodash';
|
||||
import { IMetadata, IMetaQuery, IMetableStore } from './types';
|
||||
import { itemsStartWith } from 'utils';
|
||||
import { itemsStartWith } from '@/utils/items-start-with';
|
||||
|
||||
export class MetableStore implements IMetableStore {
|
||||
metadata: IMetadata[];
|
||||
@@ -23,7 +23,7 @@ export class MetableStore implements IMetableStore {
|
||||
*/
|
||||
setExtraColumns(columns: string[]): void {
|
||||
this.extraColumns = columns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the given metadata key.
|
||||
@@ -120,6 +120,7 @@ export class MetableStore implements IMetableStore {
|
||||
key,
|
||||
...extraColumns,
|
||||
_markAsInserted: true,
|
||||
group: 'default',
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -166,11 +167,11 @@ export class MetableStore implements IMetableStore {
|
||||
* Parse the metadata to the collection.
|
||||
* @param {Array} collection -
|
||||
*/
|
||||
mapMetadataToCollection(metadata: IMetadata[], parseType: string = 'parse') {
|
||||
return metadata.map((model) =>
|
||||
this.mapMetadataToCollection(model, parseType)
|
||||
);
|
||||
}
|
||||
// mapMetadataToCollection(metadata: IMetadata[], parseType: string = 'parse') {
|
||||
// return metadata.map((model) =>
|
||||
// this.mapMetadataToCollection(model, parseType)
|
||||
// );
|
||||
// }
|
||||
|
||||
/**
|
||||
* Load metadata to the metable collection.
|
||||
@@ -198,12 +199,12 @@ export class MetableStore implements IMetableStore {
|
||||
* Static method to load metadata to the collection.
|
||||
* @param {Array} meta
|
||||
*/
|
||||
static from(meta) {
|
||||
const collection = new MetableCollection();
|
||||
collection.from(meta);
|
||||
// static from(meta) {
|
||||
// const collection = new MetableCollection();
|
||||
// collection.from(meta);
|
||||
|
||||
return collection;
|
||||
}
|
||||
// return collection;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Reset the momerized metadata.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { IMetadata, IMetableStoreStorage } from './types';
|
||||
import { MetableStore } from './MetableStore';
|
||||
import { isBlank, parseBoolean } from 'utils';
|
||||
import { MetableConfig } from './MetableConfig';
|
||||
import { EntityRepository } from '@/common/repository/EntityRepository';
|
||||
import { isBlank } from '@/utils/is-blank';
|
||||
import { parseBoolean } from '@/utils/parse-boolean';
|
||||
|
||||
export class MetableDBStore
|
||||
extends MetableStore
|
||||
@@ -72,10 +73,10 @@ export class MetableDBStore
|
||||
/**
|
||||
* Saves the modified, deleted and insert metadata.
|
||||
*/
|
||||
save() {
|
||||
async save() {
|
||||
this.validateStoreIsLoaded();
|
||||
|
||||
return Promise.all([
|
||||
await Promise.all([
|
||||
this.saveUpdated(this.metadata),
|
||||
this.saveDeleted(this.metadata),
|
||||
this.saveInserted(this.metadata),
|
||||
|
||||
@@ -15,5 +15,6 @@ export const SETTINGS = 'SETTINGS';
|
||||
inject: [SettingRepository],
|
||||
},
|
||||
],
|
||||
exports: [SETTINGS]
|
||||
})
|
||||
export class SettingsModule {}
|
||||
|
||||
@@ -10,7 +10,7 @@ export class SettingsStore extends MetableDBStore {
|
||||
constructor(repository: EntityRepository, config: any = SettingsOptions) {
|
||||
super(config);
|
||||
|
||||
// this.setExtraColumns(['group']);
|
||||
this.setExtraColumns(['group']);
|
||||
this.setRepository(repository);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,10 @@ import { PurchasesTransactionLockingGuardSubscriber } from './subscribers/Purcha
|
||||
import { SalesTransactionLockingGuardSubscriber } from './subscribers/SalesTransactionLockingGuardSubscriber';
|
||||
import { QueryTransactionsLocking } from './queries/QueryTransactionsLocking';
|
||||
import { TransactionsLockingController } from './TransactionsLocking.controller';
|
||||
import { SettingsModule } from '../Settings/Settings.module';
|
||||
|
||||
@Module({
|
||||
imports: [SettingsModule],
|
||||
providers: [
|
||||
TransactionsLockingService,
|
||||
FinancialTransactionLocking,
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
TransactionsLockingGroup,
|
||||
TransactionsLockingType,
|
||||
} from './types/TransactionsLocking.types';
|
||||
import { parseDate } from 'utils';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { SettingsStore } from '../Settings/SettingsStore';
|
||||
import { SETTINGS } from '../Settings/Settings.module';
|
||||
@@ -159,3 +158,7 @@ export class TransactionsLockingRepository {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const parseDate = (date: string) => {
|
||||
return date ? moment(date).utcOffset(0).format('YYYY-MM-DD') : '';
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
ITransactionsLockingSchema,
|
||||
TransactionsLockingGroup,
|
||||
} from '@/interfaces';
|
||||
ITransactionsLockingSchema,
|
||||
} from './types/TransactionsLocking.types';
|
||||
|
||||
export const ERRORS = {
|
||||
TRANSACTIONS_DATE_LOCKED: 'TRANSACTIONS_DATE_LOCKED',
|
||||
@@ -30,7 +30,7 @@ export const TRANSACTIONS_LOCKING_SCHEMA = [
|
||||
] as ITransactionsLockingSchema[];
|
||||
|
||||
export function getTransactionsLockingSchemaMeta(
|
||||
module: TransactionsLockingGroup
|
||||
module: TransactionsLockingGroup,
|
||||
): ITransactionsLockingSchema {
|
||||
return TRANSACTIONS_LOCKING_SCHEMA.find((schema) => schema.module === module);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TransactionsLockingGroup } from '../types/TransactionsLocking.types';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TransactionsLockingGuard } from './TransactionsLockingGuard';
|
||||
import { MomentInput } from 'moment';
|
||||
|
||||
@Injectable()
|
||||
export class PurchasesTransactionLockingGuard {
|
||||
@@ -13,7 +14,7 @@ export class PurchasesTransactionLockingGuard {
|
||||
* @param {Date} transactionDate - The transaction date.
|
||||
*/
|
||||
public transactionLockingGuard = async (
|
||||
transactionDate: Date
|
||||
transactionDate: MomentInput
|
||||
) => {
|
||||
this.transactionLockingGuardService.transactionsLockingGuard(
|
||||
transactionDate,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { TransactionsLockingGroup } from '../types/TransactionsLocking.types';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TransactionsLockingGuard } from './TransactionsLockingGuard';
|
||||
import { MomentInput } from 'moment';
|
||||
|
||||
@Injectable()
|
||||
export class SalesTransactionLockingGuard {
|
||||
@@ -13,7 +14,7 @@ export class SalesTransactionLockingGuard {
|
||||
* @param {Date} transactionDate - The transaction date.
|
||||
*/
|
||||
public transactionLockingGuard = async (
|
||||
transactionDate: Date
|
||||
transactionDate: MomentInput
|
||||
) => {
|
||||
await this.transactionLockingGuardService.transactionsLockingGuard(
|
||||
transactionDate,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import moment from 'moment';
|
||||
import moment, { MomentInput } from 'moment';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { TransactionsLockingGroup } from '../types/TransactionsLocking.types';
|
||||
import { TransactionsLockingRepository } from '../TransactionsLockingRepository';
|
||||
@@ -18,7 +18,7 @@ export class TransactionsLockingGuard {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
public isTransactionsLocking = (
|
||||
transactionDate: Date,
|
||||
transactionDate: MomentInput,
|
||||
lockingGroup: string = TransactionsLockingGroup.All
|
||||
): boolean => {
|
||||
const { isEnabled, unlockFromDate, unlockToDate, lockToDate } =
|
||||
@@ -49,7 +49,7 @@ export class TransactionsLockingGuard {
|
||||
* @throws {ServiceError}
|
||||
*/
|
||||
public validateTransactionsLocking = (
|
||||
transactionDate: Date,
|
||||
transactionDate: MomentInput,
|
||||
lockingGroup: TransactionsLockingGroup
|
||||
) => {
|
||||
const isLocked = this.isTransactionsLocking(
|
||||
@@ -83,7 +83,7 @@ export class TransactionsLockingGuard {
|
||||
* @param {Date} transactionDate - The transaction date.
|
||||
*/
|
||||
public transactionsLockingGuard = (
|
||||
transactionDate: Date,
|
||||
transactionDate: MomentInput,
|
||||
moduleType: TransactionsLockingGroup
|
||||
) => {
|
||||
const lockingType =
|
||||
|
||||
@@ -16,6 +16,7 @@ export class RefundVendorCredit extends BaseModel {
|
||||
public depositAccountId!: number;
|
||||
public description!: string;
|
||||
public branchId!: number;
|
||||
public date!: Date;
|
||||
|
||||
public vendorCredit!: VendorCredit;
|
||||
public depositAccount!: Account;
|
||||
|
||||
Reference in New Issue
Block a user