Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fetch leave encashment amount from Salary Structure Assignment #2256

Closed
wants to merge 77 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
2e36ba5
feat: fetch leave encashment amount from ssa
iamejaaz Oct 6, 2024
b48c6a3
fix: if no amount in ssa then fetch from salary structure
iamejaaz Oct 8, 2024
6b61a65
fix: unwanted indent issue
iamejaaz Oct 8, 2024
0b6d6b9
refactor: Employee working on holiday
niraj2477 Oct 17, 2023
ba8a6ec
fix: Update condition in query builder
niraj2477 Oct 17, 2023
99d0462
fix: Turkish translations
frappe-pr-bot Oct 1, 2024
7c56ce7
fix: Persian translations
frappe-pr-bot Oct 1, 2024
601d4a3
fix: Turkish translations
frappe-pr-bot Oct 2, 2024
8249bc9
fix: Persian translations
frappe-pr-bot Oct 2, 2024
a3a32bb
fix: Arabic translations
frappe-pr-bot Oct 2, 2024
14c0910
fix: French translations
frappe-pr-bot Oct 2, 2024
cf59530
fix: Spanish translations
frappe-pr-bot Oct 2, 2024
b3a3c81
fix: German translations
frappe-pr-bot Oct 2, 2024
ae14551
fix: Swedish translations
frappe-pr-bot Oct 2, 2024
f035504
fix: Bosnian translations
frappe-pr-bot Oct 2, 2024
29b31e5
fix: Esperanto translations
frappe-pr-bot Oct 2, 2024
dc53cd6
chore: update POT file
frappe-pr-bot Oct 6, 2024
1670b73
feat: add Attendance Dashboard
krantheman Aug 9, 2024
49ae62f
feat: add attendance summary
krantheman Aug 9, 2024
d744cca
feat: fetch event of selected month
krantheman Aug 9, 2024
7b862b3
feat: add calendar days
krantheman Aug 20, 2024
b7e07d9
chore: remove redundant classes
krantheman Aug 20, 2024
af2f1f6
fix: colors and icons
krantheman Aug 21, 2024
8bd28d8
feat: add Upcoming Shifts list
krantheman Aug 22, 2024
919a9e4
feat: add color coding to summary
krantheman Aug 22, 2024
a8a0ae1
feat: add ionic modal for shifts
krantheman Aug 22, 2024
32dc381
feat: add Shift Request list
krantheman Aug 26, 2024
bc0a580
feat: add Shift Request list view
krantheman Aug 26, 2024
404dc3f
feat: add Shift Request form
krantheman Aug 26, 2024
4b264cd
feat: set shift request approvers
krantheman Aug 27, 2024
8007104
feat: add recent attendance requests
krantheman Aug 27, 2024
fd9a995
feat: add Attendance Request list and form
krantheman Aug 27, 2024
75d5bcb
feat: add Attendance Request summary
krantheman Aug 27, 2024
311d1f4
fix: submit for Attendance Request
krantheman Sep 9, 2024
87d7823
refactor: upcoming shifts
krantheman Sep 9, 2024
c7e14e1
feat: add Shift Assignment list
krantheman Sep 9, 2024
ed9368d
feat: add Shift Assignment form
krantheman Sep 10, 2024
846eb05
fix: render 'New' button only if user has perms for doctype
krantheman Sep 10, 2024
b7985d1
feat: add Employee Checkin list
krantheman Sep 10, 2024
7003082
feat: add Employee Checkin form
krantheman Sep 10, 2024
7b336d7
feat: add DatetimePicker and switch from Input to DatePicker
krantheman Sep 11, 2024
aff5763
feat: add Employee Checkin summary
krantheman Sep 12, 2024
fdf31a9
feat: add Request a Shift button
krantheman Sep 17, 2024
0e6e8d0
feat: show employee name for team requests
krantheman Sep 17, 2024
870b8d9
refactor: remove tabs where unnecessary
krantheman Sep 17, 2024
09bc0a7
fix: Employee Checkin list filters
krantheman Sep 17, 2024
a32100d
feat: add attendance and shift requests to home page
krantheman Sep 17, 2024
641d4cc
feat: show team shift requests
krantheman Sep 18, 2024
0815221
feat: update icons for attendance and shifts
krantheman Sep 18, 2024
5cf42c3
feat: add notifications for shift request
krantheman Sep 18, 2024
6ce1acf
refactor: use ListItem component for all items
krantheman Sep 18, 2024
20771ce
fix: get_shift_requests api fields
krantheman Sep 19, 2024
07de363
fix(Salary Slip): consider only leaves taken until End Date in Leave …
krantheman Oct 8, 2024
cf9e721
test(Salary Slip): leave details
krantheman Oct 8, 2024
e73bdd8
chore: update site urls from frappehr.com to frappe.io/hr
krantheman Oct 9, 2024
f030d94
feat(Expense Claim): allow update of cost centre and project on submit
krantheman Oct 9, 2024
f4a0603
feat: create Shift Location doctype
krantheman Jul 4, 2024
45357cc
feat(Shift Assignment): add Shift Location field
krantheman Jul 4, 2024
3547287
feat: add geolocation fetching
krantheman Jul 4, 2024
2c53d7a
feat(Employee Checkin): validate distance from shift location
krantheman Jul 4, 2024
d64afbe
fix: consider only submited shift assignments while validating distance
krantheman Jul 12, 2024
a008666
test: add test for geofencing
krantheman Jul 12, 2024
8c2716b
fix: formatting
krantheman Jul 12, 2024
ada4477
feat(Shift & Attendance): add Shift Location link
krantheman Oct 9, 2024
5019823
feat(Shift Location): add Shift Assignment connection
krantheman Oct 10, 2024
9aa4e38
refactor: show only holidays from employee's holidays
krantheman Oct 14, 2024
d90d105
refactor: column widths
krantheman Oct 14, 2024
4b3fcf9
perf: improve get_holidays function
krantheman Oct 14, 2024
0b27a69
fix(Leave Policy Assignment): calculation of months passed
krantheman Jan 8, 2024
3dd17d9
test: add test for get_leaves_for_passed_months
krantheman Jan 9, 2024
277ef82
test: fix setUp
krantheman Jan 9, 2024
adf9d21
refactor: use IntegrationTestCase instead of FrappeTestCase
krantheman Oct 10, 2024
6fa2565
fix: payroll bank entry with the Loan Repayment amount
Nihantra-Patel Oct 15, 2024
5f8a4d2
fix: payroll bank entry with the Loan Repayment amount
Nihantra-Patel Oct 15, 2024
58960a6
fix: payroll bank entry with the Loan Repayment amount
Nihantra-Patel Oct 15, 2024
5e8fbc3
fix: payroll bank entry with the Loan Repayment amount
Nihantra-Patel Oct 15, 2024
f3c4423
Revert "fix(Leave Policy Assignment): calculation of months passed si…
krantheman Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ body:
Welcome to Frappe HR issue tracker! Before submitting a request, please consider the following:

1. This tracker should only be used to report bugs and request features / enhancements to Frappe HR
- For questions and general support, checkout the [documentation](https://frappehr.com/docs) or use the [forum](https://discuss.frappe.io) to get inputs from the open source community.
- For questions and general support, checkout the [documentation](https://docs.frappe.io/hr) or use the [forum](https://discuss.frappe.io) to get inputs from the open source community.
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
the original discussion.
3. When making a feature request, make sure to be as verbose as possible. The better you convey your message, the greater the drive to make it happen.
Expand Down Expand Up @@ -47,4 +47,4 @@ body:
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.
...
...
2 changes: 1 addition & 1 deletion .github/helper/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def docs_link_exists(body):
parts = parsed_url.path.split("/")
if len(parts) == 5 and parts[1] == "frappe" and parts[2] == "hrms":
return True
elif parsed_url.netloc == "frappehr.com":
elif parsed_url.netloc == "docs.frappe.io":
return True


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Frappe HR has everything you need to drive excellence within the company. It's a

## Learning and Community

1. [Documentation](https://frappehr.com/docs) - Extensive documentation for Frappe HR.
1. [Documentation](https://docs.frappe.io/hr) - Extensive documentation for Frappe HR.
2. [User Forum](https://discuss.erpnext.com/) - Engage with the community of ERPNext users and service providers.
3. [Telegram Group](https://t.me/frappehr) - Get instant help from the community of users.

Expand Down
122 changes: 122 additions & 0 deletions frontend/src/components/AttendanceCalendar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<template>
<div class="flex flex-col w-full gap-5" v-if="calendarEvents.data">
<div class="text-lg text-gray-800 font-bold">Attendance Calendar</div>

<div class="flex flex-col gap-6 bg-white py-6 px-3.5 rounded-lg border-none">
<!-- Month Change -->
<div class="flex flex-row justify-between items-center px-4">
<Button
icon="chevron-left"
variant="ghost"
@click="firstOfMonth = firstOfMonth.subtract(1, 'M')"
/>
<span class="text-lg text-gray-800 font-bold">
{{ firstOfMonth.format("MMMM") }} {{ firstOfMonth.format("YYYY") }}
</span>
<Button
icon="chevron-right"
variant="ghost"
@click="firstOfMonth = firstOfMonth.add(1, 'M')"
/>
</div>

<!-- Calendar -->
<div class="grid grid-cols-7 gap-y-3">
<div
v-for="day in DAYS"
class="flex justify-center text-gray-600 text-sm font-medium leading-6"
>
{{ day }}
</div>
<div v-for="_ in firstOfMonth.get('d')" />
<div v-for="index in firstOfMonth.endOf('M').get('D')">
<div
class="h-8 w-8 flex rounded-full mx-auto"
:class="getEventOnDate(index) && `bg-${colorMap[getEventOnDate(index)]}`"
>
<span class="text-gray-800 text-sm font-medium m-auto">
{{ index }}
</span>
</div>
</div>
</div>

<hr />

<!-- Summary -->
<div class="grid grid-cols-4 mx-2">
<div v-for="status in summaryStatuses" class="flex flex-col gap-1">
<div class="flex flex-row gap-1 items-center">
<span class="rounded full h-3 w-3" :class="`bg-${colorMap[status]}`" />
<span class="text-gray-600 text-sm font-medium leading-5"> {{ status }} </span>
</div>
<span class="text-gray-800 text-base font-semibold leading-6 mx-auto">
{{ summary[status] || 0 }}
</span>
</div>
</div>
</div>
</div>
</template>

<script setup>
import { computed, inject, ref, watch } from "vue"
import { createResource } from "frappe-ui"

const dayjs = inject("$dayjs")
const employee = inject("$employee")
const firstOfMonth = ref(dayjs().date(1).startOf("D"))

const colorMap = {
Present: "green-200",
"Work From Home": "green-200",
"Half Day": "yellow-100",
Absent: "red-100",
"On Leave": "blue-100",
Holiday: "gray-100",
}

const summaryStatuses = ["Present", "Half Day", "Absent", "On Leave"]

const summary = computed(() => {
const summary = {}

for (const status of Object.values(calendarEvents.data)) {
let updatedStatus = status === "Work From Home" ? "Present" : status
if (updatedStatus in summary) {
summary[updatedStatus] += 1
} else {
summary[updatedStatus] = 1
}
}

return summary
})

watch(
() => firstOfMonth.value,
() => {
calendarEvents.fetch()
}
)

const getEventOnDate = (date) => {
return calendarEvents.data[firstOfMonth.value.date(date).format("YYYY-MM-DD")]
}

const DAYS = ["S", "M", "T", "W", "T", "F", "S"]

//resources
const calendarEvents = createResource({
url: "hrms.api.get_attendance_calendar_events",
auto: true,
cache: "hrms:attendance_calendar_events",
makeParams() {
return {
employee: employee.data.name,
from_date: firstOfMonth.value.format("YYYY-MM-DD"),
to_date: firstOfMonth.value.endOf("M").format("YYYY-MM-DD"),
}
},
})
</script>
54 changes: 54 additions & 0 deletions frontend/src/components/AttendanceRequestItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<template>
<ListItem>
<template #left>
<AttendanceIcon class="h-5 w-5 text-gray-500" />
<div class="flex flex-col items-start gap-1.5">
<div class="text-base font-normal text-gray-800">
{{ props.doc.reason }}
</div>
<div class="text-xs font-normal text-gray-500">
<span>{{ props.doc.attendance_dates || getDates(props.doc) }}</span>
<span v-if="props.doc.to_date">
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">{{
`${props.doc.total_attendance_days || getTotalDays(props.doc)}d`
}}</span>
</span>
</div>
</div>
</template>
<template #right>
<Badge variant="outline" :theme="colorMap[status]" :label="status" size="md" />
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</template>
</ListItem>
</template>

<script setup>
import { computed } from "vue"
import { Badge, FeatherIcon } from "frappe-ui"

import ListItem from "@/components/ListItem.vue"
import AttendanceIcon from "@/components/icons/AttendanceIcon.vue"
import { getDates, getTotalDays } from "@/data/attendance"

const props = defineProps({
doc: {
type: Object,
},
workflowStateField: {
type: String,
required: false,
},
})

const status = computed(() => {
if (props.workflowStateField) return props.doc[props.workflowStateField]
return props.doc.docstatus ? "Submitted" : "Draft"
})

const colorMap = {
Draft: "gray",
Submitted: "blue",
}
</script>
6 changes: 6 additions & 0 deletions frontend/src/components/BottomTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import HomeIcon from "@/components/icons/HomeIcon.vue"
import LeaveIcon from "@/components/icons/LeaveIcon.vue"
import ExpenseIcon from "@/components/icons/ExpenseIcon.vue"
import SalaryIcon from "@/components/icons/SalaryIcon.vue"
import AttendanceIcon from "@/components/icons/AttendanceIcon.vue"

const route = useRoute()

Expand All @@ -39,6 +40,11 @@ const tabItems = [
title: "Home",
route: "/home",
},
{
icon: AttendanceIcon,
title: "Attendance",
route: "/dashboard/attendance",
},
{
icon: LeaveIcon,
title: "Leaves",
Expand Down
20 changes: 7 additions & 13 deletions frontend/src/components/CheckInPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

<template v-if="settings.data?.allow_employee_checkin_from_mobile_app">
<div class="font-medium text-sm text-gray-500 mt-1.5" v-if="lastLog">
Last {{ lastLogType }} was at {{ lastLogTime }}
<span>Last {{ lastLogType }} was at {{ formatTimestamp(lastLog.time) }}</span>
<span class="whitespace-pre"> &middot; </span>
<router-link :to="{ name: 'EmployeeCheckinListView' }" v-slot="{ navigate }">
<span @click="navigate" class="underline">View List</span>
</router-link>
</div>
<Button
class="mt-4 mb-1 drop-shadow-sm py-5 text-base"
Expand Down Expand Up @@ -75,6 +79,8 @@ import { createResource, createListResource, toast, FeatherIcon } from "frappe-u
import { computed, inject, ref, onMounted, onBeforeUnmount } from "vue"
import { IonModal, modalController } from "@ionic/vue"

import { formatTimestamp } from "@/utils/formatters"

const DOCTYPE = "Employee Checkin"

const socket = inject("$socket")
Expand Down Expand Up @@ -115,18 +121,6 @@ const nextAction = computed(() => {
: { action: "IN", label: "Check In" }
})

const lastLogTime = computed(() => {
const timestamp = lastLog?.value?.time
const formattedTime = dayjs(timestamp).format("hh:mm a")

if (dayjs(timestamp).isToday()) return formattedTime
else if (dayjs(timestamp).isYesterday()) return `${formattedTime} yesterday`
else if (dayjs(timestamp).isSame(dayjs(), "year"))
return `${formattedTime} on ${dayjs(timestamp).format("D MMM")}`

return `${formattedTime} on ${dayjs(timestamp).format("D MMM, YYYY")}`
})

function handleLocationSuccess(position) {
latitude.value = position.coords.latitude
longitude.value = position.coords.longitude
Expand Down
83 changes: 33 additions & 50 deletions frontend/src/components/EmployeeAdvanceItem.vue
Original file line number Diff line number Diff line change
@@ -1,52 +1,37 @@
<template>
<div class="flex flex-col w-full justify-center gap-2.5">
<div class="flex flex-row items-center justify-between">
<div class="flex flex-row items-start gap-3 grow">
<EmployeeAdvanceIcon class="h-5 w-5 mt-[3px] text-gray-500" />
<div class="flex flex-col items-start gap-1">
<div
v-if="props.doc.balance_amount"
class="text-lg font-bold text-gray-800 leading-6"
>
{{ `${currency} ${props.doc.balance_amount} /` }}
<span class="text-gray-600">
{{ `${currency} ${props.doc.paid_amount}` }}
</span>
</div>
<div v-else class="text-lg font-bold text-gray-800 leading-6">
{{ `${currency} ${props.doc.advance_amount}` }}
</div>
<div class="text-xs font-normal text-gray-500">
<span>
{{ props.doc.purpose }}
</span>
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">
{{ postingDate }}
</span>
</div>
<ListItem
:isTeamRequest="props.isTeamRequest"
:employee="props.doc.employee"
:employeeName="props.doc.employee_name"
>
<template #left>
<EmployeeAdvanceIcon class="h-5 w-5 mt-[3px] text-gray-500" />
<div class="flex flex-col items-start gap-1">
<div v-if="props.doc.balance_amount" class="text-lg font-bold text-gray-800 leading-6">
{{ `${currency} ${props.doc.balance_amount} /` }}
<span class="text-gray-600">
{{ `${currency} ${props.doc.paid_amount}` }}
</span>
</div>
<div v-else class="text-lg font-bold text-gray-800 leading-6">
{{ `${currency} ${props.doc.advance_amount}` }}
</div>
<div class="text-xs font-normal text-gray-500">
<span>
{{ props.doc.purpose }}
</span>
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">
{{ postingDate }}
</span>
</div>
</div>
<div class="flex flex-row justify-end items-center gap-2">
<Badge
variant="outline"
:theme="colorMap[status]"
:label="status"
size="md"
/>
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</div>
</div>
<div
v-if="props.isTeamRequest"
class="flex flex-row items-center gap-2 pl-8"
>
<EmployeeAvatar :employeeID="props.doc.employee" />
<div class="text-sm text-gray-600 grow">
{{ props.doc.employee_name }}
</div>
</div>
</div>
</template>
<template #right>
<Badge variant="outline" :theme="colorMap[status]" :label="status" size="md" />
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</template>
</ListItem>
</template>

<script setup>
Expand All @@ -55,7 +40,7 @@ import { computed, inject } from "vue"

import { getCurrencySymbol } from "@/data/currencies"

import EmployeeAvatar from "@/components/EmployeeAvatar.vue"
import ListItem from "@/components/ListItem.vue"
import EmployeeAdvanceIcon from "@/components/icons/EmployeeAdvanceIcon.vue"

const dayjs = inject("$dayjs")
Expand Down Expand Up @@ -88,8 +73,6 @@ const postingDate = computed(() => {
})

const status = computed(() => {
return props.workflowStateField
? props.doc[props.workflowStateField]
: props.doc.status
return props.workflowStateField ? props.doc[props.workflowStateField] : props.doc.status
})
</script>
Loading