Merge pull request #2 from frappe/hotfix
Hotfix
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 105bff4..b9d86a8 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.65'
+__version__ = '10.1.76'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 940a709..4802a7d 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -791,15 +791,25 @@
var write_off_row = $.map(frm.doc["deductions"] || [], function(t) {
return t.account==r.message[account] ? t : null; });
- if (!write_off_row.length) {
- var row = frm.add_child("deductions");
+ var row = [];
+
+ var difference_amount = flt(frm.doc.difference_amount,
+ precision("difference_amount"));
+
+ if (!write_off_row.length && difference_amount) {
+ row = frm.add_child("deductions");
row.account = r.message[account];
row.cost_center = r.message["cost_center"];
} else {
- var row = write_off_row[0];
+ row = write_off_row[0];
}
- row.amount = flt(row.amount) + flt(frm.doc.difference_amount);
+ if (row) {
+ row.amount = flt(row.amount) + difference_amount;
+ } else {
+ frappe.msgprint(__("No gain or loss in the exchange rate"))
+ }
+
refresh_field("deductions");
frm.events.set_unallocated_amount(frm);
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index 03d0918..7a2e254 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -70,12 +70,14 @@
net_pl_balance += flt(acc.balance_in_company_currency)
if net_pl_balance:
+ cost_center = frappe.db.get_value("Company", self.company, "cost_center")
gl_entries.append(self.get_gl_dict({
"account": self.closing_account_head,
"debit_in_account_currency": abs(net_pl_balance) if net_pl_balance > 0 else 0,
"debit": abs(net_pl_balance) if net_pl_balance > 0 else 0,
"credit_in_account_currency": abs(net_pl_balance) if net_pl_balance < 0 else 0,
- "credit": abs(net_pl_balance) if net_pl_balance < 0 else 0
+ "credit": abs(net_pl_balance) if net_pl_balance < 0 else 0,
+ "cost_center": cost_center
}))
from erpnext.accounts.general_ledger import make_gl_entries
diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
index 9ef66ed..eb02d97 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
@@ -72,6 +72,7 @@
"company": "_Test Company",
"fiscal_year": get_fiscal_year(today(), company="_Test Company")[0],
"posting_date": today(),
+ "cost_center": "_Test Cost Center - _TC",
"remarks": "test"
})
pcv.insert()
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index eca4320..75db8b9 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -185,7 +185,8 @@
"discount_percentage": 0.0
})
else:
- item_details.discount_percentage = pricing_rule.discount_percentage or args.discount_percentage
+ item_details.discount_percentage = (pricing_rule.get('discount_percentage', 0)
+ if pricing_rule else args.discount_percentage)
elif args.get('pricing_rule'):
item_details = remove_pricing_rule_for_item(args.get("pricing_rule"), item_details)
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 3fa34e2..30ae71d 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -11,12 +11,16 @@
from frappe import MandatoryError
class TestPricingRule(unittest.TestCase):
+ def setUp(self):
+ frappe.db.sql("delete from `tabPricing Rule`")
+
+ def tearDown(self):
+ frappe.db.sql("delete from `tabPricing Rule`")
+
def test_pricing_rule_for_discount(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
- frappe.db.sql("delete from `tabPricing Rule`")
-
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -88,14 +92,10 @@
details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 15)
- frappe.db.sql("delete from `tabPricing Rule`")
-
def test_pricing_rule_for_margin(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
- frappe.db.sql("delete from `tabPricing Rule`")
-
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -109,14 +109,14 @@
"company": "_Test Company"
}
frappe.get_doc(test_record.copy()).insert()
-
+
item_price = frappe.get_doc({
"doctype": "Item Price",
"price_list": "_Test Price List 2",
"item_code": "_Test FG Item 2",
"price_list_rate": 100
})
-
+
item_price.insert(ignore_permissions=True)
args = frappe._dict({
@@ -136,14 +136,10 @@
self.assertEquals(details.get("margin_type"), "Percentage")
self.assertEquals(details.get("margin_rate_or_amount"), 10)
- frappe.db.sql("delete from `tabPricing Rule`")
-
def test_pricing_rule_for_variants(self):
from erpnext.stock.get_item_details import get_item_details
from frappe import MandatoryError
- frappe.db.sql("delete from `tabPricing Rule`")
-
if not frappe.db.exists("Item", "Test Variant PRT"):
frappe.get_doc({
"doctype": "Item",
@@ -209,8 +205,6 @@
self.assertEquals(details.get("discount_percentage"), 17.5)
def test_pricing_rule_for_stock_qty(self):
- frappe.db.sql("delete from `tabPricing Rule`")
-
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule",
@@ -253,24 +247,18 @@
def test_pricing_rule_with_margin_and_discount(self):
frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule')
- make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10)
+ make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10, discount_percentage=10)
si = create_sales_invoice(do_not_save=True)
si.items[0].price_list_rate = 1000
si.payment_schedule = []
si.insert(ignore_permissions=True)
item = si.items[0]
- self.assertEquals(item.rate, 1100)
self.assertEquals(item.margin_rate_or_amount, 10)
-
- # With discount
- item.discount_percentage = 10
- si.payment_schedule = []
- si.save()
- item = si.items[0]
+ self.assertEquals(item.rate_with_margin, 1100)
+ self.assertEqual(item.discount_percentage, 10)
+ self.assertEquals(item.discount_amount, 110)
self.assertEquals(item.rate, 990)
- self.assertEquals(item.discount_percentage, 10)
- frappe.db.sql("delete from `tabPricing Rule`")
def make_pricing_rule(**args):
args = frappe._dict(args)
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index a6cd352..065e32a 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -589,9 +589,6 @@
def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
auto_accounting_for_stock = erpnext.is_perpetual_inventory_enabled(self.company)
- if not self.grand_total:
- return
-
if not gl_entries:
gl_entries = self.get_gl_entries()
@@ -671,9 +668,11 @@
self.get_gl_dict({
"account": tax.account_head,
"against": self.customer,
- "credit": flt(tax.base_tax_amount_after_discount_amount),
- "credit_in_account_currency": flt(tax.base_tax_amount_after_discount_amount) \
- if account_currency==self.company_currency else flt(tax.tax_amount_after_discount_amount),
+ "credit": flt(tax.base_tax_amount_after_discount_amount,
+ tax.precision("tax_amount_after_discount_amount")),
+ "credit_in_account_currency": (flt(tax.base_tax_amount_after_discount_amount,
+ tax.precision("base_tax_amount_after_discount_amount")) if account_currency==self.company_currency else
+ flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount_after_discount_amount"))),
"cost_center": tax.cost_center
}, account_currency)
)
@@ -681,7 +680,7 @@
def make_item_gl_entries(self, gl_entries):
# income account gl entries
for item in self.get("items"):
- if flt(item.base_net_amount):
+ if flt(item.base_net_amount, item.precision("base_net_amount")):
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
@@ -698,9 +697,10 @@
self.get_gl_dict({
"account": item.income_account,
"against": self.customer,
- "credit": item.base_net_amount,
- "credit_in_account_currency": item.base_net_amount \
- if account_currency==self.company_currency else item.net_amount,
+ "credit": flt(item.base_net_amount, item.precision("base_net_amount")),
+ "credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
+ if account_currency==self.company_currency
+ else flt(item.net_amount, item.precision("net_amount"))),
"cost_center": item.cost_center
}, account_currency)
)
@@ -771,7 +771,7 @@
def make_write_off_gl_entry(self, gl_entries):
# write off entries, applicable if only pos
- if self.write_off_account and self.write_off_amount:
+ if self.write_off_account and flt(self.write_off_amount, self.precision("write_off_amount")):
write_off_account_currency = get_account_currency(self.write_off_account)
default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
@@ -781,9 +781,10 @@
"party_type": "Customer",
"party": self.customer,
"against": self.write_off_account,
- "credit": self.base_write_off_amount,
- "credit_in_account_currency": self.base_write_off_amount \
- if self.party_account_currency==self.company_currency else self.write_off_amount,
+ "credit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
+ "credit_in_account_currency": (flt(self.base_write_off_amount,
+ self.precision("base_write_off_amount")) if self.party_account_currency==self.company_currency
+ else flt(self.write_off_amount, self.precision("write_off_amount"))),
"against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype
}, self.party_account_currency)
@@ -792,15 +793,16 @@
self.get_gl_dict({
"account": self.write_off_account,
"against": self.customer,
- "debit": self.base_write_off_amount,
- "debit_in_account_currency": self.base_write_off_amount \
- if write_off_account_currency==self.company_currency else self.write_off_amount,
+ "debit": flt(self.base_write_off_amount, self.precision("base_write_off_amount")),
+ "debit_in_account_currency": (flt(self.base_write_off_amount,
+ self.precision("base_write_off_amount")) if write_off_account_currency==self.company_currency
+ else flt(self.write_off_amount, self.precision("write_off_amount"))),
"cost_center": self.write_off_cost_center or default_cost_center
}, write_off_account_currency)
)
def make_gle_for_rounding_adjustment(self, gl_entries):
- if self.rounding_adjustment:
+ if flt(self.rounding_adjustment, self.precision("rounding_adjustment")):
round_off_account, round_off_cost_center = \
get_round_off_account_and_cost_center(self.company)
@@ -808,8 +810,10 @@
self.get_gl_dict({
"account": round_off_account,
"against": self.customer,
- "credit_in_account_currency": self.rounding_adjustment,
- "credit": self.base_rounding_adjustment,
+ "credit_in_account_currency": flt(self.rounding_adjustment,
+ self.precision("rounding_adjustment")),
+ "credit": flt(self.base_rounding_adjustment,
+ self.precision("base_rounding_adjustment")),
"cost_center": round_off_cost_center,
}
))
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index 7f663d8..b4276a1 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -75,7 +75,7 @@
<td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
<td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
<td class="text-right">
- {%= format_currency(flt(balance_row[__("Outstanding Amount")]), data[data.length-1]["currency"]) %}
+ {%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
</td>
</tr>
<td>{%= __("PDC/LC") %}</td>
@@ -84,7 +84,7 @@
<td></td>
<td></td>
<td class="text-right">
- {%= format_currency(flt(balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}
+ {%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
</td>
<tr class="cvs-footer">
<th class="text-left">{%= __("Cheques Required") %}</th>
@@ -93,7 +93,7 @@
<th></th>
<th></th>
<th class="text-right">
- {%= format_currency(flt(balance_row[__("Outstanding Amount")]-balance_row[__("PDC/LC Amount")]), data[data.length-1]["currency"]) %}</th>
+ {%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
</tr>
</tbody>
@@ -177,10 +177,10 @@
<td style="text-align: right">
{%= data[i]["po_no"] %}</td>
{% } %}
- <td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
- <td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][("pdc/lc_date")]) %}</td>
+ <td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
{% } %}
{% } else { %}
<td></td>
@@ -194,7 +194,7 @@
{% if(!filters.show_pdc_in_print) { %}
<td style="text-align: right">
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
+ <td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %} </td>
{% } %}
<td style="text-align: right">
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
@@ -205,9 +205,9 @@
{%= data[i][__("Customer LPO")] %}</td>
{% } %}
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
- <td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("PDC/LC Amount")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("Remaining Balance")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
{% } %}
{% } %}
{% } else { %}
@@ -220,7 +220,7 @@
<br> {%= data[i][__("Customer Name")] %}
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
<br> {%= data[i][__("Supplier Name")] %}
- {% } %}
+ {% } %}
{% } %}
<br>{%= __("Remarks") %}:
{%= data[i][__("Remarks")] %}
@@ -228,10 +228,10 @@
{% } else { %}
<td><b>{%= __("Total") %}</b></td>
{% } %}
- <td style="text-align: right">{%= format_currency(data[i][__("Total Invoiced Amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("Total Paid Amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("Credit Note Amt")], data[i]["currency"]) : format_currency(data[i][__("Debit Note Amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][__("Total Outstanding Amt")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("credit_note_amt")], data[i]["currency"]) : format_currency(data[i][__("debit_note_amt")], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %}</td>
{% } %}
{% } %}
</tr>
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 0425fe5..fb54671 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -88,20 +88,40 @@
"width": 120
})
- columns.append({
+ columns += [
+ {
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Link",
"options": "Currency",
"width": 100
- })
-
- columns += [
- _("PDC/LC Date") + ":Date:110",
- _("PDC/LC Ref") + ":Data:110",
- _("PDC/LC Amount") + ":Currency/currency:130",
- _("Remaining Balance") + ":Currency/currency:130"
- ]
+ },
+ {
+ "fieldname": "pdc/lc_date",
+ "label": _("PDC/LC Date"),
+ "fieldtype": "Date",
+ "width": 110
+ },
+ {
+ "fieldname": "pdc/lc_ref",
+ "label": _("PDC/LC Ref"),
+ "fieldtype": "Data",
+ "width": 110
+ },
+ {
+ "fieldname": "pdc/lc_amount",
+ "label": _("PDC/LC Amount"),
+ "fieldtype": "Currency",
+ "options": "Currency",
+ "width": 130
+ },
+ {
+ "fieldname": "remaining_balance",
+ "label": _("Remaining Balance"),
+ "fieldtype": "Currency",
+ "options": "Currency",
+ "width": 130
+ }]
if args.get('party_type') == 'Customer':
columns.append({
@@ -139,7 +159,6 @@
data = []
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
-
gl_entries_data = self.get_entries_till(self.filters.report_date, args.get("party_type"))
if gl_entries_data:
@@ -429,7 +448,6 @@
and pent.party_type = %s
group by pent.party, pref.reference_name""", (report_date, party_type), as_dict=1):
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
-
if scrub(party_type):
amount_field = ("jea.debit_in_account_currency"
if party_type == 'Supplier' else "jea.credit_in_account_currency")
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index 08b24fb..fdb7ec8 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe import _
+from frappe import _, scrub
from frappe.utils import flt
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
@@ -18,25 +18,93 @@
if party_naming_by == "Naming Series":
columns += [ args.get("party_type") + " Name::140"]
- credit_debit_label = _("Credit Note Amt") if args.get('party_type') == 'Customer' else _("Debit Note Amt")
+ credit_debit_label = "Credit Note Amt" if args.get('party_type') == 'Customer' else "Debit Note Amt"
+
+ columns += [{
+ "label": _("Total Invoiced Amt"),
+ "fieldname": "total_invoiced_amt",
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 100
+ },
+ {
+ "label": _("Total Paid Amt"),
+ "fieldname": "total_paid_amt",
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 100
+ }]
+
columns += [
- _("Total Invoiced Amt") + ":Currency/currency:140",
- _("Total Paid Amt") + ":Currency/currency:140",
- credit_debit_label + ":Currency/currency:140",
- _("Total Outstanding Amt") + ":Currency/currency:160",
- "0-" + str(self.filters.range1) + ":Currency/currency:100",
- str(self.filters.range1) + "-" + str(self.filters.range2) + ":Currency/currency:100",
- str(self.filters.range2) + "-" + str(self.filters.range3) + ":Currency/currency:100",
- str(self.filters.range3) + _("-Above") + ":Currency/currency:100"]
+ {
+ "label": _(credit_debit_label),
+ "fieldname": scrub(credit_debit_label),
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 140
+ },
+ {
+ "label": _("Total Outstanding Amt"),
+ "fieldname": "total_outstanding_amt",
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 160
+ },
+ {
+ "label": _("0-" + str(self.filters.range1)),
+ "fieldname": scrub("0-" + str(self.filters.range1)),
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 160
+ },
+ {
+ "label": _(str(self.filters.range1) + "-" + str(self.filters.range2)),
+ "fieldname": scrub(str(self.filters.range1) + "-" + str(self.filters.range2)),
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 160
+ },
+ {
+ "label": _(str(self.filters.range2) + "-" + str(self.filters.range3)),
+ "fieldname": scrub(str(self.filters.range2) + "-" + str(self.filters.range3)),
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 160
+ },
+ {
+ "label": _(str(self.filters.range3) + _("-Above")),
+ "fieldname": scrub(str(self.filters.range3) + _("-Above")),
+ "fieldtype": "Currency",
+ "options": "currency",
+ "width": 160
+ }
+ ]
if args.get("party_type") == "Customer":
- columns += [
- _("Territory") + ":Link/Territory:80",
- _("Customer Group") + ":Link/Customer Group:120"
- ]
+ columns += [{
+ "label": _("Territory"),
+ "fieldname": "territory",
+ "fieldtype": "Link",
+ "options": "Territory",
+ "width": 80
+ },
+ {
+ "label": _("Customer Group"),
+ "fieldname": "customer_group",
+ "fieldtype": "Link",
+ "options": "Customer Group",
+ "width": 80
+ }]
+
if args.get("party_type") == "Supplier":
- columns += [_("Supplier Type") + ":Link/Supplier Type:80"]
-
+ columns += [{
+ "label": _("Supplier Group"),
+ "fieldname": "supplier_group",
+ "fieldtype": "Link",
+ "options": "Supplier Group",
+ "width": 80
+ }]
+
columns.append({
"fieldname": "currency",
"label": _("Currency"),
@@ -67,7 +135,7 @@
row += [self.get_territory(party), self.get_customer_group(party)]
if args.get("party_type") == "Supplier":
row += [self.get_supplier_type(party)]
-
+
row.append(party_dict.currency)
data.append(row)
@@ -91,7 +159,7 @@
for k in party_total[d.party].keys():
if k != "currency":
party_total[d.party][k] += flt(d.get(k, 0))
-
+
party_total[d.party].currency = d.currency
return party_total
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 05ad741..1c12cdf 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -16,7 +16,7 @@
if not filters: filters = {}
columns = get_columns(additional_table_columns)
- company_currency = erpnext.get_company_currency(filters.company)
+ company_currency = erpnext.get_company_currency(filters.get('company'))
item_list = get_items(filters, additional_query_columns)
if item_list:
@@ -54,7 +54,7 @@
]
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
- if d.stock_uom != d.uom else [d.base_net_rate, d.base_net_amount]
+ if d.stock_uom != d.uom and d.stock_qty != 0 else [d.base_net_rate, d.base_net_amount]
total_tax = 0
for tax in tax_columns:
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index d4f1de1..e0781f1 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -85,6 +85,7 @@
frappe.msgprint(_("{0} currently has a {1} Supplier Scorecard standing, and Purchase Orders to this supplier should be issued with caution.").format(self.supplier, standing), title=_("Caution"), indicator='orange')
def validate_minimum_order_qty(self):
+ if not self.get("items"): return
items = list(set([d.item_code for d in self.get("items")]))
itemwise_min_order_qty = frappe._dict(frappe.db.sql("""select name, min_order_qty
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index cd3cbe9..0496ab2 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -10,6 +10,7 @@
from erpnext.stock.get_item_details import get_conversion_factor
from erpnext.buying.utils import validate_for_items, update_last_purchase_rate
from erpnext.stock.stock_ledger import get_valuation_rate
+from frappe.contacts.doctype.address.address import get_address_display
from erpnext.controllers.stock_controller import StockController
@@ -39,6 +40,7 @@
self.set_qty_as_per_stock_uom()
self.validate_stock_or_nonstock_items()
self.validate_warehouse()
+ self.set_supplier_address()
if self.doctype=="Purchase Invoice":
self.validate_purchase_receipt_if_update_stock()
@@ -96,6 +98,16 @@
if not d.cost_center and lc_voucher_data and lc_voucher_data[0][1]:
d.db_set('cost_center', lc_voucher_data[0][1])
+ def set_supplier_address(self):
+ address_dict = {
+ 'supplier_address': 'address_display',
+ 'shipping_address': 'shipping_address_display'
+ }
+
+ for address_field, address_display_field in address_dict.items():
+ if self.get(address_field):
+ self.set(address_display_field, get_address_display(self.get(address_field)))
+
def set_total_in_words(self):
from frappe.utils import money_in_words
if self.meta.get_field("base_in_words"):
@@ -450,7 +462,7 @@
update_last_purchase_rate(self, is_submit = 0)
def validate_schedule_date(self):
- if not self.schedule_date:
+ if not self.schedule_date and self.get("items"):
self.schedule_date = min([d.schedule_date for d in self.get("items")])
if self.schedule_date:
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index be5f64e..5c203af 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -8,6 +8,7 @@
from erpnext.stock.get_item_details import get_bin_details
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.get_item_details import get_conversion_factor
+from frappe.contacts.doctype.address.address import get_address_display
from erpnext.controllers.stock_controller import StockController
@@ -40,6 +41,7 @@
self.validate_selling_price()
self.set_qty_as_per_stock_uom()
self.set_po_nos()
+ self.set_customer_address()
check_active_sales_items(self)
def set_missing_values(self, for_validate=False):
@@ -344,6 +346,17 @@
po_nos = frappe.get_all('Sales Order', 'po_no', filters = {'name': ('in', sales_orders)})
self.po_no = ', '.join(list(set([d.po_no for d in po_nos if d.po_no])))
+ def set_customer_address(self):
+ address_dict = {
+ 'customer_address': 'address_display',
+ 'shipping_address_name': 'shipping_address',
+ 'company_address': 'company_address_display'
+ }
+
+ for address_field, address_display_field in address_dict.items():
+ if self.get(address_field):
+ self.set(address_display_field, get_address_display(self.get(address_field)))
+
def validate_items(self):
# validate items to see if they have is_sales_item enabled
from erpnext.controllers.buying_controller import validate_item_type
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 41ba61b..2639a15 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -66,8 +66,11 @@
if item.doctype in ['Quotation Item', 'Sales Order Item', 'Delivery Note Item', 'Sales Invoice Item']:
item.rate_with_margin, item.base_rate_with_margin = self.calculate_margin(item)
- item.rate = flt(item.rate_with_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))\
- if item.rate_with_margin > 0 else item.rate
+ if flt(item.rate_with_margin) > 0:
+ item.rate = flt(item.rate_with_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))
+ item.discount_amount = item.rate_with_margin - item.rate
+ elif flt(item.price_list_rate) > 0:
+ item.discount_amount = item.price_list_rate - item.rate
item.net_rate = item.rate
item.amount = flt(item.rate * item.qty, item.precision("amount"))
diff --git a/erpnext/education/doctype/assessment_result/assessment_result.js b/erpnext/education/doctype/assessment_result/assessment_result.js
index cf176aa..27f5490 100644
--- a/erpnext/education/doctype/assessment_result/assessment_result.js
+++ b/erpnext/education/doctype/assessment_result/assessment_result.js
@@ -50,6 +50,12 @@
frappe.ui.form.on("Assessment Result Detail", {
score: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
+
+ if(!d.maximum_score || !frm.doc.grading_scale) {
+ d.score = "";
+ frappe.throw(__("Please fill in all the details to generate Assessment Result."));
+ }
+
if (d.score > d.maximum_score) {
frappe.throw(__("Score cannot be greater than Maximum Score"));
}
diff --git a/erpnext/healthcare/page/medical_record/medical_record.css b/erpnext/healthcare/page/medical_record/medical_record.css
index 70014da..977625b 100644
--- a/erpnext/healthcare/page/medical_record/medical_record.css
+++ b/erpnext/healthcare/page/medical_record/medical_record.css
@@ -14,10 +14,6 @@
margin-bottom: -4px;
}
-.medical_record-row > * {
- z-index: -999;
-}
-
.date-indicator {
background:none;
font-size:12px;
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index 81671c2..5d5bdd9 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -55,8 +55,8 @@
def validate_user_details(self):
data = frappe.db.get_value('User',
self.user_id, ['enabled', 'user_image'], as_dict=1)
-
- self.image = data.get("user_image")
+ if data.get("user_image"):
+ self.image = data.get("user_image")
self.validate_for_enabled_user_id(data.get("enabled", 0))
self.validate_duplicate_user_id()
@@ -336,4 +336,4 @@
.format(company=company, condition=condition), as_dict=1)
# return employee
- return employee
\ No newline at end of file
+ return employee
diff --git a/erpnext/hr/doctype/employee_advance/employee_advance.py b/erpnext/hr/doctype/employee_advance/employee_advance.py
index 28547fb..c90e5db 100644
--- a/erpnext/hr/doctype/employee_advance/employee_advance.py
+++ b/erpnext/hr/doctype/employee_advance/employee_advance.py
@@ -58,7 +58,7 @@
select sum(ifnull(allocated_amount, 0))
from `tabExpense Claim Advance`
where employee_advance = %s and docstatus=1 and allocated_amount > 0
- """, self.name)[0][0]
+ """, self.name)[0][0] or 0
frappe.db.set_value("Employee Advance", self.name, "claimed_amount", claimed_amount)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 6c7a252..bc6f99d 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -506,4 +506,5 @@
erpnext.patches.v10_0.set_discount_amount
erpnext.patches.v10_0.recalculate_gross_margin_for_project
erpnext.patches.v10_0.delete_hub_documents
-erpnext.patches.v10_0.update_user_image_in_employee
\ No newline at end of file
+erpnext.patches.v10_0.update_user_image_in_employee
+erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/repost_gle_for_purchase_receipts_with_rejected_items.py b/erpnext/patches/v10_0/repost_gle_for_purchase_receipts_with_rejected_items.py
new file mode 100644
index 0000000..68c06ef
--- /dev/null
+++ b/erpnext/patches/v10_0/repost_gle_for_purchase_receipts_with_rejected_items.py
@@ -0,0 +1,32 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe, erpnext
+
+def execute():
+ for company in frappe.get_all("Company"):
+ if not erpnext.is_perpetual_inventory_enabled(company.name):
+ continue
+
+ acc_frozen_upto = frappe.db.get_value("Accounts Settings", None, "acc_frozen_upto") or "1900-01-01"
+ pr_with_rejected_warehouse = frappe.db.sql("""
+ select pr.name
+ from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
+ where pr.name = pr_item.parent
+ and pr.posting_date > %s
+ and pr.docstatus=1
+ and pr.company = %s
+ and pr_item.rejected_qty > 0
+ """, (acc_frozen_upto, company.name), as_dict=1)
+
+ for d in pr_with_rejected_warehouse:
+ doc = frappe.get_doc("Purchase Receipt", d.name)
+
+ doc.docstatus = 2
+ doc.make_gl_entries_on_cancel(repost_future_gle=False)
+
+
+ # update gl entries for submit state of PR
+ doc.docstatus = 1
+ doc.make_gl_entries(repost_future_gle=False)
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 75582cd..ec8dcc9 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -254,13 +254,13 @@
self.total_purchase_cost = total_purchase_cost and total_purchase_cost[0][0] or 0
def update_sales_amount(self):
- total_sales_amount = frappe.db.sql("""select sum(base_grand_total)
+ total_sales_amount = frappe.db.sql("""select sum(base_net_total)
from `tabSales Order` where project = %s and docstatus=1""", self.name)
self.total_sales_amount = total_sales_amount and total_sales_amount[0][0] or 0
def update_billed_amount(self):
- total_billed_amount = frappe.db.sql("""select sum(base_grand_total)
+ total_billed_amount = frappe.db.sql("""select sum(base_net_total)
from `tabSales Invoice` where project = %s and docstatus=1""", self.name)
self.total_billed_amount = total_billed_amount and total_billed_amount[0][0] or 0
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index 460efbf..c55e422 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -346,6 +346,11 @@
body[data-route="pos"] .collapse-btn {
cursor: pointer;
}
+@media (max-width: 767px) {
+ body[data-route="pos"] .page-actions {
+ max-width: 110px;
+ }
+}
.price-info {
position: absolute;
left: 0;
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index a31acfc..0a0dcf7 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -10,9 +10,8 @@
+ flt(item.price_list_rate) * ( flt(item.margin_rate_or_amount) / 100);
} else {
item.rate_with_margin = flt(item.price_list_rate) + flt(item.margin_rate_or_amount);
- item.base_rate_with_margin = flt(item.rate_with_margin) * flt(this.frm.doc.conversion_rate);
}
-
+ item.base_rate_with_margin = flt(item.rate_with_margin) * flt(this.frm.doc.conversion_rate);
item.rate = flt(item.rate_with_margin , precision("rate", item));
if(item.discount_percentage){
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index d9bd50c..e5ecc5b 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -33,7 +33,7 @@
item.margin_rate_or_amount = 0;
item.rate_with_margin = 0;
}
-
+ item.base_rate_with_margin = item.rate_with_margin * flt(frm.doc.conversion_rate);
cur_frm.cscript.set_gross_profit(item);
cur_frm.cscript.calculate_taxes_and_totals();
diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js
index 484d81d..75a2759 100644
--- a/erpnext/public/js/setup_wizard.js
+++ b/erpnext/public/js/setup_wizard.js
@@ -97,6 +97,9 @@
if (!this.values.company_abbr) {
return false;
}
+ if (this.values.company_abbr.length > 5) {
+ return false;
+ }
return true;
}
},
diff --git a/erpnext/public/js/utils/item_quick_entry.js b/erpnext/public/js/utils/item_quick_entry.js
index b2e0b85..0248f9a 100644
--- a/erpnext/public/js/utils/item_quick_entry.js
+++ b/erpnext/public/js/utils/item_quick_entry.js
@@ -320,7 +320,7 @@
["attribute_value", "like", e.target.value + "%"]
],
fields: ["attribute_value"],
- parent: "Item"
+ parent: "Item Attribute"
},
callback: function(r) {
if (r.message) {
diff --git a/erpnext/selling/README.md b/erpnext/selling/README.md
index db05132..d186133 100644
--- a/erpnext/selling/README.md
+++ b/erpnext/selling/README.md
@@ -1,6 +1,11 @@
-Selling management module. Includes forms for capturing / managing the sales process.
+Selling management module. Includes forms for capturing / managing the sales process:
+
+- Customer
+- Campaign
+- Quotation
+- Sales Order
+
+Moved to CRM Module:
- Lead
- Opportunity
-- Quotation
-- Sales Order
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index b17345c..2a6853a 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -173,6 +173,11 @@
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def on_trash(self):
+ if self.customer_primary_contact:
+ frappe.db.sql("""update `tabCustomer`
+ set customer_primary_contact=null, mobile_no=null, email_id=null
+ where name=%s""", self.name)
+
delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s", self.lead_name)
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index 45546e3..123fd55 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -96,6 +96,15 @@
so.save()
+ def test_delete_customer_contact(self):
+ customer = frappe.get_doc(
+ get_customer_dict('_Test Customer for delete')).insert(ignore_permissions=True)
+
+ customer.mobile_no = "8989889890"
+ customer.save()
+ self.assertTrue(customer.customer_primary_contact)
+ frappe.delete_doc('Customer', customer.name)
+
def test_disabled_customer(self):
make_test_records("Item")
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 6b721c0..d3f128f 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -15,6 +15,7 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -44,11 +45,13 @@
"reqd": 1,
"search_index": 1,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,10 +77,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,10 +107,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -134,11 +141,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -165,10 +174,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -197,11 +208,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "300px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -227,10 +240,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -257,10 +272,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -288,10 +305,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -317,10 +336,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -349,11 +370,13 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -383,11 +406,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -412,10 +437,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -443,10 +470,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -473,10 +502,12 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -503,10 +534,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -532,10 +565,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -565,11 +600,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -599,11 +636,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -630,10 +669,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -662,10 +703,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -693,10 +736,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -725,10 +770,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -754,10 +801,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -787,11 +836,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -820,10 +871,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -852,10 +905,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -880,10 +935,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -915,11 +972,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -936,6 +995,7 @@
"label": "Net Rate",
"length": 0,
"no_copy": 0,
+ "options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -946,10 +1006,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -979,11 +1041,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1011,10 +1075,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1039,10 +1105,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1072,11 +1140,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1103,10 +1173,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1136,11 +1208,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "100px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1168,10 +1242,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1198,10 +1274,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1228,10 +1306,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1258,10 +1338,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1288,10 +1370,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1317,10 +1401,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1348,10 +1434,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -1379,10 +1467,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1410,10 +1500,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1439,10 +1531,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1469,10 +1563,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1500,10 +1596,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1530,10 +1628,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1559,10 +1659,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1592,11 +1694,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1626,11 +1730,13 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1658,10 +1764,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1686,10 +1794,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -1717,10 +1827,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1750,10 +1862,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1783,6 +1897,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0,
"width": "150px"
}
@@ -1798,7 +1913,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-08-06 05:18:38.135668",
+ "modified": "2018-12-12 05:52:46.135944",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",
@@ -1811,5 +1926,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 8b0ecbf..b2c6ccc 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -552,7 +552,7 @@
def update_item(source, target, source_parent):
target.amount = flt(source.amount) - flt(source.billed_amt)
target.base_amount = target.amount * flt(source_parent.conversion_rate)
- target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty
+ target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty - source.returned_qty
item = frappe.db.get_value("Item", target.item_code, ["item_group", "selling_cost_center"], as_dict=1)
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py
index f3674ae..bb6ba1f 100644
--- a/erpnext/selling/doctype/sms_center/sms_center.py
+++ b/erpnext/selling/doctype/sms_center/sms_center.py
@@ -15,19 +15,24 @@
def create_receiver_list(self):
rec, where_clause = '', ''
if self.send_to == 'All Customer Contact':
- where_clause = self.customer and " and customer = '%s'" % \
- self.customer.replace("'", "\'") or " and ifnull(customer, '') != ''"
+ where_clause = " and dl.link_doctype = 'Customer'"
+ if self.customer:
+ where_clause += " and dl.link_name = '%s'" % \
+ self.customer.replace("'", "\'") or " and ifnull(dl.link_name, '') != ''"
if self.send_to == 'All Supplier Contact':
- where_clause = self.supplier and " and supplier = '%s'" % \
- self.supplier.replace("'", "\'") or " and ifnull(supplier, '') != ''"
+ where_clause = " and dl.link_doctype = 'Supplier'"
+ if self.supplier:
+ where_clause += " and dl.link_name = '%s'" % \
+ self.supplier.replace("'", "\'") or " and ifnull(dl.link_name, '') != ''"
if self.send_to == 'All Sales Partner Contact':
- where_clause = self.sales_partner and " and sales_partner = '%s'" % \
- self.sales_partner.replace("'", "\'") or " and ifnull(sales_partner, '') != ''"
-
+ where_clause = " and dl.link_doctype = 'Sales Partner'"
+ if self.sales_partner:
+ where_clause += "and dl.link_name = '%s'" % \
+ self.sales_partner.replace("'", "\'") or " and ifnull(dl.link_name, '') != ''"
if self.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']:
- rec = frappe.db.sql("""select CONCAT(ifnull(first_name,''), ' ', ifnull(last_name,'')),
- mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and
- docstatus != 2 %s""" % where_clause)
+ rec = frappe.db.sql("""select CONCAT(ifnull(c.first_name,''), ' ', ifnull(c.last_name,'')),
+ c.mobile_no from `tabContact` c, `tabDynamic Link` dl where ifnull(c.mobile_no,'')!='' and
+ c.docstatus != 2 and dl.parent = c.name%s""" % where_clause)
elif self.send_to == 'All Lead (Open)':
rec = frappe.db.sql("""select lead_name, mobile_no from `tabLead` where
@@ -50,7 +55,6 @@
where ifnull(tabEmployee.cell_number,'')!=''""")
rec_list = ''
-
for d in rec:
rec_list += d[0] + ' - ' + d[1] + '\n'
self.receiver_list = rec_list
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index f318c04..dfff74a 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -95,7 +95,7 @@
if not value:
import requests
- api_url = "https://frankfurter.erpnext.org/{0}".format(transaction_date)
+ api_url = "https://frankfurter.app/{0}".format(transaction_date)
response = requests.get(api_url, params={
"base": from_currency,
"symbols": to_currency
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index ccc6da4..5a0d772 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -382,8 +382,24 @@
return invoiced_qty_map
+def get_returned_qty_map(sales_orders):
+ """returns a map: {so_detail: returned_qty}"""
+ returned_qty_map = {}
+
+ for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"],
+ filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1):
+ if not returned_qty_map.get(name):
+ returned_qty_map[name] = 0
+ returned_qty_map[name] += returned_qty
+
+ return returned_qty_map
+
@frappe.whitelist()
def make_sales_invoice(source_name, target_doc=None):
+ doc = frappe.get_doc('Delivery Note', source_name)
+ sales_orders = [d.against_sales_order for d in doc.items]
+ returned_qty_map = get_returned_qty_map(sales_orders)
+
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
@@ -403,7 +419,9 @@
target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
def update_item(source_doc, target_doc, source_parent):
- target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
+ target_doc.qty = (source_doc.qty -
+ invoiced_qty_map.get(source_doc.name, 0) - returned_qty_map.get(source_doc.so_detail, 0))
+
if source_doc.serial_no and source_parent.per_billed > 0:
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
target_doc.qty, source_parent.name)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
index f1ad929..2972e41 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
@@ -1,6 +1,6 @@
frappe.listview_settings['Delivery Note'] = {
- add_fields: ["customer", "customer_name", "base_grand_total", "per_installed", "per_billed",
- "transporter_name", "grand_total", "is_return", "status"],
+ add_fields: ["customer", "customer_name", "base_grand_total", "per_installed", "per_billed",
+ "transporter_name", "grand_total", "is_return", "status", "currency"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index c3dbb8d..0771d79 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -564,6 +564,24 @@
self.assertEqual(dn.per_billed, 100)
self.assertEqual(dn.status, "Completed")
+ def test_make_sales_invoice_from_dn_for_returned_qty(self):
+ from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
+ from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
+
+ so = make_sales_order(qty=2)
+ so.submit()
+
+ dn = make_delivery_note(so.name)
+ dn.submit()
+
+ dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-1, do_not_submit=True)
+ dn1.items[0].against_sales_order = so.name
+ dn1.items[0].so_detail = so.items[0].name
+ dn1.submit()
+
+ si = make_sales_invoice(dn.name)
+ self.assertEquals(si.items[0].qty, 1)
+
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 86594a2..3bebd29 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -458,7 +458,7 @@
fields: ["attribute_value"],
limit_start: 0,
limit_page_length: 500,
- parent: "Item"
+ parent: "Item Attribute"
}
}).then((r) => {
if(r.message) {
@@ -579,7 +579,7 @@
["attribute_value", "like", term + "%"]
],
fields: ["attribute_value"],
- parent: "Item"
+ parent: "Item Attribute"
},
callback: function(r) {
if (r.message) {
diff --git a/erpnext/stock/doctype/packed_item/packed_item.py b/erpnext/stock/doctype/packed_item/packed_item.py
index 0c55b43..e0ad7ac 100644
--- a/erpnext/stock/doctype/packed_item/packed_item.py
+++ b/erpnext/stock/doctype/packed_item/packed_item.py
@@ -49,8 +49,9 @@
pi.qty = flt(qty)
pi.description = description
if not pi.warehouse:
- pi.warehouse = (main_item_row.warehouse
- if (doc.get('is_pos') or not item.default_warehouse) else item.default_warehouse)
+ pi.warehouse = (main_item_row.warehouse if ((doc.get('is_pos')
+ or not item.default_warehouse) and main_item_row.warehouse) else item.default_warehouse)
+
if not pi.batch_no:
pi.batch_no = cstr(main_item_row.get("batch_no"))
if not pi.target_warehouse:
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 80dc4e1..2c56a97 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -182,7 +182,8 @@
if warehouse_account.get(d.warehouse):
stock_value_diff = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": self.name,
- "voucher_detail_no": d.name}, "stock_value_difference")
+ "voucher_detail_no": d.name, "warehouse": d.warehouse}, "stock_value_difference")
+
if not stock_value_diff:
continue
gl_entries.append(self.get_gl_dict({
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index 5c57fb5..5033b2d 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -1,6 +1,6 @@
frappe.listview_settings['Purchase Receipt'] = {
add_fields: ["supplier", "supplier_name", "base_grand_total", "is_subcontracted",
- "transporter_name", "is_return", "status", "per_billed"],
+ "transporter_name", "is_return", "status", "per_billed", "currency"],
get_indicator: function(doc) {
if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 3d1979d..e04343d 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -81,9 +81,9 @@
self.purchase_date = purchase_sle.posting_date
self.purchase_time = purchase_sle.posting_time
self.purchase_rate = purchase_sle.incoming_rate
- if purchase_sle.voucher_type == "Purchase Receipt":
+ if purchase_sle.voucher_type in ("Purchase Receipt", "Purchase Invoice"):
self.supplier, self.supplier_name = \
- frappe.db.get_value("Purchase Receipt", purchase_sle.voucher_no,
+ frappe.db.get_value(purchase_sle.voucher_type, purchase_sle.voucher_no,
["supplier", "supplier_name"])
# If sales return entry
@@ -253,8 +253,8 @@
status = False
if sn.purchase_document_no:
- if sle.voucher_type in ['Purchase Receipt', 'Stock Entry'] and \
- sn.delivery_document_type not in ['Purchase Receipt', 'Stock Entry']:
+ if sle.voucher_type in ['Purchase Receipt', 'Stock Entry', "Purchase Invoice"] and \
+ sn.delivery_document_type not in ['Purchase Receipt', 'Stock Entry', "Purchase Invoice"]:
status = True
if status and sle.voucher_type == 'Stock Entry' and \
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 5b6e706..257434f 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -180,7 +180,7 @@
frappe.throw(_("Valuation Rate required for Item in row {0}").format(row.idx))
if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction")
- and row.valuation_rate == previous_sle.get("valuation_rate"))
+ and (row.valuation_rate == previous_sle.get("valuation_rate") or row.qty == 0))
or (not previous_sle and not row.qty)):
continue
diff --git a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
index 1d69429..8dec3d0 100644
--- a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
+++ b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
@@ -84,6 +84,14 @@
is_stock_item=1 and name=pri.item_code)""", as_dict=1):
item_supplier_map.setdefault(d.item_code, []).append(d.supplier)
+ for d in frappe.db.sql("""select pr.supplier, pri.item_code from
+ `tabPurchase Invoice` pr, `tabPurchase Invoice Item` pri
+ where pr.name=pri.parent and pr.docstatus=1 and
+ ifnull(pr.update_stock, 0) = 1 and pri.item_code=(select name from `tabItem`
+ where is_stock_item=1 and name=pri.item_code)""", as_dict=1):
+ if d.item_code not in item_supplier_map:
+ item_supplier_map.setdefault(d.item_code, []).append(d.supplier)
+
if supplier:
for item_code, suppliers in item_supplier_map.items():
if supplier not in suppliers:
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 53267d6..c73cbf2 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -176,7 +176,11 @@
# rounding as per precision
self.stock_value = flt(self.stock_value, self.precision)
- stock_value_difference = self.stock_value - self.prev_stock_value
+ if self.prev_stock_value < 0 and self.stock_value >= 0 and sle.voucher_type != 'Stock Reconciliation':
+ stock_value_difference = sle.actual_qty * self.valuation_rate
+ else:
+ stock_value_difference = self.stock_value - self.prev_stock_value
+
self.prev_stock_value = self.stock_value
# update current sle