Commit e38f46f9 by Ooh-Ao

stock projectr

parent 0987f285
# myproject/controllers/project_equipment_controller.py
from fastapi import HTTPException from fastapi import HTTPException
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import selectinload
from uuid import UUID from uuid import UUID
from ..models.project_equipment import ProjectEquipment from ..models.project_equipment import ProjectEquipment
from ..models.project import Project from ..models.project import Project
from ..models.equipment import Equipment from ..models.equipment import Equipment
from ..schemas.project_equipment_schema import ( from ..schemas.project_equipment_schema import ProjectEquipmentCreate
ProjectEquipmentCreate
)
# CREATE # CREATE
async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCreate): async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCreate):
# ถ้าต้องการตรวจสอบว่ามี project/equipment จริงหรือไม่
# project = await db.get(Project, pe_in.projectId)
# if not project:
# raise HTTPException(status_code=400, detail="Invalid projectId")
#
# equipment = await db.get(Equipment, pe_in.equipmentId)
# if not equipment:
# raise HTTPException(status_code=400, detail="Invalid equipmentId")
new_pe = ProjectEquipment( new_pe = ProjectEquipment(
projectId=pe_in.projectId, projectId=pe_in.projectId,
equipmentId=pe_in.equipmentId, equipmentId=pe_in.equipmentId,
quantity_in_project=pe_in.quantity_in_project quantity_in_project=pe_in.quantity_in_project
) )
try: try:
db.add(new_pe) db.add(new_pe)
await db.commit() await db.commit()
...@@ -39,15 +26,23 @@ async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCrea ...@@ -39,15 +26,23 @@ async def create_project_equipment(db: AsyncSession, pe_in: ProjectEquipmentCrea
raise HTTPException(status_code=400, detail=str(e.orig)) raise HTTPException(status_code=400, detail=str(e.orig))
return new_pe return new_pe
# READ ALL # READ ALL (แสดงข้อมูล Project และ Equipment แบบ nested)
async def get_all_project_equipments(db: AsyncSession): async def get_all_project_equipments(db: AsyncSession):
result = await db.execute(select(ProjectEquipment)) stmt = select(ProjectEquipment).options(
selectinload(ProjectEquipment.project),
selectinload(ProjectEquipment.equipment)
)
result = await db.execute(stmt)
return result.scalars().all() return result.scalars().all()
# READ ONE # READ ONE (แสดงข้อมูล Project และ Equipment แบบ nested)
async def get_project_equipment_by_id(db: AsyncSession, pe_id: UUID): async def get_project_equipment_by_id(db: AsyncSession, pe_id: UUID):
pe_db = await db.get(ProjectEquipment, pe_id) # สั้นลง stmt = select(ProjectEquipment).options(
return pe_db selectinload(ProjectEquipment.project),
selectinload(ProjectEquipment.equipment)
).where(ProjectEquipment.peId == pe_id)
result = await db.execute(stmt)
return result.scalar_one_or_none()
# UPDATE # UPDATE
async def update_project_equipment(db: AsyncSession, pe_id: UUID, pe_in: ProjectEquipmentCreate): async def update_project_equipment(db: AsyncSession, pe_id: UUID, pe_in: ProjectEquipmentCreate):
...@@ -85,3 +80,11 @@ async def delete_project_equipment(db: AsyncSession, pe_id: UUID): ...@@ -85,3 +80,11 @@ async def delete_project_equipment(db: AsyncSession, pe_id: UUID):
raise HTTPException(status_code=400, detail=str(e.orig)) raise HTTPException(status_code=400, detail=str(e.orig))
return {"message": "ProjectEquipment deleted successfully"} return {"message": "ProjectEquipment deleted successfully"}
# GET Equipment by ProjectId
async def get_equipment_by_project_id(db: AsyncSession, project_id: UUID):
stmt = select(ProjectEquipment).options(
selectinload(ProjectEquipment.equipment)
).where(ProjectEquipment.projectId == project_id)
result = await db.execute(stmt)
return result.scalars().all()
...@@ -28,8 +28,8 @@ class ProjectEquipment(Base): ...@@ -28,8 +28,8 @@ class ProjectEquipment(Base):
quantity_in_project = Column(Integer, nullable=False, default=0) quantity_in_project = Column(Integer, nullable=False, default=0)
# Relationship กลับไปยัง Project และ Equipment # Relationship กลับไปยัง Project และ Equipment
project = relationship("Project", back_populates="project_equipment") project = relationship("Project", back_populates="project_equipment", lazy="joined")
equipment = relationship("Equipment", back_populates="project_equipment") equipment = relationship("Equipment", lazy="joined")
# เชื่อมโยงกับ BorrowTransaction # เชื่อมโยงกับ BorrowTransaction
borrow_transactions = relationship( borrow_transactions = relationship(
......
...@@ -11,7 +11,8 @@ from ..controllers.project_equipment_controller import ( ...@@ -11,7 +11,8 @@ from ..controllers.project_equipment_controller import (
get_all_project_equipments, get_all_project_equipments,
get_project_equipment_by_id, get_project_equipment_by_id,
update_project_equipment, update_project_equipment,
delete_project_equipment delete_project_equipment,
get_equipment_by_project_id
) )
from ..schemas.project_equipment_schema import ( from ..schemas.project_equipment_schema import (
ProjectEquipmentCreate, ProjectEquipmentCreate,
...@@ -63,3 +64,12 @@ async def delete_pe_endpoint( ...@@ -63,3 +64,12 @@ async def delete_pe_endpoint(
db: AsyncSession = Depends(get_db) db: AsyncSession = Depends(get_db)
): ):
return await delete_project_equipment(db, peId) return await delete_project_equipment(db, peId)
@router.get("/project/{projectId}", response_model=List[ProjectEquipmentResponse])
async def get_equipment_for_project(
projectId: UUID,
db: AsyncSession = Depends(get_db)
):
pes = await get_equipment_by_project_id(db, projectId)
return pes
\ No newline at end of file
# myproject/schemas/project_equipment_schema.py
from pydantic import BaseModel from pydantic import BaseModel
from typing import Optional from typing import Optional
from uuid import UUID from uuid import UUID
from .project_schema import ProjectResponse
from .equipment_schema import EquipmentResponse
class ProjectEquipmentBase(BaseModel): class ProjectEquipmentBase(BaseModel):
quantity_in_project: int = 0 quantity_in_project: int = 0
...@@ -14,6 +16,8 @@ class ProjectEquipmentResponse(ProjectEquipmentBase): ...@@ -14,6 +16,8 @@ class ProjectEquipmentResponse(ProjectEquipmentBase):
peId: UUID peId: UUID
projectId: UUID projectId: UUID
equipmentId: UUID equipmentId: UUID
project: Optional[ProjectResponse] = None
equipment: Optional[EquipmentResponse] = None
class Config: class Config:
orm_mode = True orm_mode = True
...@@ -33,66 +33,25 @@ ...@@ -33,66 +33,25 @@
</div> </div>
</div> </div>
@for(item of filterList;track filterList){ @for(item of filterList;track filterList){
<!-- <div class="xxl:col-span-4 xl:col-span-6 lg:col-span-6 md:col-span-6 sm:col-span-12 col-span-12">
<div class="box team-member-card">
<div class="teammember-cover-image mt-1">
<span class="avatar avatar-xl avatar-rounded">
<img [src]="item.getPicture()" alt="">
</span>
</div>
<div class="box-body !p-0">
<div
class="flex flex-wrap align-item-center sm:mt-0 mt-[3rem] justify-between border-b border-dashed dark:border-defaultborder/10 p-4">
<div class="team-member-details flex-grow">
<p class="mb-0 font-semibold text-[1rem] text-truncate">
<a href="javascript:void(0);">{{item.equipmentName}}</a>
</p>
<p class="mb-0 text-[0.75rem] text-[#8c9097] dark:text-white/50 text-truncate">
{{item.description}}</p>
</div>
</div>
</div>
<div class="box-footer border-block-start-dashed dark:border-defaultborder/10 text-center">
<div class="btn-list">
<div class="btn-list">
<button type="button" aria-label="button" data-hs-overlay="#modal-detail" (click)="view(item)"
class="ti-btn ti-btn-sm ti-btn-primary me-[0.375rem]"><i class="ri-edit-line"></i></button>
<button (click)="delete(item)" type="button" aria-label="button"
class="ti-btn ti-btn-sm ti-btn-danger me-0"><i class="ri-delete-bin-line"></i></button>
</div>
</div>
</div>
</div>
</div> -->
<div class="xxl:col-span-2 xl:col-span-3 lg:col-span-4 md:col-span-4 sm:col-span-6 col-span-12"> <div class="xxl:col-span-2 xl:col-span-3 lg:col-span-4 md:col-span-4 sm:col-span-6 col-span-12">
<div class="box custom-box"> <div class="box custom-box">
<img [src]="item.getPicture()" class="!rounded-t-md" alt="..." <img [src]="item.equipment.getPicture()" class="!rounded-t-md" alt="..."
style="width: 100%;height: 200px;object-fit: cover;"> style="width: 100%;height: 200px;object-fit: cover;">
<div class="flex items-center justify-between nft-like-section w-full px-4"> <div class="flex items-center justify-between nft-like-section w-full px-4">
<!-- <div class="flex-grow">
<button type="button" aria-label="button"
class="ti-btn ti-btn-sm ti-btn-success-full !rounded-full btn-wave waves-effect waves-light">
<i class="ri-heart-fill"></i>
</button>
</div>
<div>
<span class="badge nft-like-badge text-white"><i
class="ri-heart-fill me-1 text-danger align-middle inline-block"></i>0.47k</span>
</div> -->
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="flex items-center mb-4"> <div class="flex items-center mb-4">
<div> <div>
<p class="text-[.9375rem] font-semibold mb-2"><a href="javascript:void(0);">{{item.equipmentName}}</a></p> <p class="text-[.9375rem] font-semibold mb-2"><a href="javascript:void(0);">{{item.equipment.equipmentName}}</a></p>
<p class="text-[0.75rem] text-[#8c9097] dark:text-white/50 mb-0">S/N# {{item.serialNumber}}</p> <p class="text-[0.75rem] text-[#8c9097] dark:text-white/50 mb-0">S/N# {{item.equipment.serialNumber}}</p>
<p class="text-[0.75rem] text-[#8c9097] dark:text-white/50 mb-0">STOCK# {{item.peId}}</p>
</div> </div>
</div> </div>
<div class="flex flex-wrap align-itesm-center justify-between"> <div class="flex flex-wrap align-itesm-center justify-between">
<div class="font-semibold mb-1">รายละเอียด :</div> <div class="font-semibold mb-1">รายละเอียด :</div>
<p class="text-[#8c9097] dark:text-white/50 mb-3">{{item.description}}</p> <p class="text-[#8c9097] dark:text-white/50 mb-3">{{item.equipment.description}}</p>
<!-- <div class="flex flex-wrap items-center leading-none"> <!-- <div class="flex flex-wrap items-center leading-none">
<span class="avatar avatar-xs me-1"> <span class="avatar avatar-xs me-1">
<img src="./assets/images/crypto-currencies/square-color/Ethereum.svg" alt=""> <img src="./assets/images/crypto-currencies/square-color/Ethereum.svg" alt="">
...@@ -101,13 +60,13 @@ ...@@ -101,13 +60,13 @@
</div> </div>
<div class="flex flex-wrap align-itesm-center justify-between mb-2"> <div class="flex flex-wrap align-itesm-center justify-between mb-2">
<div class="font-semibold mb-1">จำนวน :</div> <div class="font-semibold mb-1">จำนวน :</div>
<h3 class="text-[#8c9097] dark:text-white/50">{{item.quantity}}</h3> <h3 class="text-[#8c9097] dark:text-white/50">{{item.quantity_in_project}}</h3>
</div> </div>
<!-- <div class="grid"> <!-- <div class="grid">
<button type="button" class="ti-btn ti-btn-primary btn-wave waves-effect waves-light">Place Bid</button> <button type="button" class="ti-btn ti-btn-primary btn-wave waves-effect waves-light">Place Bid</button>
</div> --> </div> -->
</div> </div>
<div class="box-footer border-block-start-dashed dark:border-defaultborder/10 text-center"> <!-- <div class="box-footer border-block-start-dashed dark:border-defaultborder/10 text-center">
<div class="btn-list"> <div class="btn-list">
<div class="btn-list"> <div class="btn-list">
<button type="button" aria-label="button" data-hs-overlay="#modal-detail" (click)="view(item)" <button type="button" aria-label="button" data-hs-overlay="#modal-detail" (click)="view(item)"
...@@ -120,24 +79,17 @@ ...@@ -120,24 +79,17 @@
class="ti-btn ti-btn-sm ti-btn-danger me-0"><i class="ri-delete-bin-line"></i></button> class="ti-btn ti-btn-sm ti-btn-danger me-0"><i class="ri-delete-bin-line"></i></button>
</div> </div>
</div> </div>
</div> </div> -->
</div> </div>
</div> </div>
} }
</div> </div>
<!-- <nav aria-label="Page navigation" class="mb-4">
<ul class="ti-pagination !justify-end py-[0.375rem] px-3 text-[1rem] flex flex-row">
<li class="page-item disabled"><a class="page-link py-[0.375rem] px-3" href="javascript:void(0);">Previous</a></li>
<li class="page-item"><a class="page-link py-[0.375rem] px-3" href="javascript:void(0);">1</a></li>
<li class="page-item"><a class="page-link py-[0.375rem] px-3" href="javascript:void(0);">2</a></li>
<li class="page-item"><a class="page-link py-[0.375rem] px-3" href="javascript:void(0);">Next</a></li>
</ul>
</nav> -->
<!-- Start:: New Deal --> <!-- Start:: New Deal -->
<div id="modal-detail" class="hs-overlay hidden ti-modal"> <div id="modal-detail" class="hs-overlay hidden ti-modal">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out"> <div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out lg:!max-w-4xl lg:w-full m-3 lg:!mx-auto">
<div class="ti-modal-content"> <div class="ti-modal-content">
<div class="ti-modal-header"> <div class="ti-modal-header">
<h6 class="modal-title text-[1rem] font-semibold text-defaulttextcolor" id="mail-ComposeLabel">ข้อมูลอุปกรณ์ <h6 class="modal-title text-[1rem] font-semibold text-defaulttextcolor" id="mail-ComposeLabel">ข้อมูลอุปกรณ์
...@@ -149,52 +101,74 @@ ...@@ -149,52 +101,74 @@
</button> </button>
</div> </div>
<div class="ti-modal-body px-4"> <div class="ti-modal-body px-4">
<div class="grid grid-cols-12 gap-4"> <div class="grid grid-cols-12 gap-x-6">
<div class="xl:col-span-12 col-span-12"> <!-- <div class="xl:col-span-12 col-span-12">
<div class="mb-0 text-center"> <div class="box mt-6">
<span class="avatar avatar-xxl avatar-rounded"> <div class="box-header justify-between">
<img [src]="selectModel.getPicture()" alt="" id="profile-img"> <div class="box-title">
<span class="badge rounded-full bg-primary avatar-badge"> {{ 'All List' | translate}} <span
<input ng2FileSelect [uploader]="uploaderProfile" type="file" name="photo" class="badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle">{{itemsList.length}}</span>
class="absolute w-full h-full opacity-[0]" id="profile-change">
<i class="fe fe-camera text-[.625rem]"></i>
</span>
</span>
</div>
</div> </div>
<div class="xl:col-span-12 col-span-12"> <div class="flex flex-wrap gap-2">
<label for="deal-name" class="form-label">ชื่ออุปกรณ์</label> <div>
<input type="text" class="form-control" id="deal-name" placeholder="ชื่ออุปกรณ์" <input [(ngModel)]='searchTerm' class="form-control form-control" type="text"
[(ngModel)]="selectModel.equipmentName"> placeholder="{{ 'ค้นหาอุปกรณ์' | translate}}" aria-label=".form-control-sm example">
</div> </div>
<div class="xl:col-span-12 col-span-12">
<label for="deal-name" class="form-label">S/N</label>
<input type="text" class="form-control" id="deal-name" placeholder="S/N"
[(ngModel)]="selectModel.serialNumber">
</div> </div>
<!-- <div class="xl:col-span-6 col-span-12"> </div>
<label for="deal-name" class="form-label">จำนวน</label> </div>
<input type="number" class="form-control" id="deal-name" placeholder="จำนวน"
[(ngModel)]="selectModel.quantity">
</div> --> </div> -->
<div class="xl:col-span-12 col-span-12"> @for(item of filterListAll;track filterListAll){
<label for="deal-lead-score" class="form-label">รายละเอียด</label> <div class="xxl:col-span-3 xl:col-span-3 lg:col-span-3 md:col-span-3 sm:col-span-6 col-span-12">
<!-- <input type="text" class="form-control" id="deal-lead-score" placeholder="รายละเอียด" <div class="box custom-box">
[(ngModel)]="selectModel.description"> --> <img [src]="item.getPicture()" class="!rounded-t-md" alt="..."
<textarea class="form-control" id="job-description" [(ngModel)]="selectModel.description" style="width: 100%;height: 200px;object-fit: cover;">
rows="4"></textarea> <div class="flex items-center justify-between nft-like-section w-full px-4">
</div> </div>
<div class="xl:col-span-12 col-span-12"> <div class="box-body">
<div class="form-check form-check-lg flex items-center">
<input class="form-check-input" type="checkbox" id="checkebox-lg" [(ngModel)]="selectModel.is_returnable"> <div class="flex items-center mb-4">
<label class="form-check-label" for="checkebox-lg"> <div>
ตรวจสอบการคืน <p class="text-[.9375rem] font-semibold mb-2"><a
</label> href="javascript:void(0);">{{item.equipmentName}}</a></p>
<p class="text-[0.75rem] text-[#8c9097] dark:text-white/50 mb-0">S/N# {{item.serialNumber}}</p>
</div> </div>
</div> </div>
<div class="flex flex-wrap align-itesm-center justify-between">
<div class="font-semibold mb-1">รายละเอียด :</div>
<p class="text-[#8c9097] dark:text-white/50 mb-3">{{item.description}}</p>
<!-- <div class="flex flex-wrap items-center leading-none">
<span class="avatar avatar-xs me-1">
<img src="./assets/images/crypto-currencies/square-color/Ethereum.svg" alt="">
</span>0.24ETH
</div> -->
</div>
<div class="flex flex-wrap align-itesm-center justify-between mb-2">
<div class="font-semibold mb-1">จำนวน :</div>
<!-- <h3 class="text-[#8c9097] dark:text-white/50">{{item.quantity}}</h3> -->
<input type="number" class="form-control" id="deal-name" placeholder="จำนวน"
[(ngModel)]="item.quantity">
</div>
<!-- <div class="grid">
<button type="button" class="ti-btn ti-btn-primary btn-wave waves-effect waves-light">Place Bid</button>
</div> -->
</div>
<div class="box-footer border-block-start-dashed dark:border-defaultborder/10 text-center">
<div class="btn-list">
<div class="btn-list">
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-primary-full me-2"
(click)="stock(item)"><i class="ri-add-line font-semibold align-middle"></i>{{ 'นำเข้า' |
translate}}
</a>
</div>
</div>
</div>
</div>
</div>
}
</div> </div>
</div> </div>
<div class="ti-modal-footer"> <div class="ti-modal-footer">
...@@ -202,7 +176,7 @@ ...@@ -202,7 +176,7 @@
data-hs-overlay="#modal-detail"> data-hs-overlay="#modal-detail">
ยกเลิก ยกเลิก
</button> </button>
<button type="button" class="ti-btn bg-primary text-white !font-medium" (click)="save()">บันทึก</button> <!-- <button type="button" class="ti-btn bg-primary text-white !font-medium" (click)="save()">บันทึก</button> -->
</div> </div>
</div> </div>
</div> </div>
......
import { ProjectEquipmentService } from './../../services/project-equipments.service';
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core'; import { ChangeDetectionStrategy, Component, ElementRef, ViewChild } from '@angular/core';
import { NgSelectModule } from "@ng-select/ng-select"; import { NgSelectModule } from "@ng-select/ng-select";
import { TranslateModule, TranslateService } from "@ngx-translate/core"; import { TranslateModule, TranslateService } from "@ngx-translate/core";
import { FormsModule } from "@angular/forms"; import { FormsModule } from "@angular/forms";
import swal from 'sweetalert'; import swal from 'sweetalert';
import { MatPaginator, PageEvent } from "@angular/material/paginator"; import { MatPaginator, PageEvent } from "@angular/material/paginator";
import { SharedModule } from "../../../shared/shared.module"; import { SharedModule } from "../../../shared/shared.module";
import { UserProfileModel } from "../../models/user.model"; import { UserProfileModel } from "../../models/user.model";
import { UserService } from "../../services/user.service"; import { UserService } from "../../services/user.service";
import { TokenService } from "../../../shared/services/token.service"; import { TokenService } from "../../../shared/services/token.service";
import { FileUploadModule } from 'ng2-file-upload'; import { FileUploadModule } from 'ng2-file-upload';
import { FileItem, FileUploader, ParsedResponseHeaders } from "ng2-file-upload"; import { FileItem, FileUploader, ParsedResponseHeaders } from "ng2-file-upload";
import { environment } from "../../../../environments/environment"; import { environment } from "../../../../environments/environment";
import { EquipmentModel, EquipmentStockModel } from "../../models/equipments.model"; import { EquipmentModel, EquipmentStockModel } from "../../models/equipments.model";
import { EquipmentService } from "../../services/equirement.service"; import { EquipmentService } from "../../services/equirement.service";
import { HttpClient } from "@angular/common/http"; import { HttpClient } from "@angular/common/http";
import { ProjectEquipmentModel } from '../../models/project-equipments';
@Component({ @Component({
selector: 'app-admin-project-equirement', selector: 'app-admin-project-equirement',
...@@ -38,8 +40,12 @@ export class AdminProjectEquirementComponent { ...@@ -38,8 +40,12 @@ export class AdminProjectEquirementComponent {
someSelected = false; someSelected = false;
uploaderProfile: FileUploader | undefined; uploaderProfile: FileUploader | undefined;
uploadErrorMsg: string = ""; uploadErrorMsg: string = "";
itemsList: EquipmentModel[] = [] itemsList: ProjectEquipmentModel[] = []
filterList: EquipmentModel[] = [] filterList: ProjectEquipmentModel[] = []
itemsListAll: EquipmentModel[] = []
filterListAll: EquipmentModel[] = []
selectModel: EquipmentModel = new EquipmentModel() selectModel: EquipmentModel = new EquipmentModel()
selectStock?: EquipmentStockModel selectStock?: EquipmentStockModel
selectedItems = new Map<string, boolean>(); selectedItems = new Map<string, boolean>();
...@@ -60,7 +66,7 @@ export class AdminProjectEquirementComponent { ...@@ -60,7 +66,7 @@ export class AdminProjectEquirementComponent {
projectId = "" projectId = ""
_searchTerm = ""; _searchTerm = "";
isEdit = false; isEdit = false;
constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService) { constructor(private http: HttpClient, private eqService: EquipmentService, public translate: TranslateService, private tokenService: TokenService, private projectEquipmentService: ProjectEquipmentService) {
this.uploadConfig() this.uploadConfig()
this.projectId = this.tokenService.getSelectCompany().projectId!; this.projectId = this.tokenService.getSelectCompany().projectId!;
} }
...@@ -126,7 +132,19 @@ export class AdminProjectEquirementComponent { ...@@ -126,7 +132,19 @@ export class AdminProjectEquirementComponent {
} }
ngOnInit(): void { ngOnInit(): void {
this.getCompanyEquirment()
this.getProjectEquirment()
}
getCompanyEquirment(){
this.eqService.getLists().subscribe(result => { this.eqService.getLists().subscribe(result => {
this.itemsListAll = result.filter(e => e.quantity > 0)
this.updatePagedItemsAll()
})
}
getProjectEquirment(){
this.projectEquipmentService.getLists(this.projectId).subscribe(result => {
this.itemsList = result this.itemsList = result
this.updatePagedItems() this.updatePagedItems()
}) })
...@@ -136,8 +154,8 @@ export class AdminProjectEquirementComponent { ...@@ -136,8 +154,8 @@ export class AdminProjectEquirementComponent {
this.pageIndex = 0; this.pageIndex = 0;
return this.itemsList?.filter( return this.itemsList?.filter(
(x) => (x) =>
x.equipmentName.toLowerCase().indexOf(v.toLowerCase()) !== -1 || x.equipment.equipmentName.toLowerCase().indexOf(v.toLowerCase()) !== -1 ||
x.description?.toLowerCase().indexOf(v.toLowerCase()) !== -1 x.equipment.description?.toLowerCase().indexOf(v.toLowerCase()) !== -1
); );
} }
...@@ -247,6 +265,13 @@ export class AdminProjectEquirementComponent { ...@@ -247,6 +265,13 @@ export class AdminProjectEquirementComponent {
this.filterList = this.itemsList this.filterList = this.itemsList
} }
updatePagedItemsAll() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
this.filterListAll = this.itemsListAll
}
saveStock() { saveStock() {
console.log(this.selectStock) console.log(this.selectStock)
swal({ swal({
...@@ -270,5 +295,40 @@ export class AdminProjectEquirementComponent { ...@@ -270,5 +295,40 @@ export class AdminProjectEquirementComponent {
} }
stock(item: EquipmentModel) {
if (item.quantity > 0) {
swal({
title: "Are you sure?",
text: "คุณต้องการบันทึกหรือไม่",
icon: "warning",
dangerMode: false,
buttons: ["Cancel", "Confirm"],
})
.then((willDelete: any) => {
if (willDelete) {
this.projectEquipmentService.save({
"quantity_in_project": item.quantity,
"projectId": this.projectId,
"equipmentId": item.equipmentId
}).subscribe(result => {
this.selectStock = new EquipmentStockModel()
this.selectStock.quantity = item.quantity
this.selectStock.equipmentId = item.equipmentId
this.selectStock.created_by = this.tokenService.getUser().member.memberId
this.selectStock.action = "OUTBOUND",
this.selectStock.remark = "ย้ายเข้าสู่โครงการ " + this.tokenService.getSelectCompany().projectId + " (" + this.tokenService.getSelectCompany().project_code + ")"
this.eqService.stock(this.selectStock!).subscribe(result => {
swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
this.getProjectEquirment()
this.getCompanyEquirment()
this.childModal?.nativeElement.click()
})
})
}
});
}
} }
}
import { TranslateService } from "@ngx-translate/core"; import { TranslateService } from "@ngx-translate/core";
import { BaseModel } from "./base.model"; import { BaseModel } from "./base.model";
import { ProjectModel } from "./project.model";
import { EquipmentModel } from "./equipments.model";
export class ProjectEquipmentModel extends BaseModel { export class ProjectEquipmentModel extends BaseModel {
pe_id: string;
project_id: string;
equipment_id?: string;
quantity_in_project: number; quantity_in_project: number;
created_at: string; peId: string;
updated_at: string; projectId: string;
equipmentId: string;
project: ProjectModel;
equipment: EquipmentModel;
constructor(data?: Partial<ProjectEquipmentModel>, translateService?: TranslateService) { constructor(data?: Partial<ProjectEquipmentModel>, translateService?: TranslateService) {
super(data, translateService); super(data, translateService);
this.pe_id = data?.pe_id ?? ''; this.peId = data?.peId ?? '';
this.project_id = data?.project_id ?? ''; this.projectId = data?.projectId ?? '';
this.equipment_id = data?.equipment_id ?? ''; this.equipmentId = data?.equipmentId ?? '';
this.quantity_in_project = data?.quantity_in_project ?? 0; this.quantity_in_project = data?.quantity_in_project ?? 0;
this.created_at = data?.created_at ?? new Date().toISOString(); this.project = data?.project || new ProjectModel();
this.updated_at = data?.updated_at ?? new Date().toISOString(); this.equipment = data?.equipment ? new EquipmentModel(data.equipment) : new EquipmentModel();
} }
} }
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { map, tap, switchMap, filter, reduce } from "rxjs/operators"; import { map, tap, switchMap, filter, reduce } from "rxjs/operators";
import { ProjectEquipmentModel } from '../models/project-equipments'; import { ProjectEquipmentModel } from '../models/project-equipments';
import { environment } from '../../../environments/environment';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ProjectEquipmentService { export class ProjectEquipmentService {
apiBaseUrl = environment.baseUrl + "/project-equipments"; apiBaseUrl = environment.baseUrl + "/project-equipments";
constructor( constructor(
private http: HttpClient private http: HttpClient
) { } ) { }
...@@ -19,34 +19,30 @@ apiBaseUrl = environment.baseUrl + "/project-equipments"; ...@@ -19,34 +19,30 @@ apiBaseUrl = environment.baseUrl + "/project-equipments";
.get<ProjectEquipmentModel>(this.apiBaseUrl + "/" + id) .get<ProjectEquipmentModel>(this.apiBaseUrl + "/" + id)
.pipe(map((e) => new ProjectEquipmentModel(e))); .pipe(map((e) => new ProjectEquipmentModel(e)));
} }
getLists(projectId: string) {
getLists() {
return this.http return this.http
.get<ProjectEquipmentModel[]>(this.apiBaseUrl) .get<ProjectEquipmentModel[]>(this.apiBaseUrl+ "/project/" +projectId)
.pipe( .pipe(
map((e) => e.map((e) => new ProjectEquipmentModel(e))) map((e) => e.map((e) => new ProjectEquipmentModel(e)))
); );
} }
save(body: ProjectEquipmentModel) { save(body: any) {
return this.http.post<{ return this.http.post<ProjectEquipmentModel>(this.apiBaseUrl, body);
"message": string,
"user": ProjectEquipmentModel
}>(this.apiBaseUrl, new ProjectEquipmentModel(body));
} }
update(body: ProjectEquipmentModel) { update(body: ProjectEquipmentModel) {
return this.http.put<{ return this.http.put<{
"message": string, "message": string,
"user": ProjectEquipmentModel "user": ProjectEquipmentModel
}>(this.apiBaseUrl + "/" + body.equipment_id, new ProjectEquipmentModel(body)); }>(this.apiBaseUrl + "/" + body.equipmentId, new ProjectEquipmentModel(body));
} }
delete(body: ProjectEquipmentModel) { delete(body: ProjectEquipmentModel) {
return this.http.delete<{ return this.http.delete<{
"message": string, "message": string,
"user": ProjectEquipmentModel "user": ProjectEquipmentModel
}>(this.apiBaseUrl + "/" + body.equipment_id); }>(this.apiBaseUrl + "/" + body.equipmentId);
} }
......
...@@ -21,7 +21,7 @@ export class ProjectMemberService { ...@@ -21,7 +21,7 @@ export class ProjectMemberService {
getLists(projectId: string) { getLists(projectId: string) {
return this.http return this.http
.get<ProjectMemberModel[]>(this.apiBaseUrl) .get<ProjectMemberModel[]>(this.apiBaseUrl+ "/project/" +projectId)
.pipe( .pipe(
map((e) => e.map((e) => new ProjectMemberModel(e))) map((e) => e.map((e) => new ProjectMemberModel(e)))
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment