Skip to content

Commit

Permalink
feat: Business Trip (#43)
Browse files Browse the repository at this point in the history
* feat: Business Trip

* docs: Business Trip

* fix: compatibility with HRMS

* feat: add translations for Business Trip
  • Loading branch information
barredterra authored Oct 1, 2024
1 parent 6d6bdce commit e9d28bc
Show file tree
Hide file tree
Showing 24 changed files with 1,366 additions and 47 deletions.
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ App to hold regional code for Germany, built on top of ERPNext.

- Custom fields in **Employee** (tax information, etc.)
- List of religios denominations ("Konfessionen")
- List of German health insurance providers

Requires [HRMS](https://github.com/frappe/hrms) to be installed first.

- List of German health insurance providers (depends on HRMS)
- Create **Business Letters** from a template and print or email them to your customers or suppliers
- Record **Business Trips** and pay out allowances to your employees (dt. Reisekostenabrechnung) (depends on HRMS)

## Installation

> [!NOTE]
> Some features of this app depend on the [HRMS](https://github.com/frappe/hrms) app. If you want to use them, you need to install the HRMS app before installing this app.
### On Frappe Cloud

1. Go to https://frappecloud.com/dashboard/#/sites and click the "New Site" button.
2. In Step 2 ("Select apps to install"), select "ERPNext" and "ERPNext Germany".
3. Complete the new site wizard.
You can find ERPNext Germany in the [Frappe Cloud Marketplace](https://frappecloud.com/marketplace/apps/erpnext_germany).
Please refer to the [Frappe Cloud documentation](https://frappecloud.com/docs/installing-an-app) on how to install an app.

### Local

Expand All @@ -54,6 +54,16 @@ After that, you can install the app on required site (let's say demo.com ) by ru
bench --site demo.com install-app erpnext_germany
```

## Business Trip

Before an employee can create a **Business Trip**, you should configure the available regions and their travel allowances in the **Business Trip Region** list.

When a **Business Trip** is submitted, it creates a draft **Expense Claim** for the employee's travel allowances. The **Expense Claim** can be approved and submitted as usual.

The receipts for transport and accommodation can be attached, but are not processed automatically. You can check them, create a **Purchase Invoice** and pay the respective amount to the employee.

You can use our [Banking app](https://github.com/alyf-de/banking) to reconcile the **Expense Claims** and **Purchase Invoices** with the respective **Bank Transactions**.

### License

GNU GPL V3. See the `LICENSE` file for more information.
12 changes: 12 additions & 0 deletions erpnext_germany/custom_fields.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .constants import REGISTER_COURTS
from frappe import get_installed_apps


def _(message: str) -> str:
Expand Down Expand Up @@ -174,4 +175,15 @@ def get_custom_fields():
],
}

if "hrms" in get_installed_apps():
custom_fields["Expense Claim"] = [
{
"fieldtype": "Link",
"fieldname": "business_trip",
"label": _("Business Trip"),
"options": "Business Trip",
"insert_after": "company",
},
]

return custom_fields
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2024, ALYF GmbH and contributors
// For license information, please see license.txt

frappe.ui.form.on("Business Trip", {
setup(frm) {
frm.set_query("employee", erpnext.queries.employee);
},

from_date: function (frm) {
if (!frm.doc.to_date) {
frm.set_value("to_date", frm.doc.from_date);
}

frm.fields_dict.to_date.datepicker.update({
minDate: frm.doc.from_date ? new Date(frm.doc.from_date) : null,
});
},

to_date: function (frm) {
frm.fields_dict.from_date.datepicker.update({
maxDate: frm.doc.to_date ? new Date(frm.doc.to_date) : null,
});
},
});

frappe.ui.form.on("Business Trip Journey", {
journeys_add(frm, cdt, cdn) {
frappe.model.set_value(cdt, cdn, "date", frm.doc.from_date);
},
});

frappe.ui.form.on("Business Trip Accommodation", {
accommodations_add(frm, cdt, cdn) {
frappe.model.set_value(cdt, cdn, "from_date", frm.doc.from_date);
frappe.model.set_value(cdt, cdn, "to_date", frm.doc.to_date);
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
{
"actions": [],
"autoname": "BT-.####",
"creation": "2022-10-12 21:52:42.547420",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"employee",
"company",
"currency",
"title",
"column_break_2",
"employee_name",
"status",
"section_break_4",
"from_date",
"column_break_6",
"to_date",
"section_break_8",
"project",
"column_break_10",
"customer",
"section_break_12",
"journeys",
"section_break_14",
"accommodations",
"section_break_16",
"region",
"allowances",
"total_allowance",
"amended_from"
],
"fields": [
{
"fieldname": "employee",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Employee",
"options": "Employee",
"reqd": 1
},
{
"fetch_from": "employee.company",
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"options": "Company"
},
{
"fetch_from": "company.default_currency",
"fieldname": "currency",
"fieldtype": "Link",
"label": "Currency",
"options": "Currency"
},
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"reqd": 1
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break"
},
{
"fetch_from": "employee.employee_name",
"fieldname": "employee_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Employee Name",
"read_only": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:!doc.__islocal",
"fieldname": "status",
"fieldtype": "Select",
"label": "Status",
"options": "\nSubmitted\nApproved\nRejected\nPaid\nBilled"
},
{
"fieldname": "section_break_4",
"fieldtype": "Section Break"
},
{
"fieldname": "from_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "From Date",
"reqd": 1
},
{
"fieldname": "column_break_6",
"fieldtype": "Column Break"
},
{
"fieldname": "to_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "To Date",
"reqd": 1
},
{
"fieldname": "section_break_8",
"fieldtype": "Section Break"
},
{
"fieldname": "project",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Project",
"options": "Project"
},
{
"fieldname": "column_break_10",
"fieldtype": "Column Break"
},
{
"fetch_from": "project.customer",
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer"
},
{
"fieldname": "section_break_12",
"fieldtype": "Section Break"
},
{
"fieldname": "journeys",
"fieldtype": "Table",
"label": "Journeys",
"options": "Business Trip Journey"
},
{
"fieldname": "section_break_14",
"fieldtype": "Section Break"
},
{
"fieldname": "accommodations",
"fieldtype": "Table",
"label": "Accommodations",
"options": "Business Trip Accommodation"
},
{
"fieldname": "section_break_16",
"fieldtype": "Section Break"
},
{
"fieldname": "region",
"fieldtype": "Link",
"label": "Region",
"options": "Business Trip Region"
},
{
"fieldname": "allowances",
"fieldtype": "Table",
"label": "Allowances",
"options": "Business Trip Allowance"
},
{
"fieldname": "total_allowance",
"fieldtype": "Currency",
"label": "Total Allowance",
"read_only": 1
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
"label": "Amended From",
"no_copy": 1,
"options": "Business Trip",
"print_hide": 1,
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [
{
"link_doctype": "Expense Claim",
"link_fieldname": "business_trip"
}
],
"modified": "2024-09-04 23:27:34.065131",
"modified_by": "Administrator",
"module": "ERPNext Germany",
"name": "Business Trip",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"submit": 1,
"write": 1
},
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Projects Manager",
"share": 1,
"submit": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Employee",
"share": 1,
"write": 1
},
{
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User"
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "title"
}
Loading

0 comments on commit e9d28bc

Please sign in to comment.