Merge branch 'develop'

This commit is contained in:
Pratik Vyas 2014-10-07 17:05:32 +05:30
commit e0c83e22d9
28 changed files with 784 additions and 757 deletions

View File

@ -1 +1 @@
__version__ = '4.5.1'
__version__ = '4.5.2'

View File

@ -142,24 +142,6 @@
"reqd": 0,
"search_index": 1
},
{
"allow_on_submit": 1,
"description": "Start date of current invoice's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"description": "End date of current invoice's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
@ -798,6 +780,26 @@
"permlevel": 0,
"print_hide": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "Start date of current invoice's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "End date of current invoice's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -821,17 +823,6 @@
"permlevel": 0,
"print_hide": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -850,6 +841,17 @@
"print_hide": 1,
"width": "50%"
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The unique id for tracking all recurring invoices. It is generated on submit.",
@ -876,7 +878,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"modified": "2014-09-18 03:12:51.994059",
"modified": "2014-10-06 12:57:32.064210",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@ -168,30 +168,6 @@
"reqd": 1,
"search_index": 0
},
{
"allow_on_submit": 1,
"depends_on": "",
"description": "Start date of current invoice's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"read_only": 0
},
{
"allow_on_submit": 1,
"depends_on": "",
"description": "End date of current invoice's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"read_only": 0
},
{
"fieldname": "currency_section",
"fieldtype": "Section Break",
@ -1095,6 +1071,30 @@
"print_hide": 1,
"read_only": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "End date of current invoice's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"read_only": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "Start date of current invoice's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 0,
"read_only": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -1120,17 +1120,6 @@
"print_hide": 1,
"read_only": 0
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.\n",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -1152,6 +1141,17 @@
"read_only": 0,
"width": "50%"
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.\n",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The unique id for tracking all recurring invoices.\u00a0It is generated on submit.",
@ -1192,7 +1192,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"modified": "2014-09-18 03:17:54.976732",
"modified": "2014-10-06 12:54:42.549361",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@ -21,7 +21,7 @@ class AccountsReceivableReport(object):
def get_columns(self, customer_naming_by):
columns = [
_("Posting Date") + ":Date:80", _("Account") + ":Link/Account:150",
_("Voucher Type") + "::110", _("Voucher No") + "::120", "::30",
_("Voucher Type") + "::110", _("Voucher No") + ":Dynamic Link/Voucher Type:120",
_("Due Date") + ":Date:80",
_("Invoiced Amount") + ":Currency:100", _("Payment Received") + ":Currency:100",
_("Outstanding Amount") + ":Currency:100", _("Age") + ":Int:50", "0-30:Currency:100",
@ -63,11 +63,6 @@ class AccountsReceivableReport(object):
row += [self.get_territory(gle.account), gle.remarks]
data.append(row)
for i in range(0, len(data)):
data[i].insert(4, """<a href="%s"><i class="icon icon-share" style="cursor: pointer;"></i></a>""" \
% ("/".join(["#Form", data[i][2], data[i][3]]),))
return data
def get_entries_after(self, report_date):

View File

@ -35,7 +35,7 @@ def validate_filters(filters, account_details):
def get_columns():
return [_("Posting Date") + ":Date:100", _("Account") + ":Link/Account:200", _("Debit") + ":Float:100",
_("Credit") + ":Float:100", _("Voucher Type") + "::120", _("Voucher No") + "::160", _("Link") + "::20",
_("Credit") + ":Float:100", _("Voucher Type") + "::120", _("Voucher No") + ":Dynamic Link/Voucher Type:160",
_("Against Account") + "::120", _("Cost Center") + ":Link/Cost Center:100", _("Remarks") + "::400"]
def get_result(filters, account_details):
@ -162,15 +162,6 @@ def get_result_as_list(data):
for d in data:
result.append([d.get("posting_date"), d.get("account"), d.get("debit"),
d.get("credit"), d.get("voucher_type"), d.get("voucher_no"),
get_voucher_link(d.get("voucher_type"), d.get("voucher_no")),
d.get("against"), d.get("cost_center"), d.get("remarks")])
return result
def get_voucher_link(voucher_type, voucher_no):
icon = ""
if voucher_type and voucher_no:
icon = """<a href="%s"><i class="icon icon-share" style="cursor: pointer;">
</i></a>""" % ("/".join(["#Form", voucher_type, voucher_no]))
return icon

View File

@ -101,24 +101,6 @@
"reqd": 1,
"search_index": 1
},
{
"allow_on_submit": 1,
"description": "Start date of current order's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"description": "End date of current order's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
@ -695,6 +677,26 @@
"permlevel": 0,
"print_hide": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "Start date of current order's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "End date of current order's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -716,17 +718,6 @@
"permlevel": 0,
"print_hide": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -745,6 +736,17 @@
"permlevel": 0,
"print_hide": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"fieldname": "recurring_id",
@ -770,7 +772,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"modified": "2014-09-18 03:16:06.299317",
"modified": "2014-10-06 12:16:44.453946",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "4.5.1"
app_version = "4.5.2"
error_report_email = "support@erpnext.com"

View File

@ -96,7 +96,7 @@ cur_frm.cscript['Transfer Raw Materials'] = function() {
}
cur_frm.cscript['Update Finished Goods'] = function() {
cur_frm.cscript.make_se('Manufacture/Repack');
cur_frm.cscript.make_se('Manufacture');
}
cur_frm.fields_dict['production_item'].get_query = function(doc) {

View File

@ -109,15 +109,15 @@
"permlevel": 0
},
{
"depends_on": "eval:doc.docstatus==1",
"description": "Automatically updated via Stock Entry of type Manufacture/Repack",
"fieldname": "produced_qty",
"fieldtype": "Float",
"label": "Manufactured Qty",
"no_copy": 1,
"oldfieldname": "produced_qty",
"oldfieldtype": "Currency",
"permlevel": 0,
"depends_on": "eval:doc.docstatus==1",
"description": "Automatically updated via Stock Entry of type Manufacture or Repack",
"fieldname": "produced_qty",
"fieldtype": "Float",
"label": "Manufactured Qty",
"no_copy": 1,
"oldfieldname": "produced_qty",
"oldfieldtype": "Currency",
"permlevel": 0,
"read_only": 1
},
{

View File

@ -103,7 +103,7 @@ class ProductionOrder(Document):
status = "Submitted"
if stock_entries:
status = "In Process"
produced_qty = stock_entries.get("Manufacture/Repack")
produced_qty = stock_entries.get("Manufacture")
if flt(produced_qty) == flt(self.qty):
status = "Completed"
@ -113,7 +113,7 @@ class ProductionOrder(Document):
def update_produced_qty(self):
produced_qty = frappe.db.sql("""select sum(fg_completed_qty)
from `tabStock Entry` where production_order=%s and docstatus=1
and purpose='Manufacture/Repack'""", self.name)
and purpose='Manufacture'""", self.name)
produced_qty = flt(produced_qty[0][0]) if produced_qty else 0
if produced_qty > self.qty:

View File

@ -31,7 +31,7 @@ class TestProductionOrder(unittest.TestCase):
s.submit()
# from wip to fg
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture/Repack", 4))
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4))
s.insert()
s.submit()
@ -49,7 +49,7 @@ class TestProductionOrder(unittest.TestCase):
test_stock_entry.make_stock_entry("_Test Item", None, "_Test Warehouse - _TC", 100, 100)
test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100)
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture/Repack", 7))
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7))
s.insert()
self.assertRaises(StockOverProductionError, s.submit)

View File

@ -6,12 +6,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
"modified": "2014-06-03 07:18:17.082436",
"modified": "2014-09-17 12:41:55.740299",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Issued Items Against Production Order",
"owner": "Administrator",
"query": "select\n ste.production_order as \"Production Order:Link/Production Order:120\",\n ste.posting_date as \"Issue Date:Date:140\",\n ste_item.item_code as \"Item Code:Link/Item:120\",\n\tste_item.description as \"Description::150\",\n\tste_item.transfer_qty as \"Qty:Float:100\",\n\tste_item.stock_uom as \"UOM:Link/UOM:80\",\n\tste_item.amount as \"Amount:Currency:120\",\n\tste_item.serial_no as \"Serial No:Link/Serial No:80\",\n\tste_item.s_warehouse as \"Source Warehouse:Link/Warehouse:120\",\n\tste_item.t_warehouse as \"Target Warehouse:Link/Warehouse:120\",\n\tpro.production_item as \"Finished Goods:Link/Item:120\", \n\tste.name as \"Stock Entry:Link/Stock Entry:120\"\nfrom\n\t`tabStock Entry` ste, `tabStock Entry Detail` ste_item, `tabProduction Order` pro\nwhere\n\tifnull(ste.production_order, '') != '' and ste.name = ste_item.parent \n\tand ste.production_order = pro.name and ste.docstatus = 1 \n\tand ste.purpose = 'Manufacture/Repack'\norder by ste.posting_date, ste.production_order, ste_item.item_code",
"query": "select\n ste.production_order as \"Production Order:Link/Production Order:120\",\n ste.posting_date as \"Issue Date:Date:140\",\n ste_item.item_code as \"Item Code:Link/Item:120\",\n\tste_item.description as \"Description::150\",\n\tste_item.transfer_qty as \"Qty:Float:100\",\n\tste_item.stock_uom as \"UOM:Link/UOM:80\",\n\tste_item.amount as \"Amount:Currency:120\",\n\tste_item.serial_no as \"Serial No:Link/Serial No:80\",\n\tste_item.s_warehouse as \"Source Warehouse:Link/Warehouse:120\",\n\tste_item.t_warehouse as \"Target Warehouse:Link/Warehouse:120\",\n\tpro.production_item as \"Finished Goods:Link/Item:120\", \n\tste.name as \"Stock Entry:Link/Stock Entry:120\"\nfrom\n\t`tabStock Entry` ste, `tabStock Entry Detail` ste_item, `tabProduction Order` pro\nwhere\n\tifnull(ste.production_order, '') != '' and ste.name = ste_item.parent \n\tand ste.production_order = pro.name and ste.docstatus = 1 \n\tand ste.purpose = 'Manufacture' or 'Repack'\norder by ste.posting_date, ste.production_order, ste_item.item_code",
"ref_doctype": "Production Order",
"report_name": "Issued Items Against Production Order",
"report_type": "Query Report"

View File

@ -80,4 +80,5 @@ execute:frappe.delete_doc("DocType", "Landed Cost Wizard")
erpnext.patches.v4_2.default_website_style
erpnext.patches.v4_2.set_company_country
erpnext.patches.v4_2.update_sales_order_invoice_field_name
erpnext.patches.v4_2.cost_of_production_cycle
erpnext.patches.v4_2.cost_of_production_cycle
erpnext.patches.v4_2.seprate_manufacture_and_repack

View File

@ -0,0 +1,9 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.db.sql("""update `tabStock Entry` set purpose='Manufacture' where purpose='Manufacture/Repack' and ifnull(production_order,"")!="" """)
frappe.db.sql("""update `tabStock Entry` set purpose='Repack' where purpose='Manufacture/Repack' and ifnull(production_order,"")="" """)

View File

@ -169,24 +169,6 @@
"search_index": 1,
"width": "160px"
},
{
"allow_on_submit": 1,
"description": "Start date of current order's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"description": "End date of current order's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"description": "Customer's Purchase Order Number",
"fieldname": "po_no",
@ -939,6 +921,26 @@
"permlevel": 0,
"print_hide": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "Start date of current order's period",
"fieldname": "from_date",
"fieldtype": "Date",
"label": "From Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
"description": "End date of current order's period",
"fieldname": "to_date",
"fieldtype": "Date",
"label": "To Date",
"no_copy": 1,
"permlevel": 0
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -962,17 +964,6 @@
"permlevel": 0,
"print_hide": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"depends_on": "eval:doc.is_recurring==1",
@ -991,6 +982,17 @@
"permlevel": 0,
"print_hide": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"description": "The date on which next invoice will be generated. It is generated on submit.",
"fieldname": "next_date",
"fieldtype": "Date",
"label": "Next Date",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1,
"read_only": 1
},
{
"depends_on": "eval:doc.is_recurring==1",
"fieldname": "recurring_id",
@ -1018,7 +1020,7 @@
"idx": 1,
"is_submittable": 1,
"issingle": 0,
"modified": "2014-09-18 03:17:33.241162",
"modified": "2014-10-06 12:16:41.256013",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",

View File

@ -3,8 +3,15 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
class Batch(Document):
pass
def validate(self):
self.item_has_batch_enabled()
def item_has_batch_enabled(self):
has_batch_no = frappe.db.get_value("Item",self.item,"has_batch_no")
if has_batch_no =='No':
frappe.throw(_("The selected item cannot have Batch"))

View File

@ -0,0 +1,14 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
import frappe
from frappe.exceptions import ValidationError
import unittest
class TestBatch(unittest.TestCase):
def test_item_has_batch_enabled(self):
self.assertRaises(ValidationError, frappe.get_doc({
"doctype": "Batch",
"name": "_test Batch",
"item": "_Test Item"
}).save)

View File

@ -19,7 +19,7 @@ cur_frm.cscript.refresh = function(doc) {
cur_frm.cscript.edit_prices_button();
if (!doc.__islocal && doc.is_stock_item == 'Yes') {
cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method'],
cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method', 'has_batch_no'],
(doc.__onload && doc.__onload.sle_exists=="exists") ? false : true);
}
@ -185,4 +185,4 @@ cur_frm.cscript.image = function() {
else {
msgprint(__("You may need to update: {0}", [frappe.meta.get_docfield(cur_frm.doc.doctype, "description_html").label]));
}
}
}

View File

@ -187,13 +187,14 @@ class Item(WebsiteGenerator):
def cant_change(self):
if not self.get("__islocal"):
vals = frappe.db.get_value("Item", self.name,
["has_serial_no", "is_stock_item", "valuation_method"], as_dict=True)
["has_serial_no", "is_stock_item", "valuation_method", "has_batch_no"], as_dict=True)
if vals and ((self.is_stock_item == "No" and vals.is_stock_item == "Yes") or
vals.has_serial_no != self.has_serial_no or
vals.has_batch_no != self.has_batch_no or
cstr(vals.valuation_method) != cstr(self.valuation_method)):
if self.check_if_sle_exists() == "exists":
frappe.throw(_("As there are existing stock transactions for this item, you can not change the values of 'Has Serial No', 'Is Stock Item' and 'Valuation Method'"))
frappe.throw(_("As there are existing stock transactions for this item, you can not change the values of 'Has Serial No', 'Has Batch No', 'Is Stock Item' and 'Valuation Method'"))
def validate_item_type_for_reorder(self):
if self.re_order_level or len(self.get("item_reorder", {"material_request_type": "Purchase"})):

View File

@ -9,6 +9,6 @@ class TestItem(unittest.TestCase):
def test_duplicate_item(self):
from erpnext.stock.doctype.item_price.item_price import ItemPriceDuplicateItem
doc = frappe.copy_doc(test_records[0])
self.assertRaises(ItemPriceDuplicateItem, doc.insert)
self.assertRaises(ItemPriceDuplicateItem, doc.save)
test_records = frappe.get_test_records('Item Price')

View File

@ -162,8 +162,7 @@ def item_details(doctype, txt, searchfield, start, page_len, filters):
from erpnext.controllers.queries import get_match_cond
return frappe.db.sql("""select name, item_name, description from `tabItem`
where name in ( select item_code FROM `tabDelivery Note Item`
where parent= %s
and ifnull(qty, 0) > ifnull(packed_qty, 0))
where parent= %s)
and %s like "%s" %s
limit %s, %s """ % ("%s", searchfield, "%s",
get_match_cond(doctype), "%s", "%s"),

View File

@ -120,7 +120,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
clean_up: function() {
// Clear Production Order record from locals, because it is updated via Stock Entry
if(this.frm.doc.production_order &&
this.frm.doc.purpose == "Manufacture/Repack") {
this.frm.doc.purpose == "Manufacture") {
frappe.model.remove_from_locals("Production Order",
this.frm.doc.production_order);
}
@ -162,7 +162,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
},
toggle_enable_bom: function() {
this.frm.toggle_enable("bom_no", !this.frm.doc.production_order);
this.frm.toggle_enable("bom_no", this.frm.doc.purpose!="Manufacture");
},
get_doctype_docname: function() {
@ -339,6 +339,8 @@ cur_frm.cscript.toggle_related_fields = function(doc) {
cur_frm.fields_dict["mtn_details"].grid.set_column_disp("s_warehouse", !disable_from_warehouse);
cur_frm.fields_dict["mtn_details"].grid.set_column_disp("t_warehouse", !disable_to_warehouse);
cur_frm.cscript.toggle_enable_bom();
if(doc.purpose == 'Purchase Return') {
doc.customer = doc.customer_name = doc.customer_address =
doc.delivery_note_no = doc.sales_invoice_no = null;
@ -351,6 +353,8 @@ cur_frm.cscript.toggle_related_fields = function(doc) {
doc.delivery_note_no = doc.sales_invoice_no = doc.supplier =
doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no = null;
}
}
cur_frm.fields_dict['production_order'].get_query = function(doc) {
@ -457,4 +461,5 @@ cur_frm.fields_dict.customer.get_query = function(doc, cdt, cdn) {
cur_frm.fields_dict.supplier.get_query = function(doc, cdt, cdn) {
return { query: "erpnext.controllers.queries.supplier_query" }
}
cur_frm.add_fetch('production_order', 'total_fixed_cost', 'total_fixed_cost');
cur_frm.add_fetch('production_order', 'total_fixed_cost', 'total_fixed_cost');
cur_frm.add_fetch('bom_no', 'total_fixed_cost', 'total_fixed_cost');

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ class StockEntry(StockController):
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "transfer_qty")
self.validate_warehouse(pro_obj)
self.validate_production_order(pro_obj)
self.validate_production_order()
self.get_stock_and_rate()
self.validate_incoming_rate()
self.validate_bom()
@ -54,6 +54,7 @@ class StockEntry(StockController):
self.validate_valuation_rate()
self.set_total_amount()
def on_submit(self):
self.update_stock_ledger()
@ -74,7 +75,7 @@ class StockEntry(StockController):
def validate_purpose(self):
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
"Manufacture/Repack", "Subcontract", "Sales Return", "Purchase Return"]
"Manufacture", "Repack", "Subcontract", "Sales Return", "Purchase Return"]
if self.purpose not in valid_purposes:
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
@ -137,7 +138,7 @@ class StockEntry(StockController):
if self.purpose in target_mandatory and not d.t_warehouse:
frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
if self.purpose == "Manufacture/Repack":
if self.purpose in ["Manufacture", "Repack"]:
if validate_for_manufacture_repack:
if d.bom_no:
d.s_warehouse = None
@ -156,14 +157,11 @@ class StockEntry(StockController):
if cstr(d.s_warehouse) == cstr(d.t_warehouse):
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
def validate_production_order(self, pro_obj=None):
if not pro_obj:
if self.production_order:
pro_obj = frappe.get_doc('Production Order', self.production_order)
else:
return
if self.purpose == "Manufacture/Repack":
def validate_production_order(self):
if self.purpose == "Manufacture":
# check if production order is entered
if not self.production_order:
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))
# check for double entry
self.check_duplicate_entry_for_production_order()
elif self.purpose != "Material Transfer":
@ -192,7 +190,7 @@ class StockEntry(StockController):
+ self.production_order + ":" + ", ".join(other_ste), DuplicateEntryForProductionOrderError)
def validate_valuation_rate(self):
if self.purpose == "Manufacture/Repack":
if self.purpose in ["Manufacture", "Repack"]:
valuation_at_source, valuation_at_target = 0, 0
for d in self.get("mtn_details"):
if d.s_warehouse and not d.t_warehouse:
@ -248,7 +246,7 @@ class StockEntry(StockController):
raw_material_cost += flt(d.amount)
# set incoming rate for fg item
if self.purpose == "Manufacture/Repack":
if self.purpose in ["Manufacture", "Repack"]:
number_of_fg_items = len([t.t_warehouse for t in self.get("mtn_details") if t.t_warehouse])
for d in self.get("mtn_details"):
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
@ -391,7 +389,7 @@ class StockEntry(StockController):
pro_doc = frappe.get_doc("Production Order", self.production_order)
_validate_production_order(pro_doc)
pro_doc.run_method("update_status")
if self.purpose == "Manufacture/Repack":
if self.purpose == "Manufacture":
pro_doc.run_method("update_produced_qty")
self.update_planned_qty(pro_doc)
@ -463,20 +461,20 @@ class StockEntry(StockController):
def get_items(self):
self.set('mtn_details', [])
self.validate_production_order()
pro_obj = None
if self.production_order:
# common validations
pro_obj = frappe.get_doc('Production Order', self.production_order)
if pro_obj:
self.validate_production_order(pro_obj)
self.bom_no = pro_obj.bom_no
else:
# invalid production order
self.production_order = None
if self.bom_no:
if self.purpose in ["Material Issue", "Material Transfer", "Manufacture/Repack",
if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
"Subcontract"]:
if self.production_order and self.purpose == "Material Transfer":
item_dict = self.get_pending_raw_materials(pro_obj)
@ -493,7 +491,7 @@ class StockEntry(StockController):
self.add_to_stock_entry_detail(item_dict)
# add finished good item to Stock Entry Detail table -- along with bom_no
if self.production_order and self.purpose == "Manufacture/Repack":
if self.production_order and self.purpose == "Manufacture":
item = frappe.db.get_value("Item", pro_obj.production_item, ["item_name",
"description", "stock_uom", "expense_account", "buying_cost_center"], as_dict=1)
self.add_to_stock_entry_detail({
@ -509,7 +507,7 @@ class StockEntry(StockController):
}
}, bom_no=pro_obj.bom_no)
elif self.purpose in ["Material Receipt", "Manufacture/Repack"]:
elif self.purpose in ["Material Receipt", "Repack"]:
if self.purpose=="Material Receipt":
self.from_warehouse = ""

View File

@ -6,7 +6,8 @@
"Material Issue": "icon-arrow-right",
"Material Receipt": "icon-arrow-left",
"Material Transfer": "icon-resize-horizontal",
"Manufacture/Repack": "icon-wrench",
"Manufacture": "icon-wrench",
"Repack": "icon-wrench",
"Sales Return": "icon-warning-sign",
"Purchase Return": "icon-warning-sign",
"Subcontract": "icon-truck"

View File

@ -108,6 +108,6 @@
],
"posting_date": "2013-01-25",
"posting_time": "17:14:24",
"purpose": "Manufacture/Repack"
"purpose": "Repack"
}
]

View File

@ -843,7 +843,7 @@ class TestStockEntry(unittest.TestCase):
stock_entry = frappe.new_doc("Stock Entry")
stock_entry.update({
"purpose": "Manufacture/Repack",
"purpose": "Manufacture",
"production_order": production_order.name,
"bom_no": bom_no,
"fg_completed_qty": "1",

View File

@ -1,7 +1,7 @@
from setuptools import setup, find_packages
import os
version = "4.5.1"
version = "4.5.2"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()