Skip to content

Commit

Permalink
Merge branch 'develop' into is-subcontracted-fieldtype
Browse files Browse the repository at this point in the history
  • Loading branch information
s-aga-r authored Apr 4, 2022
2 parents cf5f37e + e8118fc commit e80cd29
Show file tree
Hide file tree
Showing 28 changed files with 344 additions and 227 deletions.
3 changes: 2 additions & 1 deletion erpnext/accounts/doctype/payment_entry/payment_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,8 @@ frappe.ui.form.on('Payment Entry', {
to_currency: to_currency
},
callback: function(r, rt) {
frm.set_value(exchange_rate_field, r.message);
const ex_rate = flt(r.message, frm.get_field(exchange_rate_field).get_precision());
frm.set_value(exchange_rate_field, ex_rate);
}
})
},
Expand Down
2 changes: 2 additions & 0 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
if(this.frm.updating_party_details || this.frm.doc.inter_company_invoice_reference)
return;

if (this.frm.doc.__onload && this.frm.doc.__onload.load_after_mapping) return;

erpnext.utils.get_party_details(this.frm, "erpnext.accounts.party.get_party_details",
{
posting_date: this.frm.doc.posting_date,
Expand Down
3 changes: 3 additions & 0 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
}
var me = this;
if(this.frm.updating_party_details) return;

if (this.frm.doc.__onload && this.frm.doc.__onload.load_after_mapping) return;

erpnext.utils.get_party_details(this.frm,
"erpnext.accounts.party.get_party_details", {
posting_date: this.frm.doc.posting_date,
Expand Down
43 changes: 32 additions & 11 deletions erpnext/accounts/general_ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
if not from_repost:
validate_cwip_accounts(gl_map)

round_off_debit_credit(gl_map)
process_debit_credit_difference(gl_map)

if gl_map:
check_freezing_date(gl_map[0]["posting_date"], adv_adj)
Expand Down Expand Up @@ -302,12 +302,29 @@ def validate_cwip_accounts(gl_map):
)


def round_off_debit_credit(gl_map):
def process_debit_credit_difference(gl_map):
precision = get_field_precision(
frappe.get_meta("GL Entry").get_field("debit"),
currency=frappe.get_cached_value("Company", gl_map[0].company, "default_currency"),
)

voucher_type = gl_map[0].voucher_type
voucher_no = gl_map[0].voucher_no
allowance = get_debit_credit_allowance(voucher_type, precision)

debit_credit_diff = get_debit_credit_difference(gl_map, precision)
if abs(debit_credit_diff) > allowance:
raise_debit_credit_not_equal_error(debit_credit_diff, voucher_type, voucher_no)

elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
make_round_off_gle(gl_map, debit_credit_diff, precision)

debit_credit_diff = get_debit_credit_difference(gl_map, precision)
if abs(debit_credit_diff) > allowance:
raise_debit_credit_not_equal_error(debit_credit_diff, voucher_type, voucher_no)


def get_debit_credit_difference(gl_map, precision):
debit_credit_diff = 0.0
for entry in gl_map:
entry.debit = flt(entry.debit, precision)
Expand All @@ -316,20 +333,24 @@ def round_off_debit_credit(gl_map):

debit_credit_diff = flt(debit_credit_diff, precision)

if gl_map[0]["voucher_type"] in ("Journal Entry", "Payment Entry"):
return debit_credit_diff


def get_debit_credit_allowance(voucher_type, precision):
if voucher_type in ("Journal Entry", "Payment Entry"):
allowance = 5.0 / (10**precision)
else:
allowance = 0.5

if abs(debit_credit_diff) > allowance:
frappe.throw(
_("Debit and Credit not equal for {0} #{1}. Difference is {2}.").format(
gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff
)
)
return allowance

elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
make_round_off_gle(gl_map, debit_credit_diff, precision)

def raise_debit_credit_not_equal_error(debit_credit_diff, voucher_type, voucher_no):
frappe.throw(
_("Debit and Credit not equal for {0} #{1}. Difference is {2}.").format(
voucher_type, voucher_no, debit_credit_diff
)
)


def make_round_off_gle(gl_map, debit_credit_diff, precision):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,7 @@ def validate_cart_settings(doc=None, method=None):


def get_shopping_cart_settings():
if not getattr(frappe.local, "shopping_cart_settings", None):
frappe.local.shopping_cart_settings = frappe.get_doc(
"E Commerce Settings", "E Commerce Settings"
)

return frappe.local.shopping_cart_settings
return frappe.get_cached_doc("E Commerce Settings")


@frappe.whitelist(allow_guest=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ def validate(self):


def update_website_context(context):
context["lms_enabled"] = frappe.get_doc("Education Settings").enable_lms
context["lms_enabled"] = frappe.get_cached_doc("Education Settings").enable_lms
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="web-list-item transaction-list-item">
{% set today = frappe.utils.getdate(frappe.utils.nowdate()) %}
<a href = "{{ doc.route }}/" class="no-underline">
<a href = "{{ doc.route }}" class="no-underline">
<div class="row">
<div class="col-sm-4 bold">
<span class="indicator
Expand Down
4 changes: 2 additions & 2 deletions erpnext/hr/doctype/leave_application/leave_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,9 @@ def get_number_of_leave_days(
(Based on the include_holiday setting in Leave Type)"""
number_of_days = 0
if cint(half_day) == 1:
if from_date == to_date:
if getdate(from_date) == getdate(to_date):
number_of_days = 0.5
elif half_day_date and half_day_date <= to_date:
elif half_day_date and getdate(from_date) <= getdate(half_day_date) <= getdate(to_date):
number_of_days = date_diff(to_date, from_date) + 0.5
else:
number_of_days = date_diff(to_date, from_date) + 1
Expand Down
20 changes: 17 additions & 3 deletions erpnext/hr/doctype/leave_application/test_leave_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ def test_separate_leave_ledger_entry_for_boundary_applications(self):
# creates separate leave ledger entries
frappe.delete_doc_if_exists("Leave Type", "Test Leave Validation", force=1)
leave_type = frappe.get_doc(
dict(leave_type_name="Test Leave Validation", doctype="Leave Type", allow_negative=True)
dict(
leave_type_name="Test Leave Validation",
doctype="Leave Type",
allow_negative=True,
include_holiday=True,
)
).insert()

employee = get_employee()
Expand All @@ -217,8 +222,14 @@ def test_separate_leave_ledger_entry_for_boundary_applications(self):
# application across allocations

# CASE 1: from date has no allocation, to date has an allocation / both dates have allocation
start_date = add_days(year_start, -10)
application = make_leave_application(
employee.name, add_days(year_start, -10), add_days(year_start, 3), leave_type.name
employee.name,
start_date,
add_days(year_start, 3),
leave_type.name,
half_day=1,
half_day_date=start_date,
)

# 2 separate leave ledger entries
Expand Down Expand Up @@ -828,6 +839,7 @@ def test_ledger_entry_creation_on_intermediate_allocation_expiry(self):
leave_type_name="_Test_CF_leave_expiry",
is_carry_forward=1,
expire_carry_forwarded_leaves_after_days=90,
include_holiday=True,
)
leave_type.submit()

Expand All @@ -840,6 +852,8 @@ def test_ledger_entry_creation_on_intermediate_allocation_expiry(self):
leave_type=leave_type.name,
from_date=add_days(nowdate(), -3),
to_date=add_days(nowdate(), 7),
half_day=1,
half_day_date=add_days(nowdate(), -3),
description="_Test Reason",
company="_Test Company",
docstatus=1,
Expand All @@ -855,7 +869,7 @@ def test_ledger_entry_creation_on_intermediate_allocation_expiry(self):
self.assertEqual(len(leave_ledger_entry), 2)
self.assertEqual(leave_ledger_entry[0].employee, leave_application.employee)
self.assertEqual(leave_ledger_entry[0].leave_type, leave_application.leave_type)
self.assertEqual(leave_ledger_entry[0].leaves, -9)
self.assertEqual(leave_ledger_entry[0].leaves, -8.5)
self.assertEqual(leave_ledger_entry[1].leaves, -2)

def test_leave_application_creation_after_expiry(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,8 @@ def calculate_amounts(against_loan, posting_date, payment_type=""):
if payment_type == "Loan Closure":
amounts["payable_principal_amount"] = amounts["pending_principal_amount"]
amounts["interest_amount"] += amounts["unaccrued_interest"]
amounts["payable_amount"] = amounts["payable_principal_amount"] + amounts["interest_amount"]
amounts["payable_amount"] = (
amounts["payable_principal_amount"] + amounts["interest_amount"] + amounts["penalty_amount"]
)

return amounts
13 changes: 12 additions & 1 deletion erpnext/payroll/doctype/salary_slip/test_salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -1290,14 +1290,25 @@ def create_additional_salary(employee, payroll_period, amount):
return salary_date


def make_leave_application(employee, from_date, to_date, leave_type, company=None, submit=True):
def make_leave_application(
employee,
from_date,
to_date,
leave_type,
company=None,
half_day=False,
half_day_date=None,
submit=True,
):
leave_application = frappe.get_doc(
dict(
doctype="Leave Application",
employee=employee,
leave_type=leave_type,
from_date=from_date,
to_date=to_date,
half_day=half_day,
half_day_date=half_day_date,
company=company or erpnext.get_default_company() or "_Test Company",
status="Approved",
leave_approver="test@example.com",
Expand Down
21 changes: 7 additions & 14 deletions erpnext/public/js/controllers/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,17 +403,6 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
var sms_man = new erpnext.SMSManager(this.frm.doc);
}

barcode(doc, cdt, cdn) {
const d = locals[cdt][cdn];
if (!d.barcode) {
// barcode cleared, remove item
d.item_code = "";
}
// flag required for circular triggers
d._triggerd_from_barcode = true;
this.item_code(doc, cdt, cdn);
}

item_code(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);
Expand All @@ -431,9 +420,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
this.frm.doc.doctype === 'Delivery Note') {
show_batch_dialog = 1;
}
if (!item._triggerd_from_barcode) {
item.barcode = null;
}
item.barcode = null;


if(item.item_code || item.barcode || item.serial_no) {
Expand Down Expand Up @@ -539,6 +526,12 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
if(!d[k]) d[k] = v;
});

if (d.__disable_batch_serial_selector) {
// reset for future use.
d.__disable_batch_serial_selector = false;
return;
}

if (d.has_batch_no && d.has_serial_no) {
d.batch_no = undefined;
}
Expand Down
24 changes: 19 additions & 5 deletions erpnext/public/js/utils/barcode_scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
// batch_no: "LOT12", // present if batch was scanned
// serial_no: "987XYZ", // present if serial no was scanned
// }
this.scan_api =
opts.scan_api ||
"erpnext.selling.page.point_of_sale.point_of_sale.search_for_serial_or_batch_or_barcode_number";
this.scan_api = opts.scan_api || "erpnext.stock.utils.scan_barcode";
}

process_scan() {
Expand Down Expand Up @@ -52,14 +50,16 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
return;
}

me.update_table(data.item_code, data.barcode, data.batch_no, data.serial_no);
me.update_table(data);
});
}

update_table(item_code, barcode, batch_no, serial_no) {
update_table(data) {
let cur_grid = this.frm.fields_dict[this.items_table_name].grid;
let row = null;

const {item_code, barcode, batch_no, serial_no} = data;

// Check if batch is scanned and table has batch no field
let batch_no_scan =
Boolean(batch_no) && frappe.meta.has_field(cur_grid.doctype, this.batch_no_field);
Expand All @@ -84,13 +84,27 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
}

this.show_scan_message(row.idx, row.item_code);
this.set_selector_trigger_flag(row, data);
this.set_item(row, item_code);
this.set_serial_no(row, serial_no);
this.set_batch_no(row, batch_no);
this.set_barcode(row, barcode);
this.clean_up();
}

// batch and serial selector is reduandant when all info can be added by scan
// this flag on item row is used by transaction.js to avoid triggering selector
set_selector_trigger_flag(row, data) {
const {batch_no, serial_no, has_batch_no, has_serial_no} = data;

const require_selecting_batch = has_batch_no && !batch_no;
const require_selecting_serial = has_serial_no && !serial_no;

if (!(require_selecting_batch || require_selecting_serial)) {
row.__disable_batch_serial_selector = true;
}
}

set_item(row, item_code) {
const item_data = { item_code: item_code };
item_data[this.qty_field] = (row[this.qty_field] || 0) + 1;
Expand Down
27 changes: 4 additions & 23 deletions erpnext/selling/page/point_of_sale/point_of_sale.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@


import json
from typing import Dict, Optional

import frappe
from frappe.utils.nestedset import get_root_of

from erpnext.accounts.doctype.pos_invoice.pos_invoice import get_stock_availability
from erpnext.accounts.doctype.pos_profile.pos_profile import get_child_nodes, get_item_groups
from erpnext.stock.utils import scan_barcode


def search_by_term(search_term, warehouse, price_list):
Expand Down Expand Up @@ -150,29 +152,8 @@ def get_items(start, page_length, price_list, item_group, pos_profile, search_te


@frappe.whitelist()
def search_for_serial_or_batch_or_barcode_number(search_value):
# search barcode no
barcode_data = frappe.db.get_value(
"Item Barcode", {"barcode": search_value}, ["barcode", "parent as item_code"], as_dict=True
)
if barcode_data:
return barcode_data

# search serial no
serial_no_data = frappe.db.get_value(
"Serial No", search_value, ["name as serial_no", "item_code"], as_dict=True
)
if serial_no_data:
return serial_no_data

# search batch no
batch_no_data = frappe.db.get_value(
"Batch", search_value, ["name as batch_no", "item as item_code"], as_dict=True
)
if batch_no_data:
return batch_no_data

return {}
def search_for_serial_or_batch_or_barcode_number(search_value: str) -> Dict[str, Optional[str]]:
return scan_barcode(search_value)


def get_conditions(search_term):
Expand Down
2 changes: 1 addition & 1 deletion erpnext/setup/doctype/company/company_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def get_data():
"goal_doctype_link": "company",
"goal_field": "base_grand_total",
"date_field": "posting_date",
"filter_str": "docstatus = 1 and is_opening != 'Yes'",
"filters": {"docstatus": 1, "is_opening": ("!=", "Yes")},
"aggregation": "sum",
},
"fieldname": "company",
Expand Down
Loading

0 comments on commit e80cd29

Please sign in to comment.