Merge branch 'develop' into item-variant-attributes-optional

This commit is contained in:
Faris Ansari 2019-05-07 14:25:03 +05:30 committed by GitHub
commit 9a45bd11d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 246 additions and 821 deletions

View File

@ -403,7 +403,7 @@ def make_purchase_invoice(source_name, target_doc=None):
or item.get("buying_cost_center")
or item_group.get("buying_cost_center"))
doc = get_mapped_doc("Purchase Order", source_name, {
fields = {
"Purchase Order": {
"doctype": "Purchase Invoice",
"field_map": {
@ -426,8 +426,16 @@ def make_purchase_invoice(source_name, target_doc=None):
"Purchase Taxes and Charges": {
"doctype": "Purchase Taxes and Charges",
"add_if_empty": True
},
}
if frappe.get_single("Accounts Settings").automatically_fetch_payment_terms == 1:
fields["Payment Schedule"] = {
"doctype": "Payment Schedule",
"add_if_empty": True
}
}, target_doc, postprocess)
doc = get_mapped_doc("Purchase Order", source_name, fields, target_doc, postprocess)
return doc

View File

@ -6,7 +6,7 @@ import unittest
import frappe
import frappe.defaults
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from frappe.utils import flt, add_days, nowdate
from frappe.utils import flt, add_days, nowdate, getdate
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_rm_stock_entry as make_subcontract_transfer_entry)
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
@ -142,9 +142,9 @@ class TestPurchaseOrder(unittest.TestCase):
po.submit()
self.assertEqual(po.payment_schedule[0].payment_amount, 2500.0)
self.assertEqual(po.payment_schedule[0].due_date, po.transaction_date)
self.assertEqual(getdate(po.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(po.payment_schedule[1].payment_amount, 2500.0)
self.assertEqual(po.payment_schedule[1].due_date, add_days(po.transaction_date, 30))
self.assertEqual(getdate(po.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
pi = make_purchase_invoice(po.name)
pi.save()
@ -152,9 +152,9 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(len(pi.get("items", [])), 1)
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500.0)
self.assertEqual(pi.payment_schedule[0].due_date, po.transaction_date)
self.assertEqual(getdate(pi.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(pi.payment_schedule[1].payment_amount, 2500.0)
self.assertEqual(pi.payment_schedule[1].due_date, add_days(po.transaction_date, 30))
self.assertEqual(getdate(pi.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
def test_subcontracting(self):
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
@ -303,6 +303,10 @@ class TestPurchaseOrder(unittest.TestCase):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100",
qty=20, basic_rate=100)
make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item",
qty=30, basic_rate=100)
make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item Home Desktop 100",
qty=30, basic_rate=100)
bin1 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
@ -349,6 +353,11 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6)
make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item",
qty=40, basic_rate=100)
make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item Home Desktop 100",
qty=40, basic_rate=100)
# make Purchase Receipt against PO
pr = make_purchase_receipt(po.name)
pr.supplier_warehouse = "_Test Warehouse 1 - _TC"

View File

@ -600,3 +600,4 @@ erpnext.patches.v11_1.woocommerce_set_creation_user
erpnext.patches.v11_1.set_salary_details_submittable
erpnext.patches.v11_1.rename_depends_on_lwp
execute:frappe.delete_doc("Report", "Inactive Items")
erpnext.patches.v11_1.delete_scheduling_tool

View File

@ -0,0 +1,9 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
if frappe.db.exists("DocType", "Scheduling Tool"):
frappe.delete_doc("DocType", "Scheduling Tool", ignore_permissions=True)

View File

@ -66,15 +66,14 @@ class ItemVariantsCacheManager:
as_list=1
)
disabled_items = [i.name for i in frappe.db.get_all('Item', {'disabled': 1})]
disabled_items = set([i.name for i in frappe.db.get_all('Item', {'disabled': 1})])
attribute_value_item_map = frappe._dict({})
item_attribute_value_map = frappe._dict({})
item_variants_data = [r for r in item_variants_data if r[0] not in disabled_items]
for row in item_variants_data:
item_code, attribute, attribute_value = row
if item_code in disabled_items:
continue
# (attr, value) => [item1, item2]
attribute_value_item_map.setdefault((attribute, attribute_value), []).append(item_code)
# item => {attr1: value1, attr2: value2}
@ -97,6 +96,10 @@ class ItemVariantsCacheManager:
for key in keys:
frappe.cache().hdel(key, self.item_code)
def rebuild_cache(self):
self.clear_cache()
enqueue_build_cache(self.item_code)
def build_cache(item_code):
frappe.cache().hset('item_cache_build_in_progress', item_code, 1)

View File

@ -260,7 +260,8 @@ def get_items_with_selected_attributes(item_code, selected_attributes):
items = []
for attribute, value in selected_attributes.items():
items.append(set(attribute_value_item_map[(attribute, value)]))
filtered_items = attribute_value_item_map.get((attribute, value), [])
items.append(set(filtered_items))
return set.intersection(*items)

View File

@ -109,6 +109,18 @@ frappe.ui.form.on("Project", {
}
});
},
status: function(frm) {
if (frm.doc.status === 'Cancelled') {
frappe.confirm(__('Set tasks in this project as cancelled?'), () => {
frm.doc.tasks = frm.doc.tasks.map(task => {
task.status = 'Cancelled';
return task;
});
frm.refresh_field('tasks');
});
}
}
});
frappe.ui.form.on("Project Task", {

View File

@ -35,6 +35,9 @@ class Project(Document):
def load_tasks(self):
"""Load `tasks` from the database"""
if frappe.flags.in_import:
return
self.tasks = []
for task in self.get_tasks():
task_map = {
@ -358,7 +361,8 @@ class Project(Document):
if not self.get('deleted_task_list'): return
for d in self.get('deleted_task_list'):
frappe.delete_doc("Task", d)
# unlink project
frappe.db.set_value('Task', d, 'project', '')
self.deleted_task_list = []

View File

@ -105,7 +105,7 @@ class Task(NestedSet):
def update_project(self):
if self.project and not self.flags.from_project:
frappe.get_doc("Project", self.project).update_project()
frappe.get_cached_doc("Project", self.project).update_project()
def check_recursion(self):
if self.flags.ignore_recursion_check: return
@ -150,7 +150,7 @@ class Task(NestedSet):
def populate_depends_on(self):
if self.parent_task:
parent = frappe.get_doc('Task', self.parent_task)
parent = frappe.get_cached_doc('Task', self.parent_task)
if not self.name in [row.task for row in parent.depends_on]:
parent.append("depends_on", {
"doctype": "Task Depends On",

View File

@ -123,5 +123,6 @@ frappe.ui.form.on("Customer", {
},
validate: function(frm) {
if(frm.doc.lead_name) frappe.model.clear_doc("Lead", frm.doc.lead_name);
},
});

View File

@ -60,6 +60,10 @@ class Customer(TransactionBase):
if self.loyalty_program == customer.loyalty_program and not self.loyalty_program_tier:
self.loyalty_program_tier = customer.loyalty_program_tier
if self.sales_team:
if sum([member.allocated_percentage for member in self.sales_team]) != 100:
frappe.throw(_("Total contribution percentage should be equal to 100"))
def check_customer_group_change(self):
frappe.flags.customer_group_changed = False

View File

@ -966,7 +966,7 @@ def invalidate_item_variants_cache_for_website(doc):
if item_code:
item_cache = ItemVariantsCacheManager(item_code)
item_cache.clear_cache()
item_cache.rebuild_cache()
def check_stock_uom_with_bin(item, stock_uom):

View File

@ -1116,7 +1116,7 @@ class StockEntry(StockController):
frappe.MappingMismatchError)
def validate_batch(self):
if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor", "Material Issue"]:
if self.purpose in ["Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor"]:
for item in self.get("items"):
if item.batch_no:
disabled = frappe.db.get_value("Batch", item.batch_no, "disabled")

View File

@ -40,6 +40,13 @@ $(document).ready(function() {
right: 0%;
width: 100%;
}
{% include "templates/styles/card_style.css" %}
header, footer {
display: none;
}
html, body {
background-color: #f5f7fa;
}
</style>
{% endblock %}