Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-27916

This commit is contained in:
Afshan
2021-10-27 14:05:51 +05:30
committed by GitHub
10 changed files with 100 additions and 44 deletions

View File

@@ -590,5 +590,11 @@ frappe.ui.form.on("Purchase Invoice", {
company: function(frm) { company: function(frm) {
erpnext.accounts.dimensions.update_dimension(frm, frm.doctype); erpnext.accounts.dimensions.update_dimension(frm, frm.doctype);
if (frm.doc.company) {
frappe.db.get_value('Company', frm.doc.company, 'default_payable_account', (r) => {
frm.set_value('credit_to', r.default_payable_account);
});
}
}, },
}) })

View File

@@ -10,9 +10,17 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
this.setup_posting_date_time_check(); this.setup_posting_date_time_check();
this._super(doc); this._super(doc);
}, },
company: function() { company: function() {
erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype); erpnext.accounts.dimensions.update_dimension(this.frm, this.frm.doctype);
let me = this;
if (this.frm.doc.company) {
frappe.db.get_value('Company', this.frm.doc.company, 'default_receivable_account', (r) => {
me.frm.set_value('debit_to', r.default_receivable_account);
});
}
}, },
onload: function() { onload: function() {
var me = this; var me = this;
this._super(); this._super();

View File

@@ -1359,8 +1359,8 @@ class AccountsController(TransactionBase):
total = 0 total = 0
base_total = 0 base_total = 0
for d in self.get("payment_schedule"): for d in self.get("payment_schedule"):
total += flt(d.payment_amount) total += flt(d.payment_amount, d.precision("payment_amount"))
base_total += flt(d.base_payment_amount) base_total += flt(d.base_payment_amount, d.precision("base_payment_amount"))
base_grand_total = self.get("base_rounded_total") or self.base_grand_total base_grand_total = self.get("base_rounded_total") or self.base_grand_total
grand_total = self.get("rounded_total") or self.grand_total grand_total = self.get("rounded_total") or self.grand_total
@@ -1376,8 +1376,9 @@ class AccountsController(TransactionBase):
else: else:
grand_total -= self.get("total_advance") grand_total -= self.get("total_advance")
base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total")) base_grand_total = flt(grand_total * self.get("conversion_rate"), self.precision("base_grand_total"))
if total != flt(grand_total, self.precision("grand_total")) or \
base_total != flt(base_grand_total, self.precision("base_grand_total")): if flt(total, self.precision("grand_total")) != flt(grand_total, self.precision("grand_total")) or \
flt(base_total, self.precision("base_grand_total")) != flt(base_grand_total, self.precision("base_grand_total")):
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total")) frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
def is_rounded_total_disabled(self): def is_rounded_total_disabled(self):

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
import frappe import frappe
from frappe import _dict
from frappe.utils import floor from frappe.utils import floor
@@ -96,38 +95,32 @@ class ProductFiltersBuilder:
return return
attributes = [row.attribute for row in self.doc.filter_attributes] attributes = [row.attribute for row in self.doc.filter_attributes]
attribute_docs = [
frappe.get_doc('Item Attribute', attribute) for attribute in attributes
]
valid_attributes = [] if not attributes:
return []
for attr_doc in attribute_docs: result = frappe.db.sql(
selected_attributes = [] """
for attr in attr_doc.item_attribute_values: select
or_filters = [] distinct attribute, attribute_value
filters= [ from
["Item Variant Attribute", "attribute", "=", attr.parent], `tabItem Variant Attribute`
["Item Variant Attribute", "attribute_value", "=", attr.attribute_value] where
] attribute in %(attributes)s
if self.item_group: and attribute_value is not null
or_filters.extend([ """,
["item_group", "=", self.item_group], {"attributes": attributes},
["Website Item Group", "item_group", "=", self.item_group] as_dict=1,
]) )
if frappe.db.get_all("Item", filters, or_filters=or_filters, limit=1): attribute_value_map = {}
selected_attributes.append(attr) for d in result:
attribute_value_map.setdefault(d.attribute, []).append(d.attribute_value)
if selected_attributes: out = []
valid_attributes.append( for name, values in attribute_value_map.items():
_dict( out.append(frappe._dict(name=name, item_attribute_values=values))
item_attribute_values=selected_attributes, return out
name=attr_doc.name
)
)
return valid_attributes
def get_discount_filters(self, discounts): def get_discount_filters(self, discounts):
discount_filters = [] discount_filters = []
@@ -147,4 +140,4 @@ class ProductFiltersBuilder:
label = f"{discount}% and below" label = f"{discount}% and below"
discount_filters.append([discount, label]) discount_filters.append([discount, label])
return discount_filters return discount_filters

View File

@@ -175,9 +175,7 @@ class TestProductDataEngine(unittest.TestCase):
filter_engine = ProductFiltersBuilder() filter_engine = ProductFiltersBuilder()
attribute_filter = filter_engine.get_attribute_filters()[0] attribute_filter = filter_engine.get_attribute_filters()[0]
attributes = attribute_filter.item_attribute_values attribute_values = attribute_filter.item_attribute_values
attribute_values = [d.attribute_value for d in attributes]
self.assertEqual(attribute_filter.name, "Test Size") self.assertEqual(attribute_filter.name, "Test Size")
self.assertGreater(len(attribute_values), 0) self.assertGreater(len(attribute_values), 0)
@@ -349,4 +347,4 @@ def create_variant_web_item():
variant.save() variant.save()
if not frappe.db.exists("Website Item", {"variant_of": "Test Web Item"}): if not frappe.db.exists("Website Item", {"variant_of": "Test Web Item"}):
make_website_item(variant, save=True) make_website_item(variant, save=True)

View File

@@ -311,7 +311,7 @@ class ProductionPlan(Document):
if self.total_produced_qty > 0: if self.total_produced_qty > 0:
self.status = "In Process" self.status = "In Process"
if self.total_produced_qty >= self.total_planned_qty: if self.check_have_work_orders_completed():
self.status = "Completed" self.status = "Completed"
if self.status != 'Completed': if self.status != 'Completed':
@@ -575,6 +575,15 @@ class ProductionPlan(Document):
self.append("sub_assembly_items", data) self.append("sub_assembly_items", data)
def check_have_work_orders_completed(self):
wo_status = frappe.db.get_list(
"Work Order",
filters={"production_plan": self.name},
fields="status",
pluck="status"
)
return all(s == "Completed" for s in wo_status)
@frappe.whitelist() @frappe.whitelist()
def download_raw_materials(doc, warehouses=None): def download_raw_materials(doc, warehouses=None):
if isinstance(doc, str): if isinstance(doc, str):

View File

@@ -329,3 +329,4 @@ erpnext.patches.v13_0.trim_sales_invoice_custom_field_length
erpnext.patches.v13_0.enable_scheduler_job_for_item_reposting erpnext.patches.v13_0.enable_scheduler_job_for_item_reposting
erpnext.patches.v13_0.requeue_failed_reposts erpnext.patches.v13_0.requeue_failed_reposts
erpnext.patches.v13_0.fetch_thumbnail_in_website_items erpnext.patches.v13_0.fetch_thumbnail_in_website_items
erpnext.patches.v12_0.update_production_plan_status

View File

@@ -0,0 +1,31 @@
# Copyright (c) 2021, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
def execute():
frappe.reload_doc("manufacturing", "doctype", "production_plan")
frappe.db.sql("""
UPDATE `tabProduction Plan` ppl
SET status = "Completed"
WHERE ppl.name IN (
SELECT ss.name FROM (
SELECT
(
count(wo.status = "Completed") =
count(pp.name)
) =
(
pp.status != "Completed"
AND pp.total_produced_qty >= pp.total_planned_qty
) AS should_set,
pp.name AS name
FROM
`tabWork Order` wo INNER JOIN`tabProduction Plan` pp
ON wo.production_plan = pp.name
GROUP BY pp.name
HAVING should_set = 1
) ss
)
""")

View File

@@ -1,6 +1,7 @@
{ {
"category": "Modules", "category": "Modules",
"charts": [], "charts": [],
"content": "[{\"type\":\"header\",\"data\":{\"text\":\"Your Shortcuts\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\",\"level\":4,\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Projects Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Accounts Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Stock Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"HR Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Selling Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Buying Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Support Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Shopping Cart Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Portal Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Domain Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Products Settings\",\"col\":4}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Naming Series\",\"col\":4}}]",
"creation": "2020-03-12 14:47:51.166455", "creation": "2020-03-12 14:47:51.166455",
"developer_mode_only": 0, "developer_mode_only": 0,
"disable_user_customization": 0, "disable_user_customization": 0,
@@ -15,7 +16,7 @@
"is_standard": 1, "is_standard": 1,
"label": "ERPNext Settings", "label": "ERPNext Settings",
"links": [], "links": [],
"modified": "2021-06-12 01:58:11.399566", "modified": "2021-10-26 21:32:55.323591",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Setup", "module": "Setup",
"name": "ERPNext Settings", "name": "ERPNext Settings",
@@ -29,6 +30,14 @@
"link_to": "Projects Settings", "link_to": "Projects Settings",
"type": "DocType" "type": "DocType"
}, },
{
"color": "Grey",
"doc_view": "",
"icon": "dot-horizontal",
"label": "Naming Series",
"link_to": "Naming Series",
"type": "DocType"
},
{ {
"icon": "accounting", "icon": "accounting",
"label": "Accounts Settings", "label": "Accounts Settings",

View File

@@ -339,15 +339,15 @@
<div class="filter-options"> <div class="filter-options">
{% for attr_value in attribute.item_attribute_values %} {% for attr_value in attribute.item_attribute_values %}
<div class="checkbox"> <div class="checkbox">
<label data-value="{{ attr_value }}"> <label>
<input type="checkbox" <input type="checkbox"
class="product-filter attribute-filter" class="product-filter attribute-filter"
id="{{attr_value.name}}" id="{{ attr_value }}"
data-attribute-name="{{ attribute.name }}" data-attribute-name="{{ attribute.name }}"
data-attribute-value="{{ attr_value.attribute_value }}" data-attribute-value="{{ attr_value }}"
style="width: 14px !important" style="width: 14px !important"
{% if attr_value.checked %} checked {% endif %}> {% if attr_value.checked %} checked {% endif %}>
<span class="label-area">{{ attr_value.attribute_value }}</span> <span class="label-area">{{ attr_value }}</span>
</label> </label>
</div> </div>
{% endfor %} {% endfor %}