Merge branch 'version-13-hotfix' into se-supplier-customer
This commit is contained in:
commit
be157e7467
8
.github/helper/semgrep_rules/translate.py
vendored
8
.github/helper/semgrep_rules/translate.py
vendored
@ -51,3 +51,11 @@ _(f"what" + f"this is also not cool")
|
||||
_("")
|
||||
# ruleid: frappe-translation-empty-string
|
||||
_('')
|
||||
|
||||
|
||||
class Test:
|
||||
# ok: frappe-translation-python-splitting
|
||||
def __init__(
|
||||
args
|
||||
):
|
||||
pass
|
||||
|
4
.github/helper/semgrep_rules/translate.yml
vendored
4
.github/helper/semgrep_rules/translate.yml
vendored
@ -44,8 +44,8 @@ rules:
|
||||
pattern-either:
|
||||
- pattern: _(...) + _(...)
|
||||
- pattern: _("..." + "...")
|
||||
- pattern-regex: '_\([^\)]*\\\s*' # lines broken by `\`
|
||||
- pattern-regex: '_\(\s*\n' # line breaks allowed by python for using ( )
|
||||
- pattern-regex: '[\s\.]_\([^\)]*\\\s*' # lines broken by `\`
|
||||
- pattern-regex: '[\s\.]_\(\s*\n' # line breaks allowed by python for using ( )
|
||||
message: |
|
||||
Do not split strings inside translate function. Do not concatenate using translate functions.
|
||||
Please refer: https://frappeframework.com/docs/user/en/translations
|
||||
|
9
.github/helper/semgrep_rules/ux.js
vendored
Normal file
9
.github/helper/semgrep_rules/ux.js
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
// ok: frappe-missing-translate-function-js
|
||||
frappe.msgprint('{{ _("Both login and password required") }}');
|
||||
|
||||
// ruleid: frappe-missing-translate-function-js
|
||||
frappe.msgprint('What');
|
||||
|
||||
// ok: frappe-missing-translate-function-js
|
||||
frappe.throw(' {{ _("Both login and password required") }}. ');
|
18
.github/helper/semgrep_rules/ux.py
vendored
18
.github/helper/semgrep_rules/ux.py
vendored
@ -2,30 +2,30 @@ import frappe
|
||||
from frappe import msgprint, throw, _
|
||||
|
||||
|
||||
# ruleid: frappe-missing-translate-function
|
||||
# ruleid: frappe-missing-translate-function-python
|
||||
throw("Error Occured")
|
||||
|
||||
# ruleid: frappe-missing-translate-function
|
||||
# ruleid: frappe-missing-translate-function-python
|
||||
frappe.throw("Error Occured")
|
||||
|
||||
# ruleid: frappe-missing-translate-function
|
||||
# ruleid: frappe-missing-translate-function-python
|
||||
frappe.msgprint("Useful message")
|
||||
|
||||
# ruleid: frappe-missing-translate-function
|
||||
# ruleid: frappe-missing-translate-function-python
|
||||
msgprint("Useful message")
|
||||
|
||||
|
||||
# ok: frappe-missing-translate-function
|
||||
# ok: frappe-missing-translate-function-python
|
||||
translatedmessage = _("Hello")
|
||||
|
||||
# ok: frappe-missing-translate-function
|
||||
# ok: frappe-missing-translate-function-python
|
||||
throw(translatedmessage)
|
||||
|
||||
# ok: frappe-missing-translate-function
|
||||
# ok: frappe-missing-translate-function-python
|
||||
msgprint(translatedmessage)
|
||||
|
||||
# ok: frappe-missing-translate-function
|
||||
# ok: frappe-missing-translate-function-python
|
||||
msgprint(_("Helpful message"))
|
||||
|
||||
# ok: frappe-missing-translate-function
|
||||
# ok: frappe-missing-translate-function-python
|
||||
frappe.throw(_("Error occured"))
|
||||
|
23
.github/helper/semgrep_rules/ux.yml
vendored
23
.github/helper/semgrep_rules/ux.yml
vendored
@ -1,15 +1,30 @@
|
||||
rules:
|
||||
- id: frappe-missing-translate-function
|
||||
- id: frappe-missing-translate-function-python
|
||||
pattern-either:
|
||||
- patterns:
|
||||
- pattern: frappe.msgprint("...", ...)
|
||||
- pattern-not: frappe.msgprint(_("..."), ...)
|
||||
- pattern-not: frappe.msgprint(__("..."), ...)
|
||||
- patterns:
|
||||
- pattern: frappe.throw("...", ...)
|
||||
- pattern-not: frappe.throw(_("..."), ...)
|
||||
- pattern-not: frappe.throw(__("..."), ...)
|
||||
message: |
|
||||
All user facing text must be wrapped in translate function. Please refer to translation documentation. https://frappeframework.com/docs/user/en/guides/basics/translations
|
||||
languages: [python, javascript, json]
|
||||
languages: [python]
|
||||
severity: ERROR
|
||||
|
||||
- id: frappe-missing-translate-function-js
|
||||
pattern-either:
|
||||
- patterns:
|
||||
- pattern: frappe.msgprint("...", ...)
|
||||
- pattern-not: frappe.msgprint(__("..."), ...)
|
||||
# ignore microtemplating e.g. msgprint("{{ _("server side translation") }}")
|
||||
- pattern-not: frappe.msgprint("=~/\{\{.*\_.*\}\}/i", ...)
|
||||
- patterns:
|
||||
- pattern: frappe.throw("...", ...)
|
||||
- pattern-not: frappe.throw(__("..."), ...)
|
||||
# ignore microtemplating
|
||||
- pattern-not: frappe.throw("=~/\{\{.*\_.*\}\}/i", ...)
|
||||
message: |
|
||||
All user facing text must be wrapped in translate function. Please refer to translation documentation. https://frappeframework.com/docs/user/en/guides/basics/translations
|
||||
languages: [javascript]
|
||||
severity: ERROR
|
||||
|
@ -39,7 +39,11 @@ class JournalEntry(AccountsController):
|
||||
self.validate_multi_currency()
|
||||
self.set_amounts_in_company_currency()
|
||||
self.validate_debit_credit_amount()
|
||||
self.validate_total_debit_and_credit()
|
||||
|
||||
# Do not validate while importing via data import
|
||||
if not frappe.flags.in_import:
|
||||
self.validate_total_debit_and_credit()
|
||||
|
||||
self.validate_against_jv()
|
||||
self.validate_reference_doc()
|
||||
self.set_against_account()
|
||||
|
@ -42,8 +42,9 @@ class POSInvoiceMergeLog(Document):
|
||||
if return_against_status != "Consolidated":
|
||||
# if return entry is not getting merged in the current pos closing and if it is not consolidated
|
||||
bold_unconsolidated = frappe.bold("not Consolidated")
|
||||
msg = (_("Row #{}: Original Invoice {} of return invoice {} is {}. ")
|
||||
msg = (_("Row #{}: Original Invoice {} of return invoice {} is {}.")
|
||||
.format(d.idx, bold_return_against, bold_pos_invoice, bold_unconsolidated))
|
||||
msg += " "
|
||||
msg += _("Original invoice should be consolidated before or along with the return invoice.")
|
||||
msg += "<br><br>"
|
||||
msg += _("You can add original invoice {} manually to proceed.").format(bold_return_against)
|
||||
@ -274,9 +275,9 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
|
||||
closing_entry.db_set('error_message', '')
|
||||
closing_entry.update_opening_entry()
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
frappe.db.rollback()
|
||||
message_log = frappe.message_log.pop()
|
||||
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
||||
error_message = safe_load_json(message_log)
|
||||
|
||||
if closing_entry:
|
||||
@ -300,9 +301,9 @@ def cancel_merge_logs(merge_logs, closing_entry=None):
|
||||
closing_entry.db_set('error_message', '')
|
||||
closing_entry.update_opening_entry(for_cancel=True)
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
frappe.db.rollback()
|
||||
message_log = frappe.message_log.pop()
|
||||
message_log = frappe.message_log.pop() if frappe.message_log else str(e)
|
||||
error_message = safe_load_json(message_log)
|
||||
|
||||
if closing_entry:
|
||||
@ -348,11 +349,9 @@ def job_already_enqueued(job_name):
|
||||
return True
|
||||
|
||||
def safe_load_json(message):
|
||||
JSONDecodeError = ValueError if six.PY2 else json.JSONDecodeError
|
||||
|
||||
try:
|
||||
json_message = json.loads(message).get('message')
|
||||
except JSONDecodeError:
|
||||
except Exception:
|
||||
json_message = message
|
||||
|
||||
return json_message
|
@ -1,24 +1,42 @@
|
||||
<h1 class="text-center" style="page-break-before:always">{{ filters.party[0] }}</h1>
|
||||
<h3 class="text-center">{{ _("Statement of Accounts") }}</h3>
|
||||
<div class="page-break">
|
||||
<div id="header-html" class="hidden-pdf">
|
||||
{% if letter_head %}
|
||||
<div class="letter-head text-center">{{ letter_head.content }}</div>
|
||||
<hr style="height:2px;border-width:0;color:black;background-color:black;">
|
||||
{% endif %}
|
||||
</div>
|
||||
<div id="footer-html" class="visible-pdf">
|
||||
{% if letter_head.footer %}
|
||||
<div class="letter-head-footer">
|
||||
<hr style="border-width:0;color:black;background-color:black;padding-bottom:2px;">
|
||||
{{ letter_head.footer }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<h2 class="text-center">{{ _("STATEMENTS OF ACCOUNTS") }}</h2>
|
||||
<div>
|
||||
<h5 style="float: left;">{{ _("Customer: ") }} <b>{{filters.party[0] }}</b></h5>
|
||||
<h5 style="float: right;">
|
||||
{{ _("Date: ") }}
|
||||
<b>{{ frappe.format(filters.from_date, 'Date')}}
|
||||
{{ _("to") }}
|
||||
{{ frappe.format(filters.to_date, 'Date')}}</b>
|
||||
</h5>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<h5 class="text-center">
|
||||
{{ frappe.format(filters.from_date, 'Date')}}
|
||||
{{ _("to") }}
|
||||
{{ frappe.format(filters.to_date, 'Date')}}
|
||||
</h5>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 12%">{{ _("Date") }}</th>
|
||||
<th style="width: 15%">{{ _("Ref") }}</th>
|
||||
<th style="width: 25%">{{ _("Party") }}</th>
|
||||
<th style="width: 15%">{{ _("Debit") }}</th>
|
||||
<th style="width: 15%">{{ _("Credit") }}</th>
|
||||
<th style="width: 18%">{{ _("Balance (Dr - Cr)") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 12%">{{ _("Date") }}</th>
|
||||
<th style="width: 15%">{{ _("Reference") }}</th>
|
||||
<th style="width: 25%">{{ _("Remarks") }}</th>
|
||||
<th style="width: 15%">{{ _("Debit") }}</th>
|
||||
<th style="width: 15%">{{ _("Credit") }}</th>
|
||||
<th style="width: 18%">{{ _("Balance (Dr - Cr)") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in data %}
|
||||
<tr>
|
||||
{% if(row.posting_date) %}
|
||||
@ -58,32 +76,34 @@
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<br><br>
|
||||
{% if ageing %}
|
||||
<h3 class="text-center">{{ _("Ageing Report Based On ") }} {{ ageing.ageing_based_on }}</h3>
|
||||
<h5 class="text-center">
|
||||
{{ _("Up to " ) }} {{ frappe.format(filters.to_date, 'Date')}}
|
||||
</h5>
|
||||
<br>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 12%">30 Days</th>
|
||||
<th style="width: 15%">60 Days</th>
|
||||
<th style="width: 25%">90 Days</th>
|
||||
<th style="width: 15%">120 Days</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range1, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range2, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range3, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range4, currency=filters.presentation_currency) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<p class="text-right text-muted">Printed On {{ frappe.format(frappe.utils.get_datetime(), 'Datetime') }}</p>
|
||||
</table>
|
||||
<br>
|
||||
{% if ageing %}
|
||||
<h4 class="text-center">{{ _("Ageing Report based on ") }} {{ ageing.ageing_based_on }}
|
||||
{{ _("up to " ) }} {{ frappe.format(filters.to_date, 'Date')}}
|
||||
</h4>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 25%">30 Days</th>
|
||||
<th style="width: 25%">60 Days</th>
|
||||
<th style="width: 25%">90 Days</th>
|
||||
<th style="width: 25%">120 Days</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range1, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range2, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range3, currency=filters.presentation_currency) }}</td>
|
||||
<td>{{ frappe.utils.fmt_money(ageing.range4, currency=filters.presentation_currency) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if terms_and_conditions %}
|
||||
<div>
|
||||
{{ terms_and_conditions }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
@ -1,6 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_workflow": 1,
|
||||
"autoname": "Prompt",
|
||||
"creation": "2020-05-22 16:46:18.712954",
|
||||
"doctype": "DocType",
|
||||
@ -28,9 +27,11 @@
|
||||
"customers",
|
||||
"preferences",
|
||||
"orientation",
|
||||
"section_break_14",
|
||||
"include_ageing",
|
||||
"ageing_based_on",
|
||||
"section_break_14",
|
||||
"letter_head",
|
||||
"terms_and_conditions",
|
||||
"section_break_1",
|
||||
"enable_auto_email",
|
||||
"section_break_18",
|
||||
@ -270,10 +271,22 @@
|
||||
"fieldname": "body",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Body"
|
||||
},
|
||||
{
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"label": "Letter Head",
|
||||
"options": "Letter Head"
|
||||
},
|
||||
{
|
||||
"fieldname": "terms_and_conditions",
|
||||
"fieldtype": "Link",
|
||||
"label": "Terms and Conditions",
|
||||
"options": "Terms and Conditions"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-08-08 08:47:09.185728",
|
||||
"modified": "2021-05-21 10:14:22.426672",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Process Statement Of Accounts",
|
||||
|
@ -64,6 +64,9 @@ def get_report_pdf(doc, consolidated=True):
|
||||
tax_id = frappe.get_doc('Customer', entry.customer).tax_id
|
||||
presentation_currency = get_party_account_currency('Customer', entry.customer, doc.company) \
|
||||
or doc.currency or get_company_currency(doc.company)
|
||||
if doc.letter_head:
|
||||
from frappe.www.printview import get_letter_head
|
||||
letter_head = get_letter_head(doc, 0)
|
||||
|
||||
filters= frappe._dict({
|
||||
'from_date': doc.from_date,
|
||||
@ -91,7 +94,10 @@ def get_report_pdf(doc, consolidated=True):
|
||||
continue
|
||||
|
||||
html = frappe.render_template(template_path, \
|
||||
{"filters": filters, "data": res, "ageing": ageing[0] if (doc.include_ageing and ageing) else None})
|
||||
{"filters": filters, "data": res, "ageing": ageing[0] if doc.include_ageing else None,
|
||||
"letter_head": letter_head if doc.letter_head else None,
|
||||
"terms_and_conditions": frappe.db.get_value('Terms and Conditions', doc.terms_and_conditions, 'terms')
|
||||
if doc.terms_and_conditions else None})
|
||||
|
||||
html = frappe.render_template(base_template_path, {"body": html, \
|
||||
"css": get_print_style(), "title": "Statement For " + entry.customer})
|
||||
|
@ -1137,7 +1137,6 @@ class SalesInvoice(SellingController):
|
||||
"""
|
||||
self.set_serial_no_against_delivery_note()
|
||||
self.validate_serial_against_delivery_note()
|
||||
self.validate_serial_against_sales_invoice()
|
||||
|
||||
def set_serial_no_against_delivery_note(self):
|
||||
for item in self.items:
|
||||
@ -1168,26 +1167,6 @@ class SalesInvoice(SellingController):
|
||||
frappe.throw(_("Row {0}: {1} Serial numbers required for Item {2}. You have provided {3}.").format(
|
||||
item.idx, item.qty, item.item_code, len(si_serial_nos)))
|
||||
|
||||
def validate_serial_against_sales_invoice(self):
|
||||
""" check if serial number is already used in other sales invoice """
|
||||
for item in self.items:
|
||||
if not item.serial_no:
|
||||
continue
|
||||
|
||||
for serial_no in item.serial_no.split("\n"):
|
||||
serial_no_details = frappe.db.get_value("Serial No", serial_no,
|
||||
["sales_invoice", "item_code"], as_dict=1)
|
||||
|
||||
if not serial_no_details:
|
||||
continue
|
||||
|
||||
if serial_no_details.sales_invoice and serial_no_details.item_code == item.item_code \
|
||||
and self.name != serial_no_details.sales_invoice:
|
||||
sales_invoice_company = frappe.db.get_value("Sales Invoice", serial_no_details.sales_invoice, "company")
|
||||
if sales_invoice_company == self.company:
|
||||
frappe.throw(_("Serial Number: {0} is already referenced in Sales Invoice: {1}")
|
||||
.format(serial_no, serial_no_details.sales_invoice))
|
||||
|
||||
def update_project(self):
|
||||
if self.project:
|
||||
project = frappe.get_doc("Project", self.project)
|
||||
|
@ -933,12 +933,6 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertFalse(frappe.db.get_value("Serial No", serial_nos[0], "warehouse"))
|
||||
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0],
|
||||
"delivery_document_no"), si.name)
|
||||
self.assertEqual(frappe.db.get_value("Serial No", serial_nos[0], "sales_invoice"),
|
||||
si.name)
|
||||
|
||||
# check if the serial number is already linked with any other Sales Invoice
|
||||
_si = frappe.copy_doc(si.as_dict())
|
||||
self.assertRaises(frappe.ValidationError, _si.insert)
|
||||
|
||||
return si
|
||||
|
||||
|
@ -165,7 +165,7 @@ def add_data_for_operating_activities(
|
||||
if profit_data:
|
||||
profit_data.update({
|
||||
"indent": 1,
|
||||
"parent_account": get_mapper_for(light_mappers, position=0)['section_header']
|
||||
"parent_account": get_mapper_for(light_mappers, position=1)['section_header']
|
||||
})
|
||||
data.append(profit_data)
|
||||
section_data.append(profit_data)
|
||||
@ -312,10 +312,10 @@ def add_data_for_other_activities(
|
||||
def compute_data(filters, company_currency, profit_data, period_list, light_mappers, full_mapper):
|
||||
data = []
|
||||
|
||||
operating_activities_mapper = get_mapper_for(light_mappers, position=0)
|
||||
operating_activities_mapper = get_mapper_for(light_mappers, position=1)
|
||||
other_mappers = [
|
||||
get_mapper_for(light_mappers, position=1),
|
||||
get_mapper_for(light_mappers, position=2)
|
||||
get_mapper_for(light_mappers, position=2),
|
||||
get_mapper_for(light_mappers, position=3)
|
||||
]
|
||||
|
||||
if operating_activities_mapper:
|
||||
|
@ -166,6 +166,11 @@ frappe.query_reports["General Ledger"] = {
|
||||
"fieldname": "show_cancelled_entries",
|
||||
"label": __("Show Cancelled Entries"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"fieldname": "show_net_values_in_party_account",
|
||||
"label": __("Show Net Values in Party Account"),
|
||||
"fieldtype": "Check"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -344,6 +344,9 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
|
||||
consolidated_gle = OrderedDict()
|
||||
group_by = group_by_field(filters.get('group_by'))
|
||||
|
||||
if filters.get('show_net_values_in_party_account'):
|
||||
account_type_map = get_account_type_map(filters.get('company'))
|
||||
|
||||
def update_value_in_dict(data, key, gle):
|
||||
data[key].debit += flt(gle.debit)
|
||||
data[key].credit += flt(gle.credit)
|
||||
@ -351,6 +354,24 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
|
||||
data[key].debit_in_account_currency += flt(gle.debit_in_account_currency)
|
||||
data[key].credit_in_account_currency += flt(gle.credit_in_account_currency)
|
||||
|
||||
if filters.get('show_net_values_in_party_account') and \
|
||||
account_type_map.get(data[key].account) in ('Receivable', 'Payable'):
|
||||
net_value = flt(data[key].debit) - flt(data[key].credit)
|
||||
net_value_in_account_currency = flt(data[key].debit_in_account_currency) \
|
||||
- flt(data[key].credit_in_account_currency)
|
||||
|
||||
if net_value < 0:
|
||||
dr_or_cr = 'credit'
|
||||
rev_dr_or_cr = 'debit'
|
||||
else:
|
||||
dr_or_cr = 'debit'
|
||||
rev_dr_or_cr = 'credit'
|
||||
|
||||
data[key][dr_or_cr] = abs(net_value)
|
||||
data[key][dr_or_cr+'_in_account_currency'] = abs(net_value_in_account_currency)
|
||||
data[key][rev_dr_or_cr] = 0
|
||||
data[key][rev_dr_or_cr+'_in_account_currency'] = 0
|
||||
|
||||
if data[key].against_voucher and gle.against_voucher:
|
||||
data[key].against_voucher += ', ' + gle.against_voucher
|
||||
|
||||
@ -388,6 +409,12 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
|
||||
|
||||
return totals, entries
|
||||
|
||||
def get_account_type_map(company):
|
||||
account_type_map = frappe._dict(frappe.get_all('Account', fields=['name', 'account_type'],
|
||||
filters={'company': company}, as_list=1))
|
||||
|
||||
return account_type_map
|
||||
|
||||
def get_result_as_list(data, filters):
|
||||
balance, balance_in_account_currency = 0, 0
|
||||
inv_details = get_supplier_invoice_details()
|
||||
|
@ -81,8 +81,7 @@ def convert_to_presentation_currency(gl_entries, currency_info, company):
|
||||
presentation_currency = currency_info['presentation_currency']
|
||||
company_currency = currency_info['company_currency']
|
||||
|
||||
pl_accounts = [d.name for d in frappe.get_list('Account',
|
||||
filters={'report_type': 'Profit and Loss', 'company': company})]
|
||||
account_currencies = list(set(entry['account_currency'] for entry in gl_entries))
|
||||
|
||||
for entry in gl_entries:
|
||||
account = entry['account']
|
||||
@ -92,10 +91,15 @@ def convert_to_presentation_currency(gl_entries, currency_info, company):
|
||||
credit_in_account_currency = flt(entry['credit_in_account_currency'])
|
||||
account_currency = entry['account_currency']
|
||||
|
||||
if account_currency != presentation_currency:
|
||||
value = debit or credit
|
||||
if len(account_currencies) == 1 and account_currency == presentation_currency:
|
||||
if entry.get('debit'):
|
||||
entry['debit'] = debit_in_account_currency
|
||||
|
||||
date = entry['posting_date'] if account in pl_accounts else currency_info['report_date']
|
||||
if entry.get('credit'):
|
||||
entry['credit'] = credit_in_account_currency
|
||||
else:
|
||||
value = debit or credit
|
||||
date = currency_info['report_date']
|
||||
converted_value = convert(value, presentation_currency, company_currency, date)
|
||||
|
||||
if entry.get('debit'):
|
||||
@ -104,13 +108,6 @@ def convert_to_presentation_currency(gl_entries, currency_info, company):
|
||||
if entry.get('credit'):
|
||||
entry['credit'] = converted_value
|
||||
|
||||
elif account_currency == presentation_currency:
|
||||
if entry.get('debit'):
|
||||
entry['debit'] = debit_in_account_currency
|
||||
|
||||
if entry.get('credit'):
|
||||
entry['credit'] = credit_in_account_currency
|
||||
|
||||
converted_gl_list.append(entry)
|
||||
|
||||
return converted_gl_list
|
||||
|
@ -76,12 +76,12 @@ status_map = {
|
||||
["Stopped", "eval:self.status == 'Stopped'"],
|
||||
["Cancelled", "eval:self.docstatus == 2"],
|
||||
["Pending", "eval:self.status != 'Stopped' and self.per_ordered == 0 and self.docstatus == 1"],
|
||||
["Partially Ordered", "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1"],
|
||||
["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
|
||||
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"],
|
||||
["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||
["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||
["Partially Ordered", "eval:self.status != 'Stopped' and self.per_ordered < 100 and self.per_ordered > 0 and self.docstatus == 1"],
|
||||
["Manufactured", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Manufacture'"]
|
||||
],
|
||||
"Bank Transaction": [
|
||||
|
@ -183,11 +183,11 @@ def new_bank_transaction(transaction):
|
||||
bank_account = frappe.db.get_value("Bank Account", dict(integration_id=transaction["account_id"]))
|
||||
|
||||
if float(transaction["amount"]) >= 0:
|
||||
debit = float(transaction["amount"])
|
||||
credit = 0
|
||||
else:
|
||||
debit = 0
|
||||
credit = abs(float(transaction["amount"]))
|
||||
credit = float(transaction["amount"])
|
||||
else:
|
||||
debit = abs(float(transaction["amount"]))
|
||||
credit = 0
|
||||
|
||||
status = "Pending" if transaction["pending"] == "True" else "Settled"
|
||||
|
||||
|
@ -2,23 +2,41 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Training Event', {
|
||||
onload_post_render: function(frm) {
|
||||
onload_post_render: function (frm) {
|
||||
frm.get_field("employees").grid.set_multiple_add("employee");
|
||||
},
|
||||
refresh: function(frm) {
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__("Training Result"), function() {
|
||||
refresh: function (frm) {
|
||||
if (!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__("Training Result"), function () {
|
||||
frappe.route_options = {
|
||||
training_event: frm.doc.name
|
||||
}
|
||||
};
|
||||
frappe.set_route("List", "Training Result");
|
||||
});
|
||||
frm.add_custom_button(__("Training Feedback"), function() {
|
||||
frm.add_custom_button(__("Training Feedback"), function () {
|
||||
frappe.route_options = {
|
||||
training_event: frm.doc.name
|
||||
}
|
||||
};
|
||||
frappe.set_route("List", "Training Feedback");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Training Event Employee", {
|
||||
employee: function (frm) {
|
||||
let emp = [];
|
||||
for (let d in frm.doc.employees) {
|
||||
if (frm.doc.employees[d].employee) {
|
||||
emp.push(frm.doc.employees[d].employee);
|
||||
}
|
||||
}
|
||||
frm.set_query("employee", "employees", function () {
|
||||
return {
|
||||
filters: {
|
||||
name: ["NOT IN", emp]
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,241 +1,80 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-08-08 05:33:39.965305",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"actions": [],
|
||||
"creation": "2016-08-08 05:33:39.965305",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"employee",
|
||||
"employee_name",
|
||||
"department",
|
||||
"column_break_3",
|
||||
"status",
|
||||
"attendance",
|
||||
"is_mandatory"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "employee",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Employee",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "employee",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Employee",
|
||||
"options": "Employee"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "employee.employee_name",
|
||||
"fieldname": "employee_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Employee Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fetch_from": "employee.employee_name",
|
||||
"fieldname": "employee_name",
|
||||
"fieldtype": "Read Only",
|
||||
"label": "Employee Name"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_from": "employee.department",
|
||||
"fieldname": "department",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Department",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Department",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fetch_from": "employee.department",
|
||||
"fieldname": "department",
|
||||
"fieldtype": "Link",
|
||||
"label": "Department",
|
||||
"options": "Department",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Open",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Open\nInvited\nCompleted\nFeedback Submitted",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
"allow_on_submit": 1,
|
||||
"default": "Open",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"options": "Open\nInvited\nCompleted\nFeedback Submitted"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "attendance",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Attendance",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Mandatory\nOptional",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldname": "attendance",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Attendance",
|
||||
"options": "Present\nAbsent"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"default": "1",
|
||||
"fieldname": "is_mandatory",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Is Mandatory"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-01-30 11:28:16.170333",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Training Event Employee",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-05-21 12:41:59.336237",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Training Event Employee",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -11,16 +11,18 @@
|
||||
"event": "Submit",
|
||||
"idx": 0,
|
||||
"is_standard": 1,
|
||||
"message": "<table class=\"panel-header\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr height=\"10\"></tr>\n <tr>\n <td width=\"15\"></td>\n <td>\n <div class=\"text-medium text-muted\">\n <span>{{_(\"Training Event:\")}} {{ doc.event_name }}</span>\n </div>\n </td>\n <td width=\"15\"></td>\n </tr>\n <tr height=\"10\"></tr>\n</table>\n\n<table class=\"panel-body\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr height=\"10\"></tr>\n <tr>\n <td width=\"15\"></td>\n <td>\n <div>\n <ul class=\"list-unstyled\" style=\"line-height: 1.7\">\n <li>{{ doc.introduction }}</li>\n <li>{{_(\"Event Location\")}}: <b>{{ doc.location }}</b></li>\n {% set start = frappe.utils.get_datetime(doc.start_time) %}\n {% set end = frappe.utils.get_datetime(doc.end_time) %}\n {% if start.date() == end.date() %}\n <li>{{_(\"Date\")}}: <b>{{ start.strftime(\"%A, %d %b %Y\") }}</b></li>\n <li>\n {{_(\"Timing\")}}: <b>{{ start.strftime(\"%I:%M %p\") + ' to ' + end.strftime(\"%I:%M %p\") }}</b>\n </li>\n {% else %}\n <li>{{_(\"Start Time\")}}: <b>{{ start.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n </li>\n <li>{{_(\"End Time\")}}: <b>{{ end.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n </li>\n {% endif %}\n </ul>\n {{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}\n </div>\n </td>\n <td width=\"15\"></td>\n </tr>\n <tr height=\"10\"></tr>\n</table>",
|
||||
"modified": "2019-11-29 15:38:31.805409",
|
||||
"message": "<table class=\"panel-header\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr height=\"10\"></tr>\n <tr>\n <td width=\"15\"></td>\n <td>\n <div class=\"text-medium text-muted\">\n <span>{{_(\"Training Event:\")}} {{ doc.event_name }}</span>\n </div>\n </td>\n <td width=\"15\"></td>\n </tr>\n <tr height=\"10\"></tr>\n</table>\n\n<table class=\"panel-body\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n <tr height=\"10\"></tr>\n <tr>\n <td width=\"15\"></td>\n <td>\n <div>\n {{ doc.introduction }}\n <ul class=\"list-unstyled\" style=\"line-height: 1.7\">\n <li>{{_(\"Event Location\")}}: <b>{{ doc.location }}</b></li>\n {% set start = frappe.utils.get_datetime(doc.start_time) %}\n {% set end = frappe.utils.get_datetime(doc.end_time) %}\n {% if start.date() == end.date() %}\n <li>{{_(\"Date\")}}: <b>{{ start.strftime(\"%A, %d %b %Y\") }}</b></li>\n <li>\n {{_(\"Timing\")}}: <b>{{ start.strftime(\"%I:%M %p\") + ' to ' + end.strftime(\"%I:%M %p\") }}</b>\n </li>\n {% else %}\n <li>{{_(\"Start Time\")}}: <b>{{ start.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n </li>\n <li>{{_(\"End Time\")}}: <b>{{ end.strftime(\"%A, %d %b %Y at %I:%M %p\") }}</b>\n </li>\n {% endif %}\n <li>{{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}</li>\n {% if doc.is_mandatory %}\n <li>Note: This Training Event is mandatory</li>\n {% endif %}\n </ul>\n </div>\n </td>\n <td width=\"15\"></td>\n </tr>\n <tr height=\"10\"></tr>\n</table>",
|
||||
"modified": "2021-05-24 16:29:13.165930",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Training Scheduled",
|
||||
"owner": "Administrator",
|
||||
"recipients": [
|
||||
{
|
||||
"email_by_document_field": "employee_emails"
|
||||
"receiver_by_document_field": "employee_emails"
|
||||
}
|
||||
],
|
||||
"send_system_notification": 0,
|
||||
"send_to_all_assignees": 0,
|
||||
"subject": "Training Scheduled: {{ doc.name }}"
|
||||
}
|
@ -35,6 +35,9 @@
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>{{ _('Event Link') }}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}</li>
|
||||
{% if doc.is_mandatory %}
|
||||
<li>Note: This Training Event is mandatory</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -780,3 +780,4 @@ erpnext.patches.v13_0.germany_make_custom_fields
|
||||
erpnext.patches.v13_0.germany_fill_debtor_creditor_number
|
||||
erpnext.patches.v13_0.set_pos_closing_as_failed
|
||||
erpnext.patches.v13_0.update_timesheet_changes
|
||||
erpnext.patches.v13_0.set_training_event_attendance
|
||||
|
9
erpnext/patches/v13_0/set_training_event_attendance.py
Normal file
9
erpnext/patches/v13_0/set_training_event_attendance.py
Normal file
@ -0,0 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('hr', 'doctype', 'training_event')
|
||||
frappe.reload_doc('hr', 'doctype', 'training_event_employee')
|
||||
|
||||
frappe.db.sql("update `tabTraining Event Employee` set `attendance` = 'Present'")
|
||||
frappe.db.sql("update `tabTraining Event Employee` set `is_mandatory` = 1 where `attendance` = 'Mandatory'")
|
@ -7,25 +7,30 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"employee_details_section",
|
||||
"naming_series",
|
||||
"employee",
|
||||
"employee_name",
|
||||
"salary_component",
|
||||
"type",
|
||||
"amount",
|
||||
"ref_doctype",
|
||||
"ref_docname",
|
||||
"amended_from",
|
||||
"column_break_5",
|
||||
"company",
|
||||
"department",
|
||||
"salary_details_section",
|
||||
"salary_component",
|
||||
"type",
|
||||
"currency",
|
||||
"amount",
|
||||
"column_break_13",
|
||||
"is_recurring",
|
||||
"payroll_date",
|
||||
"from_date",
|
||||
"to_date",
|
||||
"payroll_date",
|
||||
"is_recurring",
|
||||
"properties_and_references_section",
|
||||
"deduct_full_tax_on_selected_payroll_date",
|
||||
"ref_doctype",
|
||||
"ref_docname",
|
||||
"column_break_22",
|
||||
"overwrite_salary_structure_amount",
|
||||
"deduct_full_tax_on_selected_payroll_date"
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -81,7 +86,7 @@
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:(doc.is_recurring==0)",
|
||||
"description": "Date on which this component is applied",
|
||||
"description": "The date on which Salary Component with Amount will contribute for Earnings/Deduction in Salary Slip. ",
|
||||
"fieldname": "payroll_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
@ -159,6 +164,7 @@
|
||||
"fieldname": "ref_docname",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Reference Document",
|
||||
"no_copy": 1,
|
||||
"options": "ref_doctype",
|
||||
"read_only": 1
|
||||
},
|
||||
@ -171,11 +177,34 @@
|
||||
"print_hide": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "employee_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Employee Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_22",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "salary_details_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Salary Details"
|
||||
},
|
||||
{
|
||||
"fieldname": "properties_and_references_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Properties and References"
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-03-31 22:33:59.098532",
|
||||
"modified": "2021-05-26 11:10:00.812698",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Payroll",
|
||||
"name": "Additional Salary",
|
||||
|
@ -8,7 +8,7 @@ from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_
|
||||
from erpnext.projects.report.project_profitability.project_profitability import execute
|
||||
|
||||
class TestProjectProfitability(unittest.TestCase):
|
||||
@classmethod
|
||||
|
||||
def setUp(self):
|
||||
emp = make_employee('test_employee_9@salary.com', company='_Test Company')
|
||||
if not frappe.db.exists('Salary Component', 'Timesheet Component'):
|
||||
@ -21,7 +21,7 @@ class TestProjectProfitability(unittest.TestCase):
|
||||
self.sales_invoice.due_date = nowdate()
|
||||
self.sales_invoice.submit()
|
||||
|
||||
frappe.db.set_value("HR Settings", "HR Settings", "standard_working_hours", 8)
|
||||
frappe.db.set_value('HR Settings', None, 'standard_working_hours', 8)
|
||||
|
||||
def test_project_profitability(self):
|
||||
filters = {
|
||||
@ -55,4 +55,4 @@ class TestProjectProfitability(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
frappe.get_doc("Sales Invoice", self.sales_invoice.name).cancel()
|
||||
frappe.get_doc("Salary Slip", self.salary_slip.name).cancel()
|
||||
frappe.get_doc("Timesheet", self.timesheet.name).cancel()
|
||||
frappe.get_doc("Timesheet", self.timesheet.name).cancel()
|
||||
|
@ -241,7 +241,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
|
||||
|
||||
send_email() {
|
||||
const frm = this.events.get_frm();
|
||||
const recipients = this.email_dialog.get_values().recipients;
|
||||
const recipients = this.email_dialog.get_values().email_id;
|
||||
const doc = this.doc || frm.doc;
|
||||
const print_format = frm.pos_print_format;
|
||||
|
||||
|
@ -90,12 +90,6 @@ frappe.ui.form.on("Company", {
|
||||
frm.toggle_enable("default_currency", (frm.doc.__onload &&
|
||||
!frm.doc.__onload.transactions_exist));
|
||||
|
||||
if (frm.has_perm('write')) {
|
||||
frm.add_custom_button(__('Create Tax Template'), function() {
|
||||
frm.trigger("make_default_tax_template");
|
||||
});
|
||||
}
|
||||
|
||||
if (frappe.perm.has_perm("Cost Center", 0, 'read')) {
|
||||
frm.add_custom_button(__('Cost Centers'), function() {
|
||||
frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name});
|
||||
@ -121,17 +115,21 @@ frappe.ui.form.on("Company", {
|
||||
}
|
||||
|
||||
if (frm.has_perm('write')) {
|
||||
frm.add_custom_button(__('Default Tax Template'), function() {
|
||||
frm.add_custom_button(__('Create Tax Template'), function() {
|
||||
frm.trigger("make_default_tax_template");
|
||||
}, __('Create'));
|
||||
}, __('Manage'));
|
||||
}
|
||||
|
||||
if (frappe.user.has_role('System Manager')) {
|
||||
if (frm.has_perm('write')) {
|
||||
frm.add_custom_button(__('Delete Transactions'), function() {
|
||||
frm.trigger("delete_company_transactions");
|
||||
}, __('Manage'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
erpnext.company.set_chart_of_accounts_options(frm.doc);
|
||||
|
||||
if (!frappe.user.has_role('System Manager')) {
|
||||
frm.get_field("delete_company_transactions").hide();
|
||||
}
|
||||
},
|
||||
|
||||
make_default_tax_template: function(frm) {
|
||||
@ -145,11 +143,6 @@ frappe.ui.form.on("Company", {
|
||||
})
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
if(frm.get_field("delete_company_transactions").$input)
|
||||
frm.get_field("delete_company_transactions").$input.addClass("btn-danger");
|
||||
},
|
||||
|
||||
country: function(frm) {
|
||||
erpnext.company.set_chart_of_accounts_options(frm.doc);
|
||||
},
|
||||
|
@ -99,7 +99,6 @@
|
||||
"company_description",
|
||||
"registration_info",
|
||||
"registration_details",
|
||||
"delete_company_transactions",
|
||||
"lft",
|
||||
"rgt",
|
||||
"old_parent"
|
||||
@ -666,11 +665,6 @@
|
||||
"oldfieldname": "registration_details",
|
||||
"oldfieldtype": "Code"
|
||||
},
|
||||
{
|
||||
"fieldname": "delete_company_transactions",
|
||||
"fieldtype": "Button",
|
||||
"label": "Delete Company Transactions"
|
||||
},
|
||||
{
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
@ -747,7 +741,7 @@
|
||||
"image_field": "company_logo",
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2021-02-16 15:53:37.167589",
|
||||
"modified": "2021-05-07 03:11:28.189740",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Company",
|
||||
|
@ -59,13 +59,15 @@ class GlobalDefaults(Document):
|
||||
|
||||
# Make property setters to hide rounded total fields
|
||||
for doctype in ("Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
|
||||
"Supplier Quotation", "Purchase Order", "Purchase Invoice"):
|
||||
"Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"):
|
||||
make_property_setter(doctype, "base_rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
|
||||
make_property_setter(doctype, "base_rounded_total", "print_hide", 1, "Check", validate_fields_for_doctype=False)
|
||||
|
||||
make_property_setter(doctype, "rounded_total", "hidden", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
|
||||
make_property_setter(doctype, "rounded_total", "print_hide", self.disable_rounded_total, "Check", validate_fields_for_doctype=False)
|
||||
|
||||
make_property_setter(doctype, "disable_rounded_total", "default", cint(self.disable_rounded_total), "Text", validate_fields_for_doctype=False)
|
||||
|
||||
def toggle_in_words(self):
|
||||
self.disable_in_words = cint(self.disable_in_words)
|
||||
|
||||
|
@ -600,7 +600,6 @@ frappe.ui.form.on('Stock Entry', {
|
||||
add_to_transit: function(frm) {
|
||||
if(frm.doc.add_to_transit && frm.doc.purpose=='Material Transfer') {
|
||||
frm.set_value('to_warehouse', '');
|
||||
frm.set_value('stock_entry_type', 'Material Transfer');
|
||||
frm.fields_dict.to_warehouse.get_query = function() {
|
||||
return {
|
||||
filters:{
|
||||
@ -610,12 +609,13 @@ frappe.ui.form.on('Stock Entry', {
|
||||
}
|
||||
};
|
||||
};
|
||||
frm.trigger('set_tansit_warehouse');
|
||||
frm.trigger('set_transit_warehouse');
|
||||
}
|
||||
},
|
||||
|
||||
set_tansit_warehouse: function(frm) {
|
||||
if(frm.doc.add_to_transit && frm.doc.purpose == 'Material Transfer' && !frm.doc.to_warehouse) {
|
||||
set_transit_warehouse: function(frm) {
|
||||
if(frm.doc.add_to_transit && frm.doc.purpose == 'Material Transfer' && !frm.doc.to_warehouse
|
||||
&& frm.doc.from_warehouse) {
|
||||
let dt = frm.doc.from_warehouse ? 'Warehouse' : 'Company';
|
||||
let dn = frm.doc.from_warehouse ? frm.doc.from_warehouse : frm.doc.company;
|
||||
frappe.db.get_value(dt, dn, 'default_in_transit_warehouse', (r) => {
|
||||
@ -985,7 +985,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
},
|
||||
|
||||
from_warehouse: function(doc) {
|
||||
this.frm.trigger('set_tansit_warehouse');
|
||||
this.frm.trigger('set_transit_warehouse');
|
||||
this.set_warehouse_in_children(doc.items, "s_warehouse", doc.from_warehouse);
|
||||
},
|
||||
|
||||
|
@ -598,6 +598,8 @@
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval: doc.purpose=='Material Transfer' && !doc.outgoing_stock_entry",
|
||||
"fetch_from": "stock_entry_type.add_to_transit",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "add_to_transit",
|
||||
"fieldtype": "Check",
|
||||
"label": "Add to Transit",
|
||||
|
@ -6,7 +6,8 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"purpose"
|
||||
"purpose",
|
||||
"add_to_transit"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@ -18,10 +19,17 @@
|
||||
"options": "\nMaterial Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nMaterial Consumption for Manufacture\nManufacture\nRepack\nSend to Subcontractor",
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval: doc.purpose == 'Material Transfer'",
|
||||
"fieldname": "add_to_transit",
|
||||
"fieldtype": "Check",
|
||||
"label": "Add to Transit"
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"modified": "2020-08-10 23:24:37.160817",
|
||||
"modified": "2021-05-21 11:27:01.144110",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Entry Type",
|
||||
|
@ -7,4 +7,6 @@ from __future__ import unicode_literals
|
||||
from frappe.model.document import Document
|
||||
|
||||
class StockEntryType(Document):
|
||||
pass
|
||||
def validate(self):
|
||||
if self.add_to_transit and self.purpose != 'Material Transfer':
|
||||
self.add_to_transit = 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user