[sales invoice] [update stock] allow update stock in sales invoice, without it being a pos invoice

This commit is contained in:
Anand Doshi 2013-05-30 17:43:30 +05:30
parent c6f890f892
commit ecc28f0311
12 changed files with 115 additions and 101 deletions

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-05-09 13:16:11",
"creation": "2013-05-24 12:15:51",
"docstatus": 0,
"modified": "2013-05-23 12:52:09",
"modified": "2013-05-30 12:09:39",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -18,8 +18,7 @@
"parent": "POS Setting",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"read_only": 0
"permlevel": 0
},
{
"doctype": "DocPerm",
@ -44,7 +43,8 @@
"label": "User",
"oldfieldname": "user",
"oldfieldtype": "Link",
"options": "Profile"
"options": "Profile",
"read_only": 0
},
{
"doctype": "DocField",
@ -54,6 +54,7 @@
"oldfieldname": "territory",
"oldfieldtype": "Link",
"options": "Territory",
"read_only": 0,
"reqd": 1
},
{
@ -64,6 +65,7 @@
"no_copy": 1,
"oldfieldname": "naming_series",
"oldfieldtype": "Select",
"read_only": 0,
"reqd": 1
},
{
@ -74,6 +76,7 @@
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"read_only": 0,
"reqd": 1
},
{
@ -84,6 +87,7 @@
"label": "Conversion Rate",
"oldfieldname": "conversion_rate",
"oldfieldtype": "Currency",
"read_only": 0,
"reqd": 1
},
{
@ -94,6 +98,7 @@
"oldfieldname": "price_list_name",
"oldfieldtype": "Select",
"options": "link:Price List",
"read_only": 0,
"reqd": 1
},
{
@ -105,13 +110,24 @@
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break",
"oldfieldtype": "Column Break"
"oldfieldtype": "Column Break",
"read_only": 0
},
{
"default": "1",
"description": "Create Stock Ledger Entries when you submit a Sales Invoice",
"doctype": "DocField",
"fieldname": "update_stock",
"fieldtype": "Check",
"label": "Update Stock",
"reqd": 0
},
{
"doctype": "DocField",
@ -121,6 +137,7 @@
"oldfieldname": "customer_account",
"oldfieldtype": "Link",
"options": "Account",
"read_only": 0,
"reqd": 0
},
{
@ -131,6 +148,7 @@
"oldfieldname": "cash_bank_account",
"oldfieldtype": "Link",
"options": "Account",
"read_only": 0,
"reqd": 1
},
{
@ -141,6 +159,7 @@
"oldfieldname": "income_account",
"oldfieldtype": "Link",
"options": "Account",
"read_only": 0,
"reqd": 1
},
{
@ -152,6 +171,7 @@
"label": "Expense Account",
"options": "Account",
"print_hide": 1,
"read_only": 0,
"reqd": 0
},
{
@ -162,6 +182,7 @@
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"read_only": 0,
"reqd": 1
},
{
@ -172,6 +193,7 @@
"oldfieldname": "cost_center",
"oldfieldtype": "Link",
"options": "Cost Center",
"read_only": 0,
"reqd": 1
},
{
@ -181,7 +203,8 @@
"label": "Charge",
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Master"
"options": "Sales Taxes and Charges Master",
"read_only": 0
},
{
"doctype": "DocField",
@ -191,7 +214,8 @@
"oldfieldname": "letter_head",
"oldfieldtype": "Select",
"options": "link:Letter Head",
"print_hide": 1
"print_hide": 1,
"read_only": 0
},
{
"doctype": "DocField",
@ -200,7 +224,8 @@
"label": "Terms and Conditions",
"oldfieldname": "tc_name",
"oldfieldtype": "Link",
"options": "Terms and Conditions"
"options": "Terms and Conditions",
"read_only": 0
},
{
"doctype": "DocField",
@ -210,17 +235,10 @@
"label": "Select Print Heading",
"oldfieldname": "select_print_heading",
"oldfieldtype": "Select",
"options": "link:Print Heading"
"options": "link:Print Heading",
"read_only": 0
},
{
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"role": "System Manager",
"write": 1
},
{
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"role": "Accounts Manager",

View File

@ -125,13 +125,12 @@ cur_frm.cscript.hide_fields = function(doc, cdt, cdn) {
hide_field(par_flds);
unhide_field('payments_section');
for(f in item_flds_normal) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal[f], false);
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], (doc.update_stock==1?true:false));
} else {
hide_field('payments_section');
unhide_field(par_flds);
for(f in item_flds_normal) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal[f], true);
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], false);
}
for(f in item_flds_pos) cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos[f], (cint(doc.update_stock)==1?true:false));
// India related fields
var cp = wn.control_panel;

View File

@ -57,18 +57,22 @@ class DocType(SellingController):
self.validate_fixed_asset_account()
self.clear_unallocated_advances("Sales Invoice Advance", "advance_adjustment_details")
self.add_remarks()
if cint(self.doc.is_pos):
self.validate_pos()
self.validate_write_off_account()
if cint(self.doc.update_stock):
sl = get_obj('Stock Ledger')
sl.validate_serial_no(self, 'entries')
sl.validate_serial_no(self, 'packing_details')
self.validate_item_code()
self.update_current_stock()
self.validate_delivery_note()
if cint(self.doc.update_stock):
sl = get_obj('Stock Ledger')
sl.validate_serial_no(self, 'entries')
sl.validate_serial_no(self, 'packing_details')
self.validate_item_code()
self.update_current_stock()
self.validate_delivery_note()
if not self.doc.is_opening:
self.doc.is_opening = 'No'
self.set_aging_date()
self.set_against_income_account()
self.validate_c_form()
@ -78,16 +82,15 @@ class DocType(SellingController):
def on_submit(self):
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
sl_obj = get_obj("Stock Ledger")
sl_obj.validate_serial_no_warehouse(self, 'entries')
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
self.update_stock_ledger(update_stock=1)
if cint(self.doc.update_stock) == 1:
sl_obj = get_obj("Stock Ledger")
sl_obj.validate_serial_no_warehouse(self, 'entries')
sl_obj.validate_serial_no_warehouse(self, 'packing_details')
sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
self.update_stock_ledger(update_stock=1)
else:
# Check for Approving Authority
if not self.doc.recurring_id:
@ -112,13 +115,12 @@ class DocType(SellingController):
self.update_time_log_batch(None)
def on_cancel(self):
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
sl = get_obj('Stock Ledger')
sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
self.update_stock_ledger(update_stock = -1)
if cint(self.doc.update_stock) == 1:
sl = get_obj('Stock Ledger')
sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
self.update_stock_ledger(update_stock = -1)
sales_com_obj = get_obj(dt = 'Sales Common')
sales_com_obj.check_stop_sales_order(self)
@ -181,6 +183,9 @@ class DocType(SellingController):
'price_list_name', 'company', 'select_print_heading', 'cash_bank_account'):
if (not for_validate) or (for_validate and not self.doc.fields.get(fieldname)):
self.doc.fields[fieldname] = pos.get(fieldname)
if not for_validate:
self.doc.update_stock = cint(pos.get("update_stock"))
# set pos values in items
for item in self.doclist.get({"parentfield": "entries"}):
@ -265,14 +270,6 @@ class DocType(SellingController):
ret = self.get_debit_to()
self.doc.debit_to = ret.get('debit_to')
@property
def pos_settings(self):
if not hasattr(self, "_pos_settings"):
from selling.utils import get_pos_settings
self._pos_settings = get_pos_settings({"company": self.doc.company})
return self._pos_settings
def get_barcode_details(self, barcode):
return get_obj('Sales Common').get_barcode_details(barcode)
@ -442,13 +439,13 @@ class DocType(SellingController):
def validate_item_code(self):
for d in getlist(self.doclist, 'entries'):
if not d.item_code:
msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
raise Exception
msgprint("Please enter Item Code at line no : %s to update stock or remove check from Update Stock in Basic Info Tab." % (d.idx),
raise_exception=True)
def validate_delivery_note(self):
for d in self.doclist.get({"parentfield": "entries"}):
if d.delivery_note:
msgprint("""POS can not be made against Delivery Note""", raise_exception=1)
msgprint("""Stock update can not be made against Delivery Note""", raise_exception=1)
def validate_write_off_account(self):
@ -514,39 +511,29 @@ class DocType(SellingController):
def on_update(self):
# Set default warehouse from pos setting
if cint(self.doc.is_pos) == 1:
if cint(self.doc.update_stock) == 1:
if cint(self.doc.update_stock) == 1:
# Set default warehouse from pos setting
if cint(self.doc.is_pos) == 1:
w = self.get_warehouse()
if w:
for d in getlist(self.doclist, 'entries'):
if not d.warehouse:
d.warehouse = cstr(w)
self.make_packing_list()
else:
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
if flt(self.doc.paid_amount) == 0:
if self.doc.cash_bank_account:
webnotes.conn.set(self.doc, 'paid_amount',
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
else:
# show message that the amount is not paid
webnotes.conn.set(self.doc,'paid_amount',0)
webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
if flt(self.doc.paid_amount) == 0:
if self.doc.cash_bank_account:
webnotes.conn.set(self.doc, 'paid_amount',
(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
else:
# show message that the amount is not paid
webnotes.conn.set(self.doc,'paid_amount',0)
webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
self.make_packing_list()
else:
self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
webnotes.conn.set(self.doc,'paid_amount',0)
# TODO
# move to calculations
webnotes.conn.set(self.doc, 'outstanding_amount',
flt(self.doc.grand_total) - flt(self.doc.total_advance) -
flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
def check_prev_docstatus(self):
for d in getlist(self.doclist,'entries'):
if d.sales_order:
@ -663,7 +650,7 @@ class DocType(SellingController):
# expense account gl entries
if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \
and cint(self.doc.is_pos) and cint(self.doc.update_stock):
and cint(self.doc.update_stock):
for item in self.doclist.get({"parentfield": "entries"}):
self.check_expense_account(item)

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:05",
"docstatus": 0,
"modified": "2013-05-28 18:23:35",
"modified": "2013-05-29 18:53:26",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -80,7 +80,6 @@
"read_only": 0
},
{
"depends_on": "eval:doc.is_pos==1",
"doctype": "DocField",
"fieldname": "update_stock",
"fieldtype": "Check",

View File

@ -1,6 +1,6 @@
import webnotes
import unittest, json
from webnotes.utils import flt
from webnotes.utils import flt, cint
class TestSalesInvoice(unittest.TestCase):
def make(self):

View File

@ -92,7 +92,7 @@ def get_source_data(filters):
timestamp(si.posting_date, si.posting_time) as posting_datetime
from `tabSales Invoice` si, `tabSales Invoice Item` item
where item.parent = si.name and si.docstatus = 1 %s
and si.is_pos = 1 and si.update_stock = 1
and si.update_stock = 1
order by si.posting_date desc, si.posting_time desc""" % (conditions,), filters, as_dict=1)
source = delivery_note_items + sales_invoice_items

View File

@ -0,0 +1,18 @@
import webnotes, webnotes.defaults
from webnotes.utils import cint
def execute():
webnotes.reload_doc("accounts", "doctype", "pos_setting")
webnotes.conn.sql("""update `tabPOS Setting` set update_stock=%s""",
cint(webnotes.defaults.get_global_default("update_stock")))
webnotes.conn.sql("""delete from `tabSingles`
where doctype='Global Defaults' and field='update_stock'""")
webnotes.conn.sql("""delete from `tabDefaultValue`
where parent='Control Panel' and defkey="update_stock" """)
webnotes.defaults.clear_cache("Control Panel")
webnotes.reload_doc("setup", "doctype", "global_defaults")

View File

@ -254,4 +254,5 @@ patch_list = [
"patches.may_2013.p04_reorder_level",
"patches.may_2013.p05_update_cancelled_gl_entries",
"patches.may_2013.p06_make_notes",
"patches.may_2013.p07_move_update_stock_to_pos",
]

View File

@ -89,7 +89,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
company: me.frm.doc.company,
order_type: me.frm.doc.order_type,
is_pos: cint(me.frm.doc.is_pos),
update_stock: cint(me.frm.doc.update_stock),
}
},
callback: function(r) {

View File

@ -46,7 +46,6 @@ keydict = {
'maintain_same_rate' : 'maintain_same_rate',
'session_expiry': 'session_expiry',
'disable_rounded_total': 'disable_rounded_total',
"update_stock": "update_stock",
"auto_inventory_accounting": "auto_inventory_accounting",
}

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-02 17:53:24",
"docstatus": 0,
"modified": "2013-05-22 15:57:26",
"modified": "2013-05-30 12:23:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -27,8 +27,6 @@
"permlevel": 0
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"doctype": "DocPerm",
"name": "__common__",
@ -326,14 +324,6 @@
"fieldtype": "Column Break",
"read_only": 0
},
{
"description": "If checked, then in POS Sales Invoice, Update Stock gets checked by default",
"doctype": "DocField",
"fieldname": "update_stock",
"fieldtype": "Check",
"label": "Update Stock when using POS Sales Invoice",
"read_only": 0
},
{
"doctype": "DocField",
"fieldname": "account_info",
@ -526,6 +516,11 @@
"label": "SMS Sender Name",
"read_only": 0
},
{
"amend": 0,
"cancel": 0,
"doctype": "DocPerm"
},
{
"doctype": "DocPerm"
}

View File

@ -285,11 +285,10 @@ class DocType(StockController):
+ _("Status should be Submitted"), raise_exception=webnotes.InvalidStatusError)
# update stock check
if ref.doclist[0].doctype == "Sales Invoice" and (cint(ref.doclist[0].is_pos) != 1 \
or cint(ref.doclist[0].update_stock) != 1):
webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": '
+ _("Is POS and Update Stock should be checked."),
raise_exception=NotUpdateStockError)
if ref.doclist[0].doctype == "Sales Invoice" and cint(ref.doclist[0].update_stock) != 1:
webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": '
+ _("Update Stock should be checked."),
raise_exception=NotUpdateStockError)
# posting date check
ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date),
@ -684,7 +683,7 @@ def get_production_order_details(production_order):
def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters):
conditions = ""
if doctype == "Sales Invoice":
conditions = "and is_pos=1 and update_stock=1"
conditions = "and update_stock=1"
return webnotes.conn.sql("""select name, customer, customer_name
from `tab%s` where docstatus = 1