Skip to content

Commit 3bd15fb

Browse files
committed
Merge branch 'develop'
2 parents 154385d + a282c13 commit 3bd15fb

File tree

57 files changed

+896
-290
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+896
-290
lines changed

erpnext/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from __future__ import unicode_literals
33
import frappe
44

5-
__version__ = '8.0.26'
5+
__version__ = '8.0.27'
66

77
def get_default_company(user=None):
88
'''Get default company for user'''

erpnext/accounts/doctype/payment_entry/payment_entry.js

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ frappe.ui.form.on('Payment Entry', {
147147
var currency_field = (frm.doc.payment_type=="Receive") ? "paid_from_account_currency" : "paid_to_account_currency"
148148
frm.set_df_property("total_allocated_amount", "options", currency_field);
149149
frm.set_df_property("unallocated_amount", "options", currency_field);
150+
frm.set_df_property("party_balance", "options", currency_field);
150151

151152
frm.set_currency_labels(["total_amount", "outstanding_amount", "allocated_amount"],
152153
party_account_currency, "references");

erpnext/accounts/doctype/pricing_rule/pricing_rule.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,10 @@ def _get_tree_conditions(parenttype, allow_blank=True):
285285

286286
def filter_pricing_rules(args, pricing_rules):
287287
# filter for qty
288+
stock_qty = args.get('qty') * args.get('conversion_factor', 1)
288289
if pricing_rules:
289-
pricing_rules = filter(lambda x: (flt(args.get("qty"))>=flt(x.min_qty)
290-
and (flt(args.get("qty"))<=x.max_qty if x.max_qty else True)), pricing_rules)
290+
pricing_rules = filter(lambda x: (flt(stock_qty)>=flt(x.min_qty)
291+
and (flt(stock_qty)<=x.max_qty if x.max_qty else True)), pricing_rules)
291292

292293
# add variant_of property in pricing rule
293294
for p in pricing_rules:

erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py

+46
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
from __future__ import unicode_literals
66
import unittest
77
import frappe
8+
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
9+
from erpnext.stock.get_item_details import get_item_details
10+
from frappe import MandatoryError
811

912
class TestPricingRule(unittest.TestCase):
1013
def test_pricing_rule_for_discount(self):
@@ -203,3 +206,46 @@ def test_pricing_rule_for_variants(self):
203206

204207
details = get_item_details(args)
205208
self.assertEquals(details.get("discount_percentage"), 17.5)
209+
210+
def test_pricing_rule_for_stock_qty(self):
211+
frappe.db.sql("delete from `tabPricing Rule`")
212+
213+
test_record = {
214+
"doctype": "Pricing Rule",
215+
"title": "_Test Pricing Rule",
216+
"apply_on": "Item Code",
217+
"item_code": "_Test Item",
218+
"selling": 1,
219+
"price_or_discount": "Discount Percentage",
220+
"price": 0,
221+
"min_qty": 5,
222+
"max_qty": 7,
223+
"discount_percentage": 17.5,
224+
"company": "_Test Company"
225+
}
226+
frappe.get_doc(test_record.copy()).insert()
227+
228+
if not frappe.db.get_value('UOM Conversion Detail',
229+
{'parent': '_Test Item', 'uom': 'box'}):
230+
item = frappe.get_doc('Item', '_Test Item')
231+
item.append('uoms', {
232+
'uom': 'Box',
233+
'conversion_factor': 5
234+
})
235+
item.save(ignore_permissions=True)
236+
237+
# With pricing rule
238+
so = make_sales_order(item_code="_Test Item", qty=1, uom="Box", do_not_submit=True)
239+
so.items[0].price_list_rate = 100
240+
so.submit()
241+
so = frappe.get_doc('Sales Order', so.name)
242+
self.assertEquals(so.items[0].discount_percentage, 17.5)
243+
self.assertEquals(so.items[0].rate, 82.5)
244+
245+
# Without pricing rule
246+
so = make_sales_order(item_code="_Test Item", qty=2, uom="Box", do_not_submit=True)
247+
so.items[0].price_list_rate = 100
248+
so.submit()
249+
so = frappe.get_doc('Sales Order', so.name)
250+
self.assertEquals(so.items[0].discount_percentage, 0)
251+
self.assertEquals(so.items[0].rate, 100)

erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,37 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
4949
}
5050

5151
if(doc.docstatus===0) {
52-
cur_frm.add_custom_button(__('Purchase Order'), function() {
52+
var me = this;
53+
this.frm.add_custom_button(__('Purchase Order'), function() {
5354
erpnext.utils.map_current_doc({
5455
method: "erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice",
5556
source_doctype: "Purchase Order",
57+
target: me.frm,
58+
setters: {
59+
supplier: me.frm.doc.supplier || undefined,
60+
},
5661
get_query_filters: {
57-
supplier: cur_frm.doc.supplier || undefined,
5862
docstatus: 1,
5963
status: ["!=", "Closed"],
6064
per_billed: ["<", 99.99],
61-
company: cur_frm.doc.company
65+
company: me.frm.doc.company
6266
}
6367
})
6468
}, __("Get items from"));
6569

66-
cur_frm.add_custom_button(__('Purchase Receipt'), function() {
70+
this.frm.add_custom_button(__('Purchase Receipt'), function() {
6771
erpnext.utils.map_current_doc({
6872
method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_invoice",
6973
source_doctype: "Purchase Receipt",
74+
target: me.frm,
75+
date_field: "posting_date",
76+
setters: {
77+
supplier: me.frm.doc.supplier || undefined,
78+
},
7079
get_query_filters: {
71-
supplier: cur_frm.doc.supplier || undefined,
7280
docstatus: 1,
7381
status: ["!=", "Closed"],
74-
company: cur_frm.doc.company
82+
company: me.frm.doc.company
7583
}
7684
})
7785
}, __("Get items from"));
@@ -120,7 +128,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
120128
hide_fields(this.frm.doc);
121129
if(cint(this.frm.doc.is_paid)) {
122130
if(!this.frm.doc.company) {
123-
cur_frm.set_value("is_paid", 0)
131+
this.frm.set_value("is_paid", 0)
124132
msgprint(__("Please specify Company to proceed"));
125133
}
126134
}

erpnext/accounts/doctype/sales_invoice/sales_invoice.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -112,33 +112,43 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
112112
},
113113

114114
sales_order_btn: function() {
115-
this.$sales_order_btn = cur_frm.add_custom_button(__('Sales Order'),
115+
var me = this;
116+
this.$sales_order_btn = this.frm.add_custom_button(__('Sales Order'),
116117
function() {
117118
erpnext.utils.map_current_doc({
118119
method: "erpnext.selling.doctype.sales_order.sales_order.make_sales_invoice",
119120
source_doctype: "Sales Order",
121+
target: me.frm,
122+
setters: {
123+
customer: me.frm.doc.customer || undefined,
124+
},
120125
get_query_filters: {
121126
docstatus: 1,
122127
status: ["!=", "Closed"],
123128
per_billed: ["<", 99.99],
124-
customer: cur_frm.doc.customer || undefined,
125-
company: cur_frm.doc.company
129+
company: me.frm.doc.company
126130
}
127131
})
128132
}, __("Get items from"));
129133
},
130134

131135
delivery_note_btn: function() {
132-
this.$delivery_note_btn = cur_frm.add_custom_button(__('Delivery Note'),
136+
var me = this;
137+
this.$delivery_note_btn = this.frm.add_custom_button(__('Delivery Note'),
133138
function() {
134139
erpnext.utils.map_current_doc({
135140
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice",
136141
source_doctype: "Delivery Note",
142+
target: me.frm,
143+
date_field: "posting_date",
144+
setters: {
145+
company: me.frm.doc.company
146+
},
137147
get_query: function() {
138148
var filters = {
139-
company: cur_frm.doc.company
149+
docstatus: 1,
140150
};
141-
if(cur_frm.doc.customer) filters["customer"] = cur_frm.doc.customer;
151+
if(me.frm.doc.customer) filters["customer"] = me.frm.doc.customer;
142152
return {
143153
query: "erpnext.controllers.queries.get_delivery_notes_to_be_billed",
144154
filters: filters

erpnext/accounts/doctype/sales_invoice/sales_invoice.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def set_indicator(self):
5252

5353
def validate(self):
5454
super(SalesInvoice, self).validate()
55-
self.validate_posting_time()
55+
self.validate_auto_set_posting_time()
5656
self.so_dn_required()
5757
self.validate_proj_cust()
5858
self.validate_with_previous_doc()
@@ -378,6 +378,12 @@ def set_against_income_account(self):
378378
def add_remarks(self):
379379
if not self.remarks: self.remarks = 'No Remarks'
380380

381+
def validate_auto_set_posting_time(self):
382+
# Don't auto set the posting date and time if invoice is amended
383+
if self.is_new() and self.amended_from:
384+
self.set_posting_time = 1
385+
386+
self.validate_posting_time()
381387

382388
def so_dn_required(self):
383389
"""check in manage account if sales order / delivery note required or not."""

erpnext/accounts/page/pos/pos.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
7878

7979
make_menu_list: function () {
8080
var me = this;
81-
8281
this.page.clear_menu();
82+
83+
// for mobile
84+
this.page.add_menu_item(__("Pay"), function () {
85+
me.validate();
86+
me.update_paid_amount_status(true);
87+
me.create_invoice();
88+
me.make_payment();
89+
}).addClass('visible-xs');
90+
8391
this.page.add_menu_item(__("New Sales Invoice"), function () {
8492
me.save_previous_entry();
8593
me.create_new();
@@ -788,7 +796,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
788796

789797
add_customer: function() {
790798
this.frm.doc.customer = "";
791-
this.update_customer(true)
799+
this.update_customer(true);
800+
this.numeric_keypad.show();
792801
},
793802

794803
update_customer: function (new_customer) {

erpnext/buying/doctype/purchase_order/purchase_order.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -153,30 +153,37 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
153153
},
154154

155155
add_from_mappers: function() {
156-
cur_frm.add_custom_button(__('Material Request'),
156+
var me = this;
157+
this.frm.add_custom_button(__('Material Request'),
157158
function() {
158159
erpnext.utils.map_current_doc({
159160
method: "erpnext.stock.doctype.material_request.material_request.make_purchase_order",
160161
source_doctype: "Material Request",
162+
target: me.frm,
163+
setters: {
164+
company: me.frm.doc.company
165+
},
161166
get_query_filters: {
162167
material_request_type: "Purchase",
163168
docstatus: 1,
164169
status: ["!=", "Stopped"],
165170
per_ordered: ["<", 99.99],
166-
company: cur_frm.doc.company
167171
}
168172
})
169173
}, __("Add items from"));
170174

171-
cur_frm.add_custom_button(__('Supplier Quotation'),
175+
this.frm.add_custom_button(__('Supplier Quotation'),
172176
function() {
173177
erpnext.utils.map_current_doc({
174178
method: "erpnext.buying.doctype.supplier_quotation.supplier_quotation.make_purchase_order",
175179
source_doctype: "Supplier Quotation",
180+
target: me.frm,
181+
setters: {
182+
company: me.frm.doc.company
183+
},
176184
get_query_filters: {
177185
docstatus: 1,
178186
status: ["!=", "Stopped"],
179-
company: cur_frm.doc.company
180187
}
181188
})
182189
}, __("Add items from"));

erpnext/buying/doctype/request_for_quotation/request_for_quotation.js

+18-11
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ frappe.ui.form.on("Request for Quotation",{
4848
});
4949
});
5050
}
51-
51+
5252
},
5353

5454
make_suppplier_quotation: function(frm) {
@@ -124,24 +124,28 @@ frappe.ui.form.on("Request for Quotation Supplier",{
124124

125125
erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.extend({
126126
refresh: function() {
127+
var me = this;
127128
this._super();
128129
if (this.frm.doc.docstatus===0) {
129-
cur_frm.add_custom_button(__('Material Request'),
130+
this.frm.add_custom_button(__('Material Request'),
130131
function() {
131132
erpnext.utils.map_current_doc({
132133
method: "erpnext.stock.doctype.material_request.material_request.make_request_for_quotation",
133134
source_doctype: "Material Request",
135+
target: me.frm,
136+
setters: {
137+
company: me.frm.doc.company
138+
},
134139
get_query_filters: {
135140
material_request_type: "Purchase",
136141
docstatus: 1,
137142
status: ["!=", "Stopped"],
138-
per_ordered: ["<", 99.99],
139-
company: cur_frm.doc.company
143+
per_ordered: ["<", 99.99]
140144
}
141145
})
142146
}, __("Get items from"));
143147
// Get items from open Material Requests based on supplier
144-
cur_frm.add_custom_button(__('Possible Supplier'), function() {
148+
this.frm.add_custom_button(__('Possible Supplier'), function() {
145149
// Create a dialog window for the user to pick their supplier
146150
var d = new frappe.ui.Dialog({
147151
title: __('Select Possible Supplier'),
@@ -150,32 +154,35 @@ erpnext.buying.RequestforQuotationController = erpnext.buying.BuyingController.e
150154
{fieldname: 'ok_button', fieldtype:'Button', label:'Get Items from Material Requests'},
151155
]
152156
});
153-
157+
154158
// On the user clicking the ok button
155159
d.fields_dict.ok_button.input.onclick = function() {
156160
var btn = d.fields_dict.ok_button.input;
157161
var v = d.get_values();
158162
if(v) {
159163
$(btn).set_working();
160-
164+
161165
erpnext.utils.map_current_doc({
162166
method: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_item_from_material_requests_based_on_supplier",
163167
source_name: v.supplier,
168+
target: me.frm,
169+
setters: {
170+
company: me.frm.doc.company
171+
},
164172
get_query_filters: {
165173
material_request_type: "Purchase",
166174
docstatus: 1,
167175
status: ["!=", "Stopped"],
168-
per_ordered: ["<", 99.99],
169-
company: cur_frm.doc.company
176+
per_ordered: ["<", 99.99]
170177
}
171178
});
172179
$(btn).done_working();
173180
d.hide();
174181
}
175-
}
182+
}
176183
d.show();
177184
}, __("Get items from"));
178-
185+
179186
}
180187
},
181188

0 commit comments

Comments
 (0)