Merge branch 'develop' of github.com:frappe/erpnext into employee-skill-map
This commit is contained in:
commit
2a9b17efd4
@ -3,9 +3,10 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
|
||||
from frappe.utils import add_to_date, date_diff, getdate, nowdate
|
||||
from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day
|
||||
from erpnext.accounts.report.general_ledger.general_ledger import execute
|
||||
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
|
||||
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
|
||||
|
||||
from frappe.utils.nestedset import get_descendants_of
|
||||
|
||||
@ -23,13 +24,14 @@ def get(chart_name=None, from_date = None, to_date = None):
|
||||
if not to_date:
|
||||
to_date = nowdate()
|
||||
if not from_date:
|
||||
from_date = get_from_date_from_timespan(to_date, timespan)
|
||||
if timegrain in ('Monthly', 'Quarterly'):
|
||||
from_date = get_from_date_from_timespan(to_date, timespan)
|
||||
|
||||
# fetch dates to plot
|
||||
dates = get_dates_from_timegrain(from_date, to_date, timegrain)
|
||||
|
||||
# get all the entries for this account and its descendants
|
||||
gl_entries = get_gl_entries(account, to_date)
|
||||
gl_entries = get_gl_entries(account, get_period_ending(to_date, timegrain))
|
||||
|
||||
# compile balance values
|
||||
result = build_result(account, dates, gl_entries)
|
||||
@ -94,7 +96,8 @@ def get_dates_from_timegrain(from_date, to_date, timegrain):
|
||||
elif "Quarterly" == timegrain:
|
||||
months = 3
|
||||
|
||||
dates = [from_date]
|
||||
while getdate(dates[-1]) <= getdate(to_date):
|
||||
dates.append(add_to_date(dates[-1], years=years, months=months, days=days))
|
||||
dates = [get_period_ending(from_date, timegrain)]
|
||||
while getdate(dates[-1]) < getdate(to_date):
|
||||
date = get_period_ending(add_to_date(dates[-1], years=years, months=months, days=days), timegrain)
|
||||
dates.append(date)
|
||||
return dates
|
||||
|
@ -145,23 +145,25 @@ class InvoiceDiscounting(AccountsController):
|
||||
|
||||
if getdate(self.loan_end_date) > getdate(nowdate()):
|
||||
for d in self.invoices:
|
||||
je.append("accounts", {
|
||||
"account": self.accounts_receivable_discounted,
|
||||
"credit_in_account_currency": flt(d.outstanding_amount),
|
||||
"reference_type": "Invoice Discounting",
|
||||
"reference_name": self.name,
|
||||
"party_type": "Customer",
|
||||
"party": d.customer
|
||||
})
|
||||
outstanding_amount = frappe.db.get_value("Sales Invoice", d.sales_invoice, "outstanding_amount")
|
||||
if flt(outstanding_amount) > 0:
|
||||
je.append("accounts", {
|
||||
"account": self.accounts_receivable_discounted,
|
||||
"credit_in_account_currency": flt(outstanding_amount),
|
||||
"reference_type": "Invoice Discounting",
|
||||
"reference_name": self.name,
|
||||
"party_type": "Customer",
|
||||
"party": d.customer
|
||||
})
|
||||
|
||||
je.append("accounts", {
|
||||
"account": self.accounts_receivable_unpaid,
|
||||
"debit_in_account_currency": flt(d.outstanding_amount),
|
||||
"reference_type": "Invoice Discounting",
|
||||
"reference_name": self.name,
|
||||
"party_type": "Customer",
|
||||
"party": d.customer
|
||||
})
|
||||
je.append("accounts", {
|
||||
"account": self.accounts_receivable_unpaid,
|
||||
"debit_in_account_currency": flt(outstanding_amount),
|
||||
"reference_type": "Invoice Discounting",
|
||||
"reference_name": self.name,
|
||||
"party_type": "Customer",
|
||||
"party": d.customer
|
||||
})
|
||||
|
||||
return je
|
||||
|
||||
@ -190,9 +192,28 @@ def get_invoices(filters):
|
||||
customer,
|
||||
posting_date,
|
||||
outstanding_amount
|
||||
from `tabSales Invoice`
|
||||
from `tabSales Invoice` si
|
||||
where
|
||||
docstatus = 1
|
||||
and outstanding_amount > 0
|
||||
%s
|
||||
""" % where_condition, filters, as_dict=1)
|
||||
and not exists(select di.name from `tabDiscounted Invoice` di
|
||||
where di.docstatus=1 and di.sales_invoice=si.name)
|
||||
""" % where_condition, filters, as_dict=1)
|
||||
|
||||
def get_party_account_based_on_invoice_discounting(sales_invoice):
|
||||
party_account = None
|
||||
invoice_discounting = frappe.db.sql("""
|
||||
select par.accounts_receivable_discounted, par.accounts_receivable_unpaid, par.status
|
||||
from `tabInvoice Discounting` par, `tabDiscounted Invoice` ch
|
||||
where par.name=ch.parent
|
||||
and par.docstatus=1
|
||||
and ch.sales_invoice = %s
|
||||
""", (sales_invoice), as_dict=1)
|
||||
if invoice_discounting:
|
||||
if invoice_discounting[0].status == "Disbursed":
|
||||
party_account = invoice_discounting[0].accounts_receivable_discounted
|
||||
elif invoice_discounting[0].status == "Settled":
|
||||
party_account = invoice_discounting[0].accounts_receivable_unpaid
|
||||
|
||||
return party_account
|
||||
|
@ -0,0 +1,20 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'reference_name',
|
||||
'internal_links': {
|
||||
'Sales Invoice': ['invoices', 'sales_invoice']
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Reference'),
|
||||
'items': ['Sales Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Payment'),
|
||||
'items': ['Payment Entry', 'Journal Entry']
|
||||
}
|
||||
]
|
||||
}
|
@ -122,27 +122,62 @@ class TestInvoiceDiscounting(unittest.TestCase):
|
||||
period=60
|
||||
)
|
||||
|
||||
inv_disc.create_disbursement_entry()
|
||||
je = inv_disc.close_loan()
|
||||
je1 = inv_disc.create_disbursement_entry()
|
||||
je1.posting_date = nowdate()
|
||||
je1.submit()
|
||||
|
||||
self.assertEqual(je.accounts[0].account, self.short_term_loan)
|
||||
self.assertEqual(je.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
|
||||
je2 = inv_disc.close_loan()
|
||||
|
||||
self.assertEqual(je.accounts[1].account, self.bank_account)
|
||||
self.assertEqual(je.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
|
||||
self.assertEqual(je2.accounts[0].account, self.short_term_loan)
|
||||
self.assertEqual(je2.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
self.assertEqual(je.accounts[2].account, self.ar_discounted)
|
||||
self.assertEqual(je.accounts[2].credit_in_account_currency, flt(inv.outstanding_amount))
|
||||
self.assertEqual(je2.accounts[1].account, self.bank_account)
|
||||
self.assertEqual(je2.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
self.assertEqual(je.accounts[3].account, self.ar_unpaid)
|
||||
self.assertEqual(je.accounts[3].debit_in_account_currency, flt(inv.outstanding_amount))
|
||||
self.assertEqual(je2.accounts[2].account, self.ar_discounted)
|
||||
self.assertEqual(je2.accounts[2].credit_in_account_currency, flt(inv.outstanding_amount))
|
||||
|
||||
je.posting_date = nowdate()
|
||||
je.submit()
|
||||
self.assertEqual(je2.accounts[3].account, self.ar_unpaid)
|
||||
self.assertEqual(je2.accounts[3].debit_in_account_currency, flt(inv.outstanding_amount))
|
||||
|
||||
je2.posting_date = nowdate()
|
||||
je2.submit()
|
||||
inv_disc.reload()
|
||||
|
||||
self.assertEqual(inv_disc.status, "Settled")
|
||||
|
||||
def test_on_close_after_loan_period_after_inv_payment(self):
|
||||
inv = create_sales_invoice(rate=600)
|
||||
inv_disc = create_invoice_discounting([inv.name],
|
||||
accounts_receivable_credit=self.ar_credit,
|
||||
accounts_receivable_discounted=self.ar_discounted,
|
||||
accounts_receivable_unpaid=self.ar_unpaid,
|
||||
short_term_loan=self.short_term_loan,
|
||||
bank_charges_account=self.bank_charges_account,
|
||||
bank_account=self.bank_account,
|
||||
start=nowdate(),
|
||||
period=60
|
||||
)
|
||||
|
||||
je1 = inv_disc.create_disbursement_entry()
|
||||
je1.posting_date = nowdate()
|
||||
je1.submit()
|
||||
|
||||
je_on_payment = frappe.get_doc(get_payment_entry_against_invoice("Sales Invoice", inv.name))
|
||||
je_on_payment.posting_date = nowdate()
|
||||
je_on_payment.cheque_no = "126981"
|
||||
je_on_payment.cheque_date = nowdate()
|
||||
je_on_payment.save()
|
||||
je_on_payment.submit()
|
||||
|
||||
je2 = inv_disc.close_loan()
|
||||
|
||||
self.assertEqual(je2.accounts[0].account, self.short_term_loan)
|
||||
self.assertEqual(je2.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
self.assertEqual(je2.accounts[1].account, self.bank_account)
|
||||
self.assertEqual(je2.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
def test_on_close_before_loan_period(self):
|
||||
inv = create_sales_invoice(rate=700)
|
||||
inv_disc = create_invoice_discounting([inv.name],
|
||||
@ -154,23 +189,21 @@ class TestInvoiceDiscounting(unittest.TestCase):
|
||||
bank_account=self.bank_account,
|
||||
start=add_days(nowdate(), -80),
|
||||
period=60
|
||||
)
|
||||
)
|
||||
|
||||
inv_disc.create_disbursement_entry()
|
||||
je = inv_disc.close_loan()
|
||||
je1 = inv_disc.create_disbursement_entry()
|
||||
je1.posting_date = nowdate()
|
||||
je1.submit()
|
||||
|
||||
je.posting_date = nowdate()
|
||||
je.submit()
|
||||
je2 = inv_disc.close_loan()
|
||||
je2.posting_date = nowdate()
|
||||
je2.submit()
|
||||
|
||||
self.assertEqual(je.accounts[0].account, self.short_term_loan)
|
||||
self.assertEqual(je.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
|
||||
self.assertEqual(je2.accounts[0].account, self.short_term_loan)
|
||||
self.assertEqual(je2.accounts[0].debit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
self.assertEqual(je.accounts[1].account, self.bank_account)
|
||||
self.assertEqual(je.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
inv_disc.reload()
|
||||
|
||||
self.assertEqual(inv_disc.status, "Settled")
|
||||
self.assertEqual(je2.accounts[1].account, self.bank_account)
|
||||
self.assertEqual(je2.accounts[1].credit_in_account_currency, flt(inv_disc.total_amount))
|
||||
|
||||
def test_make_payment_before_loan_period(self):
|
||||
#it has problem
|
||||
|
@ -3,13 +3,14 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext, json
|
||||
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate, cint
|
||||
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, nowdate, cint, get_link_to_form
|
||||
from frappe import msgprint, _, scrub
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
from erpnext.accounts.utils import get_balance_on, get_account_currency
|
||||
from erpnext.accounts.party import get_party_account
|
||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||
from erpnext.hr.doctype.loan.loan import update_disbursement_status, update_total_amount_paid
|
||||
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
||||
|
||||
from six import string_types, iteritems
|
||||
|
||||
@ -53,6 +54,20 @@ class JournalEntry(AccountsController):
|
||||
self.update_inter_company_jv()
|
||||
self.update_invoice_discounting()
|
||||
|
||||
def on_cancel(self):
|
||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||
from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
||||
unlink_ref_doc_from_payment_entries(self)
|
||||
unlink_ref_doc_from_salary_slip(self.name)
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_loan()
|
||||
self.unlink_advance_entry_reference()
|
||||
self.unlink_asset_reference()
|
||||
self.unlink_inter_company_jv()
|
||||
self.unlink_asset_adjustment_entry()
|
||||
self.update_invoice_discounting()
|
||||
|
||||
def get_title(self):
|
||||
return self.pay_to_recd_from or self.accounts[0].account
|
||||
@ -83,31 +98,32 @@ class JournalEntry(AccountsController):
|
||||
"inter_company_journal_entry_reference", self.name)
|
||||
|
||||
def update_invoice_discounting(self):
|
||||
invoice_discounting_list = [d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"]
|
||||
def _validate_invoice_discounting_status(inv_disc, id_status, expected_status, row_id):
|
||||
id_link = get_link_to_form("Invoice Discounting", inv_disc)
|
||||
if id_status != expected_status:
|
||||
frappe.throw(_("Row #{0}: Status must be {1} for Invoice Discounting {2}").format(d.idx, expected_status, id_link))
|
||||
|
||||
invoice_discounting_list = list(set([d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"]))
|
||||
for inv_disc in invoice_discounting_list:
|
||||
short_term_loan_account = frappe.db.get_value("Invoice Discounting", inv_disc, "short_term_loan")
|
||||
short_term_loan_account, id_status = frappe.db.get_value("Invoice Discounting", inv_disc, ["short_term_loan", "status"])
|
||||
for d in self.accounts:
|
||||
if d.account == short_term_loan_account and d.reference_name == inv_disc:
|
||||
if d.credit > 0:
|
||||
status = "Disbursed"
|
||||
elif d.debit > 0:
|
||||
status = "Settled"
|
||||
if self.docstatus == 1:
|
||||
if d.credit > 0:
|
||||
_validate_invoice_discounting_status(inv_disc, id_status, "Sanctioned", d.idx)
|
||||
status = "Disbursed"
|
||||
elif d.debit > 0:
|
||||
_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx)
|
||||
status = "Settled"
|
||||
else:
|
||||
if d.credit > 0:
|
||||
_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx)
|
||||
status = "Sanctioned"
|
||||
elif d.debit > 0:
|
||||
_validate_invoice_discounting_status(inv_disc, id_status, "Settled", d.idx)
|
||||
status = "Disbursed"
|
||||
frappe.db.set_value("Invoice Discounting", inv_disc, "status", status)
|
||||
|
||||
def on_cancel(self):
|
||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||
from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
||||
unlink_ref_doc_from_payment_entries(self)
|
||||
unlink_ref_doc_from_salary_slip(self.name)
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.update_loan()
|
||||
self.unlink_advance_entry_reference()
|
||||
self.unlink_asset_reference()
|
||||
self.unlink_inter_company_jv()
|
||||
self.unlink_asset_adjustment_entry()
|
||||
|
||||
def unlink_advance_entry_reference(self):
|
||||
for d in self.get("accounts"):
|
||||
if d.is_advance == "Yes" and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
||||
@ -732,23 +748,6 @@ def get_payment_entry_against_invoice(dt, dn, amount=None, debit_in_account_cur
|
||||
"journal_entry": journal_entry
|
||||
})
|
||||
|
||||
def get_party_account_based_on_invoice_discounting(sales_invoice):
|
||||
party_account = None
|
||||
invoice_discounting = frappe.db.sql("""
|
||||
select par.accounts_receivable_discounted, par.accounts_receivable_unpaid, par.status
|
||||
from `tabInvoice Discounting` par, `tabDiscounted Invoice` ch
|
||||
where par.name=ch.parent
|
||||
and par.docstatus=1
|
||||
and ch.sales_invoice = %s
|
||||
""", (sales_invoice), as_dict=1)
|
||||
if invoice_discounting:
|
||||
if invoice_discounting[0].status == "Disbursed":
|
||||
party_account = invoice_discounting[0].accounts_receivable_discounted
|
||||
elif invoice_discounting[0].status == "Settled":
|
||||
party_account = invoice_discounting[0].accounts_receivable_unpaid
|
||||
|
||||
return party_account
|
||||
|
||||
def get_payment_entry(ref_doc, args):
|
||||
cost_center = ref_doc.get("cost_center") or frappe.get_cached_value('Company', ref_doc.company, "cost_center")
|
||||
exchange_rate = 1
|
||||
|
@ -14,6 +14,7 @@ from erpnext.accounts.general_ledger import make_gl_entries
|
||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||
from erpnext.accounts.doctype.bank_account.bank_account import get_party_bank_account, get_bank_account_details
|
||||
from erpnext.controllers.accounts_controller import AccountsController, get_supplier_block_status
|
||||
from erpnext.accounts.doctype.invoice_discounting.invoice_discounting import get_party_account_based_on_invoice_discounting
|
||||
|
||||
from six import string_types, iteritems
|
||||
|
||||
@ -237,7 +238,7 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim", "Fees"):
|
||||
if self.party_type == "Customer":
|
||||
ref_party_account = ref_doc.debit_to
|
||||
ref_party_account = get_party_account_based_on_invoice_discounting(d.reference_name) or ref_doc.debit_to
|
||||
elif self.party_type == "Student":
|
||||
ref_party_account = ref_doc.receivable_account
|
||||
elif self.party_type=="Supplier":
|
||||
@ -826,7 +827,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
|
||||
# party account
|
||||
if dt == "Sales Invoice":
|
||||
party_account = doc.debit_to
|
||||
party_account = get_party_account_based_on_invoice_discounting(dn) or doc.debit_to
|
||||
elif dt == "Purchase Invoice":
|
||||
party_account = doc.credit_to
|
||||
elif dt == "Fees":
|
||||
|
@ -481,13 +481,8 @@ class ReceivablePayableReport(object):
|
||||
conditions.append("company=%s")
|
||||
values.append(self.filters.company)
|
||||
|
||||
company_finance_book = erpnext.get_default_finance_book(self.filters.company)
|
||||
|
||||
if not self.filters.finance_book or (self.filters.finance_book == company_finance_book):
|
||||
if self.filters.finance_book:
|
||||
conditions.append("ifnull(finance_book,'') in (%s, '')")
|
||||
values.append(company_finance_book)
|
||||
elif self.filters.finance_book:
|
||||
conditions.append("ifnull(finance_book,'') = %s")
|
||||
values.append(self.filters.finance_book)
|
||||
|
||||
if self.filters.get(party_type_field):
|
||||
|
@ -31,11 +31,8 @@ def get_data(filters):
|
||||
|
||||
filters_data.append(["against_voucher", "in", assets])
|
||||
|
||||
company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
|
||||
if (not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book)):
|
||||
if filters.get("finance_book"):
|
||||
filters_data.append(["finance_book", "in", ['', filters.get('finance_book')]])
|
||||
elif filters.get("finance_book"):
|
||||
filters_data.append(["finance_book", "=", filters.get('finance_book')])
|
||||
|
||||
gl_entries = frappe.get_all('GL Entry',
|
||||
filters= filters_data,
|
||||
|
@ -355,7 +355,8 @@ def set_gl_entries_by_account(from_date, to_date, root_lft, root_rgt, filters, g
|
||||
"to_date": to_date,
|
||||
"lft": root_lft,
|
||||
"rgt": root_rgt,
|
||||
"company": d.name
|
||||
"company": d.name,
|
||||
"finance_book": filters.get("finance_book")
|
||||
},
|
||||
as_dict=True)
|
||||
|
||||
@ -385,14 +386,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
||||
if from_date:
|
||||
additional_conditions.append("gl.posting_date >= %(from_date)s")
|
||||
|
||||
company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
|
||||
|
||||
if not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book):
|
||||
additional_conditions.append("ifnull(finance_book, '') in (%s, '')" %
|
||||
frappe.db.escape(company_finance_book))
|
||||
elif filters.get("finance_book"):
|
||||
additional_conditions.append("ifnull(finance_book, '') = %s " %
|
||||
frappe.db.escape(filters.get("finance_book")))
|
||||
if filters.get("finance_book"):
|
||||
additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
|
||||
|
||||
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
|
||||
|
||||
|
@ -184,12 +184,8 @@ class PartyLedgerSummaryReport(object):
|
||||
if self.filters.company:
|
||||
conditions.append("gle.company=%(company)s")
|
||||
|
||||
self.filters.company_finance_book = erpnext.get_default_finance_book(self.filters.company)
|
||||
|
||||
if not self.filters.finance_book or (self.filters.finance_book == self.filters.company_finance_book):
|
||||
conditions.append("ifnull(finance_book,'') in (%(company_finance_book)s, '')")
|
||||
elif self.filters.finance_book:
|
||||
conditions.append("ifnull(finance_book,'') = %(finance_book)s")
|
||||
if self.filters.finance_book:
|
||||
conditions.append("ifnull(finance_book,'') in (%(finance_book)s, '')")
|
||||
|
||||
if self.filters.get("party"):
|
||||
conditions.append("party=%(party)s")
|
||||
|
@ -392,14 +392,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
|
||||
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
|
||||
additional_conditions.append("cost_center in %(cost_center)s")
|
||||
|
||||
company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
|
||||
|
||||
if not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book):
|
||||
additional_conditions.append("ifnull(finance_book, '') in (%s, '')" %
|
||||
frappe.db.escape(company_finance_book))
|
||||
elif filters.get("finance_book"):
|
||||
additional_conditions.append("ifnull(finance_book, '') = %s " %
|
||||
frappe.db.escape(filters.get("finance_book")))
|
||||
if filters.get("finance_book"):
|
||||
additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
|
||||
|
||||
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
|
||||
|
||||
|
@ -186,12 +186,8 @@ def get_conditions(filters):
|
||||
if filters.get("project"):
|
||||
conditions.append("project in %(project)s")
|
||||
|
||||
company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
|
||||
if not filters.get("finance_book") or (filters.get("finance_book") == company_finance_book):
|
||||
filters['finance_book'] = company_finance_book
|
||||
if filters.get("finance_book"):
|
||||
conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
|
||||
elif filters.get("finance_book"):
|
||||
conditions.append("ifnull(finance_book, '') = %(finance_book)s")
|
||||
|
||||
from frappe.desk.reportview import build_match_conditions
|
||||
match_conditions = build_match_conditions("GL Entry")
|
||||
|
@ -112,13 +112,15 @@ def convert_to_presentation_currency(gl_entries, currency_info):
|
||||
|
||||
if entry.get('debit'):
|
||||
entry['debit'] = converted_value
|
||||
else:
|
||||
|
||||
if entry.get('credit'):
|
||||
entry['credit'] = converted_value
|
||||
|
||||
elif account_currency == presentation_currency:
|
||||
if entry.get('debit'):
|
||||
entry['debit'] = debit_in_account_currency
|
||||
else:
|
||||
|
||||
if entry.get('credit'):
|
||||
entry['credit'] = credit_in_account_currency
|
||||
|
||||
converted_gl_list.append(entry)
|
||||
|
@ -1,28 +1,29 @@
|
||||
{
|
||||
"add_total_row": 1,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-05-13 16:10:02",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2017-02-24 20:10:53.005589",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Requested Items To Be Ordered",
|
||||
"owner": "Administrator",
|
||||
"query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.qty, 0)) as \"Qty:Float:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.qty, 0))\norder by mr.transaction_date asc",
|
||||
"ref_doctype": "Purchase Order",
|
||||
"report_name": "Requested Items To Be Ordered",
|
||||
"report_type": "Query Report",
|
||||
"add_total_row": 1,
|
||||
"creation": "2013-05-13 16:10:02",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 3,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2019-04-18 19:02:03.099422",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Requested Items To Be Ordered",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.stock_qty, 0)) as \"Qty:Float:100\",\n\tifnull(mr_item.stock_uom, '') as \"UOM:Link/UOM:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.stock_qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.stock_qty, 0))\norder by mr.transaction_date asc",
|
||||
"ref_doctype": "Purchase Order",
|
||||
"report_name": "Requested Items To Be Ordered",
|
||||
"report_type": "Query Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Stock User"
|
||||
},
|
||||
},
|
||||
{
|
||||
"role": "Purchase Manager"
|
||||
},
|
||||
},
|
||||
{
|
||||
"role": "Purchase User"
|
||||
}
|
||||
|
@ -232,6 +232,11 @@ def get_data():
|
||||
"label": _("Bank Account"),
|
||||
"name": "Bank Account",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"label": _("Invoice Discounting"),
|
||||
"name": "Invoice Discounting",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"label": _("Bank Statement Transaction Entry List"),
|
||||
|
@ -80,6 +80,14 @@ class Employee(NestedSet):
|
||||
if not self.create_user_permission: return
|
||||
if not has_permission('User Permission', ptype='write'): return
|
||||
|
||||
employee_user_permission_exists = frappe.db.exists('User Permission', {
|
||||
'allow': 'Employee',
|
||||
'for_value': self.name,
|
||||
'user': self.user_id
|
||||
})
|
||||
|
||||
if employee_user_permission_exists: return
|
||||
|
||||
add_user_permission("Employee", self.name, self.user_id)
|
||||
set_user_permission_if_allowed("Company", self.company, self.user_id)
|
||||
|
||||
|
@ -189,7 +189,7 @@
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "<h4>Condition Examples</h4>\n<ol>\n<li>Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)<br>\n<code>Condition: date_of_birth>date(1937, 12, 31) and date_of_birth<date(1958, 01, 01)</code></li><br><li>Applying tax by employee gender<br>\n<code>Condition: gender=\"Male\"</code></li><br>\n<li>Applying tax by Salary Component<br>\n<code>Condition: base > 10000</code></li></ol>",
|
||||
"options": "<h4>Condition Examples</h4>\n<ol>\n<li>Applying tax if employee born between 31-12-1937 and 01-01-1958 (Employees aged 60 to 80)<br>\n<code>Condition: date_of_birth>date(1937, 12, 31) and date_of_birth<date(1958, 01, 01)</code></li><br><li>Applying tax by employee gender<br>\n<code>Condition: gender==\"Male\"</code></li><br>\n<li>Applying tax by Salary Component<br>\n<code>Condition: base > 10000</code></li></ol>",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@ -229,4 +229,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
@ -29,19 +29,12 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
|
||||
});
|
||||
},
|
||||
|
||||
show_upload: function() {
|
||||
var me = this;
|
||||
show_upload() {
|
||||
var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty();
|
||||
|
||||
// upload
|
||||
frappe.upload.make({
|
||||
parent: $wrapper,
|
||||
args: {
|
||||
method: 'erpnext.hr.doctype.upload_attendance.upload_attendance.upload'
|
||||
},
|
||||
no_socketio: true,
|
||||
sample_url: "e.g. http://example.com/somefile.csv",
|
||||
callback: function(attachment, r) {
|
||||
new frappe.ui.FileUploader({
|
||||
wrapper: $wrapper,
|
||||
method: 'erpnext.hr.doctype.upload_attendance.upload_attendance.upload',
|
||||
on_success(file_doc, r) {
|
||||
var $log_wrapper = $(cur_frm.fields_dict.import_log.wrapper).empty();
|
||||
|
||||
if(!r.messages) r.messages = [];
|
||||
@ -59,10 +52,10 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
|
||||
});
|
||||
|
||||
r.messages = ["<h4 style='color:red'>"+__("Import Failed!")+"</h4>"]
|
||||
.concat(r.messages)
|
||||
.concat(r.messages);
|
||||
} else {
|
||||
r.messages = ["<h4 style='color:green'>"+__("Import Successful!")+"</h4>"].
|
||||
concat(r.message.messages)
|
||||
r.messages = ["<h4 style='color:green'>"+__("Import Successful!")+"</h4>"]
|
||||
.concat(r.message.messages);
|
||||
}
|
||||
|
||||
$.each(r.messages, function(i, v) {
|
||||
@ -79,11 +72,7 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// rename button
|
||||
$wrapper.find('form input[type="submit"]')
|
||||
.attr('value', 'Upload and Import')
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
cur_frm.cscript = new erpnext.hr.AttendanceControlPanel({frm: cur_frm});
|
||||
|
@ -116,10 +116,10 @@ def upload():
|
||||
if not frappe.has_permission("Attendance", "create"):
|
||||
raise frappe.PermissionError
|
||||
|
||||
from frappe.utils.csvutils import read_csv_content_from_uploaded_file
|
||||
from frappe.utils.csvutils import read_csv_content
|
||||
from frappe.modules import scrub
|
||||
|
||||
rows = read_csv_content_from_uploaded_file()
|
||||
rows = read_csv_content(frappe.local.uploaded_file)
|
||||
rows = list(filter(lambda x: x and any(x), rows))
|
||||
if not rows:
|
||||
msg = [_("Please select a csv file")]
|
||||
|
@ -682,6 +682,9 @@ def get_children(doctype, parent=None, is_root=False, **filters):
|
||||
frappe.msgprint(_('Please select a BOM'))
|
||||
return
|
||||
|
||||
if parent:
|
||||
frappe.form_dict.parent = parent
|
||||
|
||||
if frappe.form_dict.parent:
|
||||
bom_doc = frappe.get_doc("BOM", frappe.form_dict.parent)
|
||||
frappe.has_permission("BOM", doc=bom_doc, throw=True)
|
||||
@ -694,7 +697,7 @@ def get_children(doctype, parent=None, is_root=False, **filters):
|
||||
item_names = tuple(d.get('item_code') for d in bom_items)
|
||||
|
||||
items = frappe.get_list('Item',
|
||||
fields=['image', 'description', 'name'],
|
||||
fields=['image', 'description', 'name', 'stock_uom', 'item_name'],
|
||||
filters=[['name', 'in', item_names]]) # to get only required item dicts
|
||||
|
||||
for bom_item in bom_items:
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
@ -14,10 +15,12 @@
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -41,14 +44,17 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -72,14 +78,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -103,14 +112,51 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_request_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Material Request Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nPurchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -132,14 +178,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "quantity",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -149,7 +198,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Quantity",
|
||||
"label": "Required Quantity",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
@ -162,14 +211,52 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "projected_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Projected Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"collapsible_depends_on": "",
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "actual_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -192,14 +279,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "min_order_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -222,14 +312,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -252,14 +345,17 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -283,14 +379,18 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "requested_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -313,20 +413,19 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-15 13:08:30.535963",
|
||||
"modified": "2019-04-08 18:15:26.849602",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Material Request Plan Item",
|
||||
@ -335,10 +434,10 @@
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
@ -11,6 +11,23 @@ frappe.ui.form.on('Production Plan', {
|
||||
}
|
||||
}
|
||||
|
||||
frm.set_query('for_warehouse', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
company: doc.company
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.fields_dict['po_items'].grid.get_field('item_code').get_query = function(doc) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters:{
|
||||
'is_stock_item': 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict['po_items'].grid.get_field('bom_no').get_query = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.item_code) {
|
||||
@ -50,6 +67,51 @@ frappe.ui.form.on('Production Plan', {
|
||||
}
|
||||
|
||||
frm.trigger("material_requirement");
|
||||
|
||||
const projected_qty_formula = ` <table class="table table-bordered" style="background-color: #f9f9f9;">
|
||||
<tr><td style="padding-left:25px">
|
||||
<div>
|
||||
<h3>
|
||||
<a href = "https://erpnext.com/docs/user/manual/en/stock/projected-quantity">
|
||||
${__("Projected Quantity Formula")}
|
||||
</a>
|
||||
</h3>
|
||||
<div>
|
||||
<h3 style="font-size: 13px">
|
||||
(Actual Qty + Planned Qty + Requested Qty + Ordered Qty) - (Reserved Qty + Reserved for Production + Reserved for Subcontract)
|
||||
</h3>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<ul>
|
||||
<li>
|
||||
${__("Actual Qty: Quantity available in the warehouse.")}
|
||||
</li>
|
||||
<li>
|
||||
${__("Planned Qty: Quantity, for which, Work Order has been raised, but is pending to be manufactured.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Requested Qty: Quantity requested for purchase, but not ordered.')}
|
||||
</li>
|
||||
<li>
|
||||
${__('Ordered Qty: Quantity ordered for purchase, but not received.')}
|
||||
</li>
|
||||
<li>
|
||||
${__("Reserved Qty: Quantity ordered for sale, but not delivered.")}
|
||||
</li>
|
||||
<li>
|
||||
${__('Reserved Qty for Production: Raw materials quantity to make manufacturing items.')}
|
||||
</li>
|
||||
<li>
|
||||
${__('Reserved Qty for Subcontract: Raw materials quantity to make subcotracted items.')}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</td></tr>
|
||||
</table>`;
|
||||
|
||||
set_field_options("projected_qty_formula", projected_qty_formula);
|
||||
},
|
||||
|
||||
make_work_order: function(frm) {
|
||||
@ -106,6 +168,8 @@ frappe.ui.form.on('Production Plan', {
|
||||
},
|
||||
|
||||
get_items_for_mr: function(frm) {
|
||||
const set_fields = ['actual_qty', 'item_code',
|
||||
'item_name', 'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
|
||||
freeze: true,
|
||||
@ -115,13 +179,11 @@ frappe.ui.form.on('Production Plan', {
|
||||
frm.set_value('mr_items', []);
|
||||
$.each(r.message, function(i, d) {
|
||||
var item = frm.add_child('mr_items');
|
||||
item.actual_qty = d.actual_qty;
|
||||
item.item_code = d.item_code;
|
||||
item.item_name = d.item_name;
|
||||
item.min_order_qty = d.min_order_qty;
|
||||
item.quantity = d.quantity;
|
||||
item.sales_order = d.sales_order;
|
||||
item.warehouse = d.warehouse;
|
||||
for (let key in d) {
|
||||
if (d[key] && in_list(set_fields, key)) {
|
||||
item[key] = d[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
refresh_field('mr_items');
|
||||
@ -129,6 +191,16 @@ frappe.ui.form.on('Production Plan', {
|
||||
});
|
||||
},
|
||||
|
||||
for_warehouse: function(frm) {
|
||||
if (frm.doc.mr_items) {
|
||||
frm.trigger("get_items_for_mr");
|
||||
}
|
||||
},
|
||||
|
||||
download_materials_required: function(frm) {
|
||||
$c_obj_csv(frm.doc, 'download_raw_materials', '', '');
|
||||
},
|
||||
|
||||
show_progress: function(frm) {
|
||||
var bars = [];
|
||||
var message = '';
|
||||
@ -163,6 +235,25 @@ frappe.ui.form.on('Production Plan', {
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Production Plan Item", {
|
||||
item_code: function(frm, cdt, cdn) {
|
||||
const row = locals[cdt][cdn];
|
||||
if (row.item_code) {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_item_data",
|
||||
args: {
|
||||
item_code: row.item_code
|
||||
},
|
||||
callback: function(r) {
|
||||
for (let key in r.message) {
|
||||
frappe.model.set_value(cdt, cdn, key, r.message[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Material Request Plan Item", {
|
||||
warehouse: function(frm, cdt, cdn) {
|
||||
const row = locals[cdt][cdn];
|
||||
@ -170,12 +261,16 @@ frappe.ui.form.on("Material Request Plan Item", {
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_bin_details",
|
||||
args: {
|
||||
row: row
|
||||
row: row,
|
||||
for_warehouse: row.warehouse
|
||||
},
|
||||
callback: function(r) {
|
||||
frappe.model.set_value(cdt, cdn, 'actual_qty', r.message[1])
|
||||
let {projected_qty, actual_qty} = r.message;
|
||||
|
||||
frappe.model.set_value(cdt, cdn, 'projected_qty', projected_qty);
|
||||
frappe.model.set_value(cdt, cdn, 'actual_qty', actual_qty);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
@ -22,6 +23,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@ -56,6 +58,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -90,6 +93,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "get_items_from",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@ -123,6 +127,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break1",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -155,6 +160,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Today",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -190,6 +196,7 @@
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from",
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "filters",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -222,6 +229,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -256,6 +264,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from == \"Sales Order\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -290,6 +299,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from == \"Material Request\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -324,6 +334,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from == \"Sales Order\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -357,6 +368,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -389,6 +401,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -421,6 +434,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -455,6 +469,7 @@
|
||||
"collapsible_depends_on": "eval: doc.__islocal",
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from == \"Sales Order\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_orders_detail",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -489,6 +504,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "get_sales_orders",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
@ -522,6 +538,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_orders",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -557,6 +574,7 @@
|
||||
"collapsible_depends_on": "eval: doc.__islocal",
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.get_items_from == \"Material Request\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_request_detail",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -590,6 +608,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "get_material_request",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
@ -623,6 +642,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_requests",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -657,7 +677,8 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fieldname": "items_for_production",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "select_items_to_manufacture_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@ -666,7 +687,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Select Items",
|
||||
"label": "Select Items to Manufacture",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -690,6 +711,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "get_items_from",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "get_items",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
@ -723,6 +745,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "po_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -732,7 +755,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Items",
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Production Plan Item",
|
||||
@ -757,6 +780,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_request_planning",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -790,6 +814,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "include_non_stock_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -815,69 +840,6 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "ignore_existing_ordered_qty",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ignore Existing Ordered Quantity",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_25",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -886,6 +848,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "include_subcontracted_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -918,9 +881,43 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "section_break_27",
|
||||
"fieldtype": "Section Break",
|
||||
"description": "If enabled, then system will create the material even if the raw materials are available",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "ignore_existing_ordered_qty",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ignore Existing Projected Quantity",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_25",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -950,6 +947,74 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "for_warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "For Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "download_materials_required",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Download Materials Required",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "get_items_for_mr",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
@ -982,6 +1047,40 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_27",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "mr_items",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -1008,6 +1107,40 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "projected_qty_formula",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Projected Qty Formula",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -1015,6 +1148,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "other_details",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -1048,6 +1182,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_planned_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -1081,6 +1216,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -1113,6 +1249,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_32",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -1145,6 +1282,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Draft",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@ -1178,6 +1316,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1205,17 +1344,15 @@
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-calendar",
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-08-21 14:44:25.071991",
|
||||
"modified": "2019-04-09 12:05:14.300886",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan",
|
||||
@ -1244,7 +1381,6 @@
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
from frappe import msgprint, _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
|
||||
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_children
|
||||
from frappe.utils import cstr, flt, cint, nowdate, add_days, comma_and, now_datetime, ceil
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import get_item_details
|
||||
from six import string_types, iteritems
|
||||
@ -262,7 +262,8 @@ class ProductionPlan(Document):
|
||||
"fg_warehouse" : d.warehouse,
|
||||
"production_plan" : self.name,
|
||||
"production_plan_item" : d.name,
|
||||
"product_bundle_item" : d.product_bundle_item
|
||||
"product_bundle_item" : d.product_bundle_item,
|
||||
"make_work_order_for_sub_assembly_items": d.get("make_work_order_for_sub_assembly_items", 0)
|
||||
}
|
||||
|
||||
item_details.update({
|
||||
@ -293,6 +294,10 @@ class ProductionPlan(Document):
|
||||
if work_order:
|
||||
wo_list.append(work_order)
|
||||
|
||||
if item.get("make_work_order_for_sub_assembly_items"):
|
||||
work_orders = self.make_work_order_for_sub_assembly_items(item)
|
||||
wo_list.extend(work_orders)
|
||||
|
||||
frappe.flags.mute_messages = False
|
||||
|
||||
if wo_list:
|
||||
@ -302,11 +307,35 @@ class ProductionPlan(Document):
|
||||
else :
|
||||
msgprint(_("No Work Orders created"))
|
||||
|
||||
def make_work_order_for_sub_assembly_items(self, item):
|
||||
work_orders = []
|
||||
bom_data = {}
|
||||
|
||||
get_sub_assembly_items(item.get("bom_no"), bom_data)
|
||||
|
||||
for key, data in bom_data.items():
|
||||
data.update({
|
||||
'qty': data.get("stock_qty") * item.get("qty"),
|
||||
'production_plan': self.name,
|
||||
'company': self.company,
|
||||
'fg_warehouse': item.get("fg_warehouse")
|
||||
})
|
||||
|
||||
work_order = self.create_work_order(data)
|
||||
if work_order:
|
||||
work_orders.append(work_order)
|
||||
|
||||
return work_orders
|
||||
|
||||
def create_work_order(self, item):
|
||||
from erpnext.manufacturing.doctype.work_order.work_order import OverProductionError, get_default_warehouse
|
||||
warehouse = get_default_warehouse()
|
||||
wo = frappe.new_doc("Work Order")
|
||||
wo.update(item)
|
||||
|
||||
if item.get("warehouse"):
|
||||
wo.fg_warehouse = item.get("warehouse")
|
||||
|
||||
wo.set_work_order_operations()
|
||||
|
||||
if not wo.fg_warehouse:
|
||||
@ -325,8 +354,10 @@ class ProductionPlan(Document):
|
||||
for item in self.mr_items:
|
||||
item_doc = frappe.get_cached_doc('Item', item.item_code)
|
||||
|
||||
material_request_type = item.material_request_type or item_doc.default_material_request_type
|
||||
|
||||
# key for Sales Order:Material Request Type:Customer
|
||||
key = '{}:{}:{}'.format(item.sales_order, item_doc.default_material_request_type,item_doc.customer or '')
|
||||
key = '{}:{}:{}'.format(item.sales_order, material_request_type, item_doc.customer or '')
|
||||
schedule_date = add_days(nowdate(), cint(item_doc.lead_time_days))
|
||||
|
||||
if not key in material_request_map:
|
||||
@ -338,7 +369,7 @@ class ProductionPlan(Document):
|
||||
"status": "Draft",
|
||||
"company": self.company,
|
||||
"requested_by": frappe.session.user,
|
||||
'material_request_type': item_doc.default_material_request_type,
|
||||
'material_request_type': material_request_type,
|
||||
'customer': item_doc.customer or ''
|
||||
})
|
||||
material_request_list.append(material_request)
|
||||
@ -373,6 +404,26 @@ class ProductionPlan(Document):
|
||||
else :
|
||||
msgprint(_("No material request created"))
|
||||
|
||||
def download_raw_materials(self):
|
||||
item_list = [['Item Code', 'Description', 'Stock UOM', 'Required Qty', 'Warehouse',
|
||||
'projected Qty', 'Actual Qty']]
|
||||
|
||||
doc = self.as_dict()
|
||||
for d in get_items_for_material_requests(doc, ignore_existing_ordered_qty=True):
|
||||
item_list.append([d.get('item_code'), d.get('description'), d.get('stock_uom'), d.get('quantity'),
|
||||
d.get('warehouse'), d.get('projected_qty'), d.get('actual_qty')])
|
||||
|
||||
if not self.for_warehouse:
|
||||
row = {'item_code': d.get('item_code')}
|
||||
for bin_dict in get_bin_details(row, self.company, all_warehouse=True):
|
||||
if d.get("warehouse") == bin_dict.get('warehouse'):
|
||||
continue
|
||||
|
||||
item_list.append(['', '', '', '', bin_dict.get('warehouse'),
|
||||
bin_dict.get('projected_qty'), bin_dict.get('actual_qty')])
|
||||
|
||||
return item_list
|
||||
|
||||
def get_exploded_items(item_details, company, bom_no, include_non_stock_items, planned_qty=1):
|
||||
for d in frappe.db.sql("""select bei.item_code, item.default_bom as bom,
|
||||
ifnull(sum(bei.stock_qty/ifnull(bom.quantity, 1)), 0)*%s as qty, item.item_name,
|
||||
@ -439,17 +490,17 @@ def get_subitems(doc, data, item_details, bom_no, company, include_non_stock_ite
|
||||
include_non_stock_items, include_subcontracted_items, d.qty)
|
||||
return item_details
|
||||
|
||||
def get_material_request_items(row, sales_order, company, ignore_existing_ordered_qty, warehouse):
|
||||
def get_material_request_items(row, sales_order,
|
||||
company, ignore_existing_ordered_qty, warehouse, bin_dict):
|
||||
total_qty = row['qty']
|
||||
projected_qty, actual_qty = get_bin_details(row)
|
||||
|
||||
requested_qty = 0
|
||||
if ignore_existing_ordered_qty:
|
||||
requested_qty = total_qty
|
||||
elif total_qty > projected_qty:
|
||||
requested_qty = total_qty - projected_qty
|
||||
if requested_qty > 0 and requested_qty < row['min_order_qty']:
|
||||
requested_qty = row['min_order_qty']
|
||||
required_qty = 0
|
||||
if ignore_existing_ordered_qty or bin_dict.get("projected_qty") < 0:
|
||||
required_qty = total_qty
|
||||
elif total_qty > bin_dict.get("projected_qty"):
|
||||
required_qty = total_qty - bin_dict.get("projected_qty")
|
||||
if required_qty > 0 and required_qty < row['min_order_qty']:
|
||||
required_qty = row['min_order_qty']
|
||||
item_group_defaults = get_item_group_defaults(row.item_code, company)
|
||||
|
||||
if not row['purchase_uom']:
|
||||
@ -459,20 +510,24 @@ def get_material_request_items(row, sales_order, company, ignore_existing_ordere
|
||||
if not row['conversion_factor']:
|
||||
frappe.throw(_("UOM Conversion factor ({0} -> {1}) not found for item: {2}")
|
||||
.format(row['purchase_uom'], row['stock_uom'], row.item_code))
|
||||
requested_qty = requested_qty / row['conversion_factor']
|
||||
required_qty = required_qty / row['conversion_factor']
|
||||
|
||||
if frappe.db.get_value("UOM", row['purchase_uom'], "must_be_whole_number"):
|
||||
requested_qty = ceil(requested_qty)
|
||||
required_qty = ceil(required_qty)
|
||||
|
||||
if requested_qty > 0:
|
||||
if required_qty > 0:
|
||||
return {
|
||||
'item_code': row.item_code,
|
||||
'item_name': row.item_name,
|
||||
'quantity': requested_qty,
|
||||
'quantity': required_qty,
|
||||
'description': row.description,
|
||||
'stock_uom': row.get("stock_uom"),
|
||||
'warehouse': warehouse or row.get('source_warehouse') \
|
||||
or row.get('default_warehouse') or item_group_defaults.get("default_warehouse"),
|
||||
'actual_qty': actual_qty,
|
||||
'actual_qty': bin_dict.get("actual_qty", 0),
|
||||
'projected_qty': bin_dict.get("projected_qty", 0),
|
||||
'min_order_qty': row['min_order_qty'],
|
||||
'material_request_type': row.get("default_material_request_type"),
|
||||
'sales_order': sales_order
|
||||
}
|
||||
|
||||
@ -515,37 +570,48 @@ def get_sales_orders(self):
|
||||
return open_so
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bin_details(row):
|
||||
def get_bin_details(row, company, for_warehouse=None, all_warehouse=False):
|
||||
if isinstance(row, string_types):
|
||||
row = frappe._dict(json.loads(row))
|
||||
|
||||
conditions = ""
|
||||
warehouse = row.get('source_warehouse') or row.get('default_warehouse')
|
||||
company = frappe.db.escape(company)
|
||||
conditions, warehouse = "", ""
|
||||
|
||||
conditions = " and warehouse in (select name from `tabWarehouse` where company = {0})".format(company)
|
||||
if not all_warehouse:
|
||||
warehouse = for_warehouse or row.get('source_warehouse') or row.get('default_warehouse')
|
||||
|
||||
if warehouse:
|
||||
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
|
||||
conditions = " and exists(select name from `tabWarehouse` where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse)".format(lft, rgt)
|
||||
conditions = """ and warehouse in (select name from `tabWarehouse`
|
||||
where lft >= {0} and rgt <= {1} and name=`tabBin`.warehouse and company = {2})
|
||||
""".format(lft, rgt, company)
|
||||
|
||||
item_projected_qty = frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
|
||||
ifnull(sum(actual_qty),0) as actual_qty from `tabBin`
|
||||
return frappe.db.sql(""" select ifnull(sum(projected_qty),0) as projected_qty,
|
||||
ifnull(sum(actual_qty),0) as actual_qty, warehouse from `tabBin`
|
||||
where item_code = %(item_code)s {conditions}
|
||||
""".format(conditions=conditions), { "item_code": row['item_code'] }, as_list=1)
|
||||
|
||||
return item_projected_qty and item_projected_qty[0] or (0,0)
|
||||
group by item_code, warehouse
|
||||
""".format(conditions=conditions), { "item_code": row['item_code'] }, as_dict=1)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_items_for_material_requests(doc, sales_order=None, company=None):
|
||||
def get_items_for_material_requests(doc, ignore_existing_ordered_qty=None):
|
||||
if isinstance(doc, string_types):
|
||||
doc = frappe._dict(json.loads(doc))
|
||||
|
||||
doc['mr_items'] = []
|
||||
po_items = doc.get('po_items') if doc.get('po_items') else doc.get('items')
|
||||
company = doc.get('company')
|
||||
warehouse = doc.get('for_warehouse')
|
||||
|
||||
if not ignore_existing_ordered_qty:
|
||||
ignore_existing_ordered_qty = doc.get('ignore_existing_ordered_qty')
|
||||
|
||||
so_item_details = frappe._dict()
|
||||
for data in po_items:
|
||||
warehouse = data.get('for_warehouse')
|
||||
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or doc.get('ignore_existing_ordered_qty')
|
||||
planned_qty = data.get('required_qty') or data.get('planned_qty')
|
||||
ignore_existing_ordered_qty = data.get('ignore_existing_ordered_qty') or ignore_existing_ordered_qty
|
||||
warehouse = data.get("warehouse") or warehouse
|
||||
|
||||
item_details = {}
|
||||
if data.get("bom") or data.get("bom_no"):
|
||||
if data.get('required_qty'):
|
||||
@ -592,8 +658,8 @@ def get_items_for_material_requests(doc, sales_order=None, company=None):
|
||||
'conversion_factor' : conversion_factor,
|
||||
}
|
||||
)
|
||||
if not sales_order:
|
||||
sales_order = doc.get("sales_order")
|
||||
|
||||
sales_order = doc.get("sales_order")
|
||||
|
||||
for item_code, details in iteritems(item_details):
|
||||
so_item_details.setdefault(sales_order, frappe._dict())
|
||||
@ -606,10 +672,48 @@ def get_items_for_material_requests(doc, sales_order=None, company=None):
|
||||
for sales_order, item_code in iteritems(so_item_details):
|
||||
item_dict = so_item_details[sales_order]
|
||||
for details in item_dict.values():
|
||||
bin_dict = get_bin_details(details, doc.company, warehouse)
|
||||
bin_dict = bin_dict[0] if bin_dict else {}
|
||||
|
||||
if details.qty > 0:
|
||||
items = get_material_request_items(details, sales_order, company,
|
||||
ignore_existing_ordered_qty, warehouse)
|
||||
ignore_existing_ordered_qty, warehouse, bin_dict)
|
||||
if items:
|
||||
mr_items.append(items)
|
||||
|
||||
if not mr_items:
|
||||
frappe.msgprint(_("""As raw materials projected quantity is more than required quantity, there is no need to create material request.
|
||||
Still if you want to make material request, kindly enable <b>Ignore Existing Projected Quantity</b> checkbox"""))
|
||||
|
||||
return mr_items
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_data(item_code):
|
||||
item_details = get_item_details(item_code)
|
||||
|
||||
return {
|
||||
"bom_no": item_details.get("bom_no"),
|
||||
"stock_uom": item_details.get("stock_uom"),
|
||||
"description": item_details.get("description")
|
||||
}
|
||||
|
||||
def get_sub_assembly_items(bom_no, bom_data):
|
||||
data = get_children('BOM', parent = bom_no)
|
||||
for d in data:
|
||||
if d.expandable:
|
||||
key = (d.name, d.value)
|
||||
if key not in bom_data:
|
||||
bom_data.setdefault(key, {
|
||||
'stock_qty': 0,
|
||||
'description': d.description,
|
||||
'production_item': d.item_code,
|
||||
'item_name': d.item_name,
|
||||
'stock_uom': d.stock_uom,
|
||||
'uom': d.stock_uom,
|
||||
'bom_no': d.value
|
||||
})
|
||||
|
||||
bom_item = bom_data.get(key)
|
||||
bom_item["stock_qty"] += d.stock_qty
|
||||
|
||||
get_sub_assembly_items(bom_item.get("bom_no"), bom_data)
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
@ -13,10 +14,12 @@
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "include_exploded_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -44,10 +47,12 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -79,10 +84,12 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "bom_no",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -114,10 +121,12 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "planned_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -148,11 +157,114 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"description": "If enabled, system will create the work order for the exploded items against which BOM is available.",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "make_work_order_for_sub_assembly_items",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Make Work Order for Sub Assembly Items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "For Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Today",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "planned_start_date",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 0,
|
||||
@ -180,12 +292,14 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -193,6 +307,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Quantity and Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@ -210,169 +325,13 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Reserved Warehouse in Sales Order / Finished Goods Warehouse",
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Warehouse",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Warehouse",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Produced Qty",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "source_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "sales_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order Item",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "material_request",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Material Request",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Material Request",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "pending_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -403,10 +362,148 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "ordered_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ordered Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "produced_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Produced Qty",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "200px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "200px"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "stock_uom",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -438,12 +535,14 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "reference_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@ -451,15 +550,48 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"label": "Reference",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_order",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "source_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "200px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
@ -467,15 +599,115 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "200px"
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sales_order_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sales Order Item",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_19",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_request",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Material Request",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Material Request",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "material_request_item",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
@ -503,41 +735,12 @@
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "ordered_qty",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Ordered Qty",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "product_bundle_item",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -566,16 +769,14 @@
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-04-25 17:19:24.572528",
|
||||
"modified": "2019-04-08 23:09:57.199423",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Plan Item",
|
||||
@ -583,9 +784,9 @@
|
||||
"permissions": [],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
@ -20,6 +20,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@ -52,6 +53,7 @@
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -86,6 +88,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "issue",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -112,6 +115,40 @@
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Task Type",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
@ -120,6 +157,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -152,6 +190,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -185,6 +224,7 @@
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@ -219,6 +259,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "priority",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@ -253,6 +294,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Color",
|
||||
"hidden": 0,
|
||||
@ -285,6 +327,7 @@
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "parent_task",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -320,6 +363,7 @@
|
||||
"collapsible_depends_on": "eval:doc.__islocal",
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_timeline",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -353,6 +397,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "exp_start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -389,6 +434,7 @@
|
||||
"default": "0",
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "expected_time",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -423,6 +469,8 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_from": "type.weight",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "task_weight",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -455,6 +503,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -487,6 +536,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "exp_end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -521,6 +571,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "progress",
|
||||
"fieldtype": "Percent",
|
||||
"hidden": 0,
|
||||
@ -554,6 +605,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "is_milestone",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
@ -588,6 +640,7 @@
|
||||
"collapsible_depends_on": "",
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_details",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -622,6 +675,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"hidden": 0,
|
||||
@ -659,6 +713,7 @@
|
||||
"collapsible_depends_on": "",
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_depends_on",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -692,6 +747,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "depends_on",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@ -726,6 +782,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "depends_on_tasks",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
@ -761,6 +818,7 @@
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_actual",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -796,6 +854,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "act_start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -832,6 +891,7 @@
|
||||
"default": "",
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "actual_time",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@ -865,6 +925,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_15",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -897,6 +958,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "act_end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -931,6 +993,7 @@
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_costing",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -964,6 +1027,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_costing_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
@ -999,6 +1063,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_expense_claim",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
@ -1032,6 +1097,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_20",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -1064,6 +1130,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "total_billing_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
@ -1096,6 +1163,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "sb_more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
@ -1128,6 +1196,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.status == \"Closed\" || doc.status == \"Pending Review\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "review_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -1162,6 +1231,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.status == \"Closed\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "closing_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@ -1195,6 +1265,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_22",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@ -1225,6 +1296,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "department",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1258,6 +1330,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "company",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@ -1290,6 +1363,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -1322,6 +1396,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 1,
|
||||
@ -1354,6 +1429,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
@ -1381,18 +1457,16 @@
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-check",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 5,
|
||||
"menu_index": 0,
|
||||
"modified": "2019-02-19 12:22:02.147606",
|
||||
"modified": "2019-04-20 22:45:20.777600",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Task",
|
||||
@ -1420,9 +1494,8 @@
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "subject",
|
||||
"show_name_in_global_search": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_order": "DESC",
|
||||
"timeline_field": "project",
|
||||
"title_field": "subject",
|
||||
|
0
erpnext/projects/doctype/task_type/__init__.py
Normal file
0
erpnext/projects/doctype/task_type/__init__.py
Normal file
8
erpnext/projects/doctype/task_type/task_type.js
Normal file
8
erpnext/projects/doctype/task_type/task_type.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Task Type', {
|
||||
// refresh: function(frm) {
|
||||
|
||||
// }
|
||||
});
|
127
erpnext/projects/doctype/task_type/task_type.json
Normal file
127
erpnext/projects/doctype/task_type/task_type.json
Normal file
@ -0,0 +1,127 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "Prompt",
|
||||
"beta": 0,
|
||||
"creation": "2019-04-19 15:04:05.317138",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "weight",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Weight",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Description",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-04-19 15:31:48.080164",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Task Type",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
}
|
10
erpnext/projects/doctype/task_type/task_type.py
Normal file
10
erpnext/projects/doctype/task_type/task_type.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class TaskType(Document):
|
||||
pass
|
10
erpnext/projects/doctype/task_type/test_task_type.py
Normal file
10
erpnext/projects/doctype/task_type/test_task_type.py
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
class TestTaskType(unittest.TestCase):
|
||||
pass
|
@ -58,43 +58,9 @@ $.extend(erpnext, {
|
||||
.css({"margin-bottom": "10px", "margin-top": "10px"})
|
||||
.appendTo(grid_row.grid_form.fields_dict.serial_no.$wrapper));
|
||||
|
||||
var me = this;
|
||||
$btn.on("click", function() {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Add Serial No"),
|
||||
fields: [
|
||||
{
|
||||
"fieldtype": "Link",
|
||||
"fieldname": "serial_no",
|
||||
"options": "Serial No",
|
||||
"label": __("Serial No"),
|
||||
"get_query": function () {
|
||||
return {
|
||||
filters: {
|
||||
item_code:grid_row.doc.item_code,
|
||||
warehouse:cur_frm.doc.is_return ? null : grid_row.doc.warehouse
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldtype": "Button",
|
||||
"fieldname": "add",
|
||||
"label": __("Add")
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
d.get_input("add").on("click", function() {
|
||||
var serial_no = d.get_value("serial_no");
|
||||
if(serial_no) {
|
||||
var val = (grid_row.doc.serial_no || "").split("\n").concat([serial_no]).join("\n");
|
||||
grid_row.grid_form.fields_dict.serial_no.set_model_value(val.trim());
|
||||
}
|
||||
d.hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
d.show();
|
||||
me.show_serial_batch_selector(grid_row.frm, grid_row.doc);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -5,12 +5,11 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
this.show_dialog = show_dialog;
|
||||
// frm, item, warehouse_details, has_batch, oldest
|
||||
let d = this.item;
|
||||
|
||||
// Don't show dialog if batch no or serial no already set
|
||||
if(d && d.has_batch_no && (!d.batch_no || this.show_dialog)) {
|
||||
if (d && d.has_batch_no && (!d.batch_no || this.show_dialog)) {
|
||||
this.has_batch = 1;
|
||||
this.setup();
|
||||
} else if(d && d.has_serial_no && (!d.serial_no || this.show_dialog)) {
|
||||
// !(this.show_dialog == false) ensures that show_dialog is implictly true, even when undefined
|
||||
} else if(d && d.has_serial_no && !(this.show_dialog == false)) {
|
||||
this.has_batch = 0;
|
||||
this.setup();
|
||||
}
|
||||
@ -68,13 +67,41 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
{
|
||||
fieldname: 'qty',
|
||||
fieldtype:'Float',
|
||||
read_only: 1,
|
||||
read_only: me.has_batch,
|
||||
label: __(me.has_batch ? 'Total Qty' : 'Qty'),
|
||||
default: 0
|
||||
},
|
||||
{
|
||||
fieldname: 'auto_fetch_button',
|
||||
fieldtype:'Button',
|
||||
hidden: me.has_batch,
|
||||
label: __('Fetch based on FIFO'),
|
||||
click: () => {
|
||||
let qty = this.dialog.fields_dict.qty.get_value();
|
||||
let numbers = frappe.call({
|
||||
method: "erpnext.stock.doctype.serial_no.serial_no.auto_fetch_serial_number",
|
||||
args: {
|
||||
qty: qty,
|
||||
item_code: me.item_code,
|
||||
warehouse: me.warehouse_details.name
|
||||
}
|
||||
});
|
||||
|
||||
numbers.then((data) => {
|
||||
let auto_fetched_serial_numbers = data.message;
|
||||
let records_length = auto_fetched_serial_numbers.length;
|
||||
if (records_length < qty) {
|
||||
frappe.msgprint(`Fetched only ${records_length} serial numbers.`);
|
||||
}
|
||||
let serial_no_list_field = this.dialog.fields_dict.serial_no;
|
||||
numbers = auto_fetched_serial_numbers.join('\n');
|
||||
serial_no_list_field.set_value(numbers);
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
if(this.has_batch) {
|
||||
if (this.has_batch) {
|
||||
title = __("Select Batch Numbers");
|
||||
fields = fields.concat(this.get_batch_fields());
|
||||
} else {
|
||||
@ -87,6 +114,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
fields: fields
|
||||
});
|
||||
|
||||
if (this.item.serial_no) {
|
||||
this.dialog.fields_dict.serial_no.set_value(this.item.serial_no);
|
||||
}
|
||||
|
||||
this.dialog.set_primary_action(__('Insert'), function() {
|
||||
me.values = me.dialog.get_values();
|
||||
if(me.validate()) {
|
||||
@ -234,7 +265,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
var me = this;
|
||||
return [
|
||||
{fieldtype:'Section Break', label: __('Batches')},
|
||||
{fieldname: 'batches', fieldtype: 'Table',
|
||||
{fieldname: 'batches', fieldtype: 'Table', label: __('Batch Entries'),
|
||||
fields: [
|
||||
{
|
||||
fieldtype:'Link',
|
||||
@ -343,10 +374,10 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
var me = this;
|
||||
this.serial_list = [];
|
||||
return [
|
||||
{fieldtype: 'Section Break', label: __('Serial No')},
|
||||
{fieldtype: 'Section Break', label: __('Serial Numbers')},
|
||||
{
|
||||
fieldtype: 'Link', fieldname: 'serial_no_select', options: 'Serial No',
|
||||
label: __('Select'),
|
||||
label: __('Select to add Serial Number.'),
|
||||
get_query: function() {
|
||||
return { filters: {item_code: me.item_code, warehouse: me.warehouse_details.name}};
|
||||
},
|
||||
@ -383,6 +414,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
{
|
||||
fieldname: 'serial_no',
|
||||
fieldtype: 'Small Text',
|
||||
label: __(me.has_batch ? 'Selected Batch Numbers' : 'Selected Serial Numbers'),
|
||||
onchange: function() {
|
||||
me.serial_list = this.get_value()
|
||||
.replace(/\n/g, ' ').match(/\S+/g) || [];
|
||||
|
@ -39,7 +39,6 @@ class Gstr1Report(object):
|
||||
shipping_bill_date,
|
||||
reason_for_issuing_document
|
||||
"""
|
||||
# self.customer_type = "Company" if self.filters.get("type_of_business") == "B2B" else "Individual"
|
||||
|
||||
def run(self):
|
||||
self.get_columns()
|
||||
@ -55,18 +54,50 @@ class Gstr1Report(object):
|
||||
return self.columns, self.data
|
||||
|
||||
def get_data(self):
|
||||
|
||||
if self.filters.get("type_of_business") == "B2C Small":
|
||||
self.get_b2cs_data()
|
||||
else:
|
||||
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
|
||||
invoice_details = self.invoices.get(inv)
|
||||
for rate, items in items_based_on_rate.items():
|
||||
row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
|
||||
|
||||
if self.filters.get("type_of_business") == "CDNR":
|
||||
row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
|
||||
row.append("C" if invoice_details.return_against else "R")
|
||||
|
||||
self.data.append(row)
|
||||
|
||||
def get_b2cs_data(self):
|
||||
b2cs_output = {}
|
||||
|
||||
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
|
||||
invoice_details = self.invoices.get(inv)
|
||||
|
||||
for rate, items in items_based_on_rate.items():
|
||||
row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
|
||||
if self.filters.get("type_of_business") == "B2C Small":
|
||||
row.append("E" if invoice_details.ecommerce_gstin else "OE")
|
||||
place_of_supply = invoice_details.get("place_of_supply")
|
||||
ecommerce_gstin = invoice_details.get("ecommerce_gstin")
|
||||
|
||||
if self.filters.get("type_of_business") == "CDNR":
|
||||
row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
|
||||
row.append("C" if invoice_details.return_against else "R")
|
||||
b2cs_output.setdefault((rate, place_of_supply, ecommerce_gstin),{
|
||||
"place_of_supply": "",
|
||||
"ecommerce_gstin": "",
|
||||
"rate": "",
|
||||
"taxable_value": 0,
|
||||
"cess_amount": 0,
|
||||
"type": 0
|
||||
})
|
||||
|
||||
self.data.append(row)
|
||||
row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin))
|
||||
row["place_of_supply"] = place_of_supply
|
||||
row["ecommerce_gstin"] = ecommerce_gstin
|
||||
row["rate"] = rate
|
||||
row["taxable_value"] += sum([abs(net_amount)
|
||||
for item_code, net_amount in self.invoice_items.get(inv).items() if item_code in items])
|
||||
row["type"] = "E" if ecommerce_gstin else "OE"
|
||||
|
||||
for key, value in iteritems(b2cs_output):
|
||||
self.data.append(value)
|
||||
|
||||
def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
|
||||
row = []
|
||||
@ -114,7 +145,6 @@ class Gstr1Report(object):
|
||||
if self.filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
|
||||
# customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type})
|
||||
|
||||
if self.filters.get("type_of_business") == "B2B":
|
||||
customers = frappe.get_all("Customer",
|
||||
|
@ -365,6 +365,8 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
fields: [
|
||||
{fieldtype:'Read Only', fieldname:'item_code',
|
||||
label: __('Item Code'), in_list_view:1},
|
||||
{fieldtype:'Link', fieldname:'warehouse', options: 'Warehouse',
|
||||
label: __('For Warehouse'), in_list_view:1},
|
||||
{fieldtype:'Link', fieldname:'bom', options: 'BOM', reqd: 1,
|
||||
label: __('BOM'), in_list_view:1, get_query: function(doc) {
|
||||
return {filters: {item: doc.item_code}};
|
||||
@ -372,8 +374,6 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
},
|
||||
{fieldtype:'Float', fieldname:'required_qty', reqd: 1,
|
||||
label: __('Qty'), in_list_view:1},
|
||||
{fieldtype:'Link', fieldname:'for_warehouse', options: 'Warehouse',
|
||||
label: __('For Warehouse')}
|
||||
],
|
||||
data: r.message,
|
||||
get_data: function() {
|
||||
|
@ -937,7 +937,12 @@ def make_raw_material_request(items, company, sales_order, project=None):
|
||||
item["ignore_existing_ordered_qty"] = items.get('ignore_existing_ordered_qty')
|
||||
item["include_raw_materials_from_sales_order"] = items.get('include_raw_materials_from_sales_order')
|
||||
|
||||
raw_materials = get_items_for_material_requests(items, sales_order, company)
|
||||
items.update({
|
||||
'company': company,
|
||||
'sales_order': sales_order
|
||||
})
|
||||
|
||||
raw_materials = get_items_for_material_requests(items)
|
||||
if not raw_materials:
|
||||
frappe.msgprint(_("Material Request not created, as quantity for Raw Materials already available."))
|
||||
return
|
||||
|
@ -54,8 +54,16 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
this.prepare_menu();
|
||||
this.set_online_status();
|
||||
},
|
||||
() => this.setup_company(),
|
||||
() => this.make_new_invoice(),
|
||||
() => {
|
||||
if(!this.frm.doc.company) {
|
||||
this.setup_company()
|
||||
.then((company) => {
|
||||
this.frm.doc.company = company;
|
||||
this.get_pos_profile();
|
||||
});
|
||||
}
|
||||
},
|
||||
() => {
|
||||
frappe.dom.unfreeze();
|
||||
},
|
||||
@ -63,6 +71,22 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
]);
|
||||
}
|
||||
|
||||
get_pos_profile() {
|
||||
return frappe.xcall("erpnext.stock.get_item_details.get_pos_profile",
|
||||
{'company': this.frm.doc.company})
|
||||
.then((r) => {
|
||||
if(r) {
|
||||
this.frm.doc.pos_profile = r.name;
|
||||
this.set_pos_profile_data()
|
||||
.then(() => {
|
||||
this.on_change_pos_profile();
|
||||
});
|
||||
} else {
|
||||
this.raise_exception_for_pos_profile();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set_online_status() {
|
||||
this.connection_status = false;
|
||||
this.page.set_indicator(__("Offline"), "grey");
|
||||
@ -77,6 +101,11 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
});
|
||||
}
|
||||
|
||||
raise_exception_for_pos_profile() {
|
||||
setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
|
||||
frappe.throw(__("POS Profile is required to use Point-of-Sale"));
|
||||
}
|
||||
|
||||
prepare_dom() {
|
||||
this.wrapper.append(`
|
||||
<div class="pos">
|
||||
@ -489,7 +518,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
|
||||
setup_company() {
|
||||
return new Promise(resolve => {
|
||||
if(!frappe.sys_defaults.company) {
|
||||
if(!this.frm.doc.company) {
|
||||
frappe.prompt({fieldname:"company", options: "Company", fieldtype:"Link",
|
||||
label: __("Select Company"), reqd: 1}, (data) => {
|
||||
this.company = data.company;
|
||||
@ -529,6 +558,10 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
return new Promise(resolve => {
|
||||
if (this.frm) {
|
||||
this.frm = get_frm(this.frm);
|
||||
if(this.company) {
|
||||
this.frm.doc.company = this.company;
|
||||
}
|
||||
|
||||
resolve();
|
||||
} else {
|
||||
frappe.model.with_doctype(doctype, () => {
|
||||
@ -545,6 +578,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
frm.refresh(name);
|
||||
frm.doc.items = [];
|
||||
frm.doc.is_pos = 1;
|
||||
|
||||
return frm;
|
||||
}
|
||||
}
|
||||
@ -554,6 +588,10 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
this.frm.doc.company = this.company;
|
||||
}
|
||||
|
||||
if (!this.frm.doc.company) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
return this.frm.call({
|
||||
doc: this.frm.doc,
|
||||
@ -562,8 +600,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
if(!r.exc) {
|
||||
if (!this.frm.doc.pos_profile) {
|
||||
frappe.dom.unfreeze();
|
||||
setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
|
||||
frappe.throw(__("POS Profile is required to use Point-of-Sale"));
|
||||
this.raise_exception_for_pos_profile();
|
||||
}
|
||||
this.frm.script_manager.trigger("update_stock");
|
||||
frappe.model.set_default_values(this.frm.doc);
|
||||
|
@ -47,9 +47,8 @@ def get_columns():
|
||||
},
|
||||
{
|
||||
"label": _("Material Request"),
|
||||
"options": "Material Request",
|
||||
"fieldname": "material_request",
|
||||
"fieldtype": "Link",
|
||||
"fieldtype": "Data",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
@ -116,33 +115,43 @@ def get_data():
|
||||
{"sales_order_item": ("!=",""), "docstatus": 1},
|
||||
["parent", "qty", "sales_order", "item_code"])
|
||||
|
||||
grouped_records = {}
|
||||
materials_request_dict = {}
|
||||
|
||||
for record in mr_records:
|
||||
grouped_records.setdefault(record.sales_order, []).append(record)
|
||||
key = (record.sales_order, record.item_code)
|
||||
if key not in materials_request_dict:
|
||||
materials_request_dict.setdefault(key, {
|
||||
'qty': 0,
|
||||
'material_requests': [record.parent]
|
||||
})
|
||||
|
||||
details = materials_request_dict.get(key)
|
||||
details['qty'] += record.qty
|
||||
|
||||
if record.parent not in details.get('material_requests'):
|
||||
details['material_requests'].append(record.parent)
|
||||
|
||||
pending_so=[]
|
||||
for so in sales_order_entry:
|
||||
# fetch all the material request records for a sales order item
|
||||
mr_list = grouped_records.get(so.name) or [{}]
|
||||
mr_item_record = ([mr for mr in mr_list if mr.get('item_code') == so.item_code] or [{}])
|
||||
key = (so.name, so.item_code)
|
||||
materials_request = materials_request_dict.get(key) or {}
|
||||
|
||||
for mr in mr_item_record:
|
||||
# check for pending sales order
|
||||
if cint(so.net_qty) > cint(mr.get('qty')):
|
||||
so_record = {
|
||||
"item_code": so.item_code,
|
||||
"item_name": so.item_name,
|
||||
"description": so.description,
|
||||
"sales_order_no": so.name,
|
||||
"date": so.transaction_date,
|
||||
"material_request": cstr(mr.get('parent')),
|
||||
"customer": so.customer,
|
||||
"territory": so.territory,
|
||||
"so_qty": so.net_qty,
|
||||
"requested_qty": cint(mr.get('qty')),
|
||||
"pending_qty": so.net_qty - cint(mr.get('qty')),
|
||||
"company": so.company
|
||||
}
|
||||
pending_so.append(so_record)
|
||||
# check for pending sales order
|
||||
if cint(so.net_qty) > cint(materials_request.get('qty')):
|
||||
so_record = {
|
||||
"item_code": so.item_code,
|
||||
"item_name": so.item_name,
|
||||
"description": so.description,
|
||||
"sales_order_no": so.name,
|
||||
"date": so.transaction_date,
|
||||
"material_request": ','.join(materials_request.get('material_requests', [])),
|
||||
"customer": so.customer,
|
||||
"territory": so.territory,
|
||||
"so_qty": so.net_qty,
|
||||
"requested_qty": cint(materials_request.get('qty')),
|
||||
"pending_qty": so.net_qty - cint(materials_request.get('qty')),
|
||||
"company": so.company
|
||||
}
|
||||
pending_so.append(so_record)
|
||||
return pending_so
|
@ -372,7 +372,7 @@ def replace_abbr(company, old, new):
|
||||
def _rename_record(doc):
|
||||
parts = doc[0].rsplit(" - ", 1)
|
||||
if len(parts) == 1 or parts[1].lower() == old.lower():
|
||||
frappe.rename_doc(dt, doc[0], parts[0] + " - " + new)
|
||||
frappe.rename_doc(dt, doc[0], parts[0] + " - " + new, force=True)
|
||||
|
||||
def _rename_records(dt):
|
||||
# rename is expensive so let's be economical with memory usage
|
||||
|
@ -101,6 +101,30 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
refresh: function(doc, dt, dn) {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
if ((!doc.is_return) && (doc.status!="Closed" || doc.is_new())) {
|
||||
if (this.frm.doc.docstatus===0) {
|
||||
this.frm.add_custom_button(__('Sales Order'),
|
||||
function() {
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
|
||||
source_doctype: "Sales Order",
|
||||
target: me.frm,
|
||||
setters: {
|
||||
customer: me.frm.doc.customer || undefined,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
status: ["not in", ["Closed", "On Hold"]],
|
||||
per_delivered: ["<", 99.99],
|
||||
company: me.frm.doc.company,
|
||||
project: me.frm.doc.project || undefined,
|
||||
}
|
||||
})
|
||||
}, __("Get items from"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!doc.is_return && doc.status!="Closed") {
|
||||
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
|
||||
this.frm.add_custom_button(__('Installation Note'), function() {
|
||||
@ -127,27 +151,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
||||
if (!doc.__islocal && doc.docstatus==1) {
|
||||
this.frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||
}
|
||||
|
||||
if (this.frm.doc.docstatus===0) {
|
||||
this.frm.add_custom_button(__('Sales Order'),
|
||||
function() {
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
|
||||
source_doctype: "Sales Order",
|
||||
target: me.frm,
|
||||
setters: {
|
||||
customer: me.frm.doc.customer || undefined,
|
||||
},
|
||||
get_query_filters: {
|
||||
docstatus: 1,
|
||||
status: ["not in", ["Closed", "On Hold"]],
|
||||
per_delivered: ["<", 99.99],
|
||||
company: me.frm.doc.company,
|
||||
project: me.frm.doc.project || undefined,
|
||||
}
|
||||
})
|
||||
}, __("Get items from"));
|
||||
}
|
||||
}
|
||||
|
||||
if (doc.docstatus==1) {
|
||||
|
@ -396,19 +396,7 @@ def get_invoiced_qty_map(delivery_note):
|
||||
|
||||
return invoiced_qty_map
|
||||
|
||||
def get_returned_qty_map_against_so(sales_orders):
|
||||
"""returns a map: {so_detail: returned_qty}"""
|
||||
returned_qty_map = {}
|
||||
|
||||
for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"],
|
||||
filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1):
|
||||
if not returned_qty_map.get(name):
|
||||
returned_qty_map[name] = 0
|
||||
returned_qty_map[name] += returned_qty
|
||||
|
||||
return returned_qty_map
|
||||
|
||||
def get_returned_qty_map_against_dn(delivery_note):
|
||||
def get_returned_qty_map(delivery_note):
|
||||
"""returns a map: {so_detail: returned_qty}"""
|
||||
returned_qty_map = frappe._dict(frappe.db.sql("""select dn_item.item_code, sum(abs(dn_item.qty)) as qty
|
||||
from `tabDelivery Note Item` dn_item, `tabDelivery Note` dn
|
||||
@ -425,8 +413,7 @@ def get_returned_qty_map_against_dn(delivery_note):
|
||||
def make_sales_invoice(source_name, target_doc=None):
|
||||
doc = frappe.get_doc('Delivery Note', source_name)
|
||||
sales_orders = [d.against_sales_order for d in doc.items]
|
||||
returned_qty_map_against_so = get_returned_qty_map_against_so(sales_orders)
|
||||
returned_qty_map_against_dn = get_returned_qty_map_against_dn(source_name)
|
||||
returned_qty_map = get_returned_qty_map(source_name)
|
||||
invoiced_qty_map = get_invoiced_qty_map(source_name)
|
||||
|
||||
def set_missing_values(source, target):
|
||||
@ -447,17 +434,16 @@ def make_sales_invoice(source_name, target_doc=None):
|
||||
|
||||
def update_item(source_doc, target_doc, source_parent):
|
||||
target_doc.qty, returned_qty = get_pending_qty(source_doc)
|
||||
if not source_doc.so_detail:
|
||||
returned_qty_map_against_dn[source_doc.item_code] = returned_qty
|
||||
returned_qty_map[source_doc.item_code] = returned_qty
|
||||
|
||||
if source_doc.serial_no and source_parent.per_billed > 0:
|
||||
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
|
||||
target_doc.qty, source_parent.name)
|
||||
|
||||
def get_pending_qty(item_row):
|
||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) - returned_qty_map_against_so.get(item_row.so_detail, 0)
|
||||
returned_qty = flt(returned_qty_map_against_dn.get(item_row.item_code, 0))
|
||||
if not item_row.so_detail:
|
||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
|
||||
returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
|
||||
if returned_qty:
|
||||
if returned_qty >= pending_qty:
|
||||
pending_qty = 0
|
||||
returned_qty -= pending_qty
|
||||
|
@ -655,7 +655,7 @@ class TestDeliveryNote(unittest.TestCase):
|
||||
si = make_sales_invoice(dn.name)
|
||||
self.assertEquals(si.items[0].qty, 1)
|
||||
|
||||
def test_make_sales_invoice_from_dn_with_returned_qty_against_dn(self):
|
||||
def test_make_sales_invoice_from_dn_with_returned_qty_duplicate_items(self):
|
||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
||||
|
||||
dn = create_delivery_note(qty=8, do_not_submit=True)
|
||||
|
@ -1062,3 +1062,7 @@ def update_variants(variants, template, publish_progress=True):
|
||||
count+=1
|
||||
if publish_progress:
|
||||
frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))
|
||||
|
||||
def on_doctype_update():
|
||||
# since route is a Text column, it needs a length for indexing
|
||||
frappe.db.add_index("Item", ["route(500)"])
|
||||
|
@ -407,10 +407,7 @@ def update_billed_amount_based_on_po(po_detail, update_modified=True):
|
||||
def make_purchase_invoice(source_name, target_doc=None):
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
doc = frappe.get_doc('Purchase Receipt', source_name)
|
||||
purchase_orders = [d.purchase_order for d in doc.items]
|
||||
returned_qty_map_against_po = get_returned_qty_map_against_po(purchase_orders)
|
||||
returned_qty_map_against_pr = get_returned_qty_map_against_pr(source_name)
|
||||
|
||||
returned_qty_map = get_returned_qty_map(source_name)
|
||||
invoiced_qty_map = get_invoiced_qty_map(source_name)
|
||||
|
||||
def set_missing_values(source, target):
|
||||
@ -424,14 +421,12 @@ def make_purchase_invoice(source_name, target_doc=None):
|
||||
|
||||
def update_item(source_doc, target_doc, source_parent):
|
||||
target_doc.qty, returned_qty = get_pending_qty(source_doc)
|
||||
if not source_doc.purchase_order_item:
|
||||
returned_qty_map_against_pr[source_doc.item_code] = returned_qty
|
||||
returned_qty_map[source_doc.item_code] = returned_qty
|
||||
|
||||
def get_pending_qty(item_row):
|
||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) \
|
||||
- returned_qty_map_against_po.get(item_row.purchase_order_item, 0)
|
||||
returned_qty = flt(returned_qty_map_against_pr.get(item_row.item_code, 0))
|
||||
if not item_row.purchase_order_item:
|
||||
pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
|
||||
returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
|
||||
if returned_qty:
|
||||
if returned_qty >= pending_qty:
|
||||
pending_qty = 0
|
||||
returned_qty -= pending_qty
|
||||
@ -484,19 +479,7 @@ def get_invoiced_qty_map(purchase_receipt):
|
||||
|
||||
return invoiced_qty_map
|
||||
|
||||
def get_returned_qty_map_against_po(purchase_orders):
|
||||
"""returns a map: {so_detail: returned_qty}"""
|
||||
returned_qty_map = {}
|
||||
|
||||
for name, returned_qty in frappe.get_all('Purchase Order Item', fields = ["name", "returned_qty"],
|
||||
filters = {'parent': ('in', purchase_orders), 'docstatus': 1}, as_list=1):
|
||||
if not returned_qty_map.get(name):
|
||||
returned_qty_map[name] = 0
|
||||
returned_qty_map[name] += returned_qty
|
||||
|
||||
return returned_qty_map
|
||||
|
||||
def get_returned_qty_map_against_pr(purchase_receipt):
|
||||
def get_returned_qty_map(purchase_receipt):
|
||||
"""returns a map: {so_detail: returned_qty}"""
|
||||
returned_qty_map = frappe._dict(frappe.db.sql("""select pr_item.item_code, sum(abs(pr_item.qty)) as qty
|
||||
from `tabPurchase Receipt Item` pr_item, `tabPurchase Receipt` pr
|
||||
|
@ -418,7 +418,7 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
pi = make_purchase_invoice(pr.name)
|
||||
self.assertEquals(pi.items[0].qty, 3)
|
||||
|
||||
def test_make_purchase_invoice_from_dn_with_returned_qty_against_dn(self):
|
||||
def test_make_purchase_invoice_from_pr_with_returned_qty_duplicate_items(self):
|
||||
pr1 = make_purchase_receipt(qty=8, do_not_submit=True)
|
||||
pr1.append("items", {
|
||||
"item_code": "_Test Item",
|
||||
|
@ -459,3 +459,13 @@ def get_delivery_note_serial_no(item_code, qty, delivery_note):
|
||||
serial_nos = '\n'.join(dn_serial_nos)
|
||||
|
||||
return serial_nos
|
||||
|
||||
@frappe.whitelist()
|
||||
def auto_fetch_serial_number(qty, item_code, warehouse):
|
||||
serial_numbers = frappe.get_list("Serial No", filters={
|
||||
"item_code": item_code,
|
||||
"warehouse": warehouse,
|
||||
"delivery_document_no": "",
|
||||
"sales_invoice": ""
|
||||
}, limit=qty, order_by="creation")
|
||||
return [item['name'] for item in serial_numbers]
|
||||
|
@ -60,7 +60,7 @@ $(document).ready(function() {
|
||||
</div>
|
||||
|
||||
|
||||
<p class='text-muted text-center small' style='margin-top: -20px;'><a href="https://erpnext.com/pricing">Start a free 30-day trial </a>
|
||||
<p class='text-muted text-center small' style='margin-top: -20px;'><a href="https://erpnext.com/pricing">Start a free 14-day trial </a>
|
||||
</p>
|
||||
<style>
|
||||
html, body {
|
||||
|
Loading…
x
Reference in New Issue
Block a user