Merge pull request #2727 from neilLasrado/voucher-type
journal entry - accounts table cannot be blank - validation added
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
index 9df3b88..02ffb99 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
@@ -97,5 +97,7 @@
with open(os.path.join(os.path.dirname(__file__), "syscohada_syscohada_chart_template.json"), "r") as f:
_get_chart_name(f.read())
- charts.append("Standard")
+ if len(charts) > 1:
+ charts.append("Standard")
+
return charts
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/ni_ni_chart_template.json b/erpnext/accounts/doctype/account/chart_of_accounts/ni_ni_chart_template.json
new file mode 100644
index 0000000..6db540a
--- /dev/null
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/ni_ni_chart_template.json
@@ -0,0 +1,432 @@
+{
+ "country_code": "ni",
+ "name": "Catalogo de Cuentas",
+ "is_active": "Yes",
+ "tree": {
+ "Activo": {
+ "Activo Corriente": {
+ "Efectivo en Caja y Bancos": {
+ "Caja": {
+ "Caja General Moneda Nacional": {
+ "account_type": "Cash"
+ },
+ "Caja General Moneda Extrangera": {
+ "account_type": "Cash"
+ },
+ "Caja Chica Moneda Nacional": {
+ "account_type": "Cash"
+ },
+ "Caja Chica Moneda Extrangera": {
+ "account_type": "Cash"
+ },
+ "Fondos por Depositar": {
+ "account_type": "Cash"
+ }
+ },
+ "Cuentas Bancarias": {
+ "Cuenta Corriente Moneda Nacional": {
+ "account_type": "Bank"
+ },
+ "Cuenta Corriente Moneda Extrangera": {
+ "account_type": "Bank"
+ }
+ },
+ "Otros Equivalentes a Efectivo": {
+ "group_or_ledger": "Group",
+ "account_type": "Cash"
+ }
+ },
+ "Activos Financieros Realizables a Corto Plazo": {
+ "Inversiones a Corto Plazo": {},
+ "Bonos y Acciones Disponibles para la Venta": {},
+ "Certificados Bancarios": {},
+ "Otros Valores Negociables a Corto Plazo": {}
+ },
+ "Cuentas y Documentos por Cobrar a Clientes": {
+ "Cuentas por Cobrar Moneda Nacional": {
+ "account_type": "Receivable"
+ },
+ "Cuentas por Cobrar Moneda Extrangera": {
+ "account_type": "Receivable"
+ },
+ "Documentos por Cobrar Moneda Nacional": {
+ "account_type": "Receivable"
+ },
+ "Documentos por Cobrar Moneda Extrangera": {
+ "account_type": "Receivable"
+ },
+ "Cuentas por Cobrar por Exportaciones": {
+ "account_type": "Receivable"
+ },
+ "Estimacion para Cuentas Incobrables": {}
+ },
+ "Inventarios": {
+ "group_or_ledger": "Group",
+ "account_type": "Stock"
+ },
+ "Impuestos Acreditables": {
+ "Impuesto a Valor Agregado Acreditable": {
+ "IVA Acreditable por Compra de Bienes": {
+ "account_type": "Tax"
+ },
+ "IVA Acreditable por Importaciones": {
+ "account_type": "Tax"
+ },
+ "IVA Acreditable por Prestacion de Servicios": {
+ "account_type": "Tax"
+ },
+ "Acreditacion Proporcional": {}
+ },
+ "Anticipos de IR o Pago Minimo Definitivo": {},
+ "Retenciones a Cuenta de IR Acreditables": {
+ "Retencion por V/Bienes o P/Servicios 2%": {
+ "account_type": "Tax"
+ },
+ "Retencion Operaciones Targeta Debito/Credito 1.5%": {
+ "account_type": "Tax"
+ }
+ },
+ "Retenciones a Cuenta de IMI Acreditables": {},
+ "Retenciones Definitivas Sobre Rentas o Ganancias de Capital": {}
+ },
+ "Otras Cuentas por Cobrar": {
+ "group_or_ledger": "Group",
+ "account_type": "Receivable"
+ }
+ },
+ "Activo no Corriente": {
+ "Propiedad Planta y Equipo": {
+ "Terrenos": {},
+ "Edificios": {},
+ "Almacenes": {},
+ "Otros Activos Inmobiliarios": {},
+ "Parque Vehicular": {},
+ "Equipo de Computo": {},
+ "Mobiliario y Equipo de Oficinas": {},
+ "Maquinaria Industrial": {},
+ "Otra Bienes Mobiliarios": {},
+ "Depresiacion Acumulada": {},
+ "account_type": "Fixed Asset"
+ },
+ "Inversiones Permanentes": {
+ "Inversiones Permanentes": {
+ "group_or_ledger": "Group",
+ "account_type": "Fixed Asset"
+ },
+ "Negocios Conjuntos": {
+ "group_or_ledger": "Group",
+ "account_type": "Fixed Asset"
+ }
+ },
+ "Bienes en Arrendamiento Financiero": {
+ "Locales y Edificios en Arrendamiento": {},
+ "Equipos y Maquinaria en Arrendamiento": {}
+ },
+ "Activos Intangibles": {
+ "Patentes": {
+ "group_or_ledger": "Group"
+ },
+ "Marcas Registradas": {
+ "group_or_ledger": "Group"
+ },
+ "Derechos de Autor": {
+ "group_or_ledger": "Group"
+ },
+ "Concesiones": {
+ "group_or_ledger": "Group"
+ },
+ "Licencias": {
+ "group_or_ledger": "Group"
+ },
+ "Gastos de investigacion": {
+ "group_or_ledger": "Group"
+ },
+ "Amortizacion de Activos Intangibles": {
+ "group_or_ledger": "Group"
+ },
+ "Deterioro de Valor de Activos Intangibles": {}
+ },
+ "Amortizables": {
+ "Gastos de Consitucion": {},
+ "Gastos Pre Operativos": {},
+ "Mejoras en Bienes Arrendados": {
+ "group_or_ledger": "Group"
+ },
+ "Amortizacion de Activos Amortizables": {},
+ "Deterioro de Valaor de Activos Amortizables": {}
+ },
+ "Cuentas por Cobrar a Largo Plazo": {
+ "Creditos a Largo Plazo": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "Inversiones a Largo Plazo": {
+ "Depositos Bancarios a Plazo": {
+ "group_or_ledger": "Group"
+ },
+ "Intereses percibidos por adelantado": {
+ "group_or_ledger": "Group"
+ },
+ "Titulos y Acciones": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "Activo por Impuestos Diferidos": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "root_type": "Asset"
+ },
+ "Pasivo": {
+ "Pasivo Corriente": {
+ "Cuentas por Pagar Proveedores": {
+ "Cuentas por Pagar Moneda Nacional": {
+ "account_type": "Payable"
+ },
+ "Cuentas por Pagar Moneda Extrangera": {
+ "account_type": "Payable"
+ },
+ "Documentos por Pagar Moneda Nacional": {
+ "account_type": "Payable"
+ },
+ "Documentos por Pagar Moneda Extrangera": {
+ "account_type": "Payable"
+ },
+ "Cuentas por Pagar por Importaciones": {
+ "account_type": "Payable"
+ }
+ },
+ "Anticipos de Clientes": {},
+ "Pasivos Financieros a Corto Plazo": {
+ "Prestamos por Pagar a Corto Plazo": {
+ "group_or_ledger": "Group"
+ },
+ "Sobregiros Bancarios": {
+ "group_or_ledger": "Group"
+ },
+ "Otras Deudas Bancarias": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "Gastos por Pagar": {
+ "Servicios Basicos": {
+ "group_or_ledger": "Group"
+ },
+ "Prestaciones Sociales": {
+ "group_or_ledger": "Group"
+ },
+ "Salarios por Pagar": {}
+ },
+ "Provisiones por Pagar": {
+ "Pasivos Laborales": {
+ "Indemnizacion Laboral": {},
+ "Aguinaldo por Pagar": {}
+ },
+ "Reclamos por Pagar": {},
+ "Responsabilidad frente a terceros": {}
+ },
+ "Impuestos por Pagar": {
+ "Impuesto al Valor Agregado por Pagar": {
+ "account_type": "Tax"
+ },
+ "Impuesto sobre la Renta": {
+ "account_type": "Tax"
+ },
+ "Impuestos Municipales": {
+ "account_type": "Tax"
+ }
+ },
+ "Retenciones por Pagar": {
+ "Rentas del Trabajo": {
+ "Retencion Rentas del Trabajo Tarifa Progresiva": {
+ "account_type": "Tax"
+ },
+ "Retencion Definitiva por Rentas del Trabajo": {
+ "account_type": "Tax"
+ }
+ },
+ "Rentas de Actividades Economicas": {
+ "Retencion 2% por C/Bienes o P/Servicios": {
+ "account_type": "Tax"
+ },
+ "Retencion 10% Servicios Profesionales": {
+ "account_type": "Tax"
+ },
+ "Retencion 3% compra Bienes Agropecuarios": {
+ "account_type": "Tax"
+ },
+ "Retencion 5% compra Madera en Rollo": {
+ "account_type": "Tax"
+ },
+ "Otras Retenciones 10%": {
+ "account_type": "Tax"
+ }
+ },
+ "Rentas y Ganancias de Capital": {
+ "Retencion Defintiva 10% por Rentas de Capital": {
+ "account_type": "Tax"
+ },
+ "Retencion Definitiva 5% por Rentas de Capital": {
+ "account_type": "Tax"
+ },
+ "Retencion Definitiva 10% por Ganancia de Capital": {
+ "account_type": "Tax"
+ },
+ "Retencion Definitiva Actividades Economicas No Residentes": {
+ "account_type": "Tax"
+ },
+ "Retencion Definitiva Transacciones Bursatiles": {
+ "account_type": "Tax"
+ },
+ "Retenciones Defintiva 5% Fondos de Inversion": {
+ "account_type": "Tax"
+ }
+ },
+ "Retencion 17% Operaciones con Paraisos Fiscales": {
+ "account_type": "Tax"
+ }
+ },
+ "Otras Cuentas por Pagar": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "Pasivo No Corriente": {
+ "Prestamos a Largo Plazo": {
+ "group_or_ledger": "Group"
+ },
+ "Cuentas por Pagar a Largo Plaso": {
+ "group_or_ledger": "Group"
+ },
+ "Otras Cuentas por Pagar a Largo Plazo": {
+ "group_or_ledger": "Group"
+ },
+ "Otros Pasivos Financieros a Largo Plaso": {
+ "group_or_ledger": "Group"
+ }
+ },
+ "Obligaciones por Arrendamiento Financiero a Largo Plazo": {
+ "group_or_ledger": "Group"
+ },
+ "Pasivo por Impuestos Diferidos": {
+ "group_or_ledger": "Group"
+ },
+ "root_type": "Liability"
+ },
+ "Patrimonio": {
+ "Aporte de Socios": {
+ "Capital": {
+ "Capital Social Pagado": {
+ "account_type": "Equity"
+ },
+ "Capital Social no Pagado": {
+ "account_type": "Equity"
+ }
+ }
+ },
+ "Donaciones": {
+ "group_or_ledger": "Group"
+ },
+ "Ganancias Acumuladas": {
+ "Reservas": {
+ "Reservas Legales": {
+ "account_type": "Equity"
+ },
+ "Reservas Voluntarias": {
+ "account_type": "Equity"
+ }
+ },
+ "Resultados": {
+ "Resultados Acumulados": {
+ "account_type": "Equity"
+ },
+ "Ajustes a Periodos Anteriores": {
+ "account_type": "Equity"
+ },
+ "Resultado del ejercicio": {
+ "account_type": "Equity"
+ }
+ }
+ },
+ "root_type": "Equity"
+ },
+ "Ingresos": {
+ "Ventas": {
+ "Venta de Bienes o Prestacion de Servicios Grabados": {},
+ "Venta de Bienes o Prestacion de Servicios Exentos": {},
+ "Venta de Bienes o Prestacion de Servicios Exonerados": {},
+ "Venta por Exportaciones": {}
+ },
+ "Otros Ingresos Grabables": {
+ "Ganacia Cambiaria": {},
+ "Sobrante en Arqueo de Caja": {},
+ "Otros Ingresos Grabables": {}
+ },
+ "Ingresos no Grabables": {
+ "Ingreso por Rentas y Ganacias de Capital sujetas a Retencion Definitiva": {},
+ "Interes Bancarios": {},
+ "Otros Ingresos no Grabables": {}
+ },
+ "root_type": "Income"
+ },
+ "Costos y Gastos": {
+ "Costo de Venta": {
+ "Costo de Bienes": {},
+ "Costo de Servicios": {},
+ "Costo de Produccion": {},
+ "account_type": "Cost of Goods Sold"
+ },
+ "Gastos de Ventas": {
+ "Publicidad": {},
+ "Mercadeo": {},
+ "Muestras Gratis": {},
+ "Regalosa Clientes": {},
+ "Fletes": {},
+ "Promociones": {}
+ },
+ "Gastos de Administracion": {
+ "Alquileres": {},
+ "Combustible": {},
+ "Servicios Basicos": {
+ "Energia Electrica": {},
+ "Agua Potable": {},
+ "Internet": {},
+ "Telefono Fijo": {},
+ "Celular": {},
+ "Costos por Servicios WEB": {}
+ },
+ "Vigilancia": {},
+ "Gastos Varios": {},
+ "Mantenimiento y Reparaciones": {},
+ "Papeleria": {},
+ "Representacion": {},
+ "Amortizaciones": {},
+ "Inatec": {},
+ "Indemnizacion": {},
+ "Fletes y Correos": {},
+ "Cuentas Incobrables": {},
+ "Capacitacion al Personal": {},
+ "Uniformes": {},
+ "Seguros": {},
+ "Donaciones": {},
+ "Impuesto Municipal": {},
+ "Matricula": {},
+ "Recoleccion de Basura": {},
+ "IVA Proporcional no Acreditado": {},
+ "Ayuda a Empleados": {}
+ },
+ "Gastos por Servicios Profesionales y Tecnicos": {},
+ "Gastos por Salarios y Otras Compensaciones": {},
+ "Gastopor Depreciacion": {},
+ "Otros Gastos": {
+ "Perdida Cambiario": {},
+ "Perdida e nVenta de Activo Fijo": {},
+ "Siniestros": {},
+ "Certificacion de Cheques y Chequeras": {}
+ },
+ "Costos y Gastos No Deducibles": {},
+ "Impuesto por Rentas y Ganancias de Capital": {},
+ "Impuesto sobre la Rentade Activividades Economicas": {},
+ "root_type": "Expense"
+ }
+ }
+}
diff --git a/erpnext/config/crm.py b/erpnext/config/crm.py
new file mode 100644
index 0000000..74909c4
--- /dev/null
+++ b/erpnext/config/crm.py
@@ -0,0 +1,126 @@
+from frappe import _
+
+def get_data():
+ return [
+ {
+ "label": _("Documents"),
+ "icon": "icon-star",
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Lead",
+ "description": _("Database of potential customers."),
+ },
+ {
+ "type": "doctype",
+ "name": "Customer",
+ "description": _("Customer database."),
+ },
+ {
+ "type": "doctype",
+ "name": "Opportunity",
+ "description": _("Potential opportunities for selling."),
+ },
+ {
+ "type": "doctype",
+ "name": "Contact",
+ "description": _("All Contacts."),
+ },
+ {
+ "type": "doctype",
+ "name": "Newsletter",
+ "description": _("Newsletters to contacts, leads."),
+ },
+ ]
+ },
+ {
+ "label": _("Tools"),
+ "icon": "icon-wrench",
+ "items": [
+ {
+ "type": "doctype",
+ "name": "SMS Center",
+ "description":_("Send mass SMS to your contacts"),
+ },
+ ]
+ },
+ {
+ "label": _("Setup"),
+ "icon": "icon-cog",
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Campaign",
+ "description": _("Sales campaigns."),
+ },
+ {
+ "type": "page",
+ "label": _("Customer Group"),
+ "name": "Sales Browser",
+ "icon": "icon-sitemap",
+ "link": "Sales Browser/Customer Group",
+ "description": _("Manage Customer Group Tree."),
+ "doctype": "Customer Group",
+ },
+ {
+ "type": "page",
+ "label": _("Territory"),
+ "name": "Sales Browser",
+ "icon": "icon-sitemap",
+ "link": "Sales Browser/Territory",
+ "description": _("Manage Territory Tree."),
+ "doctype": "Territory",
+ },
+ {
+ "type": "page",
+ "label": _("Sales Person"),
+ "name": "Sales Browser",
+ "icon": "icon-sitemap",
+ "link": "Sales Browser/Sales Person",
+ "description": _("Manage Sales Person Tree."),
+ "doctype": "Sales Person",
+ },
+ {
+ "type": "doctype",
+ "name": "SMS Settings",
+ "description": _("Setup SMS gateway settings")
+ },
+ ]
+ },
+ {
+ "label": _("Main Reports"),
+ "icon": "icon-table",
+ "items": [
+ {
+ "type": "page",
+ "name": "sales-funnel",
+ "label": _("Sales Funnel"),
+ "icon": "icon-bar-chart",
+ },
+ ]
+ },
+ {
+ "label": _("Standard Reports"),
+ "icon": "icon-list",
+ "items": [
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Lead Details",
+ "doctype": "Lead"
+ },
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Customer Addresses and Contacts",
+ "doctype": "Contact"
+ },
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Customers Not Buying Since Long Time",
+ "doctype": "Sales Order"
+ },
+ ]
+ },
+ ]
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index 7d2a620..dbeb8d1 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -45,6 +45,11 @@
"icon": "octicon octicon-tag",
"type": "module"
},
+ "CRM": {
+ "color": "#EF4DB6",
+ "icon": "octicon octicon-broadcast",
+ "type": "module"
+ },
"Stock": {
"color": "#f39c12",
"icon": "icon-truck",
diff --git a/erpnext/config/support.py b/erpnext/config/support.py
index 2ed2c5f..54219c5 100644
--- a/erpnext/config/support.py
+++ b/erpnext/config/support.py
@@ -13,8 +13,8 @@
},
{
"type": "doctype",
- "name": "Customer Issue",
- "description": _("Customer Issue against Serial No."),
+ "name": "Warranty Claim",
+ "description": _("Warranty Claim against Serial No."),
},
{
"type": "doctype",
diff --git a/erpnext/controllers/js/contact_address_common.js b/erpnext/controllers/js/contact_address_common.js
index 77f4742..88a7f9e 100644
--- a/erpnext/controllers/js/contact_address_common.js
+++ b/erpnext/controllers/js/contact_address_common.js
@@ -20,7 +20,7 @@
docname = last_route.slice(2).join("/");
if(["Customer", "Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
- "Installation Note", "Opportunity", "Customer Issue", "Maintenance Visit",
+ "Installation Note", "Opportunity", "Warranty Claim", "Maintenance Visit",
"Maintenance Schedule"]
.indexOf(doctype)!==-1) {
var refdoc = frappe.get_doc(doctype, docname);
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 0e56fc7..4e06b6b 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -55,7 +55,7 @@
self.update_if_missing(party_details)
elif getattr(self, "lead", None):
- from erpnext.selling.doctype.lead.lead import get_lead_details
+ from erpnext.crm.doctype.lead.lead import get_lead_details
self.update_if_missing(get_lead_details(self.lead))
def set_price_list_and_item_details(self):
diff --git a/erpnext/crm/__init__.py b/erpnext/crm/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/crm/__init__.py
diff --git a/erpnext/crm/doctype/__init__.py b/erpnext/crm/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/crm/doctype/__init__.py
diff --git a/erpnext/crm/doctype/lead/.py b/erpnext/crm/doctype/lead/.py
new file mode 100644
index 0000000..70a6b22
--- /dev/null
+++ b/erpnext/crm/doctype/lead/.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class Lead(Document):
+ pass
diff --git a/erpnext/crm/doctype/lead/__init__.py b/erpnext/crm/doctype/lead/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/crm/doctype/lead/__init__.py
diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/crm/doctype/lead/lead.js
similarity index 93%
rename from erpnext/selling/doctype/lead/lead.js
rename to erpnext/crm/doctype/lead/lead.js
index 170e718..b2eab16 100644
--- a/erpnext/selling/doctype/lead/lead.js
+++ b/erpnext/crm/doctype/lead/lead.js
@@ -41,14 +41,14 @@
create_customer: function() {
frappe.model.open_mapped_doc({
- method: "erpnext.selling.doctype.lead.lead.make_customer",
+ method: "erpnext.crm.doctype.lead.lead.make_customer",
frm: cur_frm
})
},
create_opportunity: function() {
frappe.model.open_mapped_doc({
- method: "erpnext.selling.doctype.lead.lead.make_opportunity",
+ method: "erpnext.crm.doctype.lead.lead.make_opportunity",
frm: cur_frm
})
}
diff --git a/erpnext/selling/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json
similarity index 98%
rename from erpnext/selling/doctype/lead/lead.json
rename to erpnext/crm/doctype/lead/lead.json
index de43be7..32b604d 100644
--- a/erpnext/selling/doctype/lead/lead.json
+++ b/erpnext/crm/doctype/lead/lead.json
@@ -331,9 +331,9 @@
],
"icon": "icon-user",
"idx": 1,
- "modified": "2015-02-05 05:11:40.379661",
+ "modified": "2015-02-16 23:54:10.622839",
"modified_by": "Administrator",
- "module": "Selling",
+ "module": "CRM",
"name": "Lead",
"owner": "Administrator",
"permissions": [
diff --git a/erpnext/selling/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
similarity index 100%
rename from erpnext/selling/doctype/lead/lead.py
rename to erpnext/crm/doctype/lead/lead.py
diff --git a/erpnext/selling/doctype/lead/test_lead.py b/erpnext/crm/doctype/lead/test_lead.py
similarity index 90%
rename from erpnext/selling/doctype/lead/test_lead.py
rename to erpnext/crm/doctype/lead/test_lead.py
index 218e75a..181d75b 100644
--- a/erpnext/selling/doctype/lead/test_lead.py
+++ b/erpnext/crm/doctype/lead/test_lead.py
@@ -10,7 +10,7 @@
class TestLead(unittest.TestCase):
def test_make_customer(self):
- from erpnext.selling.doctype.lead.lead import make_customer
+ from erpnext.crm.doctype.lead.lead import make_customer
frappe.delete_doc_if_exists("Customer", "_Test Lead")
diff --git a/erpnext/selling/doctype/lead/test_records.json b/erpnext/crm/doctype/lead/test_records.json
similarity index 100%
rename from erpnext/selling/doctype/lead/test_records.json
rename to erpnext/crm/doctype/lead/test_records.json
diff --git a/erpnext/selling/doctype/opportunity/README.md b/erpnext/crm/doctype/opportunity/README.md
similarity index 100%
rename from erpnext/selling/doctype/opportunity/README.md
rename to erpnext/crm/doctype/opportunity/README.md
diff --git a/erpnext/crm/doctype/opportunity/__init__.py b/erpnext/crm/doctype/opportunity/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/crm/doctype/opportunity/__init__.py
diff --git a/erpnext/selling/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
similarity index 93%
rename from erpnext/selling/doctype/opportunity/opportunity.js
rename to erpnext/crm/doctype/opportunity/opportunity.js
index 1180793..a0ebcce 100644
--- a/erpnext/selling/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -7,12 +7,12 @@
frappe.ui.form.on_change("Opportunity", "contact_person", erpnext.utils.get_contact_details);
-frappe.provide("erpnext.selling");
+frappe.provide("erpnext.crm");
frappe.require("assets/erpnext/js/utils.js");
cur_frm.email_field = "contact_email";
// TODO commonify this code
-erpnext.selling.Opportunity = frappe.ui.form.Controller.extend({
+erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
onload: function() {
if(!this.frm.doc.enquiry_from && this.frm.doc.customer)
this.frm.doc.enquiry_from = "Customer";
@@ -62,13 +62,13 @@
create_quotation: function() {
frappe.model.open_mapped_doc({
- method: "erpnext.selling.doctype.opportunity.opportunity.make_quotation",
+ method: "erpnext.crm.doctype.opportunity.opportunity.make_quotation",
frm: cur_frm
})
}
});
-$.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm}));
+$.extend(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm}));
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
erpnext.toggle_naming_series();
@@ -102,7 +102,7 @@
cur_frm.cscript.lead = function(doc, cdt, cdn) {
cur_frm.toggle_display("contact_info", doc.customer || doc.lead);
frappe.model.map_current_doc({
- method: "erpnext.selling.doctype.lead.lead.make_opportunity",
+ method: "erpnext.crm.doctype.lead.lead.make_opportunity",
source_name: cur_frm.doc.lead,
frm: cur_frm
});
diff --git a/erpnext/selling/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
similarity index 99%
rename from erpnext/selling/doctype/opportunity/opportunity.json
rename to erpnext/crm/doctype/opportunity/opportunity.json
index 980de56..751df21 100644
--- a/erpnext/selling/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -391,9 +391,9 @@
"icon": "icon-info-sign",
"idx": 1,
"is_submittable": 1,
- "modified": "2015-02-05 05:11:41.732687",
+ "modified": "2015-02-16 23:52:23.489259",
"modified_by": "Administrator",
- "module": "Selling",
+ "module": "CRM",
"name": "Opportunity",
"owner": "Administrator",
"permissions": [
diff --git a/erpnext/selling/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
similarity index 100%
rename from erpnext/selling/doctype/opportunity/opportunity.py
rename to erpnext/crm/doctype/opportunity/opportunity.py
diff --git a/erpnext/selling/doctype/opportunity/opportunity_list.js b/erpnext/crm/doctype/opportunity/opportunity_list.js
similarity index 100%
rename from erpnext/selling/doctype/opportunity/opportunity_list.js
rename to erpnext/crm/doctype/opportunity/opportunity_list.js
diff --git a/erpnext/selling/doctype/opportunity/test_opportunity.py b/erpnext/crm/doctype/opportunity/test_opportunity.py
similarity index 100%
rename from erpnext/selling/doctype/opportunity/test_opportunity.py
rename to erpnext/crm/doctype/opportunity/test_opportunity.py
diff --git a/erpnext/selling/doctype/opportunity/test_records.json b/erpnext/crm/doctype/opportunity/test_records.json
similarity index 100%
rename from erpnext/selling/doctype/opportunity/test_records.json
rename to erpnext/crm/doctype/opportunity/test_records.json
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 2499a61..ffc9496 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -68,3 +68,8 @@
default_mail_footer = """<div style="padding: 7px; text-align: right;">
<a style="color: #888; font-size: 80%;" href="https://erpnext.com">Sent via ERPNext</a></div>"""
+
+get_translated_dict = {
+ ("page", "setup-wizard"): "frappe.geo.country_info.get_translated_dict",
+ ("doctype", "Global Defaults"): "frappe.geo.country_info.get_translated_dict"
+}
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index c95507d..05350d5 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -185,7 +185,7 @@
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
- "options": "company",
+ "options": "Company",
"permlevel": 0,
"precision": ""
},
@@ -252,7 +252,7 @@
"is_submittable": 1,
"issingle": 0,
"istable": 0,
- "modified": "2015-02-05 05:11:35.113320",
+ "modified": "2015-02-13 14:58:32.967368",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index f7ebaa9..2eeef08 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -7,7 +7,7 @@
cfn_set_fields(doc, dt, dn);
this.frm.add_fetch("sales_order", "delivery_date", "expected_delivery_date");
-
+
if(doc.__islocal) {
cur_frm.set_value({
"actual_start_date": "",
@@ -70,7 +70,7 @@
method: "set_production_order_operations"
});
},
-
+
planned_start_date: function() {
return this.frm.call({
doc: this.frm.doc,
@@ -144,7 +144,7 @@
}
cur_frm.cscript['Transfer Raw Materials'] = function() {
- cur_frm.cscript.make_se('Material Transfer');
+ cur_frm.cscript.make_se('Material Transfer for Manufacture');
}
cur_frm.cscript['Update Finished Goods'] = function() {
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 67b53f6..7375cf2 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -210,7 +210,7 @@
d.status = "Completed"
else:
frappe.throw(_("Completed Qty can not be greater than 'Qty to Manufacture'"))
-
+
def set_actual_dates(self):
if self.get("operations"):
actual_date = frappe.db.sql("""select min(actual_start_time) as start_date, max(actual_end_time) as end_date from `tabProduction Order Operation`
@@ -220,11 +220,11 @@
else:
self.actual_start_date = None
self.actual_end_date = None
-
+
def validate_delivery_date(self):
if self.planned_start_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
frappe.throw(_("Expected Delivery Date cannot be greater than Planned Start Date"))
-
+
if self.planned_end_date and self.expected_delivery_date and getdate(self.expected_delivery_date) < getdate(self.planned_end_date):
frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date."))
@@ -254,7 +254,7 @@
stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
- if purpose=="Material Transfer":
+ if purpose=="Material Transfer for Manufacture":
stock_entry.to_warehouse = production_order.wip_warehouse
else:
stock_entry.from_warehouse = production_order.wip_warehouse
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 243c2d8..255fbc5 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -1,10 +1,11 @@
Accounts
+CRM
Buying
-HR
-Manufacturing
Projects
Selling
Setup
+HR
+Manufacturing
Stock
Support
Utilities
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 00db68f..d1955f2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -108,3 +108,7 @@
erpnext.patches.v5_0.update_companywise_payment_account
erpnext.patches.v5_0.remove_birthday_events
erpnext.patches.v5_0.update_item_name_in_bom
+execute:frappe.reload_doc('crm', 'doctype', 'lead')
+execute:frappe.reload_doc('crm', 'doctype', 'opportunity')
+erpnext.patches.v5_0.rename_customer_issue
+erpnext.patches.v5_0.update_material_transfer_for_manufacture
diff --git a/erpnext/patches/repair_tools/fix_naming_series_records_lost_by_reload.py b/erpnext/patches/repair_tools/fix_naming_series_records_lost_by_reload.py
index 80e7437..0baed6b 100644
--- a/erpnext/patches/repair_tools/fix_naming_series_records_lost_by_reload.py
+++ b/erpnext/patches/repair_tools/fix_naming_series_records_lost_by_reload.py
@@ -13,7 +13,7 @@
'Attendance': 'ATT-',
'C-Form': 'C-FORM-',
'Customer': 'CUST-',
- 'Customer Issue': 'CI-',
+ 'Warranty Claim': 'CI-',
'Delivery Note': 'DN-',
'Installation Note': 'IN-',
'Item': 'ITEM-',
diff --git a/erpnext/patches/v4_0/set_naming_series_property_setter.py b/erpnext/patches/v4_0/set_naming_series_property_setter.py
index d62d845..bd4ed91 100644
--- a/erpnext/patches/v4_0/set_naming_series_property_setter.py
+++ b/erpnext/patches/v4_0/set_naming_series_property_setter.py
@@ -10,7 +10,7 @@
'Attendance': 'ATT-',
'C-Form': 'C-FORM-',
'Customer': 'CUST-',
- 'Customer Issue': 'CI-',
+ 'Warranty Claim': 'CI-',
'Delivery Note': 'DN-',
'Installation Note': 'IN-',
'Item': 'ITEM-',
diff --git a/erpnext/patches/v5_0/rename_customer_issue.py b/erpnext/patches/v5_0/rename_customer_issue.py
new file mode 100644
index 0000000..c3c38a7
--- /dev/null
+++ b/erpnext/patches/v5_0/rename_customer_issue.py
@@ -0,0 +1,5 @@
+import frappe
+
+def execute():
+ if frappe.db.table_exists("tabCustomer Issue"):
+ frappe.rename_doc("DocType", "Customer Issue", "Warrany Claim")
diff --git a/erpnext/patches/v5_0/update_material_transfer_for_manufacture.py b/erpnext/patches/v5_0/update_material_transfer_for_manufacture.py
new file mode 100644
index 0000000..d862ad3
--- /dev/null
+++ b/erpnext/patches/v5_0/update_material_transfer_for_manufacture.py
@@ -0,0 +1,5 @@
+import frappe
+
+def execute():
+ frappe.db.sql("""update `tabStock Entry` set purpose='Material Transfer for Manufacture'
+ where ifnull(production_order, '')!='' and purpose='Material Transfer'""")
diff --git a/erpnext/public/js/feature_setup.js b/erpnext/public/js/feature_setup.js
index 536f956..91720f2 100644
--- a/erpnext/public/js/feature_setup.js
+++ b/erpnext/public/js/feature_setup.js
@@ -64,7 +64,7 @@
'Stock Ledger Entry': {'fields':['batch_no']}
},
'fs_item_serial_nos': {
- 'Customer Issue': {'fields':['serial_no']},
+ 'Warranty Claim': {'fields':['serial_no']},
'Delivery Note': {'items':['serial_no'],'packed_items':['serial_no']},
'Installation Note': {'items':['serial_no']},
'Item': {'fields':['has_serial_no']},
@@ -155,7 +155,7 @@
'Sales Order': {'fields':['sales_team']}
},
'fs_more_info': {
- "Customer Issue": {"fields": ["more_info"]},
+ "Warranty Claim": {"fields": ["more_info"]},
'Material Request': {'fields':['more_info']},
'Lead': {'fields':['more_info']},
'Opportunity': {'fields':['more_info']},
diff --git a/erpnext/selling/doctype/lead/README.md b/erpnext/selling/doctype/lead/README.md
deleted file mode 100644
index a12dcf6..0000000
--- a/erpnext/selling/doctype/lead/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Prospective customer / prospect database. List of all prospects that could be source of business.
\ No newline at end of file
diff --git a/erpnext/selling/doctype/lead/__init__.py b/erpnext/selling/doctype/lead/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/selling/doctype/lead/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/selling/doctype/lead/lead_list.js b/erpnext/selling/doctype/lead/lead_list.js
deleted file mode 100644
index 9bbde6c..0000000
--- a/erpnext/selling/doctype/lead/lead_list.js
+++ /dev/null
@@ -1,9 +0,0 @@
-frappe.listview_settings['Lead'] = {
- add_fields: ["territory", "company_name", "status", "source"],
- get_indicator: function(doc) {
- var indicator = [__(doc.status), "darkgrey", "status,=," + doc.status];
- if(doc.status==="Open") indicator[1] = "red";
- if(doc.status==="Opportunity") indicator[1] = "green";
- return indicator;
- }
-};
diff --git a/erpnext/selling/doctype/opportunity/__init__.py b/erpnext/selling/doctype/opportunity/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/selling/doctype/opportunity/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index 776671a..c950056 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -32,7 +32,7 @@
cur_frm.add_custom_button(__('From Opportunity'),
function() {
frappe.model.map_current_doc({
- method: "erpnext.selling.doctype.opportunity.opportunity.make_quotation",
+ method: "erpnext.crm.doctype.opportunity.opportunity.make_quotation",
source_doctype: "Opportunity",
get_query_filters: {
docstatus: 1,
@@ -94,7 +94,7 @@
lead: function() {
var me = this;
frappe.call({
- method: "erpnext.selling.doctype.lead.lead.get_lead_details",
+ method: "erpnext.crm.doctype.lead.lead.get_lead_details",
args: { "lead": this.frm.doc.lead },
callback: function(r) {
if(r.message) {
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 5a05220..2c2b51b 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -149,7 +149,7 @@
customer_name = frappe.db.get_value("Customer", {"lead_name": lead_name},
["name", "customer_name"], as_dict=True)
if not customer_name:
- from erpnext.selling.doctype.lead.lead import _make_customer
+ from erpnext.crm.doctype.lead.lead import _make_customer
customer_doclist = _make_customer(lead_name, ignore_permissions=ignore_permissions)
customer = frappe.get_doc(customer_doclist)
customer.flags.ignore_permissions = ignore_permissions
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 96f75c0..4e0d766 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -17,7 +17,8 @@
"invoiced_amount", "payables"]],
["Bank Balance", ["bank_balance"]],
["Buying", ["new_purchase_requests", "new_supplier_quotations", "new_purchase_orders"]],
- ["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]],
+ ["CRM", ["new_leads", "new_enquiries"]],
+ ["Selling", ["new_quotations", "new_sales_orders"]],
["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]],
["Support", ["new_communications", "new_support_tickets", "open_tickets"]],
["Projects", ["new_projects"]],
diff --git a/erpnext/setup/doctype/item_group/item_group.js b/erpnext/setup/doctype/item_group/item_group.js
index 3bb6c17..717c7d6 100644
--- a/erpnext/setup/doctype/item_group/item_group.js
+++ b/erpnext/setup/doctype/item_group/item_group.js
@@ -12,6 +12,7 @@
cur_frm.cscript.set_root_readonly = function(doc) {
// read-only for root item group
+ cur_frm.set_intro("");
if(!doc.parent_item_group) {
cur_frm.set_read_only();
cur_frm.set_intro(__("This is a root item group and cannot be edited."), true);
diff --git a/erpnext/setup/doctype/item_group/item_group.json b/erpnext/setup/doctype/item_group/item_group.json
index 47a709d..32d0bb6 100644
--- a/erpnext/setup/doctype/item_group/item_group.json
+++ b/erpnext/setup/doctype/item_group/item_group.json
@@ -9,6 +9,13 @@
"document_type": "Master",
"fields": [
{
+ "fieldname": "gs",
+ "fieldtype": "Section Break",
+ "in_list_view": 0,
+ "label": "General Settings",
+ "permlevel": 0
+ },
+ {
"fieldname": "item_group_name",
"fieldtype": "Data",
"in_list_view": 1,
@@ -21,13 +28,6 @@
"search_index": 0
},
{
- "fieldname": "gs",
- "fieldtype": "Section Break",
- "in_list_view": 0,
- "label": "General Settings",
- "permlevel": 0
- },
- {
"description": "",
"fieldname": "parent_item_group",
"fieldtype": "Link",
@@ -104,7 +104,7 @@
"in_list_view": 0,
"label": "Page Name",
"permlevel": 0,
- "read_only": 1
+ "read_only": 0
},
{
"depends_on": "show_in_website",
@@ -190,7 +190,7 @@
"in_create": 1,
"issingle": 0,
"max_attachments": 3,
- "modified": "2015-02-05 05:11:39.844136",
+ "modified": "2015-02-16 23:50:48.113171",
"modified_by": "Administrator",
"module": "Setup",
"name": "Item Group",
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 59a0ecb..ba95bd0 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -34,6 +34,17 @@
NestedSet.on_trash(self)
WebsiteGenerator.on_trash(self)
+ def set_parent_website_route(self):
+ """Overwrite `parent_website_route` from `WebsiteGenerator`.
+ Only set `parent_website_route` if parent is visble.
+
+ e.g. If `show_in_website` is set for Products then url should be `/products`"""
+ if self.parent_item_group and frappe.db.get_value("Item Group",
+ self.parent_item_group, "show_in_website"):
+ super(WebsiteGenerator, self)()
+ else:
+ self.parent_website_route = ""
+
def validate_name_with_item(self):
if frappe.db.exists("Item", self.name):
frappe.throw(frappe._("An item exists with same name ({0}), please change the item group name or rename the item").format(self.name))
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.css b/erpnext/setup/page/setup_wizard/setup_wizard.css
index 6ff5b12..41eef34 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.css
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.css
@@ -1,26 +1,70 @@
-#page-setup-wizard {
- position: fixed;
- top: 0px; bottom: 0px;
- left: 0px; right: 0px;
- overflow: auto;
- padding-top: 30px;
-}
-.setup-wizard-wrapper {
- margin: 0px auto;
+.setup-wizard-slide {
+ padding-left: 0px;
+ padding-right: 0px;
}
@media (min-width: 768px) {
- .setup-wizard-wrapper {
- width: 725px;
+ .setup-wizard-slide.single-column {
+ max-width: 500px;
+ }
+
+ .setup-wizard-slide.two-column {
+ max-width: 768px;
}
}
-#page-setup-wizard .col-md-6 .control-input .btn {
- width: 100%;
+.setup-wizard-slide .lead {
+ margin-bottom: 10px;
}
-#page-setup-wizard .form-section {
- margin: 0px -15px;
- padding: 0px;
- max-width: 400px;
+.setup-wizard-slide .form {
+ margin-top: 20px;
+ border: 1px solid #d1d8dd;
+ box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.1);
+}
+
+.setup-wizard-slide .footer {
+ margin: 20px auto;
+}
+
+.setup-wizard-progress {
+ border-bottom: 1px solid #d1d8dd;
+ padding-bottom: 15px;
+ margin: -20px auto 20px;
+}
+
+.setup-wizard-slide .icon-fixed-width {
+ vertical-align: middle;
+}
+
+.setup-wizard-slide .icon-circle-blank {
+ font-size: 7px;
+}
+
+.setup-wizard-slide .icon-circle {
+ font-size: 10px;
+}
+
+.setup-wizard-slide .frappe-control[data-fieldtype="Attach Image"] {
+ text-align: center;
+}
+
+.setup-wizard-slide .missing-image,
+.setup-wizard-slide .attach-image-display {
+ display: block;
+ position: relative;
+ left: 50%;
+ transform: translate(-50%, 0);
+ -webkit-transform: translate(-50%, 0);
+}
+
+.setup-wizard-slide .missing-image .octicon {
+ position: relative;
+ top: 50%;
+ transform: translate(0px, -50%);
+ -webkit-transform: translate(0px, -50%);
+}
+
+.setup-wizard-message-image {
+ margin: 15px auto;
}
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.js b/erpnext/setup/page/setup_wizard/setup_wizard.js
index c31fab4..a10dc80 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.js
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.js
@@ -1,3 +1,5 @@
+frappe.provide("erpnext.wiz");
+
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
if(sys_defaults.company) {
frappe.set_route("desktop");
@@ -10,360 +12,36 @@
page_name: "setup-wizard",
parent: wrapper,
on_complete: function(wiz) {
- var values = wiz.get_values();
- wiz.show_working();
- frappe.call({
- method: "erpnext.setup.page.setup_wizard.setup_wizard.setup_account",
- args: values,
- callback: function(r) {
- wiz.show_complete();
- setTimeout(function() {
- if(user==="Administrator") {
- msgprint(__("Login with your new User ID") + ": " + values.email);
- setTimeout(function() {
- frappe.app.logout();
- }, 2000);
- } else {
- window.location = "/desk";
- }
- }, 2000);
- },
- error: function(r) {
-
- var d = msgprint(__("There were errors."));
- d.custom_onhide = function() {
- frappe.set_route(erpnext.wiz.page_name, "0");
- };
- }
- })
+ erpnext.wiz.setup_account(wiz);
},
title: __("Welcome"),
- working_html: function() { return '<h3 class="text-muted text-center"><i class="icon-refresh icon-spin"></i></h3>\
- <h2 class="text-center">'+__('Setting up...')+'</h2>\
- <p class="text-center">' +
- __('Sit tight while your system is being setup. This may take a few moments.') +
- '</p>' },
- complete_html: function() { return '<h1 class="text-muted text-center"></h1>\
- <h2 class="text-center">'+__('Setup Complete')+'</h2>\
- <p class="text-center">' +
- __('Your setup is complete. Refreshing...') +
- '</p>'},
+ working_html: erpnext.wiz.working_html,
+ complete_html: erpnext.wiz.complete_html,
slides: [
- // User
- {
- title: __("Select Your Language"),
- icon: "icon-globe",
- fields: [
- {
- "fieldname": "language", "label": __("Language"), "fieldtype": "Select",
- reqd:1
- },
- ],
- help: "",
- onload: function(slide) {
- var me = this;
- var select = slide.get_field("language");
-
- if (!this.language_list) {
- frappe.call({
- method: "erpnext.setup.page.setup_wizard.setup_wizard.load_languages",
- callback: function(r) {
- me.language_list = r.message;
- select.df.options = me.language_list;
- select.set_input("english");
- }
- })
- } else {
- select.df.options = this.language_list;
- select.refresh();
- }
-
- slide.get_input("language").on("change", function() {
- var lang = $(this).val() || "english";
- frappe._messages = {};
- frappe.call({
- method: "erpnext.setup.page.setup_wizard.setup_wizard.load_messages",
- args: {
- language: lang
- },
- callback: function(r) {
- // re-render all slides
- $.each(slide.wiz.slide_dict, function(key, s) {
- s.make();
- });
-
- // select is re-made after language change
- var select = slide.get_field("language");
- select.set_input(lang);
- }
- })
- });
- }
- },
-
- {
- title: __("The First User: You"),
- icon: "icon-user",
- fields: [
- {"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data",
- reqd:1},
- {"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data",
- reqd:1},
- {"fieldname": "email", "label": __("Email Id"), "fieldtype": "Data",
- reqd:1, "description": __("Your Login Id"), "options":"Email"},
- {"fieldname": "password", "label": __("Password"), "fieldtype": "Password",
- reqd:1},
- {fieldtype:"Attach Image", fieldname:"attach_user",
- label: __("Attach Your Picture")},
- ],
- help: __('The first user will become the System Manager (you can change that later).'),
- onload: function(slide) {
- if(user!=="Administrator") {
- slide.form.fields_dict.password.$wrapper.toggle(false);
- slide.form.fields_dict.email.$wrapper.toggle(false);
- slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name);
- slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name);
-
- var user_image = frappe.get_cookie("user_image");
- if(user_image) {
- var $attach_user = slide.form.fields_dict.attach_user.$wrapper;
- $attach_user.find(".missing-image").toggle(false);
- $attach_user.find("img").attr("src", user_image).toggle(true);
- }
-
- delete slide.form.fields_dict.email;
- delete slide.form.fields_dict.password;
- }
- }
- },
-
- // Country
- {
- title: __("Country, Timezone and Currency"),
- icon: "icon-flag",
- fields: [
- {fieldname:'country', label: __('Country'), reqd:1,
- options: "", fieldtype: 'Select'},
- {fieldname:'currency', label: __('Default Currency'), reqd:1,
- options: "", fieldtype: 'Select'},
- {fieldname:'timezone', label: __('Time Zone'), reqd:1,
- options: "", fieldtype: 'Select'},
- {fieldname:'chart_of_accounts', label: __('Chart of Accounts'),
- options: "", fieldtype: 'Select'}
- ],
- help: __('Select your home country and check the timezone and currency.'),
- onload: function(slide, form) {
- frappe.call({
- method:"frappe.geo.country_info.get_country_timezone_info",
- callback: function(data) {
- frappe.country_info = data.message.country_info;
- frappe.all_timezones = data.message.all_timezones;
- slide.get_input("country").empty()
- .add_options([""].concat(keys(frappe.country_info).sort()));
- slide.get_input("currency").empty()
- .add_options(frappe.utils.unique([""].concat($.map(frappe.country_info,
- function(opts, country) { return opts.currency; }))).sort());
- slide.get_input("timezone").empty()
- .add_options([""].concat(frappe.all_timezones));
- }
- })
-
- slide.get_input("country").on("change", function() {
- var country = slide.get_input("country").val();
- var $timezone = slide.get_input("timezone");
- $timezone.empty();
- // add country specific timezones first
- if(country){
- var timezone_list = frappe.country_info[country].timezones || [];
- $timezone.add_options(timezone_list.sort());
- slide.get_field("currency").set_input(frappe.country_info[country].currency);
- }
- // add all timezones at the end, so that user has the option to change it to any timezone
- $timezone.add_options([""].concat(frappe.all_timezones));
-
- slide.get_field("timezone").set_input($timezone.val());
-
- // temporarily set date format
- frappe.boot.sysdefaults.date_format = (frappe.country_info[country].date_format
- || "dd-mm-yyyy");
-
- // get country specific chart of accounts
- frappe.call({
- method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
- args: {"country": country},
- callback: function(r) {
- if(r.message)
- slide.get_input("chart_of_accounts").empty()
- .add_options([""].concat(r.message));
- }
- })
- });
- }
- },
-
- // Organization
- {
- title: __("The Organization"),
- icon: "icon-building",
- fields: [
- {fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1,
- placeholder: __('e.g. "My Company LLC"')},
- {fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data',
- description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1},
- {fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data',
- placeholder: __('e.g. "XYZ National Bank"'), reqd:1 },
- {fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date',
- description: __('Your financial year begins on'), reqd:1},
- {fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date',
- description: __('Your financial year ends on'), reqd:1},
- {fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data',
- placeholder:__('e.g. "Build tools for builders"'), reqd:1},
- ],
- help: __('The name of your company for which you are setting up this system.'),
- onload: function(slide) {
- slide.get_input("company_name").on("change", function() {
- var parts = slide.get_input("company_name").val().split(" ");
- var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
- slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
- }).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
-
- slide.get_input("company_abbr").on("change", function() {
- if(slide.get_input("company_abbr").val().length > 5) {
- msgprint("Company Abbreviation cannot have more than 5 characters");
- slide.get_field("company_abbr").set_input("");
- }
- });
-
- slide.get_input("fy_start_date").on("change", function() {
- var year_end_date =
- frappe.datetime.add_days(frappe.datetime.add_months(
- frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1);
- slide.get_field("fy_end_date").set_input(year_end_date);
-
- });
- }
- },
-
- // Logo
- {
- icon: "icon-bookmark",
- title: __("Logo and Letter Heads"),
- help: __('Upload your letter head and logo - you can edit them later.'),
- fields: [
- {fieldtype:"Attach Image", fieldname:"attach_letterhead",
- label: __("Attach Letterhead"),
- description: __("Keep it web friendly 900px (w) by 100px (h)")
- },
- {fieldtype:"Attach Image", fieldname:"attach_logo",
- label:__("Attach Logo"),
- description: __("100px by 100px")},
- ],
- },
-
- // Taxes
- {
- icon: "icon-money",
- "title": __("Add Taxes"),
- "help": __("List your tax heads (e.g. VAT, Excise; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
- "fields": [],
- before_load: function(slide) {
- slide.fields = [];
- for(var i=1; i<4; i++) {
- slide.fields = slide.fields.concat([
- {fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i,
- placeholder:__("e.g. VAT") + " " + i},
- {fieldtype:"Column Break"},
- {fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")},
- {fieldtype:"Section Break"},
- ]);
- }
- }
- },
-
- // Customers
- {
- icon: "icon-group",
- "title": __("Your Customers"),
- "help": __("List a few of your customers. They could be organizations or individuals."),
- "fields": [],
- before_load: function(slide) {
- slide.fields = [];
- for(var i=1; i<6; i++) {
- slide.fields = slide.fields.concat([
- {fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i,
- placeholder:__("Customer Name")},
- {fieldtype:"Column Break"},
- {fieldtype:"Data", fieldname:"customer_contact_" + i,
- label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
- {fieldtype:"Section Break"}
- ])
- }
- }
- },
-
- // Suppliers
- {
- icon: "icon-group",
- "title": __("Your Suppliers"),
- "help": __("List a few of your suppliers. They could be organizations or individuals."),
- "fields": [],
- before_load: function(slide) {
- slide.fields = [];
- for(var i=1; i<6; i++) {
- slide.fields = slide.fields.concat([
- {fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i,
- placeholder:__("Supplier Name")},
- {fieldtype:"Column Break"},
- {fieldtype:"Data", fieldname:"supplier_contact_" + i,
- label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
- {fieldtype:"Section Break"}
- ])
- }
- }
- },
-
- // Items to Sell
- {
- icon: "icon-barcode",
- "title": __("Your Products or Services"),
- "help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
- "fields": [],
- before_load: function(slide) {
- slide.fields = [];
- for(var i=1; i<6; i++) {
- slide.fields = slide.fields.concat([
- {fieldtype:"Section Break", show_section_border: true},
- {fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i,
- placeholder:__("A Product or Service")},
- {fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item")},
- {fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
- {fieldtype:"Column Break"},
- {fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i,
- options:[__("Products"), __("Services"),
- __("Raw Material"), __("Consumable"), __("Sub Assemblies")]},
- {fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"),
- options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
- __("Hour"), __("Minute")]},
- {fieldtype:"Attach", fieldname:"item_img_" + i, label:__("Attach Image")},
- ])
- }
- }
- },
+ erpnext.wiz.welcome.slide,
+ erpnext.wiz.region.slide,
+ erpnext.wiz.user.slide,
+ erpnext.wiz.org.slide,
+ erpnext.wiz.branding.slide,
+ erpnext.wiz.taxes.slide,
+ erpnext.wiz.customers.slide,
+ erpnext.wiz.suppliers.slide,
+ erpnext.wiz.items.slide,
]
}
- erpnext.wiz = new frappe.wiz.Wizard(wizard_settings)
+ erpnext.wiz.wizard = new erpnext.wiz.Wizard(wizard_settings)
}
frappe.pages['setup-wizard'].on_page_show = function(wrapper) {
- if(frappe.get_route()[1])
- erpnext.wiz.show(frappe.get_route()[1]);
+ if(frappe.get_route()[1]) {
+ erpnext.wiz.wizard.show(frappe.get_route()[1]);
+ }
+
}
-frappe.provide("frappe.wiz");
-
-frappe.wiz.Wizard = Class.extend({
+erpnext.wiz.Wizard = Class.extend({
init: function(opts) {
$.extend(this, opts);
this.make();
@@ -398,7 +76,7 @@
if(this.current_slide && this.current_slide.id===id)
return;
if(!this.slide_dict[id]) {
- this.slide_dict[id] = new frappe.wiz.WizardSlide($.extend(this.slides[id], {wiz:this, id:id}));
+ this.slide_dict[id] = new erpnext.wiz.WizardSlide($.extend(this.slides[id], {wiz:this, id:id}));
this.slide_dict[id].make();
}
@@ -422,7 +100,7 @@
}
});
-frappe.wiz.WizardSlide = Class.extend({
+erpnext.wiz.WizardSlide = Class.extend({
init: function(opts) {
$.extend(this, opts);
this.$wrapper = $("<div>")
@@ -437,9 +115,15 @@
this.before_load(this);
}
- this.$body = $(frappe.render_template("setup_wizard_page",
- {help: __(this.help), title:__(this.title), main_title:__(this.wiz.title), step: this.id + 1 }))
- .appendTo(this.$wrapper);
+ this.$body = $(frappe.render_template("setup_wizard_page", {
+ help: __(this.help),
+ title:__(this.title),
+ main_title:__(this.wiz.title),
+ step: this.id + 1,
+ name: this.name,
+ css_class: this.css_class || "",
+ slides_count: this.wiz.slides.length
+ })).appendTo(this.$wrapper);
this.body = this.$body.find(".form")[0];
@@ -494,4 +178,431 @@
get_field: function(fn) {
return this.form.get_field(fn);
}
-})
+});
+
+$.extend(erpnext.wiz, {
+ welcome: {
+ slide: {
+ name: "welcome",
+ title: __("Welcome to ERPNext"),
+ icon: "icon-world",
+ help: __("Let's prepare the system for first use."),
+
+ fields: [
+ { fieldname: "language", label: __("Select Your Language"), reqd:1,
+ fieldtype: "Select" },
+ ],
+
+ onload: function(slide) {
+ if (!erpnext.wiz.welcome.data) {
+ erpnext.wiz.welcome.load_languages(slide);
+ } else {
+ erpnext.wiz.welcome.setup_fields(slide);
+ }
+ },
+
+ css_class: "single-column"
+ },
+
+ load_languages: function(slide) {
+ frappe.call({
+ method: "erpnext.setup.page.setup_wizard.setup_wizard.load_languages",
+ callback: function(r) {
+ erpnext.wiz.welcome.data = r.message;
+ erpnext.wiz.welcome.setup_fields(slide);
+
+ slide.get_field("language")
+ .set_input(erpnext.wiz.welcome.data.default_language || "english");
+ }
+ });
+ },
+
+ setup_fields: function(slide) {
+ var select = slide.get_field("language");
+ select.df.options = erpnext.wiz.welcome.data.languages;
+ select.refresh();
+ erpnext.wiz.welcome.bind_events(slide);
+ },
+
+ bind_events: function(slide) {
+ slide.get_input("language").unbind("change").on("change", function() {
+ var lang = $(this).val() || "english";
+ frappe._messages = {};
+ frappe.call({
+ method: "erpnext.setup.page.setup_wizard.setup_wizard.load_messages",
+ args: {
+ language: lang
+ },
+ callback: function(r) {
+ // TODO save values!
+
+ // re-render all slides
+ $.each(slide.wiz.slide_dict, function(key, s) {
+ s.make();
+ });
+
+ // select is re-made after language change
+ var select = slide.get_field("language");
+ select.set_input(lang);
+ }
+ })
+ });
+ },
+ },
+
+ region: {
+ slide: {
+ title: __("Region"),
+ icon: "icon-flag",
+ help: __("Select your Country, Time Zone and Currency"),
+ fields: [
+ { fieldname: "country", label: __("Country"), reqd:1,
+ fieldtype: "Select" },
+ { fieldname: "timezone", label: __("Time Zone"), reqd:1,
+ fieldtype: "Select" },
+ { fieldname: "currency", label: __("Currency"), reqd:1,
+ fieldtype: "Select" },
+ ],
+
+ onload: function(slide) {
+ frappe.call({
+ method:"frappe.geo.country_info.get_country_timezone_info",
+ callback: function(data) {
+ erpnext.wiz.region.data = data.message;
+ erpnext.wiz.region.setup_fields(slide);
+ erpnext.wiz.region.bind_events(slide);
+ }
+ });
+ },
+
+ css_class: "single-column"
+ },
+
+ setup_fields: function(slide) {
+ var data = erpnext.wiz.region.data;
+
+ slide.get_input("country").empty()
+ .add_options([""].concat(keys(data.country_info).sort()));
+
+ slide.get_input("currency").empty()
+ .add_options(frappe.utils.unique([""].concat($.map(data.country_info,
+ function(opts, country) { return opts.currency; }))).sort());
+
+ slide.get_input("timezone").empty()
+ .add_options([""].concat(data.all_timezones));
+
+ if (data.default_country) {
+ slide.set_input("country", data.default_country);
+ }
+ },
+
+ bind_events: function(slide) {
+ slide.get_input("country").on("change", function() {
+ var country = slide.get_input("country").val();
+ var $timezone = slide.get_input("timezone");
+ var data = erpnext.wiz.region.data;
+
+ $timezone.empty();
+
+ // add country specific timezones first
+ if(country){
+ var timezone_list = data.country_info[country].timezones || [];
+ $timezone.add_options(timezone_list.sort());
+ slide.get_field("currency").set_input(data.country_info[country].currency);
+ }
+
+ // add all timezones at the end, so that user has the option to change it to any timezone
+ $timezone.add_options([""].concat(data.all_timezones));
+
+ slide.get_field("timezone").set_input($timezone.val());
+
+ // temporarily set date format
+ frappe.boot.sysdefaults.date_format = (data.country_info[country].date_format
+ || "dd-mm-yyyy");
+ });
+ }
+ },
+
+ user: {
+ slide: {
+ title: __("The First User: You"),
+ icon: "icon-user",
+ fields: [
+ {"fieldname": "first_name", "label": __("First Name"), "fieldtype": "Data",
+ reqd:1},
+ {"fieldname": "last_name", "label": __("Last Name"), "fieldtype": "Data"},
+ {"fieldname": "email", "label": __("Email Address"), "fieldtype": "Data",
+ reqd:1, "description": __("You will use it to Login"), "options":"Email"},
+ {"fieldname": "password", "label": __("Password"), "fieldtype": "Password",
+ reqd:1},
+ {fieldtype:"Attach Image", fieldname:"attach_user",
+ label: __("Attach Your Picture")},
+ ],
+ help: __('The first user will become the System Manager (you can change this later).'),
+ onload: function(slide) {
+ if(user!=="Administrator") {
+ slide.form.fields_dict.password.$wrapper.toggle(false);
+ slide.form.fields_dict.email.$wrapper.toggle(false);
+ slide.form.fields_dict.first_name.set_input(frappe.boot.user.first_name);
+ slide.form.fields_dict.last_name.set_input(frappe.boot.user.last_name);
+
+ var user_image = frappe.get_cookie("user_image");
+ if(user_image) {
+ var $attach_user = slide.form.fields_dict.attach_user.$wrapper;
+ $attach_user.find(".missing-image").toggle(false);
+ $attach_user.find("img").attr("src", user_image).toggle(true);
+ }
+
+ delete slide.form.fields_dict.email;
+ delete slide.form.fields_dict.password;
+ }
+ },
+ css_class: "single-column"
+ },
+ },
+
+ org: {
+ slide: {
+ title: __("The Organization"),
+ icon: "icon-building",
+ fields: [
+ {fieldname:'company_name', label: __('Company Name'), fieldtype:'Data', reqd:1,
+ placeholder: __('e.g. "My Company LLC"')},
+ {fieldname:'company_abbr', label: __('Company Abbreviation'), fieldtype:'Data',
+ description: __('Max 5 characters'), placeholder: __('e.g. "MC"'), reqd:1},
+ {fieldname:'company_tagline', label: __('What does it do?'), fieldtype:'Data',
+ placeholder:__('e.g. "Build tools for builders"'), reqd:1},
+ {fieldname:'bank_account', label: __('Bank Account'), fieldtype:'Data',
+ placeholder: __('e.g. "XYZ National Bank"'), reqd:1 },
+ {fieldname:'chart_of_accounts', label: __('Chart of Accounts'),
+ options: "", fieldtype: 'Select'},
+
+ // TODO remove this
+ {fieldtype: "Section Break"},
+ {fieldname:'fy_start_date', label:__('Financial Year Start Date'), fieldtype:'Date',
+ description: __('Your financial year begins on'), reqd:1},
+ {fieldname:'fy_end_date', label:__('Financial Year End Date'), fieldtype:'Date',
+ description: __('Your financial year ends on'), reqd:1},
+
+ ],
+ help: __('The name of your company for which you are setting up this system.'),
+
+ onload: function(slide) {
+ erpnext.wiz.org.load_chart_of_accounts(slide);
+ erpnext.wiz.org.bind_events(slide);
+ },
+
+ css_class: "single-column"
+ },
+
+ load_chart_of_accounts: function(slide) {
+ var country = slide.wiz.get_values().country;
+
+ frappe.call({
+ method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
+ args: {"country": country},
+ callback: function(r) {
+ if(r.message) {
+ slide.get_input("chart_of_accounts").empty()
+ .add_options(r.message);
+
+ if (r.message.length===1) {
+ var field = slide.get_field("chart_of_accounts");
+ field.set_value(r.message[0]);
+ field.df.hidden = 1;
+ field.refresh();
+ }
+ }
+ }
+ })
+ },
+
+ bind_events: function(slide) {
+ slide.get_input("company_name").on("change", function() {
+ var parts = slide.get_input("company_name").val().split(" ");
+ var abbr = $.map(parts, function(p) { return p ? p.substr(0,1) : null }).join("");
+ slide.get_field("company_abbr").set_input(abbr.slice(0, 5).toUpperCase());
+ }).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
+
+ slide.get_input("company_abbr").on("change", function() {
+ if(slide.get_input("company_abbr").val().length > 5) {
+ msgprint("Company Abbreviation cannot have more than 5 characters");
+ slide.get_field("company_abbr").set_input("");
+ }
+ });
+
+ // TODO remove this
+ slide.get_input("fy_start_date").on("change", function() {
+ var year_end_date =
+ frappe.datetime.add_days(frappe.datetime.add_months(
+ frappe.datetime.user_to_obj(slide.get_input("fy_start_date").val()), 12), -1);
+ slide.get_input("fy_end_date").val(frappe.datetime.obj_to_user(year_end_date));
+
+ });
+ }
+ },
+
+ branding: {
+ slide: {
+ icon: "icon-bookmark",
+ title: __("The Brand"),
+ help: __('Upload your letter head and logo. (you can edit them later).'),
+ fields: [
+ {fieldtype:"Attach Image", fieldname:"attach_letterhead",
+ label: __("Attach Letterhead"),
+ description: __("Keep it web friendly 900px (w) by 100px (h)")
+ },
+ {fieldtype: "Column Break"},
+ {fieldtype:"Attach Image", fieldname:"attach_logo",
+ label:__("Attach Logo"),
+ description: __("100px by 100px")},
+ ],
+
+ css_class: "two-column"
+ },
+ },
+
+ taxes: {
+ slide: {
+ icon: "icon-money",
+ "title": __("Add Taxes"),
+ "help": __("List your tax heads (e.g. VAT, Excise; they should have unique names) and their standard rates. This will create a standard template, which you can edit and add more later."),
+ "fields": [],
+ before_load: function(slide) {
+ slide.fields = [];
+ for(var i=1; i<4; i++) {
+ slide.fields = slide.fields.concat([
+ {fieldtype:"Section Break"},
+ {fieldtype:"Data", fieldname:"tax_"+ i, label:__("Tax") + " " + i,
+ placeholder:__("e.g. VAT") + " " + i},
+ {fieldtype:"Column Break"},
+ {fieldtype:"Float", fieldname:"tax_rate_" + i, label:__("Rate (%)"), placeholder:__("e.g. 5")},
+ ]);
+ }
+ },
+ css_class: "two-column"
+ },
+ },
+
+ customers: {
+ slide: {
+ icon: "icon-group",
+ "title": __("Your Customers"),
+ "help": __("List a few of your customers. They could be organizations or individuals."),
+ "fields": [],
+ before_load: function(slide) {
+ slide.fields = [];
+ for(var i=1; i<6; i++) {
+ slide.fields = slide.fields.concat([
+ {fieldtype:"Section Break"},
+ {fieldtype:"Data", fieldname:"customer_" + i, label:__("Customer") + " " + i,
+ placeholder:__("Customer Name")},
+ {fieldtype:"Column Break"},
+ {fieldtype:"Data", fieldname:"customer_contact_" + i,
+ label:__("Contact Name") + " " + i, placeholder:__("Contact Name")}
+ ])
+ }
+ },
+ css_class: "two-column"
+ },
+ },
+
+ suppliers: {
+ slide: {
+ icon: "icon-group",
+ "title": __("Your Suppliers"),
+ "help": __("List a few of your suppliers. They could be organizations or individuals."),
+ "fields": [],
+ before_load: function(slide) {
+ slide.fields = [];
+ for(var i=1; i<6; i++) {
+ slide.fields = slide.fields.concat([
+ {fieldtype:"Section Break"},
+ {fieldtype:"Data", fieldname:"supplier_" + i, label:__("Supplier")+" " + i,
+ placeholder:__("Supplier Name")},
+ {fieldtype:"Column Break"},
+ {fieldtype:"Data", fieldname:"supplier_contact_" + i,
+ label:__("Contact Name") + " " + i, placeholder:__("Contact Name")},
+ ])
+ }
+ },
+ css_class: "two-column"
+ },
+ },
+
+ items: {
+ slide: {
+ icon: "icon-barcode",
+ "title": __("Your Products or Services"),
+ "help": __("List your products or services that you buy or sell. Make sure to check the Item Group, Unit of Measure and other properties when you start."),
+ "fields": [],
+ before_load: function(slide) {
+ slide.fields = [];
+ for(var i=1; i<6; i++) {
+ slide.fields = slide.fields.concat([
+ {fieldtype:"Section Break", show_section_border: true},
+ {fieldtype:"Data", fieldname:"item_" + i, label:__("Item") + " " + i,
+ placeholder:__("A Product or Service")},
+ {fieldtype:"Select", label:__("Group"), fieldname:"item_group_" + i,
+ options:[__("Products"), __("Services"),
+ __("Raw Material"), __("Consumable"), __("Sub Assemblies")]},
+ {fieldtype:"Select", fieldname:"item_uom_" + i, label:__("UOM"),
+ options:[__("Unit"), __("Nos"), __("Box"), __("Pair"), __("Kg"), __("Set"),
+ __("Hour"), __("Minute")]},
+ {fieldtype: "Check", fieldname: "is_sales_item_" + i, label:__("We sell this Item"), default: 1},
+ {fieldtype: "Check", fieldname: "is_purchase_item_" + i, label:__("We buy this Item")},
+ {fieldtype:"Column Break"},
+ {fieldtype:"Attach Image", fieldname:"item_img_" + i, label:__("Attach Image")},
+ ])
+ }
+ },
+ css_class: "two-column"
+ },
+ },
+
+ working_html: function() {
+ return frappe.render_template("setup_wizard_message", {
+ image: "/assets/frappe/images/ui/bubble-tea-smile.svg",
+ title: __("Setting Up"),
+ message: __('Sit tight while your system is being setup. This may take a few moments.')
+ });
+ },
+
+ complete_html: function() {
+ return frappe.render_template("setup_wizard_message", {
+ image: "/assets/frappe/images/ui/bubble-tea-happy.svg",
+ title: __('Setup Complete'),
+ message: __('Your setup is complete. Refreshing.') + ".."
+ });
+ },
+
+ setup_account: function(wiz) {
+ var values = wiz.get_values();
+ wiz.show_working();
+ return frappe.call({
+ method: "erpnext.setup.page.setup_wizard.setup_wizard.setup_account",
+ args: values,
+ callback: function(r) {
+ wiz.show_complete();
+ setTimeout(function() {
+ if(user==="Administrator") {
+ msgprint(__("Login with your new User ID") + ": " + values.email);
+ setTimeout(function() {
+ frappe.app.logout();
+ }, 2000);
+ } else {
+ window.location = "/desk";
+ }
+ }, 2000);
+ },
+ error: function(r) {
+
+ var d = msgprint(__("There were errors."));
+ d.custom_onhide = function() {
+ frappe.set_route(erpnext.wiz.page_name, "0");
+ };
+ }
+ });
+ },
+});
+
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.py b/erpnext/setup/page/setup_wizard/setup_wizard.py
index d234f4f..445aa3d 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.py
@@ -7,7 +7,8 @@
from frappe.utils import cstr, flt, getdate
from frappe import _
from frappe.utils.file_manager import save_file
-from frappe.translate import set_default_language, get_dict, get_lang_dict, send_translations
+from frappe.translate import (set_default_language, get_dict,
+ get_lang_dict, send_translations, get_language_from_code)
from frappe.geo.country_info import get_country_info
from frappe.utils.nestedset import get_root_of
from default_website import website_maker
@@ -443,4 +444,9 @@
@frappe.whitelist()
def load_languages():
- return sorted(get_lang_dict().keys())
+ from frappe.sessions import get_geo_from_ip
+
+ return {
+ "default_language": get_language_from_code(frappe.local.lang),
+ "languages": sorted(get_lang_dict().keys())
+ }
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard_message.html b/erpnext/setup/page/setup_wizard/setup_wizard_message.html
new file mode 100644
index 0000000..e2f6bbc
--- /dev/null
+++ b/erpnext/setup/page/setup_wizard/setup_wizard_message.html
@@ -0,0 +1,7 @@
+<div class="container setup-wizard-slide">
+ <img class="img-responsive setup-wizard-message-image" src="{%= image %}">
+
+ <p class="text-center lead">{%= title %}</p>
+
+ <p class="text-center">{%= message %}</p>
+</div>
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard_page.html b/erpnext/setup/page/setup_wizard/setup_wizard_page.html
index 81a79a0..0067317 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard_page.html
+++ b/erpnext/setup/page/setup_wizard/setup_wizard_page.html
@@ -1,19 +1,21 @@
-<div>
- <h3>{%= title %}</h3>
- <hr>
+<div class="container setup-wizard-slide {%= css_class %}" data-slide-name="{%= name %}">
+ <div class="text-center setup-wizard-progress text-extra-muted">
+ {% for (var i=0; i < slides_count; i++) { %}
+ <i class="icon-fixed-width {% if (i+1==step) { %} icon-circle {% } else { %} icon-circle-blank {% } %}"></i>
+ {% } %}
+ </div>
+ <p class="text-center lead">{%= title %}</p>
<div class="row">
<div class="col-sm-12">
- <p class="text-muted">{%= help %}</p><br>
+ {% if (help) { %} <p class="text-center">{%= help %}</p> {% } %}
<div class="form"></div>
</div>
</div>
- <br>
- <div class="footer">
+ <div class="footer text-center">
<div>
- <a class="prev-btn hide btn btn-default btn-sm">{%= __("Previous") %}</a>
+ <a class="prev-btn hide grey small">{%= __("Previous") %}</a>
<a class="next-btn hide btn btn-primary btn-sm">{%= __("Next") %}</a>
<a class="complete-btn hide btn btn-primary btn-sm"><b>{%= __("Complete Setup") %}</b></a>
</div>
</div>
- <br><br>
</div>
diff --git a/erpnext/startup/notifications.py b/erpnext/startup/notifications.py
index eccd1d2..66bc83d 100644
--- a/erpnext/startup/notifications.py
+++ b/erpnext/startup/notifications.py
@@ -8,7 +8,7 @@
return { "for_doctype":
{
"Issue": {"status":"Open"},
- "Customer Issue": {"status":"Open"},
+ "Warranty Claim": {"status":"Open"},
"Task": {"status":"Open"},
"Lead": {"status":"Open"},
"Contact": {"status":"Open"},
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index e7606fd..5447f8a 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -135,7 +135,7 @@
pr_qty = flt(d.qty) * flt(d.conversion_factor)
if pr_qty:
- val_rate_db_precision = 6 if cint(self.precision("valuation_rate")) <= 6 else 9
+ val_rate_db_precision = 6 if cint(self.precision("valuation_rate", d)) <= 6 else 9
sl_entries.append(self.get_sl_entries(d, {
"actual_qty": flt(pr_qty),
"serial_no": cstr(d.serial_no).strip(),
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index cc7169b..a77aa74 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -122,7 +122,7 @@
clean_up: function() {
// Clear Production Order record from locals, because it is updated via Stock Entry
if(this.frm.doc.production_order &&
- this.frm.doc.purpose == "Manufacture") {
+ in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose)) {
frappe.model.remove_from_locals("Production Order",
this.frm.doc.production_order);
}
@@ -164,7 +164,7 @@
},
toggle_enable_bom: function() {
- this.frm.toggle_enable("bom_no", this.frm.doc.purpose!="Manufacture");
+ this.frm.toggle_enable("bom_no", !in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose));
},
get_doctype_docname: function() {
@@ -233,8 +233,10 @@
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
},
- source_mandatory: ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract"],
- target_mandatory: ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract"],
+ source_mandatory: ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract",
+ "Material Transfer for Manufacture"],
+ target_mandatory: ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract",
+ "Material Transfer for Manufacture"],
from_warehouse: function(doc) {
var me = this;
@@ -251,6 +253,7 @@
},
set_warehouse_if_missing: function(fieldname, value, condition) {
+ var changed = false;
for (var i=0, l=(this.frm.doc.items || []).length; i<l; i++) {
var row = this.frm.doc.items[i];
if (!row[fieldname]) {
@@ -259,8 +262,10 @@
}
frappe.model.set_value(row.doctype, row.name, fieldname, value, "Link");
+ changed = true;
}
}
+ refresh_field("items");
},
items_on_form_rendered: function(doc, grid_row) {
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.json b/erpnext/stock/doctype/stock_entry/stock_entry.json
index 7746d98..ac6e94b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.json
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.json
@@ -1,674 +1,674 @@
{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "creation": "2013-04-09 11:43:55",
- "docstatus": 0,
- "doctype": "DocType",
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "creation": "2013-04-09 11:43:55",
+ "docstatus": 0,
+ "doctype": "DocType",
"fields": [
{
- "fieldname": "col1",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_width": "50%",
- "read_only": 0,
+ "fieldname": "col1",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_width": "50%",
+ "read_only": 0,
"width": "50%"
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "in_filter": 0,
- "label": "Series",
- "no_copy": 1,
- "oldfieldname": "naming_series",
- "oldfieldtype": "Select",
- "options": "STE-",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
+ "allow_on_submit": 0,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Series",
+ "no_copy": 1,
+ "oldfieldname": "naming_series",
+ "oldfieldtype": "Select",
+ "options": "STE-",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "default": "Material Issue",
- "fieldname": "purpose",
- "fieldtype": "Select",
- "hidden": 0,
- "in_filter": 1,
- "in_list_view": 1,
- "label": "Purpose",
- "no_copy": 0,
- "oldfieldname": "purpose",
- "oldfieldtype": "Select",
- "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nManufacture\nRepack\nSubcontract\nSales Return\nPurchase Return",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
+ "allow_on_submit": 0,
+ "default": "Material Issue",
+ "fieldname": "purpose",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "in_filter": 1,
+ "in_list_view": 1,
+ "label": "Purpose",
+ "no_copy": 0,
+ "oldfieldname": "purpose",
+ "oldfieldtype": "Select",
+ "options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nManufacture\nRepack\nSubcontract\nSales Return\nPurchase Return",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "fieldname": "delivery_note_no",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "label": "Delivery Note No",
- "no_copy": 1,
- "oldfieldname": "delivery_note_no",
- "oldfieldtype": "Link",
- "options": "Delivery Note",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:in_list([\"Material Transfer for Manufacture\", \"Manufacture\"], doc.purpose)",
+ "fieldname": "production_order",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 1,
+ "label": "Production Order",
+ "no_copy": 0,
+ "oldfieldname": "production_order",
+ "oldfieldtype": "Link",
+ "options": "Production Order",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 1
- },
+ },
{
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "fieldname": "sales_invoice_no",
- "fieldtype": "Link",
- "hidden": 0,
- "label": "Sales Invoice No",
- "no_copy": 1,
- "options": "Sales Invoice",
- "permlevel": 0,
- "print_hide": 1,
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "label": "BOM No",
+ "options": "BOM",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Purchase Return\"",
- "fieldname": "purchase_receipt_no",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "label": "Purchase Receipt No",
- "no_copy": 1,
- "oldfieldname": "purchase_receipt_no",
- "oldfieldtype": "Link",
- "options": "Purchase Receipt",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "fieldname": "delivery_note_no",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Delivery Note No",
+ "no_copy": 1,
+ "oldfieldname": "delivery_note_no",
+ "oldfieldtype": "Link",
+ "options": "Delivery Note",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 1
- },
+ },
{
- "fieldname": "col2",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_width": "50%",
- "read_only": 0,
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "fieldname": "sales_invoice_no",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "label": "Sales Invoice No",
+ "no_copy": 1,
+ "options": "Sales Invoice",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Purchase Return\"",
+ "fieldname": "purchase_receipt_no",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Purchase Receipt No",
+ "no_copy": 1,
+ "oldfieldname": "purchase_receipt_no",
+ "oldfieldtype": "Link",
+ "options": "Purchase Receipt",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1
+ },
+ {
+ "fieldname": "col2",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_width": "50%",
+ "read_only": 0,
"width": "50%"
- },
+ },
{
- "allow_on_submit": 0,
- "default": "Today",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "label": "Posting Date",
- "no_copy": 1,
- "oldfieldname": "posting_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
+ "allow_on_submit": 0,
+ "default": "Today",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "in_filter": 1,
+ "in_list_view": 0,
+ "label": "Posting Date",
+ "no_copy": 1,
+ "oldfieldname": "posting_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
"search_index": 1
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "posting_time",
- "fieldtype": "Time",
- "hidden": 0,
- "in_filter": 0,
- "label": "Posting Time",
- "no_copy": 1,
- "oldfieldname": "posting_time",
- "oldfieldtype": "Time",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
+ "allow_on_submit": 0,
+ "fieldname": "posting_time",
+ "fieldtype": "Time",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Posting Time",
+ "no_copy": 1,
+ "oldfieldname": "posting_time",
+ "oldfieldtype": "Time",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
"search_index": 0
- },
+ },
{
- "fieldname": "items_section",
- "fieldtype": "Section Break",
- "label": "Items",
- "oldfieldtype": "Section Break",
- "permlevel": 0,
+ "fieldname": "items_section",
+ "fieldtype": "Section Break",
+ "label": "Items",
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "from_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Default Source Warehouse",
- "no_copy": 1,
- "oldfieldname": "from_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "fieldname": "from_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Default Source Warehouse",
+ "no_copy": 1,
+ "oldfieldname": "from_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "cb0",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "cb0",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "to_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Default Target Warehouse",
- "no_copy": 1,
- "oldfieldname": "to_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "fieldname": "to_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Default Target Warehouse",
+ "no_copy": 1,
+ "oldfieldname": "to_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "sb0",
- "fieldtype": "Section Break",
- "options": "Simple",
- "permlevel": 0,
+ "fieldname": "sb0",
+ "fieldtype": "Section Break",
+ "options": "Simple",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "items",
- "fieldtype": "Table",
- "hidden": 0,
- "in_filter": 0,
- "label": "Items",
- "no_copy": 0,
- "oldfieldname": "mtn_details",
- "oldfieldtype": "Table",
- "options": "Stock Entry Detail",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Items",
+ "no_copy": 0,
+ "oldfieldname": "mtn_details",
+ "oldfieldtype": "Table",
+ "options": "Stock Entry Detail",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "description": "Get valuation rate and available stock at source/target warehouse on mentioned posting date-time. If serialized item, please press this button after entering serial nos.",
- "fieldname": "get_stock_and_rate",
- "fieldtype": "Button",
- "label": "Get Stock and Rate",
- "oldfieldtype": "Button",
- "options": "get_stock_and_rate",
- "permlevel": 0,
- "print_hide": 1,
+ "description": "Get valuation rate and available stock at source/target warehouse on mentioned posting date-time. If serialized item, please press this button after entering serial nos.",
+ "fieldname": "get_stock_and_rate",
+ "fieldtype": "Button",
+ "label": "Get Stock and Rate",
+ "oldfieldtype": "Button",
+ "options": "get_stock_and_rate",
+ "permlevel": 0,
+ "print_hide": 1,
"read_only": 0
- },
+ },
{
- "depends_on": "eval:(doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")",
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "label": "From Bill of Materials",
- "permlevel": 0,
+ "depends_on": "eval:(doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")",
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "label": "From Bill of Materials",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:inList([\"Material Transfer\", \"Manufacture\"], doc.purpose)",
- "fieldname": "production_order",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 1,
- "label": "Production Order",
- "no_copy": 0,
- "oldfieldname": "production_order",
- "oldfieldtype": "Link",
- "options": "Production Order",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1
- },
- {
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "fieldname": "bom_no",
- "fieldtype": "Link",
- "label": "BOM No",
- "options": "BOM",
- "permlevel": 0,
- "read_only": 0
- },
- {
- "allow_on_submit": 0,
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "description": "As per Stock UOM",
- "fieldname": "fg_completed_qty",
- "fieldtype": "Float",
- "hidden": 0,
- "in_filter": 0,
- "label": "Manufacturing Quantity",
- "no_copy": 0,
- "oldfieldname": "fg_completed_qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "description": "As per Stock UOM",
+ "fieldname": "fg_completed_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Manufacturing Quantity",
+ "no_copy": 0,
+ "oldfieldname": "fg_completed_qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)",
- "fieldname": "additional_operating_cost",
- "fieldtype": "Currency",
- "label": "Additional Operating Cost",
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
+ "depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)",
+ "fieldname": "additional_operating_cost",
+ "fieldtype": "Currency",
+ "label": "Additional Operating Cost",
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "fieldname": "cb1",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "cb1",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "default": "1",
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
- "fieldname": "use_multi_level_bom",
- "fieldtype": "Check",
- "label": "Use Multi-Level BOM",
- "permlevel": 0,
- "print_hide": 1,
+ "default": "1",
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
+ "fieldname": "use_multi_level_bom",
+ "fieldtype": "Check",
+ "label": "Use Multi-Level BOM",
+ "permlevel": 0,
+ "print_hide": 1,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
- "fieldname": "get_items",
- "fieldtype": "Button",
- "hidden": 0,
- "in_filter": 0,
- "label": "Get Items",
- "no_copy": 0,
- "oldfieldtype": "Button",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
+ "fieldname": "get_items",
+ "fieldtype": "Button",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Get Items",
+ "no_copy": 0,
+ "oldfieldtype": "Button",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "fold",
- "fieldtype": "Fold",
+ "fieldname": "fold",
+ "fieldtype": "Fold",
"permlevel": 0
- },
+ },
{
- "depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")",
- "fieldname": "contact_section",
- "fieldtype": "Section Break",
- "label": "Contact Info",
- "permlevel": 0,
+ "depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")",
+ "fieldname": "contact_section",
+ "fieldtype": "Section Break",
+ "label": "Contact Info",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Purchase Return\"",
- "fieldname": "supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "label": "Supplier",
- "no_copy": 1,
- "oldfieldname": "supplier",
- "oldfieldtype": "Link",
- "options": "Supplier",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Purchase Return\"",
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Supplier",
+ "no_copy": 1,
+ "oldfieldname": "supplier",
+ "oldfieldtype": "Link",
+ "options": "Supplier",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Purchase Return\"",
- "fieldname": "supplier_name",
- "fieldtype": "Data",
- "hidden": 0,
- "in_filter": 0,
- "label": "Supplier Name",
- "no_copy": 1,
- "oldfieldname": "supplier_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Purchase Return\"",
+ "fieldname": "supplier_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Supplier Name",
+ "no_copy": 1,
+ "oldfieldname": "supplier_name",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Purchase Return\"",
- "fieldname": "supplier_address",
- "fieldtype": "Small Text",
- "hidden": 0,
- "in_filter": 0,
- "label": "Supplier Address",
- "no_copy": 1,
- "oldfieldname": "supplier_address",
- "oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Purchase Return\"",
+ "fieldname": "supplier_address",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Supplier Address",
+ "no_copy": 1,
+ "oldfieldname": "supplier_address",
+ "oldfieldtype": "Small Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "fieldname": "customer",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "label": "Customer",
- "no_copy": 1,
- "oldfieldname": "customer",
- "oldfieldtype": "Link",
- "options": "Customer",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Customer",
+ "no_copy": 1,
+ "oldfieldname": "customer",
+ "oldfieldtype": "Link",
+ "options": "Customer",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "fieldname": "customer_name",
- "fieldtype": "Data",
- "hidden": 0,
- "in_filter": 0,
- "label": "Customer Name",
- "no_copy": 1,
- "oldfieldname": "customer_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "fieldname": "customer_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Customer Name",
+ "no_copy": 1,
+ "oldfieldname": "customer_name",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "depends_on": "eval:doc.purpose==\"Sales Return\"",
- "fieldname": "customer_address",
- "fieldtype": "Small Text",
- "hidden": 0,
- "in_filter": 0,
- "label": "Customer Address",
- "no_copy": 1,
- "oldfieldname": "customer_address",
- "oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "depends_on": "eval:doc.purpose==\"Sales Return\"",
+ "fieldname": "customer_address",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Customer Address",
+ "no_copy": 1,
+ "oldfieldname": "customer_address",
+ "oldfieldtype": "Small Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "more_info",
- "fieldtype": "Section Break",
- "label": "More Info",
- "oldfieldtype": "Section Break",
- "permlevel": 0,
+ "fieldname": "more_info",
+ "fieldtype": "Section Break",
+ "label": "More Info",
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "fieldname": "project_name",
- "fieldtype": "Link",
- "in_filter": 1,
- "label": "Project Name",
- "oldfieldname": "project_name",
- "oldfieldtype": "Link",
- "options": "Project",
- "permlevel": 0,
+ "fieldname": "project_name",
+ "fieldtype": "Link",
+ "in_filter": 1,
+ "label": "Project Name",
+ "oldfieldname": "project_name",
+ "oldfieldtype": "Link",
+ "options": "Project",
+ "permlevel": 0,
"read_only": 0
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "remarks",
- "fieldtype": "Text",
- "hidden": 0,
- "in_filter": 0,
- "label": "Remarks",
- "no_copy": 1,
- "oldfieldname": "remarks",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "fieldname": "remarks",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Remarks",
+ "no_copy": 1,
+ "oldfieldname": "remarks",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "col5",
- "fieldtype": "Column Break",
- "permlevel": 0,
- "print_width": "50%",
- "read_only": 0,
+ "fieldname": "col5",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
+ "print_width": "50%",
+ "read_only": 0,
"width": "50%"
- },
+ },
{
- "fieldname": "total_amount",
- "fieldtype": "Currency",
- "label": "Total Amount",
- "options": "Company:company:default_currency",
- "permlevel": 0,
+ "fieldname": "total_amount",
+ "fieldtype": "Currency",
+ "label": "Total Amount",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 1,
- "label": "Company",
- "no_copy": 0,
- "oldfieldname": "company",
- "oldfieldtype": "Link",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
+ "allow_on_submit": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 1,
+ "label": "Company",
+ "no_copy": 0,
+ "oldfieldname": "company",
+ "oldfieldtype": "Link",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
"search_index": 0
- },
+ },
{
- "fieldname": "fiscal_year",
- "fieldtype": "Link",
- "in_filter": 0,
- "label": "Fiscal Year",
- "options": "Fiscal Year",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 0,
+ "fieldname": "fiscal_year",
+ "fieldtype": "Link",
+ "in_filter": 0,
+ "label": "Fiscal Year",
+ "options": "Fiscal Year",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 0,
"reqd": 1
- },
+ },
{
- "allow_on_submit": 1,
- "fieldname": "select_print_heading",
- "fieldtype": "Link",
- "hidden": 0,
- "in_filter": 0,
- "label": "Print Heading",
- "no_copy": 0,
- "oldfieldname": "select_print_heading",
- "oldfieldtype": "Link",
- "options": "Print Heading",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 1,
+ "fieldname": "select_print_heading",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_filter": 0,
+ "label": "Print Heading",
+ "no_copy": 0,
+ "oldfieldname": "select_print_heading",
+ "oldfieldtype": "Link",
+ "options": "Print Heading",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "in_filter": 0,
- "label": "Amended From",
- "no_copy": 1,
- "oldfieldname": "amended_from",
- "oldfieldtype": "Link",
- "options": "Stock Entry",
- "permlevel": 0,
- "print_hide": 1,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
+ "allow_on_submit": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "in_filter": 0,
+ "label": "Amended From",
+ "no_copy": 1,
+ "oldfieldname": "amended_from",
+ "oldfieldtype": "Link",
+ "options": "Stock Entry",
+ "permlevel": 0,
+ "print_hide": 1,
+ "read_only": 1,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "credit_note",
- "fieldtype": "Link",
- "hidden": 1,
- "label": "Credit Note",
- "options": "Journal Entry",
- "permlevel": 0,
+ "fieldname": "credit_note",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "label": "Credit Note",
+ "options": "Journal Entry",
+ "permlevel": 0,
"precision": ""
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "icon-file-text",
- "idx": 1,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 1,
- "issingle": 0,
- "max_attachments": 0,
- "modified": "2015-02-05 05:11:46.986620",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Stock Entry",
- "owner": "Administrator",
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "icon-file-text",
+ "idx": 1,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "max_attachments": 0,
+ "modified": "2015-02-17 00:49:04.294855",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Stock Entry",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "apply_user_permissions": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Material User",
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "apply_user_permissions": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Material User",
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "apply_user_permissions": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Manufacturing User",
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "apply_user_permissions": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Manufacturing User",
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Manufacturing Manager",
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Manufacturing Manager",
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Material Manager",
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Material Manager",
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "posting_date, from_warehouse, to_warehouse, purpose, remarks",
- "sort_field": "modified",
- "sort_order": "DESC",
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "posting_date, from_warehouse, to_warehouse, purpose, remarks",
+ "sort_field": "modified",
+ "sort_order": "DESC",
"title_field": "purpose"
-}
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 4faa644..2ca5bc5 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -82,7 +82,7 @@
self.meta.get_label("posting_date"))
def validate_purpose(self):
- valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer",
+ valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Material Transfer for Manufacture",
"Manufacture", "Repack", "Subcontract", "Sales Return", "Purchase Return"]
if self.purpose not in valid_purposes:
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
@@ -112,7 +112,7 @@
if not item.transfer_qty:
item.transfer_qty = item.qty * item.conversion_factor
- if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return")
+ if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return", "Material Transfer for Manufacture")
and not item.serial_no
and item.item_code in serialized_items):
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
@@ -121,8 +121,8 @@
def validate_warehouse(self, pro_obj):
"""perform various (sometimes conditional) validations on warehouse"""
- source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract"]
- target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract"]
+ source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract", "Material Transfer for Manufacture"]
+ target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract", "Material Transfer for Manufacture"]
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
@@ -169,13 +169,14 @@
frappe.throw(_("Source and target warehouse cannot be same for row {0}").format(d.idx))
def validate_production_order(self):
- if self.purpose == "Manufacture":
+ if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
# check if production order is entered
if not self.production_order:
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))
# check for double entry
- self.check_if_operations_completed()
- self.check_duplicate_entry_for_production_order()
+ if self.purpose=="Manufacture":
+ self.check_if_operations_completed()
+ self.check_duplicate_entry_for_production_order()
elif self.purpose != "Material Transfer":
self.production_order = None
@@ -503,8 +504,8 @@
if self.bom_no:
if self.purpose in ["Material Issue", "Material Transfer", "Manufacture", "Repack",
- "Subcontract"]:
- if self.production_order and self.purpose == "Material Transfer":
+ "Subcontract", "Material Transfer for Manufacture"]:
+ if self.production_order and self.purpose == "Material Transfer for Manufacture":
item_dict = self.get_pending_raw_materials(pro_obj)
if self.to_warehouse and pro_obj:
for item in item_dict.values():
@@ -601,7 +602,7 @@
result = frappe.db.sql("""select t1.item_code, sum(t1.qty)
from `tabStock Entry Detail` t1, `tabStock Entry` t2
where t1.parent = t2.name and t2.production_order = %s and t2.docstatus = 1
- and t2.purpose = 'Material Transfer'
+ and t2.purpose = 'Material Transfer for Manufacture'
group by t1.item_code""", self.production_order)
for t in result:
issued_item_qty[t[0]] = flt(t[1])
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index 27ed872..c2cee33 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -5,6 +5,26 @@
frappe.require("assets/erpnext/js/utils.js");
frappe.provide("erpnext.stock");
+frappe.ui.form.on("Stock Reconciliation", "get_items", function(frm) {
+ frappe.prompt({label:"Warehouse", fieldtype:"Link", options:"Warehouse", reqd: 1},
+ function(data) {
+ frappe.call({
+ method:"erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.get_items",
+ args: {warehouse: data.warehouse},
+ callback: function(r) {
+ var items = [];
+ frm.clear_table("items");
+ for(var i=0; i< r.message.length; i++) {
+ var d = frm.add_child("items");
+ $.extend(d, r.message[i]);
+ }
+ frm.refresh_field("items");
+ }
+ });
+ }
+ );
+});
+
erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({
onload: function() {
this.set_default_expense_account();
@@ -31,6 +51,8 @@
setup: function() {
var me = this;
+ this.frm.get_field("items").grid.allow_build_edit();
+
if (sys_defaults.auto_accounting_for_stock) {
this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
this.frm.add_fetch("company", "cost_center", "cost_center");
@@ -55,108 +77,29 @@
},
refresh: function() {
- if(this.frm.doc.docstatus===0) {
- this.show_download_template();
- this.show_upload();
- if(this.frm.doc.reconciliation_json) {
- this.frm.set_intro(__("You can submit this Stock Reconciliation."));
- } else {
- this.frm.set_intro(__("Download the Template, fill appropriate data and attach the modified file."));
- }
- } else if(this.frm.doc.docstatus == 1) {
- this.frm.set_intro(__("Cancelling this Stock Reconciliation will nullify its effect."));
- this.show_stock_ledger();
- this.show_general_ledger();
- } else {
- this.frm.set_intro("");
- }
- this.show_reconciliation_data();
- this.show_download_reconciliation_data();
+ //
},
- show_download_template: function() {
- var me = this;
- this.frm.add_custom_button(__("Download Template"), function() {
- this.title = __("Stock Reconcilation Template");
- frappe.tools.downloadify([[__("Stock Reconciliation")],
- ["----"],
- [__("Stock Reconciliation can be used to update the stock on a particular date, usually as per physical inventory.")],
- [__("When submitted, the system creates difference entries to set the given stock and valuation on this date.")],
- [__("It can also be used to create opening stock entries and to fix stock value.")],
- ["----"],
- [__("Notes:")],
- [__("Item Code and Warehouse should already exist.")],
- [__("You can update either Quantity or Valuation Rate or both.")],
- [__("If no change in either Quantity or Valuation Rate, leave the cell blank.")],
- ["----"],
- ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]], null, this);
- return false;
- }, "icon-download");
- },
+ // show_download_template: function() {
+ // var me = this;
+ // this.frm.add_custom_button(__("Download Template"), function() {
+ // this.title = __("Stock Reconcilation Template");
+ // frappe.tools.downloadify([[__("Stock Reconciliation")],
+ // ["----"],
+ // [__("Stock Reconciliation can be used to update the stock on a particular date, usually as per physical inventory.")],
+ // [__("When submitted, the system creates difference entries to set the given stock and valuation on this date.")],
+ // [__("It can also be used to create opening stock entries and to fix stock value.")],
+ // ["----"],
+ // [__("Notes:")],
+ // [__("Item Code and Warehouse should already exist.")],
+ // [__("You can update either Quantity or Valuation Rate or both.")],
+ // [__("If no change in either Quantity or Valuation Rate, leave the cell blank.")],
+ // ["----"],
+ // ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]], null, this);
+ // return false;
+ // }, "icon-download");
+ // },
- show_upload: function() {
- var me = this;
- var $wrapper = $(cur_frm.fields_dict.upload_html.wrapper).empty();
-
- // upload
- frappe.upload.make({
- parent: $wrapper,
- args: {
- method: 'erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.upload'
- },
- sample_url: "e.g. http://example.com/somefile.csv",
- callback: function(attachment, r) {
- me.frm.set_value("reconciliation_json", JSON.stringify(r.message));
- me.show_reconciliation_data();
- me.frm.save();
- }
- });
-
- // rename button
- $wrapper.find('form input[type="submit"]')
- .attr('value', 'Upload')
-
- },
-
- show_download_reconciliation_data: function() {
- var me = this;
- if(this.frm.doc.reconciliation_json) {
- this.frm.add_custom_button(__("Download Reconcilation Data"), function() {
- this.title = __("Stock Reconcilation Data");
- frappe.tools.downloadify(JSON.parse(me.frm.doc.reconciliation_json), null, this);
- return false;
- }, "icon-download", "btn-default");
- }
- },
-
- show_reconciliation_data: function() {
- var $wrapper = $(cur_frm.fields_dict.reconciliation_html.wrapper).empty();
- if(this.frm.doc.reconciliation_json) {
- var reconciliation_data = JSON.parse(this.frm.doc.reconciliation_json);
-
- var _make = function(data, header) {
- var result = "";
-
- var _render = header
- ? function(col) { return "<th>" + col + "</th>"; }
- : function(col) { return "<td>" + col + "</td>"; };
-
- $.each(data, function(i, row) {
- result += "<tr>"
- + $.map(row, _render).join("")
- + "</tr>";
- });
- return result;
- };
-
- var $reconciliation_table = $("<div style='overflow-x: auto;'>\
- <table class='table table-striped table-bordered'>\
- <thead>" + _make([reconciliation_data[0]], true) + "</thead>\
- <tbody>" + _make(reconciliation_data.splice(1)) + "</tbody>\
- </table>\
- </div>").appendTo($wrapper);
- }
- },
});
cur_frm.cscript = new erpnext.stock.StockReconciliation({frm: cur_frm});
@@ -167,4 +110,4 @@
cur_frm.cscript.posting_date = function(doc, cdt, cdn){
erpnext.get_fiscal_year(doc.company, doc.posting_date);
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
index a6c09ee..6ca212d 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
@@ -1,5 +1,5 @@
{
- "allow_copy": 1,
+ "allow_copy": 0,
"autoname": "SR/.######",
"creation": "2013-03-28 10:35:31",
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
@@ -32,6 +32,14 @@
"reqd": 1
},
{
+ "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
+ "fieldname": "expense_account",
+ "fieldtype": "Link",
+ "label": "Difference Account",
+ "options": "Account",
+ "permlevel": 0
+ },
+ {
"fieldname": "amended_from",
"fieldtype": "Link",
"ignore_user_permissions": 1,
@@ -43,6 +51,11 @@
"read_only": 1
},
{
+ "fieldname": "col1",
+ "fieldtype": "Column Break",
+ "permlevel": 0
+ },
+ {
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
@@ -61,14 +74,6 @@
},
{
"depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
- "fieldname": "expense_account",
- "fieldtype": "Link",
- "label": "Difference Account",
- "options": "Account",
- "permlevel": 0
- },
- {
- "depends_on": "eval:cint(sys_defaults.auto_accounting_for_stock)",
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
@@ -76,9 +81,31 @@
"permlevel": 0
},
{
- "fieldname": "col1",
- "fieldtype": "Column Break",
- "permlevel": 0
+ "fieldname": "sb9",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
+ "fieldname": "items",
+ "fieldtype": "Table",
+ "label": "Items",
+ "options": "Stock Reconciliation Item",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
+ "fieldname": "get_items",
+ "fieldtype": "Button",
+ "label": "Get Items",
+ "permlevel": 0,
+ "precision": ""
+ },
+ {
+ "fieldname": "section_break_9",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
+ "precision": ""
},
{
"fieldname": "upload_html",
@@ -119,7 +146,7 @@
"idx": 1,
"is_submittable": 1,
"max_attachments": 1,
- "modified": "2015-02-05 05:11:47.153367",
+ "modified": "2015-02-17 02:09:17.483016",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation",
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 9c85277..1bb3f56 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -4,7 +4,6 @@
from __future__ import unicode_literals
import frappe
import frappe.defaults
-import json
from frappe import msgprint, _
from frappe.utils import cstr, flt, cint
from erpnext.stock.stock_ledger import update_entries_after
@@ -28,61 +27,41 @@
self.make_gl_entries_on_cancel()
def validate_data(self):
- if not self.reconciliation_json:
- return
-
- data = json.loads(self.reconciliation_json)
-
- # strip out extra columns (if any)
- data = [row[:4] for row in data]
-
- if self.head_row not in data:
- msgprint(_("""Wrong Template: Unable to find head row."""),
- raise_exception=1)
-
- # remove the help part and save the json
- head_row_no = 0
- if data.index(self.head_row) != 0:
- head_row_no = data.index(self.head_row)
- data = data[head_row_no:]
- self.reconciliation_json = json.dumps(data)
-
def _get_msg(row_num, msg):
- return _("Row # {0}: ").format(row_num+head_row_no+2) + msg
+ return _("Row # {0}: ").format(row_num+1) + msg
self.validation_messages = []
item_warehouse_combinations = []
# validate no of rows
- rows = data[1:]
+ rows = self.items
if len(rows) > 100:
- msgprint(_("""Sorry! We can only allow upto 100 rows for Stock Reconciliation."""),
- raise_exception=True)
+ frappe.throw(_("""Max 100 rows for Stock Reconciliation."""))
for row_num, row in enumerate(rows):
# find duplicates
- if [row[0], row[1]] in item_warehouse_combinations:
+ if [row.item_code, row.warehouse] in item_warehouse_combinations:
self.validation_messages.append(_get_msg(row_num, _("Duplicate entry")))
else:
- item_warehouse_combinations.append([row[0], row[1]])
+ item_warehouse_combinations.append([row.item_code, row.warehouse])
- self.validate_item(row[0], row_num+head_row_no+2)
+ self.validate_item(row.item_code, row_num+1)
# validate warehouse
- if not frappe.db.get_value("Warehouse", row[1]):
+ if not frappe.db.get_value("Warehouse", row.warehouse):
self.validation_messages.append(_get_msg(row_num, _("Warehouse not found in the system")))
# if both not specified
- if row[2] in ["", None] and row[3] in ["", None]:
+ if row.qty in ["", None] and row.valuation_rate in ["", None]:
self.validation_messages.append(_get_msg(row_num,
_("Please specify either Quantity or Valuation Rate or both")))
# do not allow negative quantity
- if flt(row[2]) < 0:
+ if flt(row.qty) < 0:
self.validation_messages.append(_get_msg(row_num,
_("Negative Quantity is not allowed")))
# do not allow negative valuation
- if flt(row[3]) < 0:
+ if flt(row.valuation_rate) < 0:
self.validation_messages.append(_get_msg(row_num,
_("Negative Valuation Rate is not allowed")))
@@ -129,16 +108,7 @@
and create stock ledger entries based on the difference"""
from erpnext.stock.stock_ledger import get_previous_sle
- row_template = ["item_code", "warehouse", "qty", "valuation_rate"]
-
- if not self.reconciliation_json:
- msgprint(_("""Stock Reconciliation file not uploaded"""), raise_exception=1)
-
- data = json.loads(self.reconciliation_json)
- for row_num, row in enumerate(data[data.index(self.head_row)+1:]):
- row = frappe._dict(zip(row_template, row))
- row["row_num"] = row_num
-
+ for row in self.items:
if row.qty in ("", None) or row.valuation_rate in ("", None):
previous_sle = get_previous_sle({
"item_code": row.item_code,
@@ -216,7 +186,14 @@
frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"))
@frappe.whitelist()
-def upload():
- from frappe.utils.csvutils import read_csv_content_from_uploaded_file
- csv_content = read_csv_content_from_uploaded_file()
- return filter(lambda x: x and any(x), csv_content)
+def get_items(warehouse):
+ from erpnext.stock.utils import get_stock_balance
+ items = frappe.get_list("Item", fields=["name"], filters=
+ {"is_stock_item": "Yes", "has_serial_no": "No", "has_batch_no": "No"})
+ for item in items:
+ item.item_code = item.name
+ item.warehouse = warehouse
+ del item["name"]
+ item.qty, item.valuation_rate = get_stock_balance(item.name, warehouse, with_valuation_rate=True)
+
+ return items
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/__init__.py b/erpnext/stock/doctype/stock_reconciliation_item/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reconciliation_item/__init__.py
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
new file mode 100644
index 0000000..aa55031
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -0,0 +1,110 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "creation": "2015-02-17 01:06:05.072764",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Item Code",
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Warehouse",
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "description": "Leave blank if no change",
+ "fieldname": "qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Quantity",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "description": "Leave blank if no change",
+ "fieldname": "valuation_rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "label": "Valuation Rate",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "modified": "2015-02-17 01:07:50.200649",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Stock Reconciliation Item",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
new file mode 100644
index 0000000..6597efd
--- /dev/null
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class StockReconciliationItem(Document):
+ pass
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index ceb0ebf..9a33735 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -34,19 +34,22 @@
return sum(sle_map.values())
-def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None):
+def get_stock_balance(item_code, warehouse, posting_date=None, posting_time=None, with_valuation_rate=False):
+ """Returns stock balance quantity at given warehouse on given posting date or current date.
+
+ If `with_valuation_rate` is True, will return tuple (qty, rate)"""
if not posting_date: posting_date = nowdate()
if not posting_time: posting_time = nowtime()
- last_entry = frappe.db.sql("""select qty_after_transaction from `tabStock Ledger Entry`
+ last_entry = frappe.db.sql("""select qty_after_transaction, valuation_rate from `tabStock Ledger Entry`
where item_code=%s and warehouse=%s
and timestamp(posting_date, posting_time) < timestamp(%s, %s)
order by timestamp(posting_date, posting_time) limit 1""",
(item_code, warehouse, posting_date, posting_time))
- if last_entry:
- return last_entry[0][0]
+ if with_valuation_rate:
+ return (last_entry[0][0], last_entry[0][1]) if last_entry else (0.0, 0.0)
else:
- return 0.0
+ return last_entry[0][0] if last_entry else 0.0
def get_latest_stock_balance():
bin_map = {}
diff --git a/erpnext/support/doctype/customer_issue/README.md b/erpnext/support/doctype/customer_issue/README.md
deleted file mode 100644
index 0560abe..0000000
--- a/erpnext/support/doctype/customer_issue/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Issue raised by Customer, can be tagged against Invoice, Serial Number to verify warranty, service contract.
\ No newline at end of file
diff --git a/erpnext/support/doctype/customer_issue/__init__.py b/erpnext/support/doctype/customer_issue/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/support/doctype/customer_issue/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/support/doctype/customer_issue/test_customer_issue.py b/erpnext/support/doctype/customer_issue/test_customer_issue.py
deleted file mode 100644
index 88f54e2..0000000
--- a/erpnext/support/doctype/customer_issue/test_customer_issue.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and Contributors
-# See license.txt
-
-import frappe
-import unittest
-
-test_records = frappe.get_test_records('Customer Issue')
-
-class TestCustomerIssue(unittest.TestCase):
- pass
diff --git a/erpnext/support/doctype/customer_issue/test_records.json b/erpnext/support/doctype/customer_issue/test_records.json
deleted file mode 100644
index cb3a3a1..0000000
--- a/erpnext/support/doctype/customer_issue/test_records.json
+++ /dev/null
@@ -1,6 +0,0 @@
-[
- {
- "doctype": "Customer Issue",
- "name": "_Test Customer Issue 1"
- }
-]
diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
index c58b2ee..5427b0f 100644
--- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js
@@ -27,11 +27,11 @@
}
})
}, "icon-download", "btn-default");
- cur_frm.add_custom_button(__('From Customer Issue'),
+ cur_frm.add_custom_button(__('From Warranty Claim'),
function() {
frappe.model.map_current_doc({
method: "erpnext.support.doctype.customer_issue.customer_issue.make_maintenance_visit",
- source_doctype: "Customer Issue",
+ source_doctype: "Warranty Claim",
get_query_filters: {
status: ["in", "Open, Work in Progress"],
customer: cur_frm.doc.customer || undefined,
diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
index 6ad0a9d..b7a9b9e 100644
--- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
+++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py
@@ -24,7 +24,7 @@
def update_customer_issue(self, flag):
for d in self.get('purposes'):
- if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' :
+ if d.prevdoc_docname and d.prevdoc_doctype == 'Warranty Claim' :
if flag==1:
mntc_date = self.mntc_date
service_person = d.service_person
@@ -48,11 +48,11 @@
service_person = ''
work_done = ''
- frappe.db.sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname))
+ frappe.db.sql("update `tabWarranty Claim` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname))
def check_if_last_visit(self):
- """check if last maintenance visit against same sales order/ customer issue"""
+ """check if last maintenance visit against same sales order/ Warranty Claim"""
check_for_docname = None
for d in self.get('purposes'):
if d.prevdoc_docname:
diff --git a/erpnext/support/doctype/warranty_claim/__init__.py b/erpnext/support/doctype/warranty_claim/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/support/doctype/warranty_claim/__init__.py
diff --git a/erpnext/support/doctype/warranty_claim/test_records.json b/erpnext/support/doctype/warranty_claim/test_records.json
new file mode 100644
index 0000000..b5b1904
--- /dev/null
+++ b/erpnext/support/doctype/warranty_claim/test_records.json
@@ -0,0 +1,6 @@
+[
+ {
+ "doctype": "Warranty Claim",
+ "name": "_Test Warranty Claim 1"
+ }
+]
diff --git a/erpnext/support/doctype/warranty_claim/test_warranty_claim.py b/erpnext/support/doctype/warranty_claim/test_warranty_claim.py
new file mode 100644
index 0000000..238808c
--- /dev/null
+++ b/erpnext/support/doctype/warranty_claim/test_warranty_claim.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and Contributors
+# See license.txt
+
+import frappe
+import unittest
+
+test_records = frappe.get_test_records('Warranty Claim')
+
+class TestWarrantyClaim(unittest.TestCase):
+ pass
diff --git a/erpnext/support/doctype/customer_issue/customer_issue.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
similarity index 89%
rename from erpnext/support/doctype/customer_issue/customer_issue.js
rename to erpnext/support/doctype/warranty_claim/warranty_claim.js
index d260677..e062559 100644
--- a/erpnext/support/doctype/customer_issue/customer_issue.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -4,14 +4,14 @@
frappe.provide("erpnext.support");
frappe.require("assets/erpnext/js/utils.js");
-frappe.ui.form.on_change("Customer Issue", "customer", function(frm) {
+frappe.ui.form.on_change("Warranty Claim", "customer", function(frm) {
erpnext.utils.get_party_details(frm) });
-frappe.ui.form.on_change("Customer Issue", "customer_address",
+frappe.ui.form.on_change("Warranty Claim", "customer_address",
erpnext.utils.get_address_display);
-frappe.ui.form.on_change("Customer Issue", "contact_person",
+frappe.ui.form.on_change("Warranty Claim", "contact_person",
erpnext.utils.get_contact_details);
-erpnext.support.CustomerIssue = frappe.ui.form.Controller.extend({
+erpnext.support.WarrantyClaim = frappe.ui.form.Controller.extend({
refresh: function() {
if((cur_frm.doc.status=='Open' || cur_frm.doc.status == 'Work In Progress')) {
cur_frm.add_custom_button(__('Make Maintenance Visit'),
@@ -27,7 +27,7 @@
}
});
-$.extend(cur_frm.cscript, new erpnext.support.CustomerIssue({frm: cur_frm}));
+$.extend(cur_frm.cscript, new erpnext.support.WarrantyClaim({frm: cur_frm}));
cur_frm.cscript.onload = function(doc,cdt,cdn){
if(!doc.status)
diff --git a/erpnext/support/doctype/customer_issue/customer_issue.json b/erpnext/support/doctype/warranty_claim/warranty_claim.json
similarity index 98%
rename from erpnext/support/doctype/customer_issue/customer_issue.json
rename to erpnext/support/doctype/warranty_claim/warranty_claim.json
index 41c185e..71fa5a0 100644
--- a/erpnext/support/doctype/customer_issue/customer_issue.json
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.json
@@ -387,7 +387,7 @@
"no_copy": 1,
"oldfieldname": "amended_from",
"oldfieldtype": "Data",
- "options": "Customer Issue",
+ "options": "Warranty Claim",
"permlevel": 0,
"print_hide": 1,
"width": "150px"
@@ -396,10 +396,10 @@
"icon": "icon-bug",
"idx": 1,
"is_submittable": 0,
- "modified": "2015-02-05 05:11:36.857779",
+ "modified": "2015-02-17 00:12:52.430072",
"modified_by": "Administrator",
"module": "Support",
- "name": "Customer Issue",
+ "name": "Warranty Claim",
"owner": "harshada@webnotestech.com",
"permissions": [
{
diff --git a/erpnext/support/doctype/customer_issue/customer_issue.py b/erpnext/support/doctype/warranty_claim/warranty_claim.py
similarity index 86%
rename from erpnext/support/doctype/customer_issue/customer_issue.py
rename to erpnext/support/doctype/warranty_claim/warranty_claim.py
index 9e6300e..f548f6a 100644
--- a/erpnext/support/doctype/customer_issue/customer_issue.py
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.py
@@ -11,7 +11,7 @@
from erpnext.utilities.transaction_base import TransactionBase
-class CustomerIssue(TransactionBase):
+class WarrantyClaim(TransactionBase):
def get_feed(self):
return _("{0}: From {1}").format(self.status, self.customer_name)
@@ -20,7 +20,7 @@
frappe.throw(_("Customer is required"))
if self.status=="Closed" and \
- frappe.db.get_value("Customer Issue", self.name, "status")!="Closed":
+ frappe.db.get_value("Warranty Claim", self.name, "status")!="Closed":
self.resolution_date = today()
def on_cancel(self):
@@ -30,7 +30,7 @@
(self.name))
if lst:
lst1 = ','.join([x[0] for x in lst])
- frappe.throw(_("Cancel Material Visit {0} before cancelling this Customer Issue").format(lst1))
+ frappe.throw(_("Cancel Material Visit {0} before cancelling this Warranty Claim").format(lst1))
else:
frappe.db.set(self, 'status', 'Cancelled')
@@ -51,14 +51,14 @@
and t1.docstatus=1 and t1.completion_status='Fully Completed'""", source_name)
if not visit:
- target_doc = get_mapped_doc("Customer Issue", source_name, {
- "Customer Issue": {
+ target_doc = get_mapped_doc("Warranty Claim", source_name, {
+ "Warranty Claim": {
"doctype": "Maintenance Visit",
"field_map": {}
}
}, target_doc)
- source_doc = frappe.get_doc("Customer Issue", source_name)
+ source_doc = frappe.get_doc("Warranty Claim", source_name)
if source_doc.get("item_code"):
table_map = {
"doctype": "Maintenance Visit Purpose",
diff --git a/erpnext/support/doctype/customer_issue/customer_issue_list.js b/erpnext/support/doctype/warranty_claim/warranty_claim_list.js
similarity index 64%
rename from erpnext/support/doctype/customer_issue/customer_issue_list.js
rename to erpnext/support/doctype/warranty_claim/warranty_claim_list.js
index f47934c..e162e13 100644
--- a/erpnext/support/doctype/customer_issue/customer_issue_list.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim_list.js
@@ -1,4 +1,4 @@
-frappe.listview_settings['Customer Issue'] = {
+frappe.listview_settings['Warranty Claim'] = {
add_fields: ["status", "customer", "item_code"],
filters:[["status","=", "Open"]]
};
diff --git a/erpnext/templates/form_grid/stock_entry_grid.html b/erpnext/templates/form_grid/stock_entry_grid.html
index cf9b260..ef465a4 100644
--- a/erpnext/templates/form_grid/stock_entry_grid.html
+++ b/erpnext/templates/form_grid/stock_entry_grid.html
@@ -18,15 +18,18 @@
<p>{%= doc.description %}</p>{% } %}
{% include "templates/form_grid/includes/visible_cols.html" %}
<div>
- {% if(doc.s_warehouse) { %}<span class="label
- {%= (doc.actual_qty >= doc.qty) ? "label-success"
- : "label-danger" %}"
- title="{%= (doc.actual_qty >= doc.qty) ? __("In Stock")
- : __("Not In Stock") %}">
- {%= doc.s_warehouse || "" %}</span>{% } %}
- <i class="icon-long-arrow-right"></i>
+ {% if(doc.s_warehouse) { %}
+ <span class="label label-primary">
+ {%= doc.s_warehouse || "" %}</span>
+ {% } %}
+ <i class="octicon octicon-arrow-small-right"></i>
{% if(doc.t_warehouse) { %}<span class="label label-primary">
{%= doc.t_warehouse || "" %}</span>{% } %}
+ {% if(doc.s_warehouse && doc.actual_qty < doc.qty) { %}
+ <span class="text-danger small" style="margin-left: 15px;">
+ <span class="octicon octicon-stop" style="font-size: 12px;"></span> Not in Stock
+ </span>
+ {% } %}
</div>
</div>
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index 6fe4262..e8015bd 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -5,6 +5,7 @@
import frappe
from frappe import _
from frappe.utils import cstr, now_datetime, cint
+import frappe.share
from erpnext.controllers.status_updater import StatusUpdater
@@ -36,7 +37,7 @@
opts = frappe._dict(opts)
if self.contact_date:
- event_doclist = frappe.get_doc({
+ event = frappe.get_doc({
"doctype": "Event",
"owner": opts.owner or self.owner,
"subject": opts.subject,
@@ -48,12 +49,9 @@
})
if frappe.db.exists("User", self.contact_by):
- event_doclist.append("users", {
- "doctype": "Event User",
- "person": self.contact_by
- })
+ frappe.share("Event", event.name, self.contact_by)
- event_doclist.insert(ignore_permissions=True)
+ event.insert(ignore_permissions=True)
def validate_uom_is_integer(self, uom_field, qty_fields):
validate_uom_is_integer(self, uom_field, qty_fields)