[redesign] replace document flow with dashboard, sorry @saurabh6790, fixes #5792

This commit is contained in:
Rushabh Mehta 2016-07-20 22:53:23 +05:30
parent 39077d4210
commit 5a39d41a0c
14 changed files with 194 additions and 171 deletions

View File

@ -35,25 +35,6 @@ class PurchaseInvoice(BuyingController):
'percent_join_field': 'purchase_order',
'overflow_type': 'billing'
}]
self.prev_link_mapper = {
"Purchase Order": {
"fieldname": "purchase_order",
"doctype": "Purchase Invoice Item",
"filters": [
["Purchase Invoice Item", "parent", "=", self.name],
["Purchase Invoice Item", "purchase_order", "!=", ""]
]
},
"Purchase Receipt": {
"fieldname": "purchase_receipt",
"doctype": "Purchase Invoice Item",
"filters": [
["Purchase Invoice Item", "parent", "=", self.name],
["Purchase Invoice Item", "purchase_receipt", "!=", ""]
]
}
}
def validate(self):
if not self.is_opening:
@ -65,7 +46,7 @@ class PurchaseInvoice(BuyingController):
self.po_required()
self.pr_required()
self.validate_supplier_invoice()
# validate cash purchase
if (self.is_paid == 1):
@ -96,7 +77,7 @@ class PurchaseInvoice(BuyingController):
def create_remarks(self):
if not self.remarks:
if self.bill_no and self.bill_date:
self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no,
self.remarks = _("Against Supplier Invoice {0} dated {1}").format(self.bill_no,
formatdate(self.bill_date))
else:
self.remarks = _("No Remarks")
@ -165,32 +146,32 @@ class PurchaseInvoice(BuyingController):
["Purchase Order", "purchase_order", "po_detail"],
["Purchase Receipt", "purchase_receipt", "pr_detail"]
])
def set_expense_account(self):
auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
if auto_accounting_for_stock:
stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
stock_items = self.get_stock_items()
if self.update_stock:
warehouse_account = get_warehouse_account()
for item in self.get("items"):
# in case of auto inventory accounting,
# expense account is always "Stock Received But Not Billed" for a stock item
# expense account is always "Stock Received But Not Billed" for a stock item
# except epening entry, drop-ship entry and fixed asset items
if auto_accounting_for_stock and item.item_code in stock_items \
and self.is_opening == 'No' and not item.is_fixed_asset \
and (not item.po_detail or
and (not item.po_detail or
not frappe.db.get_value("Purchase Order Item", item.po_detail, "delivered_by_supplier")):
if self.update_stock:
item.expense_account = warehouse_account[item.warehouse]["name"]
else:
item.expense_account = stock_not_billed_account
elif not item.expense_account:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
@ -262,7 +243,7 @@ class PurchaseInvoice(BuyingController):
where name=`tabPurchase Invoice Item`.parent and update_stock=1 and is_return=1)"""
}
])
def validate_purchase_receipt_if_update_stock(self):
if self.update_stock:
for item in self.get("items"):
@ -273,30 +254,30 @@ class PurchaseInvoice(BuyingController):
def on_submit(self):
self.check_prev_docstatus()
self.update_status_updater_args()
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
self.company, self.base_grand_total)
if not self.is_return:
self.update_against_document_in_jv()
self.update_prevdoc_status()
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr()
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
if self.update_stock == 1:
self.update_stock_ledger()
from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
update_serial_nos_after_submit(self, "items")
# this sequence because outstanding may get -negative
self.make_gl_entries()
self.update_project()
self.update_fixed_asset()
def update_fixed_asset(self):
def update_fixed_asset(self):
for d in self.get("items"):
if d.is_fixed_asset:
asset = frappe.get_doc("Asset", d.asset)
@ -307,10 +288,10 @@ class PurchaseInvoice(BuyingController):
else:
asset.purchase_invoice = None
asset.supplier = None
asset.flags.ignore_validate_update_after_submit = True
asset.save()
def make_gl_entries(self, repost_future_gle=False):
self.auto_accounting_for_stock = \
cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))
@ -319,24 +300,24 @@ class PurchaseInvoice(BuyingController):
self.expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
self.negative_expense_to_be_booked = 0.0
gl_entries = []
self.make_supplier_gl_entry(gl_entries)
self.make_item_gl_entries(gl_entries)
self.make_tax_gl_entries(gl_entries)
gl_entries = merge_similar_entries(gl_entries)
self.make_payment_gl_entries(gl_entries)
self.make_write_off_gl_entry(gl_entries)
if gl_entries:
update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
make_gl_entries(gl_entries, cancel=(self.docstatus == 2),
update_outstanding=update_outstanding, merge_entries=False)
if update_outstanding == "No":
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,
self.doctype, self.return_against if cint(self.is_return) else self.name)
@ -345,10 +326,10 @@ class PurchaseInvoice(BuyingController):
from erpnext.controllers.stock_controller import update_gl_entries_after
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
elif self.docstatus == 2 and cint(self.update_stock) and self.auto_accounting_for_stock:
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
def make_supplier_gl_entry(self, gl_entries):
if self.grand_total:
@ -374,18 +355,18 @@ class PurchaseInvoice(BuyingController):
stock_items = self.get_stock_items()
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
warehouse_account = get_warehouse_account()
for item in self.get("items"):
if flt(item.base_net_amount):
account_currency = get_account_currency(item.expense_account)
if self.update_stock and self.auto_accounting_for_stock:
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
# warehouse account
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
* flt(item.qty) * flt(item.conversion_factor), item.precision("base_net_amount"))
gl_entries.append(
self.get_gl_dict({
"account": item.expense_account,
@ -396,7 +377,7 @@ class PurchaseInvoice(BuyingController):
"project": item.project
}, account_currency)
)
# Amount added through landed-cost-voucher
if flt(item.landed_cost_voucher_amount):
gl_entries.append(self.get_gl_dict({
@ -424,14 +405,14 @@ class PurchaseInvoice(BuyingController):
"account": item.expense_account,
"against": self.supplier,
"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
"debit_in_account_currency": (flt(item.base_net_amount,
item.precision("base_net_amount")) if account_currency==self.company_currency
"debit_in_account_currency": (flt(item.base_net_amount,
item.precision("base_net_amount")) if account_currency==self.company_currency
else flt(item.net_amount, item.precision("net_amount"))),
"cost_center": item.cost_center,
"project": item.project
}, account_currency)
)
if self.auto_accounting_for_stock and self.is_opening == "No" and \
item.item_code in stock_items and item.item_tax_amount:
# Post reverse entry for Stock-Received-But-Not-Billed if it is booked in Purchase Receipt
@ -480,7 +461,7 @@ class PurchaseInvoice(BuyingController):
valuation_tax.setdefault(tax.cost_center, 0)
valuation_tax[tax.cost_center] += \
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.base_tax_amount_after_discount_amount)
if self.is_opening == "No" and self.negative_expense_to_be_booked and valuation_tax:
# credit valuation tax amount in "Expenses Included In Valuation"
# this will balance out valuation amount included in cost of goods sold
@ -525,7 +506,7 @@ class PurchaseInvoice(BuyingController):
"against_voucher_type": self.doctype,
}, self.party_account_currency)
)
gl_entries.append(
self.get_gl_dict({
"account": self.cash_bank_account,
@ -568,9 +549,9 @@ class PurchaseInvoice(BuyingController):
def on_cancel(self):
self.check_for_closed_status()
self.update_status_updater_args()
if not self.is_return:
from erpnext.accounts.utils import remove_against_link_from_jv
remove_against_link_from_jv(self.doctype, self.name)
@ -579,11 +560,11 @@ class PurchaseInvoice(BuyingController):
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
self.update_billing_status_in_pr()
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
if self.update_stock == 1:
self.update_stock_ledger()
self.make_gl_entries_on_cancel()
self.update_project()
self.update_fixed_asset()
@ -637,7 +618,7 @@ class PurchaseInvoice(BuyingController):
for pr in set(updated_pr):
frappe.get_doc("Purchase Receipt", pr).update_billing_percentage(update_modified=update_modified)
def validate_fixed_asset_account(self):
for d in self.get('items'):
if d.is_fixed_asset:
@ -658,12 +639,11 @@ def get_fixed_asset_account(asset, account=None):
if account:
if frappe.db.get_value("Account", account, "account_type") != "Fixed Asset":
account=None
if not account:
asset_category, company = frappe.db.get_value("Asset", asset, ["asset_category", "company"])
account = frappe.db.get_value("Asset Category Account",
filters={"parent": asset_category, "company_name": company}, fieldname="fixed_asset_account")
return account

View File

@ -0,0 +1,31 @@
from frappe import _
data = {
'fieldname': 'purchase_invoice',
'non_standard_fieldnames': {
'Delivery Note': 'against_sales_invoice',
'Journal Entry': 'reference_name',
'Payment Entry': 'reference_name',
'Payment Request': 'reference_name',
'Landed Cost Voucher': 'receipt_document',
'Purchase Invoice': 'return_against'
},
'internal_links': {
'Purchase Order': ['items', 'sales_order'],
'Purchase Receipt': ['items', 'delivery_note'],
},
'transactions': [
{
'label': _('Payment'),
'items': ['Payment Entry', 'Payment Request', 'Journal Entry']
},
{
'label': _('Reference'),
'items': ['Purchase Order', 'Purchase Receipt', 'Asset', 'Landed Cost Voucher']
},
{
'label': _('Returns'),
'items': ['Purchase Invoice']
},
]
}

View File

@ -39,25 +39,6 @@ class SalesInvoice(SellingController):
'keyword': 'Billed',
'overflow_type': 'billing'
}]
self.prev_link_mapper = {
"Sales Order": {
"fieldname": "sales_order",
"doctype": "Sales Invoice Item",
"filters": [
["Sales Invoice Item", "parent", "=", self.name],
["Sales Invoice Item", "sales_order", "!=", ""]
]
},
"Delivery Note": {
"fieldname": "delivery_note",
"doctype": "Sales Invoice Item",
"filters": [
["Sales Invoice Item", "parent", "=", self.name],
["Sales Invoice Item", "delivery_note", "!=", ""]
]
}
}
def set_indicator(self):
"""Set indicator for portal"""

View File

@ -0,0 +1,30 @@
from frappe import _
data = {
'fieldname': 'sales_invoice',
'non_standard_fieldnames': {
'Delivery Note': 'against_sales_invoice',
'Journal Entry': 'reference_name',
'Payment Entry': 'reference_name',
'Payment Request': 'reference_name',
'Sales Invoice': 'return_against'
},
'internal_links': {
'Sales Order': ['items', 'sales_order'],
'Delivery Note': ['items', 'delivery_note'],
},
'transactions': [
{
'label': _('Payment'),
'items': ['Payment Entry', 'Payment Request', 'Journal Entry']
},
{
'label': _('Reference'),
'items': ['Timesheet', 'Delivery Note', 'Sales Order']
},
{
'label': _('Returns'),
'items': ['Sales Invoice']
},
]
}

View File

@ -32,17 +32,6 @@ class PurchaseOrder(BuyingController):
'percent_join_field': 'material_request',
'overflow_type': 'order'
}]
self.prev_link_mapper = {
"Supplier Quotation": {
"fieldname": "supplier_quotation",
"doctype": "Purchase Order Item",
"filters": [
["Purchase Order Item", "parent", "=", self.name],
["Purchase Order Item", "supplier_quotation", "!=", ""]
]
}
}
def validate(self):
super(PurchaseOrder, self).validate()

View File

@ -0,0 +1,20 @@
from frappe import _
data = {
'fieldname': 'supplier_quotation',
'internal_links': {
'Material Request': ['items', 'material_request'],
'Request for Quotation': ['items', 'request_for_quotation'],
'Project': ['items', 'project'],
},
'transactions': [
{
'label': _('Related'),
'items': ['Purchase Order']
},
{
'label': _('Reference'),
'items': ['Material Request', 'Request for Quotation', 'Project']
},
]
}

View File

@ -26,8 +26,7 @@
"public/js/payment/pos_payment.html",
"public/js/payment/payment_details.html",
"public/js/templates/item_selector.html",
"public/js/utils/item_selector.js",
"public/js/utils/document_flow.js"
"public/js/utils/item_selector.js"
],
"js/item-dashboard.min.js": [
"stock/dashboard/item_dashboard.html",

View File

@ -33,7 +33,7 @@ $.extend(erpnext, {
setup_serial_no: function() {
var grid_row = cur_frm.open_grid_row();
if(!grid_row.fields_dict.serial_no ||
if(!grid_row || !grid_row.fields_dict.serial_no ||
grid_row.fields_dict.serial_no.get_status()!=="Write") return;
var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')

View File

@ -1,27 +0,0 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
// for module flow
$.extend(frappe.document_flow, {
"Selling": {
// "Sales Order": ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "Payment Entry"],
// "Quotation": ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "Payment Entry"]
},
"Accounts": {
"Sales Invoice": ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "Payment Entry"],
"Purchase Invoice": ["Supplier Quotation", "Purchase Order", "Purchase Receipt",
"Purchase Invoice", "Payment Entry"]
},
"Buying": {
// "Purchase Order": ["Supplier Quotation", "Purchase Order", "Purchase Receipt",
// "Purchase Invoice", "Payment Entry"],
"Supplier Quotation": ["Supplier Quotation", "Purchase Order", "Purchase Receipt",
"Purchase Invoice", "Payment Entry"]
},
"Stock": {
"Delivery Note": ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "Payment Entry"],
"Purchase Receipt": ["Supplier Quotation", "Purchase Order", "Purchase Receipt",
"Purchase Invoice", "Payment Entry"]
}
});

View File

@ -24,17 +24,6 @@ class SalesOrder(SellingController):
def __init__(self, arg1, arg2=None):
super(SalesOrder, self).__init__(arg1, arg2)
self.prev_link_mapper = {
"Quotation": {
"fieldname": "prevdoc_docname",
"doctype": "Sales Order Item",
"filters": [
["Sales Order Item", "parent", "=", self.name],
["Sales Order Item", "prevdoc_docname", "!=", ""]
]
}
}
def validate(self):
super(SalesOrder, self).validate()

View File

@ -60,19 +60,7 @@ class DeliveryNote(SellingController):
'source_field': '-1 * qty',
'extra_cond': """ and exists (select name from `tabDelivery Note` where name=`tabDelivery Note Item`.parent and is_return=1)"""
}]
self.prev_link_mapper = {
"Sales Order": {
"fieldname": "against_sales_order",
"doctype": "Delivery Note Item",
"filters": [
["Delivery Note Item", "parent", "=", self.name],
["Delivery Note Item", "against_sales_order", "!=", ""]
]
}
}
def before_print(self):
def toggle_print_hide(meta, fieldname):
df = meta.get_field(fieldname)
@ -203,7 +191,7 @@ class DeliveryNote(SellingController):
if not self.is_return:
self.check_credit_limit()
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO
self.update_stock_ledger()
self.make_gl_entries()
@ -215,7 +203,7 @@ class DeliveryNote(SellingController):
self.update_prevdoc_status()
self.update_billing_status()
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating reserved qty in bin depends upon updated delivered qty in SO
self.update_stock_ledger()

View File

@ -0,0 +1,26 @@
from frappe import _
data = {
'fieldname': 'delivery_note_no',
'non_standard_fieldnames': {
'Sales Invoice': 'delivery_note',
'Packing Slip': 'delivery_note',
},
'internal_links': {
'Sales Order': ['items', 'against_sales_order'],
},
'transactions': [
{
'label': _('Related'),
'items': ['Sales Invoice', 'Packing Slip']
},
{
'label': _('Reference'),
'items': ['Sales Order', 'Quality Inspection']
},
{
'label': _('Returns'),
'items': ['Stock Entry']
},
]
}

View File

@ -44,17 +44,6 @@ class PurchaseReceipt(BuyingController):
# 'overflow_type': 'receipt',
'extra_cond': """ and exists (select name from `tabPurchase Receipt` where name=`tabPurchase Receipt Item`.parent and is_return=1)"""
}]
self.prev_link_mapper = {
"Purchase Order": {
"fieldname": "purchase_order",
"doctype": "Purchase Receipt Item",
"filters": [
["Purchase Receipt Item", "parent", "=", self.name],
["Purchase Receipt Item", "purchase_order", "!=", ""]
]
}
}
def validate(self):
super(PurchaseReceipt, self).validate()
@ -123,7 +112,7 @@ class PurchaseReceipt(BuyingController):
purchase_controller = frappe.get_doc("Purchase Common")
# Check for Approving Authority
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
self.company, self.base_grand_total)
# Set status as Submitted
@ -135,7 +124,7 @@ class PurchaseReceipt(BuyingController):
if not self.is_return:
purchase_controller.update_last_purchase_rate(self, 1)
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
self.update_stock_ledger()
@ -166,13 +155,13 @@ class PurchaseReceipt(BuyingController):
frappe.db.set(self,'status','Cancelled')
self.update_prevdoc_status()
self.update_prevdoc_status()
self.update_billing_status()
if not self.is_return:
pc_obj.update_last_purchase_rate(self, 0)
# Updating stock ledger should always be called after updating prevdoc status,
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
self.update_stock_ledger()
self.make_gl_entries_on_cancel()
@ -199,8 +188,8 @@ class PurchaseReceipt(BuyingController):
for d in self.get("items"):
if d.item_code in stock_items and flt(d.valuation_rate) and flt(d.qty):
if warehouse_account.get(d.warehouse):
stock_value_diff = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": self.name,
stock_value_diff = frappe.db.get_value("Stock Ledger Entry",
{"voucher_type": "Purchase Receipt", "voucher_no": self.name,
"voucher_detail_no": d.name}, "stock_value_difference")
if not stock_value_diff:
continue
@ -251,15 +240,15 @@ class PurchaseReceipt(BuyingController):
valuation_amount_as_per_doc = flt(d.base_net_amount, d.precision("base_net_amount")) + \
flt(d.landed_cost_voucher_amount) + flt(d.rm_supp_cost) + flt(d.item_tax_amount)
divisional_loss = flt(valuation_amount_as_per_doc - stock_value_diff,
divisional_loss = flt(valuation_amount_as_per_doc - stock_value_diff,
d.precision("base_net_amount"))
if divisional_loss:
if self.is_return or flt(d.item_tax_amount):
loss_account = expenses_included_in_valuation
else:
loss_account = stock_rbnb
gl_entries.append(self.get_gl_dict({
"account": loss_account,
"against": warehouse_account[d.warehouse]["name"],

View File

@ -0,0 +1,28 @@
from frappe import _
data = {
'fieldname': 'purchase_receipt_no',
'non_standard_fieldnames': {
'Purchase Invoice': 'purchase_receipt',
'Landed Cost Voucher': 'receipt_document'
},
'internal_links': {
'Purchase Order': ['items', 'purchase_order'],
'Project': ['items', 'project'],
'Quality Inspection': ['items', 'qa_no'],
},
'transactions': [
{
'label': _('Related'),
'items': ['Purchase Invoice', 'Landed Cost Voucher']
},
{
'label': _('Reference'),
'items': ['Purchase Order', 'Quality Inspection', 'Project']
},
{
'label': _('Returns'),
'items': ['Stock Entry']
},
]
}