diff --git a/sep490-enterprise/src/main/java/enterprise/dtos/CreditPackageDTO.java b/sep490-enterprise/src/main/java/enterprise/dtos/CreditPackageDTO.java new file mode 100644 index 00000000..db43e7f6 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/dtos/CreditPackageDTO.java @@ -0,0 +1,6 @@ +package enterprise.dtos; + +import java.util.UUID; + +public record CreditPackageDTO(UUID id, int version, int numberOfCredits, long price) { +} diff --git a/sep490-enterprise/src/main/java/enterprise/entities/BundleEntity.java b/sep490-enterprise/src/main/java/enterprise/entities/BundleEntity.java deleted file mode 100644 index d787bd52..00000000 --- a/sep490-enterprise/src/main/java/enterprise/entities/BundleEntity.java +++ /dev/null @@ -1,17 +0,0 @@ -package enterprise.entities; - - -import commons.springfw.impl.entities.AbstractAuditableEntity; -import jakarta.persistence.Entity; -import jakarta.persistence.Table; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Entity -@Table(name = "bundles") -@Getter -@Setter -@NoArgsConstructor -public class BundleEntity extends AbstractAuditableEntity { -} diff --git a/sep490-enterprise/src/main/java/enterprise/entities/CreditPackageEntity.java b/sep490-enterprise/src/main/java/enterprise/entities/CreditPackageEntity.java new file mode 100644 index 00000000..9a082667 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/entities/CreditPackageEntity.java @@ -0,0 +1,30 @@ +package enterprise.entities; + +import commons.springfw.impl.entities.AbstractAuditableEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Table(name = "credit_packages") +@Getter +@Setter +@NoArgsConstructor +public class CreditPackageEntity extends AbstractAuditableEntity { + + @Column(name = "number_of_credits", nullable = false) + @Min(0) + @NotNull + private int numberOfCredits = 0; + + @Column(name = "price", nullable = false) + @Min(0) + @NotNull + private long price = 0; + +} diff --git a/sep490-enterprise/src/main/java/enterprise/entities/PaymentEntity.java b/sep490-enterprise/src/main/java/enterprise/entities/PaymentEntity.java index 706d451d..25c26032 100644 --- a/sep490-enterprise/src/main/java/enterprise/entities/PaymentEntity.java +++ b/sep490-enterprise/src/main/java/enterprise/entities/PaymentEntity.java @@ -27,11 +27,6 @@ public class PaymentEntity extends AbstractAuditableEntity { @JoinColumn(name = "enterprise_id", nullable = false) private EnterpriseEntity enterprise; - @NotNull - @ManyToOne(fetch = FetchType.LAZY, optional = false) - @JoinColumn(name = "bundle_id", nullable = false) - private BundleEntity bundle; - @NotNull @Enumerated(EnumType.STRING) @Column(name = "status") diff --git a/sep490-enterprise/src/main/java/enterprise/mappers/CreditPackageMapper.java b/sep490-enterprise/src/main/java/enterprise/mappers/CreditPackageMapper.java new file mode 100644 index 00000000..3a930107 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/mappers/CreditPackageMapper.java @@ -0,0 +1,13 @@ +package enterprise.mappers; + +import enterprise.dtos.CreditPackageDTO; +import enterprise.entities.CreditPackageEntity; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public interface CreditPackageMapper { + + CreditPackageDTO entityToDTO(CreditPackageEntity creditPackageEntity); + +} diff --git a/sep490-enterprise/src/main/java/enterprise/repositories/BundleRepository.java b/sep490-enterprise/src/main/java/enterprise/repositories/BundleRepository.java deleted file mode 100644 index 7f79d019..00000000 --- a/sep490-enterprise/src/main/java/enterprise/repositories/BundleRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package enterprise.repositories; - -import commons.springfw.impl.repositories.AbstractBaseRepository; -import enterprise.entities.BundleEntity; - -public interface BundleRepository extends AbstractBaseRepository { -} diff --git a/sep490-enterprise/src/main/java/enterprise/repositories/CreditPackageRepository.java b/sep490-enterprise/src/main/java/enterprise/repositories/CreditPackageRepository.java new file mode 100644 index 00000000..72e47758 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/repositories/CreditPackageRepository.java @@ -0,0 +1,7 @@ +package enterprise.repositories; + +import commons.springfw.impl.repositories.AbstractBaseRepository; +import enterprise.entities.CreditPackageEntity; + +public interface CreditPackageRepository extends AbstractBaseRepository { +} diff --git a/sep490-enterprise/src/main/java/enterprise/rest/CreditPackageController.java b/sep490-enterprise/src/main/java/enterprise/rest/CreditPackageController.java new file mode 100644 index 00000000..6a4e3f6c --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/rest/CreditPackageController.java @@ -0,0 +1,32 @@ +package enterprise.rest; + +import enterprise.dtos.CreditPackageDTO; +import enterprise.mappers.CreditPackageMapper; +import enterprise.services.CreditPackageService; +import green_buildings.commons.api.security.UserRole; +import jakarta.annotation.security.RolesAllowed; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/credit-package") +@RequiredArgsConstructor +public class CreditPackageController { + + private final CreditPackageService creditPackageService; + private final CreditPackageMapper mapper; + + @GetMapping + @RolesAllowed({UserRole.RoleNameConstant.SYSTEM_ADMIN, UserRole.RoleNameConstant.ENTERPRISE_OWNER}) + public List findAll() { + return creditPackageService.findAll() + .stream() + .map(mapper::entityToDTO) + .toList(); + } + +} diff --git a/sep490-enterprise/src/main/java/enterprise/services/CreditPackageService.java b/sep490-enterprise/src/main/java/enterprise/services/CreditPackageService.java new file mode 100644 index 00000000..35ab2777 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/services/CreditPackageService.java @@ -0,0 +1,9 @@ +package enterprise.services; + +import enterprise.entities.CreditPackageEntity; + +import java.util.List; + +public interface CreditPackageService { + List findAll(); +} diff --git a/sep490-enterprise/src/main/java/enterprise/services/CreditPackageServiceImpl.java b/sep490-enterprise/src/main/java/enterprise/services/CreditPackageServiceImpl.java new file mode 100644 index 00000000..8262e771 --- /dev/null +++ b/sep490-enterprise/src/main/java/enterprise/services/CreditPackageServiceImpl.java @@ -0,0 +1,22 @@ +package enterprise.services; + +import enterprise.entities.CreditPackageEntity; +import enterprise.repositories.CreditPackageRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(rollbackOn = Throwable.class) +public class CreditPackageServiceImpl implements CreditPackageService { + + private final CreditPackageRepository creditPackageRepository; + + @Override + public List findAll() { + return creditPackageRepository.findAll(); + } +} diff --git a/sep490-enterprise/src/main/resources/application.yml b/sep490-enterprise/src/main/resources/application.yml index f86c8af7..3bc49312 100644 --- a/sep490-enterprise/src/main/resources/application.yml +++ b/sep490-enterprise/src/main/resources/application.yml @@ -10,6 +10,7 @@ spring: issuer-uri: ${ISSUER_URI} application: name: enterprise + homepage: http://localhost:4200 datasource: url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}?serverTimezone=UTC username: ${POSTGRES_USER} diff --git a/sep490-enterprise/src/main/resources/db/migration/V0.0.1.6__CreditPackage.sql b/sep490-enterprise/src/main/resources/db/migration/V0.0.1.6__CreditPackage.sql new file mode 100644 index 00000000..526d40b4 --- /dev/null +++ b/sep490-enterprise/src/main/resources/db/migration/V0.0.1.6__CreditPackage.sql @@ -0,0 +1,7 @@ +ALTER TABLE payments DROP CONSTRAINT payments_fk_bundles; +ALTER TABLE payments DROP COLUMN bundle_id; +ALTER TABLE bundles RENAME TO credit_packages; + +ALTER TABLE credit_packages + ADD COLUMN number_of_credits INT NOT NULL DEFAULT 0, + ADD COLUMN price BIGINT NOT NULL DEFAULT 0; diff --git a/sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts b/sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts index 60f90685..f726dc58 100644 --- a/sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts +++ b/sep490-frontend/src/app/modules/enterprise/components/building-details/building-details.component.ts @@ -16,7 +16,7 @@ import {UUID} from '../../../../../types/uuid'; import {AppRoutingConstants} from '../../../../app-routing.constant'; import {BuildingService} from '../../../../services/building.service'; import {AbstractFormComponent} from '../../../shared/components/form/abstract-form-component'; -import {BuildingDetails} from '../../models/building-details.dto'; +import {BuildingDetails} from '../../models/enterprise.dto'; @Component({ selector: 'app-building-detail', diff --git a/sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts b/sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts index af4cdf3b..ef2fb200 100644 --- a/sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts +++ b/sep490-frontend/src/app/modules/enterprise/components/buildings/buildings.component.ts @@ -8,7 +8,7 @@ import {UUID} from '../../../../../types/uuid'; import {AppRoutingConstants} from '../../../../app-routing.constant'; import {BuildingService} from '../../../../services/building.service'; import {SubscriptionAwareComponent} from '../../../core/subscription-aware.component'; -import {Building} from '../../models/building.dto'; +import {Building} from '../../models/enterprise.dto'; import {MarkerService} from '../../services/marker.service'; import {RegionService} from '../../services/region.service'; diff --git a/sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html b/sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html index 81205bca..0552b832 100644 --- a/sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html +++ b/sep490-frontend/src/app/modules/enterprise/components/payment/payment.component.html @@ -22,6 +22,7 @@
- {{ package.credits }} + {{ package.numberOfCredits }} {{ "payment.history.credit.title" | translate }}
@@ -105,7 +105,7 @@ footer class="text-gray-600 text-base font-medium text-center" > - {{ package.price }} + {{ package.price | number: "1.0-0" }} VND
} diff --git a/sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts b/sep490-frontend/src/app/modules/enterprise/components/plan/plan.component.ts similarity index 53% rename from sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts rename to sep490-frontend/src/app/modules/enterprise/components/plan/plan.component.ts index a5042733..d8263c23 100644 --- a/sep490-frontend/src/app/modules/enterprise/components/subscription/subscription.component.ts +++ b/sep490-frontend/src/app/modules/enterprise/components/plan/plan.component.ts @@ -1,18 +1,16 @@ import {Component, OnInit} from '@angular/core'; +import {UUID} from '../../../../../types/uuid'; import {SubscriptionAwareComponent} from '../../../core/subscription-aware.component'; +import {CreditPackage} from '../../models/enterprise.dto'; +import {CreditPackageService} from '../../services/credit-package.service'; import {WalletService} from '../../services/wallet.service'; -interface CreditPackage { - id: number; - credits: number; - price: string; -} @Component({ selector: 'app-subscriptions', - templateUrl: './subscription.component.html', - styleUrl: './subscription.component.css' + templateUrl: './plan.component.html', + styleUrl: './plan.component.css' }) -export class SubscriptionComponent +export class PlanComponent extends SubscriptionAwareComponent implements OnInit { @@ -20,24 +18,23 @@ export class SubscriptionComponent {title: 'purchaseCredit.about', content: 'Content 1', value: '0'}, {title: 'purchaseCredit.termService', content: 'Content 2', value: '1'} ]; - - creditPackages: CreditPackage[] = [ - {id: 1, credits: 100, price: '10.000.000 vnđ'}, - {id: 2, credits: 100, price: '10.000.000 vnđ'}, - {id: 3, credits: 100, price: '10.000.000 vnđ'}, - {id: 4, credits: 100, price: '10.000.000 vnđ'}, - {id: 5, credits: 100, price: '10.000.000 vnđ'} - ]; - - selectedPackageId: number | null = null; + creditPackages: CreditPackage[] = []; + selectedPackageId: UUID | null = null; balance: number = 0; - constructor(private readonly walletService: WalletService) { + + constructor( + private readonly walletService: WalletService, + private readonly creditPackageService: CreditPackageService + ) { super(); } + ngOnInit(): void { this.getBalance(); + this.getCreditPackages(); } - selectPackage(id: number): void { + + selectPackage(id: UUID): void { this.selectedPackageId = id; } @@ -46,6 +43,7 @@ export class SubscriptionComponent // Handle purchase logic } } + getBalance(): void { this.registerSubscription( this.walletService.getWalletBalance().subscribe(result => { @@ -53,4 +51,12 @@ export class SubscriptionComponent }) ); } + + getCreditPackages(): void { + this.registerSubscription( + this.creditPackageService.getAllCreditPackages().subscribe(rs => { + this.creditPackages = rs; + }) + ); + } } diff --git a/sep490-frontend/src/app/modules/enterprise/enterprise-routing.module.ts b/sep490-frontend/src/app/modules/enterprise/enterprise-routing.module.ts index 34420a99..3a433d85 100644 --- a/sep490-frontend/src/app/modules/enterprise/enterprise-routing.module.ts +++ b/sep490-frontend/src/app/modules/enterprise/enterprise-routing.module.ts @@ -4,7 +4,7 @@ import {AppRoutingConstants} from '../../app-routing.constant'; import {BuildingDetailsComponent} from './components/building-details/building-details.component'; import {BuildingsComponent} from './components/buildings/buildings.component'; import {PaymentComponent} from './components/payment/payment.component'; -import {SubscriptionComponent} from './components/subscription/subscription.component'; +import {PlanComponent} from './components/plan/plan.component'; import {EnterpriseComponent} from './enterprise.component'; const routes: Routes = [ @@ -22,7 +22,7 @@ const routes: Routes = [ }, { path: AppRoutingConstants.PLAN_PATH, - component: SubscriptionComponent + component: PlanComponent }, {path: AppRoutingConstants.PAYMENT_PATH, component: PaymentComponent} ] diff --git a/sep490-frontend/src/app/modules/enterprise/enterprise.module.ts b/sep490-frontend/src/app/modules/enterprise/enterprise.module.ts index 2a5c7458..524d226b 100644 --- a/sep490-frontend/src/app/modules/enterprise/enterprise.module.ts +++ b/sep490-frontend/src/app/modules/enterprise/enterprise.module.ts @@ -3,9 +3,10 @@ import {SharedModule} from '../shared/shared.module'; import {BuildingDetailsComponent} from './components/building-details/building-details.component'; import {BuildingsComponent} from './components/buildings/buildings.component'; import {PaymentComponent} from './components/payment/payment.component'; -import {SubscriptionComponent} from './components/subscription/subscription.component'; +import {PlanComponent} from './components/plan/plan.component'; import {EnterpriseRoutingModule} from './enterprise-routing.module'; import {EnterpriseComponent} from './enterprise.component'; +import {CreditPackageService} from './services/credit-package.service'; import {MarkerService} from './services/marker.service'; import {PaymentService} from './services/payment.service'; import {PopupService} from './services/popup.service'; @@ -15,7 +16,7 @@ import {WalletService} from './services/wallet.service'; @NgModule({ declarations: [ EnterpriseComponent, - SubscriptionComponent, + PlanComponent, PaymentComponent, BuildingsComponent, BuildingDetailsComponent @@ -26,7 +27,8 @@ import {WalletService} from './services/wallet.service'; PopupService, RegionService, PaymentService, - WalletService + WalletService, + CreditPackageService ] }) export class EnterpriseModule {} diff --git a/sep490-frontend/src/app/modules/enterprise/models/building-details.dto.ts b/sep490-frontend/src/app/modules/enterprise/models/building-details.dto.ts deleted file mode 100644 index cc5f1999..00000000 --- a/sep490-frontend/src/app/modules/enterprise/models/building-details.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {BaseDTO} from '../../shared/models/models'; - -export interface BuildingDetails extends BaseDTO { - name: string; - numberOfDevices: number; -} diff --git a/sep490-frontend/src/app/modules/enterprise/models/building.dto.ts b/sep490-frontend/src/app/modules/enterprise/models/enterprise.dto.ts similarity index 54% rename from sep490-frontend/src/app/modules/enterprise/models/building.dto.ts rename to sep490-frontend/src/app/modules/enterprise/models/enterprise.dto.ts index 1c973a65..2a1e5a04 100644 --- a/sep490-frontend/src/app/modules/enterprise/models/building.dto.ts +++ b/sep490-frontend/src/app/modules/enterprise/models/enterprise.dto.ts @@ -7,3 +7,13 @@ export interface Building extends BaseDTO { validToInclusive?: Date; activated?: boolean; } + +export interface BuildingDetails { + name: string; + numberOfDevices: number; +} + +export interface CreditPackage extends BaseDTO { + numberOfCredits: number; + price: number; +} diff --git a/sep490-frontend/src/app/modules/enterprise/services/credit-package.service.ts b/sep490-frontend/src/app/modules/enterprise/services/credit-package.service.ts new file mode 100644 index 00000000..98f096ff --- /dev/null +++ b/sep490-frontend/src/app/modules/enterprise/services/credit-package.service.ts @@ -0,0 +1,16 @@ +import {HttpClient} from '@angular/common/http'; +import {Injectable} from '@angular/core'; +import {Observable} from 'rxjs'; +import {AppRoutingConstants} from '../../../app-routing.constant'; +import {CreditPackage} from '../models/enterprise.dto'; + +@Injectable() +export class CreditPackageService { + constructor(private readonly httpClient: HttpClient) {} + + public getAllCreditPackages(): Observable { + return this.httpClient.get( + `${AppRoutingConstants.ENTERPRISE_API_URL}/credit-package` + ); + } +} diff --git a/sep490-frontend/src/app/services/building.service.ts b/sep490-frontend/src/app/services/building.service.ts index a15de222..3fe67e01 100644 --- a/sep490-frontend/src/app/services/building.service.ts +++ b/sep490-frontend/src/app/services/building.service.ts @@ -3,8 +3,10 @@ import {Injectable} from '@angular/core'; import {Observable, map} from 'rxjs'; import {UUID} from '../../types/uuid'; import {AppRoutingConstants} from '../app-routing.constant'; -import {BuildingDetails} from '../modules/enterprise/models/building-details.dto'; -import {Building} from '../modules/enterprise/models/building.dto'; +import { + Building, + BuildingDetails +} from '../modules/enterprise/models/enterprise.dto'; import { SearchCriteriaDto, SearchResultDto