updated translations
This commit is contained in:
parent
8c51318d82
commit
c38fc713c6
@ -39,7 +39,7 @@ class Account(Document):
|
||||
par = frappe.db.get_value("Account", self.parent_account,
|
||||
["name", "group_or_ledger", "report_type"], as_dict=1)
|
||||
if not par:
|
||||
throw(_("Parent account does not exists"))
|
||||
throw(_("Parent account does not exist"))
|
||||
elif par["name"] == self.name:
|
||||
throw(_("You can not assign itself as parent account"))
|
||||
elif par["group_or_ledger"] != 'Group':
|
||||
@ -117,8 +117,7 @@ class Account(Document):
|
||||
|
||||
def validate_warehouse(self, warehouse):
|
||||
if frappe.db.get_value("Stock Ledger Entry", {"warehouse": warehouse}):
|
||||
throw(_("Stock transactions exist against warehouse ") + warehouse +
|
||||
_(" .You can not assign / modify / remove Master Name"))
|
||||
throw(_("Stock entries exist against warehouse {0} cannot re-assign or modify 'Master Name'").format(warehouse))
|
||||
|
||||
def update_nsm_model(self):
|
||||
"""update lft, rgt indices for nested set model"""
|
||||
@ -194,7 +193,7 @@ class Account(Document):
|
||||
# Validate properties before merging
|
||||
if merge:
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account ") + new +_(" does not exists"))
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new_account,
|
||||
["group_or_ledger", "report_type", "company"]))
|
||||
|
@ -6,24 +6,23 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cint
|
||||
from frappe.utils import cint, comma_and
|
||||
from frappe.model.document import Document
|
||||
|
||||
class AccountsSettings(Document):
|
||||
def on_update(self):
|
||||
frappe.db.set_default("auto_accounting_for_stock", self.auto_accounting_for_stock)
|
||||
|
||||
|
||||
if cint(self.auto_accounting_for_stock):
|
||||
# set default perpetual account in company
|
||||
for company in frappe.db.sql("select name from tabCompany"):
|
||||
frappe.get_doc("Company", company[0]).save()
|
||||
|
||||
|
||||
# Create account head for warehouses
|
||||
warehouse_list = frappe.db.sql("select name, company from tabWarehouse", as_dict=1)
|
||||
warehouse_with_no_company = [d.name for d in warehouse_list if not d.company]
|
||||
if warehouse_with_no_company:
|
||||
frappe.throw(_("Company is missing in following warehouses") + ": \n" +
|
||||
"\n".join(warehouse_with_no_company))
|
||||
frappe.throw(_("Company is missing in warehouses {0}").format(comma_and(warehouse_with_no_company)))
|
||||
for wh in warehouse_list:
|
||||
wh_doc = frappe.get_doc("Warehouse", wh.name)
|
||||
wh_doc.save()
|
||||
wh_doc.save()
|
||||
|
@ -17,9 +17,9 @@ class BudgetDistribution(Document):
|
||||
mnth.month = m
|
||||
mnth.idx = idx
|
||||
idx += 1
|
||||
|
||||
|
||||
def validate(self):
|
||||
total = sum([flt(d.percentage_allocation) for d in self.get("budget_distribution_details")])
|
||||
|
||||
|
||||
if total != 100.0:
|
||||
frappe.throw(_("Percentage Allocation should be equal to ") + "100%")
|
||||
frappe.throw(_("Percentage Allocation should be equal to 100%"))
|
||||
|
@ -41,4 +41,4 @@ class FiscalYear(Document):
|
||||
for fiscal_year, ysd, yed in year_start_end_dates:
|
||||
if (getdate(self.year_start_date) == ysd and getdate(self.year_end_date) == yed) \
|
||||
and (not frappe.flags.in_test):
|
||||
frappe.throw(_("Year Start Date and Year End Date are already set in Fiscal Year: ") + fiscal_year)
|
||||
frappe.throw(_("Year Start Date and Year End Date are already set in Fiscal Year {0}").format(fiscal_year))
|
||||
|
@ -33,7 +33,7 @@ class GLEntry(Document):
|
||||
mandatory = ['account','remarks','voucher_type','voucher_no','fiscal_year','company']
|
||||
for k in mandatory:
|
||||
if not self.get(k):
|
||||
frappe.throw(_("{0} is required").format(k))
|
||||
frappe.throw(_("{0} is required").format(self.meta.get_label(k)))
|
||||
|
||||
# Zero value transaction is not allowed
|
||||
if not (flt(self.debit) or flt(self.credit)):
|
||||
|
@ -120,17 +120,16 @@ class JournalVoucher(AccountsController):
|
||||
for d in self.get('entries'):
|
||||
if d.against_invoice and d.credit:
|
||||
currency = frappe.db.get_value("Sales Invoice", d.against_invoice, "currency")
|
||||
r.append('%s %s against Invoice: %s' %
|
||||
(cstr(currency), fmt_money(flt(d.credit)), d.against_invoice))
|
||||
r.append(_("{0} {1} against Invoice {1}").format(currency, fmt_money(flt(d.credit)), d.against_invoice))
|
||||
|
||||
if d.against_voucher and d.debit:
|
||||
bill_no = frappe.db.sql("""select bill_no, bill_date, currency
|
||||
from `tabPurchase Invoice` where name=%s""", d.against_voucher)
|
||||
if bill_no and bill_no[0][0] and bill_no[0][0].lower().strip() \
|
||||
not in ['na', 'not applicable', 'none']:
|
||||
r.append('%s %s against Bill %s dated %s' %
|
||||
(cstr(bill_no[0][2]), fmt_money(flt(d.debit)), bill_no[0][0],
|
||||
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d')) or ''))
|
||||
r.append(_('{0} {1} against Bill {2} dated {3}').format(bill_no[0][2],
|
||||
fmt_money(flt(d.debit)), bill_no[0][0],
|
||||
bill_no[0][1] and formatdate(bill_no[0][1].strftime('%Y-%m-%d'))))
|
||||
|
||||
if self.user_remark:
|
||||
r.append(_("Note: {0}").format(self.user_remark))
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import cstr, flt
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
|
||||
@ -16,37 +16,35 @@ class PeriodClosingVoucher(AccountsController):
|
||||
self.make_gl_entries()
|
||||
|
||||
def on_cancel(self):
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
where voucher_type = 'Period Closing Voucher' and voucher_no=%s""", self.name)
|
||||
|
||||
def validate_account_head(self):
|
||||
if frappe.db.get_value("Account", self.closing_account_head, "report_type") \
|
||||
!= "Balance Sheet":
|
||||
frappe.throw(_("Account") + ": " + self.closing_account_head +
|
||||
_("must be a Liability account"))
|
||||
frappe.throw(_("Closing Account {0} must be of type 'Liability'").format(self.closing_account_head))
|
||||
|
||||
def validate_posting_date(self):
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
self.year_start_date = get_fiscal_year(self.posting_date, self.fiscal_year)[1]
|
||||
|
||||
pce = frappe.db.sql("""select name from `tabPeriod Closing Voucher`
|
||||
where posting_date > %s and fiscal_year = %s and docstatus = 1""",
|
||||
where posting_date > %s and fiscal_year = %s and docstatus = 1""",
|
||||
(self.posting_date, self.fiscal_year))
|
||||
if pce and pce[0][0]:
|
||||
frappe.throw(_("Another Period Closing Entry") + ": " + cstr(pce[0][0]) +
|
||||
_("has been made after posting date") + ": " + self.posting_date)
|
||||
|
||||
frappe.throw(_("Another Period Closing Entry {0} has been made after {1}").format(pce[0][0], self.posting_date))
|
||||
|
||||
def get_pl_balances(self):
|
||||
"""Get balance for pl accounts"""
|
||||
return frappe.db.sql("""
|
||||
select t1.account, sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) as balance
|
||||
from `tabGL Entry` t1, `tabAccount` t2
|
||||
from `tabGL Entry` t1, `tabAccount` t2
|
||||
where t1.account = t2.name and ifnull(t2.report_type, '') = 'Profit and Loss'
|
||||
and t2.docstatus < 2 and t2.company = %s
|
||||
and t1.posting_date between %s and %s
|
||||
and t2.docstatus < 2 and t2.company = %s
|
||||
and t1.posting_date between %s and %s
|
||||
group by t1.account
|
||||
""", (self.company, self.get("year_start_date"), self.posting_date), as_dict=1)
|
||||
|
||||
|
||||
def make_gl_entries(self):
|
||||
gl_entries = []
|
||||
net_pl_balance = 0
|
||||
@ -58,7 +56,7 @@ class PeriodClosingVoucher(AccountsController):
|
||||
"debit": abs(flt(acc.balance)) if flt(acc.balance) < 0 else 0,
|
||||
"credit": abs(flt(acc.balance)) if flt(acc.balance) > 0 else 0,
|
||||
}))
|
||||
|
||||
|
||||
net_pl_balance += flt(acc.balance)
|
||||
|
||||
if net_pl_balance:
|
||||
@ -67,6 +65,6 @@ class PeriodClosingVoucher(AccountsController):
|
||||
"debit": abs(net_pl_balance) if net_pl_balance > 0 else 0,
|
||||
"credit": abs(net_pl_balance) if net_pl_balance < 0 else 0
|
||||
}))
|
||||
|
||||
|
||||
from erpnext.accounts.general_ledger import make_gl_entries
|
||||
make_gl_entries(gl_entries)
|
||||
|
@ -9,16 +9,15 @@ from frappe import throw, _
|
||||
from frappe.model.controller import DocListController
|
||||
|
||||
class PricingRule(DocListController):
|
||||
|
||||
def validate(self):
|
||||
self.validate_mandatory()
|
||||
self.cleanup_fields_value()
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
val = self.get("applicable_for")
|
||||
if val and not self.get(frappe.scrub(val)):
|
||||
throw(_("{0} is required").format(val), frappe.MandatoryError)
|
||||
tocheck = frappe.scrub(self.get(field) or "")
|
||||
if tocheck and not self.get(tocheck):
|
||||
throw(_("{0} is required").format(self.meta.get_label(tocheck)), frappe.MandatoryError)
|
||||
|
||||
def cleanup_fields_value(self):
|
||||
for logic_field in ["apply_on", "applicable_for", "price_or_discount"]:
|
||||
|
@ -95,7 +95,7 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
if not self.remarks and self.bill_date:
|
||||
self.remarks = (self.remarks or '') + "\n" \
|
||||
+ _("Against Bill %s dated %s").format(self.bill_no, formatdate(self.bill_date))
|
||||
+ _("Against Bill {0} dated {1}").format(self.bill_no, formatdate(self.bill_date))
|
||||
|
||||
if not self.remarks:
|
||||
self.remarks = "No Remarks"
|
||||
|
@ -85,8 +85,7 @@ def make_entry(args, adv_adj, update_outstanding):
|
||||
|
||||
def validate_total_debit_credit(total_debit, total_credit):
|
||||
if abs(total_debit - total_credit) > 0.005:
|
||||
frappe.throw(_("Debit and Credit not equal for this voucher: Diff (Debit) is ") +
|
||||
cstr(total_debit - total_credit))
|
||||
frappe.throw(_("Debit and Credit not equal for this voucher. Difference is {0}.").format(total_debit - total_credit))
|
||||
|
||||
def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
if gl_map[0].voucher_type=="Journal Voucher":
|
||||
@ -95,9 +94,7 @@ def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
|
||||
for entry in gl_map:
|
||||
if entry.account in aii_accounts:
|
||||
frappe.throw(_("Account") + ": " + entry.account +
|
||||
_(" can only be debited/credited through Stock transactions"),
|
||||
StockAccountInvalidTransaction)
|
||||
frappe.throw(_("Account {0} can only be updated via Stock Transactions"), StockAccountInvalidTransaction)
|
||||
|
||||
|
||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
@ -121,5 +118,5 @@ def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
validate_expense_against_budget(entry)
|
||||
|
||||
if entry.get("against_voucher") and update_outstanding == 'Yes':
|
||||
update_outstanding_amt(entry["account"], entry.get("against_voucher_type"),
|
||||
entry.get("against_voucher"), on_cancel=True)
|
||||
update_outstanding_amt(entry["account"], entry.get("against_voucher_type"),
|
||||
entry.get("against_voucher"), on_cancel=True)
|
||||
|
@ -225,7 +225,7 @@ def remove_against_link_from_jv(ref_type, ref_no, against_field):
|
||||
and voucher_no != ifnull(against_voucher, '')""",
|
||||
(now(), frappe.session.user, ref_type, ref_no))
|
||||
|
||||
frappe.msgprint(_("Following Journal Vouchers Unlinked: {0}".format("\n".join(linked_jv))))
|
||||
frappe.msgprint(_("Journal Vouchers {0} are un-linked".format("\n".join(linked_jv))))
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@ -233,9 +233,7 @@ def get_company_default(company, fieldname):
|
||||
value = frappe.db.get_value("Company", company, fieldname)
|
||||
|
||||
if not value:
|
||||
throw(_("Please mention default value for '") +
|
||||
_(frappe.get_meta("Company").get_label(fieldname) +
|
||||
_("' in Company: ") + company))
|
||||
throw(_("Please set default value {0} in Company {0}").format(frappe.get_meta("Company").get_label(fieldname), company))
|
||||
|
||||
return value
|
||||
|
||||
|
@ -281,8 +281,7 @@ class SellingController(StockController):
|
||||
discount = flt(frappe.db.get_value("Item", d.item_code, "max_discount"))
|
||||
|
||||
if discount and flt(d.discount_percentage) > discount:
|
||||
frappe.throw(_("You cannot give more than ") + cstr(discount) + "% " +
|
||||
_("discount on Item Code") + ": " + cstr(d.item_code))
|
||||
frappe.throw(_("Maxiumm discount for Item {0} is {1}%").format(d.item_code, discount))
|
||||
|
||||
def get_item_list(self):
|
||||
il = []
|
||||
@ -293,8 +292,7 @@ class SellingController(StockController):
|
||||
if self.doctype == "Sales Order":
|
||||
if (frappe.db.get_value("Item", d.item_code, "is_stock_item") == 'Yes' or
|
||||
self.has_sales_bom(d.item_code)) and not d.warehouse:
|
||||
frappe.throw(_("Please enter Reserved Warehouse for item ") +
|
||||
d.item_code + _(" as it is stock Item or packing item"))
|
||||
frappe.throw(_("Reserved Warehouse required for stock Item {0} in row {1}").format(d.item, d.idx))
|
||||
reserved_warehouse = d.warehouse
|
||||
if flt(d.qty) > flt(d.delivered_qty):
|
||||
reserved_qty_for_main_item = flt(d.qty) - flt(d.delivered_qty)
|
||||
@ -373,7 +371,7 @@ def check_active_sales_items(obj):
|
||||
is_service_item, income_account from tabItem where name = %s""",
|
||||
d.item_code, as_dict=True)[0]
|
||||
if item.is_sales_item == 'No' and item.is_service_item == 'No':
|
||||
frappe.throw(_("Item is neither Sales nor Service Item") + ": " + d.item_code)
|
||||
frappe.throw(_("Item {0} must be Sales or Service Item in {1}").format(d.item_code, d.idx))
|
||||
if getattr(d, "income_account", None) and not item.income_account:
|
||||
frappe.db.set_value("Item", d.item_code, "income_account",
|
||||
d.income_account)
|
||||
|
@ -45,6 +45,8 @@ class StockController(AccountsController):
|
||||
for sle in sle_list:
|
||||
if warehouse_account.get(sle.warehouse):
|
||||
# from warehouse account
|
||||
self.check_expense_account(detail)
|
||||
|
||||
gl_list.append(self.get_gl_dict({
|
||||
"account": warehouse_account[sle.warehouse],
|
||||
"against": detail.expense_account,
|
||||
@ -73,8 +75,6 @@ class StockController(AccountsController):
|
||||
def get_voucher_details(self, stock_ledger, default_expense_account, default_cost_center):
|
||||
if not default_expense_account:
|
||||
details = self.get(self.fname)
|
||||
for d in details:
|
||||
self.check_expense_account(d)
|
||||
else:
|
||||
details = [frappe._dict({
|
||||
"name":d,
|
||||
@ -231,10 +231,10 @@ class StockController(AccountsController):
|
||||
|
||||
def check_expense_account(self, item):
|
||||
if item.meta.get_field("expense_account") and not item.expense_account:
|
||||
frappe.throw(_("Expense or Difference account is mandatory for Item {0}").format(item.item_code))
|
||||
frappe.throw(_("Expense or Difference account is mandatory for Item {0} as there is difference in value").format(item.item_code))
|
||||
|
||||
if item.meta.get_field("expense_account") and not item.cost_center:
|
||||
frappe.throw(_("""Cost Center is mandatory for item {0}""").format(item.item_code))
|
||||
if getattr(item, "expense_account", None) and not item.cost_center:
|
||||
frappe.throw(_("""Cost Center is mandatory for Item {0}""").format(item.item_code))
|
||||
|
||||
def get_sl_entries(self, d, args):
|
||||
sl_dict = {
|
||||
|
@ -6,10 +6,6 @@ import frappe
|
||||
|
||||
from frappe.utils import cint, cstr, flt, nowdate, comma_and
|
||||
from frappe import msgprint, _
|
||||
|
||||
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
class LeaveControlPanel(Document):
|
||||
@ -33,7 +29,7 @@ class LeaveControlPanel(Document):
|
||||
def validate_values(self):
|
||||
for f in ["fiscal_year", "leave_type", "no_of_days"]:
|
||||
if not self.get(f):
|
||||
frappe.throw(_(self.meta.get_label(f)) + _(" is mandatory"))
|
||||
frappe.throw(_("{0} is required").format(self.meta.get_label(f)))
|
||||
|
||||
def allocate_leave(self):
|
||||
self.validate_values()
|
||||
|
@ -4,7 +4,7 @@
|
||||
var display_activity_log = function(msg) {
|
||||
if(!pscript.ss_html)
|
||||
pscript.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper,'div');
|
||||
pscript.ss_html.innerHTML =
|
||||
pscript.ss_html.innerHTML =
|
||||
'<div class="panel"><div class="panel-heading">'+__("Activity Log:")+'</div>'+msg+'</div>';
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ cur_frm.cscript.create_salary_slip = function(doc, cdt, cdn) {
|
||||
}
|
||||
|
||||
cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
|
||||
var check = confirm(__("Do you really want to Submit all Salary Slip for month : ") + doc.month+ __(" and fiscal year : ")+doc.fiscal_year);
|
||||
var check = confirm(__("Do you really want to Submit all Salary Slip for month {0} and year {1}", [doc.month, doc.fiscal_year]));
|
||||
if(check){
|
||||
var callback = function(r, rt){
|
||||
if (r.message)
|
||||
@ -42,8 +42,7 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) {
|
||||
var jv = frappe.model.make_new_doc_and_get_name('Journal Voucher');
|
||||
jv = locals['Journal Voucher'][jv];
|
||||
jv.voucher_type = 'Bank Voucher';
|
||||
jv.user_remark = __('Payment of salary for the month: ') + doc.month +
|
||||
__(' and fiscal year: ') + doc.fiscal_year;
|
||||
jv.user_remark = __('Payment of salary for the month {0} and year {1}', [doc.month, doc.fiscal_year]);
|
||||
jv.fiscal_year = doc.fiscal_year;
|
||||
jv.company = doc.company;
|
||||
jv.posting_date = dateutil.obj_to_str(new Date());
|
||||
|
@ -180,7 +180,7 @@ class BOM(Document):
|
||||
""" Validate main FG item"""
|
||||
item = self.get_item_det(self.item)
|
||||
if not item:
|
||||
frappe.throw(_("Item {0} does not exists in the system or has expired").format(self.item))
|
||||
frappe.throw(_("Item {0} does not exist in the system or has expired").format(self.item))
|
||||
elif item[0]['is_manufactured_item'] != 'Yes' \
|
||||
and item[0]['is_sub_contracted_item'] != 'Yes':
|
||||
frappe.throw(_("Item {0} must be manufactured or sub-contracted").format(self.item))
|
||||
|
@ -1,234 +1,667 @@
|
||||
{
|
||||
"_last_update": null,
|
||||
"_user_tags": null,
|
||||
"allow_attach": null,
|
||||
"allow_copy": null,
|
||||
"allow_email": null,
|
||||
"allow_import": 1,
|
||||
"allow_print": null,
|
||||
"allow_rename": null,
|
||||
"allow_trash": null,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-10 16:34:16.000000",
|
||||
"change_log": null,
|
||||
"client_script": null,
|
||||
"client_script_core": null,
|
||||
"client_string": null,
|
||||
"colour": null,
|
||||
"creation": "2013-01-10 16:34:16",
|
||||
"custom": null,
|
||||
"default_print_format": null,
|
||||
"description": null,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": null,
|
||||
"dt_template": null,
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "item",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Item",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "icon-gift",
|
||||
"permlevel": 0
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": "PRO",
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Series",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "\nPRO",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"description": "Bill of Material to be considered for manufacturing",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "BOM No",
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"label": "Use Multi-Level BOM",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"label": "Sales Order",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Qty To Manufacture",
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"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,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "sales_order",
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Expected Delivery Date",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Warehouses",
|
||||
"options": "icon-building",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "production_item",
|
||||
"description": "Manufactured quantity will be updated in this warehouse",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "For Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "eval:!doc.__islocal",
|
||||
"description": null,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Status",
|
||||
"no_column": null,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "status",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nDraft\nSubmitted\nStopped\nIn Process\nCompleted\nCancelled",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
"search_index": 1,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "production_item",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item To Manufacture",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "production_item",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Item",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "production_item",
|
||||
"description": "Bill of Material to be considered for manufacturing",
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "BOM No",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "bom_no",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "BOM",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": "1",
|
||||
"depends_on": null,
|
||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
||||
"fieldname": "use_multi_level_bom",
|
||||
"fieldtype": "Check",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Use Multi-Level BOM",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": null,
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": "Column Break",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": "Manufacture against Sales Order",
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Sales Order",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "production_item",
|
||||
"description": null,
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 1,
|
||||
"label": "Qty To Manufacture",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"description": "Automatically updated via Stock Entry of type Manufacture/Repack",
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Manufactured Qty",
|
||||
"no_column": null,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "produced_qty",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "sales_order",
|
||||
"description": null,
|
||||
"fieldname": "expected_delivery_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Expected Delivery Date",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "warehouses",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Warehouses",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "icon-building",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "production_item",
|
||||
"description": "Manufactured quantity will be updated in this warehouse",
|
||||
"fieldname": "fg_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": 0,
|
||||
"label": "For Warehouse",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": 0,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": null,
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "wip_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Work-in-Progress Warehouse",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": null,
|
||||
"report_hide": null,
|
||||
"reqd": 0,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "More Info",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Item Description",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "project_name",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": 1,
|
||||
"in_list_view": null,
|
||||
"label": "Project Name",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "project_name",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": null,
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": null,
|
||||
"oldfieldtype": null,
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": "production_item",
|
||||
"description": null,
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Stock UOM",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "stock_uom",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "UOM",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": null,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Company",
|
||||
"no_column": null,
|
||||
"no_copy": null,
|
||||
"oldfieldname": "company",
|
||||
"oldfieldtype": "Link",
|
||||
"options": "Company",
|
||||
"permlevel": 0,
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
"report_hide": null,
|
||||
"reqd": 1,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
},
|
||||
{
|
||||
"allow_on_submit": null,
|
||||
"default": null,
|
||||
"depends_on": null,
|
||||
"description": null,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Data",
|
||||
"hidden": null,
|
||||
"ignore_restrictions": 1,
|
||||
"in_filter": null,
|
||||
"in_list_view": null,
|
||||
"label": "Amended From",
|
||||
"no_column": null,
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "amended_from",
|
||||
"oldfieldtype": "Data",
|
||||
"options": null,
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
"print_hide": null,
|
||||
"print_width": null,
|
||||
"read_only": 1,
|
||||
"report_hide": null,
|
||||
"reqd": null,
|
||||
"search_index": null,
|
||||
"set_only_once": null,
|
||||
"trigger": null,
|
||||
"width": null
|
||||
}
|
||||
],
|
||||
"hide_heading": null,
|
||||
"hide_toolbar": null,
|
||||
"icon": "icon-cogs",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": null,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-01-20 17:49:01.000000",
|
||||
"is_transaction_doc": null,
|
||||
"issingle": null,
|
||||
"istable": null,
|
||||
"max_attachments": null,
|
||||
"menu_index": null,
|
||||
"modified": "2014-04-16 11:31:11.764385",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Order",
|
||||
"name_case": null,
|
||||
"owner": "Administrator",
|
||||
"parent": null,
|
||||
"parent_node": null,
|
||||
"parentfield": null,
|
||||
"parenttype": null,
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
@ -236,13 +669,35 @@
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": null,
|
||||
"import": null,
|
||||
"match": null,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"restrict": null,
|
||||
"restricted": null,
|
||||
"role": "Manufacturing User",
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugin": null,
|
||||
"print_outline": null,
|
||||
"read_only": null,
|
||||
"read_only_onload": null,
|
||||
"search_fields": null,
|
||||
"section_style": null,
|
||||
"server_code": null,
|
||||
"server_code_compiled": null,
|
||||
"server_code_core": null,
|
||||
"server_code_error": null,
|
||||
"show_in_menu": null,
|
||||
"smallicon": null,
|
||||
"subject": null,
|
||||
"tag_fields": null,
|
||||
"title_field": null,
|
||||
"use_template": null,
|
||||
"version": null
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
from frappe.utils import cstr, flt, nowdate
|
||||
from frappe.utils import flt, nowdate
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
@ -75,11 +75,8 @@ class ProductionOrder(Document):
|
||||
so_qty = flt(so_item_qty) + flt(dnpi_qty)
|
||||
|
||||
if total_qty > so_qty:
|
||||
frappe.throw(_("Total production order qty for item") + ": " +
|
||||
cstr(self.production_item) + _(" against sales order") + ": " +
|
||||
cstr(self.sales_order) + _(" will be ") + cstr(total_qty) + ", " +
|
||||
_("which is greater than sales order qty ") + "(" + cstr(so_qty) + ")" +
|
||||
_("Please reduce qty."), exc=OverProductionError)
|
||||
frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}").format(self.production_item,
|
||||
so_qty), OverProductionError)
|
||||
|
||||
def stop_unstop(self, status):
|
||||
""" Called from client side on Stop/Unstop event"""
|
||||
@ -115,7 +112,7 @@ class ProductionOrder(Document):
|
||||
produced_qty = flt(produced_qty[0][0]) if produced_qty else 0
|
||||
|
||||
if produced_qty > self.qty:
|
||||
frappe.throw(_("Cannot manufacture more than the planned Quantity to Manufacture ({0}) in Production Order: {1}").format(self.qty, self.name), StockOverProductionError)
|
||||
frappe.throw(_("Manufactured quantity {0} cannot be greater than planned quanitity {1} in Production Order {2}").format(produced_qty, self.qty, self.name, StockOverProductionError))
|
||||
|
||||
self.db_set("produced_qty", produced_qty)
|
||||
|
||||
@ -167,7 +164,7 @@ def get_item_details(item):
|
||||
return res
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_stock_entry(production_order_id, purpose):
|
||||
def make_stock_entry(production_order_id, purpose, qty=None):
|
||||
production_order = frappe.get_doc("Production Order", production_order_id)
|
||||
|
||||
stock_entry = frappe.new_doc("Stock Entry")
|
||||
@ -176,7 +173,7 @@ def make_stock_entry(production_order_id, purpose):
|
||||
stock_entry.company = production_order.company
|
||||
stock_entry.bom_no = production_order.bom_no
|
||||
stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
|
||||
stock_entry.fg_completed_qty = flt(production_order.qty) - flt(production_order.produced_qty)
|
||||
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
|
||||
|
||||
if purpose=="Material Transfer":
|
||||
stock_entry.to_warehouse = production_order.wip_warehouse
|
||||
|
@ -5,7 +5,6 @@
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
from frappe.utils import cstr, getdate
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry
|
||||
|
||||
@ -13,56 +12,69 @@ from erpnext.manufacturing.doctype.production_order.production_order import make
|
||||
class TestProductionOrder(unittest.TestCase):
|
||||
def test_planned_qty(self):
|
||||
set_perpetual_inventory(0)
|
||||
frappe.db.sql("delete from `tabStock Ledger Entry`")
|
||||
frappe.db.sql("""delete from `tabBin`""")
|
||||
frappe.db.sql("""delete from `tabGL Entry`""")
|
||||
|
||||
pro_doc = frappe.copy_doc(test_records[0])
|
||||
pro_doc.insert()
|
||||
pro_doc.submit()
|
||||
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import test_records as se_test_records
|
||||
mr1 = frappe.copy_doc(se_test_records[0])
|
||||
mr1.insert()
|
||||
mr1.submit()
|
||||
# add raw materials to stores
|
||||
s = frappe.new_doc("Stock Entry")
|
||||
s.purpose = "Material Receipt"
|
||||
s.company = "_Test Company"
|
||||
s.append("mtn_details", {
|
||||
"item_code": "_Test Item",
|
||||
"t_warehouse": "Stores - _TC",
|
||||
"qty": 100,
|
||||
"incoming_rate": 5000
|
||||
})
|
||||
s.insert()
|
||||
s.submit()
|
||||
|
||||
mr2 = frappe.copy_doc(se_test_records[0])
|
||||
mr2.get("mtn_details")[0].item_code = "_Test Item Home Desktop 100"
|
||||
mr2.insert()
|
||||
mr2.submit()
|
||||
# add raw materials to stores
|
||||
s = frappe.new_doc("Stock Entry")
|
||||
s.purpose = "Material Receipt"
|
||||
s.company = "_Test Company"
|
||||
s.append("mtn_details", {
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"t_warehouse": "Stores - _TC",
|
||||
"qty": 100,
|
||||
"incoming_rate": 1000
|
||||
})
|
||||
s.insert()
|
||||
s.submit()
|
||||
|
||||
stock_entry = make_stock_entry(pro_doc.name, "Manufacture/Repack")
|
||||
stock_entry = frappe.get_doc(stock_entry)
|
||||
stock_entry.fiscal_year = "_Test Fiscal Year 2013"
|
||||
stock_entry.fg_completed_qty = 4
|
||||
stock_entry.posting_date = "2013-05-12"
|
||||
stock_entry.fiscal_year = "_Test Fiscal Year 2013"
|
||||
stock_entry.set("mtn_details", [])
|
||||
stock_entry.run_method("get_items")
|
||||
stock_entry.submit()
|
||||
# from stores to wip
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 4))
|
||||
for d in s.get("mtn_details"):
|
||||
d.s_warehouse = "Stores - _TC"
|
||||
s.insert()
|
||||
s.submit()
|
||||
|
||||
# from wip to fg
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture/Repack", 4))
|
||||
s.insert()
|
||||
s.submit()
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name,
|
||||
"produced_qty"), 4)
|
||||
self.assertEqual(frappe.db.get_value("Bin", {"item_code": "_Test FG Item",
|
||||
"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"), 6)
|
||||
|
||||
return pro_doc.name
|
||||
return pro_doc
|
||||
|
||||
def test_over_production(self):
|
||||
from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError
|
||||
pro_order = self.test_planned_qty()
|
||||
pro_doc = self.test_planned_qty()
|
||||
|
||||
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
|
||||
stock_entry = frappe.get_doc(stock_entry)
|
||||
stock_entry.posting_date = "2013-05-12"
|
||||
stock_entry.fiscal_year = "_Test Fiscal Year 2013"
|
||||
stock_entry.fg_completed_qty = 15
|
||||
stock_entry.set("mtn_details", [])
|
||||
stock_entry.run_method("get_items")
|
||||
stock_entry.insert()
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 7))
|
||||
for d in s.get("mtn_details"):
|
||||
d.s_warehouse = "Stores - _TC"
|
||||
s.insert()
|
||||
s.submit()
|
||||
|
||||
self.assertRaises(StockOverProductionError, stock_entry.submit)
|
||||
s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture/Repack", 7))
|
||||
s.insert()
|
||||
|
||||
self.assertRaises(StockOverProductionError, s.submit)
|
||||
|
||||
|
||||
test_records = frappe.get_test_records('Production Order')
|
||||
|
@ -11,13 +11,13 @@ $.extend(erpnext, {
|
||||
else
|
||||
return frappe.boot.sysdefaults.currency;
|
||||
},
|
||||
|
||||
|
||||
hide_naming_series: function() {
|
||||
if(cur_frm.fields_dict.naming_series && !frappe.meta.get_docfield(cur_frm.doctype, "naming_series")) {
|
||||
if(cur_frm.fields_dict.naming_series) {
|
||||
cur_frm.toggle_display("naming_series", cur_frm.doc.__islocal?true:false);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
hide_company: function() {
|
||||
if(cur_frm.fields_dict.company) {
|
||||
var companies = Object.keys(locals[":Company"] || {});
|
||||
@ -27,28 +27,28 @@ $.extend(erpnext, {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
add_applicable_territory: function() {
|
||||
if(cur_frm.doc.__islocal && (cur_frm.doc.valid_for_territories || []).length===0) {
|
||||
var default_territory = frappe.defaults.get_user_default("territory");
|
||||
if(default_territory) {
|
||||
var territory = frappe.model.add_child(cur_frm.doc, "Applicable Territory",
|
||||
var territory = frappe.model.add_child(cur_frm.doc, "Applicable Territory",
|
||||
"valid_for_territories");
|
||||
territory.territory = default_territory;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
setup_serial_no: function(grid_row) {
|
||||
if(!grid_row.fields_dict.serial_no ||
|
||||
if(!grid_row.fields_dict.serial_no ||
|
||||
grid_row.fields_dict.serial_no.get_status()!=="Write") return;
|
||||
|
||||
|
||||
var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
|
||||
.appendTo($("<div>")
|
||||
.css({"margin-bottom": "10px", "margin-left": "15px"})
|
||||
.appendTo(grid_row.fields_dict.serial_no.$wrapper));
|
||||
|
||||
|
||||
$btn.on("click", function() {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Add Serial No"),
|
||||
@ -68,7 +68,7 @@ $.extend(erpnext, {
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
d.get_input("add").on("click", function() {
|
||||
var serial_no = d.get_value("serial_no");
|
||||
if(serial_no) {
|
||||
@ -78,8 +78,8 @@ $.extend(erpnext, {
|
||||
d.hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
d.show();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -162,5 +162,4 @@ def _make_customer(source_name, ignore_permissions=False):
|
||||
raise
|
||||
except frappe.MandatoryError:
|
||||
from frappe.utils import get_url_to_form
|
||||
frappe.throw(_("Before proceeding, please create Customer from Lead") + \
|
||||
(" - %s" % get_url_to_form("Lead", lead_name)))
|
||||
frappe.throw(_("Please create Customer from Lead {0}").format(lead_name))
|
||||
|
@ -7,7 +7,7 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
if(in_list(user_roles, "System Manager"))
|
||||
cur_frm.add_custom_button("Replace Abbreviation", cur_frm.cscript.replace_abbr)
|
||||
}
|
||||
|
||||
|
||||
if(!doc.__islocal) {
|
||||
cur_frm.toggle_enable("default_currency", !cur_frm.doc.__transactions_exist);
|
||||
}
|
||||
@ -60,42 +60,40 @@ cur_frm.cscript.has_special_chars = function(t) {
|
||||
}
|
||||
|
||||
cur_frm.cscript.company_name = function(doc){
|
||||
if(doc.company_name && cur_frm.cscript.has_special_chars(doc.company_name)){
|
||||
msgprint(("<font color=red>"+__("Special Characters")+" <b>! @ # $ % ^ * + = - [ ] ' ; , / { } | : < > ?</b> "+
|
||||
__("are not allowed for ")+"</font>\n"+__("Company Name")+" <b> "+ doc.company_name +"</b>"))
|
||||
doc.company_name = '';
|
||||
refresh_field('company_name');
|
||||
}
|
||||
if(doc.company_name && cur_frm.cscript.has_special_chars(doc.company_name)){
|
||||
msgprint(__("Special Characters not allowed in Company Name"));
|
||||
doc.company_name = '';
|
||||
refresh_field('company_name');
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.abbr = function(doc){
|
||||
if(doc.abbr && cur_frm.cscript.has_special_chars(doc.abbr)){
|
||||
msgprint("<font color=red>"+__("Special Characters ")+"<b>! @ # $ % ^ * + = - [ ] ' ; , / { } | : < > ?</b>" +
|
||||
__("are not allowed for")+ "</font>\nAbbr <b>" + doc.abbr +"</b>")
|
||||
doc.abbr = '';
|
||||
refresh_field('abbr');
|
||||
}
|
||||
if(doc.abbr && cur_frm.cscript.has_special_chars(doc.abbr)){
|
||||
msgprint(__("Special Characters not allowed in Abbreviation"));
|
||||
doc.abbr = '';
|
||||
refresh_field('abbr');
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_bank_account.get_query = function(doc) {
|
||||
cur_frm.fields_dict.default_bank_account.get_query = function(doc) {
|
||||
return{
|
||||
filters: [
|
||||
['Account', 'account_type', 'in', 'Bank, Cash'],
|
||||
['Account', 'group_or_ledger', '=', 'Ledger'],
|
||||
['Account', 'company', '=', doc.name]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_cash_account.get_query = cur_frm.fields_dict.default_bank_account.get_query;
|
||||
|
||||
cur_frm.fields_dict.receivables_group.get_query = function(doc) {
|
||||
cur_frm.fields_dict.receivables_group.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
'group_or_ledger': "Group"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.get_field("chart_of_accounts").get_query = function(doc) {
|
||||
@ -109,33 +107,33 @@ cur_frm.get_field("chart_of_accounts").get_query = function(doc) {
|
||||
cur_frm.fields_dict.payables_group.get_query = cur_frm.fields_dict.receivables_group.get_query;
|
||||
|
||||
|
||||
cur_frm.fields_dict.default_expense_account.get_query = function(doc) {
|
||||
cur_frm.fields_dict.default_expense_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
'group_or_ledger': "Ledger",
|
||||
"report_type": "Profit and Loss"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_income_account.get_query = function(doc) {
|
||||
cur_frm.fields_dict.default_income_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
'group_or_ledger': "Ledger",
|
||||
"report_type": "Profit and Loss"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.cost_center.get_query = function(doc) {
|
||||
cur_frm.fields_dict.cost_center.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
'group_or_ledger': "Ledger",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sys_defaults.auto_accounting_for_stock) {
|
||||
@ -149,7 +147,7 @@ if (sys_defaults.auto_accounting_for_stock) {
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict["expenses_included_in_valuation"].get_query =
|
||||
cur_frm.fields_dict["expenses_included_in_valuation"].get_query =
|
||||
cur_frm.fields_dict["stock_adjustment_account"].get_query;
|
||||
|
||||
cur_frm.fields_dict["stock_received_but_not_billed"].get_query = function(doc) {
|
||||
@ -161,4 +159,4 @@ if (sys_defaults.auto_accounting_for_stock) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ if(cur_frm.fields_dict['territory']) {
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc, dt, dn) {
|
||||
return {
|
||||
filters: {
|
||||
'is_group': "No"
|
||||
'is_group': "No"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,10 +26,10 @@ if(cur_frm.fields_dict['territory']) {
|
||||
|
||||
cur_frm.cscript.render_contact_row = function(wrapper, data) {
|
||||
// prepare data
|
||||
data.fullname = (data.first_name || '')
|
||||
data.fullname = (data.first_name || '')
|
||||
+ (data.last_name ? ' ' + data.last_name : '');
|
||||
data.primary = data.is_primary_contact ? ' [Primary]' : '';
|
||||
|
||||
|
||||
// prepare description
|
||||
var description = [];
|
||||
$.each([
|
||||
@ -136,10 +136,7 @@ cur_frm.cscript.render_row_in_wrapper = function(wrapper, data, doctype) {
|
||||
|
||||
cur_frm.cscript.delete_doc = function(doctype, name) {
|
||||
// confirm deletion
|
||||
var go_ahead = confirm(repl('Delete %(doctype)s "%(name)s"', {
|
||||
doctype: doctype,
|
||||
name: name
|
||||
}));
|
||||
var go_ahead = confirm(__("Delete {0} {1}?", [doctype, name]));
|
||||
if (!go_ahead) return;
|
||||
|
||||
return frappe.call({
|
||||
@ -183,4 +180,4 @@ cur_frm.cscript.render_list = function(doc, doctype, wrapper, ListView, make_new
|
||||
cur_frm[doctype.toLowerCase().replace(" ", "_") + "_list"] = record_list_view;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ class Item(WebsiteGenerator):
|
||||
if merge:
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Item", newdn):
|
||||
frappe.throw(_("Item ") + newdn +_(" does not exists"))
|
||||
frappe.throw(_("Item {0} does not exist").format(newdn))
|
||||
|
||||
field_list = ["stock_uom", "is_stock_item", "has_serial_no", "has_batch_no"]
|
||||
new_properties = [cstr(d) for d in frappe.db.get_value("Item", newdn, field_list)]
|
||||
|
@ -27,7 +27,7 @@ class LandedCostWizard(Document):
|
||||
def validate_purchase_receipts(self, purchase_receipts):
|
||||
for pr in purchase_receipts:
|
||||
if frappe.db.get_value("Purchase Receipt", pr, "docstatus") != 1:
|
||||
frappe.throw(_("Purchase Receipt") + ": " + pr + _(" is not submitted document"))
|
||||
frappe.throw(_("Purchase Receipt {0} is not submitted").format(pr))
|
||||
|
||||
def add_charges_in_pr(self, purchase_receipts):
|
||||
""" Add additional charges in selected pr proportionately"""
|
||||
|
@ -168,9 +168,8 @@ def update_completed_qty(doc, method):
|
||||
mr_obj = frappe.get_doc("Material Request", mr_name)
|
||||
|
||||
if mr_obj.status in ["Stopped", "Cancelled"]:
|
||||
frappe.throw(_("Material Request") + ": %s, " % mr_obj.name
|
||||
+ _(mr_obj.meta.get_label("status")) + " = %s. " % _(mr_obj.status)
|
||||
+ _("Cannot continue."), exc=frappe.InvalidStatusError)
|
||||
frappe.throw(_("Material Request {0} is cancelled or stopped").format(mr_obj.name),
|
||||
frappe.InvalidStatusError)
|
||||
|
||||
_update_requested_qty(doc, mr_obj, mr_items)
|
||||
|
||||
|
@ -67,7 +67,7 @@ class SerialNo(StockController):
|
||||
"""
|
||||
item = frappe.get_doc("Item", self.item_code)
|
||||
if item.has_serial_no!="Yes":
|
||||
frappe.throw(_("Item must have 'Has Serial No' as 'Yes'") + ": " + self.item_code)
|
||||
frappe.throw(_("Item {0} is not setup for Serial Nos. Check Item master").format(self.item_code))
|
||||
|
||||
self.item_group = item.item_group
|
||||
self.description = item.description
|
||||
@ -163,9 +163,9 @@ class SerialNo(StockController):
|
||||
|
||||
def on_trash(self):
|
||||
if self.status == 'Delivered':
|
||||
frappe.throw(_("Delivered Serial No ") + self.name + _(" can not be deleted"))
|
||||
frappe.throw(_("Delivered Serial No {0} cannot be deleted").format(self.name))
|
||||
if self.warehouse:
|
||||
frappe.throw(_("Cannot delete Serial No in warehouse. First remove from warehouse, then delete.") + ": " + self.name)
|
||||
frappe.throw(_("Cannot delete Serial No {0} in stock. First remove from stock, then delete.").format(self.name))
|
||||
|
||||
def before_rename(self, old, new, merge=False):
|
||||
if merge:
|
||||
@ -203,51 +203,49 @@ def process_serial_no(sle):
|
||||
def validate_serial_no(sle, item_det):
|
||||
if item_det.has_serial_no=="No":
|
||||
if sle.serial_no:
|
||||
frappe.throw(_("Serial Number should be blank for Non Serialized Item" + ": "
|
||||
+ sle.item_code), SerialNoNotRequiredError)
|
||||
frappe.throw(_("Item {0} is not setup for Serial Nos. Column must be blank").format(sle.item_code),
|
||||
SerialNoNotRequiredError)
|
||||
else:
|
||||
if sle.serial_no:
|
||||
serial_nos = get_serial_nos(sle.serial_no)
|
||||
if cint(sle.actual_qty) != flt(sle.actual_qty):
|
||||
frappe.throw(_("Serial No qty cannot be a fraction") + \
|
||||
(": %s (%s)" % (sle.item_code, sle.actual_qty)))
|
||||
frappe.throw(_("Serial No {0} quantity {1} cannot be a fraction").format(sle.item_code, sle.actual_qty))
|
||||
|
||||
if len(serial_nos) and len(serial_nos) != abs(cint(sle.actual_qty)):
|
||||
frappe.throw(_("Serial Nos do not match with qty") + \
|
||||
(": %s (%s)" % (sle.item_code, sle.actual_qty)), SerialNoQtyError)
|
||||
frappe.throw(_("{0} Serial Numbers required for Item {0}. Only {0} provided.").format(sle.actual_qty, sle.item_code, len(serial_nos)),
|
||||
SerialNoQtyError)
|
||||
|
||||
if len(serial_nos) != len(set(serial_nos)):
|
||||
frappe.throw(_("Duplicate Serial No entered against item") +
|
||||
(": %s" % sle.item_code), SerialNoDuplicateError)
|
||||
frappe.throw(_("Duplicate Serial No entered for Item {0}").format(sle.item_code), SerialNoDuplicateError)
|
||||
|
||||
for serial_no in serial_nos:
|
||||
if frappe.db.exists("Serial No", serial_no):
|
||||
sr = frappe.get_doc("Serial No", serial_no)
|
||||
|
||||
if sr.item_code!=sle.item_code:
|
||||
frappe.throw(_("Serial No does not belong to Item") +
|
||||
(": %s (%s)" % (sle.item_code, serial_no)), SerialNoItemError)
|
||||
frappe.throw(_("Serial No {0} does not belong to Item {1}").format(sle.item_code,
|
||||
serial_no), SerialNoItemError)
|
||||
|
||||
if sr.warehouse and sle.actual_qty > 0:
|
||||
frappe.throw(_("Same Serial No") + ": " + sr.name +
|
||||
_(" can not be received twice"), SerialNoDuplicateError)
|
||||
frappe.throw(_("Serial No {0} has already been received").format(sr.name),
|
||||
SerialNoDuplicateError)
|
||||
|
||||
if sle.actual_qty < 0:
|
||||
if sr.warehouse!=sle.warehouse:
|
||||
frappe.throw(_("Serial No") + ": " + serial_no +
|
||||
_(" does not belong to Warehouse") + ": " + sle.warehouse,
|
||||
SerialNoWarehouseError)
|
||||
frappe.throw(_("Serial No {0} does not belong to Warehouse {1}").format(serial_no,
|
||||
sle.warehouse), SerialNoWarehouseError)
|
||||
|
||||
if sle.voucher_type in ("Delivery Note", "Sales Invoice") \
|
||||
and sr.status != "Available":
|
||||
frappe.throw(_("Serial No status must be 'Available' to Deliver")
|
||||
+ ": " + serial_no, SerialNoStatusError)
|
||||
frappe.throw(_("Serial No {0} status must be 'Available' to Deliver").format(serial_no),
|
||||
SerialNoStatusError)
|
||||
|
||||
elif sle.actual_qty < 0:
|
||||
# transfer out
|
||||
frappe.throw(_("Serial No must exist to transfer out.") + \
|
||||
": " + serial_no, SerialNoNotExistsError)
|
||||
frappe.throw(_("Serial No {0} not in stock").format(serial_no), SerialNoNotExistsError)
|
||||
elif sle.actual_qty < 0 or not item_det.serial_no_series:
|
||||
frappe.throw(_("Serial Number Required for Serialized Item" + ": "
|
||||
+ sle.item_code), SerialNoRequiredError)
|
||||
frappe.throw(_("Serial Nos Required for Serialized Item {0}").format(sle.item_code),
|
||||
SerialNoRequiredError)
|
||||
|
||||
def update_serial_nos(sle, item_det):
|
||||
if sle.is_cancelled == "No" and not sle.serial_no and sle.actual_qty > 0 and item_det.serial_no_series:
|
||||
|
@ -10,22 +10,22 @@ frappe.provide("erpnext.stock");
|
||||
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
setup: function() {
|
||||
var me = this;
|
||||
|
||||
|
||||
this.frm.fields_dict.delivery_note_no.get_query = function() {
|
||||
return { query: "erpnext.stock.doctype.stock_entry.stock_entry.query_sales_return_doc" };
|
||||
};
|
||||
|
||||
this.frm.fields_dict.sales_invoice_no.get_query =
|
||||
|
||||
this.frm.fields_dict.sales_invoice_no.get_query =
|
||||
this.frm.fields_dict.delivery_note_no.get_query;
|
||||
|
||||
|
||||
this.frm.fields_dict.purchase_receipt_no.get_query = function() {
|
||||
return {
|
||||
return {
|
||||
filters:{ 'docstatus': 1 }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
this.frm.fields_dict.mtn_details.grid.get_field('item_code').get_query = function() {
|
||||
if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) &&
|
||||
if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) &&
|
||||
me.get_doctype_docname()) {
|
||||
return {
|
||||
query: "erpnext.stock.doctype.stock_entry.stock_entry.query_return_item",
|
||||
@ -40,13 +40,13 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
return erpnext.queries.item({is_stock_item: "Yes"});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if(cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
|
||||
this.frm.fields_dict.mtn_details.grid.get_field('expense_account').get_query =
|
||||
this.frm.fields_dict.mtn_details.grid.get_field('expense_account').get_query =
|
||||
function() {
|
||||
return {
|
||||
filters: {
|
||||
filters: {
|
||||
"company": me.frm.doc.company,
|
||||
"group_or_ledger": "Ledger"
|
||||
}
|
||||
@ -66,8 +66,8 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
this.toggle_enable_bom();
|
||||
this.show_stock_ledger();
|
||||
this.show_general_ledger();
|
||||
|
||||
if(this.frm.doc.docstatus === 1 &&
|
||||
|
||||
if(this.frm.doc.docstatus === 1 &&
|
||||
frappe.boot.user.can_create.indexOf("Journal Voucher")!==-1) {
|
||||
if(this.frm.doc.purpose === "Sales Return") {
|
||||
this.frm.add_custom_button(__("Make Credit Note"), function() { me.make_return_jv(); });
|
||||
@ -77,7 +77,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
this.add_excise_button();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
on_submit: function() {
|
||||
@ -90,22 +90,22 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
|
||||
set_default_account: function() {
|
||||
var me = this;
|
||||
|
||||
|
||||
if(cint(frappe.defaults.get_default("auto_accounting_for_stock"))) {
|
||||
var account_for = "stock_adjustment_account";
|
||||
|
||||
if (this.frm.doc.purpose == "Purchase Return")
|
||||
if (this.frm.doc.purpose == "Purchase Return")
|
||||
account_for = "stock_received_but_not_billed";
|
||||
|
||||
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.utils.get_company_default",
|
||||
args: {
|
||||
"fieldname": account_for,
|
||||
"fieldname": account_for,
|
||||
"company": this.frm.doc.company
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
$.each(doc.mtn_details || [], function(i, d) {
|
||||
$.each(me.frm.doc.mtn_details || [], function(i, d) {
|
||||
if(!d.expense_account) d.expense_account = r.message;
|
||||
});
|
||||
}
|
||||
@ -116,9 +116,9 @@ 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 &&
|
||||
if(this.frm.doc.production_order &&
|
||||
this.frm.doc.purpose == "Manufacture/Repack") {
|
||||
frappe.model.remove_from_locals("Production Order",
|
||||
frappe.model.remove_from_locals("Production Order",
|
||||
this.frm.doc.production_order);
|
||||
}
|
||||
},
|
||||
@ -145,7 +145,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
production_order: function() {
|
||||
var me = this;
|
||||
this.toggle_enable_bom();
|
||||
|
||||
|
||||
return this.frm.call({
|
||||
method: "get_production_order_details",
|
||||
args: {production_order: this.frm.doc.production_order},
|
||||
@ -167,26 +167,26 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
if(this.frm.doc.delivery_note_no && this.frm.doc.sales_invoice_no) {
|
||||
// both specified
|
||||
msgprint(__("You can not enter both Delivery Note No and Sales Invoice No. Please enter any one."));
|
||||
|
||||
|
||||
} else if(!(this.frm.doc.delivery_note_no || this.frm.doc.sales_invoice_no)) {
|
||||
// none specified
|
||||
msgprint(__("Please enter Delivery Note No or Sales Invoice No to proceed"));
|
||||
|
||||
|
||||
} else if(this.frm.doc.delivery_note_no) {
|
||||
return {doctype: "Delivery Note", docname: this.frm.doc.delivery_note_no};
|
||||
|
||||
|
||||
} else if(this.frm.doc.sales_invoice_no) {
|
||||
return {doctype: "Sales Invoice", docname: this.frm.doc.sales_invoice_no};
|
||||
|
||||
|
||||
}
|
||||
} else if(this.frm.doc.purpose === "Purchase Return") {
|
||||
if(this.frm.doc.purchase_receipt_no) {
|
||||
return {doctype: "Purchase Receipt", docname: this.frm.doc.purchase_receipt_no};
|
||||
|
||||
|
||||
} else {
|
||||
// not specified
|
||||
msgprint(__("Please enter Purchase Receipt No to proceed"));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -226,9 +226,9 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
|
||||
mtn_details_add: function(doc, cdt, cdn) {
|
||||
var row = frappe.get_doc(cdt, cdn);
|
||||
this.frm.script_manager.copy_from_first_row("mtn_details", row,
|
||||
this.frm.script_manager.copy_from_first_row("mtn_details", row,
|
||||
["expense_account", "cost_center"]);
|
||||
|
||||
|
||||
if(!row.s_warehouse) row.s_warehouse = this.frm.doc.from_warehouse;
|
||||
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
|
||||
},
|
||||
@ -236,49 +236,49 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
mtn_details_on_form_rendered: function(doc, grid_row) {
|
||||
erpnext.setup_serial_no(grid_row)
|
||||
},
|
||||
|
||||
|
||||
customer: function() {
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.party.get_party_details",
|
||||
args: { party: this.frm.doc.customer, party_type:"Customer" }
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
supplier: function() {
|
||||
return this.frm.call({
|
||||
method: "erpnext.accounts.party.get_party_details",
|
||||
args: { party: this.frm.doc.supplier, party_type:"Supplier" }
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
delivery_note_no: function() {
|
||||
this.get_party_details({
|
||||
ref_dt: "Delivery Note",
|
||||
ref_dn: this.frm.doc.delivery_note_no
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
sales_invoice_no: function() {
|
||||
this.get_party_details({
|
||||
ref_dt: "Sales Invoice",
|
||||
ref_dn: this.frm.doc.sales_invoice_no
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
purchase_receipt_no: function() {
|
||||
this.get_party_details({
|
||||
ref_dt: "Purchase Receipt",
|
||||
ref_dn: this.frm.doc.purchase_receipt_no
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
get_party_details: function(args) {
|
||||
return this.frm.call({
|
||||
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_party_details",
|
||||
args: args,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
cur_frm.script_manager.make(erpnext.stock.StockEntry);
|
||||
@ -286,23 +286,23 @@ cur_frm.script_manager.make(erpnext.stock.StockEntry);
|
||||
cur_frm.cscript.toggle_related_fields = function(doc) {
|
||||
disable_from_warehouse = inList(["Material Receipt", "Sales Return"], doc.purpose);
|
||||
disable_to_warehouse = inList(["Material Issue", "Purchase Return"], doc.purpose);
|
||||
|
||||
|
||||
cur_frm.toggle_enable("from_warehouse", !disable_from_warehouse);
|
||||
cur_frm.toggle_enable("to_warehouse", !disable_to_warehouse);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if(doc.purpose == 'Purchase Return') {
|
||||
doc.customer = doc.customer_name = doc.customer_address =
|
||||
doc.customer = doc.customer_name = doc.customer_address =
|
||||
doc.delivery_note_no = doc.sales_invoice_no = null;
|
||||
doc.bom_no = doc.production_order = doc.fg_completed_qty = null;
|
||||
} else if(doc.purpose == 'Sales Return') {
|
||||
doc.supplier=doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no=null;
|
||||
doc.bom_no = doc.production_order = doc.fg_completed_qty = null;
|
||||
} else {
|
||||
doc.customer = doc.customer_name = doc.customer_address =
|
||||
doc.delivery_note_no = doc.sales_invoice_no = doc.supplier =
|
||||
doc.customer = doc.customer_name = doc.customer_address =
|
||||
doc.delivery_note_no = doc.sales_invoice_no = doc.supplier =
|
||||
doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no = null;
|
||||
}
|
||||
}
|
||||
@ -331,7 +331,7 @@ cur_frm.fields_dict['mtn_details'].grid.get_field('batch_no').get_query = functi
|
||||
's_warehouse': d.s_warehouse,
|
||||
'posting_date': doc.posting_date
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msgprint(__("Please enter Item Code to get batch no"));
|
||||
}
|
||||
@ -350,10 +350,10 @@ cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
'cost_center' : d.cost_center,
|
||||
'company' : cur_frm.doc.company
|
||||
};
|
||||
return get_server_fields('get_item_details', {arg: JSON.stringify(args)},
|
||||
return get_server_fields('get_item_details', {arg: JSON.stringify(args)},
|
||||
'mtn_details', doc, cdt, cdn, 1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.s_warehouse = function(doc, cdt, cdn) {
|
||||
@ -366,7 +366,7 @@ cur_frm.cscript.s_warehouse = function(doc, cdt, cdn) {
|
||||
'bom_no' : d.bom_no,
|
||||
'qty' : d.s_warehouse ? -1* d.qty : d.qty
|
||||
}
|
||||
return get_server_fields('get_warehouse_details', JSON.stringify(args),
|
||||
return get_server_fields('get_warehouse_details', JSON.stringify(args),
|
||||
'mtn_details', doc, cdt, cdn, 1);
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ cur_frm.cscript.uom = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.uom && d.item_code){
|
||||
var arg = {'item_code':d.item_code, 'uom':d.uom, 'qty':d.qty}
|
||||
return get_server_fields('get_uom_details', JSON.stringify(arg),
|
||||
return get_server_fields('get_uom_details', JSON.stringify(arg),
|
||||
'mtn_details', doc, cdt, cdn, 1);
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,15 @@ class StockEntry(StockController):
|
||||
stock_items = self.get_stock_items()
|
||||
for item in self.get("mtn_details"):
|
||||
if item.item_code not in stock_items:
|
||||
frappe.throw(_("""Only Stock Items are allowed for Stock Entry"""))
|
||||
frappe.throw(_("{0} is not a stock Item").format(item.item_code))
|
||||
if not item.stock_uom:
|
||||
item.stock_uom = frappe.db.get_value("Item", item.item_code, "stock_uom")
|
||||
if not item.uom:
|
||||
item.uom = item.stock_uom
|
||||
if not item.conversion_factor:
|
||||
item.conversion_factor = 1
|
||||
if not item.transfer_qty:
|
||||
item.transfer_qty = item.qty * item.conversion_factor
|
||||
|
||||
def validate_warehouse(self, pro_obj):
|
||||
"""perform various (sometimes conditional) validations on warehouse"""
|
||||
@ -224,7 +232,7 @@ class StockEntry(StockController):
|
||||
"""validation: finished good quantity should be same as manufacturing quantity"""
|
||||
for d in self.get('mtn_details'):
|
||||
if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty):
|
||||
frappe.throw(_("Quantity in row {0} must be same as manufactured quantity").format(d.idx))
|
||||
frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}").format(d.idx, d.transfer_qty, self.fg_completed_qty))
|
||||
|
||||
def validate_return_reference_doc(self):
|
||||
"""validate item with reference doc"""
|
||||
|
@ -47,7 +47,7 @@ class StockLedgerEntry(DocListController):
|
||||
mandatory = ['warehouse','posting_date','voucher_type','voucher_no','actual_qty','company']
|
||||
for k in mandatory:
|
||||
if not self.get(k):
|
||||
frappe.throw(_("{0} is required").format(k))
|
||||
frappe.throw(_("{0} is required").format(self.meta.get_label(k)))
|
||||
|
||||
def validate_item(self):
|
||||
item_det = frappe.db.sql("""select name, has_batch_no, docstatus,
|
||||
|
@ -138,9 +138,7 @@ class StockReconciliation(StockController):
|
||||
# check valuation rate mandatory
|
||||
if row.qty != "" and not row.valuation_rate and \
|
||||
flt(previous_sle.get("qty_after_transaction")) <= 0:
|
||||
frappe.throw(_("As existing qty for item: ") + row.item_code +
|
||||
_(" at warehouse: ") + row.warehouse +
|
||||
_(" is less than equals to zero in the system, valuation rate is mandatory for this item"))
|
||||
frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
|
||||
|
||||
change_in_qty = row.qty != "" and \
|
||||
(flt(row.qty) - flt(previous_sle.get("qty_after_transaction")))
|
||||
|
@ -94,7 +94,7 @@ class Warehouse(Document):
|
||||
|
||||
if merge:
|
||||
if not frappe.db.exists("Warehouse", new_warehouse):
|
||||
frappe.throw(_("Warehouse ") + new_warehouse +_(" does not exists"))
|
||||
frappe.throw(_("Warehouse {0} does not exist").format(new_warehouse))
|
||||
|
||||
if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"):
|
||||
frappe.throw(_("Both Warehouse must belong to same Company"))
|
||||
|
@ -79,12 +79,12 @@ def get_item_details(args):
|
||||
def get_item_code(barcode=None, serial_no=None):
|
||||
if barcode:
|
||||
item_code = frappe.db.get_value("Item", {"barcode": barcode})
|
||||
if not item_code:
|
||||
frappe.throw(_("No Item with Barcode {0}").format(barcode))
|
||||
elif serial_no:
|
||||
item_code = frappe.db.get_value("Serial No", serial_no, "item_code")
|
||||
|
||||
if not item_code:
|
||||
throw(_("No Item found with ") + _("Barcode") if barcode else _("Serial No") +
|
||||
": %s" % (barcode or serial_no))
|
||||
if not item_code:
|
||||
frappe.throw(_("No Item with Serial No {0}").format(serial_no))
|
||||
|
||||
return item_code
|
||||
|
||||
@ -99,22 +99,18 @@ def validate_item_details(args, item):
|
||||
# validate if sales item or service item
|
||||
if args.get("order_type") == "Maintenance":
|
||||
if item.is_service_item != "Yes":
|
||||
throw(_("Item") + (" %s: " % item.name) +
|
||||
_("is not a service item.") +
|
||||
_("Please select a service item or change the order type to Sales."))
|
||||
throw(_("Item {0} must be a Service Item.").format(item.name))
|
||||
|
||||
elif item.is_sales_item != "Yes":
|
||||
throw(_("Item") + (" %s: " % item.name) + _("is not a sales item"))
|
||||
throw(_("Item {0} must be a Sales Item").format(item.name))
|
||||
|
||||
elif args.transaction_type == "buying":
|
||||
# validate if purchase item or subcontracted item
|
||||
if item.is_purchase_item != "Yes":
|
||||
throw(_("Item") + (" %s: " % item.name) + _("is not a purchase item"))
|
||||
throw(_("Item {0} must be a Purchase Item").format(item.name))
|
||||
|
||||
if args.get("is_subcontracted") == "Yes" and item.is_sub_contracted_item != "Yes":
|
||||
throw(_("Item") + (" %s: " % item.name) +
|
||||
_("not a sub-contracted item.") +
|
||||
_("Please select a sub-contracted item or do not sub-contract the transaction."))
|
||||
throw(_("Item {0} must be a Sub-contracted Item").format(item.name))
|
||||
|
||||
def get_basic_details(args, item_doc):
|
||||
item = item_doc
|
||||
@ -180,7 +176,7 @@ def validate_price_list(args):
|
||||
if args.get("price_list"):
|
||||
if not frappe.db.get_value("Price List",
|
||||
{"name": args.price_list, args.transaction_type: 1, "enabled": 1}):
|
||||
throw(_("Price List is either disabled or for not ") + _(args.transaction_type))
|
||||
throw(_("Price List {0} is disabled").format(args.price_list))
|
||||
else:
|
||||
throw(_("Price List not selected"))
|
||||
|
||||
|
@ -176,14 +176,14 @@ class MaintenanceSchedule(TransactionBase):
|
||||
if not d.item_code:
|
||||
throw(_("Please select item code"))
|
||||
elif not d.start_date or not d.end_date:
|
||||
throw(_("Please select Start Date and End Date for item") + " " + d.item_code)
|
||||
throw(_("Please select Start Date and End Date for Item {0}".format(d.item_code)))
|
||||
elif not d.no_of_visits:
|
||||
throw(_("Please mention no of visits required"))
|
||||
elif not d.sales_person:
|
||||
throw(_("Please select Incharge Person's name"))
|
||||
|
||||
if getdate(d.start_date) >= getdate(d.end_date):
|
||||
throw(_("Start date should be less than end date for item") + " " + d.item_code)
|
||||
throw(_("Start date should be less than end date for Item {0}").format(d.item_code))
|
||||
|
||||
def validate_sales_order(self):
|
||||
for d in self.get('item_maintenance_detail'):
|
||||
@ -238,8 +238,7 @@ class MaintenanceSchedule(TransactionBase):
|
||||
else:
|
||||
for x in item_lst1:
|
||||
if x not in item_lst2:
|
||||
throw(_("Maintenance Schedule is not generated for item ") + x +
|
||||
_(". Please click on 'Generate Schedule'"))
|
||||
throw(_("Please click on 'Generate Schedule'"))
|
||||
|
||||
def check_serial_no_added(self):
|
||||
serial_present =[]
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user