Merge pull request #19957 from nextchamp-saqib/pos-serial-no-fix
fix: display serial no selection on adding items to cart
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
index deedafd..33ae454 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
@@ -15,8 +15,8 @@
with open(frappe.uploaded_file, "rb") as upfile:
fcontent = upfile.read()
else:
- from frappe.utils.file_manager import get_uploaded_content
- fname, fcontent = get_uploaded_content()
+ fcontent = frappe.local.uploaded_file
+ fname = frappe.local.uploaded_filename
if frappe.safe_encode(fname).lower().endswith("csv".encode('utf-8')):
from frappe.utils.csvutils import read_csv_content
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
index 971d308..f73fb10 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:title",
@@ -439,19 +440,20 @@
},
{
"default": "0",
- "depends_on": "eval:!doc.mixed_conditions",
+ "depends_on": "eval:!doc.mixed_conditions && doc.price_or_product_discount == 'Price'",
"fieldname": "same_item",
"fieldtype": "Check",
"label": "Same Item"
},
{
- "depends_on": "eval:!doc.same_item || doc.mixed_conditions",
+ "depends_on": "eval:(!doc.same_item || doc.apply_on == 'Transaction') || doc.mixed_conditions",
"fieldname": "free_item",
"fieldtype": "Link",
"label": "Free Item",
"options": "Item"
},
{
+ "default": "0",
"fieldname": "free_qty",
"fieldtype": "Float",
"label": "Qty"
@@ -554,7 +556,8 @@
],
"icon": "fa fa-gift",
"idx": 1,
- "modified": "2019-10-15 12:39:40.399792",
+ "links": [],
+ "modified": "2019-12-13 15:48:48.331495",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index e871d98..b99c07e 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -182,7 +182,7 @@
def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
from erpnext.accounts.doctype.pricing_rule.utils import (get_pricing_rules,
- get_applied_pricing_rules, get_pricing_rule_items)
+ get_applied_pricing_rules, get_pricing_rule_items, get_product_discount_rule)
if isinstance(doc, string_types):
doc = json.loads(doc)
@@ -241,9 +241,11 @@
if pricing_rule.coupon_code_based==1 and args.coupon_code==None:
return item_details
- if (not pricing_rule.validate_applied_rule and
- pricing_rule.price_or_product_discount == "Price"):
- apply_price_discount_pricing_rule(pricing_rule, item_details, args)
+ if not pricing_rule.validate_applied_rule:
+ if pricing_rule.price_or_product_discount == "Price":
+ apply_price_discount_rule(pricing_rule, item_details, args)
+ else:
+ get_product_discount_rule(pricing_rule, item_details, doc)
item_details.has_pricing_rule = 1
@@ -293,7 +295,7 @@
'child_docname': args.get('child_docname')
})
-def apply_price_discount_pricing_rule(pricing_rule, item_details, args):
+def apply_price_discount_rule(pricing_rule, item_details, args):
item_details.pricing_rule_for = pricing_rule.rate_or_discount
if ((pricing_rule.margin_type == 'Amount' and pricing_rule.currency == args.currency)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 637e503..87f6822 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -7,7 +7,7 @@
import frappe, copy, json
from frappe import throw, _
from six import string_types
-from frappe.utils import flt, cint, get_datetime
+from frappe.utils import flt, cint, get_datetime, get_link_to_form, today
from erpnext.setup.doctype.item_group.item_group import get_child_item_groups
from erpnext.stock.doctype.warehouse.warehouse import get_child_warehouses
from erpnext.stock.get_item_details import get_conversion_factor
@@ -284,7 +284,7 @@
status = True
# if user has created item price against the transaction UOM
- if rule.get("uom") == args.get("uom"):
+ if args and rule.get("uom") == args.get("uom"):
conversion_factor = 1.0
if status and (flt(rate) >= (flt(rule.min_amt) * conversion_factor)
@@ -408,7 +408,8 @@
conditions = get_other_conditions(conditions, values, doc)
pricing_rules = frappe.db.sql(""" Select `tabPricing Rule`.* from `tabPricing Rule`
- where {conditions} """.format(conditions = conditions), values, as_dict=1)
+ where {conditions} and `tabPricing Rule`.disable = 0
+ """.format(conditions = conditions), values, as_dict=1)
if pricing_rules:
pricing_rules = filter_pricing_rules_for_qty_amount(doc.total_qty,
@@ -420,39 +421,65 @@
doc.set('apply_discount_on', d.apply_discount_on)
for field in ['additional_discount_percentage', 'discount_amount']:
- if not d.get(field): continue
-
pr_field = ('discount_percentage'
if field == 'additional_discount_percentage' else field)
+ if not d.get(pr_field): continue
+
if d.validate_applied_rule and doc.get(field) < d.get(pr_field):
frappe.msgprint(_("User has not applied rule on the invoice {0}")
.format(doc.name))
else:
doc.set(field, d.get(pr_field))
+
+ doc.calculate_taxes_and_totals()
elif d.price_or_product_discount == 'Product':
- apply_pricing_rule_for_free_items(doc, d)
+ item_details = frappe._dict({'parenttype': doc.doctype})
+ get_product_discount_rule(d, item_details, doc)
+ apply_pricing_rule_for_free_items(doc, item_details.free_item_data)
+ doc.set_missing_values()
def get_applied_pricing_rules(item_row):
return (item_row.get("pricing_rules").split(',')
if item_row.get("pricing_rules") else [])
-def apply_pricing_rule_for_free_items(doc, pricing_rule):
- if pricing_rule.get('free_item'):
+def get_product_discount_rule(pricing_rule, item_details, doc=None):
+ free_item = (pricing_rule.free_item
+ if not pricing_rule.same_item or pricing_rule.apply_on == 'Transaction' else item_details.item_code)
+
+ if not free_item:
+ frappe.throw(_("Free item not set in the pricing rule {0}")
+ .format(get_link_to_form("Pricing Rule", pricing_rule.name)))
+
+ item_details.free_item_data = {
+ 'item_code': free_item,
+ 'qty': pricing_rule.free_qty or 1,
+ 'rate': pricing_rule.free_item_rate or 0,
+ 'price_list_rate': pricing_rule.free_item_rate or 0,
+ 'is_free_item': 1
+ }
+
+ item_data = frappe.get_cached_value('Item', free_item, ['item_name',
+ 'description', 'stock_uom'], as_dict=1)
+
+ item_details.free_item_data.update(item_data)
+ item_details.free_item_data['uom'] = pricing_rule.free_item_uom or item_data.stock_uom
+ item_details.free_item_data['conversion_factor'] = get_conversion_factor(free_item,
+ item_details.free_item_data['uom']).get("conversion_factor", 1)
+
+ if item_details.get("parenttype") == 'Purchase Order':
+ item_details.free_item_data['schedule_date'] = doc.schedule_date if doc else today()
+
+ if item_details.get("parenttype") == 'Sales Order':
+ item_details.free_item_data['delivery_date'] = doc.delivery_date if doc else today()
+
+def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
+ if pricing_rule_args.get('item_code'):
items = [d.item_code for d in doc.items
- if d.item_code == (d.item_code
- if pricing_rule.get('same_item') else pricing_rule.get('free_item')) and d.is_free_item]
+ if d.item_code == (pricing_rule_args.get("item_code")) and d.is_free_item]
if not items:
- doc.append('items', {
- 'item_code': pricing_rule.get('free_item'),
- 'qty': pricing_rule.get('free_qty'),
- 'uom': pricing_rule.get('free_item_uom'),
- 'rate': pricing_rule.get('free_item_rate') or 0,
- 'is_free_item': 1
- })
-
- doc.set_missing_values()
+ doc.append('items', pricing_rule_args)
def get_pricing_rule_items(pr_doc):
apply_on_data = []
diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html
index 4081723..50947ec 100644
--- a/erpnext/accounts/report/financial_statements.html
+++ b/erpnext/accounts/report/financial_statements.html
@@ -1,5 +1,6 @@
{%
var report_columns = report.get_columns_for_print();
+ report_columns = report_columns.filter(col => !col.hidden);
if (report_columns.length > 8) {
frappe.throw(__("Too many columns. Export the report and print it using a spreadsheet application."));
@@ -15,34 +16,35 @@
height: 37px;
}
</style>
-{% var letterhead= filters.letter_head || (frappe.get_doc(":Company", filters.company) && frappe.get_doc(":Company", filters.company).default_letter_head) %}
-{% if(letterhead) { %}
-<div style="margin-bottom: 7px;" class="text-center">
- {%= frappe.boot.letter_heads[letterhead].header %}
-</div>
-{% } %}
+
<h2 class="text-center">{%= __(report.report_name) %}</h2>
<h3 class="text-center">{%= filters.company %}</h3>
+
{% if 'cost_center' in filters %}
<h3 class="text-center">{%= filters.cost_center %}</h3>
{% endif %}
+
<h3 class="text-center">{%= filters.fiscal_year %}</h3>
-<h5 class="text-center">{%= __("Currency") %} : {%= filters.presentation_currency || erpnext.get_currency(filters.company) %} </h4>
+<h5 class="text-center">
+ {%= __("Currency") %} : {%= filters.presentation_currency || erpnext.get_currency(filters.company) %}
+</h5>
{% if (filters.from_date) { %}
- <h4 class="text-center">{%= frappe.datetime.str_to_user(filters.from_date) %} - {%= frappe.datetime.str_to_user(filters.to_date) %}</h3>
+ <h5 class="text-center">
+ {%= frappe.datetime.str_to_user(filters.from_date) %} - {%= frappe.datetime.str_to_user(filters.to_date) %}
+ </h5>
{% } %}
<hr>
<table class="table table-bordered">
<thead>
<tr>
- <th style="width: {%= 100 - (report_columns.length - 2) * 13 %}%"></th>
- {% for(var i=2, l=report_columns.length; i<l; i++) { %}
+ <th style="width: {%= 100 - (report_columns.length - 1) * 13 %}%"></th>
+ {% for (let i=1, l=report_columns.length; i<l; i++) { %}
<th class="text-right">{%= report_columns[i].label %}</th>
{% } %}
</tr>
</thead>
<tbody>
- {% for(var j=0, k=data.length-1; j<k; j++) { %}
+ {% for(let j=0, k=data.length-1; j<k; j++) { %}
{%
var row = data[j];
var row_class = data[j].parent_account ? "" : "financial-statements-important";
@@ -52,11 +54,11 @@
<td>
<span style="padding-left: {%= cint(data[j].indent) * 2 %}em">{%= row.account_name %}</span>
</td>
- {% for(var i=2, l=report_columns.length; i<l; i++) { %}
+ {% for(let i=1, l=report_columns.length; i<l; i++) { %}
<td class="text-right">
- {% var fieldname = report_columns[i].fieldname; %}
+ {% const fieldname = report_columns[i].fieldname; %}
{% if (!is_null(row[fieldname])) { %}
- {%= format_currency(row[fieldname], filters.presentation_currency) %}
+ {%= frappe.format(row[fieldname], report_columns[i], {}, row) %}
{% } %}
</td>
{% } %}
@@ -64,4 +66,6 @@
{% } %}
</tbody>
</table>
-<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
+<p class="text-right text-muted">
+ Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
+</p>
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 3c8de60..40d5682 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -264,8 +264,8 @@
def add_total_row(out, root_type, balance_must_be, period_list, company_currency):
total_row = {
- "account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
- "account": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'",
+ "account_name": _("Total {0} ({1})").format(_(root_type), _(balance_must_be)),
+ "account": _("Total {0} ({1})").format(_(root_type), _(balance_must_be)),
"currency": company_currency
}
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 6b3f2c7..f6a7fa2 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -144,6 +144,10 @@
frm.set_df_property('purchase_invoice', 'read_only', 1);
frm.set_df_property('purchase_receipt', 'read_only', 1);
}
+ else if (frm.doc.is_existing_asset) {
+ frm.toggle_reqd('purchase_receipt', 0);
+ frm.toggle_reqd('purchase_invoice', 0);
+ }
else if (frm.doc.purchase_receipt) {
// if purchase receipt link is set then set PI disabled
frm.toggle_reqd('purchase_invoice', 0);
@@ -256,6 +260,7 @@
},
is_existing_asset: function(frm) {
+ frm.trigger("toggle_reference_doc");
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
},
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 75564af..6150516 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -319,8 +319,8 @@
if item.get('discount_amount'):
item.rate = item.price_list_rate - item.discount_amount
- elif pricing_rule_args.get('free_item'):
- apply_pricing_rule_for_free_items(self, pricing_rule_args)
+ elif pricing_rule_args.get('free_item_data'):
+ apply_pricing_rule_for_free_items(self, pricing_rule_args.get('free_item_data'))
elif pricing_rule_args.get("validate_applied_rule"):
for pricing_rule in get_applied_pricing_rules(item):
diff --git a/erpnext/patches/v12_0/set_gst_category.py b/erpnext/patches/v12_0/set_gst_category.py
index 54bc5b3..55bbdee 100644
--- a/erpnext/patches/v12_0/set_gst_category.py
+++ b/erpnext/patches/v12_0/set_gst_category.py
@@ -7,6 +7,8 @@
if not company:
return
+ frappe.reload_doc('accounts', 'doctype', 'Tax Category')
+
make_custom_fields()
for doctype in ['Sales Invoice', 'Purchase Invoice']:
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 02c3058..926227b 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -30,7 +30,7 @@
&& frappe.meta.has_field(this.frm.doc.doctype, "disable_rounded_total")) {
var df = frappe.meta.get_docfield(this.frm.doc.doctype, "disable_rounded_total");
- var disable = df.default || cint(frappe.sys_defaults.disable_rounded_total);
+ var disable = cint(df.default) || cint(frappe.sys_defaults.disable_rounded_total);
this.frm.set_value("disable_rounded_total", disable);
}
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 46a58fb..1be4f27 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1305,6 +1305,10 @@
me.remove_pricing_rule(frappe.get_doc(d.doctype, d.name));
}
+ if (d.free_item_data) {
+ me.apply_product_discount(d.free_item_data);
+ }
+
if (d.apply_rule_on_other_items) {
items_rule_dict[d.name] = d;
}
@@ -1334,6 +1338,20 @@
}
},
+ apply_product_discount: function(free_item_data) {
+ const items = this.frm.doc.items.filter(d => (d.item_code == free_item_data.item_code
+ && d.is_free_item)) || [];
+
+ if (!items.length) {
+ let row_to_modify = frappe.model.add_child(this.frm.doc,
+ this.frm.doc.doctype + ' Item', 'items');
+
+ for (let key in free_item_data) {
+ row_to_modify[key] = free_item_data[key];
+ }
+ }
+ },
+
apply_price_list: function(item, reset_plc_conversion) {
// We need to reset plc_conversion_rate sometimes because the call to
// `erpnext.stock.get_item_details.apply_price_list` is sensitive to its value
diff --git a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
index 74370cc..a4e6aed 100644
--- a/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
+++ b/erpnext/quality_management/doctype/quality_action_resolution/quality_action_resolution.json
@@ -13,7 +13,7 @@
"fieldname": "problem",
"fieldtype": "Long Text",
"in_list_view": 1,
- "label": "Problem"
+ "label": "Review"
},
{
"fieldname": "sb_00",
diff --git a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
index f5c0fbc..0a67fa5 100644
--- a/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
+++ b/erpnext/quality_management/doctype/quality_procedure_process/quality_procedure_process.json
@@ -18,7 +18,7 @@
"fieldname": "procedure",
"fieldtype": "Link",
"in_list_view": 1,
- "label": "Procedure",
+ "label": "Child Procedure",
"options": "Quality Procedure"
}
],
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 77bcc80..0f9156a 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -179,6 +179,8 @@
if not party_details.place_of_supply: return
+ if not party_details.company_gstin: return
+
if ((doctype in ("Sales Invoice", "Delivery Note", "Sales Order") and party_details.company_gstin
and party_details.company_gstin[:2] != party_details.place_of_supply[:2]) or (doctype in ("Purchase Invoice",
"Purchase Order", "Purchase Receipt") and party_details.supplier_gstin and party_details.supplier_gstin[:2] != party_details.place_of_supply[:2])):
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 2eee919..ff35154 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -14,6 +14,7 @@
from frappe.contacts.address_and_contact import load_address_and_contact
from frappe.utils.nestedset import NestedSet
+from past.builtins import cmp
import functools
class Company(NestedSet):
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index a2aab3f..af8e132 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -135,8 +135,7 @@
"publish_in_hub",
"hub_category_to_publish",
"hub_warehouse",
- "synced_with_hub",
- "manufacturers"
+ "synced_with_hub"
],
"fields": [
{
@@ -1017,12 +1016,6 @@
"read_only": 1
},
{
- "fieldname": "manufacturers",
- "fieldtype": "Table",
- "label": "Manufacturers",
- "options": "Item Manufacturer"
- },
- {
"depends_on": "eval:!doc.__islocal",
"fieldname": "over_delivery_receipt_allowance",
"fieldtype": "Float",
@@ -1049,7 +1042,7 @@
"idx": 2,
"image_field": "image",
"max_attachments": 1,
- "modified": "2019-10-09 17:05:59.576119",
+ "modified": "2019-12-13 12:15:56.197246",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 189261c..151be11 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -125,7 +125,6 @@
self.validate_auto_reorder_enabled_in_stock_settings()
self.cant_change()
self.update_show_in_website()
- self.validate_manufacturer()
if not self.get("__islocal"):
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@@ -145,13 +144,6 @@
if cint(frappe.db.get_single_value('Stock Settings', 'clean_description_html')):
self.description = clean_html(self.description)
- def validate_manufacturer(self):
- list_man = [(x.manufacturer, x.manufacturer_part_no) for x in self.get('manufacturers')]
- set_man = set(list_man)
-
- if len(list_man) != len(set_man):
- frappe.throw(_("Duplicate entry in Manufacturers table"))
-
def validate_customer_provided_part(self):
if self.is_customer_provided_item:
if self.is_purchase_item:
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 9b73d0f..060175f 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -245,7 +245,7 @@
negative_expense_to_be_booked += flt(d.item_tax_amount)
# Amount added through landed-cost-voucher
- if landed_cost_entries:
+ if d.landed_cost_voucher_amount and landed_cost_entries:
for account, amount in iteritems(landed_cost_entries[(d.item_code, d.name)]):
gl_entries.append(self.get_gl_dict({
"account": account,
@@ -611,7 +611,7 @@
def get_item_account_wise_additional_cost(purchase_document):
landed_cost_voucher = frappe.get_value("Landed Cost Purchase Receipt",
- {"receipt_document": purchase_document}, "parent")
+ {"receipt_document": purchase_document, "docstatus": 1}, "parent")
if not landed_cost_voucher:
return
@@ -622,8 +622,7 @@
based_on_field = frappe.scrub(landed_cost_voucher_doc.distribute_charges_based_on)
for item in landed_cost_voucher_doc.items:
- if item.receipt_document == purchase_document:
- total_item_cost += item.get(based_on_field)
+ total_item_cost += item.get(based_on_field)
for item in landed_cost_voucher_doc.items:
if item.receipt_document == purchase_document:
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 4770471..79ce231 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -622,7 +622,7 @@
if(r.message) {
var d = locals[cdt][cdn];
$.each(r.message, function(k, v) {
- d[k] = v;
+ frappe.model.set_value(cdt, cdn, k, v); // qty and it's subsequent fields weren't triggered
});
refresh_field("items");
erpnext.stock.select_batch_and_serial_no(frm, d);
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index f81fa68..00d27ef 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -649,6 +649,12 @@
gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account)
total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse])
+ divide_based_on = total_basic_amount
+
+ if self.get("additional_costs") and not total_basic_amount:
+ # if total_basic_amount is 0, distribute additional charges based on qty
+ divide_based_on = sum(item.qty for item in list(self.get("items")))
+
item_account_wise_additional_cost = {}
for t in self.get("additional_costs"):
@@ -656,8 +662,11 @@
if d.t_warehouse:
item_account_wise_additional_cost.setdefault((d.item_code, d.name), {})
item_account_wise_additional_cost[(d.item_code, d.name)].setdefault(t.expense_account, 0.0)
+
+ multiply_based_on = d.basic_amount if total_basic_amount else d.qty
+
item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account] += \
- (t.amount * d.basic_amount) / total_basic_amount
+ (t.amount * multiply_based_on) / divide_based_on
if item_account_wise_additional_cost:
for d in self.get("items"):
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index eddab5d..ee5f237 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -790,6 +790,50 @@
filters={"voucher_type": "Stock Entry", "voucher_no": mr.name}, fieldname="is_opening")
self.assertEqual(is_opening, "Yes")
+ def test_total_basic_amount_zero(self):
+ se = frappe.get_doc({"doctype":"Stock Entry",
+ "purpose":"Material Receipt",
+ "stock_entry_type":"Material Receipt",
+ "posting_date": nowdate(),
+ "company":"_Test Company with perpetual inventory",
+ "items":[
+ {
+ "item_code":"Basil Leaves",
+ "description":"Basil Leaves",
+ "qty": 1,
+ "basic_rate": 0,
+ "uom":"Nos",
+ "t_warehouse": "Stores - TCP1",
+ "allow_zero_valuation_rate": 1,
+ "cost_center": "Main - TCP1"
+ },
+ {
+ "item_code":"Basil Leaves",
+ "description":"Basil Leaves",
+ "qty": 2,
+ "basic_rate": 0,
+ "uom":"Nos",
+ "t_warehouse": "Stores - TCP1",
+ "allow_zero_valuation_rate": 1,
+ "cost_center": "Main - TCP1"
+ },
+ ],
+ "additional_costs":[
+ {"expense_account":"Miscellaneous Expenses - TCP1",
+ "amount":100,
+ "description": "miscellanous"}
+ ]
+ })
+ se.insert()
+ se.submit()
+
+ self.check_gl_entries("Stock Entry", se.name,
+ sorted([
+ ["Stock Adjustment - TCP1", 100.0, 0.0],
+ ["Miscellaneous Expenses - TCP1", 0.0, 100.0]
+ ])
+ )
+
def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
se = frappe.copy_doc(test_records[0])
se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series"