Merge branch 'develop' of https://github.com/frappe/erpnext into develop
This commit is contained in:
commit
f069e1c83c
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.1.15'
|
||||
__version__ = '10.1.18'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@ -4,12 +4,21 @@
|
||||
.print-format {
|
||||
padding: 8mm;
|
||||
margin:4mm;
|
||||
font-size:10px;
|
||||
font-size: 10.0pt !important;
|
||||
font-family: Tahoma, sans-serif;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% } %}
|
||||
<style>
|
||||
.print-format {
|
||||
padding: 8mm;
|
||||
margin:4mm;
|
||||
font-size: 10.0pt !important;
|
||||
font-family: Tahoma, sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
@ -91,8 +100,8 @@
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 10%">{%= __("Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||
<th style="width: 15%">{%= __("Date") %}</th>
|
||||
<th style="width: 20%">{%= __("Reference") %}</th>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
{% } %}
|
||||
@ -125,9 +134,14 @@
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]) { %}
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
<td>{%= dateutil.str_to_user(data[i]["posting_date"]) %}</td>
|
||||
<td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
{%= data[i]["voucher_type"] %}
|
||||
<br>
|
||||
{% } %}
|
||||
{%= data[i]["voucher_no"] %}
|
||||
</td>
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
|
||||
@ -22,13 +22,35 @@ class ReceivablePayableReport(object):
|
||||
return columns, data, None, chart
|
||||
|
||||
def get_columns(self, party_naming_by, args):
|
||||
columns = [_("Posting Date") + ":Date:80", _(args.get("party_type")) + ":Link/" + args.get("party_type") + ":200"]
|
||||
columns = []
|
||||
columns.append({
|
||||
"label": _("Posting Date"),
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "posting_date",
|
||||
"width": 90
|
||||
})
|
||||
|
||||
columns += [_(args.get("party_type")) + ":Link/" + args.get("party_type") + ":200"]
|
||||
|
||||
if party_naming_by == "Naming Series":
|
||||
columns += [args.get("party_type") + " Name::110"]
|
||||
|
||||
columns += [_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/"+_("Voucher Type")+":120",
|
||||
_("Due Date") + ":Date:80"]
|
||||
columns.append({
|
||||
"label": _("Voucher Type"),
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "voucher_type",
|
||||
"width": 110
|
||||
})
|
||||
|
||||
columns.append({
|
||||
"label": _("Voucher No"),
|
||||
"fieldtype": "Dynamic Link",
|
||||
"fieldname": "voucher_no",
|
||||
"width": 110,
|
||||
"options": "voucher_type",
|
||||
})
|
||||
|
||||
columns += [_("Due Date") + ":Date:80"]
|
||||
|
||||
if args.get("party_type") == "Supplier":
|
||||
columns += [_("Bill No") + "::80", _("Bill Date") + ":Date:80"]
|
||||
@ -114,7 +136,7 @@ class ReceivablePayableReport(object):
|
||||
return_entries = self.get_return_entries(args.get("party_type"))
|
||||
|
||||
data = []
|
||||
pdc_details = get_pdc_details(args.get("party_type"))
|
||||
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
|
||||
|
||||
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
|
||||
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
|
||||
@ -160,6 +182,7 @@ class ReceivablePayableReport(object):
|
||||
row.append(company_currency)
|
||||
|
||||
pdc = pdc_details.get((gle.voucher_no, gle.party), {})
|
||||
|
||||
remaining_balance = outstanding_amount - flt(pdc.get("pdc_amount"))
|
||||
row += [pdc.get("pdc_date"), pdc.get("pdc_ref"),
|
||||
flt(pdc.get("pdc_amount")), remaining_balance]
|
||||
@ -392,7 +415,7 @@ def get_ageing_data(first_range, second_range, third_range, age_as_on, entry_dat
|
||||
|
||||
return [age] + outstanding_range
|
||||
|
||||
def get_pdc_details(party_type):
|
||||
def get_pdc_details(party_type, report_date):
|
||||
pdc_details = frappe._dict()
|
||||
|
||||
for pdc in frappe.db.sql("""
|
||||
@ -405,13 +428,14 @@ def get_pdc_details(party_type):
|
||||
on
|
||||
(pref.parent = pent.name)
|
||||
where
|
||||
pent.docstatus < 2 and pent.reference_date >= pent.posting_date
|
||||
pent.docstatus < 2 and pent.reference_date >= %s
|
||||
and pent.party_type = %s
|
||||
group by pent.party, pref.reference_name""", party_type, as_dict=1):
|
||||
group by pent.party, pref.reference_name""", (report_date, party_type), as_dict=1):
|
||||
pdc_details.setdefault((pdc.invoice_no, pdc.party), pdc)
|
||||
|
||||
if scrub(party_type):
|
||||
amount_field = "jea.debit_in_account_currency + jea.credit_in_account_currency"
|
||||
amount_field = ("jea.debit_in_account_currency"
|
||||
if party_type == 'Supplier' else "jea.credit_in_account_currency")
|
||||
else:
|
||||
amount_field = "jea.debit + jea.credit"
|
||||
|
||||
@ -425,9 +449,9 @@ def get_pdc_details(party_type):
|
||||
on
|
||||
(jea.parent = je.name)
|
||||
where
|
||||
je.docstatus < 2 and je.cheque_date >= je.posting_date
|
||||
je.docstatus < 2 and je.cheque_date >= %s
|
||||
and jea.party_type = %s
|
||||
group by jea.party, jea.reference_name""".format(amount_field), party_type, as_dict=1):
|
||||
group by jea.party, jea.reference_name""".format(amount_field), (report_date, party_type), as_dict=1):
|
||||
if (pdc.invoice_no, pdc.party) in pdc_details:
|
||||
pdc_details[(pdc.invoice_no, pdc.party)]["pdc_amount"] += pdc.pdc_amount
|
||||
else:
|
||||
|
||||
@ -423,10 +423,7 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
||||
|
||||
if fg_items:
|
||||
items = tuple(set(d["rm_item_code"] for d in rm_items_list))
|
||||
item_wh = frappe._dict(frappe.db.sql("""
|
||||
select item_code, description
|
||||
from `tabItem` where name in ({0})
|
||||
""".format(", ".join(["%s"] * len(items))), items))
|
||||
item_wh = get_item_details(items)
|
||||
|
||||
stock_entry = frappe.new_doc("Stock Entry")
|
||||
stock_entry.purpose = "Subcontract"
|
||||
@ -441,13 +438,15 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
||||
for item_code in fg_items:
|
||||
for rm_item_data in rm_items_list:
|
||||
if rm_item_data["item_code"] == item_code:
|
||||
rm_item_code = rm_item_data["rm_item_code"]
|
||||
items_dict = {
|
||||
rm_item_data["rm_item_code"]: {
|
||||
rm_item_code: {
|
||||
"item_name": rm_item_data["item_name"],
|
||||
"description": item_wh.get(rm_item_data["rm_item_code"]),
|
||||
"description": item_wh[rm_item_code].get('description'),
|
||||
'qty': rm_item_data["qty"],
|
||||
'from_warehouse': rm_item_data["warehouse"],
|
||||
'stock_uom': rm_item_data["stock_uom"]
|
||||
'stock_uom': rm_item_data["stock_uom"],
|
||||
'allow_alternative_item': item_wh[rm_item_code].get('allow_alternative_item')
|
||||
}
|
||||
}
|
||||
stock_entry.add_to_stock_entry_detail(items_dict)
|
||||
@ -456,6 +455,14 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
||||
frappe.throw(_("No Items selected for transfer"))
|
||||
return purchase_order.name
|
||||
|
||||
def get_item_details(items):
|
||||
item_details = {}
|
||||
for d in frappe.db.sql("""select item_code, description, allow_alternative_item from `tabItem`
|
||||
where name in ({0})""".format(", ".join(["%s"] * len(items))), items, as_dict=1):
|
||||
item_details[d.item_code] = d
|
||||
|
||||
return item_details
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_status(status, name):
|
||||
po = frappe.get_doc("Purchase Order", name)
|
||||
|
||||
@ -321,6 +321,7 @@ def create_purchase_order(**args):
|
||||
po.is_subcontracted = args.is_subcontracted or "No"
|
||||
po.currency = args.currency or frappe.db.get_value("Company", po.company, "default_currency")
|
||||
po.conversion_factor = args.conversion_factor or 1
|
||||
po.supplier_warehouse = args.supplier_warehouse or None
|
||||
|
||||
po.append("items", {
|
||||
"item_code": args.item or args.item_code or "_Test Item",
|
||||
|
||||
@ -71,6 +71,10 @@ def get_data():
|
||||
"type": "doctype",
|
||||
"name": "Item",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Item Alternative",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Product Bundle",
|
||||
|
||||
@ -10,6 +10,7 @@ from erpnext.accounts.party import get_party_details
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
from erpnext.buying.utils import validate_for_items, update_last_purchase_rate
|
||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||
from erpnext.stock.doctype.stock_entry.stock_entry import get_used_alternative_items
|
||||
|
||||
from erpnext.controllers.stock_controller import StockController
|
||||
|
||||
@ -200,6 +201,11 @@ class BuyingController(StockController):
|
||||
exploded_item = item.get('include_exploded_items')
|
||||
|
||||
bom_items = get_items_from_bom(item.item_code, item.bom, exploded_item)
|
||||
|
||||
used_alternative_items = []
|
||||
if self.doctype == 'Purchase Receipt' and item.purchase_order:
|
||||
used_alternative_items = get_used_alternative_items(purchase_order = item.purchase_order)
|
||||
|
||||
raw_materials_cost = 0
|
||||
items = list(set([d.item_code for d in bom_items]))
|
||||
item_wh = frappe._dict(frappe.db.sql("""select item_code, default_warehouse
|
||||
@ -211,6 +217,16 @@ class BuyingController(StockController):
|
||||
if frappe.db.get_value("Warehouse", reserve_warehouse, "company") != self.company:
|
||||
reserve_warehouse = None
|
||||
|
||||
conversion_factor = item.conversion_factor
|
||||
if (self.doctype == 'Purchase Receipt' and item.purchase_order and
|
||||
bom_item.item_code in used_alternative_items):
|
||||
alternative_item_data = used_alternative_items.get(bom_item.item_code)
|
||||
bom_item.item_code = alternative_item_data.item_code
|
||||
bom_item.item_name = alternative_item_data.item_name
|
||||
bom_item.stock_uom = alternative_item_data.stock_uom
|
||||
conversion_factor = alternative_item_data.conversion_factor
|
||||
bom_item.description = alternative_item_data.description
|
||||
|
||||
# check if exists
|
||||
exists = 0
|
||||
for d in self.get(raw_material_table):
|
||||
@ -223,7 +239,7 @@ class BuyingController(StockController):
|
||||
rm = self.append(raw_material_table, {})
|
||||
|
||||
required_qty = flt(flt(bom_item.qty_consumed_per_unit) * (flt(item.qty) + getattr(item, 'rejected_qty', 0)) *
|
||||
flt(item.conversion_factor), rm.precision("required_qty"))
|
||||
flt(conversion_factor), rm.precision("required_qty"))
|
||||
rm.reference_name = item.name
|
||||
rm.bom_detail_no = bom_item.name
|
||||
rm.main_item_code = item.item_code
|
||||
@ -233,7 +249,7 @@ class BuyingController(StockController):
|
||||
if self.doctype == "Purchase Order" and not rm.reserve_warehouse:
|
||||
rm.reserve_warehouse = reserve_warehouse
|
||||
|
||||
rm.conversion_factor = item.conversion_factor
|
||||
rm.conversion_factor = conversion_factor
|
||||
|
||||
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
rm.consumed_qty = required_qty
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
erpnext/docs/assets/img/manufacturing/allow-alternative-item.png
Normal file
BIN
erpnext/docs/assets/img/manufacturing/allow-alternative-item.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
BIN
erpnext/docs/assets/img/manufacturing/item-alternative.png
Normal file
BIN
erpnext/docs/assets/img/manufacturing/item-alternative.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
@ -4,6 +4,7 @@ work-order
|
||||
workstation
|
||||
operation
|
||||
subcontracting
|
||||
item-alternative
|
||||
tools
|
||||
setup
|
||||
articles
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
# Item Alternative
|
||||
|
||||
Item alternative feature is very useful in manufacturing industries, if the raw material defined in the BOM is not available during the production process then their respective available alternative item used to complete the production process.
|
||||
|
||||
To make item alaternative for an item, kindly enable the "Allow Alternative Item" in the item.
|
||||
<img class="screenshot" alt="Item" src="{{docs_base_url}}/assets/img/manufacturing/allow-alternative-item.png">
|
||||
|
||||
* To make item alternative, goto module Stock > Items and Pricing > Item Alternative
|
||||
<img class="screenshot" alt="Item Alternative" src="{{docs_base_url}}/assets/img/manufacturing/item-alternative.png">
|
||||
|
||||
The user can enable Two-Way between an item and their alternative item if both can be used as an alternative to each other
|
||||
|
||||
|
||||
### Item Alternative for work order
|
||||
|
||||
To allow to use alternative items in the manufacturing process user can configure allow an alternative item in the BOM/Work Order
|
||||
|
||||
##### Provision to allow alternative item in the bom
|
||||
<img class="screenshot" alt="Item" src="{{docs_base_url}}/assets/img/manufacturing/allow-alternative-item-bom.png">
|
||||
|
||||
##### Provision to allow alternative item in the work order
|
||||
User can also enable/disable allow alternative item in the work order
|
||||
<img class="screenshot" alt="Item" src="{{docs_base_url}}/assets/img/manufacturing/allow-alternative-item-wo.png">
|
||||
|
||||
##### How it works for work order
|
||||
<img class="screenshot" alt="Item" src="{{docs_base_url}}/assets/img/manufacturing/work_order_item_alternative.gif">
|
||||
|
||||
### Item Alternative for subcontract
|
||||
In subcontract, the user has to transfer raw materials to the subcontracted supplier to get finished good from them. If the raw material is not available in the stock, with this feature, the user can transfer the alternate item of the subcontracted raw material to the supplier.
|
||||
|
||||
##### How it works for subcontract
|
||||
<img class="screenshot" alt="Item" src="{{docs_base_url}}/assets/img/manufacturing/purchase_order_item_alternative.gif">
|
||||
@ -42,6 +42,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -73,6 +74,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -106,6 +108,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -136,6 +139,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -168,6 +172,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -196,6 +201,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -228,6 +234,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -260,6 +267,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -290,6 +298,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -320,6 +329,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -351,6 +361,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -382,6 +393,38 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Alternative Item",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -412,6 +455,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -443,6 +487,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -472,6 +517,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -503,6 +549,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -533,6 +580,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -565,6 +613,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -597,6 +646,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -627,6 +677,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -659,6 +710,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -689,6 +741,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -720,6 +773,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -750,6 +804,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -780,6 +835,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -810,6 +866,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -841,6 +898,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -869,6 +927,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -900,6 +959,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -931,6 +991,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -962,6 +1023,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -991,6 +1053,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1021,6 +1084,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1050,6 +1114,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1081,6 +1146,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1110,6 +1176,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1142,6 +1209,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1172,6 +1240,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1200,6 +1269,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1230,6 +1300,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1259,6 +1330,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1288,6 +1360,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1317,6 +1390,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1347,6 +1421,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1378,6 +1453,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1408,6 +1484,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1440,6 +1517,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1471,6 +1549,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1502,6 +1581,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1532,6 +1612,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1564,6 +1645,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1594,6 +1676,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1626,6 +1709,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1657,6 +1741,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1688,6 +1773,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1719,6 +1805,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -1733,7 +1820,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-16 13:43:55.485813",
|
||||
"modified": "2018-02-26 22:51:40.232456",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "BOM",
|
||||
|
||||
@ -543,6 +543,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
||||
item.description,
|
||||
item.image,
|
||||
item.stock_uom,
|
||||
item.allow_alternative_item,
|
||||
item.default_warehouse,
|
||||
item.expense_account as expense_account,
|
||||
item.buying_cost_center as cost_center
|
||||
@ -606,6 +607,9 @@ def validate_bom_no(item, bom_no):
|
||||
for d in bom.items:
|
||||
if (d.item_code.lower() == item.lower()):
|
||||
rm_item_exists = True
|
||||
for d in bom.scrap_items:
|
||||
if (d.item_code.lower() == item.lower()):
|
||||
rm_item_exists = True
|
||||
if bom.item.lower() == item.lower() or \
|
||||
bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower():
|
||||
rm_item_exists = True
|
||||
|
||||
@ -171,7 +171,7 @@ frappe.ui.form.on("Work Order", {
|
||||
frm.set_value('sales_order', "");
|
||||
frm.trigger('set_sales_order');
|
||||
erpnext.in_production_item_onchange = true;
|
||||
$.each(["description", "stock_uom", "project", "bom_no"], function(i, field) {
|
||||
$.each(["description", "stock_uom", "project", "bom_no", "allow_alternative_item"], function(i, field) {
|
||||
frm.set_value(field, r.message[field]);
|
||||
});
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -71,6 +72,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -105,6 +107,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -137,6 +140,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -171,6 +175,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -202,6 +207,38 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Alternative Item",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -231,6 +268,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -264,6 +302,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -297,6 +336,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -331,6 +371,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -362,6 +403,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -394,6 +436,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -425,6 +468,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -455,6 +499,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -485,6 +530,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -517,6 +563,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -545,6 +592,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -576,6 +624,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -606,6 +655,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -637,6 +687,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -668,6 +719,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -699,6 +751,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -729,6 +782,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -758,6 +812,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -788,6 +843,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -818,6 +874,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -848,6 +905,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -880,6 +938,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -912,6 +971,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -944,6 +1004,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -975,6 +1036,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1006,6 +1068,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1037,6 +1100,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1066,6 +1130,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1097,6 +1162,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1127,6 +1193,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1156,6 +1223,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1189,6 +1257,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1221,6 +1290,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1249,6 +1319,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -1282,6 +1353,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1312,6 +1384,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1342,6 +1415,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1373,6 +1447,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1403,6 +1478,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1435,6 +1511,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -1449,7 +1526,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-13 02:58:11.328693",
|
||||
"modified": "2018-03-05 12:43:10.442928",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order",
|
||||
|
||||
@ -489,6 +489,7 @@ class WorkOrder(Document):
|
||||
'item_code': item.item_code,
|
||||
'item_name': item.item_name,
|
||||
'description': item.description,
|
||||
'allow_alternative_item': item.allow_alternative_item,
|
||||
'required_qty': item.qty,
|
||||
'source_warehouse': item.source_warehouse or item.default_warehouse
|
||||
})
|
||||
@ -503,15 +504,17 @@ class WorkOrder(Document):
|
||||
transferred_qty = frappe.db.sql('''select sum(qty)
|
||||
from `tabStock Entry` entry, `tabStock Entry Detail` detail
|
||||
where
|
||||
entry.work_order = %s
|
||||
entry.work_order = %(name)s
|
||||
and entry.purpose = "Material Transfer for Manufacture"
|
||||
and entry.docstatus = 1
|
||||
and detail.parent = entry.name
|
||||
and detail.item_code = %s''', (self.name, d.item_code))[0][0]
|
||||
and (detail.item_code = %(item)s or detail.original_item = %(item)s)''', {
|
||||
'name': self.name,
|
||||
'item': d.item_code
|
||||
})[0][0]
|
||||
|
||||
d.db_set('transferred_qty', flt(transferred_qty), update_modified = False)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_details(item, project = None):
|
||||
res = frappe.db.sql("""
|
||||
@ -548,6 +551,7 @@ def get_item_details(item, project = None):
|
||||
frappe.throw(_("Default BOM for {0} not found").format(item))
|
||||
|
||||
res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
|
||||
res['allow_alternative_item'] = frappe.db.get_value('BOM', res['bom_no'], 'allow_alternative_item')
|
||||
res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
|
||||
|
||||
return res
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -72,6 +73,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -101,6 +103,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -131,6 +134,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -161,6 +165,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -191,6 +196,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -221,6 +227,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -252,6 +259,38 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Alternative Item",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -281,6 +320,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -311,6 +351,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -341,6 +382,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -354,7 +396,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-13 02:58:11.328693",
|
||||
"modified": "2018-03-05 13:07:07.530725",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Work Order Item",
|
||||
|
||||
@ -6,6 +6,8 @@ import frappe
|
||||
from erpnext.stock.utils import get_bin
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("stock", "doctype", "bin")
|
||||
frappe.reload_doc("buying", "doctype", "purchase_order_item_supplied")
|
||||
for d in frappe.db.sql("""
|
||||
select distinct rm_item_code, reserve_warehouse
|
||||
from `tabPurchase Order Item Supplied`
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -59,7 +60,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
@ -75,6 +76,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -91,7 +93,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Project Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -107,6 +109,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -139,6 +142,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -171,6 +175,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -200,6 +205,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -216,7 +222,7 @@
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Priority",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@ -232,6 +238,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -263,6 +270,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -294,6 +302,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -323,6 +332,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -354,6 +364,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -386,6 +397,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -415,6 +427,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -446,6 +459,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -476,6 +490,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -508,6 +523,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -539,6 +555,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -570,6 +587,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -600,6 +618,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -631,6 +650,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -662,6 +682,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -692,6 +713,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -722,6 +744,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -752,6 +775,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -781,6 +805,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -812,6 +837,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -843,6 +869,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -875,6 +902,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -906,6 +934,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -937,6 +966,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -967,6 +997,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -997,6 +1028,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1026,6 +1058,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1056,6 +1089,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1087,6 +1121,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1117,6 +1152,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1147,6 +1183,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1177,6 +1214,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1207,6 +1245,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@ -1240,6 +1279,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1269,6 +1309,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1301,6 +1342,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1332,6 +1374,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1363,6 +1406,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1395,6 +1439,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1424,6 +1469,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1455,6 +1501,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1486,6 +1533,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1517,6 +1565,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1548,6 +1597,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1579,6 +1629,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1611,6 +1662,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1642,6 +1694,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -1656,7 +1709,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 4,
|
||||
"modified": "2018-03-22 11:44:38.723507",
|
||||
"modified": "2018-03-28 10:19:32.743900",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Project",
|
||||
|
||||
@ -184,6 +184,142 @@ $.extend(erpnext.utils, {
|
||||
},
|
||||
});
|
||||
|
||||
erpnext.utils.select_alternate_items = function(opts) {
|
||||
const frm = opts.frm;
|
||||
const warehouse_field = opts.warehouse_field || 'warehouse';
|
||||
const item_field = opts.item_field || 'item_code';
|
||||
|
||||
this.data = [];
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __("Select Alternate Item"),
|
||||
fields: [
|
||||
{fieldtype:'Section Break', label: __('Items')},
|
||||
{
|
||||
fieldname: "alternative_items", fieldtype: "Table", cannot_add_rows: true,
|
||||
in_place_edit: true, data: this.data,
|
||||
get_data: () => {
|
||||
return this.data;
|
||||
},
|
||||
fields: [{
|
||||
fieldtype:'Data',
|
||||
fieldname:"docname",
|
||||
hidden: 1
|
||||
}, {
|
||||
fieldtype:'Link',
|
||||
fieldname:"item_code",
|
||||
options: 'Item',
|
||||
in_list_view: 1,
|
||||
read_only: 1,
|
||||
label: __('Item Code')
|
||||
}, {
|
||||
fieldtype:'Link',
|
||||
fieldname:"alternate_item",
|
||||
options: 'Item',
|
||||
default: "",
|
||||
in_list_view: 1,
|
||||
label: __('Alternate Item'),
|
||||
onchange: function() {
|
||||
const item_code = this.get_value();
|
||||
const warehouse = this.grid_row.on_grid_fields_dict.warehouse.get_value();
|
||||
if (item_code && warehouse) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.utils.get_latest_stock_qty",
|
||||
args: {
|
||||
item_code: item_code,
|
||||
warehouse: warehouse
|
||||
},
|
||||
callback: (r) => {
|
||||
this.grid_row.on_grid_fields_dict
|
||||
.actual_qty.set_value(r.message || 0);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
get_query: (e) => {
|
||||
return {
|
||||
query: "erpnext.stock.doctype.item_alternative.item_alternative.get_alternative_items",
|
||||
filters: {
|
||||
item_code: e.item_code
|
||||
}
|
||||
};
|
||||
}
|
||||
}, {
|
||||
fieldtype:'Link',
|
||||
fieldname:"warehouse",
|
||||
options: 'Warehouse',
|
||||
default: "",
|
||||
in_list_view: 1,
|
||||
label: __('Warehouse'),
|
||||
onchange: function() {
|
||||
const warehouse = this.get_value();
|
||||
const item_code = this.grid_row.on_grid_fields_dict.item_code.get_value();
|
||||
if (item_code && warehouse) {
|
||||
frappe.call({
|
||||
method: "erpnext.stock.utils.get_latest_stock_qty",
|
||||
args: {
|
||||
item_code: item_code,
|
||||
warehouse: warehouse
|
||||
},
|
||||
callback: (r) => {
|
||||
this.grid_row.on_grid_fields_dict
|
||||
.actual_qty.set_value(r.message || 0);
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}, {
|
||||
fieldtype:'Float',
|
||||
fieldname:"actual_qty",
|
||||
default: 0,
|
||||
read_only: 1,
|
||||
in_list_view: 1,
|
||||
label: __('Available Qty')
|
||||
}]
|
||||
},
|
||||
],
|
||||
primary_action: function() {
|
||||
const args = this.get_values()["alternative_items"];
|
||||
const alternative_items = args.filter(d => {
|
||||
if (d.alternate_item && d.item_code != d.alternate_item) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
alternative_items.forEach(d => {
|
||||
let row = frappe.get_doc(opts.child_doctype, d.docname);
|
||||
let qty = row.qty;
|
||||
row[item_field] = d.alternate_item;
|
||||
|
||||
frm.script_manager.trigger(item_field, row.doctype, row.name)
|
||||
.then(() => {
|
||||
frappe.model.set_value(row.doctype, row.name, 'qty', qty);
|
||||
frappe.model.set_value(row.doctype, row.name,
|
||||
opts.original_item_field, d.item_code);
|
||||
});
|
||||
});
|
||||
|
||||
refresh_field(opts.child_docname);
|
||||
this.hide();
|
||||
},
|
||||
primary_action_label: __('Update')
|
||||
});
|
||||
|
||||
frm.doc[opts.child_docname].forEach(d => {
|
||||
if (!opts.condition || opts.condition(d)) {
|
||||
dialog.fields_dict.alternative_items.df.data.push({
|
||||
"docname": d.name,
|
||||
"item_code": d[item_field],
|
||||
"warehouse": d[warehouse_field],
|
||||
"actual_qty": d.actual_qty
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
this.data = dialog.fields_dict.alternative_items.df.data;
|
||||
dialog.fields_dict.alternative_items.grid.refresh();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
erpnext.utils.map_current_doc = function(opts) {
|
||||
if(opts.get_query_filters) {
|
||||
opts.get_query = function() {
|
||||
|
||||
@ -319,7 +319,8 @@ frappe.ui.form.ItemQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
|
||||
["parent", "=", $(e.target).attr("data-fieldname")],
|
||||
["attribute_value", "like", e.target.value + "%"]
|
||||
],
|
||||
fields: ["attribute_value"]
|
||||
fields: ["attribute_value"],
|
||||
parent: "Item"
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
|
||||
@ -85,8 +85,6 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
fields: fields
|
||||
});
|
||||
|
||||
this.bind_qty();
|
||||
|
||||
this.dialog.set_primary_action(__('Insert'), function() {
|
||||
me.values = me.dialog.get_values();
|
||||
if(me.validate()) {
|
||||
@ -102,17 +100,24 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
}
|
||||
|
||||
if (d.batch_no) {
|
||||
this.dialog.fields_dict.batches.df.data.push({
|
||||
'batch_no': d.batch_no,
|
||||
'actual_qty': d.actual_qty,
|
||||
'selected_qty': d.qty,
|
||||
'available_qty': d.actual_batch_qty
|
||||
this.frm.doc.items.forEach(data => {
|
||||
if(data.item_code == d.item_code) {
|
||||
this.dialog.fields_dict.batches.df.data.push({
|
||||
'batch_no': data.batch_no,
|
||||
'actual_qty': data.actual_qty,
|
||||
'selected_qty': data.qty,
|
||||
'available_qty': data.actual_batch_qty
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.dialog.fields_dict.batches.grid.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.has_batch) {
|
||||
this.update_total_qty();
|
||||
}
|
||||
|
||||
this.dialog.show();
|
||||
},
|
||||
|
||||
@ -161,18 +166,44 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
var me = this;
|
||||
if(this.has_batch) {
|
||||
this.values.batches.map((batch, i) => {
|
||||
let item_code_field = {};
|
||||
let row = (i !== 0) ? this.frm.add_child("items", this.item) : this.item;
|
||||
let batch_no = batch.batch_no;
|
||||
let row = '';
|
||||
|
||||
if (i !== 0 && !this.batch_exists(batch_no)) {
|
||||
row = this.frm.add_child("items", {
|
||||
'item_code': this.item.item_code,
|
||||
'item_name': this.item.item_name,
|
||||
'price_list_rate': this.item.price_list_rate,
|
||||
'rate': this.item.rate,
|
||||
'qty': batch.selected_qty,
|
||||
'batch_no': batch_no,
|
||||
'actual_qty': this.item.actual_qty,
|
||||
'discount_percentage': this.item.discount_percentage
|
||||
});
|
||||
} else {
|
||||
row = this.frm.doc.items.find(i => i.batch_no === batch_no);
|
||||
}
|
||||
|
||||
if (!row) {
|
||||
row = this.item;
|
||||
}
|
||||
|
||||
this.map_row_values(row, batch, 'batch_no',
|
||||
'selected_qty', this.values.warehouse);
|
||||
});
|
||||
} else {
|
||||
this.map_row_values(this.item, this.values, 'serial_no', 'qty');
|
||||
}
|
||||
|
||||
refresh_field("items");
|
||||
this.callback && this.callback(this.item);
|
||||
},
|
||||
|
||||
batch_exists: function(batch) {
|
||||
const batches = this.frm.doc.items.map(data => data.batch_no);
|
||||
return (batches && in_list(batches, batch)) ? true : false;
|
||||
},
|
||||
|
||||
map_row_values: function(row, values, number, qty_field, warehouse) {
|
||||
row.qty = values[qty_field];
|
||||
row[number] = values[number];
|
||||
@ -185,20 +216,15 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
bind_qty: function() {
|
||||
let batches_field = this.dialog.fields_dict.batches;
|
||||
update_total_qty: function() {
|
||||
let qty_field = this.dialog.fields_dict.qty;
|
||||
if(batches_field) {
|
||||
batches_field.grid.wrapper.on('change', function() {
|
||||
let total_qty = 0;
|
||||
batches_field.grid.wrapper.find(
|
||||
'input[data-fieldname="selected_qty"]').each(function() {
|
||||
let total_qty = 0;
|
||||
|
||||
total_qty += Number($(this).val());
|
||||
});
|
||||
qty_field.set_input(total_qty);
|
||||
});
|
||||
}
|
||||
this.dialog.fields_dict.batches.df.data.forEach(data => {
|
||||
total_qty += flt(data.selected_qty);
|
||||
});
|
||||
|
||||
qty_field.set_input(total_qty);
|
||||
},
|
||||
|
||||
get_batch_fields: function() {
|
||||
@ -230,7 +256,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
if(row === this.grid_row) {
|
||||
return "";
|
||||
}
|
||||
return row.on_grid_fields_dict.batch_no.get_value();
|
||||
|
||||
if (row.on_grid_fields_dict.batch_no) {
|
||||
return row.on_grid_fields_dict.batch_no.get_value();
|
||||
}
|
||||
});
|
||||
if(selected_batches.includes(val)) {
|
||||
this.set_value("");
|
||||
@ -293,6 +322,8 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
} else {
|
||||
this.grid.refresh();
|
||||
}
|
||||
|
||||
me.update_total_qty();
|
||||
}
|
||||
},
|
||||
],
|
||||
|
||||
@ -9,7 +9,7 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
|
||||
});
|
||||
|
||||
frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
|
||||
if (r && r.use_pos_in_offline_mode && !cint(r.use_pos_in_offline_mode)) {
|
||||
if (r && !cint(r.use_pos_in_offline_mode)) {
|
||||
// online
|
||||
wrapper.pos = new erpnext.pos.PointOfSale(wrapper);
|
||||
window.cur_pos = wrapper.pos;
|
||||
@ -23,7 +23,7 @@ frappe.pages['point-of-sale'].on_page_load = function(wrapper) {
|
||||
|
||||
frappe.pages['point-of-sale'].refresh = function(wrapper) {
|
||||
if (wrapper.pos) {
|
||||
cur_frm = wrapper.pos.frm;
|
||||
wrapper.pos.make_new_invoice();
|
||||
}
|
||||
|
||||
if (frappe.flags.is_offline) {
|
||||
@ -96,8 +96,8 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
wrapper: this.wrapper.find('.cart-container'),
|
||||
events: {
|
||||
on_customer_change: (customer) => this.frm.set_value('customer', customer),
|
||||
on_field_change: (item_code, field, value) => {
|
||||
this.update_item_in_cart(item_code, field, value);
|
||||
on_field_change: (item_code, field, value, batch_no) => {
|
||||
this.update_item_in_cart(item_code, field, value, batch_no);
|
||||
},
|
||||
on_numpad: (value) => {
|
||||
if (value == 'Pay') {
|
||||
@ -158,10 +158,12 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
});
|
||||
}
|
||||
|
||||
update_item_in_cart(item_code, field='qty', value=1) {
|
||||
update_item_in_cart(item_code, field='qty', value=1, batch_no) {
|
||||
frappe.dom.freeze();
|
||||
if(this.cart.exists(item_code)) {
|
||||
const item = this.frm.doc.items.find(i => i.item_code === item_code);
|
||||
if(this.cart.exists(item_code, batch_no)) {
|
||||
const search_field = batch_no ? 'batch_no' : 'item_code';
|
||||
const search_value = batch_no || item_code;
|
||||
const item = this.frm.doc.items.find(i => i[search_field] === search_value);
|
||||
frappe.flags.hide_serial_batch_dialog = false;
|
||||
|
||||
if (typeof value === 'string' && !in_list(['serial_no', 'batch_no'], field)) {
|
||||
@ -219,29 +221,31 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
]);
|
||||
}
|
||||
|
||||
select_batch_and_serial_no(item) {
|
||||
select_batch_and_serial_no(row) {
|
||||
frappe.dom.unfreeze();
|
||||
|
||||
erpnext.show_serial_batch_selector(this.frm, item, () => {
|
||||
this.update_item_in_frm(item, 'qty', item.qty)
|
||||
.then(() => {
|
||||
// update cart
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
if (item.qty === 0) {
|
||||
frappe.model.clear_doc(item.doctype, item.name);
|
||||
}
|
||||
},
|
||||
() => this.update_cart_data(item)
|
||||
]);
|
||||
});
|
||||
erpnext.show_serial_batch_selector(this.frm, row, () => {
|
||||
this.frm.doc.items.forEach(item => {
|
||||
this.update_item_in_frm(item, 'qty', item.qty)
|
||||
.then(() => {
|
||||
// update cart
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
if (item.qty === 0) {
|
||||
frappe.model.clear_doc(item.doctype, item.name);
|
||||
}
|
||||
},
|
||||
() => this.update_cart_data(item)
|
||||
]);
|
||||
});
|
||||
})
|
||||
}, () => {
|
||||
this.on_close(item);
|
||||
this.on_close(row);
|
||||
}, true);
|
||||
}
|
||||
|
||||
on_close(item) {
|
||||
if (!this.cart.exists(item.item_code) && item.qty) {
|
||||
if (!this.cart.exists(item.item_code, item.batch_no) && item.qty) {
|
||||
frappe.model.clear_doc(item.doctype, item.name);
|
||||
}
|
||||
}
|
||||
@ -492,6 +496,11 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
//
|
||||
// }).addClass('visible-xs');
|
||||
|
||||
this.page.add_menu_item(__("Form View"), function () {
|
||||
frappe.model.sync(me.frm.doc);
|
||||
frappe.set_route("Form", me.frm.doc.doctype, me.frm.doc.name);
|
||||
});
|
||||
|
||||
this.page.add_menu_item(__("POS Profile"), function () {
|
||||
frappe.set_route('List', 'POS Profile');
|
||||
});
|
||||
@ -602,11 +611,15 @@ class POSCart {
|
||||
this.customer_field.set_value("");
|
||||
this.frm.msgbox = "";
|
||||
|
||||
let total_item_qty = 0.0;
|
||||
this.frm.set_value("pos_total_qty",total_item_qty);
|
||||
|
||||
this.$discount_amount.find('input:text').val('');
|
||||
this.wrapper.find('.grand-total-value').text(
|
||||
format_currency(this.frm.doc.grand_total, this.frm.currency));
|
||||
this.wrapper.find('.rounded-total-value').text(
|
||||
format_currency(this.frm.doc.rounded_total, this.frm.currency));
|
||||
this.$qty_total.find(".quantity-total").text(total_item_qty);
|
||||
|
||||
const customer = this.frm.doc.customer;
|
||||
this.customer_field.set_value(customer);
|
||||
@ -721,7 +734,7 @@ class POSCart {
|
||||
total_item_qty += d.qty;
|
||||
}
|
||||
});
|
||||
this.$qty_total.find('.quantity-total').text(total_item_qty)
|
||||
this.$qty_total.find('.quantity-total').text(total_item_qty);
|
||||
this.frm.set_value("pos_total_qty",total_item_qty);
|
||||
}
|
||||
|
||||
@ -804,10 +817,11 @@ class POSCart {
|
||||
this.numpad.reset_value();
|
||||
} else {
|
||||
const item_code = this.selected_item.attr('data-item-code');
|
||||
const batch_no = this.selected_item.attr('data-batch-no');
|
||||
const field = this.selected_item.active_field;
|
||||
const value = this.numpad.get_value();
|
||||
|
||||
this.events.on_field_change(item_code, field, value);
|
||||
this.events.on_field_change(item_code, field, value, batch_no);
|
||||
}
|
||||
}
|
||||
|
||||
@ -835,7 +849,7 @@ class POSCart {
|
||||
add_item(item) {
|
||||
this.$empty_state.hide();
|
||||
|
||||
if (this.exists(item.item_code)) {
|
||||
if (this.exists(item.item_code, item.batch_no)) {
|
||||
// update quantity
|
||||
this.update_item(item);
|
||||
} else if (flt(item.qty) > 0.0) {
|
||||
@ -848,7 +862,10 @@ class POSCart {
|
||||
}
|
||||
|
||||
update_item(item) {
|
||||
const $item = this.$cart_items.find(`[data-item-code="${item.item_code}"]`);
|
||||
const item_selector = item.batch_no ?
|
||||
`[data-batch-no="${item.batch_no}"]` : `[data-item-code="${item.item_code}"]`;
|
||||
|
||||
const $item = this.$cart_items.find(item_selector);
|
||||
|
||||
if(item.qty > 0) {
|
||||
const is_stock_item = this.get_item_details(item.item_code).is_stock_item;
|
||||
@ -870,7 +887,8 @@ class POSCart {
|
||||
const rate = format_currency(item.rate, this.frm.doc.currency);
|
||||
const indicator_class = (!is_stock_item || item.actual_qty >= item.qty) ? 'green' : 'red';
|
||||
return `
|
||||
<div class="list-item indicator ${indicator_class}" data-item-code="${item.item_code}" title="Item: ${item.item_name} Available Qty: ${item.actual_qty}">
|
||||
<div class="list-item indicator ${indicator_class}" data-item-code="${item.item_code}"
|
||||
data-batch-no="${item.batch_no}" title="Item: ${item.item_name} Available Qty: ${item.actual_qty}">
|
||||
<div class="item-name list-item__content list-item__content--flex-1.5 ellipsis">
|
||||
${item.item_name}
|
||||
</div>
|
||||
@ -911,8 +929,11 @@ class POSCart {
|
||||
return this.item_data[item_code];
|
||||
}
|
||||
|
||||
exists(item_code) {
|
||||
let $item = this.$cart_items.find(`[data-item-code="${item_code}"]`);
|
||||
exists(item_code, batch_no) {
|
||||
const is_exists = batch_no ?
|
||||
`[data-batch-no="${batch_no}"]` : `[data-item-code="${item_code}"]`;
|
||||
|
||||
let $item = this.$cart_items.find(is_exists);
|
||||
return $item.length > 0;
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ erpnext.stock.ItemDashboard = Class.extend({
|
||||
if(!data) data = [];
|
||||
|
||||
data.forEach(function(d) {
|
||||
d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production;
|
||||
d.actual_or_pending = d.projected_qty + d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
|
||||
d.pending_qty = 0;
|
||||
d.total_reserved = d.reserved_qty + d.reserved_qty_for_production + d.reserved_qty_for_sub_contract;
|
||||
if(d.actual_or_pending > d.actual_qty) {
|
||||
|
||||
@ -116,14 +116,14 @@ class Bin(Document):
|
||||
se.docstatus=1
|
||||
and se.purpose='Subcontract'
|
||||
and ifnull(se.purchase_order, '') !=''
|
||||
and sed.item_code = %s
|
||||
and (sed.item_code = %(item)s or sed.original_item = %(item)s)
|
||||
and se.name = sed.parent
|
||||
and se.purchase_order = po.name
|
||||
and po.docstatus = 1
|
||||
and po.is_subcontracted = 'Yes'
|
||||
and po.status != 'Closed'
|
||||
and po.per_received < 100
|
||||
""", (self.item_code))[0][0]
|
||||
""", {'item': self.item_code})[0][0]
|
||||
|
||||
if reserved_qty_for_sub_contract > materials_transferred:
|
||||
reserved_qty_for_sub_contract = reserved_qty_for_sub_contract - materials_transferred
|
||||
|
||||
@ -456,7 +456,8 @@ $.extend(erpnext.item, {
|
||||
],
|
||||
fields: ["attribute_value"],
|
||||
limit_start: 0,
|
||||
limit_page_length: 500
|
||||
limit_page_length: 500,
|
||||
parent: "Item"
|
||||
}
|
||||
}).then((r) => {
|
||||
if(r.message) {
|
||||
@ -598,7 +599,8 @@ $.extend(erpnext.item, {
|
||||
["parent","=", i],
|
||||
["attribute_value", "like", term + "%"]
|
||||
],
|
||||
fields: ["attribute_value"]
|
||||
fields: ["attribute_value"],
|
||||
parent: "Item"
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
|
||||
@ -366,6 +366,37 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Alternative Item",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@ -3686,7 +3717,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 1,
|
||||
"modified": "2018-03-09 03:13:18.516087",
|
||||
"modified": "2018-03-12 03:13:18.516087",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item",
|
||||
|
||||
@ -15,7 +15,7 @@ def get_data():
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Groups'),
|
||||
'items': ['BOM', 'Product Bundle']
|
||||
'items': ['BOM', 'Product Bundle', 'Item Alternative']
|
||||
},
|
||||
{
|
||||
'label': _('Pricing'),
|
||||
|
||||
0
erpnext/stock/doctype/item_alternative/__init__.py
Normal file
0
erpnext/stock/doctype/item_alternative/__init__.py
Normal file
14
erpnext/stock/doctype/item_alternative/item_alternative.js
Normal file
14
erpnext/stock/doctype/item_alternative/item_alternative.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Item Alternative', {
|
||||
setup: function(frm) {
|
||||
frm.fields_dict.item_code.get_query = () => {
|
||||
return {
|
||||
filters: {
|
||||
'allow_alternative_item': 1
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
});
|
||||
292
erpnext/stock/doctype/item_alternative/item_alternative.json
Normal file
292
erpnext/stock/doctype/item_alternative/item_alternative.json
Normal file
@ -0,0 +1,292 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2018-02-26 17:39:11.249778",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Item Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "alternative_item_code",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Alternative Item Code",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "two_way",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Two-way",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Item Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "item_code.item_name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "alternative_item_name",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Alternative Item Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "alternative_item_code.item_name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-03-07 16:08:08.097107",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Item Alternative",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Stock Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Item Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "item_code",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
40
erpnext/stock/doctype/item_alternative/item_alternative.py
Normal file
40
erpnext/stock/doctype/item_alternative/item_alternative.py
Normal file
@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ItemAlternative(Document):
|
||||
def validate(self):
|
||||
self.has_alternative_item()
|
||||
self.validate_alternative_item()
|
||||
self.validate_duplicate()
|
||||
|
||||
def has_alternative_item(self):
|
||||
if (self.item_code and
|
||||
not frappe.db.get_value('Item', self.item_code, 'allow_alternative_item')):
|
||||
frappe.throw(_("Not allow to set alternative item for the item {0}").format(self.item_code))
|
||||
|
||||
def validate_alternative_item(self):
|
||||
if self.item_code == self.alternative_item_code:
|
||||
frappe.throw(_("Alternative item must not be same as item code"))
|
||||
|
||||
def validate_duplicate(self):
|
||||
if frappe.db.get_value("Item Alternative", {'item_code': self.item_code,
|
||||
'alternative_item_code': self.alternative_item_code, 'name': ('!=', self.name)}):
|
||||
frappe.throw(_("Already record exists for the item {0}".format(self.item_code)))
|
||||
|
||||
def get_alternative_items(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql(""" (select alternative_item_code from `tabItem Alternative`
|
||||
where item_code = %(item_code)s and alternative_item_code like %(txt)s)
|
||||
union
|
||||
(select item_code from `tabItem Alternative`
|
||||
where alternative_item_code = %(item_code)s and item_code like %(txt)s
|
||||
and two_way = 1) limit {0}, {1}
|
||||
""".format(start, page_len), {
|
||||
"item_code": frappe.db.escape(filters.get('item_code')),
|
||||
"txt": "%%%s%%" % frappe.db.escape(txt)
|
||||
})
|
||||
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Item Alternative", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Item Alternative
|
||||
() => frappe.tests.make('Item Alternative', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
133
erpnext/stock/doctype/item_alternative/test_item_alternative.py
Normal file
133
erpnext/stock/doctype/item_alternative/test_item_alternative.py
Normal file
@ -0,0 +1,133 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe.utils import flt
|
||||
from erpnext.stock.doctype.item.test_item import create_item
|
||||
from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
|
||||
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import make_stock_entry
|
||||
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt, make_rm_stock_entry
|
||||
import unittest
|
||||
|
||||
class TestItemAlternative(unittest.TestCase):
|
||||
def setUp(self):
|
||||
make_items()
|
||||
|
||||
def test_alternative_item_for_subcontract_rm(self):
|
||||
create_stock_reconciliation(item_code='Alternate Item For A RW 1', warehouse='_Test Warehouse - _TC',
|
||||
qty=5, rate=2000)
|
||||
create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC',
|
||||
qty=5, rate=2000)
|
||||
|
||||
supplier_warehouse = "Test Supplier Warehouse - _TC"
|
||||
po = create_purchase_order(item = "Test Finished Goods - A",
|
||||
is_subcontracted='Yes', qty=5, rate=3000, supplier_warehouse=supplier_warehouse)
|
||||
|
||||
rm_item = [{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name":"Test FG A RW 1",
|
||||
"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"},
|
||||
{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name":"Test FG A RW 2",
|
||||
"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}]
|
||||
|
||||
rm_item_string = json.dumps(rm_item)
|
||||
reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
|
||||
{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')
|
||||
|
||||
se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string))
|
||||
se.to_warehouse = supplier_warehouse
|
||||
se.insert()
|
||||
|
||||
doc = frappe.get_doc('Stock Entry', se.name)
|
||||
for item in doc.items:
|
||||
if item.item_code == 'Test FG A RW 1':
|
||||
item.item_code = 'Alternate Item For A RW 1'
|
||||
item.item_name = 'Alternate Item For A RW 1'
|
||||
item.description = 'Alternate Item For A RW 1'
|
||||
item.original_item = 'Test FG A RW 1'
|
||||
|
||||
doc.save()
|
||||
doc.submit()
|
||||
after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
|
||||
{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')
|
||||
|
||||
self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5))
|
||||
|
||||
pr = make_purchase_receipt(po.name)
|
||||
pr.save()
|
||||
|
||||
pr = frappe.get_doc('Purchase Receipt', pr.name)
|
||||
status = False
|
||||
for d in pr.supplied_items:
|
||||
if d.rm_item_code == 'Alternate Item For A RW 1':
|
||||
status = True
|
||||
|
||||
self.assertEqual(status, True)
|
||||
|
||||
def test_alternative_item_for_production_rm(self):
|
||||
create_stock_reconciliation(item_code='Alternate Item For A RW 1',
|
||||
warehouse='_Test Warehouse - _TC',qty=5, rate=2000)
|
||||
create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC',
|
||||
qty=5, rate=2000)
|
||||
pro_order = make_wo_order_test_record(production_item='Test Finished Goods - A',
|
||||
qty=5, source_warehouse='_Test Warehouse - _TC', wip_warehouse='Test Supplier Warehouse - _TC')
|
||||
|
||||
reserved_qty_for_production = frappe.db.get_value('Bin',
|
||||
{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')
|
||||
|
||||
ste = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 5))
|
||||
ste.insert()
|
||||
|
||||
for item in ste.items:
|
||||
if item.item_code == 'Test FG A RW 1':
|
||||
item.item_code = 'Alternate Item For A RW 1'
|
||||
item.item_name = 'Alternate Item For A RW 1'
|
||||
item.description = 'Alternate Item For A RW 1'
|
||||
item.original_item = 'Test FG A RW 1'
|
||||
|
||||
ste.submit()
|
||||
reserved_qty_for_production_after_transfer = frappe.db.get_value('Bin',
|
||||
{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')
|
||||
|
||||
self.assertEqual(reserved_qty_for_production_after_transfer, flt(reserved_qty_for_production - 5))
|
||||
ste1 = frappe.get_doc(make_stock_entry(pro_order.name, "Manufacture", 5))
|
||||
|
||||
status = False
|
||||
for d in ste1.items:
|
||||
if d.item_code == 'Alternate Item For A RW 1':
|
||||
status = True
|
||||
|
||||
self.assertEqual(status, True)
|
||||
ste1.submit()
|
||||
|
||||
def make_items():
|
||||
items = ['Test Finished Goods - A', 'Test FG A RW 1', 'Test FG A RW 2', 'Alternate Item For A RW 1']
|
||||
for item_code in items:
|
||||
if not frappe.db.exists('Item', item_code):
|
||||
create_item(item_code)
|
||||
|
||||
create_stock_reconciliation(item_code="Test FG A RW 1",
|
||||
warehouse='_Test Warehouse - _TC', qty=10, rate=2000)
|
||||
|
||||
if frappe.db.exists('Item', 'Test FG A RW 1'):
|
||||
doc = frappe.get_doc('Item', 'Test FG A RW 1')
|
||||
doc.allow_alternative_item = 1
|
||||
doc.save()
|
||||
|
||||
if frappe.db.exists('Item', 'Test Finished Goods - A'):
|
||||
doc = frappe.get_doc('Item', 'Test Finished Goods - A')
|
||||
doc.is_sub_contracted_item = 1
|
||||
doc.save()
|
||||
|
||||
if not frappe.db.get_value('BOM',
|
||||
{'item': 'Test Finished Goods - A', 'docstatus': 1}):
|
||||
make_bom(item = 'Test Finished Goods - A', raw_materials = ['Test FG A RW 1', 'Test FG A RW 2'])
|
||||
|
||||
if not frappe.db.get_value('Warehouse', {'warehouse_name': 'Test Supplier Warehouse'}):
|
||||
frappe.get_doc({
|
||||
'doctype': 'Warehouse',
|
||||
'warehouse_name': 'Test Supplier Warehouse',
|
||||
'company': '_Test Company'
|
||||
}).insert(ignore_permissions=True)
|
||||
@ -120,6 +120,25 @@ frappe.ui.form.on('Stock Entry', {
|
||||
});
|
||||
}
|
||||
|
||||
if(frm.doc.items) {
|
||||
const has_alternative = frm.doc.items.find(i => i.allow_alternative_item === 1);
|
||||
|
||||
if (frm.doc.docstatus == 0 && has_alternative) {
|
||||
frm.add_custom_button(__('Alternate Item'), () => {
|
||||
erpnext.utils.select_alternate_items({
|
||||
frm: frm,
|
||||
child_docname: "items",
|
||||
warehouse_field: "s_warehouse",
|
||||
child_doctype: "Stock Entry Detail",
|
||||
original_item_field: "original_item",
|
||||
condition: (d) => {
|
||||
if (d.s_warehouse && d.allow_alternative_item) {return true;}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (frm.doc.docstatus===0) {
|
||||
frm.add_custom_button(__('Purchase Invoice'), function() {
|
||||
erpnext.utils.map_current_doc({
|
||||
|
||||
@ -400,9 +400,10 @@ class StockEntry(StockController):
|
||||
if self.purpose == "Subcontract" and self.purchase_order:
|
||||
purchase_order = frappe.get_doc("Purchase Order", self.purchase_order)
|
||||
for se_item in self.items:
|
||||
item_code = se_item.original_item or se_item.item_code
|
||||
precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||
total_allowed = sum([flt(d.required_qty) for d in purchase_order.supplied_items \
|
||||
if d.rm_item_code == se_item.item_code])
|
||||
if d.rm_item_code == item_code])
|
||||
if not total_allowed:
|
||||
frappe.throw(_("Item {0} not found in 'Raw Materials Supplied' table in Purchase Order {1}")
|
||||
.format(se_item.item_code, self.purchase_order))
|
||||
@ -421,7 +422,8 @@ class StockEntry(StockController):
|
||||
def validate_bom(self):
|
||||
for d in self.get('items'):
|
||||
if d.bom_no and (d.t_warehouse != getattr(self, "pro_doc", frappe._dict()).scrap_warehouse):
|
||||
validate_bom_no(d.item_code, d.bom_no)
|
||||
item_code = d.original_item or d.item_code
|
||||
validate_bom_no(item_code, d.bom_no)
|
||||
|
||||
def validate_finished_goods(self):
|
||||
"""validation: finished good quantity should be same as manufacturing quantity"""
|
||||
@ -608,7 +610,6 @@ class StockEntry(StockController):
|
||||
item_dict = self.get_bom_raw_materials(self.fg_completed_qty)
|
||||
|
||||
#Get PO Supplied Items Details
|
||||
print('Purchase Order', self.purchase_order, self.purpose)
|
||||
if self.purchase_order and self.purpose == "Subcontract":
|
||||
#Get PO Supplied Items Details
|
||||
item_wh = frappe._dict(frappe.db.sql("""
|
||||
@ -695,9 +696,23 @@ class StockEntry(StockController):
|
||||
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
|
||||
fetch_exploded = self.use_multi_level_bom)
|
||||
|
||||
used_alternative_items = get_used_alternative_items(work_order = self.work_order)
|
||||
for item in item_dict.values():
|
||||
# if source warehouse presents in BOM set from_warehouse as bom source_warehouse
|
||||
if item["allow_alternative_item"]:
|
||||
item["allow_alternative_item"] = frappe.db.get_value('Work Order',
|
||||
self.work_order, "allow_alternative_item")
|
||||
|
||||
item.from_warehouse = self.from_warehouse or item.source_warehouse or item.default_warehouse
|
||||
if item.item_code in used_alternative_items:
|
||||
alternative_item_data = used_alternative_items.get(item.item_code)
|
||||
item.item_code = alternative_item_data.item_code
|
||||
item.item_name = alternative_item_data.item_name
|
||||
item.stock_uom = alternative_item_data.stock_uom
|
||||
item.uom = alternative_item_data.uom
|
||||
item.conversion_factor = alternative_item_data.conversion_factor
|
||||
item.description = alternative_item_data.description
|
||||
|
||||
return item_dict
|
||||
|
||||
def get_bom_scrap_material(self, qty):
|
||||
@ -813,6 +828,9 @@ class StockEntry(StockController):
|
||||
item_row["from_warehouse"] = d.source_warehouse
|
||||
|
||||
item_row["to_warehouse"] = wip_warehouse
|
||||
if item_row["allow_alternative_item"]:
|
||||
item_row["allow_alternative_item"] = pro_order.allow_alternative_item
|
||||
|
||||
item_dict.setdefault(d.item_code, item_row)
|
||||
|
||||
return item_dict
|
||||
@ -827,7 +845,7 @@ class StockEntry(StockController):
|
||||
se_child = self.append('items')
|
||||
se_child.s_warehouse = item_dict[d].get("from_warehouse")
|
||||
se_child.t_warehouse = item_dict[d].get("to_warehouse")
|
||||
se_child.item_code = cstr(d)
|
||||
se_child.item_code = item_dict[d].get('item_code') or cstr(d)
|
||||
se_child.item_name = item_dict[d]["item_name"]
|
||||
se_child.description = item_dict[d]["description"]
|
||||
se_child.uom = stock_uom
|
||||
@ -835,6 +853,7 @@ class StockEntry(StockController):
|
||||
se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty"))
|
||||
se_child.expense_account = item_dict[d].get("expense_account") or expense_account
|
||||
se_child.cost_center = item_dict[d].get("cost_center") or cost_center
|
||||
se_child.allow_alternative_item = item_dict[d].get("allow_alternative_item", 0)
|
||||
|
||||
if item_dict[d].get("idx"):
|
||||
se_child.idx = item_dict[d].get("idx")
|
||||
@ -882,8 +901,9 @@ class StockEntry(StockController):
|
||||
|
||||
#Update reserved sub contracted quantity in bin based on Supplied Item Details
|
||||
for d in self.get("items"):
|
||||
reserve_warehouse = item_wh.get(d.item_code)
|
||||
stock_bin = get_bin(d.item_code, reserve_warehouse)
|
||||
item_code = d.get('original_item') or d.get('item_code')
|
||||
reserve_warehouse = item_wh.get(item_code)
|
||||
stock_bin = get_bin(item_code, reserve_warehouse)
|
||||
stock_bin.update_reserved_qty_for_sub_contracting()
|
||||
|
||||
@frappe.whitelist()
|
||||
@ -976,6 +996,30 @@ def get_operating_cost_per_unit(work_order=None, bom_no=None):
|
||||
|
||||
return operating_cost_per_unit
|
||||
|
||||
def get_used_alternative_items(purchase_order=None, work_order=None):
|
||||
cond = ""
|
||||
|
||||
if purchase_order:
|
||||
cond = "and ste.purpose = 'Subcontract' and ste.purchase_order = '{0}'".format(purchase_order)
|
||||
elif work_order:
|
||||
cond = "and ste.purpose = 'Material Transfer for Manufacture' and ste.work_order = '{0}'".format(work_order)
|
||||
|
||||
if not cond: return {}
|
||||
|
||||
used_alternative_items = {}
|
||||
data = frappe.db.sql(""" select sted.original_item, sted.uom, sted.conversion_factor,
|
||||
sted.item_code, sted.item_name, sted.conversion_factor,sted.stock_uom, sted.description
|
||||
from
|
||||
`tabStock Entry` ste, `tabStock Entry Detail` sted
|
||||
where
|
||||
sted.parent = ste.name and ste.docstatus = 1 and sted.original_item != sted.item_code
|
||||
{0} """.format(cond), as_dict=1)
|
||||
|
||||
for d in data:
|
||||
used_alternative_items[d.original_item] = d
|
||||
|
||||
return used_alternative_items
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_uom_details(item_code, uom, qty):
|
||||
"""Returns dict `{"conversion_factor": [value], "transfer_qty": qty * [value]}`
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -70,6 +71,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -102,6 +104,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -130,6 +133,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -162,6 +166,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -190,6 +195,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -222,6 +228,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -250,6 +257,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -279,6 +287,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -309,6 +318,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -341,6 +351,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "300px"
|
||||
},
|
||||
@ -371,6 +382,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -401,6 +413,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -432,6 +445,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -461,6 +475,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -492,6 +507,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -524,6 +540,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -555,6 +572,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -586,6 +604,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -618,6 +637,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -649,6 +669,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -677,6 +698,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -709,6 +731,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -740,6 +763,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -772,6 +796,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -803,6 +828,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -834,6 +860,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -866,6 +893,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -895,6 +923,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -926,6 +955,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -954,6 +984,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -986,6 +1017,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1018,6 +1050,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1047,6 +1080,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1078,6 +1112,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1106,6 +1141,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1138,6 +1174,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1167,6 +1204,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1197,6 +1235,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1228,6 +1267,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1259,6 +1299,39 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "s_warehouse",
|
||||
"fieldname": "allow_alternative_item",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Alternative Item",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1287,6 +1360,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1318,6 +1392,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@ -1348,6 +1423,39 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "original_item",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Original Item",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@ -1361,7 +1469,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-16 20:19:57.471380",
|
||||
"modified": "2018-03-05 13:09:25.849700",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Entry Detail",
|
||||
|
||||
@ -320,7 +320,7 @@ def get_price_list_rate(args, item_doc, out):
|
||||
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
|
||||
/ flt(args.conversion_rate)
|
||||
if not args.price_list_uom_dependant:
|
||||
out.price_list_rate = flt(out.price_list_rate * (args.conversion_factor or 1.0))
|
||||
out.price_list_rate = flt(out.price_list_rate * (flt(args.conversion_factor) or 1.0))
|
||||
|
||||
if not out.price_list_rate and args.transaction_type=="buying":
|
||||
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||
|
||||
@ -14,10 +14,15 @@ def get_data(item):
|
||||
if not item:
|
||||
return []
|
||||
item_dicts = []
|
||||
variants = None
|
||||
|
||||
variant_results = frappe.db.sql("""select name from `tabItem`
|
||||
where variant_of = %s""", item, as_dict=1)
|
||||
variants = ",".join(['"' + frappe.db.escape(variant['name']) + '"' for variant in variant_results])
|
||||
if not variant_results:
|
||||
frappe.msgprint(_("There isn't any item variant for the selected item"))
|
||||
return []
|
||||
else:
|
||||
variants = ",".join(['"' + frappe.db.escape(variant['name']) + '"' for variant in variant_results])
|
||||
|
||||
order_count_map = get_open_sales_orders_map(variants)
|
||||
stock_details_map = get_stock_details_map(variants)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user