Merge branch 'develop' into employee-util-report
This commit is contained in:
commit
926a9aed58
@ -582,7 +582,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
if(frm.doc.payment_type == "Receive")
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
|
||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount, 1);
|
||||
else
|
||||
frm.events.set_unallocated_amount(frm);
|
||||
},
|
||||
@ -606,9 +606,9 @@ frappe.ui.form.on('Payment Entry', {
|
||||
{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
|
||||
{fieldtype:"Section Break"},
|
||||
{fieldtype:"Link", label:__("Cost Center"), fieldname:"cost_center", options:"Cost Center",
|
||||
"get_query": function() {
|
||||
return {
|
||||
"filters": {"company": frm.doc.company}
|
||||
"get_query": function() {
|
||||
return {
|
||||
"filters": {"company": frm.doc.company}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -743,7 +743,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
});
|
||||
},
|
||||
|
||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount, paid_amount_change) {
|
||||
var total_positive_outstanding_including_order = 0;
|
||||
var total_negative_outstanding = 0;
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
@ -800,22 +800,15 @@ frappe.ui.form.on('Payment Entry', {
|
||||
//If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
||||
row.allocated_amount = 0;
|
||||
|
||||
} else if (frappe.flags.allocate_payment_amount != 0 && !row.allocated_amount) {
|
||||
if (row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
||||
if (row.outstanding_amount >= allocated_positive_outstanding) {
|
||||
row.allocated_amount = allocated_positive_outstanding;
|
||||
} else {
|
||||
row.allocated_amount = row.outstanding_amount;
|
||||
}
|
||||
|
||||
} else if (frappe.flags.allocate_payment_amount != 0 && (!row.allocated_amount || paid_amount_change)) {
|
||||
if (row.outstanding_amount > 0 && allocated_positive_outstanding >= 0) {
|
||||
row.allocated_amount = (row.outstanding_amount >= allocated_positive_outstanding) ?
|
||||
allocated_positive_outstanding : row.outstanding_amount;
|
||||
allocated_positive_outstanding -= flt(row.allocated_amount);
|
||||
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
|
||||
if (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) {
|
||||
row.allocated_amount = -1*allocated_negative_outstanding;
|
||||
} else {
|
||||
row.allocated_amount = row.outstanding_amount;
|
||||
};
|
||||
|
||||
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
|
||||
row.allocated_amount = (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) ?
|
||||
-1*allocated_negative_outstanding : row.outstanding_amount;
|
||||
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd
|
||||
gl_map = process_gl_map(gl_map, merge_entries)
|
||||
if gl_map and len(gl_map) > 1:
|
||||
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
|
||||
else:
|
||||
# Post GL Map proccess there may no be any GL Entries
|
||||
elif gl_map:
|
||||
frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."))
|
||||
else:
|
||||
make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
|
||||
|
@ -90,6 +90,8 @@ class AccountsController(TransactionBase):
|
||||
self.ensure_supplier_is_not_blocked()
|
||||
|
||||
self.validate_date_with_fiscal_year()
|
||||
self.validate_party_accounts()
|
||||
|
||||
self.validate_inter_company_reference()
|
||||
|
||||
self.set_incoming_rate()
|
||||
@ -233,6 +235,23 @@ class AccountsController(TransactionBase):
|
||||
validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company,
|
||||
self.meta.get_label(date_field), self)
|
||||
|
||||
def validate_party_accounts(self):
|
||||
if self.doctype not in ('Sales Invoice', 'Purchase Invoice'):
|
||||
return
|
||||
|
||||
if self.doctype == 'Sales Invoice':
|
||||
party_account_field = 'debit_to'
|
||||
item_field = 'income_account'
|
||||
else:
|
||||
party_account_field = 'credit_to'
|
||||
item_field = 'expense_account'
|
||||
|
||||
for item in self.get('items'):
|
||||
if item.get(item_field) == self.get(party_account_field):
|
||||
frappe.throw(_("Row {0}: {1} {2} cannot be same as {3} (Party Account) {4}").format(item.idx,
|
||||
frappe.bold(frappe.unscrub(item_field)), item.get(item_field),
|
||||
frappe.bold(frappe.unscrub(party_account_field)), self.get(party_account_field)))
|
||||
|
||||
def validate_inter_company_reference(self):
|
||||
if self.doctype not in ('Purchase Invoice', 'Purchase Receipt', 'Purchase Order'):
|
||||
return
|
||||
@ -240,7 +259,7 @@ class AccountsController(TransactionBase):
|
||||
if self.is_internal_transfer():
|
||||
if not (self.get('inter_company_reference') or self.get('inter_company_invoice_reference')
|
||||
or self.get('inter_company_order_reference')):
|
||||
msg = _("Internal Sale or Delivery Reference missing. ")
|
||||
msg = _("Internal Sale or Delivery Reference missing.")
|
||||
msg += _("Please create purchase from internal sale or delivery document itself")
|
||||
frappe.throw(msg, title=_("Internal Sales Reference Missing"))
|
||||
|
||||
|
@ -262,7 +262,8 @@ def copy_attributes_to_variant(item, variant):
|
||||
# copy non no-copy fields
|
||||
|
||||
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
||||
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate"]
|
||||
"show_variant_in_website", "opening_stock", "variant_of", "valuation_rate",
|
||||
"has_variants", "attributes"]
|
||||
|
||||
if item.variant_based_on=='Manufacturer':
|
||||
# don't copy manufacturer values if based on part no
|
||||
|
@ -773,3 +773,4 @@ erpnext.patches.v13_0.fix_non_unique_represents_company
|
||||
erpnext.patches.v12_0.add_document_type_field_for_italy_einvoicing
|
||||
erpnext.patches.v13_0.make_non_standard_user_type #13-04-2021
|
||||
erpnext.patches.v13_0.update_shipment_status
|
||||
erpnext.patches.v13_0.remove_attribute_field_from_item_variant_setting
|
||||
|
@ -0,0 +1,8 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
"""Remove has_variants and attribute fields from item variant settings."""
|
||||
frappe.reload_doc("stock", "doctype", "Item Variant Settings")
|
||||
|
||||
frappe.db.sql("""delete from `tabVariant Field`
|
||||
where field_name in ('attributes', 'has_variants')""")
|
@ -179,9 +179,6 @@ class Project(Document):
|
||||
if self.percent_complete == 100:
|
||||
self.status = "Completed"
|
||||
|
||||
else:
|
||||
self.status = "Open"
|
||||
|
||||
def update_costing(self):
|
||||
from_time_sheet = frappe.db.sql("""select
|
||||
sum(costing_amount) as costing_amount,
|
||||
|
@ -32,7 +32,8 @@ frappe.ui.form.on("Task", {
|
||||
|
||||
frm.set_query("parent_task", function () {
|
||||
let filters = {
|
||||
"is_group": 1
|
||||
"is_group": 1,
|
||||
"name": ["!=", frm.doc.name]
|
||||
};
|
||||
if (frm.doc.project) filters["project"] = frm.doc.project;
|
||||
return {
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2019-10-15 12:33:21.845329",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
@ -86,12 +87,14 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "upload_xml_invoices_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Upload XML Invoices"
|
||||
}
|
||||
],
|
||||
"modified": "2020-05-25 21:32:49.064579",
|
||||
"links": [],
|
||||
"modified": "2021-04-24 10:33:12.250687",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Regional",
|
||||
"name": "Import Supplier Invoice",
|
||||
|
@ -28,14 +28,19 @@ class ImportSupplierInvoice(Document):
|
||||
self.name = "Import Invoice on " + format_datetime(self.creation)
|
||||
|
||||
def import_xml_data(self):
|
||||
import_file = frappe.get_doc("File", {"file_url": self.zip_file})
|
||||
zip_file = frappe.get_doc("File", {
|
||||
"file_url": self.zip_file,
|
||||
"attached_to_doctype": self.doctype,
|
||||
"attached_to_name": self.name
|
||||
})
|
||||
|
||||
self.publish("File Import", _("Processing XML Files"), 1, 3)
|
||||
|
||||
self.file_count = 0
|
||||
self.purchase_invoices_count = 0
|
||||
self.default_uom = frappe.db.get_value("Stock Settings", fieldname="stock_uom")
|
||||
|
||||
with zipfile.ZipFile(get_full_path(self.zip_file)) as zf:
|
||||
with zipfile.ZipFile(zip_file.get_full_path()) as zf:
|
||||
for file_name in zf.namelist():
|
||||
content = get_file_content(file_name, zf)
|
||||
file_content = bs(content, "xml")
|
||||
@ -126,8 +131,7 @@ class ImportSupplierInvoice(Document):
|
||||
|
||||
@frappe.whitelist()
|
||||
def process_file_data(self):
|
||||
self.status = "Processing File Data"
|
||||
self.save()
|
||||
self.db_set("status", "Processing File Data", notify=True, commit=True)
|
||||
frappe.enqueue_doc(self.doctype, self.name, "import_xml_data", queue="long", timeout=3600)
|
||||
|
||||
def publish(self, title, message, count, total):
|
||||
@ -381,24 +385,3 @@ def create_uom(uom):
|
||||
new_uom.uom_name = uom
|
||||
new_uom.save()
|
||||
return new_uom.uom_name
|
||||
|
||||
def get_full_path(file_name):
|
||||
"""Returns file path from given file name"""
|
||||
file_path = file_name
|
||||
|
||||
if "/" not in file_path:
|
||||
file_path = "/files/" + file_path
|
||||
|
||||
if file_path.startswith("/private/files/"):
|
||||
file_path = get_files_path(*file_path.split("/private/files/", 1)[1].split("/"), is_private=1)
|
||||
|
||||
elif file_path.startswith("/files/"):
|
||||
file_path = get_files_path(*file_path.split("/files/", 1)[1].split("/"))
|
||||
|
||||
elif file_path.startswith("http"):
|
||||
pass
|
||||
|
||||
elif not self.file_url:
|
||||
frappe.throw(_("There is some problem with the file url: {0}").format(file_path))
|
||||
|
||||
return file_path
|
||||
|
@ -199,7 +199,7 @@ class Gstr1Report(object):
|
||||
self.item_tax_rate = frappe._dict()
|
||||
|
||||
items = frappe.db.sql("""
|
||||
select item_code, parent, taxable_value, item_tax_rate
|
||||
select item_code, parent, taxable_value, base_net_amount, item_tax_rate
|
||||
from `tab%s Item`
|
||||
where parent in (%s)
|
||||
""" % (self.doctype, ', '.join(['%s']*len(self.invoices))), tuple(self.invoices), as_dict=1)
|
||||
@ -207,7 +207,7 @@ class Gstr1Report(object):
|
||||
for d in items:
|
||||
if d.item_code not in self.invoice_items.get(d.parent, {}):
|
||||
self.invoice_items.setdefault(d.parent, {}).setdefault(d.item_code,
|
||||
sum(i.get('taxable_value', 0) for i in items
|
||||
sum((i.get('taxable_value', 0) or i.get('base_net_amount', 0)) for i in items
|
||||
if i.item_code == d.item_code and i.parent == d.parent))
|
||||
|
||||
item_tax_rate = {}
|
||||
|
@ -63,7 +63,7 @@ class Item(WebsiteGenerator):
|
||||
if self.variant_of:
|
||||
if not self.item_code:
|
||||
template_item_name = frappe.db.get_value("Item", self.variant_of, "item_name")
|
||||
self.item_code = make_variant_item_code(self.variant_of, template_item_name, self)
|
||||
make_variant_item_code(self.variant_of, template_item_name, self)
|
||||
else:
|
||||
from frappe.model.naming import set_name_by_naming_series
|
||||
set_name_by_naming_series(self)
|
||||
@ -674,10 +674,10 @@ class Item(WebsiteGenerator):
|
||||
if not records: return
|
||||
document = _("Stock Reconciliation") if len(records) == 1 else _("Stock Reconciliations")
|
||||
|
||||
msg = _("The items {0} and {1} are present in the following {2} : ").format(
|
||||
msg = _("The items {0} and {1} are present in the following {2} :").format(
|
||||
frappe.bold(old_name), frappe.bold(new_name), document)
|
||||
|
||||
msg += '<br>'
|
||||
msg += ' <br>'
|
||||
msg += ', '.join([get_link_to_form("Stock Reconciliation", d.parent) for d in records]) + "<br><br>"
|
||||
|
||||
msg += _("Note: To merge the items, create a separate Stock Reconciliation for the old item {0}").format(
|
||||
|
@ -13,10 +13,11 @@ class ItemVariantSettings(Document):
|
||||
def set_default_fields(self):
|
||||
self.fields = []
|
||||
fields = frappe.get_meta('Item').fields
|
||||
exclude_fields = ["naming_series", "item_code", "item_name", "show_in_website",
|
||||
exclude_fields = {"naming_series", "item_code", "item_name", "show_in_website",
|
||||
"show_variant_in_website", "standard_rate", "opening_stock", "image", "description",
|
||||
"variant_of", "valuation_rate", "description", "barcodes",
|
||||
"website_image", "thumbnail", "website_specifiations", "web_long_description"]
|
||||
"website_image", "thumbnail", "website_specifiations", "web_long_description",
|
||||
"has_variants", "attributes"}
|
||||
|
||||
for d in fields:
|
||||
if not d.no_copy and d.fieldname not in exclude_fields and \
|
||||
|
@ -12,7 +12,7 @@
|
||||
"url": "https://github.com/frappe/erpnext/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"snyk": "^1.290.1"
|
||||
"snyk": "^1.518.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"onscan.js": "^1.5.2"
|
||||
|
Loading…
Reference in New Issue
Block a user