Compare commits

...

12 Commits

Author SHA1 Message Date
Aswin Ashar Abdullah e401a1bf4c fix(SPG-742) Filter status, sumber, tipe pembayaran, pembayaran via, bank, tgl konfirmasi belum jalan 2024-08-02 15:16:43 +07:00
Aswin Ashar Abdullah 1636f6b930 fix(SPG-743) Refund dengan code invoice yang sama terkena validasi 2024-08-02 14:38:36 +07:00
Firman Ramdhani d14d9101ae feat: add report CashierLogReport and CashWithdrawalsReport
continuous-integration/drone/tag Build is passing Details
2024-08-01 18:09:40 +07:00
Firman Ramdhani 746e24feb6 feat: add migration for table pos log
continuous-integration/drone/tag Build is passing Details
2024-08-01 17:48:21 +07:00
Firman Ramdhani 39d7eb28b9 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2024-08-01 17:45:55 +07:00
Firman Ramdhani 9d0d76120e feat: update model pos log 2024-08-01 17:45:33 +07:00
aswin 971407612c Merge pull request 'fix/data' (#47) from fix/data into development
Reviewed-on: #47
2024-08-01 10:37:35 +00:00
Firman Ramdhani 1e9cc9da4f feat: add default condition for type on booking report 2024-08-01 15:13:00 +07:00
Firman Ramdhani 46307774e1 Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development 2024-08-01 14:43:43 +07:00
Firman Ramdhani 62eccf29a5 feat: rename header title report 2024-08-01 14:43:37 +07:00
aswin 33f955c209 Merge pull request 'fix/data' (#46) from fix/data into development
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #46
2024-08-01 07:01:41 +00:00
aswin 77d8e7ae1e Merge pull request 'fix/data' (#45) from fix/data into development
continuous-integration/drone/tag Build is passing Details
Reviewed-on: #45
2024-07-31 11:27:39 +00:00
25 changed files with 326 additions and 94 deletions

View File

@ -22,6 +22,7 @@ export interface Param {
data: string[]; data: string[];
additional?: any[]; additional?: any[];
leftJoin?: any[]; leftJoin?: any[];
isStatus?: boolean;
} }
export interface RelationParam { export interface RelationParam {

View File

@ -52,11 +52,15 @@ export abstract class BaseIndexManager<Entity> extends BaseReadManager {
// ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut // ? karena jika tidak, ketika dia search "active" maka "inactive" juga ikut
return `'${STATUS[statusData.toUpperCase()]}'` ?? `'%${statusData}%'`; return `'${STATUS[statusData.toUpperCase()]}'` ?? `'%${statusData}%'`;
}); });
const exist = specificFilter.find((item) => item.isStatus);
if (!exist) {
specificFilter.push({ specificFilter.push({
cols: `${this.tableName}.status::text`, cols: `${this.tableName}.status::text`,
data: data, data: data,
}); });
} }
}
new SpecificSearchFilter<Entity>( new SpecificSearchFilter<Entity>(
this.queryBuilder, this.queryBuilder,

View File

@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class PosLogAddColumnDownBy1722509262047 implements MigrationInterface {
name = 'PosLogAddColumnDownBy1722509262047';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "logs_pos" ADD "drawn_by_name" character varying`,
);
await queryRunner.query(
`ALTER TABLE "logs_pos" ADD "drawn_by_id" character varying`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "logs_pos" DROP COLUMN "drawn_by_id"`);
await queryRunner.query(
`ALTER TABLE "logs_pos" DROP COLUMN "drawn_by_name"`,
);
}
}

View File

@ -0,0 +1,49 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class UpdateRelationTableTransaction1722581313837
implements MigrationInterface
{
name = 'UpdateRelationTableTransaction1722581313837';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "refunds" DROP CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4"`,
);
await queryRunner.query(
`ALTER TABLE "refunds" DROP CONSTRAINT "REL_8bb3b7579f49990d2e77684acd"`,
);
await queryRunner.query(
`ALTER TABLE "refund_items" DROP CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3"`,
);
await queryRunner.query(
`ALTER TABLE "refund_items" DROP CONSTRAINT "REL_07b481a163c219f5de8fb1c90b"`,
);
await queryRunner.query(
`ALTER TABLE "refunds" ADD CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "refund_items" ADD CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3" FOREIGN KEY ("transaction_item_id") REFERENCES "transaction_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "refund_items" DROP CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3"`,
);
await queryRunner.query(
`ALTER TABLE "refunds" DROP CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4"`,
);
await queryRunner.query(
`ALTER TABLE "refund_items" ADD CONSTRAINT "REL_07b481a163c219f5de8fb1c90b" UNIQUE ("transaction_item_id")`,
);
await queryRunner.query(
`ALTER TABLE "refund_items" ADD CONSTRAINT "FK_07b481a163c219f5de8fb1c90b3" FOREIGN KEY ("transaction_item_id") REFERENCES "transaction_items"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
await queryRunner.query(
`ALTER TABLE "refunds" ADD CONSTRAINT "REL_8bb3b7579f49990d2e77684acd" UNIQUE ("transaction_id")`,
);
await queryRunner.query(
`ALTER TABLE "refunds" ADD CONSTRAINT "FK_8bb3b7579f49990d2e77684acd4" FOREIGN KEY ("transaction_id") REFERENCES "transactions"("id") ON DELETE CASCADE ON UPDATE CASCADE`,
);
}
}

View File

@ -25,4 +25,10 @@ export class PosLogModel
@Column('varchar', { name: 'creator_id', nullable: true }) @Column('varchar', { name: 'creator_id', nullable: true })
creator_id: string; creator_id: string;
@Column('varchar', { name: 'drawn_by_name', nullable: true })
drawn_by_name: string;
@Column('varchar', { name: 'drawn_by_id', nullable: true })
drawn_by_id: string;
} }

View File

@ -27,7 +27,9 @@ export class RecordPosLogHandler implements IEventHandler<ChangeDocEvent> {
total_balance: data.withdrawal_cash ?? data.opening_cash_balance, total_balance: data.withdrawal_cash ?? data.opening_cash_balance,
pos_number: data.pos_number, pos_number: data.pos_number,
creator_id: data.pos_admin?.id, creator_id: data.pos_admin?.id,
creator_name: data.pos_admin?.name, creator_name: data.pos_admin?.name ?? data.pos_admin?.username,
drawn_by_id: data.withdraw_user?.id,
drawn_by_name: data.withdraw_user?.name ?? data.withdraw_user?.username,
created_at: data.created_at, created_at: data.created_at,
}); });

View File

@ -16,6 +16,13 @@ export default <ReportConfigEntity>{
table_schema: `transactions AS main table_schema: `transactions AS main
LEFT JOIN refunds refund ON refund.transaction_id = main.id`, LEFT JOIN refunds refund ON refund.transaction_id = main.id`,
main_table_alias: 'main', main_table_alias: 'main',
whereDefaultConditions: [
{
column: 'main.type',
filter_type: FILTER_TYPE.TEXT_IN_MEMBER,
values: [TransactionType.ADMIN, TransactionType.ONLINE],
},
],
defaultOrderBy: [], defaultOrderBy: [],
lowLevelOrderBy: [], lowLevelOrderBy: [],
filter_period_config: { filter_period_config: {
@ -41,7 +48,7 @@ export default <ReportConfigEntity>{
{ {
column: 'main__no_of_group', column: 'main__no_of_group',
query: 'main.no_of_group', query: 'main.no_of_group',
label: 'Total Group', label: '#Visitor',
type: DATA_TYPE.DIMENSION, type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.NUMBER, format: DATA_FORMAT.NUMBER,
}, },

View File

@ -1,40 +1,87 @@
import { DATA_FORMAT, DATA_TYPE, REPORT_GROUP } from '../../../constant'; import { PosLogType } from 'src/modules/configuration/log/domain/entities/pos-log.entity';
import {
DATA_FORMAT,
DATA_TYPE,
FILTER_FIELD_TYPE,
FILTER_TYPE,
REPORT_GROUP,
} from '../../../constant';
import { ReportConfigEntity } from '../../../entities/report-config.entity'; import { ReportConfigEntity } from '../../../entities/report-config.entity';
export default <ReportConfigEntity>{ export default <ReportConfigEntity>{
group_name: REPORT_GROUP.transaction_report, group_name: REPORT_GROUP.transaction_report,
unique_name: `${REPORT_GROUP.transaction_report}__cash_withdrawals`, unique_name: `${REPORT_GROUP.transaction_report}__cash_withdrawals`,
label: 'Penarikan Kas', label: 'Penarikan Kas',
table_schema: 'season_types main', table_schema: 'logs_pos main',
main_table_alias: 'main', main_table_alias: 'main',
defaultOrderBy: [], defaultOrderBy: [],
lowLevelOrderBy: [], lowLevelOrderBy: [],
filter_period_config: { filter_period_config: {
hidden: true, hidden: true,
}, },
whereDefaultConditions: [
{
column: 'main.type',
filter_type: FILTER_TYPE.TEXT_IN_MEMBER,
values: [PosLogType.cash_witdrawal],
},
],
column_configs: [ column_configs: [
{ {
column: 'main__created_at', column: 'main__date',
query: 'main.created_at', query: `TO_CHAR(to_timestamp(main.created_at::double precision / 1000), 'DD-MM-YYYY')`,
label: 'Created Date', label: 'Tanggal',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.DATE_EPOCH,
},
{
column: 'main__updated_at',
query: 'main.updated_at',
label: 'Updated Date',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.DATE_EPOCH,
},
{
column: 'main__name',
query: 'main.name',
label: 'Name',
type: DATA_TYPE.DIMENSION, type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT, format: DATA_FORMAT.TEXT,
}, },
{
column: 'main__time',
query: `TO_CHAR(to_timestamp(main.created_at::double precision / 1000), 'HH24:MI')`,
label: 'Jam',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__drawn_by_name',
query: 'main.drawn_by_name',
label: 'Nama Penarik',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__creator_name',
query: 'main.creator_name',
label: 'Nama Kasir',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__pos_number',
query: 'main.pos_number',
label: 'No. PoS',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__total_balance',
query: 'main.total_balance',
label: 'Total Penarikan',
type: DATA_TYPE.MEASURE,
format: DATA_FORMAT.CURRENCY,
},
],
filter_configs: [
{
filed_label: 'Nama Penarik',
filter_column: 'main__drawn_by_name',
field_type: FILTER_FIELD_TYPE.input_tag,
filter_type: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
},
{
filed_label: 'Nama Kasir',
filter_column: 'main__creator_name',
field_type: FILTER_FIELD_TYPE.input_tag,
filter_type: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
},
], ],
filter_configs: [],
}; };

View File

@ -1,40 +1,81 @@
import { DATA_FORMAT, DATA_TYPE, REPORT_GROUP } from '../../../constant'; import { PosLogType } from 'src/modules/configuration/log/domain/entities/pos-log.entity';
import {
DATA_FORMAT,
DATA_TYPE,
FILTER_FIELD_TYPE,
FILTER_TYPE,
REPORT_GROUP,
} from '../../../constant';
import { ReportConfigEntity } from '../../../entities/report-config.entity'; import { ReportConfigEntity } from '../../../entities/report-config.entity';
export default <ReportConfigEntity>{ export default <ReportConfigEntity>{
group_name: REPORT_GROUP.transaction_report, group_name: REPORT_GROUP.transaction_report,
unique_name: `${REPORT_GROUP.transaction_report}__cashier_log`, unique_name: `${REPORT_GROUP.transaction_report}__cashier_log`,
label: 'Kasir Log', label: 'Kasir Log',
table_schema: 'season_types main', table_schema: 'logs_pos main',
main_table_alias: 'main', main_table_alias: 'main',
defaultOrderBy: [], defaultOrderBy: [],
lowLevelOrderBy: [], lowLevelOrderBy: [],
filter_period_config: { filter_period_config: {
hidden: true, hidden: true,
}, },
whereDefaultConditions: [
{
column: 'main.type',
filter_type: FILTER_TYPE.TEXT_IN_MEMBER,
values: [PosLogType.login, PosLogType.logout],
},
],
column_configs: [ column_configs: [
{ {
column: 'main__created_at', column: 'main__date',
query: 'main.created_at', query: `TO_CHAR(to_timestamp(main.created_at::double precision / 1000), 'DD-MM-YYYY')`,
label: 'Created Date', label: 'Tanggal',
type: DATA_TYPE.DIMENSION, type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.DATE_EPOCH, format: DATA_FORMAT.TEXT,
}, },
{ {
column: 'main__updated_at', column: 'main__time',
query: 'main.updated_at', query: `TO_CHAR(to_timestamp(main.created_at::double precision / 1000), 'HH24:MI')`,
label: 'Updated Date', label: 'Jam',
type: DATA_TYPE.DIMENSION, type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.DATE_EPOCH, format: DATA_FORMAT.TEXT,
}, },
{ {
column: 'main__name', column: 'main__type',
query: 'main.name', query: 'main.type',
label: 'Name', label: 'Tipe',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__creator_name',
query: 'main.creator_name',
label: 'Nama Staff',
type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT,
},
{
column: 'main__pos_number',
query: 'main.pos_number',
label: 'No. PoS',
type: DATA_TYPE.DIMENSION, type: DATA_TYPE.DIMENSION,
format: DATA_FORMAT.TEXT, format: DATA_FORMAT.TEXT,
}, },
], ],
filter_configs: [], filter_configs: [
{
filed_label: 'Tipe',
filter_column: 'main__type',
field_type: FILTER_FIELD_TYPE.select,
filter_type: FILTER_TYPE.TEXT_IN_MEMBER,
select_custom_options: [PosLogType.login, PosLogType.logout],
},
{
filed_label: 'Nama Staff',
filter_column: 'main__creator_name',
field_type: FILTER_FIELD_TYPE.input_tag,
filter_type: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
},
],
}; };

View File

@ -18,6 +18,6 @@ export const TransactionReportConfig: ReportConfigEntity[] = [
// TimePerRideReport, // TimePerRideReport,
BookingReport, BookingReport,
RefundsReport, RefundsReport,
// CashierLogReport, CashierLogReport,
// CashWithdrawalsReport, CashWithdrawalsReport,
]; ];

View File

@ -37,11 +37,11 @@ export interface ReportConfigEntity {
table_schema: string; table_schema: string;
main_table_alias?: string; main_table_alias?: string;
customVirtualTableSchema?( // customVirtualTableSchema?(
filterModel: any, // filterModel: any,
findQueryConfig: (column: string) => string, // findQueryConfig: (column: string) => string,
createFilterSql: (key: string, item: any) => string, // createFilterSql: (key: string, item: any) => string,
): string; // ): string;
whereCondition?(filterModel: any): string[]; whereCondition?(filterModel: any): string[];
whereDefaultConditions?: { whereDefaultConditions?: {
column: string; column: string;

View File

@ -65,6 +65,11 @@ export class IndexReconciliationManager extends BaseIndexManager<TransactionEnti
get specificFilter(): Param[] { get specificFilter(): Param[] {
return [ return [
{
cols: `${this.tableName}.reconciliation_status::text`,
data: this.filterParam.statuses,
isStatus: true,
},
{ {
cols: `${this.tableName}.customer_name`, cols: `${this.tableName}.customer_name`,
data: this.filterParam.customer_names, data: this.filterParam.customer_names,
@ -115,36 +120,46 @@ export class IndexReconciliationManager extends BaseIndexManager<TransactionEnti
if (this.filterParam.payment_type) { if (this.filterParam.payment_type) {
queryBuilder.andWhere( queryBuilder.andWhere(
`${this.tableName}.creator_counter_no In (:...counters)`, `${this.tableName}.payment_type::text In (:...paymentType)`,
{ {
counters: [this.filterParam.couner_no], paymentType: [this.filterParam.payment_type],
}, },
); );
} }
if (this.filterParam.payment_via) { if (this.filterParam.payment_via) {
queryBuilder.andWhere(`${this.tableName}.payment_type In (:...type)`, { queryBuilder.andWhere(
type: [this.filterParam.payment_via], `${this.tableName}.payment_type::text In (:...type)`,
}); {
type: [`%${this.filterParam.payment_via}%`],
},
);
} }
if (this.filterParam.payment_bank) { if (this.filterParam.payment_bank) {
queryBuilder.andWhere( queryBuilder.andWhere(
`${this.tableName}.payment_type_method_name In (:...banks)`, `${this.tableName}.payment_type_method_name::text In (:...banks)`,
{ {
banks: [this.filterParam.payment_bank], banks: [`%${this.filterParam.payment_bank}%`],
}, },
); );
} }
if (this.filterParam.confirmation_date_from) { if (this.filterParam.confirmation_date_from) {
const confirmationDateFrom = new Date(
this.filterParam?.confirmation_date_from,
).getTime();
const confirmationDateTo = new Date(
`${this.filterParam?.confirmation_date_to?.split(' ')[0]} 23:59:59`,
).getTime();
new BetweenQueryHelper( new BetweenQueryHelper(
queryBuilder, queryBuilder,
this.tableName, this.tableName,
'payment_date', 'reconciliation_confirm_date',
this.filterParam.confirmation_date_from, confirmationDateFrom,
this.filterParam.confirmation_date_to, confirmationDateTo,
'payment_created', 'reconciliation_confirm_dated',
).getQuery(); ).getQuery();
} }

View File

@ -86,8 +86,6 @@ export class RecapReconciliationManager extends BaseCustomManager<TransactionEnt
where: query, where: query,
}); });
if (payment_type == 'cash') console.log(exist, 'das', query);
const new_recap = new TransactionModel(); const new_recap = new TransactionModel();
const total = _.sumBy(this.recapTransactions[recap], (recap) => const total = _.sumBy(this.recapTransactions[recap], (recap) =>
parseFloat(recap.payment_total), parseFloat(recap.payment_total),

View File

@ -29,7 +29,7 @@ export class RefundItemModel
// transaction to transaction item // transaction to transaction item
@Column('varchar', { name: 'transaction_item_id', nullable: true }) @Column('varchar', { name: 'transaction_item_id', nullable: true })
transaction_item_id: string; transaction_item_id: string;
@OneToOne(() => TransactionItemModel, (model) => model.refund, { @ManyToOne(() => TransactionItemModel, (model) => model.refunds, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
onUpdate: 'CASCADE', onUpdate: 'CASCADE',
}) })

View File

@ -1,6 +1,6 @@
import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { RefundEntity } from '../../domain/entities/refund.entity'; import { RefundEntity } from '../../domain/entities/refund.entity';
import { Column, Entity, JoinColumn, OneToMany, OneToOne } from 'typeorm'; import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model'; import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model';
import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model'; import { TransactionModel } from 'src/modules/transaction/transaction/data/models/transaction.model';
import { RefundItemModel } from './refund-item.model'; import { RefundItemModel } from './refund-item.model';
@ -64,7 +64,7 @@ export class RefundModel
// relation to transaction // relation to transaction
@Column('varchar', { name: 'transaction_id', nullable: true }) @Column('varchar', { name: 'transaction_id', nullable: true })
transaction_id: string; transaction_id: string;
@OneToOne(() => TransactionModel, (model) => model.refund, { @ManyToOne(() => TransactionModel, (model) => model.refunds, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
onUpdate: 'CASCADE', onUpdate: 'CASCADE',
}) })

View File

@ -38,7 +38,6 @@ export class BatchConfirmRefundManager extends BaseBatchUpdateStatusManager<Refu
if (this.data.status == STATUS.DRAFT) { if (this.data.status == STATUS.DRAFT) {
Object.assign(this.data, { Object.assign(this.data, {
code: `RF-${data?.['transaction']?.invoice_code.split('-')[1]}`,
request_date: new Date(), request_date: new Date(),
status: STATUS.PENDING, status: STATUS.PENDING,
}); });

View File

@ -53,7 +53,6 @@ export class ConfirmRefundManager extends BaseUpdateStatusManager<RefundEntity>
if (data.status == STATUS.DRAFT) { if (data.status == STATUS.DRAFT) {
Object.assign(this.data, { Object.assign(this.data, {
code: `RF-${data.transaction?.invoice_code?.split('-')[1]}`,
request_date: new Date(), request_date: new Date(),
status: STATUS.PENDING, status: STATUS.PENDING,
}); });

View File

@ -13,6 +13,8 @@ import { RefundModel } from '../../../data/models/refund.model';
import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager'; import { BaseCreateManager } from 'src/core/modules/domain/usecase/managers/base-create.manager';
import { RefundCreatedEvent } from '../../entities/event/refund-created.event'; import { RefundCreatedEvent } from '../../entities/event/refund-created.event';
import { STATUS } from 'src/core/strings/constants/base.constants'; import { STATUS } from 'src/core/strings/constants/base.constants';
import { In, Not } from 'typeorm';
import { generateInvoiceCodeHelper } from 'src/modules/transaction/transaction/domain/usecases/managers/helpers/generate-invoice-code.helper';
@Injectable() @Injectable()
export class CreateRefundManager extends BaseCreateManager<RefundEntity> { export class CreateRefundManager extends BaseCreateManager<RefundEntity> {
@ -26,13 +28,10 @@ export class CreateRefundManager extends BaseCreateManager<RefundEntity> {
}; };
}); });
Object.assign(this.data, {
refund_items: refund_items,
});
const exist = await this.dataService.getOneByOptions({ const exist = await this.dataService.getOneByOptions({
where: { where: {
transaction_id: this.data.transaction.id, transaction_id: this.data.transaction.id,
status: Not(In([STATUS.CANCEL])),
}, },
}); });
if (exist) { if (exist) {
@ -57,6 +56,11 @@ export class CreateRefundManager extends BaseCreateManager<RefundEntity> {
error: 'Unprocessable Entity', error: 'Unprocessable Entity',
}); });
} }
Object.assign(this.data, {
refund_items: refund_items,
code: await generateInvoiceCodeHelper(this.dataService, 'RF'),
});
return; return;
} }

View File

@ -15,7 +15,7 @@ export class DetailRefundManager extends BaseDetailManager<RefundEntity> {
} }
async afterProcess(): Promise<void> { async afterProcess(): Promise<void> {
mappingTransaction(this.result['transaction']); mappingTransaction(this.result['transaction'], this.dataId);
return; return;
} }
@ -25,7 +25,12 @@ export class DetailRefundManager extends BaseDetailManager<RefundEntity> {
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['transaction', 'transaction.items', 'items.refund'], selectRelations: [
'transaction',
'transaction.items',
'items.refunds item_refunds',
'item_refunds.refund item_refunds_refund',
],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
@ -55,7 +60,9 @@ export class DetailRefundManager extends BaseDetailManager<RefundEntity> {
'transaction', 'transaction',
'items', 'items',
'refund', 'item_refunds',
'item_refunds_refund.id',
'item_refunds_refund.status',
]; ];
} }

View File

@ -1,5 +1,5 @@
import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from 'typeorm'; import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from 'typeorm';
import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model'; import { BaseCoreModel } from 'src/core/modules/data/model/base-core.model';
import { TransactionItemEntity } from '../../domain/entities/transaction-item.entity'; import { TransactionItemEntity } from '../../domain/entities/transaction-item.entity';
import { TransactionModel } from './transaction.model'; import { TransactionModel } from './transaction.model';
@ -80,10 +80,10 @@ export class TransactionItemModel
transaction: TransactionModel; transaction: TransactionModel;
// relations to refund // relations to refund
@OneToOne(() => RefundItemModel, (model) => model.transaction_item, { @OneToMany(() => RefundItemModel, (model) => model.transaction_item, {
cascade: true, cascade: true,
onDelete: 'CASCADE', onDelete: 'CASCADE',
onUpdate: 'CASCADE', onUpdate: 'CASCADE',
}) })
refund: RefundItemModel; refunds: RefundItemModel[];
} }

View File

@ -1,6 +1,6 @@
import { TABLE_NAME } from 'src/core/strings/constants/table.constants'; import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { TransactionEntity } from '../../domain/entities/transaction.entity'; import { TransactionEntity } from '../../domain/entities/transaction.entity';
import { Column, Entity, OneToMany, OneToOne } from 'typeorm'; import { Column, Entity, OneToMany } from 'typeorm';
import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model'; import { BaseStatusModel } from 'src/core/modules/data/model/base-status.model';
import { import {
TransactionType, TransactionType,
@ -233,10 +233,10 @@ export class TransactionModel
taxes: TransactionTaxModel[]; taxes: TransactionTaxModel[];
// relations to refund // relations to refund
@OneToOne(() => RefundModel, (model) => model.transaction, { @OneToMany(() => RefundModel, (model) => model.transaction, {
cascade: true, cascade: true,
onDelete: 'CASCADE', onDelete: 'CASCADE',
onUpdate: 'CASCADE', onUpdate: 'CASCADE',
}) })
refund: RefundModel; refunds: RefundModel[];
} }

View File

@ -25,7 +25,12 @@ export class DetailTransactionManager extends BaseDetailManager<TransactionEntit
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['items', 'items.refund item_refund', 'refund'], selectRelations: [
'items',
'items.refunds item_refunds',
'item_refunds.refund item_refunds_refund',
'refunds',
],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
@ -76,8 +81,11 @@ export class DetailTransactionManager extends BaseDetailManager<TransactionEntit
`${this.tableName}.payment_total`, `${this.tableName}.payment_total`,
'items', 'items',
'item_refund', 'item_refunds',
'refund', 'item_refunds_refund.id',
'item_refunds_refund.status',
'refunds',
]; ];
} }

View File

@ -12,6 +12,12 @@ export async function generateInvoiceCodeHelper(dataService, code) {
invoice_code: ILike(`%${month_year}%`), invoice_code: ILike(`%${month_year}%`),
}; };
if (code == 'RF') {
query = {
code: ILike(`%${month_year}%`),
};
}
if (code == 'PYM') { if (code == 'PYM') {
query = { query = {
payment_code: ILike(`%${month_year}%`), payment_code: ILike(`%${month_year}%`),

View File

@ -4,7 +4,7 @@ import {
TransactionType, TransactionType,
} from 'src/modules/transaction/transaction/constants'; } from 'src/modules/transaction/transaction/constants';
export function mappingTransaction(data) { export function mappingTransaction(data, refundId?: string) {
let payment_type_bank: any = null; let payment_type_bank: any = null;
const season_period = { const season_period = {
id: data.season_period_id, id: data.season_period_id,
@ -26,6 +26,9 @@ export function mappingTransaction(data) {
const items = data?.['items']?.map((itemData) => { const items = data?.['items']?.map((itemData) => {
let tenant; let tenant;
let refund = itemData.refunds?.find(
(item) => ![STATUS.CANCEL].includes(item.refund.status),
);
if (itemData.item_tenant_id) { if (itemData.item_tenant_id) {
tenant = { tenant = {
@ -35,6 +38,9 @@ export function mappingTransaction(data) {
}; };
} }
if (refundId)
refund = itemData.refunds?.find((item) => item.refund.id == refundId);
return { return {
item: { item: {
id: itemData.item_id, id: itemData.item_id,
@ -49,20 +55,27 @@ export function mappingTransaction(data) {
}, },
}, },
id: itemData.id, id: itemData.id,
refund: itemData.refund, refund: refund,
qty: itemData.qty, qty: itemData.qty,
qty_remaining: itemData.qty_remaining, qty_remaining: itemData.qty_remaining,
total_price_refund: itemData.refund?.refund_total ?? 0, total_price_refund: refund?.refund_total ?? 0,
total_price: itemData.total_price, total_price: itemData.total_price,
}; };
}); });
const refund = data.refunds?.find(
(refund) => ![STATUS.CANCEL].includes(refund.status),
);
Object.assign(data, { Object.assign(data, {
season_period: season_period, season_period: season_period,
items: items, items: items,
payment_type_bank: payment_type_bank, payment_type_bank: payment_type_bank,
refund: refund,
}); });
delete data.refunds;
delete data.season_period_id; delete data.season_period_id;
delete data.season_period_name; delete data.season_period_name;
delete data.season_period_type_id; delete data.season_period_type_id;

View File

@ -7,6 +7,7 @@ import {
RelationParam, RelationParam,
} from 'src/core/modules/domain/entities/base-filter.entity'; } from 'src/core/modules/domain/entities/base-filter.entity';
import { BetweenQueryHelper } from 'src/core/helpers/query/between-query.helper'; import { BetweenQueryHelper } from 'src/core/helpers/query/between-query.helper';
import { STATUS } from 'src/core/strings/constants/base.constants';
@Injectable() @Injectable()
export class IndexTransactionManager extends BaseIndexManager<TransactionEntity> { export class IndexTransactionManager extends BaseIndexManager<TransactionEntity> {
@ -20,12 +21,16 @@ export class IndexTransactionManager extends BaseIndexManager<TransactionEntity>
async afterProcess(): Promise<void> { async afterProcess(): Promise<void> {
this.result?.data?.map((item) => { this.result?.data?.map((item) => {
const activeRefund = item['refunds'].find(
(refund) => ![STATUS.CANCEL].includes(refund.status),
);
Object.assign(item, { Object.assign(item, {
refund_code: item['refund']?.code ?? null, refund_code: activeRefund?.code ?? null,
refund_date: item['refund']?.refund_date ?? null, refund_date: activeRefund?.refund_date ?? null,
}); });
delete item['refund']; delete item['refunds'];
}); });
return; return;
} }
@ -36,7 +41,7 @@ export class IndexTransactionManager extends BaseIndexManager<TransactionEntity>
joinRelations: [], joinRelations: [],
// relation join and select (relasi yang ingin ditampilkan), // relation join and select (relasi yang ingin ditampilkan),
selectRelations: ['items', 'refund'], selectRelations: ['items', 'refunds'],
// relation yang hanya ingin dihitung (akan return number) // relation yang hanya ingin dihitung (akan return number)
countRelations: [], countRelations: [],
@ -76,10 +81,10 @@ export class IndexTransactionManager extends BaseIndexManager<TransactionEntity>
`${this.tableName}.payment_type_method_name`, `${this.tableName}.payment_type_method_name`,
`${this.tableName}.payment_type_method_number`, `${this.tableName}.payment_type_method_number`,
`refund.id`, `refunds.id`,
`refund.code`, `refunds.code`,
`refund.refund_date`, `refunds.refund_date`,
`refund.request_date`, `refunds.request_date`,
]; ];
} }