Merge pull request #4640 from nabinhait/fix50

Fixes
This commit is contained in:
Nabin Hait 2016-01-20 16:35:46 +05:30
commit 61673aafd4
11 changed files with 59 additions and 39 deletions

View File

@ -351,6 +351,7 @@ class JournalEntry(AccountsController):
def set_print_format_fields(self): def set_print_format_fields(self):
total_amount = 0.0 total_amount = 0.0
bank_account_currency = None bank_account_currency = None
self.pay_to_recd_from = None
for d in self.get('accounts'): for d in self.get('accounts'):
if d.party_type and d.party: if d.party_type and d.party:
if not self.pay_to_recd_from: if not self.pay_to_recd_from:
@ -361,6 +362,9 @@ class JournalEntry(AccountsController):
total_amount += (d.debit_in_account_currency or d.credit_in_account_currency) total_amount += (d.debit_in_account_currency or d.credit_in_account_currency)
bank_account_currency = d.account_currency bank_account_currency = d.account_currency
if not self.pay_to_recd_from:
total_amount = 0
self.set_total_amount(total_amount, bank_account_currency) self.set_total_amount(total_amount, bank_account_currency)
def set_total_amount(self, amt, currency): def set_total_amount(self, amt, currency):

View File

@ -98,6 +98,9 @@ def apply_pricing_rule(args):
args = frappe._dict(args) args = frappe._dict(args)
if not args.transaction_type:
set_transaction_type(args)
# list of dictionaries # list of dictionaries
out = [] out = []
@ -134,13 +137,17 @@ def get_pricing_rule_for_item(args):
if not args.item_group: if not args.item_group:
frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code)) frappe.throw(_("Item Group not mentioned in item master for item {0}").format(args.item_code))
if args.transaction_type=="selling":
if args.customer and not (args.customer_group and args.territory): if args.customer and not (args.customer_group and args.territory):
customer = frappe.db.get_value("Customer", args.customer, ["customer_group", "territory"]) customer = frappe.db.get_value("Customer", args.customer, ["customer_group", "territory"])
if customer: if customer:
args.customer_group, args.territory = customer args.customer_group, args.territory = customer
args.supplier = args.supplier_type = None
elif args.supplier and not args.supplier_type: elif args.supplier and not args.supplier_type:
args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type") args.supplier_type = frappe.db.get_value("Supplier", args.supplier, "supplier_type")
args.customer = args.customer_group = args.territory = None
pricing_rules = get_pricing_rules(args) pricing_rules = get_pricing_rules(args)
pricing_rule = filter_pricing_rules(args, pricing_rules) pricing_rule = filter_pricing_rules(args, pricing_rules)
@ -212,7 +219,7 @@ def get_pricing_rules(args):
and {transaction_type} = 1 {conditions} and {transaction_type} = 1 {conditions}
order by priority desc, name desc""".format( order by priority desc, name desc""".format(
item_group_condition=item_group_condition, item_group_condition=item_group_condition,
transaction_type= "selling" if (args.customer or args.lead) else "buying", transaction_type= args.transaction_type,
conditions=conditions), values, as_dict=1) conditions=conditions), values, as_dict=1)
def filter_pricing_rules(args, pricing_rules): def filter_pricing_rules(args, pricing_rules):
@ -270,3 +277,14 @@ def apply_internal_priority(pricing_rules, field_set, args):
if filtered_rules: break if filtered_rules: break
return filtered_rules or pricing_rules return filtered_rules or pricing_rules
def set_transaction_type(args):
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
args.transaction_type = "selling"
elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",
"Purchase Receipt", "Purchase Invoice"):
args.transaction_type = "buying"
elif args.customer:
args.transaction_type = "selling"
else:
args.transaction_type = "buying"

View File

@ -31,13 +31,12 @@ class TestPricingRule(unittest.TestCase):
"company": "_Test Company", "company": "_Test Company",
"price_list": "_Test Price List", "price_list": "_Test Price List",
"currency": "_Test Currency", "currency": "_Test Currency",
"parenttype": "Sales Order", "doctype": "Sales Order",
"conversion_rate": 1, "conversion_rate": 1,
"price_list_currency": "_Test Currency", "price_list_currency": "_Test Currency",
"plc_conversion_rate": 1, "plc_conversion_rate": 1,
"order_type": "Sales", "order_type": "Sales",
"customer": "_Test Customer", "customer": "_Test Customer",
"doctype": "Sales Order Item",
"name": None "name": None
}) })
details = get_item_details(args) details = get_item_details(args)
@ -45,7 +44,9 @@ class TestPricingRule(unittest.TestCase):
prule = frappe.get_doc(test_record.copy()) prule = frappe.get_doc(test_record.copy())
prule.applicable_for = "Customer" prule.applicable_for = "Customer"
prule.title = "_Test Pricing Rule for Customer"
self.assertRaises(MandatoryError, prule.insert) self.assertRaises(MandatoryError, prule.insert)
prule.customer = "_Test Customer" prule.customer = "_Test Customer"
prule.discount_percentage = 20 prule.discount_percentage = 20
prule.insert() prule.insert()
@ -55,16 +56,18 @@ class TestPricingRule(unittest.TestCase):
prule = frappe.get_doc(test_record.copy()) prule = frappe.get_doc(test_record.copy())
prule.apply_on = "Item Group" prule.apply_on = "Item Group"
prule.item_group = "All Item Groups" prule.item_group = "All Item Groups"
prule.title = "_Test Pricing Rule for Item Group"
prule.discount_percentage = 15 prule.discount_percentage = 15
prule.insert() prule.insert()
args.customer = None args.customer = "_Test Customer 1"
details = get_item_details(args) details = get_item_details(args)
self.assertEquals(details.get("discount_percentage"), 10) self.assertEquals(details.get("discount_percentage"), 10)
prule = frappe.get_doc(test_record.copy()) prule = frappe.get_doc(test_record.copy())
prule.applicable_for = "Campaign" prule.applicable_for = "Campaign"
prule.campaign = "_Test Campaign" prule.campaign = "_Test Campaign"
prule.title = "_Test Pricing Rule for Campaign"
prule.discount_percentage = 5 prule.discount_percentage = 5
prule.priority = 8 prule.priority = 8
prule.insert() prule.insert()

View File

@ -152,8 +152,8 @@ class AccountsController(TransactionBase):
args = parent_dict.copy() args = parent_dict.copy()
args.update(item.as_dict()) args.update(item.as_dict())
args["doctype"] = parent_dict.get("doctype") args["doctype"] = self.doctype
args["name"] = parent_dict.get("name") args["name"] = self.name
if not args.get("transaction_date"): if not args.get("transaction_date"):
args["transaction_date"] = args.get("posting_date") args["transaction_date"] = args.get("posting_date")

View File

@ -9,7 +9,6 @@ from frappe.model.mapper import get_mapped_doc
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
from erpnext.utilities.transaction_base import TransactionBase from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import get_party_account_currency from erpnext.accounts.party import get_party_account_currency
from erpnext.stock.get_item_details import apply_price_list
subject_field = "title" subject_field = "title"
sender_field = "contact_email" sender_field = "contact_email"
@ -193,8 +192,6 @@ def make_quotation(source_name, target_doc=None):
quotation.currency = party_account_currency or company_currency quotation.currency = party_account_currency or company_currency
quotation.conversion_rate = exchange_rate quotation.conversion_rate = exchange_rate
quotation.update(apply_price_list(quotation.as_dict(), as_doc = True))
quotation.run_method("set_missing_values") quotation.run_method("set_missing_values")
quotation.run_method("calculate_taxes_and_totals") quotation.run_method("calculate_taxes_and_totals")

View File

@ -4,17 +4,15 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import cint, cstr, flt from frappe.utils import cint, cstr, flt
from frappe import _ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
from operator import itemgetter from operator import itemgetter
class BOM(Document): class BOM(Document):
def autoname(self): def autoname(self):
last_name = frappe.db.sql("""select max(name) from `tabBOM` last_name = frappe.db.sql("""select max(name) from `tabBOM`
where name like "BOM/%s/%%" """ % frappe.db.escape(self.item)) where name like "BOM/{0}/%%" and item=%s""".format(frappe.db.escape(self.item)), self.item)
if last_name: if last_name:
idx = cint(cstr(last_name[0][0]).split('/')[-1].split('-')[0]) + 1 idx = cint(cstr(last_name[0][0]).split('/')[-1].split('-')[0]) + 1
else: else:

View File

@ -26,6 +26,7 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
cur_frm.cscript['Declare Order Lost'], __("Status")); cur_frm.cscript['Declare Order Lost'], __("Status"));
} }
cur_frm.page.set_inner_btn_group_as_primary(__("Make"));
} }
if (this.frm.doc.docstatus===0) { if (this.frm.doc.docstatus===0) {

View File

@ -334,8 +334,8 @@ class TestSalesOrder(unittest.TestCase):
existing_ordered_qty = bin[0].ordered_qty if bin else 0.0 existing_ordered_qty = bin[0].ordered_qty if bin else 0.0
existing_reserved_qty = bin[0].reserved_qty if bin else 0.0 existing_reserved_qty = bin[0].reserved_qty if bin else 0.0
bin = frappe.get_all("Bin", filters={"item_code": dn_item.item_code, "warehouse": "_Test Warehouse - _TC"}, bin = frappe.get_all("Bin", filters={"item_code": dn_item.item_code,
fields=["reserved_qty"]) "warehouse": "_Test Warehouse - _TC"}, fields=["reserved_qty"])
existing_reserved_qty_for_dn_item = bin[0].reserved_qty if bin else 0.0 existing_reserved_qty_for_dn_item = bin[0].reserved_qty if bin else 0.0

View File

@ -93,13 +93,14 @@ class TestItem(unittest.TestCase):
"price_list_currency": "_Test Currency", "price_list_currency": "_Test Currency",
"plc_conversion_rate": 1, "plc_conversion_rate": 1,
"order_type": "Sales", "order_type": "Sales",
"customer": "_Test Customer"
}) })
for key, value in to_check.iteritems(): for key, value in to_check.iteritems():
self.assertEquals(value, details.get(key)) self.assertEquals(value, details.get(key))
def test_make_item_variant(self): def test_make_item_variant(self):
frappe.delete_doc_if_exists("Item", "_Test Variant Item-L") frappe.delete_doc_if_exists("Item", "_Test Variant Item-L", force=1)
variant = create_variant("_Test Variant Item", {"Test Size": "Large"}) variant = create_variant("_Test Variant Item", {"Test Size": "Large"})
variant.save() variant.save()

View File

@ -11,7 +11,6 @@ from frappe.utils import cstr, flt, getdate
from frappe import _ from frappe import _
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
from erpnext.stock.get_item_details import apply_price_list
from erpnext.controllers.buying_controller import BuyingController from erpnext.controllers.buying_controller import BuyingController
@ -24,7 +23,7 @@ class MaterialRequest(BuyingController):
return _("{0}: {1}").format(self.status, self.material_request_type) return _("{0}: {1}").format(self.status, self.material_request_type)
def check_if_already_pulled(self): def check_if_already_pulled(self):
pass#if self.[d.sales_order_no for d in self.get('items')] pass
def validate_qty_against_so(self): def validate_qty_against_so(self):
so_items = {} # Format --> {'SO/00001': {'Item/001': 120, 'Item/002': 24}} so_items = {} # Format --> {'SO/00001': {'Item/001': 120, 'Item/002': 24}}
@ -183,7 +182,6 @@ def update_item(obj, target, source_parent):
@frappe.whitelist() @frappe.whitelist()
def make_purchase_order(source_name, target_doc=None): def make_purchase_order(source_name, target_doc=None):
def postprocess(source, target_doc): def postprocess(source, target_doc):
target_doc.update(apply_price_list(target_doc.as_dict(), as_doc = True))
set_missing_values(source, target_doc) set_missing_values(source, target_doc)
doclist = get_mapped_doc("Material Request", source_name, { doclist = get_mapped_doc("Material Request", source_name, {
@ -226,8 +224,6 @@ def make_purchase_order_based_on_supplier(source_name, target_doc=None):
target_doc.set("items", [d for d in target_doc.get("items") target_doc.set("items", [d for d in target_doc.get("items")
if d.get("item_code") in supplier_items and d.get("qty") > 0]) if d.get("item_code") in supplier_items and d.get("qty") > 0])
target_doc.update(apply_price_list(target_doc.as_dict(), as_doc = True))
set_missing_values(source, target_doc) set_missing_values(source, target_doc)
for mr in material_requests: for mr in material_requests:
@ -271,7 +267,6 @@ def get_material_requests_based_on_supplier(supplier):
@frappe.whitelist() @frappe.whitelist()
def make_supplier_quotation(source_name, target_doc=None): def make_supplier_quotation(source_name, target_doc=None):
def postprocess(source, target_doc): def postprocess(source, target_doc):
target_doc.update(apply_price_list(target_doc.as_dict(), as_doc = True))
set_missing_values(source, target_doc) set_missing_values(source, target_doc)
doclist = get_mapped_doc("Material Request", source_name, { doclist = get_mapped_doc("Material Request", source_name, {

View File

@ -6,7 +6,7 @@ import frappe
from frappe import _, throw from frappe import _, throw
from frappe.utils import flt, cint, add_days, cstr from frappe.utils import flt, cint, add_days, cstr
import json import json
from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_for_item from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_for_item, set_transaction_type
from erpnext.setup.utils import get_exchange_rate from erpnext.setup.utils import get_exchange_rate
from frappe.model.meta import get_field_precision from frappe.model.meta import get_field_precision
@ -85,6 +85,8 @@ def process_args(args):
elif not args.item_code and args.serial_no: elif not args.item_code and args.serial_no:
args.item_code = get_item_code(serial_no=args.serial_no) args.item_code = get_item_code(serial_no=args.serial_no)
set_transaction_type(args)
return args return args
@frappe.whitelist() @frappe.whitelist()
@ -107,7 +109,7 @@ def validate_item_details(args, item):
from erpnext.stock.doctype.item.item import validate_end_of_life from erpnext.stock.doctype.item.item import validate_end_of_life
validate_end_of_life(item.name, item.end_of_life, item.disabled) validate_end_of_life(item.name, item.end_of_life, item.disabled)
if args.customer or args.doctype=="Opportunity": if args.transaction_type=="selling":
# validate if sales item or service item # validate if sales item or service item
if args.get("order_type") == "Maintenance": if args.get("order_type") == "Maintenance":
if item.is_service_item != 1: if item.is_service_item != 1:
@ -119,7 +121,7 @@ def validate_item_details(args, item):
if cint(item.has_variants): if cint(item.has_variants):
throw(_("Item {0} is a template, please select one of its variants").format(item.name)) throw(_("Item {0} is a template, please select one of its variants").format(item.name))
elif args.supplier and args.doctype != "Material Request": elif args.transaction_type=="buying" and args.doctype != "Material Request":
# validate if purchase item or subcontracted item # validate if purchase item or subcontracted item
if item.is_purchase_item != 1: if item.is_purchase_item != 1:
throw(_("Item {0} must be a Purchase Item").format(item.name)) throw(_("Item {0} must be a Purchase Item").format(item.name))
@ -219,7 +221,7 @@ def get_price_list_rate(args, item_doc, out):
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \ out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
/ flt(args.conversion_rate) / flt(args.conversion_rate)
if not out.price_list_rate and args.supplier: if not out.price_list_rate and args.transaction_type=="buying":
from erpnext.stock.doctype.item.item import get_last_purchase_details from erpnext.stock.doctype.item.item import get_last_purchase_details
out.update(get_last_purchase_details(item_doc.name, out.update(get_last_purchase_details(item_doc.name,
args.name, args.conversion_rate)) args.name, args.conversion_rate))
@ -251,7 +253,7 @@ def get_price_list_rate_for(price_list, item_code):
def validate_price_list(args): def validate_price_list(args):
if args.get("price_list"): if args.get("price_list"):
if not frappe.db.get_value("Price List", if not frappe.db.get_value("Price List",
{"name": args.price_list, "selling" if (args.customer or args.lead) else "buying": 1, "enabled": 1}): {"name": args.price_list, args.transaction_type: 1, "enabled": 1}):
throw(_("Price List {0} is disabled").format(args.price_list)) throw(_("Price List {0} is disabled").format(args.price_list))
else: else:
throw(_("Price List not selected")) throw(_("Price List not selected"))
@ -283,10 +285,11 @@ def validate_conversion_rate(args, meta):
frappe._dict({"fields": args}))) frappe._dict({"fields": args})))
def get_party_item_code(args, item_doc, out): def get_party_item_code(args, item_doc, out):
if args.customer: if args.transaction_type=="selling" and args.customer:
customer_item_code = item_doc.get("customer_items", {"customer_name": args.customer}) customer_item_code = item_doc.get("customer_items", {"customer_name": args.customer})
out.customer_item_code = customer_item_code[0].ref_code if customer_item_code else None out.customer_item_code = customer_item_code[0].ref_code if customer_item_code else None
else:
if args.transaction_type=="buying" and args.supplier:
item_supplier = item_doc.get("supplier_items", {"supplier": args.supplier}) item_supplier = item_doc.get("supplier_items", {"supplier": args.supplier})
out.supplier_part_no = item_supplier[0].supplier_part_no if item_supplier else None out.supplier_part_no = item_supplier[0].supplier_part_no if item_supplier else None