Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
BookingMyHrManagement
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chanachai
BookingMyHrManagement
Commits
3f575b1c
Commit
3f575b1c
authored
Apr 29, 2025
by
DESKTOP-E0VCCBD\zedan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
284738a8
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
1371 additions
and
208 deletions
+1371
-208
borrow_controller.cpython-312.pyc
...controllers/__pycache__/borrow_controller.cpython-312.pyc
+0
-0
borrow_controller.py
API-Fast/src/controllers/borrow_controller.py
+2
-1
equipment_repair_controller.py
API-Fast/src/controllers/equipment_repair_controller.py
+237
-0
equipment_repair.py
API-Fast/src/models/equipment_repair.py
+31
-0
borrow_routes.cpython-312.pyc
...Fast/src/routes/__pycache__/borrow_routes.cpython-312.pyc
+0
-0
equipment_repair_routes.py
API-Fast/src/routes/equipment_repair_routes.py
+80
-0
equipment_repair_schema.py
API-Fast/src/schemas/equipment_repair_schema.py
+36
-0
admin-project-equirement.component.html
...roject-equirement/admin-project-equirement.component.html
+122
-6
admin-project-equirement.component.ts
...-project-equirement/admin-project-equirement.component.ts
+31
-0
admin-project-home.component.html
...ment/admin-project-home/admin-project-home.component.html
+7
-7
admin-project-home.component.ts
...gement/admin-project-home/admin-project-home.component.ts
+29
-6
emp-borrow-repair.component.html
...gement/emp-borrow-repair/emp-borrow-repair.component.html
+413
-0
emp-borrow-repair.component.scss
...gement/emp-borrow-repair/emp-borrow-repair.component.scss
+0
-0
emp-borrow-repair.component.ts
...nagement/emp-borrow-repair/emp-borrow-repair.component.ts
+40
-0
emp-borrow-return-status.component.html
...row-return-status/emp-borrow-return-status.component.html
+42
-1
emp-borrow-return-status.component.ts
...orrow-return-status/emp-borrow-return-status.component.ts
+54
-35
emp-borrow-status.component.html
...gement/emp-borrow-status/emp-borrow-status.component.html
+40
-0
emp-borrow-status.component.ts
...nagement/emp-borrow-status/emp-borrow-status.component.ts
+11
-4
emp-borrow-transaction.component.html
...-borrow-transaction/emp-borrow-transaction.component.html
+35
-30
emp-borrow-transaction.component.ts
...mp-borrow-transaction/emp-borrow-transaction.component.ts
+134
-112
user.model.ts
Web-Manage/src/app/DPU/models/user.model.ts
+1
-1
sidebar.component.html
.../src/app/shared/components/sidebar/sidebar.component.html
+2
-2
sidebar.component.ts
...ge/src/app/shared/components/sidebar/sidebar.component.ts
+3
-0
nav.service.ts
Web-Manage/src/app/shared/services/nav.service.ts
+13
-1
th.json
Web-Manage/src/assets/i18n/th.json
+7
-0
dev.box-icon-element.html
...e/src/assets/iconfonts/boxicons/dev.box-icon-element.html
+1
-2
No files found.
API-Fast/src/controllers/__pycache__/borrow_controller.cpython-312.pyc
View file @
3f575b1c
No preview for this file type
API-Fast/src/controllers/borrow_controller.py
View file @
3f575b1c
...
...
@@ -48,7 +48,7 @@ async def create_borrow_transaction(db: AsyncSession, borrow_in: BorrowTransacti
)
# ถ้าสถานะเป็น "approved" ให้ทำการตรวจสอบและตัดสต็อกทันที
if
status
==
"approved"
:
if
status
==
"approved"
or
status
==
"repair"
or
status
==
"remove"
:
if
pe_db
.
quantity_in_project
<
borrow_in
.
quantity_borrowed
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Not enough equipment to approve"
)
pe_db
.
quantity_in_project
-=
borrow_in
.
quantity_borrowed
...
...
@@ -56,6 +56,7 @@ async def create_borrow_transaction(db: AsyncSession, borrow_in: BorrowTransacti
new_borrow
.
approved_by
=
borrow_in
.
approved_by
# ถ้ามีการส่ง admin id
new_borrow
.
approved_at
=
datetime
.
utcnow
()
db
.
add
(
pe_db
)
try
:
db
.
add
(
new_borrow
)
...
...
API-Fast/src/controllers/equipment_repair_controller.py
0 → 100644
View file @
3f575b1c
# myproject/controllers/borrow_controller.py
from
typing
import
List
,
Optional
from
uuid
import
UUID
from
datetime
import
datetime
from
fastapi
import
HTTPException
from
sqlalchemy.ext.asyncio
import
AsyncSession
from
sqlalchemy
import
select
from
sqlalchemy.exc
import
SQLAlchemyError
from
..models.project_equipment
import
ProjectEquipment
from
..models.project_member
import
ProjectMember
from
..models.equipment_repair
import
BorrowRepair
from
..models.equipment
import
Equipment
from
..schemas.equipment_repair_schema
import
BorrowRepairBase
# CREATE
async
def
create_borrow_repair
(
db
:
AsyncSession
,
borrow_in
:
BorrowRepairBase
):
"""
สร้าง BorrowTransaction โดยที่ถ้าสถานะเป็น 'approved'
ระบบจะตัดจำนวนในสต็อกทันที (deduct stock) และบันทึกสถานะเป็น 'approved'
Admin เป็นผู้สร้าง transaction นี้และระบุ memberId ที่เบิกอุปกรณ์
"""
# หา ProjectEquipment ที่อ้างอิง
pe_db
=
await
db
.
get
(
ProjectEquipment
,
borrow_in
.
peId
)
if
not
pe_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"ProjectEquipment not found"
)
# ตรวจสอบว่า member อยู่ใน project หรือไม่
result_pm
=
await
db
.
execute
(
select
(
ProjectMember
)
.
where
(
ProjectMember
.
memberId
==
borrow_in
.
memberId
,
ProjectMember
.
projectId
==
pe_db
.
projectId
)
)
pm_db
=
result_pm
.
scalar_one_or_none
()
if
not
pm_db
:
raise
HTTPException
(
status_code
=
403
,
detail
=
"Member is not in this project"
)
# กำหนดสถานะเริ่มต้นจาก input ถ้ามี, ถ้าไม่ระบุให้เป็น "requested"
status
=
borrow_in
.
status
if
borrow_in
.
status
else
"requested"
new_borrow
=
BorrowRepair
(
memberId
=
borrow_in
.
memberId
,
peId
=
borrow_in
.
peId
,
quantity_borrowed
=
borrow_in
.
quantity_borrowed
,
status
=
status
)
# ถ้าสถานะเป็น "approved" ให้ทำการตรวจสอบและตัดสต็อกทันที
if
status
==
"approved"
:
if
pe_db
.
quantity_in_project
<
borrow_in
.
quantity_borrowed
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Not enough equipment to approve"
)
pe_db
.
quantity_in_project
-=
borrow_in
.
quantity_borrowed
# บันทึกการตัดสต็อก (อาจเพิ่ม approved_by, approved_at ได้ที่นี่)
new_borrow
.
approved_by
=
borrow_in
.
approved_by
# ถ้ามีการส่ง admin id
new_borrow
.
approved_at
=
datetime
.
utcnow
()
db
.
add
(
pe_db
)
try
:
db
.
add
(
new_borrow
)
await
db
.
commit
()
await
db
.
refresh
(
new_borrow
)
except
SQLAlchemyError
as
e
:
await
db
.
rollback
()
raise
HTTPException
(
status_code
=
400
,
detail
=
str
(
e
.
orig
))
return
new_borrow
# UPDATE
async
def
update_borrow_repair
(
db
:
AsyncSession
,
borrow_id
:
UUID
,
borrow_up
:
BorrowRepairBase
):
borrow_db
=
await
db
.
get
(
BorrowRepair
,
borrow_id
)
if
not
borrow_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"BorrowRepair not found"
)
try
:
# ถ้า user ส่ง status ใหม่มา
if
borrow_up
.
status
:
# ------------------------------------------------------------------
# 1) กรณี "approved"
# ------------------------------------------------------------------
if
borrow_up
.
status
==
"approved"
:
# ต้องเป็นคำขอที่ยังอยู่ในสถานะ requested ก่อน
if
borrow_db
.
status
!=
"requested"
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Cannot approve a transaction that is not in 'requested' status."
)
# หา projectEquipment
pe_db
=
await
db
.
get
(
ProjectEquipment
,
borrow_db
.
peId
)
if
not
pe_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"ProjectEquipment not found"
)
# ตรวจสอบจำนวน
if
pe_db
.
quantity_in_project
<
borrow_db
.
quantity_borrowed
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Not enough equipment to approve"
)
# ตัดจำนวนใน project_equipment
pe_db
.
quantity_in_project
-=
borrow_db
.
quantity_borrowed
db
.
add
(
pe_db
)
# เปลี่ยนสถานะเป็น approved
borrow_db
.
status
=
"approved"
# หากต้องการเก็บว่าใครเป็นคน approved และเวลาใด
# borrow_db.approved_by = current_admin_id
# borrow_db.approved_at = datetime.utcnow()
if
borrow_up
.
status
==
"repair"
:
# ต้องเป็นคำขอที่ยังอยู่ในสถานะ requested ก่อน
if
borrow_db
.
status
!=
"returned"
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Cannot approve a transaction that is not in 'repair' status."
)
# หา projectEquipment
pe_db
=
await
db
.
get
(
ProjectEquipment
,
borrow_db
.
peId
)
if
not
pe_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"ProjectEquipment not found"
)
# ตรวจสอบจำนวน
if
pe_db
.
quantity_in_project
<
borrow_db
.
quantity_borrowed
:
raise
HTTPException
(
status_code
=
400
,
detail
=
"Not enough equipment to approve"
)
# ตัดจำนวนใน project_equipment
pe_db
.
quantity_in_project
-=
borrow_db
.
quantity_borrowed
db
.
add
(
pe_db
)
# เปลี่ยนสถานะเป็น approved
borrow_db
.
status
=
"approved"
# เปลี่ยนสถานะเป็น repair
borrow_db
.
status
=
"repair"
# หากต้องการเก็บว่าใครเป็นคน approved และเวลาใด
# borrow_db.approved_by = current_admin_id
# borrow_db.approved_at = datetime.utcnow()
# ------------------------------------------------------------------
# 2) กรณี "returned"
# ------------------------------------------------------------------
elif
borrow_up
.
status
==
"returned"
:
# หา projectEquipment
pe_db
=
await
db
.
get
(
ProjectEquipment
,
borrow_db
.
peId
)
if
not
pe_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"ProjectEquipment not found"
)
# หาอุปกรณ์
result_eq
=
await
db
.
execute
(
select
(
Equipment
)
.
where
(
Equipment
.
equipmentId
==
pe_db
.
equipmentId
))
eq_db
=
result_eq
.
scalar_one_or_none
()
if
not
eq_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"Equipment not found"
)
# ถ้าอุปกรณ์เป็นประเภทคืนได้ (is_returnable == True) ก็คืนจำนวน
if
eq_db
.
is_returnable
:
pe_db
.
quantity_in_project
+=
borrow_db
.
quantity_borrowed
db
.
add
(
pe_db
)
borrow_db
.
status
=
"returned"
borrow_db
.
returned_date
=
datetime
.
utcnow
()
# ------------------------------------------------------------------
# 3) กรณีสถานะอื่น ๆ (เช่น rejected, borrowed, ฯลฯ)
# ------------------------------------------------------------------
else
:
borrow_db
.
status
=
borrow_up
.
status
# ถ้ามีฟิลด์อื่น เช่น quantity_borrowed หรืออื่น ๆ ก็อัปเดตที่นี่
# if borrow_up.quantity_borrowed is not None:
# borrow_db.quantity_borrowed = borrow_up.quantity_borrowed
# ...
db
.
add
(
borrow_db
)
await
db
.
commit
()
await
db
.
refresh
(
borrow_db
)
except
SQLAlchemyError
as
e
:
await
db
.
rollback
()
raise
HTTPException
(
status_code
=
400
,
detail
=
str
(
e
.
orig
))
return
borrow_db
# GET ALL
async
def
get_all_borrow_repair
(
db
:
AsyncSession
):
result
=
await
db
.
execute
(
select
(
BorrowRepair
))
return
result
.
scalars
()
.
all
()
# GET BY ID
async
def
get_borrow_repair_by_id
(
db
:
AsyncSession
,
borrow_id
:
UUID
):
return
await
db
.
get
(
BorrowRepair
,
borrow_id
)
# DELETE
async
def
delete_borrow_repair
(
db
:
AsyncSession
,
borrow_id
:
UUID
):
borrow_db
=
await
db
.
get
(
BorrowRepair
,
borrow_id
)
if
not
borrow_db
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"BorrowRepair not found"
)
try
:
await
db
.
delete
(
borrow_db
)
await
db
.
commit
()
except
SQLAlchemyError
as
e
:
await
db
.
rollback
()
raise
HTTPException
(
status_code
=
400
,
detail
=
str
(
e
.
orig
))
return
{
"message"
:
"BorrowRepair deleted"
}
# NEW API: Search BorrowRepairs by query parameters
async
def
search_borrow_repair
(
db
:
AsyncSession
,
member_id
:
Optional
[
UUID
]
=
None
,
peId
:
Optional
[
UUID
]
=
None
,
status
:
Optional
[
str
]
=
None
,
date_from
:
Optional
[
datetime
]
=
None
,
date_to
:
Optional
[
datetime
]
=
None
)
->
List
[
BorrowRepair
]:
"""
ค้นหา BorrowRepair โดยสามารถกรองตาม:
- member_id: รหัสสมาชิกที่เบิกอุปกรณ์
- status: สถานะของการเบิก (requested, approved, returned, rejected, etc.)
- date_from และ date_to: ช่วงวันของ created_at
"""
query
=
select
(
BorrowRepair
)
if
member_id
:
query
=
query
.
where
(
BorrowRepair
.
memberId
==
member_id
)
if
peId
:
query
=
query
.
where
(
BorrowRepair
.
peId
==
peId
)
if
status
:
query
=
query
.
where
(
BorrowRepair
.
status
==
status
)
if
date_from
:
query
=
query
.
where
(
BorrowRepair
.
created_at
>=
date_from
)
if
date_to
:
query
=
query
.
where
(
BorrowRepair
.
created_at
<=
date_to
)
result
=
await
db
.
execute
(
query
)
return
result
.
scalars
()
.
all
()
\ No newline at end of file
API-Fast/src/models/equipment_repair.py
0 → 100644
View file @
3f575b1c
from
sqlalchemy
import
Column
,
String
,
Integer
,
DateTime
,
ForeignKey
from
sqlalchemy.dialects.postgresql
import
UUID
from
sqlalchemy.sql
import
func
from
datetime
import
datetime
from
uuid
import
uuid4
from
sqlalchemy.orm
import
relationship
from
..config.database
import
Base
class
BorrowRepair
(
Base
):
__tablename__
=
"borrow_transactions"
borrowId
=
Column
(
UUID
(
as_uuid
=
True
),
primary_key
=
True
,
default
=
uuid4
)
peId
=
Column
(
UUID
(
as_uuid
=
True
),
ForeignKey
(
"project_equipment.peId"
),
nullable
=
False
)
memberId
=
Column
(
UUID
(
as_uuid
=
True
),
ForeignKey
(
"member.memberId"
),
nullable
=
False
)
quantity_borrowed
=
Column
(
Integer
,
nullable
=
False
,
default
=
1
)
status
=
Column
(
String
(
50
),
nullable
=
False
,
default
=
"repair"
)
# requested, approved, rejected, borrowed, returned
returned_date
=
Column
(
DateTime
,
nullable
=
True
)
created_at
=
Column
(
DateTime
,
nullable
=
False
,
server_default
=
func
.
now
())
# Approval fields
approved_by
=
Column
(
UUID
(
as_uuid
=
True
),
ForeignKey
(
"member.memberId"
),
nullable
=
True
)
approved_at
=
Column
(
DateTime
,
nullable
=
True
)
rejected_reason
=
Column
(
String
,
nullable
=
True
)
# Relationships
# Relationship สำหรับผู้เบิก
member
=
relationship
(
"Member"
,
foreign_keys
=
[
memberId
],
back_populates
=
"borrow_transactions"
,
lazy
=
"joined"
)
# Relationship สำหรับ ProjectEquipment
project_equipment
=
relationship
(
"ProjectEquipment"
,
back_populates
=
"borrow_transactions"
,
lazy
=
"joined"
)
# Relationship สำหรับผู้อนุมัติ
approved_by_member
=
relationship
(
"Member"
,
foreign_keys
=
[
approved_by
],
back_populates
=
"borrow_transactions"
,
lazy
=
"joined"
)
API-Fast/src/routes/__pycache__/borrow_routes.cpython-312.pyc
View file @
3f575b1c
No preview for this file type
API-Fast/src/routes/equipment_repair_routes.py
0 → 100644
View file @
3f575b1c
# myproject/routes/borrow_routes.py
from
datetime
import
datetime
from
fastapi
import
APIRouter
,
Depends
,
HTTPException
,
status
from
typing
import
List
,
Optional
from
uuid
import
UUID
from
sqlalchemy.ext.asyncio
import
AsyncSession
from
..config.database
import
get_db
from
..controllers.equipment_repair_controller
import
(
create_borrow_repair
,
update_borrow_repair
,
get_all_borrow_repair
,
get_borrow_repair_by_id
,
delete_borrow_repair
,
search_borrow_repair
)
from
..schemas.equipment_repair_schema
import
(
BorrowRepairBase
,
BorrowRepairResponse
,
)
router
=
APIRouter
()
# CREATE (พนักงานยืมอุปกรณ์)
@router.post
(
"/"
,
response_model
=
BorrowRepairResponse
,
status_code
=
status
.
HTTP_201_CREATED
)
async
def
create_borrow_endpoint
(
borrow_in
:
BorrowRepairBase
,
db
:
AsyncSession
=
Depends
(
get_db
)
):
new_borrow
=
await
create_borrow_repair
(
db
,
borrow_in
)
return
new_borrow
# UPDATE (เช่น คืนอุปกรณ์)
@router.put
(
"/{borrowrepairId}"
,
response_model
=
BorrowRepairResponse
)
async
def
update_borrow_endpoint
(
borrowId
:
UUID
,
borrow_up
:
BorrowRepairBase
,
db
:
AsyncSession
=
Depends
(
get_db
)
):
updated_borrow
=
await
update_borrow_repair
(
db
,
borrowId
,
borrow_up
)
return
updated_borrow
# GET ALL
@router.get
(
"/"
,
response_model
=
List
[
BorrowRepairResponse
])
async
def
get_all_borrows_endpoint
(
db
:
AsyncSession
=
Depends
(
get_db
)):
return
await
get_all_borrow_repair
(
db
)
# GET BY ID
@router.get
(
"/{borrowrepairId}"
,
response_model
=
BorrowRepairResponse
)
async
def
get_borrow_by_id_endpoint
(
borrowId
:
UUID
,
db
:
AsyncSession
=
Depends
(
get_db
)
):
tx
=
await
get_borrow_repair_by_id
(
db
,
borrowId
)
if
not
tx
:
raise
HTTPException
(
status_code
=
404
,
detail
=
"BorrowTransaction not found"
)
return
tx
# DELETE
@router.delete
(
"/{borrowrepairId}"
)
async
def
delete_borrow_endpoint
(
borrowId
:
UUID
,
db
:
AsyncSession
=
Depends
(
get_db
)
):
return
await
delete_borrow_repair
(
db
,
borrowId
)
# NEW API: Search BorrowTransactions by query parameters
@router.get
(
"/search/borrow"
,
response_model
=
List
[
BorrowRepairResponse
])
async
def
search_borrow_endpoint
(
member_id
:
Optional
[
UUID
]
=
None
,
peId
:
Optional
[
UUID
]
=
None
,
status
:
Optional
[
str
]
=
None
,
date_from
:
Optional
[
datetime
]
=
None
,
date_to
:
Optional
[
datetime
]
=
None
,
db
:
AsyncSession
=
Depends
(
get_db
)
):
results
=
await
search_borrow_repair
(
db
,
member_id
,
peId
,
status
,
date_from
,
date_to
)
return
results
\ No newline at end of file
API-Fast/src/schemas/equipment_repair_schema.py
0 → 100644
View file @
3f575b1c
# myproject/schemas/borrow_schema.py
from
pydantic
import
BaseModel
from
uuid
import
UUID
from
typing
import
Optional
from
datetime
import
datetime
from
.member_schema
import
MemberResponse
# Schema สำหรับ Member
from
.project_equipment_schema
import
ProjectEquipmentResponse
# Schema สำหรับ ProjectEquipment
class
BorrowRepairBase
(
BaseModel
):
peId
:
Optional
[
UUID
]
=
None
quantity_borrowed
:
int
status
:
str
=
"borrowed"
# เช่น requested, borrowed, returned
returned_date
:
Optional
[
datetime
]
=
None
memberId
:
UUID
approved_by
:
Optional
[
UUID
]
=
None
class
BorrowRepairCreate
(
BorrowRepairBase
):
peId
:
UUID
memberId
:
UUID
class
BorrowRepairResponse
(
BorrowRepairBase
):
borrowId
:
UUID
created_at
:
datetime
peId
:
UUID
memberId
:
UUID
# แสดงข้อมูลของสมาชิกที่เบิกอุปกรณ์ (จาก memberId)
member
:
Optional
[
MemberResponse
]
=
None
# แสดงข้อมูลของ project_equipment ที่ผูกกับ peId ซึ่งจะมีข้อมูลอุปกรณ์ (ผ่าน relationship ใน ORM)
project_equipment
:
Optional
[
ProjectEquipmentResponse
]
=
None
# แสดงข้อมูลของสมาชิกที่อนุมัติ (จาก approved_by)
approved_by_member
:
Optional
[
MemberResponse
]
=
None
class
Config
:
orm_mode
=
True
\ No newline at end of file
Web-Manage/src/app/DPU/company-management/admin-project-equirement/admin-project-equirement.component.html
View file @
3f575b1c
...
...
@@ -99,29 +99,38 @@
<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=
"box-footer border-block-start-dashed dark:border-defaultborder/10 text-center"
>
<div
class=
"btn-list"
>
<div
class=
"
btn-list"
>
<div
class=
"
flex justify-center gap-2"
>
<!-- เพิ่ม flex และ gap --
>
<button
data-hs-overlay=
"#modal-stock"
type=
"button"
aria-label=
"button"
(
click
)="
viewStock
(
item
)"
class=
"ti-btn ti-btn-sm ti-btn-
warning me-[0.375rem]
"
class=
"ti-btn ti-btn-sm ti-btn-
success
"
>
<i
class=
"ri-store-line"
></i>
</button>
<button
data-hs-overlay=
"#modal-stock-his"
(
click
)="
viewHisStock
(
item
)"
type=
"button"
aria-label=
"button"
class=
"ti-btn ti-btn-sm ti-btn-danger
me-0
"
class=
"ti-btn ti-btn-sm ti-btn-danger"
>
<i
class=
"ri-time-line"
></i>
</button>
<button
data-hs-overlay=
"#modal-repair"
type=
"button"
aria-label=
"button"
(
click
)="
viewStock
(
item
)"
class=
"ti-btn ti-btn-sm ti-btn-warning"
>
<i
class=
"ri-tools-line"
></i>
</button>
</div>
</div>
</div>
...
...
@@ -379,6 +388,113 @@
</div>
<!-- Start:: New Deal -->
<div
id=
"modal-repair"
class=
"hs-overlay hidden ti-modal"
*
ngIf=
"selectModel"
>
<div
class=
"hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out"
>
<div
class=
"ti-modal-content"
>
<div
class=
"ti-modal-header"
>
<h6
class=
"modal-title text-[1rem] font-semibold text-defaulttextcolor"
id=
"mail-ComposeLabel"
>
ซ่อม/ซำรุด
</h6>
<button
type=
"button"
class=
"hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay=
"#modal-repair"
>
<span
class=
"sr-only"
>
Close
</span>
<i
class=
"ri-close-line"
></i>
</button>
</div>
<div
class=
"ti-modal-body px-4"
>
<div
class=
"xl:col-span-12 col-span-12"
>
<img
[
src
]="
selectModel
.
equipment
.
getPicture
()"
class=
"!rounded-t-md"
alt=
"..."
style=
"width: 100%; height: auto; object-fit: cover"
/>
</div>
<div
class=
"grid grid-cols-12 gap-4"
>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"deal-name"
class=
"form-label"
>
ชื่ออุปกรณ์
</label>
<input
readonly
type=
"text"
class=
"form-control"
id=
"deal-name"
placeholder=
"ชื่ออุปกรณ์"
[(
ngModel
)]="
selectModel
.
equipment
.
equipmentName
"
/>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"deal-name"
class=
"form-label"
>
S/N
</label>
<input
readonly
type=
"text"
class=
"form-control"
id=
"deal-name"
placeholder=
"S/N"
[(
ngModel
)]="
selectModel
.
equipment
.
serialNumber
"
/>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"input-label"
class=
"form-label"
>
{{
"สถานะ" | translate
}}
</label>
<!-- <ng-select [items]="customerList" bindLabel="companyThName" [(ngModel)]="projectModel.customer">
</ng-select> -->
<select
class=
"mb-4 sm:mb-0 form-select !py-3"
id=
"inlineFormSelectPref"
[(
ngModel
)]="
borrowSelect
.
status
"
>
<option
ngValue=
"repair"
selected
>
ส่งซ่อม
</option>
<option
ngValue=
"remove"
selected
>
นำอุปกรณ์ออก
</option>
</select>
<!-- <select class="mb-4 sm:mb-0 form-select !py-3" id="inlineFormSelectPref"
[(ngModel)]="projectModel.customer">
<option [ngValue]="null" selected>-</option>
<option *ngFor="let item of customerList" [ngValue]="item">{{item.getCompanyName()}}</option>
</select> -->
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"deal-name"
class=
"form-label"
>
จำนวน
</label>
<input
type=
"number"
class=
"form-control"
id=
"deal-name"
placeholder=
"จำนวนที่ชำรุด"
[(
ngModel
)]="
borrowSelect
.
quantity_borrowed
"
/>
</div>
</div>
</div>
<div
class=
"ti-modal-footer"
>
<button
#
closeModalStock
type=
"button"
class=
"hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay=
"#modal-repair"
>
ยกเลิก
</button>
<button
type=
"button"
class=
"ti-btn bg-primary text-white !font-medium"
(
click
)="
saveRepair
()"
>
บันทึก
</button>
</div>
</div>
</div>
</div>
<!-- Start:: New Deal -->
<div
id=
"modal-stock-his"
class=
"hs-overlay hidden ti-modal"
...
...
Web-Manage/src/app/DPU/company-management/admin-project-equirement/admin-project-equirement.component.ts
View file @
3f575b1c
...
...
@@ -279,6 +279,37 @@ export class AdminProjectEquirementComponent {
}
saveRepair
()
{
// console.log(this.selectStock)
swal
({
title
:
"Are you sure?"
,
text
:
"คุณต้องการบันทึกหรือไม่"
,
icon
:
"warning"
,
dangerMode
:
false
,
buttons
:
[
"Cancel"
,
"Confirm"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
this
.
borrowTransactionsService
.
save
({
"peId"
:
this
.
selectModel
.
peId
,
"quantity_borrowed"
:
this
.
borrowSelect
.
quantity_borrowed
,
"status"
:
this
.
borrowSelect
.
status
,
"memberId"
:
this
.
tokenService
.
getUser
().
member
.
memberId
,
"approved_by"
:
this
.
tokenService
.
getUser
().
member
.
memberId
}).
subscribe
(
result
=>
{
swal
(
"Save Success!!"
,
"บันทึกข้อมูลสำเร็จ"
,
"success"
);
this
.
ngOnInit
()
this
.
closeModalStock
?.
nativeElement
.
click
()
},
(
error
:
any
)
=>
{
swal
(
"Fail!!"
,
error
.
error
.
detail
,
"info"
);
})
}
});
}
stock
(
item
:
EquipmentModel
)
{
if
(
item
.
quantity
>
0
)
{
swal
({
...
...
Web-Manage/src/app/DPU/company-management/admin-project-home/admin-project-home.component.html
View file @
3f575b1c
<app-page-header
[
title
]="'
จัดการโครงการ'"
[
activeTitle
]="'ผู้ดูแลระบบ'"
[
title1
]="'จัดการ
โครงการ'"
></app-page-header>
<app-page-header
[
title
]="'
เลือกโครงการ'"
[
activeTitle
]="'ผู้ดูแลโปรเจค'"
[
title1
]="'เลือก
โครงการ'"
></app-page-header>
<div
class=
"grid grid-cols-12 gap-6"
>
...
...
@@ -10,10 +10,10 @@
class=
"badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>
{{itemsList.length}}
</span>
</div>
<div
class=
"flex flex-wrap gap-2"
>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-primary-full me-2"
(
click
)="
new
()"
<
!--<
a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-primary-full me-2" (click)="new()"
data-hs-overlay="#modal-detail"><i class="ri-add-line font-semibold align-middle"></i>{{ 'Create' |
translate}}
</a>
</a>
-->
<!-- <a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-success-full me-2" *ngIf="someSelected"
(click)="adjustSelect(1)"><i class="ri-user-follow-line font-semibold align-middle"></i>{{ 'Active' |
...
...
@@ -26,10 +26,10 @@
</a> -->
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-danger-full me-2"
*
ngIf=
"someSelected"
<
!-- <
a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-danger-full me-2" *ngIf="someSelected"
(click)="deleteSelect()"><i class="ri-delete-bin-line font-semibold align-middle"></i>{{ 'Delete' |
translate}}
</a>
</a>
-->
<div>
<input
class=
"form-control form-control"
type=
"text"
placeholder=
"ค้นหาโครงการ"
aria-label=
".form-control-sm example"
[(
ngModel
)]='
searchTerm
'
>
...
...
@@ -69,7 +69,7 @@
class=
"font-semibold text-[.875rem] block text-truncate project-list-title"
>
{{item.project_name}}
</a>
<span
class=
"text-[#8c9097] dark:text-white/50 block text-[0.75rem]"
>
{{item.project_code}}
</span>
</div>
<div
class=
"hs-dropdown ti-dropdown"
>
<
!-- <
div class="hs-dropdown ti-dropdown">
<a aria-label="anchor" href="javascript:void(0);" class="ti-btn ti-btn-sm ti-btn-light !mb-0"
aria-expanded="false">
<i class="fe fe-more-vertical"></i>
...
...
@@ -82,7 +82,7 @@
<li><a class="ti-dropdown-item" (click)="delete(item)"><i
class="ri-delete-bin-line me-1 align-middle inline-flex"></i>Delete</a></li>
</ul>
</div>
</div>
-->
</div>
<div
class=
"box-body"
>
...
...
Web-Manage/src/app/DPU/company-management/admin-project-home/admin-project-home.component.ts
View file @
3f575b1c
import
{
map
}
from
'rxjs/operators'
;
import
{
ProjectMemberModel
}
from
'./../../models/project-members'
;
import
{
ProjectMemberService
}
from
'./../../services/project-members.service'
;
import
{
Component
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
import
{
DomSanitizer
,
SafeHtml
}
from
'@angular/platform-browser'
;
import
{
RouterModule
}
from
'@angular/router'
;
...
...
@@ -49,6 +52,8 @@ export class AdminProjectHomeComponent {
pageIndex
=
0
;
uploaderProfile
:
FileUploader
|
undefined
;
uploadErrorMsg
:
string
=
""
;
projectId
=
""
projectList
:
ProjectModel
[]
get
searchTerm
():
string
{
return
this
.
_searchTerm
;
}
...
...
@@ -64,10 +69,11 @@ export class AdminProjectHomeComponent {
}
_searchTerm
=
""
;
constructor
(
private
projectService
:
ProjectService
,
public
translate
:
TranslateService
,
private
tokenService
:
TokenService
)
{
constructor
(
private
project
MemberService
:
ProjectMemberService
,
private
project
Service
:
ProjectService
,
public
translate
:
TranslateService
,
private
tokenService
:
TokenService
)
{
this
.
uploadConfig
()
}
uploadConfig
()
{
this
.
uploaderProfile
=
new
FileUploader
({
url
:
environment
.
baseUrl
+
"/api/upload-image"
,
...
...
@@ -120,12 +126,29 @@ export class AdminProjectHomeComponent {
}
ngOnInit
():
void
{
this
.
projectService
.
getLists
().
subscribe
(
result
=>
{
this
.
itemsList
=
result
this
.
updatePagedItems
()
})
const
user
=
this
.
tokenService
.
getUser
();
const
memberId
=
user
?.
member
?.
memberId
;
if
(
memberId
)
{
// ดึงรายการ ProjectMemberModel ที่ user นี้ถูก assign ไว้
this
.
projectMemberService
.
getCompanyAdmin
(
memberId
).
subscribe
((
memberProjects
:
ProjectMemberModel
[])
=>
{
const
allowedProjectIds
=
memberProjects
.
filter
(
pm
=>
!!
pm
.
projectId
)
.
map
(
pm
=>
pm
.
projectId
);
// ดึงรายการโปรเจกต์ทั้งหมด แล้วกรองตามที่ admin assign ให้
this
.
projectService
.
getLists
().
subscribe
((
allProjects
:
ProjectModel
[])
=>
{
this
.
itemsList
=
allProjects
.
filter
(
p
=>
p
.
projectId
&&
allowedProjectIds
.
includes
(
p
.
projectId
)
);
this
.
updatePagedItems
();
});
});
}
}
filter
(
v
:
string
)
{
return
this
.
itemsList
?.
filter
(
(
x
)
=>
...
...
@@ -295,4 +318,4 @@ export class AdminProjectHomeComponent {
// }
}
Web-Manage/src/app/DPU/company-management/emp-borrow-repair/emp-borrow-repair.component.html
0 → 100644
View file @
3f575b1c
<app-page-header
[
title
]="'อนุมัติการคืนอุปกรณ์'"
[
activeTitle
]="'ผู้ดูแลระบบ'"
[
title1
]="'อนุมัติการคืนอุปกรณ์'"
></app-page-header>
<div
class=
"grid grid-cols-12 gap-x-6"
>
<div
class=
"xl:col-span-12 col-span-12"
>
<div
class=
"box mt-6"
>
<div
class=
"box-header justify-between"
>
<div
class=
"box-title"
>
{{ "รายการทั้งหมด" | translate }}
<span
class=
"badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>
{{ filteredList.length }}
</span
>
</div>
<!-- แท็บสถานะ -->
<div
class=
"flex flex-wrap gap-2"
>
<!-- สถานะทั้งหมด -->
<div>
<button
class=
"px-4 py-2 rounded-full border text-sm font-medium bg-blue-100 text-blue-800 border-blue-200"
(
click
)="
selectedStatus =
'!requested,!rejected'
;
applyFilter
()"
>
ทั้งหมด
</button>
</div>
<div>
<button
class=
"px-4 py-2 rounded-full border text-sm font-medium bg-warning/10 text-warning border-warning/20"
(
click
)="
selectedStatus =
'approved'
;
applyFilter
()"
>
รอคืนอุปกรณื
</button>
</div>
<!-- <div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-success/10 text-success border-success/20"
(click)="filterByStatus('approved')"
>
อนุมัติแล้ว
</button>
</div> -->
<div>
<button
class=
"px-4 py-2 rounded-full border text-sm font-medium bg-info/10 text-info border-info/20"
(
click
)="
selectedStatus =
'returned'
;
applyFilter
()"
>
คืนแล้ว
</button>
</div>
<!-- <div>
<button
class="px-4 py-2 rounded-full border text-sm font-medium bg-danger/10 text-danger border-danger/20"
(click)="filterByStatus('rejected')"
>
ไม่อนุมัติ
</button>
</div> -->
</div>
<div
class=
"flex flex-wrap gap-2"
>
<div>
<input
[(
ngModel
)]="
searchTerm
"
class=
"form-control form-control"
type=
"text"
placeholder=
"{{ 'ค้นหารายการ...' | translate }}"
aria-label=
".form-control-sm example"
(
input
)="
applyFilter
()"
/>
</div>
</div>
</div>
<div
class=
"box-body"
>
<div
class=
"table-responsive"
>
<table
class=
"table whitespace-nowrap table-bordered min-w-full"
>
<thead
class=
"bg-light"
>
<tr>
<th
scope=
"col"
class=
"text-start"
>
โปรเจค
</th>
<th
scope=
"col"
class=
"text-start"
>
อุปกรณ์ที่ยืม
</th>
<th
scope=
"col"
class=
"text-start"
>
พนักงาน
</th>
<th
scope=
"col"
class=
"text-start"
>
จำนวน
</th>
<th
scope=
"col"
class=
"text-start"
>
วันที่ยืม
</th>
<th
scope=
"col"
class=
"text-start"
>
วันที่คืน
</th>
<th
scope=
"col"
class=
"text-start"
>
สถานะ
</th>
<th
scope=
"col"
class=
"text-start"
>
ผู้อนุมัติ
</th>
<th
scope=
"col"
class=
"text-start"
>
การดำเนินการ
</th>
</tr>
</thead>
<tbody>
@for(product of filteredList;track filterList){
<tr
class=
"product-list"
>
<td>
{{ product.project_equipment?.project?.project_name }}
</td>
<td>
{{ product.project_equipment?.equipment?.equipmentName }}
</td>
<td>
<div
class=
"flex items-center"
>
<div
class=
"font-semibold"
>
{{ product.member?.getFullname() }}
</div>
</div>
</td>
<td>
{{ product.quantity_borrowed }}
</td>
<td>
{{ product.created_at | date : "dd/MM/yyyy HH:mm" }}
</td>
<td>
@if(product.returned_date) {
{{ product.returned_date | date : "dd/MM/yyyy HH:mm" }}
}
</td>
<td>
<span
class=
"badge"
[
ngClass
]="{
'
bg-warning
/
10
text-warning
'
:
product
.
status =
==
'
approved
',
'
bg-danger
/
10
text-danger
'
:
product
.
status =
==
'
rejected
',
'
bg-info
/
10
text-info
'
:
product
.
status =
==
'
returned
',
}"
>
{{ getStatusText(product.status) }}
</span>
</td>
<td>
{{ product.approved_by_member?.getFullname()}}
</td>
<td>
<div
class=
"flex gap-1"
>
<!-- ปุ่มอนุมัติการคืน -->
@if(product.project_equipment?.equipment?.is_returnable
&&
product.status === 'approved'
&&
!product.returned_date) {
<button
aria-label=
"อนุมัติการคืน"
(
click
)="
view
(
product
)"
class=
"ti-btn ti-btn-sm ti-btn-success"
data-hs-overlay=
"#detail-container"
>
<i
class=
"ri-check-line"
></i>
</button>
}
<!-- ปุ่มแจ้งซ่อม -->
@if(product.project_equipment?.equipment?.is_returnable
&&
(product.status === 'returned' || product.status ===
'returned')) {
<button
aria-label=
"แจ้งซ่อม"
(
click
)="
reportRepair
(
product
)"
class=
"ti-btn ti-btn-sm ti-btn-warning"
>
<i
class=
"ri-tools-line"
></i>
</button>
} @if(product.status === 'approved' || product.status ===
'returned'){
<button
aria-label=
"รายละเอียด"
(
click
)="
view
(
product
)"
class=
"ti-btn ti-btn-sm ti-btn-light me-[0.375rem]"
data-hs-overlay=
"#detail-borrow"
>
<i
class=
"fe fe-eye"
></i>
</button>
}
</div>
</td>
</tr>
}
</tbody>
</table>
<div
class=
"box-footer"
>
<div
class=
"flex items-center flex-wrap overflow-auto"
*
ngIf=
"filteredList.length > 0"
>
<div
class=
"mb-2 sm:mb-0"
>
<div>
{{'Showing' | translate}} {{filteredList.length}} {{'entries'
| translate}}
<i
class=
"bi bi-arrow-right ms-2 font-semibold"
></i>
</div>
</div>
<div
class=
"ms-auto"
>
<nav
aria-label=
"Page navigation"
>
<ul
class=
"ti-pagination mb-0"
>
<li
*
ngIf=
"pageIndex>0"
class=
"page-item {{pageIndex==0 ? 'disabled' : ''}}"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{'Previous' | translate}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex-1>0"
(
click
)="
pageIndex =
pageIndex-2;updatePagedItems()"
>
{{pageIndex-1}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex>0 && ((pageIndex-1)*10 < (searchTerm == '' ? itemsList.length : filterList.length))"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{pageIndex}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link active px-3 py-[0.375rem]"
href=
"javascript:void(0);"
>
{{pageIndex +1}}
</a>
</li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{pageIndex +2}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+2)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+2;updatePagedItems()"
>
{{pageIndex +3}}
</a></li>
<li
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{'Next' |
translate}}
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
id=
"detail-container"
class=
"hs-overlay hidden ti-modal"
*
ngIf=
"selectedBorrowItem as item"
>
<div
class=
"hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out"
>
<div
class=
"ti-modal-content"
>
<div
class=
"ti-modal-header"
>
<h6
class=
"modal-title text-[1rem] font-semibold text-defaulttextcolor"
id=
"mail-ComposeLabel"
>
รายละเอียดการยืม
</h6>
<button
type=
"button"
class=
"hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay=
"#detail-container"
>
<span
class=
"sr-only"
>
Close
</span>
<i
class=
"ri-close-line"
></i>
</button>
</div>
<div
class=
"ti-modal-body px-4"
>
<div
class=
"grid grid-cols-12 gap-4"
>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"deal-name"
class=
"form-label"
>
ชื่ออุปกรณ์
</label>
<input
readonly
type=
"text"
class=
"form-control"
id=
"deal-name"
placeholder=
"ชื่ออุปกรณ์"
[
ngModel
]="
selectedBorrowItem
.
project_equipment
.
equipment
.
equipmentName
"
/>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
for=
"deal-name"
class=
"form-label"
>
จำนวน
</label>
<input
type=
"number"
class=
"form-control"
id=
"quantity"
placeholder=
"จำนวน"
[(
ngModel
)]="
selectedBorrowItem
.
quantity_borrowed
"
/>
</div>
</div>
<div
class=
"ti-modal-footer"
>
<button
#
closeModalStock
type=
"button"
class=
"hs-dropdown-toggle ti-btn ti-btn-light align-middle"
data-hs-overlay=
"#detail-container"
>
ยกเลิก
</button>
<button
type=
"button"
class=
"ti-btn bg-primary text-white !font-medium"
data-hs-overlay=
"#detail-container"
(
click
)="
approve
(
item
)"
>
บันทึก
</button>
</div>
</div>
</div>
</div>
</div>
<div
id=
"detail-borrow"
class=
"hs-overlay hidden ti-modal"
*
ngIf=
"selectedBorrowItem"
>
<div
class=
"hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out"
>
<div
class=
"ti-modal-content"
>
<div
class=
"ti-modal-header"
>
<h6
class=
"modal-title text-[1rem] font-semibold text-defaulttextcolor"
>
รายละเอียดการยืม
</h6>
<button
type=
"button"
class=
"hs-dropdown-toggle !text-[1rem] !font-semibold !text-defaulttextcolor"
data-hs-overlay=
"#detail-borrow"
>
<span
class=
"sr-only"
>
Close
</span>
<i
class=
"ri-close-line"
></i>
</button>
</div>
<div
class=
"ti-modal-body px-4"
>
<div
class=
"grid grid-cols-12 gap-4"
>
<!-- ข้อมูลผู้ยืม -->
<div
class=
"xl:col-span-12 col-span-12"
>
<label
class=
"form-label"
>
ชื่อผู้ยืม
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
member
.
getFullname
()
||
'
-
'"
/>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
class=
"form-label"
>
เบอร์โทรติดต่อ
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
member
.
phoneNumber
||
'
-
'"
/>
</div>
<!-- ข้อมูลอุปกรณ์ -->
<div
class=
"xl:col-span-12 col-span-12"
>
<label
class=
"form-label"
>
ชื่ออุปกรณ์
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
project_equipment
.
equipment
.
equipmentName
"
/>
</div>
<div
class=
"xl:col-span-12 col-span-12"
>
<label
class=
"form-label"
>
ชื่อโปรเจค
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
project_equipment
.
project
.
project_name
"
/>
</div>
<!-- จำนวน -->
<div
class=
"xl:col-span-12 col-span-12"
>
<label
class=
"form-label"
>
จำนวน
</label>
<input
readonly
type=
"number"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
quantity_borrowed
||
'
0
'"
/>
</div>
<!-- วันที่ยืม -->
<div
class=
"xl:col-span-6 col-span-12"
>
<label
class=
"form-label"
>
วันที่ยืม
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
created_at
?
(
selectedBorrowItem
.
created_at
|
date
:
'
dd
/
MM
/
yyyy
HH:mm
')
:
'
-
'
"
/>
</div>
<!-- วันที่คืน -->
<div
class=
"xl:col-span-6 col-span-12"
>
<label
class=
"form-label"
>
วันที่คืน
</label>
<input
readonly
type=
"text"
class=
"form-control"
[
value
]="
selectedBorrowItem
.
returned_date
?
(
selectedBorrowItem
.
returned_date
|
date
:
'
dd
/
MM
/
yyyy
HH:mm
')
:
'
-
'
"
/>
</div>
</div>
</div>
<div
class=
"ti-modal-footer"
>
<button
type=
"button"
class=
"ti-btn ti-btn-light align-middle"
data-hs-overlay=
"#detail-borrow"
>
ปิด
</button>
</div>
</div>
</div>
</div>
Web-Manage/src/app/DPU/company-management/emp-borrow-repair/emp-borrow-repair.component.scss
0 → 100644
View file @
3f575b1c
Web-Manage/src/app/DPU/company-management/emp-borrow-repair/emp-borrow-repair.component.ts
0 → 100644
View file @
3f575b1c
import
{
UserModel
}
from
'./../../../shared/user-auth.model'
;
import
{
ProjectEquipmentService
}
from
'./../../services/project-equipments.service'
;
import
{
ProjectMemberService
}
from
'./../../services/project-members.service'
;
import
{
filter
}
from
'rxjs/operators'
;
import
{
CommonModule
}
from
"@angular/common"
;
import
{
Component
,
ViewChild
,
ElementRef
}
from
'@angular/core'
;
import
{
NgSelectModule
}
from
"@ng-select/ng-select"
;
import
{
TranslateModule
,
TranslateService
}
from
"@ngx-translate/core"
;
import
{
FormsModule
}
from
"@angular/forms"
;
import
swal
from
'sweetalert'
;
import
{
SharedModule
}
from
"../../../shared/shared.module"
;
import
{
TokenService
}
from
"../../../shared/services/token.service"
;
import
{
BorrowTransactionsService
}
from
'../../services/borrow-transactions.service'
;
import
{
BorrowTransactionsModel
}
from
'../../models/borrow-transactions'
;
import
{
EquipmentService
}
from
"../../services/equirement.service"
;
import
{
EquipmentModel
,
EquipmentStockModel
}
from
"../../models/equipments.model"
;
import
{
ProjectEquipmentModel
}
from
"../../models/project-equipments"
;
import
{
ProjectMemberModel
}
from
'../../models/project-members'
;
import
{
HttpClient
}
from
'@angular/common/http'
;
import
{
ProjectModel
}
from
'../../models/project.model'
;
import
{
ChangeDetectorRef
}
from
'@angular/core'
;
import
{
Subject
}
from
'rxjs'
;
import
{
takeUntil
}
from
'rxjs/operators'
;
import
{
UserProfileModel
}
from
'../../models/user.model'
;
@
Component
({
selector
:
'app-emp-borrow-repair'
,
templateUrl
:
'./emp-borrow-repair.component.html'
,
styleUrls
:
[
'./emp-borrow-repair.component.css'
]
})
export
class
EmpBorrowRepairComponent
implements
OnInit
{
constructor
()
{
}
ngOnInit
()
{
}
}
Web-Manage/src/app/DPU/company-management/emp-borrow-return-status/emp-borrow-return-status.component.html
View file @
3f575b1c
...
...
@@ -144,7 +144,7 @@
<!-- ปุ่มแจ้งซ่อม -->
@if(product.project_equipment?.equipment?.is_returnable
&&
(product.status === '
approv
ed' || product.status ===
(product.status === '
return
ed' || product.status ===
'returned')) {
<button
aria-label=
"แจ้งซ่อม"
...
...
@@ -170,6 +170,47 @@
}
</tbody>
</table>
<div
class=
"box-footer"
>
<div
class=
"flex items-center flex-wrap overflow-auto"
*
ngIf=
"filteredList.length > 0"
>
<div
class=
"mb-2 sm:mb-0"
>
<div>
{{'Showing' | translate}} {{filteredList.length}} {{'entries'
| translate}}
<i
class=
"bi bi-arrow-right ms-2 font-semibold"
></i>
</div>
</div>
<div
class=
"ms-auto"
>
<nav
aria-label=
"Page navigation"
>
<ul
class=
"ti-pagination mb-0"
>
<li
*
ngIf=
"pageIndex>0"
class=
"page-item {{pageIndex==0 ? 'disabled' : ''}}"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{'Previous' | translate}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex-1>0"
(
click
)="
pageIndex =
pageIndex-2;updatePagedItems()"
>
{{pageIndex-1}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex>0 && ((pageIndex-1)*10 < (searchTerm == '' ? itemsList.length : filterList.length))"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{pageIndex}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link active px-3 py-[0.375rem]"
href=
"javascript:void(0);"
>
{{pageIndex +1}}
</a>
</li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{pageIndex +2}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+2)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
(
click
)="
pageIndex =
pageIndex+2;updatePagedItems()"
>
{{pageIndex +3}}
</a></li>
<li
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filterList.length)"
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{'Next' |
translate}}
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
Web-Manage/src/app/DPU/company-management/emp-borrow-return-status/emp-borrow-return-status.component.ts
View file @
3f575b1c
...
...
@@ -21,6 +21,7 @@ import { ProjectModel } from '../../models/project.model';
import
{
ChangeDetectorRef
}
from
'@angular/core'
;
import
{
Subject
}
from
'rxjs'
;
import
{
takeUntil
}
from
'rxjs/operators'
;
import
{
UserProfileModel
}
from
'../../models/user.model'
;
...
...
@@ -47,7 +48,7 @@ export class EmpBorrowReturnStatusComponent {
Projecteqlist
:
ProjectEquipmentModel
;
projecteMember
:
ProjectMemberModel
;
selectedBorrowItem
:
BorrowTransactionsModel
;
projectList
:
ProjectModel
;
projectList
:
ProjectModel
;
allSelected
=
false
;
someSelected
=
false
;
uploadErrorMsg
:
string
=
""
;
...
...
@@ -61,6 +62,7 @@ export class EmpBorrowReturnStatusComponent {
borrowSelect
:
BorrowTransactionsModel
=
new
BorrowTransactionsModel
()
filteredList
:
any
[]
=
[];
pageIndex
=
0
;
member
:
UserProfileModel
;
get
searchTerm
():
string
{
return
this
.
_searchTerm
;
}
...
...
@@ -78,7 +80,7 @@ export class EmpBorrowReturnStatusComponent {
_searchTerm
=
""
;
isEdit
=
false
;
empList
:
ProjectMemberModel
[]
=
[]
hisList
:
BorrowTransactionsModel
[]
=
[];
hisList
:
BorrowTransactionsModel
[]
=
[];
selectedStatus
:
string
=
'!requested,!rejected'
;
isProcessing
=
false
;
constructor
(
...
...
@@ -217,7 +219,7 @@ export class EmpBorrowReturnStatusComponent {
}
getStatusText
(
status
:
string
):
string
{
switch
(
status
)
{
switch
(
status
)
{
case
'requested'
:
return
'รออนุมัติ'
;
case
'approved'
:
return
'รอคืนอุปกรณ์'
;
case
'rejected'
:
return
'ไม่อนุมัติ'
;
...
...
@@ -237,7 +239,7 @@ export class EmpBorrowReturnStatusComponent {
}
viewHisStock
(
item
:
ProjectEquipmentModel
)
{
this
.
borrowTransactionsService
.
search
({
"peId"
:
item
.
peId
,
"member_id"
:
this
.
tokenService
.
getUser
().
member
.
memberId
}).
subscribe
(
result
=>
{
this
.
borrowTransactionsService
.
search
({
"peId"
:
item
.
peId
,
"member_id"
:
this
.
tokenService
.
getUser
().
member
.
memberId
}).
subscribe
(
result
=>
{
this
.
hisList
=
result
})
}
...
...
@@ -333,57 +335,74 @@ export class EmpBorrowReturnStatusComponent {
title
:
"แจ้งซ่อมอุปกรณ์"
,
text
:
`คุณต้องการแจ้งซ่อมอุปกรณ์
${
item
.
project_equipment
?.
equipment
?.
equipmentName
}
หรือไม่
?
`,
content: {
element: "input",
attributes: {
placeholder: "ระบุอาการเสีย/ปัญหาที่พบ",
type: "text",
},
element: this.createRepairForm(item.quantity_borrowed) // << ส่งจำนวนยืมเข้าไป
},
icon: "warning",
buttons: ["ยกเลิก", "แจ้งซ่อม"],
}).then((repairDescription) => {
if (repairDescription) {
}).then((confirmed) => {
if (confirmed) {
const description = (document.getElementById("repairDescription") as HTMLInputElement).value;
const quantity = +(document.getElementById("repairQuantity") as HTMLInputElement).value;
if (!description || quantity <= 0) {
swal("กรุณากรอกข้อมูลให้ครบถ้วน", "", "error");
return;
}
const repairData = {
borrowTransactionId: item.borrowId,
equipmentId: item.project_equipment?.equipment?.equipmentId,
reportedBy: this.tokenService.getUser().member.memberId,
description:
repairDescription
,
description:
`
$
{
description
}
(
จำนวน
$
{
quantity
})
`
,
status: 'pending'
};
// อัปเดตสถานะการยืมเป็น repairing
const updateBorrowData = {
status: 'repairing'
};
// // สร้างรายการซ่อม
// this.equipmentRepairService.create(repairData).subscribe(
// (result) => {
// // อัปเดตสถานะการยืม
// this.borrowTransactionsService.update(item.borrowId, updateBorrowData).subscribe(
// (updateResult) => {
// swal("แจ้งซ่อมสำเร็จ", "ระบบได้บันทึกการแจ้งซ่อมแล้ว", "success");
// this.loadReturnList();
// },
// (updateError) => {
// swal("เกิดข้อผิดพลาด", "ไม่สามารถอัปเดตสถานะการยืมได้", "error");
// }
// );
// },
// (result) => {
// swal("เกิดข้อผิดพลาด", "ไม่สามารถแจ้งซ่อมได้", "error");
// }
// );
// เรียก service เพื่อบันทึกการแจ้งซ่อม...
}
});
}
private createRepairForm(defaultQuantity: number): HTMLElement {
const wrapper = document.createElement("div");
const qtyInput = document.createElement("input");
qtyInput.id = "repairQuantity";
qtyInput.placeholder = "จำนวนที่แจ้งซ่อม";
qtyInput.type = "number";
qtyInput.min = "1";
qtyInput.className = "swal-content__input";
qtyInput.style.marginTop = "10px";
qtyInput.value = defaultQuantity?.toString() || '1';
const descInput = document.createElement("input");
descInput.id = "repairDescription";
descInput.placeholder = "ระบุอาการเสีย/ปัญหาที่พบ";
descInput.type = "text";
descInput.className = "swal-content__input";
wrapper.appendChild(descInput);
wrapper.appendChild(qtyInput);
return wrapper;
}
updatePagedItems() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
this.filterList = this.itemsList
const endIndex = startIndex + 10;
const source = this.searchTerm
? this.itemsList.filter(x => x.equipment?.equipmentName?.includes(this.searchTerm))
: this.itemsList;
this.filterList = source.slice(startIndex, endIndex);
}
updatePagedItemsAll() {
const startIndex = this.pageIndex * 10;
const endIndex = startIndex + 10;
...
...
Web-Manage/src/app/DPU/company-management/emp-borrow-status/emp-borrow-status.component.html
View file @
3f575b1c
...
...
@@ -135,6 +135,46 @@
}
</tbody>
</table>
<div
class=
"box-footer"
>
<div
class=
"flex items-center flex-wrap overflow-auto"
*
ngIf=
"filteredList.length > 0"
>
<div
class=
"mb-2 sm:mb-0"
>
<div>
{{'Showing' | translate}} {{filteredList.length}} {{'entries'
| translate}}
<i
class=
"bi bi-arrow-right ms-2 font-semibold"
></i>
</div>
</div>
<div
class=
"ms-auto"
>
<nav
aria-label=
"Page navigation"
>
<ul
class=
"ti-pagination mb-0"
>
<li
*
ngIf=
"pageIndex>0"
class=
"page-item {{pageIndex==0 ? 'disabled' : ''}}"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{'Previous' | translate}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex-1>0"
(
click
)="
pageIndex =
pageIndex-2;updatePagedItems()"
>
{{pageIndex-1}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"pageIndex>0 && ((pageIndex-1)*10 < (searchTerm == '' ? itemsList.length : filterList.length))"
(
click
)="
pageIndex =
pageIndex-1;updatePagedItems()"
>
{{pageIndex}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link active px-3 py-[0.375rem]"
href=
"javascript:void(0);"
>
{{pageIndex +1}}
</a>
</li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filteredList.length)"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{pageIndex +2}}
</a></li>
<li
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
href=
"javascript:void(0);"
*
ngIf=
"(pageIndex+2)*10 < (searchTerm == '' ? itemsList.length : filteredList.length)"
(
click
)="
pageIndex =
pageIndex+2;updatePagedItems()"
>
{{pageIndex +3}}
</a></li>
<li
*
ngIf=
"(pageIndex+1)*10 < (searchTerm == '' ? itemsList.length : filteredList.length)"
class=
"page-item"
><a
class=
"page-link px-3 py-[0.375rem]"
(
click
)="
pageIndex =
pageIndex+1;updatePagedItems()"
>
{{'Next' |
translate}}
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
</div>
...
...
Web-Manage/src/app/DPU/company-management/emp-borrow-status/emp-borrow-status.component.ts
View file @
3f575b1c
...
...
@@ -83,6 +83,8 @@ export class EmpBorrowStatusComponent {
ngOnInit
():
void
{
this
.
loadBorrowHistory
();
this
.
filterList
=
[...
this
.
itemsList
];
this
.
updatePagedItems
()
}
loadBorrowHistory
():
void
{
...
...
@@ -183,12 +185,17 @@ export class EmpBorrowStatusComponent {
x
.
equipment
.
description
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
);
}
updatePagedItems
()
{
updatePagedItems
()
{
const
startIndex
=
this
.
pageIndex
*
10
;
const
endIndex
=
startIndex
+
10
;
// this.filterList = this.itemsList.slice(startIndex, endIndex);
this
.
filterList
=
this
.
itemsList
const
endIndex
=
startIndex
+
10
;
const
source
=
this
.
searchTerm
?
this
.
itemsList
.
filter
(
x
=>
x
.
peId
?.
includes
(
this
.
searchTerm
))
:
this
.
itemsList
;
this
.
filterList
=
source
.
slice
(
startIndex
,
endIndex
);
}
updatePagedItemsAll
()
{
const
startIndex
=
this
.
pageIndex
*
10
;
const
endIndex
=
startIndex
+
10
;
...
...
Web-Manage/src/app/DPU/company-management/emp-borrow-transaction/emp-borrow-transaction.component.html
View file @
3f575b1c
<app-page-header
[
title
]="'
จัดการสมาชิก'"
[
activeTitle
]="'ผู้ดูแลระบบ'"
[
title1
]="'จัดการสมาชิก
'"
></app-page-header>
<app-page-header
[
title
]="'
ประวัติการทำรายการ'"
[
activeTitle
]="'ผู้ใช้งานทั่วไป'"
[
title1
]="'ประวัติการทำรายการ
'"
></app-page-header>
<div
class=
"grid grid-cols-12 gap-6"
>
...
...
@@ -10,11 +10,11 @@
class=
"badge bg-light text-default rounded-full ms-1 text-[0.75rem] align-middle"
>
{{itemsList.length}}
</span>
</div>
<div
class=
"flex flex-wrap gap-2"
>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-primary-full me-2"
(
click
)="
new
()"
<
!-- <
a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-primary-full me-2" (click)="new()"
data-hs-overlay="#modal-detail"><i class="ri-add-line font-semibold align-middle"></i>{{ 'Create' |
translate}}
</a>
<a
href=
"javascript:void(0);"
class=
"hs-dropdown-toggle ti-btn ti-btn-success-full me-2"
*
ngIf=
"someSelected"
</a>
-->
<
!-- <
a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-success-full me-2" *ngIf="someSelected"
(click)="adjustSelect(1)"><i class="ri-user-follow-line font-semibold align-middle"></i>{{ 'Active' |
translate}}
</a>
...
...
@@ -28,7 +28,7 @@
<a href="javascript:void(0);" class="hs-dropdown-toggle ti-btn ti-btn-danger-full me-2" *ngIf="someSelected"
(click)="deleteSelect()"><i class="ri-delete-bin-line font-semibold align-middle"></i>{{ 'Delete' |
translate}}
</a>
</a>
-->
<div>
<input
class=
"form-control form-control"
type=
"text"
placeholder=
"ค้นหาสมาชิก"
aria-label=
".form-control-sm example"
[(
ngModel
)]='
searchTerm
'
>
...
...
@@ -55,18 +55,16 @@
<input
class=
"form-check-input check-all"
type=
"checkbox"
id=
"all-products"
(
change
)="
toggleAll
($
event
)"
[
checked
]="
allSelected
"
aria-label=
"..."
>
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Username' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Fullname' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Email' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Mobile' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'User Group' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Borrowed equipment' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Amount' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Borrow Date' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Date return' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Status' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Update Date' | translate}}
</th>
<th
scope=
"col"
class=
"text-start"
></th>
<th
scope=
"col"
class=
"text-start"
>
{{ 'Approver' | translate}}
</th>
</tr>
</thead>
<tbody>
@for(item of filterList;track
filterList
){
@for(item of filterList;track
item.peId
){
<tr
class=
"border border-defaultborder dark:border-defaultborder/10"
>
<td
class=
"product-checkbox"
><input
class=
"form-check-input"
type=
"checkbox"
[
checked
]="
selectedItems
.
get
(
item
.
memberId
)"
...
...
@@ -74,14 +72,14 @@
</td>
<td>
<div
class=
"flex items-center"
>
<span
class=
"avatar avatar-sm p-1 me-1 bg-light !rounded-full"
>
<
!-- <
span class="avatar avatar-sm p-1 me-1 bg-light !rounded-full">
<img
[src]="item.getPicture()"
alt="" id="profile-img">
</span>
</span>
-->
<div
class=
"ms-2"
>
<p
class=
"font-semibold mb-0 flex items-center text-primary"
><a
(
click
)="
view
(
item
)"
>
{{item.
usern
ame}}
</a></p>
<p
class=
"font-semibold mb-0 flex items-center text-primary"
><a>
{{item.
project_equipment.equipment.equipmentN
ame}}
</a></p>
<p
class=
"text-[0.75rem] text-muted mb-0"
>
{{item.memberId}}
</p>
</div>
</div>
...
...
@@ -97,30 +95,37 @@
</div>
</div>
</td> -->
<td>
{{item.
firstName}} {{item.lastName
}}
</td>
<td>
{{item.
quantity_borrowed
}}
</td>
<td>
<div>
<span
class=
"block mb-1"
><i
class=
"
ri-mail-line me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"
></i>
{{item.email
}}
</span>
class=
"
me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"
></i>
{{item.created_at
}}
</span>
</div>
</td>
<td>
<div>
<span
class=
"block"
><i
class=
"
ri-phone-line me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"
></i>
{{item.phoneNumber
}}
</span>
class=
"
me-2 align-middle text-[.875rem] text-[#8c9097] dark:text-white/50 inline-flex"
></i>
{{item.returned_date
}}
</span>
</div>
</td>
<td>
<span
class=
"badge bg-{{ item.role == 1 ? 'primary' : 'info'}} text-white"
>
{{item.getRole()}}
</span>
class=
"badge"
[
ngClass
]="{
'
bg-success
/
10
text-success
'
:
item
.
status =
==
'
approved
',
'
bg-warning
/
10
text-warning
'
:
item
.
status =
==
'
requested
',
'
bg-danger
/
10
text-danger
'
:
item
.
status =
==
'
rejected
',
'
bg-info
/
10
text-info
'
:
item
.
status =
==
'
returned
'
}"
>
{{ getStatusText(item.status) }}
</span>
</td>
<td>
<span
class=
"badge bg
-{{ item.status == 1 ? 'primary' : 'danger'}} text-white"
>
{{item.getStatus()
}}
</span>
class=
"badge bg
text-white"
>
{{item.approved_by
}}
</span>
</td>
<td><span
class=
"badge bg-info/10 text-primary"
><i
class=
"bi bi-clock me-1"
></i>
{{item.updatedAt | date : 'medium'}}
</span></td>
<td>
<td>
<!-- <td>
<div class="flex flex-row items-center !gap-2 ">
<a aria-label="anchor" (click)="view(item)" data-hs-overlay="#modal-detail"
class="ti-btn ti-btn-wave !gap-0 !m-0 bg-info/10 text-info hover:bg-info hover:text-white hover:border-info"><i
...
...
@@ -129,7 +134,7 @@
class="ti-btn ti-btn-wave product-btn !gap-0 !m-0 bg-danger/10 text-danger hover:bg-danger hover:text-white hover:border-danger"><i
class="ri-delete-bin-line"></i></a>
</div>
</td>
</td>
-->
</tr>
}
...
...
@@ -183,7 +188,7 @@
<!-- Start:: Create Contact
-->
<!-- Start:: Create Contact
<div id="modal-detail" class="hs-overlay hidden ti-modal [--overlay-backdrop:static]">
<div class="hs-overlay-open:mt-7 ti-modal-box mt-0 ease-out">
<div class="ti-modal-content">
...
...
@@ -304,5 +309,5 @@
</div>
</div>
</div>
</div>
</div>
-->
<!-- End:: Create Contact -->
Web-Manage/src/app/DPU/company-management/emp-borrow-transaction/emp-borrow-transaction.component.ts
View file @
3f575b1c
import
{
BorrowTransactionsService
}
from
'./../../services/borrow-transactions.service'
;
import
{
UserService
}
from
'./../../services/user.service'
;
import
{
HttpClient
}
from
'@angular/common/http'
;
import
{
Component
,
ElementRef
,
ViewChild
}
from
'@angular/core'
;
...
...
@@ -8,7 +9,6 @@ import { BorrowTransactionsModel } from '../../models/borrow-transactions';
import
{
EquipmentModel
,
EquipmentStockModel
}
from
'../../models/equipments.model'
;
import
{
ProjectEquipmentModel
}
from
'../../models/project-equipments'
;
import
{
ProjectMemberModel
}
from
'../../models/project-members'
;
import
{
BorrowTransactionsService
}
from
'../../services/borrow-transactions.service'
;
import
{
EquipmentService
}
from
'../../services/equirement.service'
;
import
{
ProjectEquipmentService
}
from
'../../services/project-equipments.service'
;
import
{
ProjectMemberService
}
from
'../../services/project-members.service'
;
...
...
@@ -46,13 +46,14 @@ export class EmpBorrowTransactionComponent {
allSelected
=
false
;
someSelected
=
false
;
confirmPassword
=
""
itemsList
:
UserProfile
Model
[]
=
[]
filterList
:
UserProfile
Model
[]
=
[]
selectModel
:
UserProfileModel
=
new
UserProfile
Model
()
itemsList
:
BorrowTransactions
Model
[]
=
[]
filterList
:
BorrowTransactions
Model
[]
=
[]
selectModel
:
BorrowTransactionsModel
=
new
BorrowTransactions
Model
()
selectedItems
=
new
Map
<
string
,
boolean
>
();
roleList
:
UserRoleModel
[]
=
[]
descName
=
'engName'
pageIndex
=
0
;
memberId
=
""
uploaderProfile
:
FileUploader
|
undefined
;
uploadErrorMsg
:
string
=
""
;
get
searchTerm
():
string
{
...
...
@@ -135,7 +136,7 @@ export class EmpBorrowTransactionComponent {
if
(
item
.
isSuccess
)
{
const
res
=
JSON
.
parse
(
response
);
console
.
log
(
"res"
,
res
);
this
.
selectModel
.
picture
=
res
.
filename
this
.
selectModel
.
member
=
res
.
filename
swal
(
res
.
message
,
"บันทึกสำเร็จ"
,
"success"
);
}
else
{
...
...
@@ -147,25 +148,41 @@ export class EmpBorrowTransactionComponent {
ngOnInit
():
void
{
this
.
userService
.
getLists
().
subscribe
(
result
=>
{
this
.
itemsList
=
result
const
user
=
this
.
tokenService
.
getUser
();
const
memberId
=
user
?.
member
?.
memberId
;
this
.
borrowTransactionsService
.
getLists
().
subscribe
(
result
=>
{
this
.
itemsList
=
result
.
filter
(
e
=>
e
.
member
.
memberId
==
memberId
);
this
.
itemsList
.
sort
((
a
,
b
)
=>
new
Date
(
b
.
created_at
).
getTime
()
-
new
Date
(
a
.
created_at
).
getTime
()
);
this
.
filterList
=
[...
this
.
itemsList
];
this
.
updatePagedItems
()
})
}
filter
(
v
:
string
)
{
return
this
.
itemsList
?.
filter
(
(
x
)
=>
x
.
memberId
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
username
?
.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
email
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
phoneNumber
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
getRole
()
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
getStatus
()?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
getFullname
()?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
x
.
member
.
username
.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
created_at
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
returned_date
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
approved_by
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
||
x
.
status
?.
toLowerCase
().
indexOf
(
v
.
toLowerCase
())
!==
-
1
);
}
getStatusText
(
status
:
string
):
string
{
switch
(
status
)
{
case
'requested'
:
return
'รออนุมัติ'
;
case
'approved'
:
return
'อนุมัติแล้ว'
;
case
'rejected'
:
return
'ไม่อนุมัติ'
;
case
'returned'
:
return
'คืนแล้ว'
;
case
'repairing'
:
return
'กำลังซ่อม'
;
default
:
return
status
;
}
}
delete
(
item
:
UserProfileModel
)
{
swal
({
title
:
"Are you sure?"
,
...
...
@@ -186,16 +203,16 @@ export class EmpBorrowTransactionComponent {
});
}
new
()
{
this
.
action
=
'add'
this
.
selectModel
=
new
UserProfileModel
()
}
//
new() {
//
this.action = 'add'
//
this.selectModel = new UserProfileModel()
//
}
view
(
item
:
UserProfile
Model
)
{
view
(
item
:
BorrowTransactions
Model
)
{
this
.
action
=
'edit'
this
.
confirmPassword
=
''
this
.
selectModel
=
new
UserProfile
Model
(
item
)
this
.
selectModel
=
new
BorrowTransactions
Model
(
item
)
console
.
log
(
this
.
selectModel
)
}
...
...
@@ -208,35 +225,40 @@ export class EmpBorrowTransactionComponent {
dangerMode
:
false
,
buttons
:
[
"Cancel"
,
"Confirm"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
if
(
this
.
action
==
'add'
)
{
this
.
userService
.
save
(
this
.
selectModel
).
subscribe
(
result
=>
{
console
.
log
(
result
)
swal
(
"Save Success!!"
,
"บันทึกข้อมูลสมาชิก"
,
"success"
);
this
.
ngOnInit
()
this
.
childModal
?.
nativeElement
.
click
()
})
}
else
if
(
this
.
action
==
'edit'
)
{
this
.
userService
.
update
(
this
.
selectModel
).
subscribe
(
result
=>
{
console
.
log
(
result
)
swal
(
"Update Success!!"
,
"บันทึกข้อมูลสมาชิก"
,
"success"
);
this
.
ngOnInit
()
this
.
childModal
?.
nativeElement
.
click
()
})
}
}
});
//
.then((willDelete: any) => {
//
if (willDelete) {
//
if (this.action == 'add') {
//
this.userService.save(this.selectModel).subscribe(result => {
//
console.log(result)
//
swal("Save Success!!", "บันทึกข้อมูลสมาชิก", "success");
//
this.ngOnInit()
//
this.childModal?.nativeElement.click()
//
})
//
} else if (this.action == 'edit') {
//
this.userService.update(this.selectModel).subscribe(result => {
//
console.log(result)
//
swal("Update Success!!", "บันทึกข้อมูลสมาชิก", "success");
//
this.ngOnInit()
//
this.childModal?.nativeElement.click()
//
})
//
}
//
}
//
});
}
updatePagedItems
()
{
const
startIndex
=
this
.
pageIndex
*
10
;
const
endIndex
=
startIndex
+
10
;
this
.
filterList
=
this
.
itemsList
.
slice
(
startIndex
,
endIndex
);
const
endIndex
=
startIndex
+
10
;
const
source
=
this
.
searchTerm
?
this
.
itemsList
.
filter
(
x
=>
x
.
member
?.
username
?.
includes
(
this
.
searchTerm
))
:
this
.
itemsList
;
this
.
filterList
=
source
.
slice
(
startIndex
,
endIndex
);
}
toggleAll
(
event
:
any
)
{
...
...
@@ -255,77 +277,77 @@ export class EmpBorrowTransactionComponent {
this
.
someSelected
=
this
.
itemsList
.
some
(
item
=>
this
.
selectedItems
.
get
(
item
.
memberId
));
}
deleteSelect
()
{
let
employeeInfo
=
''
;
this
.
selectedItems
.
forEach
((
isSelected
,
memberId
)
=>
{
if
(
isSelected
)
{
const
user
=
this
.
itemsList
.
find
(
user
=>
user
.
memberId
===
memberId
);
if
(
user
)
{
employeeInfo
+=
`
${
this
.
translate
.
instant
(
'Fullname'
)}
:
${
user
.
getFullname
()}
\n`
;
}
}
});
swal
({
title
:
"Are you sure?"
,
text
:
employeeInfo
,
icon
:
"warning"
,
dangerMode
:
true
,
buttons
:
[
"Cancel"
,
"Yes, Delete it!"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
this
.
selectedItems
.
forEach
((
isSelected
,
memberId
)
=>
{
if
(
isSelected
)
{
const
user
=
this
.
itemsList
.
find
(
user
=>
user
.
memberId
===
memberId
);
if
(
user
)
{
this
.
userService
.
delete
(
user
).
subscribe
(
result
=>
{
swal
(
"Save Success!!"
,
"บันทึกข้อมูลสำเร็จ"
,
"success"
);
this
.
ngOnInit
();
});
}
}
});
}
});
}
// deleteSelect() {
// let employeeInfo = '';
// this.selectedItems.forEach((isSelected, memberId) => {
// if (isSelected) {
// const user = this.itemsList.find(user => user.memberId === memberId);
// if (user) {
// employeeInfo += `${this.translate.instant('Fullname')}: ${user.getFullname()}\n`;
// }
// }
// });
adjustSelect
(
status
:
number
)
{
let
title
=
"Are you sure?"
let
employeeInfo
=
''
;
// ตัวแปรสำหรับเก็บข้อมูลพนักงาน
this
.
selectedItems
.
forEach
((
isSelected
,
memberId
)
=>
{
if
(
isSelected
)
{
const
user
=
this
.
itemsList
.
find
(
user
=>
user
.
memberId
===
memberId
);
if
(
user
)
{
employeeInfo
+=
`
${
this
.
translate
.
instant
(
'Fullname'
)}
:
${
user
.
getFullname
()}
\n`
;
}
}
});
swal
({
title
:
title
,
text
:
employeeInfo
,
icon
:
"warning"
,
dangerMode
:
false
,
buttons
:
[
"Cancel"
,
"Confirm"
],
})
.
then
((
willDelete
:
any
)
=>
{
if
(
willDelete
)
{
this
.
selectedItems
.
forEach
((
isSelected
,
memberId
)
=>
{
if
(
isSelected
)
{
const
user
=
this
.
itemsList
.
find
(
user
=>
user
.
memberId
===
memberId
);
if
(
user
)
{
user
.
status
=
status
this
.
userService
.
update
(
user
).
subscribe
(
result
=>
{
swal
(
"Save Success!!"
,
"บันทึกข้อมูลสำเร็จ"
,
"success"
);
this
.
ngOnInit
();
});
}
}
});
}
// swal({
// title: "Are you sure?",
// text: employeeInfo,
// icon: "warning",
// dangerMode: true,
// buttons: ["Cancel", "Yes, Delete it!"],
// })
// .then((willDelete: any) => {
// if (willDelete) {
// this.selectedItems.forEach((isSelected, memberId) => {
// if (isSelected) {
// const user = this.itemsList.find(user => user.memberId === memberId);
// if (user) {
// this.userService.delete(user).subscribe(result => {
// swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
// this.ngOnInit();
// });
// }
// }
// });
// }
// });
// }
});
}
// adjustSelect(status: number) {
// let title = "Are you sure?"
// let employeeInfo = ''; // ตัวแปรสำหรับเก็บข้อมูลพนักงาน
// this.selectedItems.forEach((isSelected, memberId) => {
// if (isSelected) {
// const user = this.itemsList.find(user => user.memberId === memberId);
// if (user) {
// employeeInfo += `${this.translate.instant('Fullname')}: ${user.getFullname()}\n`;
// }
// }
// });
// swal({
// title: title,
// text: employeeInfo,
// icon: "warning",
// dangerMode: false,
// buttons: ["Cancel", "Confirm"],
// })
// .then((willDelete: any) => {
// if (willDelete) {
// this.selectedItems.forEach((isSelected, memberId) => {
// if (isSelected) {
// const user = this.itemsList.find(user => user.memberId === memberId);
// if (user) {
// user.status = status
// this.userService.update(user).subscribe(result => {
// swal("Save Success!!", "บันทึกข้อมูลสำเร็จ", "success");
// this.ngOnInit();
// });
// }
// }
// });
// }
// });
// }
// filterEmp(empId: string) {
// this.selectModel = this.empList.filter(e => e.memberId == empId)[0]
...
...
Web-Manage/src/app/DPU/models/user.model.ts
View file @
3f575b1c
...
...
@@ -14,7 +14,7 @@ export class UserProfileModel extends BaseModel {
status
:
number
;
picture
:
any
;
createdAt
:
string
;
updatedAt
:
string
;
updatedAt
:
string
;
constructor
(
data
?:
Partial
<
UserProfileModel
>
,
translateService
?:
TranslateService
...
...
Web-Manage/src/app/shared/components/sidebar/sidebar.component.html
View file @
3f575b1c
...
...
@@ -43,8 +43,8 @@
<a href="javascript:void(0);" class="badge badge-md !rounded-full bg-info/10 text-info me-2"
title="No of employees"><i class="bi bi-people me-1"></i>No. of Emp : 345 //TODO</a>
</div> -->
<a
routerLink=
"/company/
company-info
"
class=
"ti-btn btn-wave ti-btn-primary-full"
>
View Profile
<i
class=
"ri-arrow-right-line"
></i>
<a
routerLink=
"/company/
admin-home
"
class=
"ti-btn btn-wave ti-btn-primary-full"
>
เลือกโครงการ
<i
class=
"ri-arrow-right-line"
></i>
</a>
</div>
</div>
...
...
Web-Manage/src/app/shared/components/sidebar/sidebar.component.ts
View file @
3f575b1c
...
...
@@ -68,6 +68,7 @@ export class SidebarComponent {
isInstallerRoute
:
boolean
=
false
;
previousUrl
:
string
=
''
;
currentUrl
:
string
=
''
;
roleInProject
:
string
=
''
;
constructor
(
private
navServices
:
NavService
,
private
sanitizer
:
DomSanitizer
,
...
...
@@ -80,6 +81,8 @@ export class SidebarComponent {
this
.
screenWidth
=
window
.
innerWidth
;
}
ngOnInit
()
{
let
bodyElement
:
any
=
document
.
querySelector
(
'.main-content'
);
...
...
Web-Manage/src/app/shared/services/nav.service.ts
View file @
3f575b1c
...
...
@@ -152,7 +152,7 @@ export class NavService implements OnDestroy {
{
headTitle
:
'จัดการโครงการ'
},
{
icon
:
'home'
,
path
:
'/company/
admin-
home'
,
path
:
'/company/home'
,
title
:
'หน้าแรก'
,
type
:
'link'
,
selected
:
false
,
...
...
@@ -183,6 +183,18 @@ export class NavService implements OnDestroy {
{
path
:
'/company/emp-borrow-return-status'
,
title
:
'คืน'
,
type
:
'link'
}
],
},
{
icon
:
'ruler'
,
title
:
'จัดการอุปกรซ่อม-ชำรุด'
,
type
:
'sub'
,
selected
:
false
,
active
:
false
,
Menusub
:
true
,
children
:
[
{
path
:
'/company/emp-borrow-status'
,
title
:
'อุปกรณ์ที่ซ่อม/ชำรุด'
,
type
:
'link'
},
],
},
];
}
...
...
Web-Manage/src/assets/i18n/th.json
View file @
3f575b1c
{
"Home"
:
"หน้าแรก"
,
"Approver"
:
"ผู้อนุมัติ"
,
"All List"
:
"รายการทั้งหมด"
,
"Create"
:
"สร้าง"
,
"Delete"
:
"ลบ"
,
...
...
@@ -29,12 +30,15 @@
"Gender"
:
"เพศ"
,
"Admin-System"
:
"ผู้ดูแลระบบ"
,
"Admin-Company"
:
"ผู้ดูแลบริษัท"
,
"Amount"
:
"จำนวน"
,
"User"
:
"ผู้ใช้งาน"
,
"User Group"
:
"กลุ่มผู้ใช้งาน"
,
"User Role"
:
"บทบาทผู้ใช้งาน"
,
"User Setting"
:
"กำหนดผู้ใช้งาน"
,
"User Management"
:
"จัดการผู้ใช้งาน"
,
"Borrowed equipment"
:
"อุปกรณ์ที่ยืม"
,
"Menu"
:
"เมนู"
,
"Member"
:
"พนักงาน"
,
"Action"
:
"รูปแบบการใช้งาน"
,
"Login History"
:
"การเข้าใช้งานระบบ"
,
"usage History"
:
"กิจกรรมผู้ใช้งาน"
,
...
...
@@ -43,6 +47,7 @@
"Prefix"
:
"คำนำหน้า"
,
"Region"
:
"ภูมิภาค"
,
"Province"
:
"จังหวัด"
,
"Project"
:
"โปรเจค"
,
"District"
:
"อำเภอ"
,
"Subdistrict"
:
"ตำบล"
,
"Zipcode"
:
"รหัสไปรษณีย์"
,
...
...
@@ -50,6 +55,8 @@
"Department"
:
"แผนก"
,
"Division"
:
"ฝ่าย"
,
"Section"
:
"ส่วน"
,
"Borrow Date"
:
"วันที่ยืม"
,
"Date return"
:
"วันที่คืน"
,
"Position"
:
"ตำแหน่ง"
,
"Employee Management"
:
"จัดการพนักงาน"
,
"Please fill in information"
:
"*"
,
...
...
Web-Manage/src/assets/iconfonts/boxicons/dev.box-icon-element.html
View file @
3f575b1c
...
...
@@ -1375,4 +1375,4 @@ const icons_l = [
$controls
.
querySelector
(
"select[name='animation']"
).
addEventListener
(
"input"
,
setIconAttr
.
bind
(
null
,
"animation"
));
</script>
</body>
</html>
\ No newline at end of file
</html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment