[merge] merged with master
This commit is contained in:
commit
3eb901f47d
@ -167,7 +167,7 @@ erpnext.POS = Class.extend({
|
||||
"fieldtype": "Data",
|
||||
"label": "Barcode",
|
||||
"fieldname": "pos_barcode",
|
||||
"placeholder": "Barcode"
|
||||
"placeholder": "Barcode / Serial No"
|
||||
},
|
||||
parent: this.wrapper.find(".barcode-area")
|
||||
});
|
||||
@ -228,7 +228,7 @@ erpnext.POS = Class.extend({
|
||||
}
|
||||
});
|
||||
},
|
||||
add_to_cart: function(item_code) {
|
||||
add_to_cart: function(item_code, serial_no) {
|
||||
var me = this;
|
||||
var caught = false;
|
||||
|
||||
@ -239,39 +239,46 @@ erpnext.POS = Class.extend({
|
||||
if (no_of_items != 0) {
|
||||
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||
if (d.item_code == item_code)
|
||||
if (d.item_code == item_code) {
|
||||
caught = true;
|
||||
if (serial_no) {
|
||||
d.serial_no += '\n' + serial_no;
|
||||
me.frm.script_manager.trigger("serial_no", d.doctype, d.name);
|
||||
}
|
||||
else {
|
||||
d.qty += 1;
|
||||
me.frm.script_manager.trigger("qty", d.doctype, d.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// if duplicate row then append the qty
|
||||
if (caught) {
|
||||
me.update_qty(item_code, 1);
|
||||
}
|
||||
else {
|
||||
// if item not found then add new item
|
||||
if (!caught) {
|
||||
var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
|
||||
this.frm.cscript.fname);
|
||||
child.item_code = item_code;
|
||||
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
|
||||
|
||||
if (serial_no)
|
||||
child.serial_no = serial_no;
|
||||
|
||||
me.frm.script_manager.trigger("item_code", child.doctype, child.name);
|
||||
}
|
||||
me.refresh();
|
||||
},
|
||||
update_qty: function(item_code, qty, textbox_qty) {
|
||||
update_qty: function(item_code, qty) {
|
||||
var me = this;
|
||||
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
|
||||
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
|
||||
if (d.item_code == item_code) {
|
||||
if (textbox_qty) {
|
||||
if (qty == 0 && d.item_code == item_code)
|
||||
wn.model.clear_doc(d.doctype, d.name);
|
||||
if (qty == 0)
|
||||
wn.model.clear_doc(d.doctype, d.name);
|
||||
else {
|
||||
d.qty = qty;
|
||||
me.frm.script_manager.trigger("qty", d.doctype, d.name);
|
||||
}
|
||||
else
|
||||
d.qty += 1;
|
||||
|
||||
me.frm.cscript.qty(me.frm.doc, d.doctype, d.name);
|
||||
}
|
||||
});
|
||||
me.frm.dirty();
|
||||
me.refresh();
|
||||
},
|
||||
refresh: function() {
|
||||
@ -352,7 +359,7 @@ erpnext.POS = Class.extend({
|
||||
// append quantity to the respective item after change from input box
|
||||
$(this.wrapper).find("input.qty").on("change", function() {
|
||||
var item_code = $(this).closest("tr")[0].id;
|
||||
me.update_qty(item_code, $(this).val(), true);
|
||||
me.update_qty(item_code, $(this).val());
|
||||
});
|
||||
|
||||
// on td click toggle the highlighting of row
|
||||
@ -407,11 +414,14 @@ erpnext.POS = Class.extend({
|
||||
var me = this;
|
||||
me.barcode_timeout = null;
|
||||
wn.call({
|
||||
method: 'accounts.doctype.sales_invoice.pos.get_item_from_barcode',
|
||||
args: {barcode: this.barcode.$input.val()},
|
||||
method: 'accounts.doctype.sales_invoice.pos.get_item_code',
|
||||
args: {barcode_serial_no: this.barcode.$input.val()},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
me.add_to_cart(r.message[0].name);
|
||||
if (r.message[1] == "serial_no")
|
||||
me.add_to_cart(r.message[0][0].item_code, r.message[0][0].name);
|
||||
else
|
||||
me.add_to_cart(r.message[0][0].name);
|
||||
}
|
||||
else
|
||||
msgprint(wn._("Invalid Barcode"));
|
||||
@ -443,7 +453,6 @@ erpnext.POS = Class.extend({
|
||||
});
|
||||
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
|
||||
this.frm.script_manager.trigger("calculate_taxes_and_totals");
|
||||
me.frm.dirty();
|
||||
me.refresh();
|
||||
},
|
||||
make_payment: function() {
|
||||
|
@ -20,25 +20,30 @@ def get_items(price_list, sales_or_purchase, item=None, item_group=None):
|
||||
condition += " and i.name='%s'" % item
|
||||
|
||||
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
|
||||
pl_items.ref_rate, pl_items.currency
|
||||
item_det.ref_rate, item_det.currency
|
||||
from `tabItem` i LEFT JOIN
|
||||
(select ip.item_code, ip.ref_rate, pl.currency from
|
||||
`tabItem Price` ip, `tabPrice List` pl
|
||||
where ip.parent=%s and ip.parent = pl.name) pl_items
|
||||
(select item_code, ref_rate, currency from
|
||||
`tabItem Price` where price_list=%s) item_det
|
||||
ON
|
||||
pl_items.item_code=i.name
|
||||
item_det.item_code=i.name
|
||||
where
|
||||
%s""" % ('%s', condition), (price_list), as_dict=1)
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_item_from_barcode(barcode):
|
||||
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
||||
(barcode), as_dict=1)
|
||||
def get_item_code(barcode_serial_no):
|
||||
input_via = "serial_no"
|
||||
item_code = webnotes.conn.sql("""select name, item_code from `tabSerial No` where
|
||||
name=%s""", (barcode_serial_no), as_dict=1)
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_item_from_serial_no(serial_no):
|
||||
return webnotes.conn.sql("""select name, item_code from `tabSerial No` where
|
||||
name=%s""", (serial_no), as_dict=1)
|
||||
if not item_code:
|
||||
input_via = "barcode"
|
||||
item_code = webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
|
||||
(barcode_serial_no), as_dict=1)
|
||||
|
||||
if item_code:
|
||||
return item_code, input_via
|
||||
else:
|
||||
webnotes.throw("Invalid Barcode / Serial No")
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_mode_of_payment():
|
||||
|
@ -30,8 +30,12 @@ def process_gl_map(gl_map, merge_entries=True):
|
||||
entry.credit = flt(entry.credit, 2)
|
||||
|
||||
# toggle debit, credit if negative entry
|
||||
if flt(entry.debit) < 0 or flt(entry.credit) < 0:
|
||||
entry.debit, entry.credit = abs(flt(entry.credit)), abs(flt(entry.debit))
|
||||
if flt(entry.debit) < 0:
|
||||
entry.credit = flt(entry.credit) - flt(entry.debit)
|
||||
entry.debit = 0.0
|
||||
if flt(entry.credit) < 0:
|
||||
entry.debit = flt(entry.debit) - flt(entry.credit)
|
||||
entry.credit = 0.0
|
||||
|
||||
return gl_map
|
||||
|
||||
|
@ -67,9 +67,14 @@ wn.module_page["Buying"] = [
|
||||
},
|
||||
{
|
||||
label: wn._("Price List"),
|
||||
description: wn._("Mupltiple Item prices."),
|
||||
description: wn._("Multiple Price list."),
|
||||
doctype:"Price List"
|
||||
},
|
||||
{
|
||||
label: wn._("Item Price"),
|
||||
description: wn._("Multiple Item prices."),
|
||||
doctype:"Item Price"
|
||||
},
|
||||
{
|
||||
"doctype":"Supplier Type",
|
||||
"label": wn._("Supplier Type"),
|
||||
|
@ -89,10 +89,9 @@ def _get_price_list_rate(args, item_bean, meta):
|
||||
|
||||
# try fetching from price list
|
||||
if args.buying_price_list and args.price_list_currency:
|
||||
price_list_rate = webnotes.conn.sql("""select ip.ref_rate from `tabItem Price` ip,
|
||||
`tabPrice List` pl where ip.parent = pl.name and ip.parent=%s and
|
||||
ip.item_code=%s and pl.buying_or_selling='Buying'""",
|
||||
(args.buying_price_list, args.item_code), as_dict=1)
|
||||
price_list_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||
where price_list=%s and item_code=%s and buying_or_selling='Buying'""",
|
||||
(args.buying_price_list, args.item_code), as_dict=1)
|
||||
|
||||
if price_list_rate:
|
||||
from utilities.transaction_base import validate_currency
|
||||
|
@ -12,18 +12,17 @@ from accounts.general_ledger import make_gl_entries, delete_gl_entries
|
||||
|
||||
class StockController(AccountsController):
|
||||
def make_gl_entries(self):
|
||||
if not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
return
|
||||
|
||||
warehouse_account = self.get_warehouse_account()
|
||||
|
||||
if self.doc.docstatus==1:
|
||||
gl_entries = self.get_gl_entries_for_stock(warehouse_account)
|
||||
make_gl_entries(gl_entries)
|
||||
else:
|
||||
if self.doc.docstatus == 2:
|
||||
delete_gl_entries(voucher_type=self.doc.doctype, voucher_no=self.doc.name)
|
||||
|
||||
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
warehouse_account = self.get_warehouse_account()
|
||||
|
||||
self.update_gl_entries_after(warehouse_account)
|
||||
if self.doc.docstatus==1:
|
||||
gl_entries = self.get_gl_entries_for_stock(warehouse_account)
|
||||
make_gl_entries(gl_entries)
|
||||
|
||||
self.update_gl_entries_after(warehouse_account)
|
||||
|
||||
def get_gl_entries_for_stock(self, warehouse_account=None, default_expense_account=None,
|
||||
default_cost_center=None):
|
||||
@ -91,9 +90,6 @@ class StockController(AccountsController):
|
||||
return stock_ledger
|
||||
|
||||
def get_warehouse_account(self):
|
||||
for d in webnotes.conn.sql("select name from tabWarehouse"):
|
||||
webnotes.bean("Warehouse", d[0]).save()
|
||||
|
||||
warehouse_account = dict(webnotes.conn.sql("""select master_name, name from tabAccount
|
||||
where account_type = 'Warehouse' and ifnull(master_name, '') != ''"""))
|
||||
return warehouse_account
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
{
|
||||
"_label": "Login"
|
||||
}
|
||||
---
|
||||
To login into the customer account, the customer has to use his email id and the password sent by ERPNext; generated through the sign-up process.
|
||||
|
||||
![Login](img/customer-portal-login.png)
|
16
docs/user/customer_portal/docs.user.customer_portal.md
Normal file
16
docs/user/customer_portal/docs.user.customer_portal.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
{
|
||||
"_label": "Customer Portal",
|
||||
"_toc": [
|
||||
"docs.user.customer_portal.sign_up",
|
||||
"docs.user.customer_portal.login",
|
||||
"docs.user.customer_portal.orders",
|
||||
"docs.user.customer_portal.tickets"
|
||||
]
|
||||
}
|
||||
---
|
||||
|
||||
Customer Portal is designed to give easy accesibility to customers of a company.
|
||||
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
---
|
||||
{
|
||||
"_label": "Customer Orders, Invoices, and Shipping Status"
|
||||
}
|
||||
---
|
||||
ERPNext Web Portal gives your customers quick access to their Orders, Invoices and Shipments
|
||||
Customers can check the status of their orders, invoices, and shipping status by logging on to the web.
|
||||
|
||||
|
||||
![Portal Menu](img/portal-menu.png)
|
||||
|
||||
|
||||
|
||||
Once an order is raised, either using the Shopping Cart or from within ERPNext, your customer can view the order and keep an eye on the billing and shipment status. When the invoice and payment against these orders are submitted, the customer can see the updated status on the portal, at a glance.
|
||||
|
||||
|
||||
![Customer Portal](img/customer-portal-orders-1.png)
|
||||
|
||||
|
||||
#### Invoice with paid status.
|
||||
|
||||
|
||||
![Invoice Paid](img/portal-invoice-paid.png)
|
||||
|
||||
|
||||
#### Invoice with billed status.
|
||||
|
||||
|
||||
![Billed Invoice](img/portal-order-billed.png)
|
||||
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
{
|
||||
"_label": "Sign-Up"
|
||||
}
|
||||
---
|
||||
Customers have to log-in to the Company Website, and sign-up as a customer.
|
||||
|
||||
#### Step 1: Click on Login Icon
|
||||
|
||||
![Sign Up](img/customer-portal-sign-up-1.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Step 2: Click on Sign Up Icon
|
||||
|
||||
![Sign Up](img/customer-portal-sign-up-2.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Step 3: Enter Customer Name and ID
|
||||
|
||||
![Sign Up](img/customer-portal-sign-up-3.png)
|
||||
|
||||
After the sign up process, a mail will be sent to the customers email id with the password details.
|
||||
|
@ -0,0 +1,28 @@
|
||||
---
|
||||
{
|
||||
"_label": "Support Tickets"
|
||||
}
|
||||
---
|
||||
|
||||
The customer portal makes it very easy for a customer to raise concerns. A simple and intuitive interface facilitates your customer to report their concerns as Support Tickets. They can view the complete thread of their conversation.
|
||||
|
||||
#### Empty Ticket List
|
||||
|
||||
![Ticket List](img/portal-ticket-list-empty.png)
|
||||
|
||||
|
||||
|
||||
#### New Support Ticket
|
||||
|
||||
![New Ticket](img/portal-new-ticket.png)
|
||||
|
||||
|
||||
#### Open Support Ticket
|
||||
|
||||
![Open Support Ticket](img/portal-ticket-1.png)
|
||||
|
||||
|
||||
#### Reply on Support Ticket
|
||||
|
||||
![Reply Support Ticket](img/portal-ticket-reply.png)
|
||||
|
@ -7,18 +7,20 @@ A very common customization is adding of custom fields. You can add Custom Field
|
||||
|
||||
> Setup > Custom Field > New Custom Field
|
||||
|
||||
![Custome Field](img/custom-field.png)
|
||||
![Custom Field](img/custom-field.png)
|
||||
|
||||
|
||||
|
||||
In the form:
|
||||
|
||||
- Select the Document on which you want to add the Custom Field.
|
||||
- Select the Type of field and the Options (see section on field types).
|
||||
- Select the Type of field and the Options .
|
||||
- Select where you want the field to appear in the Form (“after field” section).
|
||||
|
||||
and save the Custom Field. When you open a new / existing form of the type you selected in step 1, you will see it with the Custom Fields.
|
||||
|
||||
To understand Custom Fields in detail, visit [DocType-Fields](docs.user.knowledge.doctype_fields.html)
|
||||
|
||||
#### Naming
|
||||
|
||||
Many times you want your fields to be carried over from one form to another. For example, you may have added a Custom Field in Quotation that you want to include in Sales Order when a Sales Order is created from the Quotation. This is simple in ERPNext, just make sure the fields have the same “fieldname”
|
||||
|
@ -3,12 +3,13 @@
|
||||
"_label": "Customize Form"
|
||||
}
|
||||
---
|
||||
Please read ERPNext Structure before you start customizing.
|
||||
|
||||
You can Customize Forms by changing its layout, making certain fields mandatory, hiding others and changing permission levels on fields by going to:
|
||||
|
||||
> Setup > Customize ERPNext > Customize Forms
|
||||
|
||||
#### Step 1: Select the required Form Type for Customization.
|
||||
|
||||
|
||||
![Customize Forms](img/customize-form-1.png)
|
||||
|
||||
@ -24,12 +25,14 @@ Select the Form you want to customize and the fields table will be updated with
|
||||
|
||||
You can also allow attachments, set max number of attachments and set the default Print Format.
|
||||
|
||||
#### Step 2: Replace Fields with required changes.
|
||||
|
||||
![Customize Forms](img/customize-form-2.png)
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
To understand field definitions, visit [Doctype-Fields](docs.user.knowledge.doctype_fields.html)
|
||||
|
||||
|
||||
> Though we want you to do everything you can to customize your ERP based on your business needs, we recommend that you do not make “wild” changes to the forms. This is because, these changes may affect certain operations and may mess up your forms. Make small changes and see its effect before doing some more.
|
@ -17,8 +17,9 @@
|
||||
"docs.user.website",
|
||||
"docs.user.tools",
|
||||
"docs.user.customize",
|
||||
"docs.user.knowledge"
|
||||
],
|
||||
"docs.user.knowledge",
|
||||
"docs.user.customer_portal"
|
||||
],
|
||||
"_no_toc": 1
|
||||
}
|
||||
---
|
||||
@ -70,6 +71,7 @@ Contents
|
||||
1. [Terms and Conditions](docs.user.selling.terms.html)
|
||||
1. [Price Lists](docs.user.setup.price_list.html)
|
||||
1. [Discount](docs.user.selling.discount.html)
|
||||
1. [Shopping Cart](docs.user.selling.shopping_cart.html)
|
||||
1. [Customers](docs.user.selling.customer.html)
|
||||
1. [Lead](docs.user.selling.lead.html)
|
||||
1. [Opportunity](docs.user.selling.opportunity.html)
|
||||
@ -88,6 +90,7 @@ Contents
|
||||
1. [Warehouse](docs.user.stock.warehouse.html)
|
||||
1. [Item Group](docs.user.stock.item_group.html)
|
||||
1. [Item](docs.user.stock.item.html)
|
||||
1. [Product Listing on Website](docs.user.stock.product_listing_on_website.html)
|
||||
1. [Serialized Inventory](docs.user.stock.serialized.html)
|
||||
1. [Purchase Receipt](docs.user.stock.purchase_receipt.html)
|
||||
1. [Delivery Note](docs.user.stock.delivery_note.html)
|
||||
@ -159,5 +162,11 @@ Contents
|
||||
1. [Accounting Knowledge](docs.user.knowledge.accounting.html)
|
||||
1. [Accounting Entries](docs.user.knowledge.accounting_entries.html)
|
||||
1. [DocType Definitions](docs.user.knowledge.doctype.html)
|
||||
1. [DocType Fields](docs.user.knowledge.doctype_fields.html)
|
||||
1. [Attachment and CSV Files](docs.user.knowledge.attachment_csv.html)
|
||||
1. [Format using Markdown](docs.user.knowledge.markdown.html)
|
||||
1. [Customer Portal](docs.user.customer_portal.html)
|
||||
1. [Sign Up](docs.user.customer_portal.sign_up.html)
|
||||
2. [Login](docs.user.customer_portal.login.html)
|
||||
3. [Customer Orders](docs.user.customer_portal.orders.html)
|
||||
4. [Support Tickets](docs.user.customer_portal.tickets.html)
|
||||
|
@ -71,197 +71,3 @@ Many DocTypes are single tables, but some work in groups. For example, Quotation
|
||||
|
||||
There are a certain type of DocTypes that are “Single”, i.e. they have no table associated and have only one record of its fields. DocTypes such as Global Defaults, Production Planning Tool are “Single” DocTypes.
|
||||
|
||||
#### Field Columns
|
||||
|
||||
In the fields table, there are many columns, here is an explanation of the columns of the field table.
|
||||
|
||||
<table class="table table-bordered text-left">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<td width="30%">Column</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Label</td>
|
||||
<td>Field Label (that appears in the form).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td>Field Type</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Column name in the database, must be code friendly with no white spaces, special characters and capital letters.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>options</td>
|
||||
<td>Field settings:<br>
|
||||
For Select: List of options (each on a new line).<br>
|
||||
For Link: DocType that is “linked”.<br>
|
||||
For HTML: HTML Content
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Perm Level</td>
|
||||
<td>Permission level (number) of the field. You can group fields by numbers, called levels, and apply rules on the levels.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Width</td>
|
||||
<td>Width of the field (in pixels) - useful for “Table” types.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Reqd</td>
|
||||
<td>Checked if field is mandatory (required).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>In Filter</td>
|
||||
<td>Checked if field appears as a standard filter in old style reports.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hidden</td>
|
||||
<td>Checked if field is hidden.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Print Hide</td>
|
||||
<td>Checked if field is hidden in Print Formats.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Report Hide</td>
|
||||
<td>Checked if field is hidden in old style reports.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Allow on Submit</td>
|
||||
<td>Checked if this field can be edited after the document is “Submitted”.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Depends On</td>
|
||||
<td>The fieldname of the field that will decide whether this field will be shown or hidden. It is useful to hide un-necessary fields.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>Description of the field</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Default</td>
|
||||
<td>Default value when a new record is created.<br>
|
||||
Note: “user” will set the current user as default and “today” will set today’s date (if the field is a Date field).</td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<table>
|
||||
|
||||
#### Field Types and Options
|
||||
|
||||
Here is a list of the different types of fields used to make / customize forms in ERPNext.
|
||||
|
||||
<table class="table table-bordered text-left">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<td width="30%">Type</td>
|
||||
<td>Description</td>
|
||||
<td>Options/Setting</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Data</td>
|
||||
<td>Single line text field with 180 characters</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Select</td>
|
||||
<td>Select from a pre-determined items in a drop-down.</td>
|
||||
<td>The “Options” contains the drop-down items, each on a new row</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Link</td>
|
||||
<td>Link an existing document / record</td>
|
||||
<td>Options contains the name of the type of document (DocType)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Currency</td>
|
||||
<td>Number with 2 decimal places, that will be shown separated by commas for thousands etc. in Print.</td>
|
||||
<td>e.g. 1,000,000.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Float</td>
|
||||
<td>Number with 6 decimal places.</td>
|
||||
<td>e.g. 3.141593</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Int</td>
|
||||
<td>Integer (no decimals)</td>
|
||||
<td>e.g. 100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>Date</td>
|
||||
<td>Format can be selected in Global Defaults</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Time</td>
|
||||
<td>Time</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Text</td>
|
||||
<td>Multi-line text box without formatting features</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Text editor</td>
|
||||
<td>Multi-line text box with formatting toolbar etc</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Code</td>
|
||||
<td>Code Editor</td>
|
||||
<td>Options can include the type of language for syntax formatting.
|
||||
Eg JS / Python / HTML</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Table (Grid)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Table</td>
|
||||
<td>Table of child items linked to the record.</td>
|
||||
<td>Options contains the name of the DocType of the child table. For example “Sales Invoice Item” for “Sales Invoice”</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Layout</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Section Break</td>
|
||||
<td>Break into a new horizontal section.</td>
|
||||
<td>The layout in ERPNext is evaluated from top to bottom.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Column Break</td>
|
||||
<td>Break into a new vertical column.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTML</td>
|
||||
<td>Add a static text / help / link etc in HTML</td>
|
||||
<td>Options contains the HTML.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Action</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button</td>
|
||||
<td>Button</td>
|
||||
<td>[for developers only]</td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
201
docs/user/knowledge/docs.user.knowledge.doctype_fields.md
Normal file
201
docs/user/knowledge/docs.user.knowledge.doctype_fields.md
Normal file
@ -0,0 +1,201 @@
|
||||
---
|
||||
{
|
||||
"_label": "DocType-Fields"
|
||||
}
|
||||
---
|
||||
|
||||
#### Field Columns
|
||||
|
||||
In the fields table, there are many columns. The columns of the field table are explained below:
|
||||
|
||||
<table class="table table-bordered text-left">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<td width="30%">Column</td>
|
||||
<td>Description</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Label</td>
|
||||
<td>Field Label (that appears in the form).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td>Field Type</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>Column name in the database, must be code friendly with no white spaces, special characters and capital letters.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>options</td>
|
||||
<td>Field settings:<br>
|
||||
For Select: List of options (each on a new line).<br>
|
||||
For Link: DocType that is “linked”.<br>
|
||||
For HTML: HTML Content
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Perm Level</td>
|
||||
<td>Permission level (number) of the field. You can group fields by numbers, called levels, and apply rules on the levels.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Width</td>
|
||||
<td>Width of the field (in pixels) - useful for “Table” types.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Reqd</td>
|
||||
<td>Checked if field is mandatory (required).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>In Filter</td>
|
||||
<td>Checked if field appears as a standard filter in old style reports.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Hidden</td>
|
||||
<td>Checked if field is hidden.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Print Hide</td>
|
||||
<td>Checked if field is hidden in Print Formats.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Report Hide</td>
|
||||
<td>Checked if field is hidden in old style reports.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Allow on Submit</td>
|
||||
<td>Checked if this field can be edited after the document is “Submitted”.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Depends On</td>
|
||||
<td>The fieldname of the field that will decide whether this field will be shown or hidden. It is useful to hide un-necessary fields.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>Description of the field</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Default</td>
|
||||
<td>Default value when a new record is created.<br>
|
||||
Note: “user” will set the current user as default and “today” will set today’s date (if the field is a Date field).</td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<table>
|
||||
|
||||
|
||||
#### Field Types and Options
|
||||
|
||||
Here is a list of the different types of fields used to make / customize forms in ERPNext.
|
||||
|
||||
<table class="table table-bordered text-left">
|
||||
<thead>
|
||||
<tr class="active">
|
||||
<td width="30%">Type</td>
|
||||
<td>Description</td>
|
||||
<td>Options/Setting</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Data</td>
|
||||
<td>Single line text field with 180 characters</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Select</td>
|
||||
<td>Select from a pre-determined items in a drop-down.</td>
|
||||
<td>The “Options” contains the drop-down items, each on a new row</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Link</td>
|
||||
<td>Link an existing document / record</td>
|
||||
<td>Options contains the name of the type of document (DocType)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Currency</td>
|
||||
<td>Number with 2 decimal places, that will be shown separated by commas for thousands etc. in Print.</td>
|
||||
<td>e.g. 1,000,000.00</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Float</td>
|
||||
<td>Number with 6 decimal places.</td>
|
||||
<td>e.g. 3.141593</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Int</td>
|
||||
<td>Integer (no decimals)</td>
|
||||
<td>e.g. 100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date</td>
|
||||
<td>Date</td>
|
||||
<td>Format can be selected in Global Defaults</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Time</td>
|
||||
<td>Time</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Text</td>
|
||||
<td>Multi-line text box without formatting features</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Text editor</td>
|
||||
<td>Multi-line text box with formatting toolbar etc</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Code</td>
|
||||
<td>Code Editor</td>
|
||||
<td>Options can include the type of language for syntax formatting.
|
||||
Eg JS / Python / HTML</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Table (Grid)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Table</td>
|
||||
<td>Table of child items linked to the record.</td>
|
||||
<td>Options contains the name of the DocType of the child table. For example “Sales Invoice Item” for “Sales Invoice”</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Layout</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Section Break</td>
|
||||
<td>Break into a new horizontal section.</td>
|
||||
<td>The layout in ERPNext is evaluated from top to bottom.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Column Break</td>
|
||||
<td>Break into a new vertical column.</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>HTML</td>
|
||||
<td>Add a static text / help / link etc in HTML</td>
|
||||
<td>Options contains the HTML.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3" class="active">Action</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Button</td>
|
||||
<td>Button</td>
|
||||
<td>[for developers only]</td>
|
||||
</tr>
|
||||
<tbody>
|
||||
<table>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
"docs.user.knowledge.accounting",
|
||||
"docs.user.knowledge.accounting_entries",
|
||||
"docs.user.knowledge.doctype",
|
||||
"docs.user.knowledge.doctype_fields",
|
||||
"docs.user.knowledge.attachment_csv",
|
||||
"docs.user.knowledge.markdown"
|
||||
]
|
||||
|
@ -9,6 +9,9 @@
|
||||
"docs.user.selling.sales_person",
|
||||
"docs.user.selling.campaign",
|
||||
"docs.user.selling.terms",
|
||||
"docs.user.setup.price_list",
|
||||
"docs.user.selling.discount",
|
||||
"docs.user.selling.shopping_cart",
|
||||
"docs.user.selling. customer",
|
||||
"docs.user.selling.lead",
|
||||
"docs.user.selling.opportunity",
|
||||
|
41
docs/user/selling/docs.user.selling.shopping_cart.md
Normal file
41
docs/user/selling/docs.user.selling.shopping_cart.md
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
{
|
||||
"_label": "Shopping Cart"
|
||||
}
|
||||
---
|
||||
On the Webpage, a shopping cart is an icon that allows you to store all the things that you have earmarked for purchasing. It is a graphical representation of a shopping basket or a shopping cart that allows you to save the items you intend to buy.
|
||||
|
||||
This software displays the price of the product . It also displays shipping and handling charges, along with taxes, if applicable.
|
||||
|
||||
To set up a shopping cart, go to the selling module.
|
||||
|
||||
> Selling > Shopping Cart Settings
|
||||
|
||||
|
||||
#### Step 1: Enter Company Details and Default Territory.
|
||||
|
||||
|
||||
![Shopping Cart](img/shopping-cart-1.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Step 2: Enter Price List, Tax Master and Shipping Rule.
|
||||
|
||||
|
||||
![Shopping Cart](img/shopping-cart-2.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Shopping Cart Display
|
||||
|
||||
On the Website, the shopping cart image will be seen below the Item price. Customers can click on the cart and enter the amount of quantity they wish to buy. The Item number will be stored on the right hand corner of the page, next to the flower sign.
|
||||
|
||||
![Shopping Cart](img/shopping-cart-display-1.png)
|
||||
|
||||
<br>
|
||||
|
||||
Click on the flower sign on the right hand side to see the cart details. Click on the cart to get the final amount details.
|
||||
|
||||
|
||||
![Shopping Cart](img/shopping-cart-display-amount.png)
|
||||
|
@ -7,14 +7,18 @@ One of the primary motivator for compulsory use of accounting tools is calculati
|
||||
|
||||
### Tax Accounts
|
||||
|
||||
For Tax Accounts that you want to use in the tax templates, you must mention them as type “Tax” in your Chart of Accounts. Some Item-tax features are given below :
|
||||
For Tax Accounts that you want to use in the tax templates, you must go to Chart of Accounts and mention them as type “Tax” in your Chart of Item.
|
||||
|
||||
## Item Tax
|
||||
|
||||
If some of your Items require different tax rates as compared to others, mention them in the Item tax table. Even if you have selected your sales and purchase taxes as default tax rates, the system will pull the Item tax rate for calculations. Item tax will get preference over other sales or purchase taxes. However, if you wish to apply default sales and purchase taxes, do not mention item tax rates in the Item master. The system will then select the sales or purchase tax rate specified by you as default rates.
|
||||
|
||||
![Item Tax](img/item-tax-1.png)
|
||||
|
||||
|
||||
- **Discount**: The maximum Discount that can be applied on an Item can be fixed in the Item master. Read [Discount](docs.user.selling.discount.html)
|
||||
- **Inclusive and Exclusive Tax**: ERPNext allows you to enter Item rates which are tax inclusive.
|
||||
- **Flat Discount**: This feature will be added soon.
|
||||
- **Exception to the rule**: Item tax settings are required only if a particular Item has a different tax rate than the rate defined in the standard tax Account
|
||||
|
||||
|
||||
- **Item tax is overwrite-able**: You can overwrite or change the item tax rate by going to the Item master in the Item tax table.
|
||||
|
||||
## Sales Taxes and Charges Master
|
||||
|
||||
@ -22,6 +26,8 @@ You must usually collect taxes from your Customer and pay them to the government
|
||||
|
||||
The way ERPNext sets up taxes is via templates. Other types of charges that may apply to your invoices (like shipping, insurance etc.) can also be configured as taxes.
|
||||
|
||||
Select template and modify as per your need.
|
||||
|
||||
To create a new sales tax template called Sales Taxes and Charges Master, you have to go to:
|
||||
|
||||
> Setup > Accounts > Sales Taxes and Charge Master
|
||||
@ -38,9 +44,11 @@ The tax rate you define here will be the standard tax rate for all Items. If the
|
||||
In each row, you have to mention:
|
||||
|
||||
- Calculation Type:
|
||||
- This can be on net total (that is your basic amount).
|
||||
- On previous row total / amount (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
|
||||
- Actual (as mentioned).
|
||||
- On Net Total : This can be on net total (total amount without taxes).
|
||||
- On Previous Row Total/Amount: You can apply taxes on previous row total / amount. If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total. Previous row amount means a particular tax amount.And, previous row total means net total plus taxes applied up to that row. In the Enter Row Field, mention row number on which you want to apply the current tax. If you want to apply the tax on the 3rd row, mention "3" in the Enter Row field.
|
||||
|
||||
- Actual : Enter as per actual amount in rate column.
|
||||
|
||||
- Account Head: The Account ledger under which this tax will be booked
|
||||
- Cost Center: If the tax / charge is an income (like shipping) it needs to be booked against - a Cost Center.
|
||||
- Description: Description of the tax (that will be printed in invoices / quotes).
|
||||
|
@ -92,58 +92,4 @@ Inspection Criteria: If a Quality Inspection is prepared for this Item, then thi
|
||||
|
||||
Visit [Manufacturing](docs.user.mfg.html) and [Website](docs.user.website.html) to understand these topics in detail.
|
||||
|
||||
### Listing Item on Website
|
||||
|
||||
To list your Item on the Website, fill the Item details and save the file. Once the file is saved, a plus (+) button will appear next to the Image icon. Click on the plus button and add your Item image. The html code will be generated automatically.
|
||||
|
||||
##### Step 1: Save Image
|
||||
|
||||
![Webimage](img/item-webimage.png)
|
||||
|
||||
<br>
|
||||
|
||||
##### Step 2: Check the 'Show in Website' box.
|
||||
|
||||
Under the Website section, please check the box that says 'show in Website'. Once the box is checked, the page will display other fields for entering information.
|
||||
|
||||
![Webimage](img/item-webimage-1.png)
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
##### Step 3: Enter Website Details
|
||||
|
||||
![Webimage](img/item-webimage-2.png)
|
||||
|
||||
|
||||
The page name will be generated automatically. Mention the Item-Group under which the Item will be displayed.
|
||||
|
||||
#### Item Groups
|
||||
|
||||
Mention the Item Group under this column. If you wish to list your Item under the broad category products, name your Item Group as Products. In case you have various varieties of Item and want to classify them under different names, make Item Groups with those names and check the box that says 'show in Website'. For Example, if you wish to create a category called 'Bags', create a Item Group named Bags.
|
||||
|
||||
|
||||
![Item Group](img/itemgroup-webimage-bags.png)
|
||||
|
||||
Once the Item Group is created go to the Website Settings page under Website. Enter the Label, Url, and Parent Label.
|
||||
|
||||
|
||||
![Item Group](img/itemgroup-website-settings.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Webpage labels
|
||||
|
||||
![Webpage](img/webpage-labels.png)
|
||||
|
||||
Add more Items under a particular Item Group.
|
||||
|
||||
To add more Items under a certain Label, mention the Item Group on the Item Page. The Items will be added automatically on the Webpage, under the Item Group Label. For Example, To add Item-Kiddies Bag and Butterfly Print Bag, check the 'Show in Website'box. The Items will be placed under the Label Bags on the Webpage.
|
||||
|
||||
![Item Group](img/itemgroup-websettings.png)
|
||||
|
||||
<br>
|
||||
|
||||
Item Group Display
|
||||
|
||||
![Item Group Display](img/webpage-itemgroup-display.png)
|
||||
To list your products on the website and understand this process in detail, visit [Product Listing On Website](docs.user.stock.product_listing_on_website.html)
|
||||
|
@ -5,6 +5,7 @@
|
||||
"docs.user.stock.warehouse",
|
||||
"docs.user.stock.item_group",
|
||||
"docs.user.stock.item",
|
||||
"docs.user.stock.product_listing_on_website",
|
||||
"docs.user.stock.serialized",
|
||||
"docs.user.stock.purchase_receipt",
|
||||
"docs.user.stock.delivery_note",
|
||||
|
@ -0,0 +1,61 @@
|
||||
---
|
||||
{
|
||||
"_label": "Product Listing on Website"
|
||||
}
|
||||
---
|
||||
|
||||
### Listing Item on Website
|
||||
|
||||
To list your Item on the Website, fill the Item details and save the file. Once the file is saved, a plus (+) button will appear next to the Image icon. Click on the plus button and add your Item image. The html code will be generated automatically.
|
||||
|
||||
##### Step 1: Save Image
|
||||
|
||||
![Webimage](img/item-webimage.png)
|
||||
|
||||
<br>
|
||||
|
||||
##### Step 2: Check the 'Show in Website' box.
|
||||
|
||||
Under the Website section, please check the box that says 'show in Website'. Once the box is checked, the page will display other fields for entering information.
|
||||
|
||||
![Webimage](img/item-webimage-1.png)
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
##### Step 3: Enter Website Details
|
||||
|
||||
![Webimage](img/item-webimage-2.png)
|
||||
|
||||
|
||||
The page name will be generated automatically. Mention the Item-Group under which the Item will be displayed.
|
||||
|
||||
#### Item Groups
|
||||
|
||||
Mention the Item Group under this column. If you wish to list your Item under the broad category products, name your Item Group as Products. In case you have various varieties of Item and want to classify them under different names, make Item Groups with those names and check the box that says 'show in Website'. For Example, if you wish to create a category called 'Bags', create a Item Group named Bags.
|
||||
|
||||
|
||||
![Item Group](img/itemgroup-webimage-bags.png)
|
||||
|
||||
Once the Item Group is created go to the Website Settings page under Website. Enter the Label, Url, and Parent Label.
|
||||
|
||||
|
||||
![Item Group](img/itemgroup-website-settings.png)
|
||||
|
||||
<br>
|
||||
|
||||
#### Webpage labels
|
||||
|
||||
![Webpage](img/webpage-labels.png)
|
||||
|
||||
Add more Items under a particular Item Group.
|
||||
|
||||
To add more Items under a certain Label, mention the Item Group on the Item Page. The Items will be added automatically on the Webpage, under the Item Group Label. For Example, To add Item-Kiddies Bag and Butterfly Print Bag, check the 'Show in Website'box. The Items will be placed under the Label Bags on the Webpage.
|
||||
|
||||
![Item Group](img/itemgroup-websettings.png)
|
||||
|
||||
<br>
|
||||
|
||||
Item Group Display
|
||||
|
||||
![Item Group Display](img/webpage-itemgroup-display.png)
|
@ -14,6 +14,7 @@ def make():
|
||||
out.seek(0)
|
||||
last_commit = None
|
||||
for l in out.readlines():
|
||||
l = l.decode('utf-8')
|
||||
if last_commit is not None:
|
||||
if l.startswith("Date:"):
|
||||
last_commit["date"] = l[8:-1]
|
||||
@ -59,4 +60,4 @@ def make():
|
||||
lufile.write(json.dumps(logs, indent=1, sort_keys=True))
|
||||
|
||||
if __name__=="__main__":
|
||||
make()
|
||||
make()
|
||||
|
@ -120,7 +120,7 @@ class DocType:
|
||||
elif self.doc.rm_cost_as_per == "Price List":
|
||||
if not self.doc.buying_price_list:
|
||||
webnotes.throw(_("Please select Price List"))
|
||||
rate = webnotes.conn.get_value("Item Price", {"parent": self.doc.buying_price_list,
|
||||
rate = webnotes.conn.get_value("Item Price", {"price_list": self.doc.buying_price_list,
|
||||
"item_code": arg["item_code"]}, "ref_rate") or 0
|
||||
elif self.doc.rm_cost_as_per == 'Standard Rate':
|
||||
rate = arg['standard_rate']
|
||||
@ -413,7 +413,9 @@ def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1):
|
||||
ifnull(sum(bom_item.qty_consumed_per_unit),0) * %(qty)s as qty,
|
||||
item.description,
|
||||
item.stock_uom,
|
||||
item.default_warehouse
|
||||
item.default_warehouse,
|
||||
item.purchase_account as expense_account,
|
||||
item.cost_center
|
||||
from
|
||||
`tab%(table)s` bom_item, `tabItem` item
|
||||
where
|
||||
@ -452,4 +454,4 @@ def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1):
|
||||
def get_bom_items(bom, qty=1, fetch_exploded=1):
|
||||
items = get_bom_items_as_dict(bom, qty, fetch_exploded).values()
|
||||
items.sort(lambda a, b: a.item_code > b.item_code and 1 or -1)
|
||||
return items
|
||||
return items
|
||||
|
@ -4,5 +4,7 @@
|
||||
import webnotes
|
||||
|
||||
def execute():
|
||||
webnotes.delete_doc("DocType", "Sales and Purchase Return Item")
|
||||
webnotes.delete_doc("DocType", "Sales and Purchase Return Tool")
|
||||
if webnotes.conn.exists("DocType", "Sales and Purchase Return Item"):
|
||||
webnotes.delete_doc("DocType", "Sales and Purchase Return Item")
|
||||
if webnotes.conn.exists("DocType", "Sales and Purchase Return Tool"):
|
||||
webnotes.delete_doc("DocType", "Sales and Purchase Return Tool")
|
@ -11,6 +11,7 @@ def execute():
|
||||
and docstatus=2""" % (entry['voucher_type'], "%s"), entry['voucher_no'])
|
||||
is_cancelled = docstatus and 'Yes' or None
|
||||
if is_cancelled:
|
||||
print entry['voucher_type'], entry['voucher_no']
|
||||
webnotes.conn.sql("""update `tabGL Entry` set is_cancelled = 'Yes'
|
||||
where voucher_type = %s and voucher_no = %s""",
|
||||
(entry['voucher_type'], entry['voucher_no']))
|
||||
|
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
def execute():
|
||||
webnotes.reload_doc("setup", "doctype", "item_price")
|
||||
|
||||
webnotes.conn.sql("""update `tabItem Price` ip, `tabItem` i
|
||||
set ip.item_name=i.item_name, ip.item_description=i.description
|
||||
where ip.item_code=i.name""")
|
||||
|
||||
webnotes.conn.sql("""update `tabItem Price` ip, `tabPrice List` pl
|
||||
set ip.price_list=pl.name, ip.currency=pl.currency,
|
||||
ip.buying_or_selling=pl.buying_or_selling
|
||||
where ip.parent=pl.name""")
|
||||
|
||||
webnotes.conn.sql("""update `tabItem Price`
|
||||
set parent=null, parenttype=null, parentfield=null, idx=null""")
|
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
def execute():
|
||||
from patches.march_2013 import p06_remove_sales_purchase_return_tool
|
||||
p06_remove_sales_purchase_return_tool.execute()
|
9
patches/october_2013/p04_update_report_permission.py
Normal file
9
patches/october_2013/p04_update_report_permission.py
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
import webnotes
|
||||
|
||||
def execute():
|
||||
webnotes.conn.sql("""update tabDocPerm set `create`=1 where
|
||||
parent='Report'
|
||||
and role in ('Administrator', 'Report Manager', 'System Manager')""")
|
@ -0,0 +1,16 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
def execute():
|
||||
import webnotes
|
||||
entries = webnotes.conn.sql("""select voucher_type, voucher_no
|
||||
from `tabGL Entry` group by voucher_type, voucher_no""", as_dict=1)
|
||||
for entry in entries:
|
||||
try:
|
||||
cancelled_voucher = webnotes.conn.sql("""select name from `tab%s` where name = %s
|
||||
and docstatus=2""" % (entry['voucher_type'], "%s"), entry['voucher_no'])
|
||||
if cancelled_voucher:
|
||||
webnotes.conn.sql("""delete from `tabGL Entry` where voucher_type = %s and
|
||||
voucher_no = %s""", (entry['voucher_type'], entry['voucher_no']))
|
||||
except:
|
||||
pass
|
@ -229,4 +229,9 @@ patch_list = [
|
||||
"patches.october_2013.p06_rename_packing_list_doctype",
|
||||
"execute:webnotes.delete_doc('DocType', 'Sales Common')",
|
||||
"patches.october_2013.p09_update_naming_series_settings",
|
||||
"patches.october_2013.p02_update_price_list_and_item_details_in_item_price",
|
||||
"execute:webnotes.delete_doc('Report', 'Item-wise Price List')",
|
||||
"patches.october_2013.p03_remove_sales_and_purchase_return_tool",
|
||||
"patches.october_2013.p04_update_report_permission",
|
||||
"patches.october_2013.p05_delete_gl_entries_for_cancelled_vouchers",
|
||||
]
|
@ -114,6 +114,40 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({
|
||||
this.frm.refresh();
|
||||
}
|
||||
},
|
||||
|
||||
serial_no: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
var item = wn.model.get_doc(cdt, cdn);
|
||||
|
||||
if (item.serial_no) {
|
||||
if (!item.item_code) {
|
||||
this.frm.script_manager.trigger("item_code", cdt, cdn);
|
||||
}
|
||||
else {
|
||||
var sr_no = [];
|
||||
|
||||
// Replacing all occurences of comma with carriage return
|
||||
var serial_nos = item.serial_no.trim().replace(/,/g, '\n');
|
||||
|
||||
serial_nos = serial_nos.trim().split('\n');
|
||||
|
||||
// Trim each string and push unique string to new list
|
||||
for (var x=0; x<=serial_nos.length - 1; x++) {
|
||||
if (serial_nos[x].trim() != "" && sr_no.indexOf(serial_nos[x].trim()) == -1) {
|
||||
sr_no.push(serial_nos[x].trim());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new list to the serial no. field in grid with each in new line
|
||||
item.serial_no = "";
|
||||
for (var x=0; x<=sr_no.length - 1; x++)
|
||||
item.serial_no += sr_no[x] + '\n';
|
||||
|
||||
refresh_field("serial_no", item.name, item.parentfield);
|
||||
wn.model.set_value(item.doctype, item.name, "qty", sr_no.length);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
this.calculate_taxes_and_totals();
|
||||
|
@ -83,9 +83,14 @@ wn.module_page["Selling"] = [
|
||||
},
|
||||
{
|
||||
label: wn._("Price List"),
|
||||
description: wn._("Mupltiple Item prices."),
|
||||
description: wn._("Multiple Price list."),
|
||||
doctype:"Price List"
|
||||
},
|
||||
{
|
||||
label: wn._("Item Price"),
|
||||
description: wn._("Multiple Item prices."),
|
||||
doctype:"Item Price"
|
||||
},
|
||||
{
|
||||
label: wn._("Sales BOM"),
|
||||
description: wn._("Bundle items at time of sale."),
|
||||
@ -166,6 +171,11 @@ wn.module_page["Selling"] = [
|
||||
right: true,
|
||||
icon: "icon-list",
|
||||
items: [
|
||||
{
|
||||
"label":wn._("Lead Details"),
|
||||
route: "query-report/Lead Details",
|
||||
doctype: "Lead"
|
||||
},
|
||||
{
|
||||
"label":wn._("Customer Addresses And Contacts"),
|
||||
route: "query-report/Customer Addresses And Contacts",
|
||||
|
22
selling/report/lead_details/lead_details.txt
Normal file
22
selling/report/lead_details/lead_details.txt
Normal file
@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-10-22 11:58:16",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-10-22 12:08:18",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"name": "__common__",
|
||||
"query": "SELECT\n `tabLead`.name as \"Lead Id:Link/Lead:120\",\n `tabLead`.lead_name as \"Lead Name::120\",\n\t`tabLead`.company_name as \"Company Name::120\",\n\t`tabLead`.status as \"Status::120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2), \n\t\ttabAddress.state, tabAddress.pincode, tabAddress.country\n\t) as 'Address::180',\n\t`tabLead`.phone as \"Phone::100\",\n\t`tabLead`.mobile_no as \"Mobile No::100\",\n\t`tabLead`.email_id as \"Email Id::120\",\n\t`tabLead`.lead_owner as \"Lead Owner::120\",\n\t`tabLead`.source as \"Source::120\",\n\t`tabLead`.territory as \"Territory::120\"\nFROM\n\t`tabLead`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.lead=`tabLead`.name\n\t)\nWHERE\n\t`tabLead`.docstatus<2\nORDER BY\n\t`tabLead`.name asc",
|
||||
"ref_doctype": "Lead",
|
||||
"report_name": "Lead Details",
|
||||
"report_type": "Query Report"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Lead Details"
|
||||
}
|
||||
]
|
@ -153,7 +153,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
item_code: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
var item = wn.model.get_doc(cdt, cdn);
|
||||
if(item.item_code || item.barcode) {
|
||||
if(item.item_code || item.barcode || item.serial_no) {
|
||||
if(!this.validate_company_and_party("customer")) {
|
||||
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
|
||||
} else {
|
||||
@ -164,6 +164,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
args: {
|
||||
item_code: item.item_code,
|
||||
barcode: item.barcode,
|
||||
serial_no: item.serial_no,
|
||||
warehouse: item.warehouse,
|
||||
doctype: me.frm.doc.doctype,
|
||||
parentfield: item.parentfield,
|
||||
|
@ -40,7 +40,9 @@ def get_item_details(args):
|
||||
args = webnotes._dict(args)
|
||||
|
||||
if args.barcode:
|
||||
args.item_code = _get_item_code(args.barcode)
|
||||
args.item_code = _get_item_code(barcode=args.barcode)
|
||||
elif not args.item_code and args.serial_no:
|
||||
args.item_code = _get_item_code(serial_no=args.serial_no)
|
||||
|
||||
item_bean = webnotes.bean("Item", args.item_code)
|
||||
|
||||
@ -88,15 +90,17 @@ def _get_serial_nos_by_fifo(args, item_bean):
|
||||
"qty": cint(args.qty)
|
||||
}))
|
||||
|
||||
def _get_item_code(barcode):
|
||||
item_code = webnotes.conn.sql_list("""select name from `tabItem` where barcode=%s""", barcode)
|
||||
def _get_item_code(barcode=None, serial_no=None):
|
||||
if barcode:
|
||||
input_type = "Barcode"
|
||||
item_code = webnotes.conn.sql_list("""select name from `tabItem` where barcode=%s""", barcode)
|
||||
elif serial_no:
|
||||
input_type = "Serial No"
|
||||
item_code = webnotes.conn.sql_list("""select item_code from `tabSerial No`
|
||||
where name=%s""", serial_no)
|
||||
|
||||
if not item_code:
|
||||
msgprint(_("No Item found with Barcode") + ": %s" % barcode, raise_exception=True)
|
||||
|
||||
elif len(item_code) > 1:
|
||||
msgprint(_("Items") + " %s " % comma_and(item_code) +
|
||||
_("have the same Barcode") + " %s" % barcode, raise_exception=True)
|
||||
msgprint(_("No Item found with ") + input_type + ": %s" % (barcode or serial_no), raise_exception=True)
|
||||
|
||||
return item_code[0]
|
||||
|
||||
@ -142,9 +146,8 @@ def _get_basic_details(args, item_bean, warehouse_fieldname):
|
||||
return out
|
||||
|
||||
def _get_price_list_rate(args, item_bean, meta):
|
||||
ref_rate = webnotes.conn.sql("""select ip.ref_rate from `tabItem Price` ip,
|
||||
`tabPrice List` pl where ip.parent = pl.name and ip.parent=%s and
|
||||
ip.item_code=%s and pl.buying_or_selling='Selling'""",
|
||||
ref_rate = webnotes.conn.sql("""select ref_rate from `tabItem Price`
|
||||
where price_list=%s and item_code=%s and buying_or_selling='Selling'""",
|
||||
(args.selling_price_list, args.item_code), as_dict=1)
|
||||
|
||||
if not ref_rate:
|
||||
|
@ -27,9 +27,8 @@ def get_product_info(item_code):
|
||||
else:
|
||||
in_stock = -1
|
||||
|
||||
price = price_list and webnotes.conn.sql("""select ip.ref_rate, pl.currency from
|
||||
`tabItem Price` ip, `tabPrice List` pl where ip.parent = pl.name and
|
||||
ip.item_code=%s and ip.parent=%s""",
|
||||
price = price_list and webnotes.conn.sql("""select ref_rate, currency from
|
||||
`tabItem Price` where item_code=%s and price_list=%s""",
|
||||
(item_code, price_list), as_dict=1) or []
|
||||
|
||||
price = price and price[0] or None
|
||||
|
@ -2,14 +2,53 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
if(doc.abbr && !doc.__islocal)
|
||||
cur_frm.set_df_property("abbr", "read_only", 1)
|
||||
if(doc.abbr && !doc.__islocal) {
|
||||
cur_frm.set_df_property("abbr", "read_only", 1);
|
||||
if(in_list(user_roles, "System Manager"))
|
||||
cur_frm.add_custom_button("Replace Abbreviation", cur_frm.cscript.replace_abbr)
|
||||
}
|
||||
|
||||
if(!doc.__islocal) {
|
||||
cur_frm.toggle_enable("default_currency", !cur_frm.doc.__transactions_exist);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.replace_abbr = function() {
|
||||
var dialog = new wn.ui.Dialog({
|
||||
title: "Replace Abbr",
|
||||
fields: [
|
||||
{"fieldtype": "Data", "label": "New Abbreviation", "fieldname": "new_abbr",
|
||||
"reqd": 1 },
|
||||
{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
|
||||
]
|
||||
});
|
||||
|
||||
dialog.fields_dict.update.$input.click(function() {
|
||||
args = dialog.get_values();
|
||||
if(!args) return;
|
||||
return wn.call({
|
||||
method: "setup.doctype.company.company.replace_abbr",
|
||||
args: {
|
||||
"company": cur_frm.doc.name,
|
||||
"old": cur_frm.doc.abbr,
|
||||
"new": args.new_abbr
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
msgprint(wn._("There were errors."));
|
||||
return;
|
||||
} else {
|
||||
cur_frm.set_value("abbr", args.new_abbr);
|
||||
}
|
||||
dialog.hide();
|
||||
cur_frm.refresh();
|
||||
},
|
||||
btn: this
|
||||
})
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
cur_frm.cscript.has_special_chars = function(t) {
|
||||
var iChars = "!@#$%^*+=-[]\\\';,/{}|\":<>?";
|
||||
for (var i = 0; i < t.length; i++) {
|
||||
|
@ -5,9 +5,7 @@ from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes import _, msgprint
|
||||
|
||||
from webnotes.utils import cstr, cint
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes.utils import cstr
|
||||
import webnotes.defaults
|
||||
|
||||
|
||||
@ -315,4 +313,19 @@ class DocType:
|
||||
where doctype='Global Defaults' and field='default_company'
|
||||
and value=%s""", (newdn, olddn))
|
||||
|
||||
webnotes.defaults.clear_default("company", value=olddn)
|
||||
webnotes.defaults.clear_default("company", value=olddn)
|
||||
|
||||
@webnotes.whitelist()
|
||||
def replace_abbr(company, old, new):
|
||||
webnotes.conn.set_value("Company", company, "abbr", new)
|
||||
|
||||
def _rename_record(dt):
|
||||
for d in webnotes.conn.sql("select name from `tab%s` where company=%s" % (dt, '%s'), company):
|
||||
parts = d[0].split(" - ")
|
||||
if parts[-1].lower() == old.lower():
|
||||
name_without_abbr = " - ".join(parts[:-1])
|
||||
webnotes.rename_doc(dt, d[0], name_without_abbr + " - " + new)
|
||||
|
||||
for dt in ["Account", "Cost Center", "Warehouse"]:
|
||||
_rename_record(dt)
|
||||
webnotes.conn.commit()
|
||||
|
@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-05-02 17:53:24",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-08-06 11:22:22",
|
||||
"modified": "2013-10-23 10:22:44",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@ -175,13 +175,6 @@
|
||||
"options": "Standard\nClassic\nModern\nSpartan",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "hr",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "HR",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm"
|
||||
}
|
||||
|
16
setup/doctype/item_price/item_price.js
Normal file
16
setup/doctype/item_price/item_price.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
$.extend(cur_frm.cscript, {
|
||||
|
||||
onload: function () {
|
||||
|
||||
// Fetch price list details
|
||||
cur_frm.add_fetch("price_list", "buying_or_selling", "buying_or_selling");
|
||||
cur_frm.add_fetch("price_list", "currency", "currency");
|
||||
|
||||
// Fetch item details
|
||||
cur_frm.add_fetch("item_code", "item_name", "item_name");
|
||||
cur_frm.add_fetch("item_code", "description", "item_description");
|
||||
}
|
||||
});
|
@ -5,7 +5,36 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
from webnotes import _
|
||||
|
||||
class ItemPriceDuplicateItem(Exception): pass
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
def on_update(self):
|
||||
self.update_price_list_details()
|
||||
self.update_item_details()
|
||||
self.check_duplicate_item()
|
||||
|
||||
def update_price_list_details(self):
|
||||
self.doc.buying_or_selling = webnotes.conn.get_value("Price List", self.doc.price_list,
|
||||
"buying_or_selling")
|
||||
|
||||
self.doc.currency = webnotes.conn.get_value("Price List", self.doc.price_list,
|
||||
"currency")
|
||||
|
||||
def update_item_details(self):
|
||||
self.doc.item_name = webnotes.conn.get_value("Item", self.doc.item_code, "item_name")
|
||||
|
||||
self.doc.item_description = webnotes.conn.get_value("Item", self.doc.item_code,
|
||||
"description")
|
||||
|
||||
def check_duplicate_item(self):
|
||||
if webnotes.conn.sql("""select name from `tabItem Price`
|
||||
where item_code=%s and price_list=%s and name!=%s""",
|
||||
(self.doc.item_code, self.doc.price_list, self.doc.name)):
|
||||
webnotes.throw(_("Duplicate Item: ") + self.doc.item_code +
|
||||
_(" already available in Price List: ") + self.doc.price_list,
|
||||
ItemPriceDuplicateItem)
|
@ -2,52 +2,126 @@
|
||||
{
|
||||
"creation": "2013-05-02 16:29:48",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-09-13 11:50:02",
|
||||
"modified": "2013-10-21 15:11:20",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"autoname": "RFD/.#####",
|
||||
"description": "Multiple Item prices.",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"icon": "icon-flag",
|
||||
"in_create": 0,
|
||||
"istable": 1,
|
||||
"istable": 0,
|
||||
"module": "Setup",
|
||||
"name": "__common__",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"name": "__common__",
|
||||
"parent": "Item Price",
|
||||
"parentfield": "fields",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"doctype": "DocPerm",
|
||||
"name": "__common__",
|
||||
"parent": "Item Price",
|
||||
"parentfield": "permissions",
|
||||
"parenttype": "DocType",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocType",
|
||||
"name": "Item Price"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "price_list",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"label": "Price List",
|
||||
"options": "Price List",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Code",
|
||||
"oldfieldname": "price_list_name",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Item",
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "ref_rate",
|
||||
"fieldtype": "Currency",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Rate",
|
||||
"oldfieldname": "ref_rate",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "col_br_1",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "buying_or_selling",
|
||||
"fieldtype": "Select",
|
||||
"in_filter": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Valid for Buying or Selling?",
|
||||
"options": "Selling\nBuying",
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_description",
|
||||
"fieldtype": "Text",
|
||||
"label": "Item Description",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "currency",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Currency",
|
||||
"options": "Currency",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "Sales Master Manager"
|
||||
},
|
||||
{
|
||||
"doctype": "DocPerm",
|
||||
"role": "Purchase Master Manager"
|
||||
}
|
||||
]
|
23
setup/doctype/item_price/test_item_price.py
Normal file
23
setup/doctype/item_price/test_item_price.py
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import webnotes
|
||||
from setup.doctype.item_price.item_price import ItemPriceDuplicateItem
|
||||
|
||||
class TestItem(unittest.TestCase):
|
||||
def test_duplicate_item(self):
|
||||
item_price = webnotes.bean(copy=test_records[0])
|
||||
self.assertRaises(ItemPriceDuplicateItem, item_price.insert)
|
||||
|
||||
test_records = [
|
||||
[
|
||||
{
|
||||
"doctype": "Item Price",
|
||||
"price_list": "_Test Price List",
|
||||
"item_code": "_Test Item",
|
||||
"ref_rate": 100
|
||||
}
|
||||
]
|
||||
]
|
@ -5,253 +5,13 @@ $.extend(cur_frm.cscript, {
|
||||
onload: function() {
|
||||
erpnext.add_for_territory();
|
||||
},
|
||||
});
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.show_item_prices();
|
||||
}
|
||||
|
||||
cur_frm.cscript.show_item_prices = function() {
|
||||
var item_price = wn.model.get("Item Price", {parent: cur_frm.doc.name});
|
||||
|
||||
$(cur_frm.fields_dict.item_prices_html.wrapper).empty();
|
||||
|
||||
new wn.ui.form.TableGrid({
|
||||
parent: cur_frm.fields_dict.item_prices_html.wrapper,
|
||||
frm: cur_frm,
|
||||
table_field: wn.meta.get_docfield("Price List", "item_prices", cur_frm.doc.name)
|
||||
});
|
||||
}
|
||||
|
||||
wn.ui.form.TableGrid = Class.extend({
|
||||
init: function(opts) {
|
||||
$.extend(this, opts);
|
||||
this.fields = wn.meta.get_docfields("Item Price", cur_frm.doc.name);
|
||||
this.make_table();
|
||||
},
|
||||
make_table: function() {
|
||||
var me = this;
|
||||
// Creating table & assigning attributes
|
||||
var grid_table = document.createElement("table");
|
||||
grid_table.className = "table table-hover table-bordered table-grid";
|
||||
|
||||
// Appending header & rows to table
|
||||
grid_table.appendChild(this.make_table_headers());
|
||||
grid_table.appendChild(this.make_table_rows());
|
||||
|
||||
// Creating button to add new row
|
||||
var btn_div = document.createElement("div");
|
||||
var new_row_btn = document.createElement("button");
|
||||
new_row_btn.className = "btn btn-success table-new-row";
|
||||
new_row_btn.title = "Add new row";
|
||||
|
||||
var btn_icon = document.createElement("i");
|
||||
btn_icon.className = "icon-plus";
|
||||
new_row_btn.appendChild(btn_icon);
|
||||
new_row_btn.innerHTML += " Add new row";
|
||||
btn_div.appendChild(new_row_btn);
|
||||
|
||||
// Appending table & button to parent
|
||||
var $grid_table = $(grid_table).appendTo($(this.parent));
|
||||
var $btn_div = $(btn_div).appendTo($(this.parent));
|
||||
|
||||
$btn_div.on("click", ".table-new-row", function() {
|
||||
me.make_dialog();
|
||||
return false;
|
||||
});
|
||||
|
||||
$grid_table.on("click", ".table-row", function() {
|
||||
me.make_dialog(this);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
make_table_headers: function() {
|
||||
var me = this;
|
||||
var header = document.createElement("thead");
|
||||
|
||||
// Creating header row
|
||||
var row = document.createElement("tr");
|
||||
row.className = "active";
|
||||
|
||||
// Creating head first cell
|
||||
var th = document.createElement("th");
|
||||
th.width = "8%";
|
||||
th.className = "text-center";
|
||||
th.innerHTML = "#";
|
||||
row.appendChild(th);
|
||||
|
||||
// Make other headers with label as heading
|
||||
for(var i=0, l=this.fields.length; i<l; i++) {
|
||||
var df = this.fields[i];
|
||||
|
||||
if(!!!df.hidden && df.in_list_view === 1) {
|
||||
var th = document.createElement("th");
|
||||
|
||||
// If currency then move header to right
|
||||
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) th.className = "text-right";
|
||||
|
||||
th.innerHTML = wn._(df.label);
|
||||
row.appendChild(th);
|
||||
}
|
||||
}
|
||||
|
||||
header.appendChild(row);
|
||||
|
||||
return header;
|
||||
},
|
||||
make_table_rows: function() {
|
||||
var me = this;
|
||||
|
||||
// Creating table body
|
||||
var table_body = document.createElement("tbody");
|
||||
|
||||
var item_prices = wn.model.get_children(this.table_field.options, this.frm.doc.name,
|
||||
this.table_field.fieldname, this.frm.doctype);
|
||||
|
||||
for(var i=0, l=item_prices.length; i<l; i++) {
|
||||
var d = item_prices[i];
|
||||
|
||||
// Creating table row
|
||||
var tr = this.add_new_row(d);
|
||||
|
||||
// append row to table body
|
||||
table_body.appendChild(tr);
|
||||
}
|
||||
|
||||
this.table_body = table_body;
|
||||
|
||||
return table_body;
|
||||
},
|
||||
make_dialog: function(row) {
|
||||
var me = this;
|
||||
|
||||
this.dialog = new wn.ui.Dialog({
|
||||
title: this.table_field.options,
|
||||
fields: this.fields
|
||||
});
|
||||
|
||||
if (row)
|
||||
this.dialog.set_values(this.make_dialog_values(row));
|
||||
|
||||
$a(this.dialog.body, 'div', '', '', this.make_dialog_buttons(row));
|
||||
this.dialog.show();
|
||||
|
||||
this.dialog.$wrapper.find('button.update').on('click', function() {
|
||||
me.update_row(row);
|
||||
});
|
||||
|
||||
this.dialog.$wrapper.find('button.delete').on('click', function() {
|
||||
me.delete_row(row);
|
||||
});
|
||||
return row;
|
||||
},
|
||||
make_dialog_values: function(row) {
|
||||
var me = this;
|
||||
var dialog_values = {};
|
||||
|
||||
$.each(this.fields, function(i, item) {
|
||||
dialog_values[item.fieldname] = $(row).find('td[data-fieldname="'+ item.fieldname +'"]').attr('data-fieldvalue');
|
||||
});
|
||||
|
||||
return dialog_values;
|
||||
},
|
||||
make_dialog_buttons: function(row) {
|
||||
var me = this;
|
||||
var buttons = '<button class="btn btn-primary update">Update</button>';
|
||||
|
||||
// if user can delete then only add the delete button in dialog
|
||||
if (wn.model.can_delete(me.frm.doc.doctype) && row)
|
||||
buttons += ' <button class="btn btn-default delete">Delete</button>';
|
||||
|
||||
return buttons;
|
||||
},
|
||||
update_row: function(row) {
|
||||
var me = this;
|
||||
|
||||
if (!row) {
|
||||
var d = wn.model.add_child(this.frm.doc, this.table_field.options,
|
||||
this.table_field.fieldname);
|
||||
refresh_field(this.table_field.fieldname);
|
||||
this.update_item_price(d.name);
|
||||
var tr = this.add_new_row(d);
|
||||
this.table_body.appendChild(tr);
|
||||
}
|
||||
else {
|
||||
this.update_item_price(null, row);
|
||||
}
|
||||
|
||||
this.dialog.hide();
|
||||
},
|
||||
|
||||
update_item_price: function(docname, row) {
|
||||
var me = this;
|
||||
if(!docname && row) docname = $(row).attr("data-docname");
|
||||
$.each(me.fields, function(i, df) {
|
||||
var val = me.dialog.get_values()[df.fieldname];
|
||||
|
||||
if(["Currency", "Float"].indexOf(df.fieldtype)!==-1) {
|
||||
val = flt(val);
|
||||
} else if(["Int", "Check"].indexOf(df.fieldtype)!==-1) {
|
||||
val = cint(val);
|
||||
}
|
||||
|
||||
wn.model.set_value(me.table_field.options, docname,
|
||||
df.fieldname, val);
|
||||
|
||||
if(row) {
|
||||
var $td = $(row).find('td[data-fieldname="'+ df.fieldname +'"]');
|
||||
$td.attr('data-fieldvalue', val);
|
||||
// If field type is currency the update with format currency
|
||||
$td.html(wn.format(val, df));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
delete_row: function(row) {
|
||||
var me = this;
|
||||
var docname = $(row).find('td:last').attr('data-docname');
|
||||
wn.model.clear_doc(me.table_field.options, docname);
|
||||
$(row).remove();
|
||||
|
||||
// Re-assign idx
|
||||
$.each($(this.parent).find("tbody tr"), function(idx, data) {
|
||||
var $td = $(data).find('td:first');
|
||||
$td.html(idx + 1);
|
||||
});
|
||||
this.dialog.hide();
|
||||
},
|
||||
|
||||
add_new_row: function(d) {
|
||||
var tr = document.createElement("tr");
|
||||
tr.className = "table-row";
|
||||
tr.setAttribute("data-docname", d.name);
|
||||
|
||||
// Creating table data & appending to row
|
||||
var td = document.createElement("td");
|
||||
td.className = "text-center";
|
||||
td.innerHTML = d.idx;
|
||||
tr.appendChild(td);
|
||||
|
||||
for(var f=0, lf=this.fields.length; f<lf; f++) {
|
||||
var df = this.fields[f];
|
||||
if(!!!df.hidden && df.in_list_view===1) {
|
||||
var td = document.createElement("td");
|
||||
td.setAttribute("data-fieldname", df.fieldname);
|
||||
td.setAttribute("data-fieldvalue", d[df.fieldname]);
|
||||
td.setAttribute("data-docname", d.name);
|
||||
|
||||
// If currency then move header to right
|
||||
if(["Int", "Currency", "Float"].indexOf(df.fieldtype) !== -1) {
|
||||
td.className = "text-right";
|
||||
}
|
||||
|
||||
// format and set display
|
||||
td.innerHTML = wn.format(d[df.fieldname], df);
|
||||
|
||||
// append column to tabel row
|
||||
tr.appendChild(td);
|
||||
}
|
||||
}
|
||||
return tr;
|
||||
refresh: function() {
|
||||
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
||||
wn.route_options = {
|
||||
"price_list": cur_frm.doc.name
|
||||
};
|
||||
wn.set_route("Report", "Item Price");
|
||||
}, "icon-money");
|
||||
}
|
||||
});
|
@ -8,8 +8,6 @@ from webnotes.utils import comma_or, cint
|
||||
from webnotes.model.controller import DocListController
|
||||
import webnotes.defaults
|
||||
|
||||
class PriceListDuplicateItem(Exception): pass
|
||||
|
||||
class DocType(DocListController):
|
||||
def validate(self):
|
||||
if self.doc.buying_or_selling not in ["Buying", "Selling"]:
|
||||
@ -27,23 +25,13 @@ class DocType(DocListController):
|
||||
else:
|
||||
# at least one territory
|
||||
self.validate_table_has_rows("valid_for_territories")
|
||||
|
||||
# check for duplicate items
|
||||
self.check_duplicate_items()
|
||||
|
||||
def on_update(self):
|
||||
self.set_default_if_missing()
|
||||
self.update_item_price()
|
||||
cart_settings = webnotes.get_obj("Shopping Cart Settings")
|
||||
if cint(cart_settings.doc.enabled):
|
||||
cart_settings.validate_price_lists()
|
||||
|
||||
def check_duplicate_items(self):
|
||||
item_codes = []
|
||||
for d in self.doclist.get({"parentfield": "item_prices"}):
|
||||
if d.item_code not in item_codes:
|
||||
item_codes.append(d.item_code)
|
||||
else:
|
||||
msgprint(_("Duplicate Item ") + ": " + d.item_code, raise_exception=PriceListDuplicateItem)
|
||||
|
||||
def set_default_if_missing(self):
|
||||
if self.doc.buying_or_selling=="Selling":
|
||||
@ -54,3 +42,7 @@ class DocType(DocListController):
|
||||
if not webnotes.conn.get_value("Buying Settings", None, "buying_price_list"):
|
||||
webnotes.set_value("Buying Settings", "Buying Settings", "buying_price_list", self.doc.name)
|
||||
|
||||
def update_item_price(self):
|
||||
webnotes.conn.sql("""update `tabItem Price` set currency=%s,
|
||||
buying_or_selling=%s where price_list=%s""",
|
||||
(self.doc.currency, self.doc.buying_or_selling, self.doc.name))
|
@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-01-25 11:35:09",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-10-02 11:36:09",
|
||||
"modified": "2013-10-18 13:33:07",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@ -84,27 +84,6 @@
|
||||
"options": "For Territory",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"description": "To change row values, click on the respective row",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_prices_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"label": "Item Prices"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_prices_html",
|
||||
"fieldtype": "HTML"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_prices",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 1,
|
||||
"label": "Item Prices",
|
||||
"options": "Item Price"
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
|
@ -2,16 +2,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import webnotes
|
||||
from setup.doctype.price_list.price_list import PriceListDuplicateItem
|
||||
|
||||
class TestItem(unittest.TestCase):
|
||||
def test_duplicate_item(self):
|
||||
price_list = webnotes.bean(copy=test_records[0])
|
||||
item_price = price_list.doclist.get({"doctype": "Item Price"})[0]
|
||||
price_list.doclist.append(webnotes.doc(item_price.fields.copy()))
|
||||
self.assertRaises(PriceListDuplicateItem, price_list.insert)
|
||||
|
||||
# test_ignore = ["Item"]
|
||||
|
||||
@ -28,12 +19,6 @@ test_records = [
|
||||
"parentfield": "valid_for_territories",
|
||||
"territory": "All Territories"
|
||||
},
|
||||
{
|
||||
"doctype": "Item Price",
|
||||
"parentfield": "item_prices",
|
||||
"item_code": "_Test Item",
|
||||
"ref_rate": 100
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
|
@ -41,6 +41,7 @@ items = [
|
||||
{"doctype":"UOM"},
|
||||
{"doctype":"Brand"},
|
||||
{"doctype":"Price List"},
|
||||
{"doctype": "Item Price"},
|
||||
{ "title": "Stock Settings",
|
||||
"route": "Form/Stock Settings", "type": "Link", "icon": "icon-cog" },
|
||||
],
|
||||
|
@ -1,22 +0,0 @@
|
||||
[
|
||||
{
|
||||
"creation": "2013-09-25 10:29:04",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-09-25 10:29:04",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"json": "{\"filters\":[[\"Item Price\",\"item_code\",\"like\",\"%\"],[\"Price List\",\"price_list_name\",\"like\",\"%\"]],\"columns\":[[\"item_code\",\"Item Price\"],[\"price_list_name\",\"Price List\"],[\"currency\",\"Price List\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Price List\"],[\"name\",\"Price List\"]],\"sort_by\":\"Price List.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Price List",
|
||||
"report_name": "Item-Wise Price List",
|
||||
"report_type": "Report Builder"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"name": "Item-Wise Price List"
|
||||
}
|
||||
]
|
@ -2,14 +2,14 @@
|
||||
{
|
||||
"creation": "2013-09-25 10:21:15",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-09-25 10:24:57",
|
||||
"modified": "2013-10-21 16:06:22",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
{
|
||||
"doctype": "Report",
|
||||
"is_standard": "Yes",
|
||||
"json": "{\"filters\":[[\"Item Price\",\"item_code\",\"like\",\"%\"],[\"Price List\",\"price_list_name\",\"like\",\"%\"]],\"columns\":[[\"item_code\",\"Item Price\"],[\"price_list_name\",\"Price List\"],[\"currency\",\"Price List\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Price List\"],[\"name\",\"Price List\"]],\"sort_by\":\"Price List.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
||||
"json": "{\"filters\":[[\"Item Price\",\"price_list\",\"like\",\"%\"],[\"Item Price\",\"item_code\",\"like\",\"%\"]],\"columns\":[[\"name\",\"Item Price\"],[\"price_list\",\"Item Price\"],[\"item_code\",\"Item Price\"],[\"item_name\",\"Item Price\"],[\"item_description\",\"Item Price\"],[\"ref_rate\",\"Item Price\"],[\"buying_or_selling\",\"Item Price\"],[\"currency\",\"Item Price\"]],\"sort_by\":\"Item Price.modified\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}",
|
||||
"name": "__common__",
|
||||
"ref_doctype": "Price List",
|
||||
"report_name": "Item-wise Price List Rate",
|
||||
|
@ -13,6 +13,7 @@ cur_frm.cscript.refresh = function(doc) {
|
||||
window.open(doc.page_name);
|
||||
}, "icon-globe");
|
||||
}
|
||||
cur_frm.cscript.edit_prices_button();
|
||||
|
||||
if (!doc.__islocal && doc.is_stock_item == 'Yes') {
|
||||
cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method'],
|
||||
@ -26,6 +27,15 @@ cur_frm.cscript.make_dashboard = function() {
|
||||
return;
|
||||
}
|
||||
|
||||
cur_frm.cscript.edit_prices_button = function() {
|
||||
cur_frm.add_custom_button("Add / Edit Prices", function() {
|
||||
wn.route_options = {
|
||||
"item_code": cur_frm.doc.name
|
||||
};
|
||||
wn.set_route("Report", "Item Price");
|
||||
}, "icon-money");
|
||||
}
|
||||
|
||||
cur_frm.cscript.item_code = function(doc) {
|
||||
if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code);
|
||||
if(!doc.description) cur_frm.set_value("description", doc.item_code);
|
||||
|
@ -144,11 +144,18 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||
},
|
||||
|
||||
production_order: function() {
|
||||
var me = this;
|
||||
this.toggle_enable_bom();
|
||||
|
||||
return this.frm.call({
|
||||
method: "get_production_order_details",
|
||||
args: {production_order: this.frm.doc.production_order}
|
||||
args: {production_order: this.frm.doc.production_order},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
if (me.frm.doc.purpose == "Material Transfer" && !me.frm.doc.to_warehouse)
|
||||
me.frm.set_value("to_warehouse", r.message["wip_warehouse"]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -469,11 +469,12 @@ class DocType(StockController):
|
||||
if self.doc.purpose=="Material Receipt":
|
||||
self.doc.from_warehouse = ""
|
||||
|
||||
item = webnotes.conn.sql("""select item, description, uom from `tabBOM`
|
||||
where name=%s""", (self.doc.bom_no,), as_dict=1)
|
||||
item = webnotes.conn.sql("""select name, item_name, description, uom
|
||||
from `tabItem` where name=%s""", (self.doc.bom_no), as_dict=1)
|
||||
self.add_to_stock_entry_detail({
|
||||
item[0]["item"] : {
|
||||
"qty": self.doc.fg_completed_qty,
|
||||
"item_name": item[0].item_name,
|
||||
"description": item[0]["description"],
|
||||
"stock_uom": item[0]["uom"],
|
||||
"from_warehouse": ""
|
||||
@ -481,7 +482,6 @@ class DocType(StockController):
|
||||
}, bom_no=self.doc.bom_no)
|
||||
|
||||
self.get_stock_and_rate()
|
||||
|
||||
|
||||
def get_bom_raw_materials(self, qty):
|
||||
from manufacturing.doctype.bom.bom import get_bom_items_as_dict
|
||||
@ -544,16 +544,24 @@ class DocType(StockController):
|
||||
return issued_item_qty
|
||||
|
||||
def add_to_stock_entry_detail(self, item_dict, bom_no=None):
|
||||
idx = 1
|
||||
expense_account, cost_center = webnotes.conn.get_values("Company", self.doc.company, \
|
||||
["default_expense_account", "cost_center"])[0]
|
||||
|
||||
for d in item_dict:
|
||||
se_child = addchild(self.doc, 'mtn_details', 'Stock Entry Detail',
|
||||
self.doclist)
|
||||
se_child.idx = idx
|
||||
se_child.s_warehouse = item_dict[d].get("from_warehouse", self.doc.from_warehouse)
|
||||
se_child.t_warehouse = item_dict[d].get("to_warehouse", self.doc.to_warehouse)
|
||||
se_child.item_code = cstr(d)
|
||||
se_child.item_name = item_dict[d]["item_name"]
|
||||
se_child.description = item_dict[d]["description"]
|
||||
se_child.uom = item_dict[d]["stock_uom"]
|
||||
se_child.stock_uom = item_dict[d]["stock_uom"]
|
||||
se_child.qty = flt(item_dict[d]["qty"])
|
||||
se_child.expense_account = item_dict[d]["expense_account"] or expense_account
|
||||
se_child.cost_center = item_dict[d]["cost_center"] or cost_center
|
||||
|
||||
# in stock uom
|
||||
se_child.transfer_qty = flt(item_dict[d]["qty"])
|
||||
@ -562,6 +570,9 @@ class DocType(StockController):
|
||||
# to be assigned for finished item
|
||||
se_child.bom_no = bom_no
|
||||
|
||||
# increment idx by 1
|
||||
idx += 1
|
||||
|
||||
def get_cust_values(self):
|
||||
"""fetches customer details"""
|
||||
if self.doc.delivery_note_no:
|
||||
@ -627,8 +638,8 @@ class DocType(StockController):
|
||||
@webnotes.whitelist()
|
||||
def get_production_order_details(production_order):
|
||||
result = webnotes.conn.sql("""select bom_no,
|
||||
ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty, use_multi_level_bom
|
||||
from `tabProduction Order` where name = %s""", production_order, as_dict=1)
|
||||
ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty, use_multi_level_bom,
|
||||
wip_warehouse from `tabProduction Order` where name = %s""", production_order, as_dict=1)
|
||||
return result and result[0] or {}
|
||||
|
||||
def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters):
|
||||
|
@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-03-29 18:22:12",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-10-15 14:58:09",
|
||||
"modified": "2013-10-23 14:35:46",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@ -65,6 +65,14 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "description",
|
||||
|
@ -3,11 +3,9 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import cint, flt, validate_email_add
|
||||
from webnotes.utils import cint, validate_email_add
|
||||
from webnotes import msgprint, _
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
@ -30,8 +28,8 @@ class DocType:
|
||||
if not webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||
"master_name": self.doc.name}) and not webnotes.conn.get_value("Account",
|
||||
{"account_name": self.doc.warehouse_name}):
|
||||
if self.doc.fields.get("__islocal") or not webnotes.conn.get_value("Stock Ledger Entry",
|
||||
{"warehouse": self.doc.name}):
|
||||
if self.doc.fields.get("__islocal") or not webnotes.conn.get_value(
|
||||
"Stock Ledger Entry", {"warehouse": self.doc.name}):
|
||||
self.validate_parent_account()
|
||||
ac_bean = webnotes.bean({
|
||||
"doctype": "Account",
|
||||
@ -101,7 +99,8 @@ class DocType:
|
||||
|
||||
def on_trash(self):
|
||||
# delete bin
|
||||
bins = webnotes.conn.sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1)
|
||||
bins = webnotes.conn.sql("select * from `tabBin` where warehouse = %s",
|
||||
self.doc.name, as_dict=1)
|
||||
for d in bins:
|
||||
if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \
|
||||
d['indented_qty'] or d['projected_qty'] or d['planned_qty']:
|
||||
@ -116,8 +115,10 @@ class DocType:
|
||||
webnotes.delete_doc("Account", warehouse_account)
|
||||
|
||||
# delete cancelled sle
|
||||
if webnotes.conn.sql("""select name from `tabStock Ledger Entry` where warehouse = %s""", self.doc.name):
|
||||
if webnotes.conn.sql("""select name from `tabStock Ledger Entry` where warehouse = %s""",
|
||||
self.doc.name):
|
||||
msgprint("""Warehosue can not be deleted as stock ledger entry
|
||||
exists for this warehouse.""", raise_exception=1)
|
||||
else:
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
|
||||
webnotes.conn.sql("delete from `tabStock Ledger Entry` where warehouse = %s",
|
||||
self.doc.name)
|
||||
|
@ -77,7 +77,12 @@ wn.module_page["Stock"] = [
|
||||
{
|
||||
"doctype":"Price List",
|
||||
"label": wn._("Price List"),
|
||||
"description": wn._("Multiple Item Prices")
|
||||
"description": wn._("Multiple Price list.")
|
||||
},
|
||||
{
|
||||
"doctype":"Item Price",
|
||||
"label": wn._("Item Price"),
|
||||
"description": wn._("Multiple Item prices.")
|
||||
},
|
||||
{
|
||||
"doctype":"Quality Inspection",
|
||||
@ -202,8 +207,8 @@ wn.module_page["Stock"] = [
|
||||
},
|
||||
{
|
||||
"label":wn._("Item-wise Price List Rate"),
|
||||
route: "Report/Price List/Item-Wise Price List",
|
||||
doctype: "Price List"
|
||||
route: "Report/Item Price/Item-wise Price List Rate",
|
||||
doctype: "Item Price"
|
||||
},
|
||||
{
|
||||
"label":wn._("Purchase In Transit"),
|
||||
|
@ -57,10 +57,9 @@ def get_price_list():
|
||||
|
||||
rate = {}
|
||||
|
||||
price_list = webnotes.conn.sql("""select ip.item_code, pl.buying_or_selling,
|
||||
concat(pl.name, " - ", pl.currency, " ", ip.ref_rate) as price
|
||||
from `tabItem Price` ip, `tabPrice List` pl where
|
||||
ip.parent = pl.name and pl.docstatus<2""", as_dict=1)
|
||||
price_list = webnotes.conn.sql("""select item_code, buying_or_selling,
|
||||
concat(price_list, " - ", currency, " ", ref_rate) as price
|
||||
from `tabItem Price`""", as_dict=1)
|
||||
|
||||
for j in price_list:
|
||||
if j.price:
|
||||
|
@ -13,8 +13,11 @@ def repost():
|
||||
"""
|
||||
webnotes.conn.auto_commit_on_many_writes = 1
|
||||
|
||||
for d in webnotes.conn.sql("select item_code, warehouse from tabBin"):
|
||||
repost_stock(d[0], d[1])
|
||||
for d in webnotes.conn.sql("""select distinct item_code, warehouse from
|
||||
(select item_code, warehouse from tabBin
|
||||
union
|
||||
select item_code, warehouse from `tabStock Ledger Entry`) a"""):
|
||||
repost_stock(d[0], d[1])
|
||||
|
||||
webnotes.conn.auto_commit_on_many_writes = 0
|
||||
|
||||
@ -31,7 +34,10 @@ def repost_stock(item_code, warehouse):
|
||||
|
||||
def repost_actual_qty(item_code, warehouse):
|
||||
from stock.stock_ledger import update_entries_after
|
||||
update_entries_after({ "item_code": item_code, "warehouse": warehouse })
|
||||
try:
|
||||
update_entries_after({ "item_code": item_code, "warehouse": warehouse })
|
||||
except:
|
||||
pass
|
||||
|
||||
def get_reserved_qty(item_code, warehouse):
|
||||
reserved_qty = webnotes.conn.sql("""
|
||||
|
Loading…
x
Reference in New Issue
Block a user