Merge branch 'version-12-hotfix' into version-12
This commit is contained in:
commit
9335cdd536
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '12.0.4'
|
||||
__version__ = '12.0.5'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -6,16 +6,10 @@ from frappe import _
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'bank',
|
||||
'non_standard_fieldnames': {
|
||||
'Paymnet Order': 'company_bank'
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Bank Deatils'),
|
||||
'items': ['Bank Account', 'Bank Guarantee']
|
||||
},
|
||||
{
|
||||
'items': ['Payment Order']
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -648,13 +648,18 @@ def get_orders_to_be_billed(posting_date, party_type, party,
|
||||
|
||||
orders = []
|
||||
if voucher_type:
|
||||
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||
if party_account_currency == company_currency:
|
||||
grand_total_field = "base_grand_total"
|
||||
rounded_total_field = "base_rounded_total"
|
||||
else:
|
||||
grand_total_field = "grand_total"
|
||||
rounded_total_field = "rounded_total"
|
||||
|
||||
orders = frappe.db.sql("""
|
||||
select
|
||||
name as voucher_no,
|
||||
{ref_field} as invoice_amount,
|
||||
({ref_field} - advance_paid) as outstanding_amount,
|
||||
if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) as invoice_amount,
|
||||
(if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) - advance_paid) as outstanding_amount,
|
||||
transaction_date as posting_date
|
||||
from
|
||||
`tab{voucher_type}`
|
||||
@ -663,13 +668,14 @@ def get_orders_to_be_billed(posting_date, party_type, party,
|
||||
and docstatus = 1
|
||||
and company = %s
|
||||
and ifnull(status, "") != "Closed"
|
||||
and {ref_field} > advance_paid
|
||||
and if({rounded_total_field}, {rounded_total_field}, {grand_total_field}) > advance_paid
|
||||
and abs(100 - per_billed) > 0.01
|
||||
{condition}
|
||||
order by
|
||||
transaction_date, name
|
||||
""".format(**{
|
||||
"ref_field": ref_field,
|
||||
"rounded_total_field": rounded_total_field,
|
||||
"grand_total_field": grand_total_field,
|
||||
"voucher_type": voucher_type,
|
||||
"party_type": scrub(party_type),
|
||||
"condition": condition
|
||||
|
@ -382,7 +382,7 @@ def get_qty_amount_data_for_cumulative(pr_doc, doc, items=[]):
|
||||
`tab{child_doc}`.amount
|
||||
FROM `tab{child_doc}`, `tab{parent_doc}`
|
||||
WHERE
|
||||
`tab{child_doc}`.parent = `tab{parent_doc}`.name and {date_field}
|
||||
`tab{child_doc}`.parent = `tab{parent_doc}`.name and `tab{parent_doc}`.{date_field}
|
||||
between %s and %s and `tab{parent_doc}`.docstatus = 1
|
||||
{condition} group by `tab{child_doc}`.name
|
||||
""".format(parent_doc = doctype,
|
||||
|
@ -93,6 +93,7 @@ def check_if_in_list(gle, gl_map, dimensions=None):
|
||||
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||
if not from_repost:
|
||||
validate_account_for_perpetual_inventory(gl_map)
|
||||
validate_cwip_accounts(gl_map)
|
||||
|
||||
round_off_debit_credit(gl_map)
|
||||
|
||||
@ -123,6 +124,16 @@ def validate_account_for_perpetual_inventory(gl_map):
|
||||
frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
|
||||
.format(entry.account), StockAccountInvalidTransaction)
|
||||
|
||||
def validate_cwip_accounts(gl_map):
|
||||
if not cint(frappe.db.get_value("Asset Settings", None, "disable_cwip_accounting")) \
|
||||
and gl_map[0].voucher_type == "Journal Entry":
|
||||
cwip_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
||||
where account_type = 'Capital Work in Progress' and is_group=0""")]
|
||||
|
||||
for entry in gl_map:
|
||||
if entry.account in cwip_accounts:
|
||||
frappe.throw(_("Account: <b>{0}</b> is capital Work in progress and can not be updated by Journal Entry").format(entry.account))
|
||||
|
||||
def round_off_debit_credit(gl_map):
|
||||
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
|
||||
currency=frappe.get_cached_value('Company', gl_map[0].company, "default_currency"))
|
||||
|
@ -30,7 +30,9 @@ def update_last_purchase_rate(doc, is_submit):
|
||||
# for it to be considered for latest purchase rate
|
||||
if flt(d.conversion_factor):
|
||||
last_purchase_rate = flt(d.base_rate) / flt(d.conversion_factor)
|
||||
else:
|
||||
# Check if item code is present
|
||||
# Conversion factor should not be mandatory for non itemized items
|
||||
elif d.item_code:
|
||||
frappe.throw(_("UOM Conversion factor is required in row {0}").format(d.idx))
|
||||
|
||||
# update last purchsae rate
|
||||
@ -84,13 +86,13 @@ def get_linked_material_requests(items):
|
||||
items = json.loads(items)
|
||||
mr_list = []
|
||||
for item in items:
|
||||
material_request = frappe.db.sql("""SELECT distinct mr.name AS mr_name,
|
||||
(mr_item.qty - mr_item.ordered_qty) AS qty,
|
||||
material_request = frappe.db.sql("""SELECT distinct mr.name AS mr_name,
|
||||
(mr_item.qty - mr_item.ordered_qty) AS qty,
|
||||
mr_item.item_code AS item_code,
|
||||
mr_item.name AS mr_item
|
||||
mr_item.name AS mr_item
|
||||
FROM `tabMaterial Request` mr, `tabMaterial Request Item` mr_item
|
||||
WHERE mr.name = mr_item.parent
|
||||
AND mr_item.item_code = %(item)s
|
||||
AND mr_item.item_code = %(item)s
|
||||
AND mr.material_request_type = 'Purchase'
|
||||
AND mr.per_ordered < 99.99
|
||||
AND mr.docstatus = 1
|
||||
@ -98,6 +100,6 @@ def get_linked_material_requests(items):
|
||||
ORDER BY mr_item.item_code ASC""",{"item": item}, as_dict=1)
|
||||
if material_request:
|
||||
mr_list.append(material_request)
|
||||
|
||||
|
||||
return mr_list
|
||||
|
||||
|
@ -94,6 +94,13 @@ def get_data():
|
||||
"name": "BOM Update Tool",
|
||||
"description": _("Replace BOM and update latest price in all BOMs"),
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"label": _("BOM Comparison Tool"),
|
||||
"name": "bom-comparison-tool",
|
||||
"description": _("Compare BOMs for changes in Raw Materials and Operations"),
|
||||
"data_doctype": "BOM"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1192,6 +1192,10 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
|
||||
.format(child_item.idx, child_item.item_code))
|
||||
else:
|
||||
child_item.rate = flt(d.get("rate"))
|
||||
if child_item.price_list_rate:
|
||||
child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, \
|
||||
child_item.precision("discount_percentage"))
|
||||
|
||||
child_item.flags.ignore_validate_update_after_submit = True
|
||||
if new_child_flag:
|
||||
child_item.idx = len(parent.items) + 1
|
||||
|
@ -395,7 +395,9 @@ class BuyingController(StockController):
|
||||
def set_qty_as_per_stock_uom(self):
|
||||
for d in self.get("items"):
|
||||
if d.meta.get_field("stock_qty"):
|
||||
if not d.conversion_factor:
|
||||
# Check if item code is present
|
||||
# Conversion factor should not be mandatory for non itemized items
|
||||
if not d.conversion_factor and d.item_code:
|
||||
frappe.throw(_("Row {0}: Conversion Factor is mandatory").format(d.idx))
|
||||
d.stock_qty = flt(d.qty) * flt(d.conversion_factor)
|
||||
|
||||
|
@ -82,7 +82,7 @@ class calculate_taxes_and_totals(object):
|
||||
|
||||
item.net_rate = item.rate
|
||||
|
||||
if not item.qty and self.doc.is_return:
|
||||
if not item.qty and self.doc.get("is_return"):
|
||||
item.amount = flt(-1 * item.rate, item.precision("amount"))
|
||||
else:
|
||||
item.amount = flt(item.rate * item.qty, item.precision("amount"))
|
||||
|
@ -77,7 +77,7 @@ def get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_len
|
||||
|
||||
if or_filters:
|
||||
for r in frappe.get_list(doctype, fields=fields,filters=filters, or_filters=or_filters,
|
||||
limit_start=limit_start, limit_page_length=limit_page_length,
|
||||
limit_start=limit_start, limit_page_length=limit_page_length,
|
||||
ignore_permissions=ignore_permissions, order_by=order_by):
|
||||
data.append(r)
|
||||
|
||||
@ -130,38 +130,56 @@ def get_customers_suppliers(doctype, user):
|
||||
suppliers = []
|
||||
meta = frappe.get_meta(doctype)
|
||||
|
||||
customer_field_name = get_customer_field_name(doctype)
|
||||
|
||||
has_customer_field = meta.has_field(customer_field_name)
|
||||
has_supplier_field = meta.has_field('supplier')
|
||||
|
||||
if has_common(["Supplier", "Customer"], frappe.get_roles(user)):
|
||||
contacts = frappe.db.sql("""
|
||||
select
|
||||
select
|
||||
`tabContact`.email_id,
|
||||
`tabDynamic Link`.link_doctype,
|
||||
`tabDynamic Link`.link_name
|
||||
from
|
||||
from
|
||||
`tabContact`, `tabDynamic Link`
|
||||
where
|
||||
`tabContact`.name=`tabDynamic Link`.parent and `tabContact`.email_id =%s
|
||||
""", user, as_dict=1)
|
||||
customers = [c.link_name for c in contacts if c.link_doctype == 'Customer'] \
|
||||
if meta.get_field("customer") else None
|
||||
suppliers = [c.link_name for c in contacts if c.link_doctype == 'Supplier'] \
|
||||
if meta.get_field("supplier") else None
|
||||
customers = [c.link_name for c in contacts if c.link_doctype == 'Customer']
|
||||
suppliers = [c.link_name for c in contacts if c.link_doctype == 'Supplier']
|
||||
elif frappe.has_permission(doctype, 'read', user=user):
|
||||
customers = [customer.name for customer in frappe.get_list("Customer")] \
|
||||
if meta.get_field("customer") else None
|
||||
suppliers = [supplier.name for supplier in frappe.get_list("Customer")] \
|
||||
if meta.get_field("supplier") else None
|
||||
customer_list = frappe.get_list("Customer")
|
||||
customers = suppliers = [customer.name for customer in customer_list]
|
||||
|
||||
return customers, suppliers
|
||||
return customers if has_customer_field else None, \
|
||||
suppliers if has_supplier_field else None
|
||||
|
||||
def has_website_permission(doc, ptype, user, verbose=False):
|
||||
doctype = doc.doctype
|
||||
customers, suppliers = get_customers_suppliers(doctype, user)
|
||||
if customers:
|
||||
return frappe.get_all(doctype, filters=[(doctype, "customer", "in", customers),
|
||||
(doctype, "name", "=", doc.name)]) and True or False
|
||||
return frappe.db.exists(doctype, filters=get_customer_filter(doc, customers))
|
||||
elif suppliers:
|
||||
fieldname = 'suppliers' if doctype == 'Request for Quotation' else 'supplier'
|
||||
return frappe.get_all(doctype, filters=[(doctype, fieldname, "in", suppliers),
|
||||
(doctype, "name", "=", doc.name)]) and True or False
|
||||
return frappe.db.exists(doctype, filters={
|
||||
'name': doc.name,
|
||||
fieldname: ["in", suppliers]
|
||||
})
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_customer_filter(doc, customers):
|
||||
doctype = doc.doctype
|
||||
filters = frappe._dict()
|
||||
filters.name = doc.name
|
||||
filters[get_customer_field_name(doctype)] = ['in', customers]
|
||||
if doctype == 'Quotation':
|
||||
filters.party_type = 'Customer'
|
||||
return filters
|
||||
|
||||
def get_customer_field_name(doctype):
|
||||
if doctype == 'Quotation':
|
||||
return 'party_name'
|
||||
else:
|
||||
return 'customer'
|
@ -64,13 +64,20 @@ class EmployeeAdvance(Document):
|
||||
|
||||
def update_claimed_amount(self):
|
||||
claimed_amount = frappe.db.sql("""
|
||||
select sum(ifnull(allocated_amount, 0))
|
||||
from `tabExpense Claim Advance`
|
||||
where employee_advance = %s and docstatus=1 and allocated_amount > 0
|
||||
SELECT sum(ifnull(allocated_amount, 0))
|
||||
FROM `tabExpense Claim Advance` eca, `tabExpense Claim` ec
|
||||
WHERE
|
||||
eca.employee_advance = %s
|
||||
AND ec.approval_status="Approved"
|
||||
AND ec.name = eca.parent
|
||||
AND ec.docstatus=1
|
||||
AND eca.allocated_amount > 0
|
||||
""", self.name)[0][0] or 0
|
||||
|
||||
if claimed_amount:
|
||||
frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
|
||||
frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
|
||||
self.reload()
|
||||
self.set_status()
|
||||
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_due_advance_amount(employee, posting_date):
|
||||
|
@ -183,7 +183,7 @@ frappe.ui.form.on("Expense Claim", {
|
||||
refresh: function(frm) {
|
||||
frm.trigger("toggle_fields");
|
||||
|
||||
if(frm.doc.docstatus == 1) {
|
||||
if(frm.doc.docstatus === 1 && frm.doc.approval_status !== "Rejected") {
|
||||
frm.add_custom_button(__('Accounting Ledger'), function() {
|
||||
frappe.route_options = {
|
||||
voucher_no: frm.doc.name,
|
||||
@ -194,7 +194,7 @@ frappe.ui.form.on("Expense Claim", {
|
||||
}, __("View"));
|
||||
}
|
||||
|
||||
if (frm.doc.docstatus===1
|
||||
if (frm.doc.docstatus===1 && !cint(frm.doc.is_paid) && cint(frm.doc.grand_total) > 0
|
||||
&& (cint(frm.doc.total_amount_reimbursed) < cint(frm.doc.total_sanctioned_amount))
|
||||
&& frappe.model.can_create("Payment Entry")) {
|
||||
frm.add_custom_button(__('Payment'),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@ from erpnext.setup.utils import get_exchange_rate
|
||||
from frappe.website.website_generator import WebsiteGenerator
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
from erpnext.stock.get_item_details import get_price_list_rate
|
||||
from frappe.core.doctype.version.version import get_diff
|
||||
|
||||
import functools
|
||||
|
||||
@ -763,3 +764,52 @@ def add_additional_cost(stock_entry, work_order):
|
||||
'description': name[0],
|
||||
'amount': items.get(name[0])
|
||||
})
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bom_diff(bom1, bom2):
|
||||
from frappe.model import table_fields
|
||||
|
||||
doc1 = frappe.get_doc('BOM', bom1)
|
||||
doc2 = frappe.get_doc('BOM', bom2)
|
||||
|
||||
out = get_diff(doc1, doc2)
|
||||
out.row_changed = []
|
||||
out.added = []
|
||||
out.removed = []
|
||||
|
||||
meta = doc1.meta
|
||||
|
||||
identifiers = {
|
||||
'operations': 'operation',
|
||||
'items': 'item_code',
|
||||
'scrap_items': 'item_code',
|
||||
'exploded_items': 'item_code'
|
||||
}
|
||||
|
||||
for df in meta.fields:
|
||||
old_value, new_value = doc1.get(df.fieldname), doc2.get(df.fieldname)
|
||||
|
||||
if df.fieldtype in table_fields:
|
||||
identifier = identifiers[df.fieldname]
|
||||
# make maps
|
||||
old_row_by_identifier, new_row_by_identifier = {}, {}
|
||||
for d in old_value:
|
||||
old_row_by_identifier[d.get(identifier)] = d
|
||||
for d in new_value:
|
||||
new_row_by_identifier[d.get(identifier)] = d
|
||||
|
||||
# check rows for additions, changes
|
||||
for i, d in enumerate(new_value):
|
||||
if d.get(identifier) in old_row_by_identifier:
|
||||
diff = get_diff(old_row_by_identifier[d.get(identifier)], d, for_child=True)
|
||||
if diff and diff.changed:
|
||||
out.row_changed.append((df.fieldname, i, d.get(identifier), diff.changed))
|
||||
else:
|
||||
out.added.append([df.fieldname, d.as_dict()])
|
||||
|
||||
# check for deletions
|
||||
for d in old_value:
|
||||
if not d.get(identifier) in new_row_by_identifier:
|
||||
out.removed.append([df.fieldname, d.as_dict()])
|
||||
|
||||
return out
|
||||
|
@ -320,7 +320,8 @@ class ProductionPlan(Document):
|
||||
'qty': data.get("stock_qty") * item.get("qty"),
|
||||
'production_plan': self.name,
|
||||
'company': self.company,
|
||||
'fg_warehouse': item.get("fg_warehouse")
|
||||
'fg_warehouse': item.get("fg_warehouse"),
|
||||
'update_consumed_material_cost_in_project': 0
|
||||
})
|
||||
|
||||
work_order = self.create_work_order(data)
|
||||
@ -430,7 +431,7 @@ def download_raw_materials(production_plan):
|
||||
continue
|
||||
|
||||
item_list.append(['', '', '', '', bin_dict.get('warehouse'),
|
||||
bin_dict.get('projected_qty'), bin_dict.get('actual_qty')])
|
||||
bin_dict.get('projected_qty', 0), bin_dict.get('actual_qty', 0)])
|
||||
|
||||
build_csv_response(item_list, doc.name)
|
||||
|
||||
@ -507,8 +508,8 @@ def get_material_request_items(row, sales_order,
|
||||
required_qty = 0
|
||||
if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0:
|
||||
required_qty = total_qty
|
||||
elif total_qty > bin_dict.get("projected_qty"):
|
||||
required_qty = total_qty - bin_dict.get("projected_qty")
|
||||
elif total_qty > bin_dict.get("projected_qty", 0):
|
||||
required_qty = total_qty - bin_dict.get("projected_qty", 0)
|
||||
if required_qty > 0 and required_qty < row['min_order_qty']:
|
||||
required_qty = row['min_order_qty']
|
||||
item_group_defaults = get_item_group_defaults(row.item_code, company)
|
||||
|
@ -1,484 +1,504 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"field_order": [
|
||||
"item",
|
||||
"naming_series",
|
||||
"status",
|
||||
"production_item",
|
||||
"item_name",
|
||||
"image",
|
||||
"bom_no",
|
||||
"allow_alternative_item",
|
||||
"use_multi_level_bom",
|
||||
"skip_transfer",
|
||||
"column_break1",
|
||||
"company",
|
||||
"qty",
|
||||
"material_transferred_for_manufacturing",
|
||||
"produced_qty",
|
||||
"sales_order",
|
||||
"project",
|
||||
"from_wip_warehouse",
|
||||
"warehouses",
|
||||
"wip_warehouse",
|
||||
"fg_warehouse",
|
||||
"column_break_12",
|
||||
"scrap_warehouse",
|
||||
"required_items_section",
|
||||
"required_items",
|
||||
"time",
|
||||
"planned_start_date",
|
||||
"actual_start_date",
|
||||
"column_break_13",
|
||||
"planned_end_date",
|
||||
"actual_end_date",
|
||||
"expected_delivery_date",
|
||||
"operations_section",
|
||||
"transfer_material_against",
|
||||
"operations",
|
||||
"section_break_22",
|
||||
"planned_operating_cost",
|
||||
"actual_operating_cost",
|
||||
"additional_operating_cost",
|
||||
"column_break_24",
|
||||
"total_operating_cost",
|
||||
"more_info",
|
||||
"description",
|
||||
"stock_uom",
|
||||
"column_break2",
|
||||
"material_request",
|
||||
"material_request_item",
|
||||
"sales_order_item",
|
||||
"production_plan",
|
||||
"production_plan_item",
|
||||
"product_bundle_item",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "fa fa-gift"
|
||||
},
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "MFG-WO-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "Draft",
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled",
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.production_item",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "production_item.image",
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 1,
|
||||
"label": "Image",
|
||||
"options": "image",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Alternative Item"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Plan material for sub-assemblies",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Check if material transfer entry is not required",
|
||||
"fieldname": "skip_transfer",
|
||||
"fieldtype": "Check",
|
||||
"label": "Skip Material Transfer to WIP Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"remember_last_selected_value": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1 && doc.skip_transfer==0",
|
||||
"fieldname": "material_transferred_for_manufacturing",
|
||||
"fieldtype": "Float",
|
||||
"label": "Material Transferred for Manufacturing",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order"
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"oldfieldname": "project",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "skip_transfer",
|
||||
"fieldname": "from_wip_warehouse",
|
||||
"fieldtype": "Check",
|
||||
"label": "Backflush Raw Materials From Work-in-Progress Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "fa fa-building"
|
||||
},
|
||||
{
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Target Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "scrap_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Scrap Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "required_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Required Items"
|
||||
},
|
||||
{
|
||||
"fieldname": "required_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Required Items",
|
||||
"no_copy": 1,
|
||||
"options": "Work Order Item",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "time",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Time",
|
||||
"options": "fa fa-time"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"default": "now",
|
||||
"fieldname": "planned_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned Start Date",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual Start Date",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned End Date",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual End Date",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "operations_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operations",
|
||||
"options": "fa fa-wrench"
|
||||
},
|
||||
{
|
||||
"default": "Work Order",
|
||||
"depends_on": "operations",
|
||||
"fieldname": "transfer_material_against",
|
||||
"fieldtype": "Select",
|
||||
"label": "Transfer Material Against",
|
||||
"options": "\nWork Order\nJob Card"
|
||||
},
|
||||
{
|
||||
"fieldname": "operations",
|
||||
"fieldtype": "Table",
|
||||
"label": "Operations",
|
||||
"options": "Work Order Operation",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "operations",
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operation Cost"
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Planned Operating Cost",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Actual Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "additional_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Additional Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_24",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Information",
|
||||
"options": "fa fa-file-text"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"description": "Manufacture against Material Request",
|
||||
"fieldname": "material_request",
|
||||
"fieldtype": "Link",
|
||||
"label": "Material Request",
|
||||
"options": "Material Request"
|
||||
},
|
||||
{
|
||||
"fieldname": "material_request_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Material Request Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Sales Order Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_plan",
|
||||
"fieldtype": "Link",
|
||||
"label": "Production Plan",
|
||||
"no_copy": 1,
|
||||
"options": "Production Plan",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_plan_item",
|
||||
"fieldtype": "Data",
|
||||
"label": "Production Plan Item",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "product_bundle_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Product Bundle Item",
|
||||
"no_copy": 1,
|
||||
"options": "Item",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Work Order",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cogs",
|
||||
"idx": 1,
|
||||
"image_field": "image",
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-05-27 09:36:16.707719",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"set_user_permissions": 1,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock User"
|
||||
}
|
||||
],
|
||||
"sort_order": "ASC",
|
||||
"title_field": "production_item",
|
||||
"track_changes": 1,
|
||||
"track_seen": 1
|
||||
}
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"item",
|
||||
"naming_series",
|
||||
"status",
|
||||
"production_item",
|
||||
"item_name",
|
||||
"image",
|
||||
"bom_no",
|
||||
"column_break1",
|
||||
"company",
|
||||
"qty",
|
||||
"material_transferred_for_manufacturing",
|
||||
"produced_qty",
|
||||
"sales_order",
|
||||
"project",
|
||||
"settings_section",
|
||||
"allow_alternative_item",
|
||||
"use_multi_level_bom",
|
||||
"column_break_18",
|
||||
"skip_transfer",
|
||||
"from_wip_warehouse",
|
||||
"update_consumed_material_cost_in_project",
|
||||
"warehouses",
|
||||
"wip_warehouse",
|
||||
"fg_warehouse",
|
||||
"column_break_12",
|
||||
"scrap_warehouse",
|
||||
"required_items_section",
|
||||
"required_items",
|
||||
"time",
|
||||
"planned_start_date",
|
||||
"actual_start_date",
|
||||
"column_break_13",
|
||||
"planned_end_date",
|
||||
"actual_end_date",
|
||||
"expected_delivery_date",
|
||||
"operations_section",
|
||||
"transfer_material_against",
|
||||
"operations",
|
||||
"section_break_22",
|
||||
"planned_operating_cost",
|
||||
"actual_operating_cost",
|
||||
"additional_operating_cost",
|
||||
"column_break_24",
|
||||
"total_operating_cost",
|
||||
"more_info",
|
||||
"description",
|
||||
"stock_uom",
|
||||
"column_break2",
|
||||
"material_request",
|
||||
"material_request_item",
|
||||
"sales_order_item",
|
||||
"production_plan",
|
||||
"production_plan_item",
|
||||
"product_bundle_item",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "fa fa-gift"
|
||||
},
|
||||
{
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"label": "Series",
|
||||
"options": "MFG-WO-.YYYY.-",
|
||||
"print_hide": 1,
|
||||
"reqd": 1,
|
||||
"set_only_once": 1
|
||||
},
|
||||
{
|
||||
"default": "Draft",
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled",
|
||||
"read_only": 1,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.production_item",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "production_item.image",
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"hidden": 1,
|
||||
"label": "Image",
|
||||
"options": "image",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"label": "Allow Alternative Item"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "Plan material for sub-assemblies",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Check if material transfer entry is not required",
|
||||
"fieldname": "skip_transfer",
|
||||
"fieldtype": "Check",
|
||||
"label": "Skip Material Transfer to WIP Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"label": "Company",
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"remember_last_selected_value": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1 && doc.skip_transfer==0",
|
||||
"fieldname": "material_transferred_for_manufacturing",
|
||||
"fieldtype": "Float",
|
||||
"label": "Material Transferred for Manufacturing",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"label": "Manufactured Qty",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order"
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"oldfieldname": "project",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "skip_transfer",
|
||||
"fieldname": "from_wip_warehouse",
|
||||
"fieldtype": "Check",
|
||||
"label": "Backflush Raw Materials From Work-in-Progress Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "fa fa-building"
|
||||
},
|
||||
{
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Target Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "scrap_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Scrap Warehouse",
|
||||
"options": "Warehouse"
|
||||
},
|
||||
{
|
||||
"fieldname": "required_items_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Required Items"
|
||||
},
|
||||
{
|
||||
"fieldname": "required_items",
|
||||
"fieldtype": "Table",
|
||||
"label": "Required Items",
|
||||
"no_copy": 1,
|
||||
"options": "Work Order Item",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "time",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Time",
|
||||
"options": "fa fa-time"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"default": "now",
|
||||
"fieldname": "planned_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned Start Date",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual Start Date",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Planned End Date",
|
||||
"no_copy": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_end_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Actual End Date",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date"
|
||||
},
|
||||
{
|
||||
"fieldname": "operations_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operations",
|
||||
"options": "fa fa-wrench"
|
||||
},
|
||||
{
|
||||
"default": "Work Order",
|
||||
"depends_on": "operations",
|
||||
"fieldname": "transfer_material_against",
|
||||
"fieldtype": "Select",
|
||||
"label": "Transfer Material Against",
|
||||
"options": "\nWork Order\nJob Card"
|
||||
},
|
||||
{
|
||||
"fieldname": "operations",
|
||||
"fieldtype": "Table",
|
||||
"label": "Operations",
|
||||
"options": "Work Order Operation",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "operations",
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Operation Cost"
|
||||
},
|
||||
{
|
||||
"fieldname": "planned_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Planned Operating Cost",
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Actual Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "additional_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Additional Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_24",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_operating_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Operating Cost",
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Information",
|
||||
"options": "fa fa-file-text"
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Item Description",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"label": "Stock UOM",
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"description": "Manufacture against Material Request",
|
||||
"fieldname": "material_request",
|
||||
"fieldtype": "Link",
|
||||
"label": "Material Request",
|
||||
"options": "Material Request"
|
||||
},
|
||||
{
|
||||
"fieldname": "material_request_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Material Request Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "sales_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "Sales Order Item",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_plan",
|
||||
"fieldtype": "Link",
|
||||
"label": "Production Plan",
|
||||
"no_copy": 1,
|
||||
"options": "Production Plan",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_plan_item",
|
||||
"fieldtype": "Data",
|
||||
"label": "Production Plan Item",
|
||||
"no_copy": 1,
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "product_bundle_item",
|
||||
"fieldtype": "Link",
|
||||
"label": "Product Bundle Item",
|
||||
"no_copy": 1,
|
||||
"options": "Item",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Work Order",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "settings_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Settings"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "update_consumed_material_cost_in_project",
|
||||
"fieldtype": "Check",
|
||||
"label": "Update Consumed Material Cost In Project"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cogs",
|
||||
"idx": 1,
|
||||
"image_field": "image",
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-07-31 00:13:38.218277",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"import": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Manufacturing User",
|
||||
"set_user_permissions": 1,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock User"
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"title_field": "production_item",
|
||||
"track_changes": 1,
|
||||
"track_seen": 1
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
frappe.pages['bom-comparison-tool'].on_page_load = function(wrapper) {
|
||||
var page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('BOM Comparison Tool'),
|
||||
single_column: true
|
||||
});
|
||||
|
||||
new erpnext.BOMComparisonTool(page);
|
||||
}
|
||||
|
||||
erpnext.BOMComparisonTool = class BOMComparisonTool {
|
||||
constructor(page) {
|
||||
this.page = page;
|
||||
this.make_form();
|
||||
}
|
||||
|
||||
make_form() {
|
||||
this.form = new frappe.ui.FieldGroup({
|
||||
fields: [
|
||||
{
|
||||
label: __('BOM 1'),
|
||||
fieldname: 'name1',
|
||||
fieldtype: 'Link',
|
||||
options: 'BOM',
|
||||
change: () => this.fetch_and_render()
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break'
|
||||
},
|
||||
{
|
||||
label: __('BOM 2'),
|
||||
fieldname: 'name2',
|
||||
fieldtype: 'Link',
|
||||
options: 'BOM',
|
||||
change: () => this.fetch_and_render()
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break'
|
||||
},
|
||||
{
|
||||
fieldtype: 'HTML',
|
||||
fieldname: 'preview'
|
||||
}
|
||||
],
|
||||
body: this.page.body
|
||||
});
|
||||
this.form.make();
|
||||
}
|
||||
|
||||
fetch_and_render() {
|
||||
let { name1, name2 } = this.form.get_values();
|
||||
if (!(name1 && name2)) {
|
||||
this.form.get_field('preview').html('');
|
||||
return;
|
||||
}
|
||||
|
||||
// set working state
|
||||
this.form.get_field('preview').html(`
|
||||
<div class="text-muted margin-top">
|
||||
${__("Fetching...")}
|
||||
</div>
|
||||
`);
|
||||
|
||||
frappe.call('erpnext.manufacturing.doctype.bom.bom.get_bom_diff', {
|
||||
bom1: name1,
|
||||
bom2: name2
|
||||
}).then(r => {
|
||||
let diff = r.message;
|
||||
frappe.model.with_doctype('BOM', () => {
|
||||
this.render('BOM', name1, name2, diff);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render(doctype, name1, name2, diff) {
|
||||
|
||||
let change_html = (title, doctype, changed) => {
|
||||
let values_changed = this.get_changed_values(doctype, changed)
|
||||
.map(change => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
return `
|
||||
<tr>
|
||||
<td>${frappe.meta.get_label(doctype, fieldname)}</td>
|
||||
<td>${value1}</td>
|
||||
<td>${value2}</td>
|
||||
</tr>
|
||||
`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return `
|
||||
<h4 class="margin-top">${title}</h4>
|
||||
<div>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th width="33%">${__('Field')}</th>
|
||||
<th width="33%">${name1}</th>
|
||||
<th width="33%">${name2}</th>
|
||||
</tr>
|
||||
${values_changed}
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
let value_changes = change_html(__('Values Changed'), doctype, diff.changed);
|
||||
|
||||
let row_changes_by_fieldname = group_items(diff.row_changed, change => change[0]);
|
||||
|
||||
let table_changes = Object.keys(row_changes_by_fieldname).map(fieldname => {
|
||||
let changes = row_changes_by_fieldname[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
|
||||
let html = changes.map(change => {
|
||||
let [fieldname,, item_code, changes] = change;
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let child_doctype = df.options;
|
||||
let values_changed = this.get_changed_values(child_doctype, changes);
|
||||
|
||||
return values_changed.map((change, i) => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
let th = i === 0
|
||||
? `<th rowspan="${values_changed.length}">${item_code}</th>`
|
||||
: '';
|
||||
return `
|
||||
<tr>
|
||||
${th}
|
||||
<td>${frappe.meta.get_label(child_doctype, fieldname)}</td>
|
||||
<td>${value1}</td>
|
||||
<td>${value2}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}).join('');
|
||||
|
||||
return `
|
||||
<h4 class="margin-top">${__('Changes in {0}', [df.label])}</h4>
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
<th width="25%">${__('Item Code')}</th>
|
||||
<th width="25%">${__('Field')}</th>
|
||||
<th width="25%">${name1}</th>
|
||||
<th width="25%">${name2}</th>
|
||||
</tr>
|
||||
${html}
|
||||
</table>
|
||||
`;
|
||||
}).join('');
|
||||
|
||||
let get_added_removed_html = (title, grouped_items) => {
|
||||
return Object.keys(grouped_items).map(fieldname => {
|
||||
let rows = grouped_items[fieldname];
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
let fields = frappe.meta.get_docfields(df.options)
|
||||
.filter(df => df.in_list_view);
|
||||
|
||||
let html = rows.map(row => {
|
||||
let [, doc] = row;
|
||||
let cells = fields
|
||||
.map(df => `<td>${doc[df.fieldname]}</td>`)
|
||||
.join('');
|
||||
return `<tr>${cells}</tr>`;
|
||||
}).join('');
|
||||
|
||||
let header = fields.map(df => `<th>${df.label}</th>`).join('');
|
||||
return `
|
||||
<h4 class="margin-top">${$.format(title, [df.label])}</h4>
|
||||
<table class="table table-bordered">
|
||||
<tr>${header}</tr>
|
||||
${html}
|
||||
</table>
|
||||
`;
|
||||
}).join('');
|
||||
};
|
||||
|
||||
let added_by_fieldname = group_items(diff.added, change => change[0]);
|
||||
let removed_by_fieldname = group_items(diff.removed, change => change[0]);
|
||||
|
||||
let added_html = get_added_removed_html(__('Rows Added in {0}'), added_by_fieldname);
|
||||
let removed_html = get_added_removed_html(__('Rows Removed in {0}'), removed_by_fieldname);
|
||||
|
||||
let html = `
|
||||
${value_changes}
|
||||
${table_changes}
|
||||
${added_html}
|
||||
${removed_html}
|
||||
`;
|
||||
|
||||
this.form.get_field('preview').html(html);
|
||||
}
|
||||
|
||||
get_changed_values(doctype, changed) {
|
||||
return changed.filter(change => {
|
||||
let [fieldname, value1, value2] = change;
|
||||
if (!value1) value1 = '';
|
||||
if (!value2) value2 = '';
|
||||
if (value1 === value2) return false;
|
||||
let df = frappe.meta.get_docfield(doctype, fieldname);
|
||||
if (!df) return false;
|
||||
if (df.hidden) return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function group_items(array, fn) {
|
||||
return array.reduce((acc, item) => {
|
||||
let key = fn(item);
|
||||
acc[key] = acc[key] || [];
|
||||
acc[key].push(item);
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
"content": null,
|
||||
"creation": "2019-07-29 13:24:38.201981",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"idx": 0,
|
||||
"modified": "2019-07-29 13:24:38.201981",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "bom-comparison-tool",
|
||||
"owner": "Administrator",
|
||||
"page_name": "BOM Comparison Tool",
|
||||
"restrict_to_domain": "Manufacturing",
|
||||
"roles": [
|
||||
{
|
||||
"role": "System Manager"
|
||||
},
|
||||
{
|
||||
"role": "Manufacturing User"
|
||||
},
|
||||
{
|
||||
"role": "Manufacturing Manager"
|
||||
}
|
||||
],
|
||||
"script": null,
|
||||
"standard": "Yes",
|
||||
"style": null,
|
||||
"system_page": 0,
|
||||
"title": "BOM Comparison Tool"
|
||||
}
|
@ -60,7 +60,15 @@ $.extend(erpnext, {
|
||||
|
||||
var me = this;
|
||||
$btn.on("click", function() {
|
||||
me.show_serial_batch_selector(grid_row.frm, grid_row.doc);
|
||||
let callback = '';
|
||||
let on_close = '';
|
||||
|
||||
if (grid_row.doc.serial_no) {
|
||||
grid_row.doc.has_serial_no = true;
|
||||
}
|
||||
|
||||
me.show_serial_batch_selector(grid_row.frm, grid_row.doc,
|
||||
callback, on_close, true);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -255,27 +255,44 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
var fields = [
|
||||
{fieldtype:'Table', fieldname: 'items',
|
||||
description: __('Select BOM and Qty for Production'),
|
||||
fields: [
|
||||
{fieldtype:'Read Only', fieldname:'item_code',
|
||||
label: __('Item Code'), in_list_view:1},
|
||||
{fieldtype:'Link', fieldname:'bom', options: 'BOM', reqd: 1,
|
||||
label: __('Select BOM'), in_list_view:1, get_query: function(doc) {
|
||||
return {filters: {item: doc.item_code}};
|
||||
}},
|
||||
{fieldtype:'Float', fieldname:'pending_qty', reqd: 1,
|
||||
label: __('Qty'), in_list_view:1},
|
||||
{fieldtype:'Data', fieldname:'sales_order_item', reqd: 1,
|
||||
label: __('Sales Order Item'), hidden:1}
|
||||
],
|
||||
data: r.message,
|
||||
get_data: function() {
|
||||
return r.message
|
||||
const fields = [{
|
||||
label: 'Items',
|
||||
fieldtype: 'Table',
|
||||
fieldname: 'items',
|
||||
description: __('Select BOM and Qty for Production'),
|
||||
fields: [{
|
||||
fieldtype: 'Read Only',
|
||||
fieldname: 'item_code',
|
||||
label: __('Item Code'),
|
||||
in_list_view: 1
|
||||
}, {
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'bom',
|
||||
options: 'BOM',
|
||||
reqd: 1,
|
||||
label: __('Select BOM'),
|
||||
in_list_view: 1,
|
||||
get_query: function (doc) {
|
||||
return { filters: { item: doc.item_code } };
|
||||
}
|
||||
}, {
|
||||
fieldtype: 'Float',
|
||||
fieldname: 'pending_qty',
|
||||
reqd: 1,
|
||||
label: __('Qty'),
|
||||
in_list_view: 1
|
||||
}, {
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'sales_order_item',
|
||||
reqd: 1,
|
||||
label: __('Sales Order Item'),
|
||||
hidden: 1
|
||||
}],
|
||||
data: r.message,
|
||||
get_data: () => {
|
||||
return r.message
|
||||
}
|
||||
]
|
||||
}]
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Select Items to Manufacture'),
|
||||
fields: fields,
|
||||
|
@ -251,13 +251,12 @@ def _get_cart_quotation(party=None):
|
||||
if quotation:
|
||||
qdoc = frappe.get_doc("Quotation", quotation[0].name)
|
||||
else:
|
||||
[company, price_list] = frappe.db.get_value("Shopping Cart Settings", None, ["company", "price_list"])
|
||||
company = frappe.db.get_value("Shopping Cart Settings", None, ["company"])
|
||||
qdoc = frappe.get_doc({
|
||||
"doctype": "Quotation",
|
||||
"naming_series": get_shopping_cart_settings().quotation_series or "QTN-CART-",
|
||||
"quotation_to": party.doctype,
|
||||
"company": company,
|
||||
"selling_price_list": price_list,
|
||||
"order_type": "Shopping Cart",
|
||||
"status": "Draft",
|
||||
"docstatus": 0,
|
||||
|
@ -145,6 +145,10 @@ class StockEntry(StockController):
|
||||
self.precision("transfer_qty", item))
|
||||
|
||||
def update_cost_in_project(self):
|
||||
if (self.work_order and not frappe.db.get_value("Work Order",
|
||||
self.work_order, "update_consumed_material_cost_in_project")):
|
||||
return
|
||||
|
||||
if self.project:
|
||||
amount = frappe.db.sql(""" select ifnull(sum(sed.amount), 0)
|
||||
from
|
||||
|
3
package-lock.json
generated
3
package-lock.json
generated
@ -1,3 +0,0 @@
|
||||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user