Skip to content

Commit

Permalink
improve product history
Browse files Browse the repository at this point in the history
  • Loading branch information
akbarsaputrait committed Sep 19, 2024
1 parent 135abe3 commit a103f72
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/app/customer/order/order.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export class OrderController {

for (const stock of productStocks) {
stock.last_action = `Incoming Order: ${orderNumber}`;
stock.actor = customer.logName;
await manager.getRepository(ProductStock).save(stock);
}
});
Expand Down
2 changes: 2 additions & 0 deletions src/app/owner/restaurant/order/detail.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export class DetailController {
if (orderProduct) {
stock.onhand -= stock.allocated; // Decrease Onhand Stock
stock.allocated -= orderProduct.qty; // Decrease Allocated Stock
stock.sold += orderProduct.qty;
stock.actor = actor ? actor.logName : 'System';
stock.last_action = `Completed Order: ${order.number}`;
stocks.push(stock);
Expand Down Expand Up @@ -163,6 +164,7 @@ export class DetailController {
// Update Stock
for (const stock of stocks) {
stock.last_action = `${titleCase(order.status)} Order: ${order.number}`;
stock.actor = actor.logName;
await manager.getRepository(ProductStock).save(stock);
}

Expand Down
24 changes: 23 additions & 1 deletion src/app/owner/restaurant/product/detail.controller.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import { Loc } from '@core/decorators/location.decorator';
import { Quero } from '@core/decorators/quero.decorator';
import { Rest } from '@core/decorators/restaurant.decorator';
import { OwnerAuthGuard } from '@core/guards/auth.guard';
import { OwnerGuard } from '@core/guards/owner.guard';
import { AwsService } from '@core/services/aws.service';
import { PermAct, PermOwner } from '@core/services/role.service';
import { Media } from '@db/entities/core/media.entity';
import { Location } from '@db/entities/owner/location.entity';
import { ProductHistory } from '@db/entities/owner/product-history.entity';
import { ProductStock } from '@db/entities/owner/product-stock.entity';
import { Product } from '@db/entities/owner/product.entity';
import { ProductTransformer } from '@db/transformers/product.transformer';
import { RawTransformer } from '@db/transformers/raw.transformer';
import { StockTransformer } from '@db/transformers/stock.transformer';
import { ValidationException } from '@lib/exceptions/validation.exception';
import { Validator } from '@lib/helpers/validator.helper';
import { Permissions } from '@lib/rbac';
import AppDataSource from '@lib/typeorm/datasource.typeorm';
import { BadRequestException, Body, Controller, Delete, Get, Param, Post, Put, Req, Res, UseGuards } from '@nestjs/common';
import { Not } from 'typeorm';

@Controller(':product_id')
@UseGuards(OwnerAuthGuard())
@UseGuards(OwnerAuthGuard(), OwnerGuard)
export class DetailController {
constructor(private aws: AwsService) {}

Expand Down Expand Up @@ -113,4 +118,21 @@ export class DetailController {

return response.collection(stocks, StockTransformer);
}

@Get('/histories')
@Permissions(`${PermOwner.Product}@${PermAct.R}`)
async history(@Param() param, @Res() response, @Loc() location) {
const query = AppDataSource.createQueryBuilder(ProductHistory, 't1');
query.leftJoin(Location, 't2', 't2.id = t1.location_id');
query.where('t1.product_id = :product_id', { product_id: param.product_id });

if (location) {
query.andWhere('t2.id = :locId', { locId: location.id });
}

query.selectWithAlias(['t2.id', '_t2.name as location', 't1.action', 't1.data', 't1.actor', 't1.created_at']);

const data = await query.search().sort().getRawPaged();
await response.paginate(data, RawTransformer);
}
}
12 changes: 11 additions & 1 deletion src/app/owner/restaurant/stock/stock.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class StockController {
@Put('/:stock_id')
@UseGuards(OwnerGuard)
@Permissions(`${PermOwner.Stock}@${PermAct.U}`)
async update(@Rest() rest, @Body() body, @Res() response, @Param() param) {
async update(@Rest() rest, @Body() body, @Res() response, @Param() param, @Me() me: Owner) {
const rules = {
onhand: 'required|numeric|min:0',
};
Expand All @@ -220,6 +220,8 @@ export class StockController {
if (Number(body.onhand) <= 0) {
await AppDataSource.transaction(async (manager) => {
productStock.onhand = 0;
productStock.last_action = `Update Stock`;
productStock.actor = me.logName;
await manager.getRepository(ProductStock).save(productStock);

variant.status = VariantStatus.Unvailable;
Expand All @@ -232,7 +234,15 @@ export class StockController {
} else {
await AppDataSource.transaction(async (manager) => {
productStock.onhand = Number(body.onhand);
productStock.last_action = `Update Stock`;
productStock.actor = me.logName;
await manager.getRepository(ProductStock).save(productStock);

variant.status = VariantStatus.Available;
await manager.getRepository(ProductVariant).save(variant);

product.status = ProductStatus.Available;
await manager.getRepository(Product).save(product);
});
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/staff/restaurant/order/detail.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export class DetailController {
if (orderProduct) {
stock.onhand -= stock.allocated; // Decrease Onhand Stock
stock.allocated -= orderProduct.qty; // Decrease Allocated Stock
stock.sold += orderProduct.qty;
stock.actor = actor ? actor.logName : 'System';
stock.last_action = `Completed Order: ${order.number}`;
stocks.push(stock);
Expand Down Expand Up @@ -163,6 +164,7 @@ export class DetailController {
// Update Stock
for (const stock of stocks) {
stock.last_action = `${titleCase(order.status)} Order: ${order.number}`;
stock.actor = actor.logName;
await manager.getRepository(ProductStock).save(stock);
}

Expand Down
31 changes: 24 additions & 7 deletions src/app/staff/restaurant/stock/stock.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class StockController {
@Put('/:stock_id')
@UseGuards(StaffGuard)
@Permissions(`${PermStaff.Stock}@${PermAct.U}`)
async update(@Rest() rest, @Body() body, @Res() response, @Param() param) {
async update(@Rest() rest, @Body() body, @Res() response, @Param() param, @Me() me: StaffUser) {
const rules = {
onhand: 'required|numeric|min:0',
};
Expand All @@ -234,15 +234,32 @@ export class StockController {
if (variant === null) {
// Set all product variants to unavailable when parent are 0
if (Number(body.onhand) <= 0) {
await ProductStock.update({ product_id: product.id }, { onhand: 0 });
await ProductVariant.update({ product_id: product.id }, { status: VariantStatus.Unvailable });
await AppDataSource.transaction(async (manager) => {
productStock.onhand = 0;
productStock.last_action = `Update Stock`;
productStock.actor = me.logName;
await manager.getRepository(ProductStock).save(productStock);

product.status = ProductStatus.Unvailable;
await product.save();
variant.status = VariantStatus.Unvailable;
await manager.getRepository(ProductVariant).save(variant);

product.status = ProductStatus.Unvailable;
await manager.getRepository(Product).save(product);
});
}
} else {
productStock.onhand = Number(body.onhand);
await productStock.save();
await AppDataSource.transaction(async (manager) => {
productStock.onhand = Number(body.onhand);
productStock.last_action = `Update Stock`;
productStock.actor = me.logName;
await manager.getRepository(ProductStock).save(productStock);

variant.status = VariantStatus.Available;
await manager.getRepository(ProductVariant).save(variant);

product.status = ProductStatus.Available;
await manager.getRepository(Product).save(product);
});
}

await response.item(productStock, StockTransformer);
Expand Down
4 changes: 4 additions & 0 deletions src/database/entities/core/customer.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,8 @@ export class Customer extends BaseEntity {
get isValid() {
return this.isVerified && this.isActive;
}

get logName() {
return `${this.name} ${this.email || this.phone ? `<${this.email || this.phone}>` : ''}`;
}
}
3 changes: 3 additions & 0 deletions src/database/entities/owner/product-history.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export class ProductHistory extends BaseEntity {
@JsonColumn()
data: any;

@Column()
actor: string;

@CreateDateColumn()
created_at: Date;

Expand Down
13 changes: 13 additions & 0 deletions src/database/migrations/1726768379070-history-actor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class HistoryActor1726768379070 implements MigrationInterface {
name = 'HistoryActor1726768379070';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`product_history\` ADD \`actor\` varchar(255) NULL`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`product_history\` DROP COLUMN \`actor\``);
}
}
1 change: 1 addition & 0 deletions src/database/subscribers/product-stock.subscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class ProductStockSubscriber implements EntitySubscriberInterface<Product
};
history.product_id = entity.product_id;
history.location_id = entity.location_id;
history.actor = entity.actor;
await manager.getRepository(ProductHistory).save(history);

// reset last action
Expand Down

0 comments on commit a103f72

Please sign in to comment.