Merge branch 'develop' into workstation-type-feat-for-bom

This commit is contained in:
rohitwaghchaure 2022-11-16 23:26:08 +05:30 committed by GitHub
commit 31afae3e75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 57 additions and 89 deletions

View File

@ -16,8 +16,8 @@ repos:
- id: check-merge-conflict - id: check-merge-conflict
- id: check-ast - id: check-ast
- repo: https://gitlab.com/pycqa/flake8 - repo: https://github.com/PyCQA/flake8
rev: 3.9.2 rev: 5.0.4
hooks: hooks:
- id: flake8 - id: flake8
additional_dependencies: [ additional_dependencies: [

View File

@ -3,10 +3,6 @@
frappe.ui.form.on('Accounting Dimension Filter', { frappe.ui.form.on('Accounting Dimension Filter', {
refresh: function(frm, cdt, cdn) { refresh: function(frm, cdt, cdn) {
if (frm.doc.accounting_dimension) {
frm.set_df_property('dimensions', 'label', frm.doc.accounting_dimension, cdn, 'dimension_value');
}
let help_content = let help_content =
`<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);"> `<table class="table table-bordered" style="background-color: var(--scrollbar-track-color);">
<tr><td> <tr><td>
@ -68,6 +64,7 @@ frappe.ui.form.on('Accounting Dimension Filter', {
frm.clear_table("dimensions"); frm.clear_table("dimensions");
let row = frm.add_child("dimensions"); let row = frm.add_child("dimensions");
row.accounting_dimension = frm.doc.accounting_dimension; row.accounting_dimension = frm.doc.accounting_dimension;
frm.fields_dict["dimensions"].grid.update_docfield_property("dimension_value", "label", frm.doc.accounting_dimension);
frm.refresh_field("dimensions"); frm.refresh_field("dimensions");
frm.trigger('setup_filters'); frm.trigger('setup_filters');
}, },

View File

@ -45,21 +45,6 @@ frappe.ui.form.on("Journal Entry Template", {
frm.trigger("clear_child"); frm.trigger("clear_child");
switch(frm.doc.voucher_type){ switch(frm.doc.voucher_type){
case "Opening Entry":
frm.set_value("is_opening", "Yes");
frappe.call({
type:"GET",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_opening_accounts",
args: {
"company": frm.doc.company
},
callback: function(r) {
if(r.message) {
add_accounts(frm.doc, r.message);
}
}
});
break;
case "Bank Entry": case "Bank Entry":
case "Cash Entry": case "Cash Entry":
frappe.call({ frappe.call({

View File

@ -62,7 +62,6 @@ class PaymentEntry(AccountsController):
self.set_missing_values() self.set_missing_values()
self.validate_payment_type() self.validate_payment_type()
self.validate_party_details() self.validate_party_details()
self.validate_bank_accounts()
self.set_exchange_rate() self.set_exchange_rate()
self.validate_mandatory() self.validate_mandatory()
self.validate_reference_documents() self.validate_reference_documents()
@ -243,23 +242,6 @@ class PaymentEntry(AccountsController):
if not frappe.db.exists(self.party_type, self.party): if not frappe.db.exists(self.party_type, self.party):
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party)) frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
if self.party_account and self.party_type in ("Customer", "Supplier"):
self.validate_account_type(
self.party_account, [erpnext.get_party_account_type(self.party_type)]
)
def validate_bank_accounts(self):
if self.payment_type in ("Pay", "Internal Transfer"):
self.validate_account_type(self.paid_from, ["Bank", "Cash"])
if self.payment_type in ("Receive", "Internal Transfer"):
self.validate_account_type(self.paid_to, ["Bank", "Cash"])
def validate_account_type(self, account, account_types):
account_type = frappe.db.get_value("Account", account, "account_type")
# if account_type not in account_types:
# frappe.throw(_("Account Type for {0} must be {1}").format(account, comma_or(account_types)))
def set_exchange_rate(self, ref_doc=None): def set_exchange_rate(self, ref_doc=None):
self.set_source_exchange_rate(ref_doc) self.set_source_exchange_rate(ref_doc)
self.set_target_exchange_rate(ref_doc) self.set_target_exchange_rate(ref_doc)

View File

@ -2098,7 +2098,7 @@
{ {
"collapsible": 1, "collapsible": 1,
"collapsible_depends_on": "write_off_amount", "collapsible_depends_on": "write_off_amount",
"depends_on": "grand_total", "depends_on": "is_pos",
"fieldname": "write_off_section", "fieldname": "write_off_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hide_days": 1, "hide_days": 1,
@ -2126,7 +2126,7 @@
"link_fieldname": "consolidated_invoice" "link_fieldname": "consolidated_invoice"
} }
], ],
"modified": "2022-11-07 16:02:07.972258", "modified": "2022-11-15 09:33:47.870616",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",

View File

@ -571,13 +571,14 @@ class SalesInvoice(SellingController):
# validate if deferred revenue is enabled for any item # validate if deferred revenue is enabled for any item
# Don't allow to update the invoice if deferred revenue is enabled # Don't allow to update the invoice if deferred revenue is enabled
for item in self.get("items"): if needs_repost:
if item.enable_deferred_revenue: for item in self.get("items"):
frappe.throw( if item.enable_deferred_revenue:
_( frappe.throw(
"Deferred Revenue is enabled for item {0}. You cannot update the invoice after submission." _(
).format(item.item_code) "Deferred Revenue is enabled for item {0}. You cannot update the invoice after submission."
) ).format(item.item_code)
)
self.db_set("repost_required", needs_repost) self.db_set("repost_required", needs_repost)
@ -1393,7 +1394,11 @@ class SalesInvoice(SellingController):
def make_write_off_gl_entry(self, gl_entries): def make_write_off_gl_entry(self, gl_entries):
# write off entries, applicable if only pos # write off entries, applicable if only pos
if self.write_off_account and flt(self.write_off_amount, self.precision("write_off_amount")): if (
self.is_pos
and 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) write_off_account_currency = get_account_currency(self.write_off_account)
default_cost_center = frappe.get_cached_value("Company", self.company, "cost_center") default_cost_center = frappe.get_cached_value("Company", self.company, "cost_center")

View File

@ -100,7 +100,7 @@ class SubcontractingController(StockController):
and self._doc_before_save and self._doc_before_save
): ):
for row in self._doc_before_save.get("items"): for row in self._doc_before_save.get("items"):
item_dict[row.name] = (row.item_code, row.received_qty or row.qty) item_dict[row.name] = (row.item_code, row.qty)
return item_dict return item_dict
@ -118,9 +118,7 @@ class SubcontractingController(StockController):
for row in self.items: for row in self.items:
self.__reference_name.append(row.name) self.__reference_name.append(row.name)
if (row.name not in item_dict) or (row.item_code, row.received_qty or row.qty) != item_dict[ if (row.name not in item_dict) or (row.item_code, row.qty) != item_dict[row.name]:
row.name
]:
self.__changed_name.append(row.name) self.__changed_name.append(row.name)
if item_dict.get(row.name): if item_dict.get(row.name):
@ -463,13 +461,12 @@ class SubcontractingController(StockController):
def __get_qty_based_on_material_transfer(self, item_row, transfer_item): def __get_qty_based_on_material_transfer(self, item_row, transfer_item):
key = (item_row.item_code, item_row.get(self.subcontract_data.order_field)) key = (item_row.item_code, item_row.get(self.subcontract_data.order_field))
item_qty = item_row.received_qty or item_row.qty
if self.qty_to_be_received.get(key) == item_qty: if self.qty_to_be_received == item_row.qty:
return transfer_item.qty return transfer_item.qty
if self.qty_to_be_received: if self.qty_to_be_received:
qty = (flt(item_qty) * flt(transfer_item.qty)) / flt(self.qty_to_be_received.get(key, 0)) qty = (flt(item_row.qty) * flt(transfer_item.qty)) / flt(self.qty_to_be_received.get(key, 0))
transfer_item.item_details.required_qty = transfer_item.qty transfer_item.item_details.required_qty = transfer_item.qty
if transfer_item.serial_no or frappe.get_cached_value( if transfer_item.serial_no or frappe.get_cached_value(
@ -494,11 +491,7 @@ class SubcontractingController(StockController):
for bom_item in self.__get_materials_from_bom( for bom_item in self.__get_materials_from_bom(
row.item_code, row.bom, row.get("include_exploded_items") row.item_code, row.bom, row.get("include_exploded_items")
): ):
qty = ( qty = flt(bom_item.qty_consumed_per_unit) * flt(row.qty) * row.conversion_factor
flt(bom_item.qty_consumed_per_unit)
* flt(row.received_qty or row.qty)
* row.conversion_factor
)
bom_item.main_item_code = row.item_code bom_item.main_item_code = row.item_code
self.__update_reserve_warehouse(bom_item, row) self.__update_reserve_warehouse(bom_item, row)
self.__set_alternative_item(bom_item) self.__set_alternative_item(bom_item)

View File

@ -649,23 +649,13 @@ class ProductionPlan(Document):
else: else:
material_request = material_request_map[key] material_request = material_request_map[key]
conversion_factor = 1.0
if (
material_request_type == "Purchase"
and item_doc.purchase_uom
and item_doc.purchase_uom != item_doc.stock_uom
):
conversion_factor = (
get_conversion_factor(item_doc.name, item_doc.purchase_uom).get("conversion_factor") or 1.0
)
# add item # add item
material_request.append( material_request.append(
"items", "items",
{ {
"item_code": item.item_code, "item_code": item.item_code,
"from_warehouse": item.from_warehouse, "from_warehouse": item.from_warehouse,
"qty": item.quantity / conversion_factor, "qty": item.quantity,
"schedule_date": schedule_date, "schedule_date": schedule_date,
"warehouse": item.warehouse, "warehouse": item.warehouse,
"sales_order": item.sales_order, "sales_order": item.sales_order,
@ -1053,11 +1043,25 @@ def get_material_request_items(
if include_safety_stock: if include_safety_stock:
required_qty += flt(row["safety_stock"]) required_qty += flt(row["safety_stock"])
item_details = frappe.get_cached_value(
"Item", row.item_code, ["purchase_uom", "stock_uom"], as_dict=1
)
conversion_factor = 1.0
if (
row.get("default_material_request_type") == "Purchase"
and item_details.purchase_uom
and item_details.purchase_uom != item_details.stock_uom
):
conversion_factor = (
get_conversion_factor(row.item_code, item_details.purchase_uom).get("conversion_factor") or 1.0
)
if required_qty > 0: if required_qty > 0:
return { return {
"item_code": row.item_code, "item_code": row.item_code,
"item_name": row.item_name, "item_name": row.item_name,
"quantity": required_qty, "quantity": required_qty / conversion_factor,
"required_bom_qty": total_qty, "required_bom_qty": total_qty,
"stock_uom": row.get("stock_uom"), "stock_uom": row.get("stock_uom"),
"warehouse": warehouse "warehouse": warehouse

View File

@ -826,6 +826,11 @@ class TestProductionPlan(FrappeTestCase):
) )
pln.make_material_request() pln.make_material_request()
for row in pln.mr_items:
self.assertEqual(row.uom, "Nos")
self.assertEqual(row.quantity, 1)
for row in frappe.get_all( for row in frappe.get_all(
"Material Request Item", "Material Request Item",
filters={"production_plan": pln.name}, filters={"production_plan": pln.name},

View File

@ -11,7 +11,7 @@ $.extend(erpnext.bulk_transaction_processing, {
}); });
let count_of_rows = checked_items.length; let count_of_rows = checked_items.length;
frappe.confirm(__("Create {0} {1} ?", [count_of_rows, to_doctype]), ()=>{ frappe.confirm(__("Create {0} {1} ?", [count_of_rows, __(to_doctype)]), ()=>{
if (doc_name.length == 0) { if (doc_name.length == 0) {
frappe.call({ frappe.call({
method: "erpnext.utilities.bulk_transaction.transaction_processing", method: "erpnext.utilities.bulk_transaction.transaction_processing",
@ -20,11 +20,11 @@ $.extend(erpnext.bulk_transaction_processing, {
}); });
if (count_of_rows > 10) { if (count_of_rows > 10) {
frappe.show_alert("Starting a background job to create {0} {1}", [count_of_rows, to_doctype]); frappe.show_alert("Starting a background job to create {0} {1}", [count_of_rows, __(to_doctype)]);
} }
} else { } else {
frappe.msgprint(__("Selected document must be in submitted state")); frappe.msgprint(__("Selected document must be in submitted state"));
} }
}); });
} }
}); });

View File

@ -6,6 +6,7 @@ import json
from typing import Dict, Optional from typing import Dict, Optional
import frappe import frappe
from frappe.utils import cint
from frappe.utils.nestedset import get_root_of from frappe.utils.nestedset import get_root_of
from erpnext.accounts.doctype.pos_invoice.pos_invoice import get_stock_availability from erpnext.accounts.doctype.pos_invoice.pos_invoice import get_stock_availability
@ -108,10 +109,10 @@ def get_items(start, page_length, price_list, item_group, pos_profile, search_te
item.name asc item.name asc
LIMIT LIMIT
{page_length} offset {start}""".format( {page_length} offset {start}""".format(
start=start, start=cint(start),
page_length=page_length, page_length=cint(page_length),
lft=lft, lft=cint(lft),
rgt=rgt, rgt=cint(rgt),
condition=condition, condition=condition,
bin_join_selection=bin_join_selection, bin_join_selection=bin_join_selection,
bin_join_condition=bin_join_condition, bin_join_condition=bin_join_condition,

View File

@ -58,7 +58,6 @@ class SubcontractingReceipt(SubcontractingController):
def before_validate(self): def before_validate(self):
super(SubcontractingReceipt, self).before_validate() super(SubcontractingReceipt, self).before_validate()
self.set_items_bom() self.set_items_bom()
self.set_received_qty()
self.set_items_cost_center() self.set_items_cost_center()
self.set_items_expense_account() self.set_items_expense_account()
@ -213,10 +212,6 @@ class SubcontractingReceipt(SubcontractingController):
"bom", "bom",
) )
def set_received_qty(self):
for item in self.items:
item.received_qty = flt(item.qty) + flt(item.rejected_qty)
def set_items_cost_center(self): def set_items_cost_center(self):
if self.company: if self.company:
cost_center = frappe.get_cached_value("Company", self.company, "cost_center") cost_center = frappe.get_cached_value("Company", self.company, "cost_center")

View File

@ -515,17 +515,18 @@ class TestSubcontractingReceipt(FrappeTestCase):
scr.items[0].rejected_qty = 3 scr.items[0].rejected_qty = 3
scr.save() scr.save()
# consumed_qty should be ((received_qty) * (transfered_qty / qty)) = ((5 + 3) * (20 / 10)) = 16 # consumed_qty should be (accepted_qty * (transfered_qty / qty)) = (5 * (20 / 10)) = 10
self.assertEqual(scr.supplied_items[0].consumed_qty, 16) self.assertEqual(scr.supplied_items[0].consumed_qty, 10)
# Set Backflush Based On as "BOM" # Set Backflush Based On as "BOM"
set_backflush_based_on("BOM") set_backflush_based_on("BOM")
scr.items[0].qty = 6 # Accepted Qty
scr.items[0].rejected_qty = 4 scr.items[0].rejected_qty = 4
scr.save() scr.save()
# consumed_qty should be ((received_qty) * (qty_consumed_per_unit)) = ((5 + 4) * (1)) = 9 # consumed_qty should be (accepted_qty * qty_consumed_per_unit) = (6 * 1) = 6
self.assertEqual(scr.supplied_items[0].consumed_qty, 9) self.assertEqual(scr.supplied_items[0].consumed_qty, 6)
def make_return_subcontracting_receipt(**args): def make_return_subcontracting_receipt(**args):