Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c1bba6b
fix: update currency & exchange rate, update base & transaction field…
iamkhanraheel Feb 5, 2026
370b469
fix: advance child table row selection as per the sanctioned amount i…
iamkhanraheel Feb 25, 2026
2b0dc14
fix: update base fields value as per the exchange rate in real time
iamkhanraheel Feb 25, 2026
a767d69
fix(Link): reload link field options when filters change
ruchamahabal Mar 5, 2026
0912671
fix: update currency in advance account filters, remove fetching defa…
iamkhanraheel Mar 6, 2026
cde96b3
fix: add currency filter in payable account of expense claim
iamkhanraheel Mar 6, 2026
f7ef13f
fix: set exchange rate to 0 if currency not set, correct typo
iamkhanraheel Mar 8, 2026
1164ff8
fix: formatting
iamkhanraheel Mar 26, 2026
604dc07
fix: currency not showing up in recent expenses
ruchamahabal Mar 30, 2026
6972cea
fix(Link): new options don't populate when search term changes
ruchamahabal Mar 30, 2026
3908367
fix: fetching exchange rate fails when expense currency changes from …
ruchamahabal Mar 30, 2026
0f9ef2b
fix: don't pass currency in expense claim tables, use doc currency
ruchamahabal Mar 30, 2026
f18d124
fix: remove all basefield conversion & label update
iamkhanraheel Mar 30, 2026
0874b5a
fix: watch for currency change only to update label, cleanup currency…
iamkhanraheel Mar 31, 2026
fd43c57
fix(expense_claim_pwa): fetch salary employee from employee master
iamkhanraheel Apr 6, 2026
6457589
fix: don't pass currency in expense advances, use doc currency
ruchamahabal Apr 6, 2026
f7ecbfa
fix: set exchange rate first, clear advances table on API response
ruchamahabal Apr 6, 2026
c49a2fb
fix(Link): options not loading once value is set
ruchamahabal Apr 6, 2026
26e5017
fix: move expenses table currency update call to onSuccess of table f…
ruchamahabal Apr 6, 2026
e6c66bb
chore: remove unused flt function
ruchamahabal Apr 6, 2026
e6dbfbd
fix: don't reload form fields on currency change
ruchamahabal Apr 6, 2026
55ddf2a
refactor: use currency conversion as a composable instead of explicit…
ruchamahabal Apr 6, 2026
e57651a
fix: apply currency filter in employee advance account on currency ch…
ruchamahabal Apr 6, 2026
cdcc2e6
fix: show correct currency in expense preview
ruchamahabal Apr 6, 2026
1a3754d
fix: pass expense claim ref to composable
ruchamahabal Apr 6, 2026
2743cad
fix: wire currency conversion labels in expense taxes
ruchamahabal Apr 6, 2026
378b0c2
fix: fields clipping in expense item entry
ruchamahabal Apr 6, 2026
480693c
fix: missing patch workflow
asmitahase Apr 6, 2026
8a41129
fix: don't remove payments
asmitahase Apr 6, 2026
97ead0e
fix: site backup without payments
asmitahase Apr 6, 2026
d6b4653
Merge pull request #3119 from asmitahase/patch-workflow
asmitahase Apr 6, 2026
8cc9b68
fix: has permission check
ruchamahabal Apr 6, 2026
7af1034
fix: Advance allocation function like before
ruchamahabal Apr 6, 2026
021bf70
fix: retain unallocated advances cards & allocated advances selection…
ruchamahabal Apr 6, 2026
aa9c20d
Merge pull request #4083 from iamkhanraheel/fix/v16_changes_pwa
ruchamahabal Apr 6, 2026
4173793
fix(PWA): render Text Editor component for rich text fields instead o…
ruchamahabal Apr 6, 2026
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
173 changes: 173 additions & 0 deletions .github/workflows/patch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
name: Patch

on:
pull_request:
paths-ignore:
- '**.js'
- '**.css'
- '**.md'
- '**.html'
- '**.csv'
- 'crowdin.yml'
- '.mergify.yml'
workflow_dispatch:

concurrency:
group: patch-develop-${{ github.event_name }}-${{ github.event.number || github.event_name == 'workflow_dispatch' && github.run_id || '' }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 60

name: Patch Test

services:
mysql:
image: mariadb:11.8
env:
MARIADB_ROOT_PASSWORD: 'root'
ports:
- 3306:3306
options: --health-cmd="mariadb-admin ping" --health-interval=5s --health-timeout=2s --health-retries=3

steps:
- name: Clone
uses: actions/checkout@v6

- name: Check for valid Python & Merge Conflicts
run: |
python -m compileall -f "${GITHUB_WORKSPACE}"
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
then echo "Found merge conflicts"
exit 1
fi

- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: |
3.11
3.13
3.14

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
check-latest: true

- name: Add to Hosts
run: echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-

- name: Cache node modules
uses: actions/cache@v4
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-

- name: Install
run: |
pip install frappe-bench
bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
env:
DB: mariadb
TYPE: server

- name: Run Patch Tests
run: |
cd ~/frappe-bench/
bench remove-app payments --force
bench remove-app lending --force
jq 'del(.install_apps)' ~/frappe-bench/sites/test_site/site_config.json > tmp.json
mv tmp.json ~/frappe-bench/sites/test_site/site_config.json

wget https://frappe.io/files/frappe-hr-v14-p.sql.gz
bench --site test_site --force restore ~/frappe-bench/frappe-hr-v14-p.sql.gz

git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
git -C "apps/hrms" remote set-url upstream https://github.com/frappe/hrms.git


function update_to_version() {
version=$1

branch_name="version-$version-hotfix"
echo "Updating to v$version"

# Fetch and checkout branches
git -C "apps/frappe" fetch --depth 1 upstream $branch_name:$branch_name
git -C "apps/erpnext" fetch --depth 1 upstream $branch_name:$branch_name
git -C "apps/hrms" fetch --depth 1 upstream $branch_name:$branch_name
git -C "apps/frappe" checkout -q -f $branch_name
git -C "apps/erpnext" checkout -q -f $branch_name
git -C "apps/hrms" checkout -q -f $branch_name

# Resetup env and install apps
pgrep honcho | xargs kill
rm -rf ~/frappe-bench/env
bench -v setup env --python python$2
bench pip install -e ./apps/erpnext
bench pip install -e ./apps/hrms
bench start &>> ~/frappe-bench/bench_start.log &

bench --site test_site migrate
}

update_to_version 15 3.13
update_to_version 16 3.14

echo "Updating to latest version"
git -C "apps/frappe" fetch --depth 1 upstream "${GITHUB_BASE_REF:-${GITHUB_REF##*/}}"
git -C "apps/frappe" checkout -q -f FETCH_HEAD
git -C "apps/erpnext" checkout -q -f FETCH_HEAD
git -C "apps/hrms" checkout -q -f "$GITHUB_SHA"

pgrep honcho | xargs kill
rm -rf ~/frappe-bench/env
bench -v setup env
bench pip install -e ./apps/erpnext
bench pip install -e ./apps/hrms
bench start &>> ~/frappe-bench/bench_start.log &

bench --site test_site migrate

- name: Show bench output
if: ${{ always() }}
run: |
cd ~/frappe-bench
cat bench_start.log || true
cd logs
for f in ./*.log*; do
echo "Printing log: $f";
cat $f
done
10 changes: 3 additions & 7 deletions frontend/src/components/ExpenseAdvancesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<div class="flex flex-row items-start gap-3">
<FormControl
type="checkbox"
class="mt-[0.5px]"
class="mt-[1.5px]"
v-model="advance.selected"
:disabled="isReadOnly"
/>
Expand All @@ -34,7 +34,7 @@
<div class="text-xs font-normal text-gray-500">
{{ __("{0}: {1}", [
__("Unclaimed Amount"),
formatCurrency(advance.unclaimed_amount, currency),
formatCurrency(advance.unclaimed_amount, expenseClaim.currency),
]) }}
</div>
</div>
Expand Down Expand Up @@ -74,17 +74,13 @@ const props = defineProps({
type: Object,
required: true,
},
currency: {
type: String,
required: true,
},
isReadOnly: {
type: Boolean,
default: false,
},
})

const currencySymbol = computed(() => getCurrencySymbol(props.currency))
const currencySymbol = computed(() => getCurrencySymbol(props.expenseClaim.currency))

function toggleAdvanceSelection(advance) {
if (props.isReadOnly) return
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/components/ExpenseClaimItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<span>{{ claimDates }}</span>
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">
{{ formatCurrency(props.doc.total_claimed_amount, currency) }}
{{ formatCurrency(props.doc.total_claimed_amount, props.doc.currency) }}
</span>
</div>
</div>
Expand All @@ -33,7 +33,6 @@ import { computed, inject } from "vue"
import ListItem from "@/components/ListItem.vue"
import ExpenseIcon from "@/components/icons/ExpenseIcon.vue"

import { getCompanyCurrency } from "@/data/currencies"
import { formatCurrency } from "@/utils/formatters"

const dayjs = inject("$dayjs")
Expand Down Expand Up @@ -99,7 +98,6 @@ const claimDates = computed(() => {
}
})

const currency = computed(() => getCompanyCurrency(props.doc.company))

const approvalStatus = computed(() => {
return props.doc.approval_status === "Draft" ? "Pending" : props.doc.approval_status
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/components/ExpenseItems.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{{
__("{0}: {1}", [
__("Sanctioned"),
formatCurrency(item.sanctioned_amount || 0, currency),
formatCurrency(item.sanctioned_amount || 0, doc.currency),
])
}}
</span>
Expand All @@ -33,7 +33,7 @@
</div>
</div>
<span class="text-gray-700 font-normal rounded text-base">
{{ formatCurrency(item.amount, currency) }}
{{ formatCurrency(item.amount, doc.currency) }}
</span>
</div>
</div>
Expand All @@ -42,9 +42,8 @@
</template>

<script setup>
import { computed, inject } from "vue"
import { inject } from "vue"

import { getCompanyCurrency } from "@/data/currencies"
import { formatCurrency } from "@/utils/formatters"

const props = defineProps({
Expand All @@ -55,5 +54,4 @@ const props = defineProps({
})

const dayjs = inject("$dayjs")
const currency = computed(() => getCompanyCurrency(props.doc.company))
</script>
20 changes: 12 additions & 8 deletions frontend/src/components/ExpenseTaxesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<h2 class="text-base font-semibold text-gray-800">{{ __("Taxes & Charges") }} </h2>
<div class="flex flex-row gap-3 items-center">
<span class="text-base font-semibold text-gray-800">
{{ formatCurrency(expenseClaim.total_taxes_and_charges, currency) }}
{{ formatCurrency(expenseClaim.total_taxes_and_charges, expenseClaim.currency) }}
</span>
<Button
v-if="!isReadOnly"
Expand Down Expand Up @@ -35,17 +35,17 @@
{{ item.account_head }}
</div>
<div class="text-xs font-normal text-gray-500">
<span> Rate: {{ formatCurrency(item.rate, currency) }} </span>
<span> Rate: {{ formatCurrency(item.rate, expenseClaim.currency) }} </span>
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">
Amount: {{ formatCurrency(item.tax_amount, currency) }}
Amount: {{ formatCurrency(item.tax_amount, expenseClaim.currency) }}
</span>
</div>
</div>
</div>
<div class="flex flex-row justify-end items-center gap-2">
<span class="text-gray-700 font-normal rounded text-base">
{{ formatCurrency(item.total, currency) }}
{{ formatCurrency(item.total, expenseClaim.currency) }}
</span>
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</div>
Expand Down Expand Up @@ -134,16 +134,13 @@ import EmptyState from "@/components/EmptyState.vue"
import CustomIonModal from "@/components/CustomIonModal.vue"

import { formatCurrency } from "@/utils/formatters"
import { useCurrencyConversion } from "@/composables/useCurrencyConversion"

const props = defineProps({
expenseClaim: {
type: Object,
required: true,
},
currency: {
type: String,
required: true,
},
isReadOnly: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -215,6 +212,13 @@ const taxesTableFields = createResource({
})
taxesTableFields.reload()

const expenseClaimRef = computed(() => props.expenseClaim)
useCurrencyConversion(
taxesTableFields,
expenseClaimRef,
["tax_amount", "total"]
)

const modalTitle = computed(() => {
if (props.isReadOnly) return __("Expense Tax")

Expand Down
Loading
Loading