From 3daa49ac1f1c641a7dca56c2c1656584102fb6ab Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 21 Oct 2014 16:16:30 +0530 Subject: [PATCH] [shopping-cart] i'm back --- erpnext/config/desktop.py | 7 + erpnext/hooks.py | 19 +- erpnext/modules.txt | 1 + erpnext/patches/v4_2/party_model.py | 3 + .../update_frozen_accounts_permission_role.py | 4 +- erpnext/public/build.json | 6 +- erpnext/public/css/shopping_cart.css | 11 + erpnext/public/js/shopping_cart.js | 66 +++ erpnext/shopping_cart/__init__.py | 126 +++++ erpnext/shopping_cart/cart.py | 434 ++++++++++++++++++ erpnext/shopping_cart/doctype/__init__.py | 0 .../shopping_cart_price_list/__init__.py | 0 .../shopping_cart_price_list.json | 23 + .../shopping_cart_price_list.py | 12 + .../shopping_cart_settings/__init__.py | 0 .../shopping_cart_settings.js | 10 + .../shopping_cart_settings.json | 115 +++++ .../shopping_cart_settings.py | 215 +++++++++ .../test_shopping_cart_settings.py | 79 ++++ .../shopping_cart_shipping_rule/__init__.py | 0 .../shopping_cart_shipping_rule.json | 23 + .../shopping_cart_shipping_rule.py | 12 + .../__init__.py | 0 ...hopping_cart_taxes_and_charges_master.json | 23 + .../shopping_cart_taxes_and_charges_master.py | 12 + erpnext/shopping_cart/product.py | 54 +++ erpnext/shopping_cart/test_shopping_cart.py | 230 ++++++++++ erpnext/shopping_cart/utils.py | 47 ++ erpnext/templates/includes/cart.js | 297 ++++++++++++ erpnext/templates/includes/product_page.js | 2 +- erpnext/templates/includes/sale.html | 85 ++++ .../includes/sales_transactions.html | 30 ++ erpnext/templates/includes/transactions.html | 53 +++ erpnext/templates/pages/address.html | 112 +++++ erpnext/templates/pages/address.py | 62 +++ erpnext/templates/pages/addresses.html | 52 +++ erpnext/templates/pages/addresses.py | 13 + erpnext/templates/pages/cart.html | 57 +++ erpnext/templates/pages/cart.py | 7 + erpnext/templates/pages/invoice.html | 6 + erpnext/templates/pages/invoice.py | 31 ++ erpnext/templates/pages/invoices.html | 6 + erpnext/templates/pages/invoices.py | 29 ++ erpnext/templates/pages/order.html | 6 + erpnext/templates/pages/order.py | 34 ++ erpnext/templates/pages/orders.html | 5 + erpnext/templates/pages/orders.py | 30 ++ erpnext/templates/pages/shipment.html | 6 + erpnext/templates/pages/shipment.py | 17 + erpnext/templates/pages/shipments.html | 5 + erpnext/templates/pages/shipments.py | 25 + erpnext/templates/pages/ticket.html | 116 +++++ erpnext/templates/pages/ticket.py | 41 ++ erpnext/templates/pages/tickets.html | 92 ++++ erpnext/templates/pages/tickets.py | 54 +++ erpnext/templates/pages/user.html | 57 +++ erpnext/templates/pages/user.py | 40 ++ erpnext/templates/utils.py | 49 +- erpnext/translations/ar.csv | 46 ++ erpnext/translations/de.csv | 48 ++ erpnext/translations/el.csv | 46 ++ erpnext/translations/es.csv | 46 ++ erpnext/translations/fr.csv | 46 ++ erpnext/translations/hi.csv | 46 ++ erpnext/translations/hr.csv | 46 ++ erpnext/translations/id.csv | 46 ++ erpnext/translations/it.csv | 46 ++ erpnext/translations/ja.csv | 46 ++ erpnext/translations/kn.csv | 46 ++ erpnext/translations/ko.csv | 46 ++ erpnext/translations/nl.csv | 46 ++ erpnext/translations/pt-BR.csv | 46 ++ erpnext/translations/pt.csv | 46 ++ erpnext/translations/ro.csv | 46 ++ erpnext/translations/ru.csv | 46 ++ erpnext/translations/sr.csv | 46 ++ erpnext/translations/ta.csv | 46 ++ erpnext/translations/th.csv | 46 ++ erpnext/translations/tr.csv | 46 ++ erpnext/translations/vi.csv | 46 ++ erpnext/translations/zh-cn.csv | 46 ++ erpnext/translations/zh-tw.csv | 46 ++ 82 files changed, 4047 insertions(+), 10 deletions(-) create mode 100644 erpnext/public/css/shopping_cart.css create mode 100644 erpnext/public/js/shopping_cart.js create mode 100644 erpnext/shopping_cart/__init__.py create mode 100644 erpnext/shopping_cart/cart.py create mode 100644 erpnext/shopping_cart/doctype/__init__.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_settings/__init__.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/__init__.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.json create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/__init__.py create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.json create mode 100644 erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.py create mode 100644 erpnext/shopping_cart/product.py create mode 100644 erpnext/shopping_cart/test_shopping_cart.py create mode 100644 erpnext/shopping_cart/utils.py create mode 100644 erpnext/templates/includes/cart.js create mode 100644 erpnext/templates/includes/sale.html create mode 100644 erpnext/templates/includes/sales_transactions.html create mode 100644 erpnext/templates/includes/transactions.html create mode 100644 erpnext/templates/pages/address.html create mode 100644 erpnext/templates/pages/address.py create mode 100644 erpnext/templates/pages/addresses.html create mode 100644 erpnext/templates/pages/addresses.py create mode 100644 erpnext/templates/pages/cart.html create mode 100644 erpnext/templates/pages/cart.py create mode 100644 erpnext/templates/pages/invoice.html create mode 100644 erpnext/templates/pages/invoice.py create mode 100644 erpnext/templates/pages/invoices.html create mode 100644 erpnext/templates/pages/invoices.py create mode 100644 erpnext/templates/pages/order.html create mode 100644 erpnext/templates/pages/order.py create mode 100644 erpnext/templates/pages/orders.html create mode 100644 erpnext/templates/pages/orders.py create mode 100644 erpnext/templates/pages/shipment.html create mode 100644 erpnext/templates/pages/shipment.py create mode 100644 erpnext/templates/pages/shipments.html create mode 100644 erpnext/templates/pages/shipments.py create mode 100644 erpnext/templates/pages/ticket.html create mode 100644 erpnext/templates/pages/ticket.py create mode 100644 erpnext/templates/pages/tickets.html create mode 100644 erpnext/templates/pages/tickets.py create mode 100644 erpnext/templates/pages/user.html create mode 100644 erpnext/templates/pages/user.py diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py index 34f15995f7..ce9b25503b 100644 --- a/erpnext/config/desktop.py +++ b/erpnext/config/desktop.py @@ -48,5 +48,12 @@ def get_data(): "color": "#2c3e50", "icon": "icon-phone", "type": "module" + }, + "Shopping Cart": { + "color": "#B7E090", + "icon": "icon-shopping-cart", + "label": _("Shopping Cart"), + "link": "Form/Shopping Cart Settings", + "type": "module" } } diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 54b911a596..ea65400e36 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -11,14 +11,18 @@ error_report_email = "support@erpnext.com" app_include_js = "assets/js/erpnext.min.js" app_include_css = "assets/css/erpnext.css" web_include_js = "assets/js/erpnext-web.min.js" +web_include_css = "assets/css/shopping-cart-web.css" after_install = "erpnext.setup.install.after_install" boot_session = "erpnext.startup.boot.boot_session" notification_config = "erpnext.startup.notifications.get_notification_config" +on_session_creation = "erpnext.shopping_cart.utils.set_cart_count" +on_logout = "erpnext.shopping_cart.utils.clear_cart_count" +update_website_context = ["erpnext.shopping_cart.utils.update_website_context", "erpnext.startup.webutils.update_website_context"] + dump_report_map = "erpnext.startup.report_data_map.data_map" -update_website_context = "erpnext.startup.webutils.update_website_context" before_tests = "erpnext.setup.utils.before_tests" @@ -36,7 +40,13 @@ doc_events = { "User": { "validate": "erpnext.hr.doctype.employee.employee.validate_employee_role", "on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions" - } + }, + "Sales Taxes and Charges Master": { + "on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings" + }, + "Price List": { + "on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings" + }, } scheduler_events = { @@ -55,6 +65,5 @@ scheduler_events = { ] } -default_mail_footer = """
- Sent via ERPNext
""" - +default_mail_footer = """
+ Sent via ERPNext
""" diff --git a/erpnext/modules.txt b/erpnext/modules.txt index 68d095e1e1..243c2d859f 100644 --- a/erpnext/modules.txt +++ b/erpnext/modules.txt @@ -9,3 +9,4 @@ Stock Support Utilities Contacts +Shopping Cart diff --git a/erpnext/patches/v4_2/party_model.py b/erpnext/patches/v4_2/party_model.py index e1fa982b1b..287153131c 100644 --- a/erpnext/patches/v4_2/party_model.py +++ b/erpnext/patches/v4_2/party_model.py @@ -74,6 +74,9 @@ def set_party_in_jv_and_gl_entry(receivable_payable_accounts): for d in accounts: account_map.setdefault(d.name, d) + if not account_map: + return + for dt in ["Journal Voucher Detail", "GL Entry"]: records = frappe.db.sql("""select name, account from `tab%s` where account in (%s)""" % (dt, ", ".join(['%s']*len(account_map))), tuple(account_map.keys())) diff --git a/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py b/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py index f569695234..e4bf9a9b23 100644 --- a/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py +++ b/erpnext/patches/v5_0/update_frozen_accounts_permission_role.py @@ -7,6 +7,6 @@ def execute(): account_settings = frappe.get_doc("Accounts Settings") if not account_settings.frozen_accounts_modifier and account_settings.bde_auth_role: - account_settings.frozen_accounts_modifier = account_settings.bde_auth_role + frappe.db.set_value("Account Settings", None, + "frozen_accounts_modifier", account_settings.bde_auth_role) - account_settings.save() diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 0998c53821..3f6dd12920 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -3,7 +3,8 @@ "public/css/erpnext.css" ], "js/erpnext-web.min.js": [ - "public/js/website_utils.js" + "public/js/website_utils.js", + "public/js/shopping_cart.js" ], "js/erpnext.min.js": [ "public/js/conf.js", @@ -11,5 +12,8 @@ "public/js/utils.js", "public/js/queries.js", "public/js/utils/party.js" + ], + "css/shopping-cart-web.css": [ + "public/css/shopping_cart.css" ] } diff --git a/erpnext/public/css/shopping_cart.css b/erpnext/public/css/shopping_cart.css new file mode 100644 index 0000000000..5e869720b5 --- /dev/null +++ b/erpnext/public/css/shopping_cart.css @@ -0,0 +1,11 @@ +.item-main-image { + max-width: 100%; + margin: auto; +} +.web-long-description { + font-size: 18px; + line-height: 200%; +} +.item-stock { + margin-bottom: 10px !important; +} diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js new file mode 100644 index 0000000000..0c718b0065 --- /dev/null +++ b/erpnext/public/js/shopping_cart.js @@ -0,0 +1,66 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +// shopping cart +frappe.provide("shopping_cart"); + +$(function() { + // update user + if(full_name) { + $('.navbar li[data-label="User"] a') + .html(' ' + full_name); + } + + // update login + shopping_cart.set_cart_count(); +}); + +$.extend(shopping_cart, { + update_cart: function(opts) { + if(!full_name) { + if(localStorage) { + localStorage.setItem("last_visited", window.location.pathname); + localStorage.setItem("pending_add_to_cart", opts.item_code); + } + window.location.href = "/login"; + } else { + return frappe.call({ + type: "POST", + method: "erpnext.shopping_cart.cart.update_cart", + args: { + item_code: opts.item_code, + qty: opts.qty, + with_doc: opts.with_doc || 0 + }, + btn: opts.btn, + callback: function(r) { + if(opts.callback) + opts.callback(r); + + shopping_cart.set_cart_count(); + } + }); + } + }, + + set_cart_count: function() { + var cart_count = getCookie("cart_count"); + var $cart = $("#website-post-login").find('[data-label="Cart"]'); + var $badge = $cart.find(".badge"); + var $cog = $("#website-post-login").find(".dropdown-toggle"); + var $cog_count = $cog.find(".cart-count"); + if(cart_count) { + if($badge.length === 0) { + var $badge = $('').prependTo($cart.find("a")); + } + $badge.html(cart_count); + if($cog_count.length === 0) { + var $cog_count = $('').insertAfter($cog.find(".icon-cog")); + } + $cog_count.html(cart_count); + } else { + $badge.remove(); + $cog_count.remove(); + } + } +}); diff --git a/erpnext/shopping_cart/__init__.py b/erpnext/shopping_cart/__init__.py new file mode 100644 index 0000000000..656918b188 --- /dev/null +++ b/erpnext/shopping_cart/__init__.py @@ -0,0 +1,126 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import get_fullname, flt +from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_shopping_cart_enabled, get_default_territory + +# TODO +# validate stock of each item in Website Warehouse or have a list of possible warehouses in Shopping Cart Settings + +def get_quotation(user=None): + if not user: + user = frappe.session.user + if user == "Guest": + raise frappe.PermissionError + + is_shopping_cart_enabled() + party = get_party(user) + values = { + "order_type": "Shopping Cart", + party.doctype.lower(): party.name, + "docstatus": 0, + "contact_email": user + } + + try: + quotation = frappe.get_doc("Quotation", values) + except frappe.DoesNotExistError: + quotation = frappe.new_doc("Quotation") + quotation.update(values) + if party.doctype == "Customer": + quotation.contact_person = frappe.db.get_value("Contact", {"customer": party.name, "email_id": user}) + quotation.insert(ignore_permissions=True) + + return quotation + +def set_item_in_cart(item_code, qty, user=None): + validate_item(item_code) + quotation = get_quotation(user=user) + qty = flt(qty) + quotation_item = quotation.get("quotation_details", {"item_code": item_code}) + + if qty==0: + if quotation_item: + # remove + quotation.get("quotation_details").remove(quotation_item[0]) + else: + # add or update + if quotation_item: + quotation_item[0].qty = qty + else: + quotation.append("quotation_details", { + "doctype": "Quotation Item", + "item_code": item_code, + "qty": qty + }) + + quotation.save(ignore_permissions=True) + return quotation + +def set_address_in_cart(address_fieldname, address, user=None): + quotation = get_quotation(user=user) + validate_address(quotation, address_fieldname, address) + + if quotation.get(address_fieldname) != address: + quotation.set(address_fieldname, address) + if address_fieldname=="customer_address": + quotation.set("address_display", None) + else: + quotation.set("shipping_address", None) + + quotation.save(ignore_permissions=True) + + return quotation + +def validate_item(item_code): + item = frappe.db.get_value("Item", item_code, ["item_name", "show_in_website"], as_dict=True) + if not item.show_in_website: + frappe.throw(_("{0} cannot be purchased using Shopping Cart").format(item.item_name)) + +def validate_address(quotation, address_fieldname, address): + party = get_party(quotation.contact_email) + address_doc = frappe.get_doc(address) + if address_doc.get(party.doctype.lower()) != party.name: + if address_fieldname=="customer_address": + frappe.throw(_("Invalid Billing Address")) + else: + frappe.throw(_("Invalid Shipping Address")) + +def get_party(user): + def _get_party(user): + customer = frappe.db.get_value("Contact", {"email_id": user}, "customer") + if customer: + return frappe.get_doc("Customer", customer) + + lead = frappe.db.get_value("Lead", {"email_id": user}) + if lead: + return frappe.get_doc("Lead", lead) + + # create a lead + lead = frappe.new_doc("Lead") + lead.update({ + "email_id": user, + "lead_name": get_fullname(user), + "territory": guess_territory() + }) + lead.insert(ignore_permissions=True) + + return lead + + if not getattr(frappe.local, "shopping_cart_party", None): + frappe.local.shopping_cart_party = {} + + if not frappe.local.shopping_cart_party.get(user): + frappe.local.shopping_cart_party[user] = _get_party(user) + + return frappe.local.shopping_cart_party[user] + +def guess_territory(): + territory = None + if frappe.session.get("session_country"): + territory = frappe.db.get_value("Territory", frappe.session.get("session_country")) + + return territory or get_default_territory() diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py new file mode 100644 index 0000000000..e39a54c070 --- /dev/null +++ b/erpnext/shopping_cart/cart.py @@ -0,0 +1,434 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import throw, _ +import frappe.defaults +from frappe.utils import flt, get_fullname, fmt_money, cstr +from erpnext.utilities.doctype.address.address import get_address_display +from frappe.utils.nestedset import get_root_of + +class WebsitePriceListMissingError(frappe.ValidationError): pass + +def set_cart_count(quotation=None): + if not quotation: + quotation = _get_cart_quotation() + cart_count = cstr(len(quotation.get("quotation_details"))) + frappe.local.cookie_manager.set_cookie("cart_count", cart_count) + +@frappe.whitelist() +def get_cart_quotation(doc=None): + party = get_lead_or_customer() + + if not doc: + quotation = _get_cart_quotation(party) + doc = quotation + set_cart_count(quotation) + + return { + "doc": decorate_quotation_doc(doc), + "addresses": [{"name": address.name, "display": address.display} + for address in get_address_docs(party)], + "shipping_rules": get_applicable_shipping_rules(party) + } + +@frappe.whitelist() +def place_order(): + quotation = _get_cart_quotation() + quotation.company = frappe.db.get_value("Shopping Cart Settings", None, "company") + for fieldname in ["customer_address", "shipping_address_name"]: + if not quotation.get(fieldname): + throw(_("{0} is required").format(quotation.meta.get_label(fieldname))) + + quotation.ignore_permissions = True + quotation.submit() + + if quotation.lead: + # company used to create customer accounts + frappe.defaults.set_user_default("company", quotation.company) + + from erpnext.selling.doctype.quotation.quotation import _make_sales_order + sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True)) + for item in sales_order.get("sales_order_details"): + item.reserved_warehouse = frappe.db.get_value("Item", item.item_code, "website_warehouse") or None + + sales_order.ignore_permissions = True + sales_order.insert() + sales_order.submit() + frappe.local.cookie_manager.delete_cookie("cart_count") + + return sales_order.name + +@frappe.whitelist() +def update_cart(item_code, qty, with_doc): + quotation = _get_cart_quotation() + + qty = flt(qty) + if qty == 0: + quotation.set("quotation_details", quotation.get("quotation_details", {"item_code": ["!=", item_code]})) + if not quotation.get("quotation_details") and \ + not quotation.get("__islocal"): + quotation.__delete = True + + else: + quotation_items = quotation.get("quotation_details", {"item_code": item_code}) + if not quotation_items: + quotation.append("quotation_details", { + "doctype": "Quotation Item", + "item_code": item_code, + "qty": qty + }) + else: + quotation_items[0].qty = qty + + apply_cart_settings(quotation=quotation) + + if hasattr(quotation, "__delete"): + frappe.delete_doc("Quotation", quotation.name, ignore_permissions=True) + quotation = _get_cart_quotation() + else: + quotation.ignore_permissions = True + quotation.save() + + set_cart_count(quotation) + + if with_doc: + return get_cart_quotation(quotation) + else: + return quotation.name + +@frappe.whitelist() +def update_cart_address(address_fieldname, address_name): + quotation = _get_cart_quotation() + address_display = get_address_display(frappe.get_doc("Address", address_name).as_dict()) + + if address_fieldname == "shipping_address_name": + quotation.shipping_address_name = address_name + quotation.shipping_address = address_display + + if not quotation.customer_address: + address_fieldname == "customer_address" + + if address_fieldname == "customer_address": + quotation.customer_address = address_name + quotation.address_display = address_display + + + apply_cart_settings(quotation=quotation) + + quotation.ignore_permissions = True + quotation.save() + + return get_cart_quotation(quotation) + +def guess_territory(): + territory = None + geoip_country = frappe.session.get("session_country") + if geoip_country: + territory = frappe.db.get_value("Territory", geoip_country) + + return territory or \ + frappe.db.get_value("Shopping Cart Settings", None, "territory") or \ + get_root_of("Territory") + +def decorate_quotation_doc(quotation_doc): + doc = frappe._dict(quotation_doc.as_dict()) + for d in doc.get("quotation_details", []): + d.update(frappe.db.get_value("Item", d["item_code"], + ["website_image", "description", "page_name"], as_dict=True)) + d["formatted_rate"] = fmt_money(d.get("rate"), currency=doc.currency) + d["formatted_amount"] = fmt_money(d.get("amount"), currency=doc.currency) + + for d in doc.get("other_charges", []): + d["formatted_tax_amount"] = fmt_money(flt(d.get("tax_amount")) / doc.conversion_rate, + currency=doc.currency) + + doc.formatted_grand_total_export = fmt_money(doc.grand_total_export, + currency=doc.currency) + + return doc + +def _get_cart_quotation(party=None): + if not party: + party = get_lead_or_customer() + + quotation = frappe.db.get_value("Quotation", + {party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0}) + + if quotation: + qdoc = frappe.get_doc("Quotation", quotation) + else: + qdoc = frappe.get_doc({ + "doctype": "Quotation", + "naming_series": frappe.defaults.get_user_default("shopping_cart_quotation_series") or "QTN-CART-", + "quotation_to": party.doctype, + "company": frappe.db.get_value("Shopping Cart Settings", None, "company"), + "order_type": "Shopping Cart", + "status": "Draft", + "docstatus": 0, + "__islocal": 1, + (party.doctype.lower()): party.name + }) + + if party.doctype == "Customer": + qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user, + "customer": party.name}) + + qdoc.ignore_permissions = True + qdoc.run_method("set_missing_values") + apply_cart_settings(party, qdoc) + + return qdoc + +def update_party(fullname, company_name=None, mobile_no=None, phone=None): + party = get_lead_or_customer() + + if party.doctype == "Lead": + party.company_name = company_name + party.lead_name = fullname + party.mobile_no = mobile_no + party.phone = phone + else: + party.customer_name = company_name or fullname + party.customer_type == "Company" if company_name else "Individual" + + contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user, + "customer": party.name}) + contact = frappe.get_doc("Contact", contact_name) + contact.first_name = fullname + contact.last_name = None + contact.customer_name = party.customer_name + contact.mobile_no = mobile_no + contact.phone = phone + contact.ignore_permissions = True + contact.save() + + party_doc = frappe.get_doc(party.as_dict()) + party_doc.ignore_permissions = True + party_doc.save() + + qdoc = _get_cart_quotation(party) + if not qdoc.get("__islocal"): + qdoc.customer_name = company_name or fullname + qdoc.run_method("set_missing_lead_customer_details") + qdoc.ignore_permissions = True + qdoc.save() + +def apply_cart_settings(party=None, quotation=None): + if not party: + party = get_lead_or_customer() + if not quotation: + quotation = _get_cart_quotation(party) + + cart_settings = frappe.get_doc("Shopping Cart Settings") + + billing_territory = get_address_territory(quotation.customer_address) or \ + party.territory or get_root_of("Territory") + + set_price_list_and_rate(quotation, cart_settings, billing_territory) + + quotation.run_method("calculate_taxes_and_totals") + + set_taxes(quotation, cart_settings, billing_territory) + + _apply_shipping_rule(party, quotation, cart_settings) + +def set_price_list_and_rate(quotation, cart_settings, billing_territory): + """set price list based on billing territory""" + quotation.selling_price_list = cart_settings.get_price_list(billing_territory) + + # reset values + quotation.price_list_currency = quotation.currency = \ + quotation.plc_conversion_rate = quotation.conversion_rate = None + for item in quotation.get("quotation_details"): + item.price_list_rate = item.discount_percentage = item.rate = item.amount = None + + # refetch values + quotation.run_method("set_price_list_and_item_details") + + # set it in cookies for using in product page + frappe.local.cookie_manager.set_cookie("selling_price_list", quotation.selling_price_list) + +def set_taxes(quotation, cart_settings, billing_territory): + """set taxes based on billing territory""" + quotation.taxes_and_charges = cart_settings.get_tax_master(billing_territory) + + # clear table + quotation.set("other_charges", []) + + # append taxes + quotation.append_taxes_from_master("other_charges", "taxes_and_charges") + +def get_lead_or_customer(): + customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, "customer") + if customer: + return frappe.get_doc("Customer", customer) + + lead = frappe.db.get_value("Lead", {"email_id": frappe.session.user}) + if lead: + return frappe.get_doc("Lead", lead) + else: + lead_doc = frappe.get_doc({ + "doctype": "Lead", + "email_id": frappe.session.user, + "lead_name": get_fullname(frappe.session.user), + "territory": guess_territory(), + "status": "Open" # TODO: set something better??? + }) + + if frappe.session.user not in ("Guest", "Administrator"): + lead_doc.ignore_permissions = True + lead_doc.insert() + + return lead_doc + +def get_address_docs(party=None): + if not party: + party = get_lead_or_customer() + + address_docs = frappe.db.sql("""select * from `tabAddress` + where `%s`=%s order by name""" % (party.doctype.lower(), "%s"), party.name, + as_dict=True, update={"doctype": "Address"}) + + for address in address_docs: + address.display = get_address_display(address) + address.display = (address.display).replace("\n", "
\n") + + return address_docs + +@frappe.whitelist() +def apply_shipping_rule(shipping_rule): + quotation = _get_cart_quotation() + + quotation.shipping_rule = shipping_rule + + apply_cart_settings(quotation=quotation) + + quotation.ignore_permissions = True + quotation.save() + + return get_cart_quotation(quotation) + +def _apply_shipping_rule(party=None, quotation=None, cart_settings=None): + shipping_rules = get_shipping_rules(party, quotation, cart_settings) + + if not shipping_rules: + return + + elif quotation.shipping_rule not in shipping_rules: + quotation.shipping_rule = shipping_rules[0] + + quotation.run_method("apply_shipping_rule") + quotation.run_method("calculate_taxes_and_totals") + +def get_applicable_shipping_rules(party=None, quotation=None): + shipping_rules = get_shipping_rules(party, quotation) + + if shipping_rules: + rule_label_map = frappe.db.get_values("Shipping Rule", shipping_rules, "label") + # we need this in sorted order as per the position of the rule in the settings page + return [[rule, rule_label_map.get(rule)] for rule in shipping_rules] + +def get_shipping_rules(party=None, quotation=None, cart_settings=None): + if not party: + party = get_lead_or_customer() + if not quotation: + quotation = _get_cart_quotation() + if not cart_settings: + cart_settings = frappe.get_doc("Shopping Cart Settings") + + # set shipping rule based on shipping territory + shipping_territory = get_address_territory(quotation.shipping_address_name) or \ + party.territory + + shipping_rules = cart_settings.get_shipping_rules(shipping_territory) + + return shipping_rules + +def get_address_territory(address_name): + """Tries to match city, state and country of address to existing territory""" + territory = None + + if address_name: + address_fields = frappe.db.get_value("Address", address_name, + ["city", "state", "country"]) + for value in address_fields: + territory = frappe.db.get_value("Territory", value) + if territory: + break + + return territory + +import unittest +test_dependencies = ["Item", "Price List", "Contact", "Shopping Cart Settings"] + +class TestCart(unittest.TestCase): + def tearDown(self): + return + + cart_settings = frappe.get_doc("Shopping Cart Settings") + cart_settings.ignore_permissions = True + cart_settings.enabled = 0 + cart_settings.save() + + def enable_shopping_cart(self): + return + if not frappe.db.get_value("Shopping Cart Settings", None, "enabled"): + cart_settings = frappe.get_doc("Shopping Cart Settings") + cart_settings.ignore_permissions = True + cart_settings.enabled = 1 + cart_settings.save() + + def test_get_lead_or_customer(self): + frappe.session.user = "test@example.com" + party1 = get_lead_or_customer() + party2 = get_lead_or_customer() + self.assertEquals(party1.name, party2.name) + self.assertEquals(party1.doctype, "Lead") + + frappe.session.user = "test_contact_customer@example.com" + party = get_lead_or_customer() + self.assertEquals(party.name, "_Test Customer") + + def test_add_to_cart(self): + self.enable_shopping_cart() + frappe.session.user = "test@example.com" + + update_cart("_Test Item", 1) + + quotation = _get_cart_quotation() + quotation_items = quotation.get("quotation_details", {"item_code": "_Test Item"}) + self.assertTrue(quotation_items) + self.assertEquals(quotation_items[0].qty, 1) + + return quotation + + def test_update_cart(self): + self.test_add_to_cart() + + update_cart("_Test Item", 5) + + quotation = _get_cart_quotation() + quotation_items = quotation.get("quotation_details", {"item_code": "_Test Item"}) + self.assertTrue(quotation_items) + self.assertEquals(quotation_items[0].qty, 5) + + return quotation + + def test_remove_from_cart(self): + quotation0 = self.test_add_to_cart() + + update_cart("_Test Item", 0) + + quotation = _get_cart_quotation() + self.assertEquals(quotation0.name, quotation.name) + + quotation_items = quotation.get("quotation_details", {"item_code": "_Test Item"}) + self.assertEquals(quotation_items, []) + + def test_place_order(self): + quotation = self.test_update_cart() + sales_order_name = place_order() + sales_order = frappe.get_doc("Sales Order", sales_order_name) + self.assertEquals(sales_order.getone({"item_code": "_Test Item"}).prevdoc_docname, quotation.name) diff --git a/erpnext/shopping_cart/doctype/__init__.py b/erpnext/shopping_cart/doctype/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py b/erpnext/shopping_cart/doctype/shopping_cart_price_list/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json new file mode 100644 index 0000000000..12b6290fb1 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.json @@ -0,0 +1,23 @@ +{ + "creation": "2013-06-20 16:00:18.000000", + "docstatus": 0, + "doctype": "DocType", + "fields": [ + { + "fieldname": "selling_price_list", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Price List", + "options": "Price List", + "permlevel": 0, + "reqd": 1 + } + ], + "idx": 1, + "istable": 1, + "modified": "2013-12-20 19:30:47.000000", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Shopping Cart Price List", + "owner": "Administrator" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py new file mode 100644 index 0000000000..cd925764d4 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_price_list/shopping_cart_price_list.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +from frappe.model.document import Document + +class ShoppingCartPriceList(Document): + pass \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/__init__.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js new file mode 100644 index 0000000000..5ea8e3ed27 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.js @@ -0,0 +1,10 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +$.extend(cur_frm.cscript, { + onload: function() { + if(cur_frm.doc.__onload && cur_frm.doc.__onload.quotation_series) { + cur_frm.fields_dict.quotation_series.df.options = cur_frm.doc.__onload.quotation_series; + } + } +}); diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json new file mode 100644 index 0000000000..73409302c1 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json @@ -0,0 +1,115 @@ +{ + "creation": "2013-06-19 15:57:32", + "description": "Default settings for Shopping Cart", + "docstatus": 0, + "doctype": "DocType", + "fields": [ + { + "fieldname": "enabled", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Enable Shopping Cart", + "permlevel": 0 + }, + { + "fieldname": "section_break_2", + "fieldtype": "Section Break", + "permlevel": 0 + }, + { + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "permlevel": 0, + "reqd": 1 + }, + { + "description": "Add / Edit", + "fieldname": "default_territory", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "in_list_view": 1, + "label": "Default Territory", + "options": "Territory", + "permlevel": 0, + "reqd": 1 + }, + { + "fieldname": "column_break_4", + "fieldtype": "Column Break", + "permlevel": 0 + }, + { + "description": "Add / Edit", + "fieldname": "default_customer_group", + "fieldtype": "Link", + "ignore_user_permissions": 1, + "label": "Default Customer Group", + "options": "Customer Group", + "permlevel": 0, + "reqd": 1 + }, + { + "fieldname": "quotation_series", + "fieldtype": "Select", + "label": "Quotation Series", + "permlevel": 0, + "reqd": 1 + }, + { + "fieldname": "section_break_6", + "fieldtype": "Section Break", + "permlevel": 0 + }, + { + "fieldname": "price_lists", + "fieldtype": "Table", + "label": "Shopping Cart Price Lists", + "options": "Shopping Cart Price List", + "permlevel": 0, + "reqd": 0 + }, + { + "fieldname": "shipping_rules", + "fieldtype": "Table", + "label": "Shopping Cart Shipping Rules", + "options": "Shopping Cart Shipping Rule", + "permlevel": 0, + "reqd": 0 + }, + { + "fieldname": "column_break_10", + "fieldtype": "Column Break", + "permlevel": 0 + }, + { + "fieldname": "sales_taxes_and_charges_masters", + "fieldtype": "Table", + "label": "Shopping Cart Taxes and Charges Masters", + "options": "Shopping Cart Taxes and Charges Master", + "permlevel": 0, + "reqd": 0 + } + ], + "icon": "icon-shopping-cart", + "idx": 1, + "issingle": 1, + "modified": "2014-05-26 03:05:53.747800", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Shopping Cart Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "role": "Website Manager", + "write": 1 + } + ] +} \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py new file mode 100644 index 0000000000..48e31f6557 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.py @@ -0,0 +1,215 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _, msgprint +from frappe.utils import comma_and +from frappe.model.document import Document +from frappe.utils.nestedset import get_ancestors_of +from erpnext.utilities.doctype.address.address import get_territory_from_address + +class ShoppingCartSetupError(frappe.ValidationError): pass + +class ShoppingCartSettings(Document): + def onload(self): + self.get("__onload").quotation_series = frappe.get_meta("Quotation").get_options("naming_series") + + def validate(self): + if self.enabled: + self.validate_price_lists() + self.validate_tax_masters() + self.validate_exchange_rates_exist() + + def on_update(self): + frappe.db.set_default("shopping_cart_enabled", self.get("enabled") or 0) + frappe.db.set_default("shopping_cart_quotation_series", self.get("quotation_series")) + + def validate_overlapping_territories(self, parentfield, fieldname): + # for displaying message + doctype = self.meta.get_field(parentfield).options + + # specify atleast one entry in the table + self.validate_table_has_rows(parentfield, raise_exception=ShoppingCartSetupError) + + territory_name_map = self.get_territory_name_map(parentfield, fieldname) + for territory, names in territory_name_map.items(): + if len(names) > 1: + frappe.throw(_("{0} {1} has a common territory {2}").format(_(doctype), comma_and(names), territory), ShoppingCartSetupError) + + return territory_name_map + + def validate_price_lists(self): + territory_name_map = self.validate_overlapping_territories("price_lists", "selling_price_list") + + # validate that a Shopping Cart Price List exists for the default territory as a catch all! + price_list_for_default_territory = self.get_name_from_territory(self.default_territory, "price_lists", + "selling_price_list") + + if not price_list_for_default_territory: + msgprint(_("Please specify a Price List which is valid for Territory") + + ": " + self.default_territory, raise_exception=ShoppingCartSetupError) + + def validate_tax_masters(self): + self.validate_overlapping_territories("sales_taxes_and_charges_masters", + "sales_taxes_and_charges_master") + + def get_territory_name_map(self, parentfield, fieldname): + territory_name_map = {} + + # entries in table + names = [doc.get(fieldname) for doc in self.get(parentfield)] + + if names: + # for condition in territory check + parenttype = frappe.get_meta(self.meta.get_options(parentfield)).get_options(fieldname) + + # to validate territory overlap + # make a map of territory: [list of names] + # if list against each territory has more than one element, raise exception + territory_name = frappe.db.sql("""select `territory`, `parent` + from `tabApplicable Territory` + where `parenttype`=%s and `parent` in (%s)""" % + ("%s", ", ".join(["%s"]*len(names))), tuple([parenttype] + names)) + + for territory, name in territory_name: + territory_name_map.setdefault(territory, []).append(name) + + if len(territory_name_map[territory]) > 1: + territory_name_map[territory].sort(key=lambda val: names.index(val)) + + return territory_name_map + + def validate_exchange_rates_exist(self): + """check if exchange rates exist for all Price List currencies (to company's currency)""" + company_currency = frappe.db.get_value("Company", self.company, "default_currency") + if not company_currency: + msgprint(_("Please specify currency in Company") + ": " + self.company, + raise_exception=ShoppingCartSetupError) + + price_list_currency_map = frappe.db.get_values("Price List", + [d.selling_price_list for d in self.get("price_lists")], + "currency") + + # check if all price lists have a currency + for price_list, currency in price_list_currency_map.items(): + if not currency: + frappe.throw(_("Currency is required for Price List {0}").format(price_list)) + + expected_to_exist = [currency + "-" + company_currency + for currency in price_list_currency_map.values() + if currency != company_currency] + + if expected_to_exist: + exists = frappe.db.sql_list("""select name from `tabCurrency Exchange` + where name in (%s)""" % (", ".join(["%s"]*len(expected_to_exist)),), + tuple(expected_to_exist)) + + missing = list(set(expected_to_exist).difference(exists)) + + if missing: + msgprint(_("Missing Currency Exchange Rates for {0}").format(comma_and(missing)), + raise_exception=ShoppingCartSetupError) + + def get_name_from_territory(self, territory, parentfield, fieldname): + name = None + territory_name_map = self.get_territory_name_map(parentfield, fieldname) + + if territory_name_map.get(territory): + name = territory_name_map.get(territory) + else: + territory_ancestry = self.get_territory_ancestry(territory) + for ancestor in territory_ancestry: + if territory_name_map.get(ancestor): + name = territory_name_map.get(ancestor) + break + + return name + + def get_price_list(self, billing_territory): + price_list = self.get_name_from_territory(billing_territory, "price_lists", "selling_price_list") + return price_list and price_list[0] or None + + def get_tax_master(self, billing_territory): + tax_master = self.get_name_from_territory(billing_territory, "sales_taxes_and_charges_masters", + "sales_taxes_and_charges_master") + return tax_master and tax_master[0] or None + + def get_shipping_rules(self, shipping_territory): + return self.get_name_from_territory(shipping_territory, "shipping_rules", "shipping_rule") + + def get_territory_ancestry(self, territory): + if not hasattr(self, "_territory_ancestry"): + self._territory_ancestry = {} + + if not self._territory_ancestry.get(territory): + self._territory_ancestry[territory] = get_ancestors_of("Territory", territory) + + return self._territory_ancestry[territory] + +def validate_cart_settings(doc, method): + frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings").run_method("validate") + +def get_shopping_cart_settings(): + if not getattr(frappe.local, "shopping_cart_settings", None): + frappe.local.shopping_cart_settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings") + + return frappe.local.shopping_cart_settings + +def get_default_territory(): + return get_shopping_cart_settings().default_territory + +def is_shopping_cart_enabled(): + if not get_shopping_cart_settings().enabled: + frappe.throw(_("You need to enable Shopping Cart"), ShoppingCartSetupError) + +def apply_shopping_cart_settings(quotation, method): + """Called via a validate hook on Quotation""" + from erpnext.shopping_cart import get_party + if quotation.order_type != "Shopping Cart": + return + + quotation.billing_territory = (get_territory_from_address(quotation.customer_address) + or get_party(quotation.contact_email).territory or get_default_territory()) + quotation.shipping_territory = (get_territory_from_address(quotation.shipping_address_name) + or get_party(quotation.contact_email).territory or get_default_territory()) + + set_price_list(quotation) + set_taxes_and_charges(quotation) + quotation.calculate_taxes_and_totals() + set_shipping_rule(quotation) + +def set_price_list(quotation): + previous_selling_price_list = quotation.selling_price_list + quotation.selling_price_list = get_shopping_cart_settings().get_price_list(quotation.billing_territory) + + if not quotation.selling_price_list: + quotation.selling_price_list = get_shopping_cart_settings().get_price_list(get_default_territory()) + + if previous_selling_price_list != quotation.selling_price_list: + quotation.price_list_currency = quotation.currency = quotation.plc_conversion_rate = quotation.conversion_rate = None + for d in quotation.get("quotation_details"): + d.price_list_rate = d.discount_percentage = d.rate = d.amount = None + + quotation.set_price_list_and_item_details() + +def set_taxes_and_charges(quotation): + previous_taxes_and_charges = quotation.taxes_and_charges + quotation.taxes_and_charges = get_shopping_cart_settings().get_tax_master(quotation.billing_territory) + + if previous_taxes_and_charges != quotation.taxes_and_charges: + quotation.set_other_charges() + +def set_shipping_rule(quotation): + shipping_rules = get_shopping_cart_settings().get_shipping_rules(quotation.shipping_territory) + if not shipping_rules: + quotation.remove_shipping_charge() + return + + if quotation.shipping_rule not in shipping_rules: + quotation.remove_shipping_charge() + quotation.shipping_rule = shipping_rules[0] + + quotation.apply_shipping_rule() diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py new file mode 100644 index 0000000000..a45aaa4cd8 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/test_shopping_cart_settings.py @@ -0,0 +1,79 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +import unittest +from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import ShoppingCartSetupError + +class TestShoppingCartSettings(unittest.TestCase): + def setUp(self): + frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """) + frappe.db.sql("""delete from `tabShopping Cart Price List`""") + frappe.db.sql("""delete from `tabShopping Cart Taxes and Charges Master`""") + frappe.db.sql("""delete from `tabShopping Cart Shipping Rule`""") + + def get_cart_settings(self): + return frappe.get_doc({"doctype": "Shopping Cart Settings", + "company": "_Test Company"}) + + def test_price_list_territory_overlap(self): + cart_settings = self.get_cart_settings() + + def _add_price_list(price_list): + cart_settings.append("price_lists", { + "doctype": "Shopping Cart Price List", + "selling_price_list": price_list + }) + + for price_list in ("_Test Price List Rest of the World", "_Test Price List India", + "_Test Price List"): + _add_price_list(price_list) + + controller = cart_settings + controller.validate_overlapping_territories("price_lists", "selling_price_list") + + _add_price_list("_Test Price List 2") + + controller = cart_settings + self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories, + "price_lists", "selling_price_list") + + return cart_settings + + def test_taxes_territory_overlap(self): + cart_settings = self.get_cart_settings() + + def _add_tax_master(tax_master): + cart_settings.append("sales_taxes_and_charges_masters", { + "doctype": "Shopping Cart Taxes and Charges Master", + "sales_taxes_and_charges_master": tax_master + }) + + for tax_master in ("_Test Sales Taxes and Charges Master", "_Test India Tax Master"): + _add_tax_master(tax_master) + + controller = cart_settings + controller.validate_overlapping_territories("sales_taxes_and_charges_masters", + "sales_taxes_and_charges_master") + + _add_tax_master("_Test Sales Taxes and Charges Master - Rest of the World") + + controller = cart_settings + self.assertRaises(ShoppingCartSetupError, controller.validate_overlapping_territories, + "sales_taxes_and_charges_masters", "sales_taxes_and_charges_master") + + def test_exchange_rate_exists(self): + frappe.db.sql("""delete from `tabCurrency Exchange`""") + + cart_settings = self.test_price_list_territory_overlap() + controller = cart_settings + self.assertRaises(ShoppingCartSetupError, controller.validate_exchange_rates_exist) + + from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \ + currency_exchange_records + frappe.get_doc(currency_exchange_records[0]).insert() + controller.validate_exchange_rates_exist() + diff --git a/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/__init__.py b/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.json b/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.json new file mode 100644 index 0000000000..5ff55f9744 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.json @@ -0,0 +1,23 @@ +{ + "creation": "2013-07-03 13:15:34.000000", + "docstatus": 0, + "doctype": "DocType", + "fields": [ + { + "fieldname": "shipping_rule", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Shipping Rule", + "options": "Shipping Rule", + "permlevel": 0, + "reqd": 1 + } + ], + "idx": 1, + "istable": 1, + "modified": "2013-12-20 19:30:47.000000", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Shopping Cart Shipping Rule", + "owner": "Administrator" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.py b/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.py new file mode 100644 index 0000000000..17aa9647c2 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_shipping_rule/shopping_cart_shipping_rule.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +from frappe.model.document import Document + +class ShoppingCartShippingRule(Document): + pass \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/__init__.py b/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.json b/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.json new file mode 100644 index 0000000000..bfe31e5a9d --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.json @@ -0,0 +1,23 @@ +{ + "creation": "2013-06-20 16:57:03.000000", + "docstatus": 0, + "doctype": "DocType", + "fields": [ + { + "fieldname": "sales_taxes_and_charges_master", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Tax Master", + "options": "Sales Taxes and Charges Master", + "permlevel": 0, + "reqd": 1 + } + ], + "idx": 1, + "istable": 1, + "modified": "2013-12-20 19:30:47.000000", + "modified_by": "Administrator", + "module": "Shopping Cart", + "name": "Shopping Cart Taxes and Charges Master", + "owner": "Administrator" +} \ No newline at end of file diff --git a/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.py b/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.py new file mode 100644 index 0000000000..e0d0f9f759 --- /dev/null +++ b/erpnext/shopping_cart/doctype/shopping_cart_taxes_and_charges_master/shopping_cart_taxes_and_charges_master.py @@ -0,0 +1,12 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +from frappe.model.document import Document + +class ShoppingCartTaxesandChargesMaster(Document): + pass diff --git a/erpnext/shopping_cart/product.py b/erpnext/shopping_cart/product.py new file mode 100644 index 0000000000..5a86d1d07a --- /dev/null +++ b/erpnext/shopping_cart/product.py @@ -0,0 +1,54 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe +from frappe.utils import cint, fmt_money, cstr +from erpnext.shopping_cart.cart import _get_cart_quotation +from urllib import unquote + +@frappe.whitelist(allow_guest=True) +def get_product_info(item_code): + """get product price / stock info""" + if not cint(frappe.db.get_default("shopping_cart_enabled")): + return {} + + cart_quotation = _get_cart_quotation() + + price_list = cstr(unquote(frappe.local.request.cookies.get("selling_price_list"))) + + warehouse = frappe.db.get_value("Item", item_code, "website_warehouse") + if warehouse: + in_stock = frappe.db.sql("""select actual_qty from tabBin where + item_code=%s and warehouse=%s""", (item_code, warehouse)) + if in_stock: + in_stock = in_stock[0][0] > 0 and 1 or 0 + else: + in_stock = -1 + + price = price_list and frappe.db.sql("""select price_list_rate, currency from + `tabItem Price` where item_code=%s and price_list=%s""", + (item_code, price_list), as_dict=1) or [] + + price = price and price[0] or None + qty = 0 + + if price: + price["formatted_price"] = fmt_money(price["price_list_rate"], currency=price["currency"]) + + price["currency"] = not cint(frappe.db.get_default("hide_currency_symbol")) \ + and (frappe.db.get_value("Currency", price.currency, "symbol") or price.currency) \ + or "" + + if frappe.session.user != "Guest": + item = cart_quotation.get({"item_code": item_code}) + if item: + qty = item[0].qty + + return { + "price": price, + "stock": in_stock, + "uom": frappe.db.get_value("Item", item_code, "stock_uom"), + "qty": qty + } diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py new file mode 100644 index 0000000000..f77522a429 --- /dev/null +++ b/erpnext/shopping_cart/test_shopping_cart.py @@ -0,0 +1,230 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import unittest +import frappe +from erpnext.shopping_cart import get_quotation, set_item_in_cart + +class TestShoppingCart(unittest.TestCase): + """ + Note: + Shopping Cart == Quotation + """ + def setUp(self): + frappe.set_user("Administrator") + self.enable_shopping_cart() + + def tearDown(self): + frappe.set_user("Administrator") + self.disable_shopping_cart() + + def test_get_cart_new_user(self): + self.login_as_new_user() + + # test if lead is created and quotation with new lead is fetched + quotation = get_quotation() + self.assertEquals(quotation.quotation_to, "Lead") + self.assertEquals(frappe.db.get_value("Lead", quotation.lead, "email_id"), "test_cart_user@example.com") + self.assertEquals(quotation.customer, None) + self.assertEquals(quotation.contact_email, frappe.session.user) + + return quotation + + def test_get_cart_lead(self): + self.login_as_lead() + + # test if quotation with lead is fetched + quotation = get_quotation() + self.assertEquals(quotation.quotation_to, "Lead") + self.assertEquals(quotation.lead, frappe.db.get_value("Lead", {"email_id": "test_cart_lead@example.com"})) + self.assertEquals(quotation.customer, None) + self.assertEquals(quotation.contact_email, frappe.session.user) + + return quotation + + def test_get_cart_customer(self): + self.login_as_customer() + + # test if quotation with customer is fetched + quotation = get_quotation() + self.assertEquals(quotation.quotation_to, "Customer") + self.assertEquals(quotation.customer, "_Test Customer") + self.assertEquals(quotation.lead, None) + self.assertEquals(quotation.contact_email, frappe.session.user) + + return quotation + + def test_add_to_cart(self): + self.login_as_lead() + + # add first item + set_item_in_cart("_Test Item", 1) + quotation = self.test_get_cart_lead() + self.assertEquals(quotation.get("quotation_details")[0].item_code, "_Test Item") + self.assertEquals(quotation.get("quotation_details")[0].qty, 1) + self.assertEquals(quotation.get("quotation_details")[0].amount, 10) + + # add second item + set_item_in_cart("_Test Item 2", 1) + quotation = self.test_get_cart_lead() + self.assertEquals(quotation.get("quotation_details")[1].item_code, "_Test Item 2") + self.assertEquals(quotation.get("quotation_details")[1].qty, 1) + self.assertEquals(quotation.get("quotation_details")[1].amount, 20) + + self.assertEquals(len(quotation.get("quotation_details")), 2) + + def test_update_cart(self): + # first, add to cart + self.test_add_to_cart() + + # update first item + set_item_in_cart("_Test Item", 5) + quotation = self.test_get_cart_lead() + self.assertEquals(quotation.get("quotation_details")[0].item_code, "_Test Item") + self.assertEquals(quotation.get("quotation_details")[0].qty, 5) + self.assertEquals(quotation.get("quotation_details")[0].amount, 50) + self.assertEquals(quotation.net_total, 70) + self.assertEquals(len(quotation.get("quotation_details")), 2) + + def test_remove_from_cart(self): + # first, add to cart + self.test_add_to_cart() + + # remove first item + set_item_in_cart("_Test Item", 0) + quotation = self.test_get_cart_lead() + self.assertEquals(quotation.get("quotation_details")[0].item_code, "_Test Item 2") + self.assertEquals(quotation.get("quotation_details")[0].qty, 1) + self.assertEquals(quotation.get("quotation_details")[0].amount, 20) + self.assertEquals(quotation.net_total, 20) + self.assertEquals(len(quotation.get("quotation_details")), 1) + + # remove second item + set_item_in_cart("_Test Item 2", 0) + quotation = self.test_get_cart_lead() + self.assertEquals(quotation.net_total, 0) + self.assertEquals(len(quotation.get("quotation_details")), 0) + + def test_set_billing_address(self): + return + + # first, add to cart + self.test_add_to_cart() + + quotation = self.test_get_cart_lead() + default_address = frappe.get_doc("Address", {"lead": quotation.lead, "is_primary_address": 1}) + self.assertEquals("customer_address", default_address.name) + + def test_set_shipping_address(self): + # first, add to cart + self.test_add_to_cart() + + + + def test_shipping_rule(self): + self.test_set_shipping_address() + + # check if shipping rule changed + pass + + def test_price_list(self): + self.test_set_billing_address() + + # check if price changed + pass + + def test_place_order(self): + pass + + # helper functions + def enable_shopping_cart(self): + settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings") + + if settings.default_territory == "_Test Territory Rest Of The World": + settings.enabled = 1 + else: + settings.update({ + "enabled": 1, + "company": "_Test Company", + "default_territory": "_Test Territory Rest Of The World", + "default_customer_group": "_Test Customer Group", + "quotation_series": "_T-Quotation-" + }) + settings.set("price_lists", [ + # price lists + {"doctype": "Shopping Cart Price List", "parentfield": "price_lists", + "selling_price_list": "_Test Price List India"}, + {"doctype": "Shopping Cart Price List", "parentfield": "price_lists", + "selling_price_list": "_Test Price List Rest of the World"} + ]) + settings.set("sales_taxes_and_charges_masters", [ + # tax masters + {"doctype": "Shopping Cart Taxes and Charges Master", "parentfield": "sales_taxes_and_charges_masters", + "sales_taxes_and_charges_master": "_Test India Tax Master"}, + {"doctype": "Shopping Cart Taxes and Charges Master", "parentfield": "sales_taxes_and_charges_masters", + "sales_taxes_and_charges_master": "_Test Sales Taxes and Charges Master - Rest of the World"}, + ]) + settings.set("shipping_rules", {"doctype": "Shopping Cart Shipping Rule", "parentfield": "shipping_rules", + "shipping_rule": "_Test Shipping Rule - India"}) + + settings.save() + frappe.local.shopping_cart_settings = None + + def disable_shopping_cart(self): + settings = frappe.get_doc("Shopping Cart Settings", "Shopping Cart Settings") + settings.enabled = 0 + settings.save() + frappe.local.shopping_cart_settings = None + + def login_as_new_user(self): + frappe.set_user("test_cart_user@example.com") + + def login_as_lead(self): + self.create_lead() + frappe.set_user("test_cart_lead@example.com") + + def login_as_customer(self): + frappe.set_user("test_contact_customer@example.com") + + def create_lead(self): + if frappe.db.get_value("Lead", {"email_id": "test_cart_lead@example.com"}): + return + + lead = frappe.get_doc({ + "doctype": "Lead", + "email_id": "test_cart_lead@example.com", + "lead_name": "_Test Website Lead", + "status": "Open", + "territory": "_Test Territory Rest Of The World" + }) + lead.insert(ignore_permissions=True) + + frappe.get_doc({ + "doctype": "Address", + "address_line1": "_Test Address Line 1", + "address_title": "_Test Cart Lead Address", + "address_type": "Office", + "city": "_Test City", + "country": "United States", + "lead": lead.name, + "lead_name": "_Test Website Lead", + "is_primary_address": 1, + "phone": "+91 0000000000" + }).insert(ignore_permissions=True) + + frappe.get_doc({ + "doctype": "Address", + "address_line1": "_Test Address Line 1", + "address_title": "_Test Cart Lead Address", + "address_type": "Home", + "city": "_Test City", + "country": "India", + "lead": lead.name, + "lead_name": "_Test Website Lead", + "phone": "+91 0000000000" + }).insert(ignore_permissions=True) + + +test_dependencies = ["Sales Taxes and Charges Master", "Price List", "Item Price", "Shipping Rule", "Currency Exchange", + "Customer Group", "Lead", "Customer", "Contact", "Address", "Item"] diff --git a/erpnext/shopping_cart/utils.py b/erpnext/shopping_cart/utils.py new file mode 100644 index 0000000000..ee011a4e11 --- /dev/null +++ b/erpnext/shopping_cart/utils.py @@ -0,0 +1,47 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe +import frappe.defaults +from frappe.utils import cint + +def show_cart_count(): + if (frappe.db.get_default("shopping_cart_enabled") and + frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User"): + return True + + return False + +def set_cart_count(login_manager): + if show_cart_count(): + from .shopping_cart.cart import set_cart_count + set_cart_count() + +def clear_cart_count(login_manager): + if show_cart_count(): + frappe.local.cookie_manager.delete_cookie("cart_count") + +def update_website_context(context): + post_login = [] + cart_enabled = cint(frappe.db.get_default("shopping_cart_enabled")) + context["shopping_cart_enabled"] = cart_enabled + + if cart_enabled: + post_login += [ + {"label": "Cart", "url": "cart", "icon": "icon-shopping-cart", "class": "cart-count"}, + {"class": "divider"} + ] + + post_login += [ + {"label": "User", "url": "user", "icon": "icon-user"}, + {"label": "Addresses", "url": "addresses", "icon": "icon-map-marker"}, + {"label": "My Orders", "url": "orders", "icon": "icon-list"}, + {"label": "My Tickets", "url": "tickets", "icon": "icon-tags"}, + {"label": "Invoices", "url": "invoices", "icon": "icon-file-text"}, + {"label": "Shipments", "url": "shipments", "icon": "icon-truck"}, + {"class": "divider"} + ] + + context["post_login"] = post_login + context.get("post_login", []) diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js new file mode 100644 index 0000000000..90cfea59da --- /dev/null +++ b/erpnext/templates/includes/cart.js @@ -0,0 +1,297 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +// js inside blog page + +// shopping cart +frappe.provide("shopping_cart"); + +$.extend(shopping_cart, { + show_error: function(title, text) { + $("#cart-container").html('

' + title + '

' + text + '
'); + }, + + bind_events: function() { + // bind update button + $(document).on("click", ".item-update-cart button", function() { + var item_code = $(this).attr("data-item-code"); + shopping_cart.update_cart({ + item_code: item_code, + qty: $('input[data-item-code="'+item_code+'"]').val(), + with_doc: 1, + btn: this, + callback: function(r) { + if(!r.exc) { + shopping_cart.render(r.message); + var $button = $('button[data-item-code="'+item_code+'"]').addClass("btn-success"); + setTimeout(function() { $button.removeClass("btn-success"); }, 1000); + } + }, + }); + }); + + $("#cart-add-shipping-address").on("click", function() { + window.location.href = "address?address_fieldname=shipping_address_name"; + }); + + $("#cart-add-billing-address").on("click", function() { + window.location.href = "address?address_fieldname=customer_address"; + }); + + $(".btn-place-order").on("click", function() { + shopping_cart.place_order(this); + }); + }, + + render: function(out) { + var doc = out.doc; + var addresses = out.addresses; + + var $cart_items = $("#cart-items").empty(); + var $cart_taxes = $("#cart-taxes").empty(); + var $cart_totals = $("#cart-totals").empty(); + var $cart_billing_address = $("#cart-billing-address").empty(); + var $cart_shipping_address = $("#cart-shipping-address").empty(); + + var no_items = $.map(doc.quotation_details || [], + function(d) { return d.item_code || null;}).length===0; + if(no_items) { + shopping_cart.show_error("Empty :-(", frappe._("Go ahead and add something to your cart.")); + $("#cart-addresses").toggle(false); + return; + } + + var shipping_rule_added = false; + var taxes_exist = false; + var shipping_rule_labels = $.map(out.shipping_rules || [], function(rule) { return rule[1]; }); + + $.each(doc.quotation_details || [], function(i, d) { + shopping_cart.render_item_row($cart_items, d); + }); + + $.each(doc.other_charges || [], function(i, d) { + if(out.shipping_rules && out.shipping_rules.length && + shipping_rule_labels.indexOf(d.description)!==-1) { + shipping_rule_added = true; + shopping_cart.render_tax_row($cart_taxes, d, out.shipping_rules); + } else { + shopping_cart.render_tax_row($cart_taxes, d); + } + + taxes_exist = true; + }); + + if(out.shipping_rules && out.shipping_rules.length && !shipping_rule_added) { + shopping_cart.render_tax_row($cart_taxes, {description: "", formatted_tax_amount: ""}, + out.shipping_rules); + taxes_exist = true; + } + + if(taxes_exist) + $('
').appendTo($cart_taxes); + + shopping_cart.render_tax_row($cart_totals, { + description: "Total", + formatted_tax_amount: "" + doc.formatted_grand_total_export + "" + }); + + if(!(addresses && addresses.length)) { + $cart_shipping_address.html('
'+frappe._("Hey! Go ahead and add an address")+'
'); + } else { + shopping_cart.render_address($cart_shipping_address, addresses, doc.shipping_address_name); + shopping_cart.render_address($cart_billing_address, addresses, doc.customer_address); + } + }, + + render_item_row: function($cart_items, doc) { + doc.image_html = doc.website_image ? + '
' : + '{% include "templates/includes/product_missing_image.html" %}'; + + if(doc.description === doc.item_name) doc.description = ""; + + $(repl('
\ +
\ +
\ +
%(image_html)s
\ +
\ +

%(item_name)s

\ +

%(description)s

\ +
\ +
\ +
\ +
\ +
\ + \ +
\ + \ +
\ +
\ +

at %(formatted_rate)s

\ + = %(formatted_amount)s\ +
\ +

', doc)).appendTo($cart_items); + }, + + render_tax_row: function($cart_taxes, doc, shipping_rules) { + var shipping_selector; + if(shipping_rules) { + shipping_selector = ''; + } + + var $tax_row = $(repl('
\ +
\ +
\ +
' + + (shipping_selector || '

%(description)s

') + + '
\ +
\ +
\ +
\ + %(formatted_tax_amount)s

\ +
\ +
', doc)).appendTo($cart_taxes); + + if(shipping_selector) { + $tax_row.find('select option').each(function(i, opt) { + if($(opt).html() == doc.description) { + $(opt).attr("selected", "selected"); + } + }); + $tax_row.find('select').on("change", function() { + shopping_cart.apply_shipping_rule($(this).val(), this); + }); + } + }, + + apply_shipping_rule: function(rule, btn) { + return frappe.call({ + btn: btn, + type: "POST", + method: "erpnext.shopping_cart.cart.apply_shipping_rule", + args: { shipping_rule: rule }, + callback: function(r) { + if(!r.exc) { + shopping_cart.render(r.message); + } + } + }); + }, + + render_address: function($address_wrapper, addresses, address_name) { + $.each(addresses, function(i, address) { + $(repl('
\ +
\ +
\ +
%(name)s
\ +
\ +
\ +
\ +
\ +
%(display)s
\ +
\ +
', address)) + .css({"margin": "10px auto"}) + .appendTo($address_wrapper); + }); + + $address_wrapper.find(".panel-heading") + .find(".address-title") + .css({"cursor": "pointer"}) + .on("click", function() { + $address_wrapper.find('.panel-collapse[data-address-name="' + +$(this).attr("data-address-name")+'"]').collapse("toggle"); + }); + + $address_wrapper.find('input[type="checkbox"]').on("click", function() { + if($(this).prop("checked")) { + var me = this; + $address_wrapper.find('input[type="checkbox"]').each(function(i, chk) { + if($(chk).attr("data-address-name")!=$(me).attr("data-address-name")) { + $(chk).prop("checked", false); + } + }); + + return frappe.call({ + type: "POST", + method: "erpnext.shopping_cart.cart.update_cart_address", + args: { + address_fieldname: $address_wrapper.attr("data-fieldname"), + address_name: $(this).attr("data-address-name") + }, + callback: function(r) { + if(!r.exc) { + shopping_cart.render(r.message); + } + } + }); + } else { + return false; + } + }); + + $address_wrapper.find('input[type="checkbox"][data-address-name="'+ address_name +'"]') + .prop("checked", true); + + $address_wrapper.find(".panel-collapse").collapse({ + parent: $address_wrapper, + toggle: false + }); + + $address_wrapper.find('.panel-collapse[data-address-name="'+ address_name +'"]') + .collapse("show"); + }, + + place_order: function(btn) { + return frappe.call({ + type: "POST", + method: "erpnext.shopping_cart.cart.place_order", + btn: btn, + callback: function(r) { + if(r.exc) { + var msg = ""; + if(r._server_messages) { + msg = JSON.parse(r._server_messages || []).join("
"); + } + + $("#cart-error") + .empty() + .html(msg || frappe._("Something went wrong!")) + .toggle(true); + } else { + window.location.href = "order?name=" + encodeURIComponent(r.message); + } + } + }); + } +}); + +$(document).ready(function() { + shopping_cart.bind_events(); + return frappe.call({ + type: "POST", + method: "erpnext.shopping_cart.cart.get_cart_quotation", + callback: function(r) { + $("#cart-container").removeClass("hide"); + $(".progress").remove(); + if(r.exc) { + if(r.exc.indexOf("WebsitePriceListMissingError")!==-1) { + shopping_cart.show_error("Oops!", frappe._("Price List not configured.")); + } else if(r["403"]) { + shopping_cart.show_error("Hey!", frappe._("You need to be logged in to view your cart.")); + } else { + shopping_cart.show_error("Oops!", frappe._("Something went wrong.")); + } + } else { + shopping_cart.set_cart_count(); + shopping_cart.render(r.message); + } + } + }); +}); diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js index 42d4ae7ca5..03520fc551 100644 --- a/erpnext/templates/includes/product_page.js +++ b/erpnext/templates/includes/product_page.js @@ -7,7 +7,7 @@ $(document).ready(function() { frappe.call({ type: "POST", - method: "shopping_cart.shopping_cart.product.get_product_info", + method: "erpnext.shopping_cart.product.get_product_info", args: { item_code: "{{ name }}" }, diff --git a/erpnext/templates/includes/sale.html b/erpnext/templates/includes/sale.html new file mode 100644 index 0000000000..e823248b02 --- /dev/null +++ b/erpnext/templates/includes/sale.html @@ -0,0 +1,85 @@ +
+ +

{{ doc.name }}

+ {% if doc.name == _("Not Allowed") -%} + + {% else %} +
+
+
+
+ {% if doc.status -%}{{ doc.status }}{%- endif %} +
+
+ {{ frappe.utils.formatdate(doc.posting_date or doc.transaction_date) }} +
+
+
+
+
+ + + + + + + + + + + + {%- for row in doc.get({"doctype": doc.doctype + " Item"}) %} + + + + + + + + + + {% endfor -%} + +
SrItem NameDescriptionQtyUoMBasic RateAmount
{{ row.idx }}{{ row.item_name }}{{ row.description }}{{ row.qty }}{{ row.stock_uom }}{{ frappe.utils.fmt_money(row.rate, currency=doc.currency) }}{{ frappe.utils.fmt_money(row.amount, currency=doc.currency) }}
+
+
+
+
+
+ + + + + + + {%- for charge in doc.get({"doctype":"Sales Taxes and Charges"}) -%} + {%- if not charge.included_in_print_rate -%} + + + + + {%- endif -%} + {%- endfor -%} + + + + + + + + + +
Net Total{{ + frappe.utils.fmt_money(doc.net_total/doc.conversion_rate, currency=doc.currency) + }}
{{ charge.description }}{{ frappe.utils.fmt_money(charge.tax_amount / doc.conversion_rate, currency=doc.currency) }}
Grand Total{{ frappe.utils.fmt_money(doc.grand_total_export, currency=doc.currency) }}
Rounded Total{{ frappe.utils.fmt_money(doc.rounded_total_export, currency=doc.currency) }}
+
+
+
+ {%- endif %} +
+ + diff --git a/erpnext/templates/includes/sales_transactions.html b/erpnext/templates/includes/sales_transactions.html new file mode 100644 index 0000000000..e8717af391 --- /dev/null +++ b/erpnext/templates/includes/sales_transactions.html @@ -0,0 +1,30 @@ + + +{% include "templates/includes/transactions.html" %} + + + + diff --git a/erpnext/templates/includes/transactions.html b/erpnext/templates/includes/transactions.html new file mode 100644 index 0000000000..b0eda195b0 --- /dev/null +++ b/erpnext/templates/includes/transactions.html @@ -0,0 +1,53 @@ +
+ + +
+
+
+
+
+
+ +
+
+ + + diff --git a/erpnext/templates/pages/address.html b/erpnext/templates/pages/address.html new file mode 100644 index 0000000000..95ddb76156 --- /dev/null +++ b/erpnext/templates/pages/address.html @@ -0,0 +1,112 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %} +{% macro render_fields(docfields) -%} +{% for df in docfields -%} + {% if df.fieldtype == "Data" -%} +
+ + +
+ {% elif df.fieldtype == "Check" -%} +
+ +
+ {% elif df.fieldtype in ("Select", "Link") -%} +
+ {% set select_options = frappe.get_list(df.options)|map(attribute="name") + if df.fieldtype == "Link" else df.options.split("\n") %} + + +
+ {%- endif %} +{%- endfor %} +{%- endmacro %} + +
+ +

{{ title }}

+ +
+
+ +
+
+
+ {{ render_fields(meta.left_fields) }} +
+
+ {{ render_fields(meta.right_fields) }} +
+ + +
+ + + + +{% endblock %} diff --git a/erpnext/templates/pages/address.py b/erpnext/templates/pages/address.py new file mode 100644 index 0000000000..46dde92c8f --- /dev/null +++ b/erpnext/templates/pages/address.py @@ -0,0 +1,62 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import json + +import frappe +from erpnext.shopping_cart.cart import get_lead_or_customer, update_cart_address +from frappe.desk.form.meta import get_meta + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + def _get_fields(fieldnames): + return [frappe._dict(zip(["label", "fieldname", "fieldtype", "options"], + [df.label, df.fieldname, df.fieldtype, df.options])) + for df in get_meta("Address").get("fields", {"fieldname": ["in", fieldnames]})] + + docname = doc = None + title = "New Address" + if frappe.form_dict.name: + doc = frappe.get_doc("Address", frappe.form_dict.name) + docname = doc.name + title = doc.name + + return { + "doc": doc, + "meta": frappe._dict({ + "left_fields": _get_fields(["address_title", "address_type", "address_line1", "address_line2", + "city", "state", "pincode", "country"]), + "right_fields": _get_fields(["email_id", "phone", "fax", "is_primary_address", + "is_shipping_address"]) + }), + "docname": docname, + "title": title + } + +@frappe.whitelist() +def save_address(fields, address_fieldname=None): + party = get_lead_or_customer() + fields = json.loads(fields) + + if fields.get("name"): + doc = frappe.get_doc("Address", fields.get("name")) + else: + doc = frappe.get_doc({"doctype": "Address", "__islocal": 1}) + + doc.update(fields) + + party_fieldname = party.doctype.lower() + doc.update({ + party_fieldname: party.name, + (party_fieldname + "_name"): party.get(party_fieldname + "_name") + }) + doc.ignore_permissions = True + doc.save() + + if address_fieldname: + update_cart_address(address_fieldname, doc.name) + + return doc.name diff --git a/erpnext/templates/pages/addresses.html b/erpnext/templates/pages/addresses.html new file mode 100644 index 0000000000..58a9798add --- /dev/null +++ b/erpnext/templates/pages/addresses.html @@ -0,0 +1,52 @@ +{% block title %} {{ "My Addresses" }} {% endblock %} + +{% block header %}

My Addresses

{% endblock %} + +{% block breadcrumbs %}{% include "templates/includes/breadcrumbs.html" %}{% endblock %} + +{% block content %} +
+

New Address

+
+
+
+
+
+
+
+ + + + +{% endblock %} + diff --git a/erpnext/templates/pages/addresses.py b/erpnext/templates/pages/addresses.py new file mode 100644 index 0000000000..531d3a37ed --- /dev/null +++ b/erpnext/templates/pages/addresses.py @@ -0,0 +1,13 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from erpnext.shopping_cart.cart import get_address_docs + +no_cache = 1 +no_sitemap = 1 + +@frappe.whitelist() +def get_addresses(): + return get_address_docs() diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html new file mode 100644 index 0000000000..a8dc03e1ae --- /dev/null +++ b/erpnext/templates/pages/cart.html @@ -0,0 +1,57 @@ +{% block title %} {{ "Shopping Cart" }} {% endblock %} + +{% block header %}

Shopping Cart

{% endblock %} + +{% block script %}{% include "templates/includes/cart.js" %}{% endblock %} + +{% block content %} +
+
+
+
+
+

+
+ +
+
+
+
+

Item Details

+
+
+

Qty, Amount

+

+
+
+
+
+
+
+
+
+
+
+

Shipping Address

+
+ +
+
+

Billing Address

+
+ +
+
+
+
+

+
+
+ + +{% endblock %} + diff --git a/erpnext/templates/pages/cart.py b/erpnext/templates/pages/cart.py new file mode 100644 index 0000000000..9c9f096232 --- /dev/null +++ b/erpnext/templates/pages/cart.py @@ -0,0 +1,7 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +no_cache = 1 +no_sitemap = 1 \ No newline at end of file diff --git a/erpnext/templates/pages/invoice.html b/erpnext/templates/pages/invoice.html new file mode 100644 index 0000000000..13b0e7291a --- /dev/null +++ b/erpnext/templates/pages/invoice.html @@ -0,0 +1,6 @@ +{% block title %} {{ doc.name }} {% endblock %} + +{% block header %}

{{ doc.name }}

{% endblock %} + +{% block content%}{% include "templates/includes/sale.html" %}{% endblock %} + diff --git a/erpnext/templates/pages/invoice.py b/erpnext/templates/pages/invoice.py new file mode 100644 index 0000000000..5b55007c7b --- /dev/null +++ b/erpnext/templates/pages/invoice.py @@ -0,0 +1,31 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import flt, fmt_money +from shopping_cart.templates.utils import get_transaction_context + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + invoice_context = frappe._dict({ + "parent_link": "invoices", + "parent_title": "Invoices" + }) + invoice_context.update(get_transaction_context("Sales Invoice", frappe.form_dict.name)) + modify_status(invoice_context.doc) + return invoice_context + +def modify_status(doc): + doc.status = "" + if flt(doc.outstanding_amount): + doc.status = ' %s' % \ + ("label-warning", "icon-exclamation-sign", + _("To Pay") + " = " + fmt_money(doc.outstanding_amount, currency=doc.currency)) + else: + doc.status = ' %s' % \ + ("label-success", "icon-ok", _("Paid")) + \ No newline at end of file diff --git a/erpnext/templates/pages/invoices.html b/erpnext/templates/pages/invoices.html new file mode 100644 index 0000000000..9f493cacc9 --- /dev/null +++ b/erpnext/templates/pages/invoices.html @@ -0,0 +1,6 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %} + diff --git a/erpnext/templates/pages/invoices.py b/erpnext/templates/pages/invoices.py new file mode 100644 index 0000000000..98c514088c --- /dev/null +++ b/erpnext/templates/pages/invoices.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from shopping_cart.templates.utils import get_currency_context + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + invoices_context = get_currency_context() + invoices_context.update({ + "title": "Invoices", + "method": "shopping_cart.templates.pages.invoices.get_invoices", + "icon": "icon-file-text", + "empty_list_message": "No Invoices Found", + "page": "invoice" + }) + return invoices_context + +@frappe.whitelist() +def get_invoices(start=0): + from shopping_cart.templates.utils import get_transaction_list + from shopping_cart.templates.pages.invoice import modify_status + invoices = get_transaction_list("Sales Invoice", start, ["outstanding_amount"]) + for d in invoices: + modify_status(d) + return invoices \ No newline at end of file diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html new file mode 100644 index 0000000000..13b0e7291a --- /dev/null +++ b/erpnext/templates/pages/order.html @@ -0,0 +1,6 @@ +{% block title %} {{ doc.name }} {% endblock %} + +{% block header %}

{{ doc.name }}

{% endblock %} + +{% block content%}{% include "templates/includes/sale.html" %}{% endblock %} + diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py new file mode 100644 index 0000000000..832a60e1d5 --- /dev/null +++ b/erpnext/templates/pages/order.py @@ -0,0 +1,34 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from shopping_cart.templates.utils import get_transaction_context + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + order_context = frappe._dict({ + "parent_link": "orders", + "parent_title": "My Orders" + }) + + order_context.update(get_transaction_context("Sales Order", frappe.form_dict.name)) + modify_status(order_context.doc) + return order_context + +def modify_status(doc): + doc.status = [] + if 0 < doc.per_billed < 100: + doc.status.append(("label-warning", "icon-ok", _("Partially Billed"))) + elif doc.per_billed == 100: + doc.status.append(("label-success", "icon-ok", _("Billed"))) + + if 0 < doc.per_delivered < 100: + doc.status.append(("label-warning", "icon-truck", _("Partially Delivered"))) + elif doc.per_delivered == 100: + doc.status.append(("label-success", "icon-truck", _("Delivered"))) + doc.status = " " + " ".join((' %s' % s + for s in doc.status)) diff --git a/erpnext/templates/pages/orders.html b/erpnext/templates/pages/orders.html new file mode 100644 index 0000000000..d58cbd8e9c --- /dev/null +++ b/erpnext/templates/pages/orders.html @@ -0,0 +1,5 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %} diff --git a/erpnext/templates/pages/orders.py b/erpnext/templates/pages/orders.py new file mode 100644 index 0000000000..c443b6afc1 --- /dev/null +++ b/erpnext/templates/pages/orders.py @@ -0,0 +1,30 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from shopping_cart.templates.utils import get_currency_context, get_transaction_list +from shopping_cart.templates.pages.order import modify_status + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + orders_context = get_currency_context() + orders_context.update({ + "title": "My Orders", + "method": "shopping_cart.templates.pages.orders.get_orders", + "icon": "icon-list", + "empty_list_message": "No Orders Yet", + "page": "order", + }) + return orders_context + +@frappe.whitelist() +def get_orders(start=0): + orders = get_transaction_list("Sales Order", start, ["per_billed", "per_delivered"]) + for d in orders: + modify_status(d) + + return orders + \ No newline at end of file diff --git a/erpnext/templates/pages/shipment.html b/erpnext/templates/pages/shipment.html new file mode 100644 index 0000000000..13b0e7291a --- /dev/null +++ b/erpnext/templates/pages/shipment.html @@ -0,0 +1,6 @@ +{% block title %} {{ doc.name }} {% endblock %} + +{% block header %}

{{ doc.name }}

{% endblock %} + +{% block content%}{% include "templates/includes/sale.html" %}{% endblock %} + diff --git a/erpnext/templates/pages/shipment.py b/erpnext/templates/pages/shipment.py new file mode 100644 index 0000000000..ba98e1d465 --- /dev/null +++ b/erpnext/templates/pages/shipment.py @@ -0,0 +1,17 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from shopping_cart.templates.utils import get_transaction_context + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + shipment_context = frappe._dict({ + "parent_link": "shipments", + "parent_title": "Shipments" + }) + shipment_context.update(get_transaction_context("Delivery Note", frappe.form_dict.name)) + return shipment_context diff --git a/erpnext/templates/pages/shipments.html b/erpnext/templates/pages/shipments.html new file mode 100644 index 0000000000..d58cbd8e9c --- /dev/null +++ b/erpnext/templates/pages/shipments.html @@ -0,0 +1,5 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %}{% include "templates/includes/sales_transactions.html" %}{% endblock %} diff --git a/erpnext/templates/pages/shipments.py b/erpnext/templates/pages/shipments.py new file mode 100644 index 0000000000..fe28c7ea97 --- /dev/null +++ b/erpnext/templates/pages/shipments.py @@ -0,0 +1,25 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from shopping_cart.templates.utils import get_currency_context + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + shipments_context = get_currency_context() + shipments_context.update({ + "title": "Shipments", + "method": "shopping_cart.templates.pages.shipments.get_shipments", + "icon": "icon-truck", + "empty_list_message": "No Shipments Found", + "page": "shipment" + }) + return shipments_context + +@frappe.whitelist() +def get_shipments(start=0): + from shopping_cart.templates.utils import get_transaction_list + return get_transaction_list("Delivery Note", start) diff --git a/erpnext/templates/pages/ticket.html b/erpnext/templates/pages/ticket.html new file mode 100644 index 0000000000..39c69dfa0a --- /dev/null +++ b/erpnext/templates/pages/ticket.html @@ -0,0 +1,116 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %} +{% set status_label = { + "Open": "label-success", + "To Reply": "label-danger", + "Closed": "label-default" +} %} + +
+ + {% if not doc -%} + + {% else %} +
+ {%- if doc.status -%} + {% if doc.status == "Waiting for Customer" -%} + {% set status = "To Reply" %} + {% else %} + {% set status = doc.status %} + {%- endif -%} +
+
+ {{ status }} +
+
+
{{ doc.subject }}
+
+
+ {{ frappe.utils.formatdate(doc.creation) }} +
+
+
+

Messages

+
+ + +
+
+ +
+ + + {%- for comm in + (doc.get({"doctype":"Communication"})|sort(reverse=True, attribute="creation")) %} + + + + {% endfor -%} + +
+
+ {{ comm.sender }} on {{ frappe.utils.formatdate(comm.creation) }}
+
+

{{ frappe.utils.is_html(comm.content) and comm.content or + comm.content.replace("\n", "
")}}

+
+
+ {%- endif -%} + {% endif -%} +
+ + + + +{% endblock %} diff --git a/erpnext/templates/pages/ticket.py b/erpnext/templates/pages/ticket.py new file mode 100644 index 0000000000..9582146ceb --- /dev/null +++ b/erpnext/templates/pages/ticket.py @@ -0,0 +1,41 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import today + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + doc = frappe.get_doc("Support Ticket", frappe.form_dict.name) + if doc.raised_by == frappe.session.user: + ticket_context = { + "title": doc.name, + "doc": doc + } + else: + ticket_context = {"title": "Not Allowed", "doc": {}} + + return ticket_context + +@frappe.whitelist() +def add_reply(ticket, message): + if not message: + raise frappe.throw(_("Please write something")) + + doc = frappe.get_doc("Support Ticket", ticket) + if doc.raised_by != frappe.session.user: + raise frappe.throw(_("You are not allowed to reply to this ticket."), frappe.PermissionError) + + comm = frappe.get_doc({ + "doctype":"Communication", + "subject": doc.subject, + "content": message, + "sender": doc.raised_by, + "sent_or_received": "Received" + }) + comm.insert(ignore_permissions=True) + diff --git a/erpnext/templates/pages/tickets.html b/erpnext/templates/pages/tickets.html new file mode 100644 index 0000000000..6c03313f3e --- /dev/null +++ b/erpnext/templates/pages/tickets.html @@ -0,0 +1,92 @@ +{% block title %} {{ title }} {% endblock %} + +{% block header %}

{{ title }}

{% endblock %} + +{% block content %} +{% include "templates/includes/transactions.html" %} + + + + +{% endblock %} + diff --git a/erpnext/templates/pages/tickets.py b/erpnext/templates/pages/tickets.py new file mode 100644 index 0000000000..158173f2af --- /dev/null +++ b/erpnext/templates/pages/tickets.py @@ -0,0 +1,54 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.utils import cint, formatdate + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + return { + "title": "My Tickets", + "method": "shopping_cart.templates.pages.tickets.get_tickets", + "icon": "icon-ticket", + "empty_list_message": "No Tickets Raised", + "page": "ticket" + } + +@frappe.whitelist() +def get_tickets(start=0): + tickets = frappe.db.sql("""select name, subject, status, creation + from `tabSupport Ticket` where raised_by=%s + order by modified desc + limit %s, 20""", (frappe.session.user, cint(start)), as_dict=True) + for t in tickets: + t.creation = formatdate(t.creation) + + return tickets + +@frappe.whitelist() +def make_new_ticket(subject, message): + if not (subject and message): + raise frappe.throw(_("Please write something in subject and message!")) + + ticket = frappe.get_doc({ + "doctype":"Support Ticket", + "subject": subject, + "raised_by": frappe.session.user, + }) + ticket.insert(ignore_permissions=True) + + comm = frappe.get_doc({ + "doctype":"Communication", + "subject": subject, + "content": message, + "sender": frappe.session.user, + "sent_or_received": "Received", + "reference_doctype": "Support Ticket", + "reference_name": ticket.name + }) + comm.insert(ignore_permissions=True) + + return ticket.name diff --git a/erpnext/templates/pages/user.html b/erpnext/templates/pages/user.html new file mode 100644 index 0000000000..b4a1a39008 --- /dev/null +++ b/erpnext/templates/pages/user.html @@ -0,0 +1,57 @@ +{% block title %} {{ "My Profile" }} {% endblock %} + +{% block header %}

My Profile

{% endblock %} + +{% block content %} +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+ + +{% endblock %} + diff --git a/erpnext/templates/pages/user.py b/erpnext/templates/pages/user.py new file mode 100644 index 0000000000..5869e98770 --- /dev/null +++ b/erpnext/templates/pages/user.py @@ -0,0 +1,40 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import cstr +from erpnext.shopping_cart.cart import get_lead_or_customer + +no_cache = 1 +no_sitemap = 1 + +def get_context(context): + party = get_lead_or_customer() + if party.doctype == "Lead": + mobile_no = party.mobile_no + phone = party.phone + else: + mobile_no, phone = frappe.db.get_value("Contact", {"email_id": frappe.session.user, + "customer": party.name}, ["mobile_no", "phone"]) + + return { + "company_name": cstr(party.customer_name if party.doctype == "Customer" else party.company_name), + "mobile_no": cstr(mobile_no), + "phone": cstr(phone) + } + +@frappe.whitelist() +def update_user(fullname, password=None, company_name=None, mobile_no=None, phone=None): + from erpnext.shopping_cart.cart import update_party + update_party(fullname, company_name, mobile_no, phone) + + if not fullname: + return _("Name is required") + + frappe.db.set_value("User", frappe.session.user, "first_name", fullname) + frappe.local.cookie_manager.set_cookie("full_name", fullname) + + return _("Updated") + \ No newline at end of file diff --git a/erpnext/templates/utils.py b/erpnext/templates/utils.py index 9892924007..139e63af30 100644 --- a/erpnext/templates/utils.py +++ b/erpnext/templates/utils.py @@ -2,7 +2,10 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe + +import frappe, json +from frappe import _ +from frappe.utils import cint, formatdate @frappe.whitelist(allow_guest=True) def send_message(subject="Website Query", message="", sender="", status="Open"): @@ -18,3 +21,47 @@ def send_message(subject="Website Query", message="", sender="", status="Open"): "sent_or_received": "Received" }) comm.insert(ignore_permissions=True) + +def get_transaction_list(doctype, start, additional_fields=None): + # find customer id + customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, + "customer") + + if customer: + if additional_fields: + additional_fields = ", " + ", ".join(("`%s`" % f for f in additional_fields)) + else: + additional_fields = "" + + transactions = frappe.db.sql("""select name, creation, currency, grand_total_export + %s + from `tab%s` where customer=%s and docstatus=1 + order by creation desc + limit %s, 20""" % (additional_fields, doctype, "%s", "%s"), + (customer, cint(start)), as_dict=True) + for doc in transactions: + items = frappe.db.sql_list("""select item_name + from `tab%s Item` where parent=%s limit 6""" % (doctype, "%s"), doc.name) + doc.items = ", ".join(items[:5]) + ("..." if (len(items) > 5) else "") + doc.creation = formatdate(doc.creation) + return transactions + else: + return [] + +def get_currency_context(): + return { + "global_number_format": frappe.db.get_default("number_format") or "#,###.##", + "currency": frappe.db.get_default("currency"), + "currency_symbols": json.dumps(dict(frappe.db.sql("""select name, symbol + from tabCurrency where ifnull(enabled,0)=1"""))) + } + +def get_transaction_context(doctype, name): + customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, + "customer") + + doc = frappe.get_doc(doctype, name) + if doc.customer != customer: + return { "doc": frappe._dict({"name": _("Not Allowed")}) } + else: + return { "doc": doc } diff --git a/erpnext/translations/ar.csv b/erpnext/translations/ar.csv index 4e587dbc94..aefb890128 100644 --- a/erpnext/translations/ar.csv +++ b/erpnext/translations/ar.csv @@ -3329,3 +3329,49 @@ website page link,الموقع رابط الصفحة {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: مركز التكلفة إلزامي القطعة ل{2} {0}: {1} not found in Invoice Details table,{0}: {1} غير موجود في جدول تفاصيل الفاتورة  (Half Day),(نصف يوم) +"Add / Edit"," إضافة / تحرير < / A>" +"Add / Edit"," إضافة / تحرير < / A>" +Billed,توصف +Company,شركة +Currency is required for Price List {0},مطلوب العملة ل قائمة الأسعار {0} +Default Customer Group,المجموعة الافتراضية العملاء +Default Territory,الافتراضي الإقليم +Delivered,تسليم +Enable Shopping Cart,تمكين سلة التسوق +Go ahead and add something to your cart.,المضي قدما وإضافة شيء إلى عربة التسوق. +Hey! Go ahead and add an address,احترس المضي قدما وإضافة عنوان +Invalid Billing Address,عنوان الفواتير غير صالحة +Invalid Shipping Address,العنوان شحن غير صالحة +Missing Currency Exchange Rates for {0},أسعار صرف العملات في عداد المفقودين ل {0} +Name is required,مطلوب اسم +Not Allowed,غير مسموح +Paid,مدفوع +Partially Billed,وصفت جزئيا +Partially Delivered,سلمت جزئيا +Please specify a Price List which is valid for Territory,الرجاء تحديد قائمة الأسعار التي هي صالحة للأراضي +Please specify currency in Company,يرجى تحديد العملة في شركة +Please write something,يرجى كتابة شيء +Please write something in subject and message!,يرجى كتابة شيء في الموضوع و رسالة ! +Price List,قائمة الأسعار +Price List not configured.,قائمة السعر لم يتم تكوين. +Quotation Series,سلسلة الاقتباس +Shipping Rule,الشحن القاعدة +Shopping Cart,سلة التسوق +Shopping Cart Price List,عربة التسوق قائمة الأسعار +Shopping Cart Price Lists,سلة التسوق قوائم الأسعار +Shopping Cart Settings,إعدادات سلة التسوق +Shopping Cart Shipping Rule,سلة التسوق الشحن القاعدة +Shopping Cart Shipping Rules,سلة التسوق قواعد الشحن +Shopping Cart Taxes and Charges Master,التسوق سلة الضرائب والرسوم ماجستير +Shopping Cart Taxes and Charges Masters,التسوق سلة الضرائب والرسوم الماجستير +Something went wrong!,ذهب شيئا خاطئا! +Something went wrong.,ذهب شيئا خاطئا. +Tax Master,ماستر الضرائب +To Pay,على الدفع +Updated,تحديث +You are not allowed to reply to this ticket.,لا يسمح لك للرد على هذه التذكرة . +You need to be logged in to view your cart.,تحتاج إلى تسجيل الدخول لمشاهدة عربة التسوق. +You need to enable Shopping Cart,تحتاج إلى تمكين سلة التسوق +{0} cannot be purchased using Shopping Cart,{0} لا يمكن شراؤها باستخدام عربة التسوق +{0} is required,{0} مطلوب +{0} {1} has a common territory {2},{0} {1} لديه أراضي مشتركة {2} diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv index a1c0a5688e..ac797e1305 100644 --- a/erpnext/translations/de.csv +++ b/erpnext/translations/de.csv @@ -3460,3 +3460,51 @@ website page link,Website-Link {0} {1} status is Unstopped,{0} {1} Status unstopped {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Kostenstelle ist obligatorisch für Artikel {2} {0}: {1} not found in Invoice Details table,{0}: {1} nicht in der Rechnungs Details-Tabelle gefunden +"Add / Edit"," Hinzufügen / Bearbeiten " +"Add / Edit"," Hinzufügen / Bearbeiten " +Billed,Abgerechnet +Company,Unternehmen +Currency is required for Price List {0},Die Währung ist für Preisliste erforderlich {0} +Default Customer Group,Standardkundengruppe +Default Territory,Standardregion +Default settings for Shopping Cart,Standardeinstellungen für Einkaufswagen +Delivered,Geliefert +Enable Shopping Cart,Einkaufswagen aktivieren +Go ahead and add something to your cart.,Gehen Sie voran und fügen Sie etwas in Ihren Warenkorb. +Hey! Go ahead and add an address,Hallo! Gehen Sie voran und fügen Sie eine Adresse +Invalid Billing Address,Ungültige Rechnungsadresse +Invalid Shipping Address,Falsche Lieferadresse +Missing Currency Exchange Rates for {0},Fehlende Wechselkurse für {0} +Name is required,Name ist erforderlich +Not Allowed,Nicht erlaubt +Paid,bezahlt +Partially Billed,teilweise Angekündigt +Partially Delivered,teilweise Lieferung +Please specify a Price List which is valid for Territory,"Legen Sie eine Preisliste fest, die für die Region gültig ist" +Please specify currency in Company,Geben Sie die Währung im Unternehmen an +Please write something,Bitte schreiben Sie etwas +Please write something in subject and message!,Bitte schreiben Sie etwas in Betreff und die Nachricht ! +Price List,Preisliste +Price List not configured.,Preisliste nicht konfiguriert. +Quotation Series,Angebotsserie +Shipping Rule,Versandregel +Shopping Cart,Einkaufswagen +Shopping Cart Price List,Einkaufswagen Preisliste +Shopping Cart Price Lists,Einkaufswagen Preislisten +Shopping Cart Settings,Einkaufswageneinstellungen +Shopping Cart Shipping Rule,Einkaufswagen-Versandregel +Shopping Cart Shipping Rules,Einkaufswagen-Versandregeln +Shopping Cart Taxes and Charges Master,Einkaufswagen-Steuern und Abgabenstamm +Shopping Cart Taxes and Charges Masters,Einkaufswagen-Steuern und Abgabenstämme +Something went wrong!,Etwas ist schiefgelaufen! +Something went wrong.,Es gab ein Problem. +Tax Master,Steuerstamm +To Pay,To Pay +Updated,Aktualisiert +Website Manager, +You are not allowed to reply to this ticket.,"Sie sind nicht berechtigt, auf diesem Ticket antworten ." +You need to be logged in to view your cart.,"Sie müssen angemeldet sein, um Ihren Warenkorb zu sehen." +You need to enable Shopping Cart,Sie benötigen den Einkaufswagen zu ermöglichen +{0} cannot be purchased using Shopping Cart,{0} kann nicht mit Einkaufswagen erworben werden +{0} is required,{0} ist erforderlich +{0} {1} has a common territory {2},{0} {1} hat einen gemeinsamen Territorium {2} diff --git a/erpnext/translations/el.csv b/erpnext/translations/el.csv index 4e1e05f8a7..7526120113 100644 --- a/erpnext/translations/el.csv +++ b/erpnext/translations/el.csv @@ -3329,3 +3329,49 @@ website page link,Ιστοσελίδα link της σελίδας {0} {1} status is Unstopped,{0} {1} η κατάσταση είναι ανεμπόδιστη {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Κέντρο Κόστους είναι υποχρεωτική για τη θέση {2} {0}: {1} not found in Invoice Details table,{0}: {1} δεν βρέθηκε στον πίνακα Στοιχεία τιμολογίου +"Add / Edit"," Προσθήκη / Επεξεργασία < / a>" +"Add / Edit"," Προσθήκη / Επεξεργασία < / a>" +Billed,Χρεώνεται +Company,Εταιρεία +Currency is required for Price List {0},Νόμισμα απαιτείται για Τιμοκατάλογος {0} +Default Customer Group,Προεπιλογή Ομάδα πελατών +Default Territory,Έδαφος Προεπιλογή +Delivered,Δημοσιεύθηκε +Enable Shopping Cart,Ενεργοποίηση Καλάθι Αγορών +Go ahead and add something to your cart.,Προχωρήστε και να προσθέσω κάτι στο καλάθι σας. +Hey! Go ahead and add an address,Γειά! Προχωρήστε και να προσθέσετε μια διεύθυνση +Invalid Billing Address,Μη έγκυρη διεύθυνση χρέωσης +Invalid Shipping Address,Μη έγκυρη διεύθυνση αποστολής +Missing Currency Exchange Rates for {0},Λείπει Τιμές συναλλάγματος για {0} +Name is required,Όνομα απαιτείται +Not Allowed,δεν επιτρέπονται κατοικίδια +Paid,Αμειβόμενος +Partially Billed,μερικώς Billed +Partially Delivered,μερικώς Δημοσιεύθηκε +Please specify a Price List which is valid for Territory,Παρακαλείστε να προσδιορίσετε μια λίστα τιμών που ισχύει για Επικράτεια +Please specify currency in Company,Παρακαλείστε να προσδιορίσετε το νόμισμα στην εταιρεία +Please write something,Παρακαλώ γράψτε κάτι +Please write something in subject and message!,Παρακαλώ γράψτε κάτι στο θέμα και το μήνυμα ! +Price List,Τιμοκατάλογος +Price List not configured.,Τιμοκατάλογος δεν έχει ρυθμιστεί. +Quotation Series,Σειρά Προσφοράς +Shipping Rule,Αποστολές Κανόνας +Shopping Cart,Καλάθι Αγορών +Shopping Cart Price List,Shopping Τιμοκατάλογος Καλάθι +Shopping Cart Price Lists,Τιμοκατάλογοι Καλάθι Αγορών +Shopping Cart Settings,Ρυθμίσεις Καλάθι Αγορών +Shopping Cart Shipping Rule,Καλάθι Αγορών αποστολή Κανόνας +Shopping Cart Shipping Rules,Κανόνες Shipping Καλάθι Αγορών +Shopping Cart Taxes and Charges Master,Φόροι Καλάθι και Χρεώσεις Δάσκαλος +Shopping Cart Taxes and Charges Masters,Φόροι Καλάθι και Χρεώσεις Masters +Something went wrong!,Κάτι πήγε στραβά! +Something went wrong.,Κάτι πήγε στραβά. +Tax Master,Δάσκαλος φόρου +To Pay,να πληρώσει +Updated,Ενημέρωση +You are not allowed to reply to this ticket.,Δεν επιτρέπεται να απαντήσετε σε αυτό το εισιτήριο . +You need to be logged in to view your cart.,Θα πρέπει να είστε συνδεδεμένοι για να δείτε το καλάθι σας. +You need to enable Shopping Cart,Χρειάζεται να ενεργοποιήσετε Καλάθι Αγορών +{0} cannot be purchased using Shopping Cart,{0} δεν μπορούν να αγοραστούν χρησιμοποιώντας Καλάθι Αγορών +{0} is required,{0} απαιτείται +{0} {1} has a common territory {2},{0} {1} έχει ένα κοινό έδαφος {2} diff --git a/erpnext/translations/es.csv b/erpnext/translations/es.csv index 0fe2847998..16885620cd 100644 --- a/erpnext/translations/es.csv +++ b/erpnext/translations/es.csv @@ -3335,3 +3335,49 @@ website page link,el vínculo web {0} {1} status is Unstopped,{0} {1} Estado es destapados {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Centro de Costo es obligatorio para el punto {2} {0}: {1} not found in Invoice Details table,{0}: {1} no se encuentra en la factura Detalles mesa +"Add / Edit"," Añadir / Editar < / a>" +"Add / Edit"," Añadir / Editar < / a>" +Billed,Anunciado +Company,Empresa +Currency is required for Price List {0},Se requiere de divisas para el precio de lista {0} +Default Customer Group,Grupo predeterminado Cliente +Default Territory,Territorio predeterminado +Delivered,liberado +Enable Shopping Cart,Habilitar Compras +Go ahead and add something to your cart.,Seguir adelante y añadir algo a su carrito. +Hey! Go ahead and add an address,¡Hey! Seguir adelante y añadir una dirección +Invalid Billing Address,No válida dirección de facturación +Invalid Shipping Address,Dirección no válida de envío +Missing Currency Exchange Rates for {0},Missing Tipo de Cambio para {0} +Name is required,El nombre es necesario +Not Allowed,No se permite +Paid,pagado +Partially Billed,Parcialmente Anunciado +Partially Delivered,Parcialmente Entregado +Please specify a Price List which is valid for Territory,"Por favor, especifique una lista de precios que es válido para el territorio" +Please specify currency in Company,"Por favor, especifique la moneda en la empresa" +Please write something,"Por favor, escribir algo" +Please write something in subject and message!,"Por favor, escriba algo en asunto y el mensaje !" +Price List,Lista de Precios +Price List not configured.,Lista de precios no está configurado. +Quotation Series,Serie Cotización +Shipping Rule,Regla de envío +Shopping Cart,Cesta de la compra +Shopping Cart Price List,Cesta de la compra Precio de lista +Shopping Cart Price Lists,Compras Listas de precios +Shopping Cart Settings,Compras Ajustes +Shopping Cart Shipping Rule,Compras Regla de envío +Shopping Cart Shipping Rules,Compras Reglas de Envío +Shopping Cart Taxes and Charges Master,Compras Impuestos y Cargos Maestro +Shopping Cart Taxes and Charges Masters,Carrito impuestos y las cargas Masters +Something went wrong!,¡Algo salió mal! +Something went wrong.,Algo salió mal. +Tax Master,Maestro de Impuestos +To Pay,Pagar +Updated,actualizado +You are not allowed to reply to this ticket.,No se le permite responder a este boleto. +You need to be logged in to view your cart.,Tienes que estar registrado para ver su carrito. +You need to enable Shopping Cart,Necesita habilitar Compras +{0} cannot be purchased using Shopping Cart,{0} no puede ser comprado usando Compras +{0} is required,{0} es necesario +{0} {1} has a common territory {2},{0} {1} tiene un territorio común {2} diff --git a/erpnext/translations/fr.csv b/erpnext/translations/fr.csv index 2d3af178b7..34cdafa6ca 100644 --- a/erpnext/translations/fr.csv +++ b/erpnext/translations/fr.csv @@ -3330,3 +3330,49 @@ website page link,Lien vers page web {0} {1} status is Unstopped,Vous ne pouvez pas reporter le numéro de rangée supérieure ou égale à numéro de la ligne actuelle pour ce type de charge {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Centre de coûts est obligatoire pour objet {2} {0}: {1} not found in Invoice Details table,{0}: {1} ne trouve pas dans la table Détails de la facture +"Add / Edit"," Ajouter / Modifier < / a>" +"Add / Edit"," Ajouter / Modifier < / a>" +Billed,Facturé +Company,Entreprise +Currency is required for Price List {0},{0} est obligatoire +Default Customer Group,Groupe de clients par défaut +Default Territory,Territoire défaut +Delivered,Livré +Enable Shopping Cart,Activer Panier +Go ahead and add something to your cart.,Allez-y et ajouter quelque chose à votre panier. +Hey! Go ahead and add an address,Hé ! Allez-y et ajoutez une adresse +Invalid Billing Address,"Pour exécuter un test ajouter le nom du module dans la route après '{0}' . Par exemple, {1}" +Invalid Shipping Address,effondrement +Missing Currency Exchange Rates for {0},Vider le cache +Name is required,Le nom est obligatoire +Not Allowed,"Groupe ajoutée, rafraîchissant ..." +Paid,payé +Partially Billed,partiellement Facturé +Partially Delivered,Livré partiellement +Please specify a Price List which is valid for Territory,S'il vous plaît spécifier une liste de prix qui est valable pour le territoire +Please specify currency in Company,S'il vous plaît préciser la devise dans la société +Please write something,S'il vous plaît écrire quelque chose +Please write something in subject and message!,S'il vous plaît écrire quelque chose dans le thème et le message ! +Price List,Liste des Prix +Price List not configured.,Liste des prix non configuré. +Quotation Series,Série de devis +Shipping Rule,Livraison règle +Shopping Cart,Panier +Shopping Cart Price List,Panier Liste des prix +Shopping Cart Price Lists,Panier Liste des prix +Shopping Cart Settings,Panier Paramètres +Shopping Cart Shipping Rule,Panier Livraison règle +Shopping Cart Shipping Rules,Panier Règles d'expédition +Shopping Cart Taxes and Charges Master,Panier taxes et redevances Maître +Shopping Cart Taxes and Charges Masters,Panier Taxes et frais de maîtrise +Something went wrong!,Quelque chose s'est mal passé! +Something went wrong.,Une erreur est survenue. +Tax Master,Maître d'impôt +To Pay,à payer +Updated,Mise à jour +You are not allowed to reply to this ticket.,Vous n'êtes pas autorisé à répondre à ce billet . +You need to be logged in to view your cart.,Vous devez être connecté pour voir votre panier. +You need to enable Shopping Cart,Poster n'existe pas . S'il vous plaît ajoutez poste ! +{0} cannot be purchased using Shopping Cart,Envoyer permanence {0} ? +{0} is required,{0} ne peut pas être acheté en utilisant Panier +{0} {1} has a common territory {2},Alternative lien de téléchargement diff --git a/erpnext/translations/hi.csv b/erpnext/translations/hi.csv index e1092492ac..b9b64fe800 100644 --- a/erpnext/translations/hi.csv +++ b/erpnext/translations/hi.csv @@ -3329,3 +3329,49 @@ website page link,वेबसाइट के पेज लिंक {0} {1} status is Unstopped,{0} {1} स्थिति unstopped है {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: लागत केंद्र मद के लिए अनिवार्य है {2} {0}: {1} not found in Invoice Details table,{0} {1} चालान विवरण तालिका में नहीं मिला +"Add / Edit"," जोड़ें / संपादित करें " +"Add / Edit"," जोड़ें / संपादित करें " +Billed,का बिल +Company,कंपनी +Currency is required for Price List {0},मुद्रा मूल्य सूची के लिए आवश्यक है {0} +Default Customer Group,डिफ़ॉल्ट ग्राहक समूह +Default Territory,Default टेरिटरी +Delivered,दिया गया +Enable Shopping Cart,शॉपिंग कार्ट सक्षम करें +Go ahead and add something to your cart.,आगे बढ़ो और अपनी गाड़ी को कुछ जोड़ सकते. +Hey! Go ahead and add an address,अरे! आगे बढ़ो और एक पते जोड़ +Invalid Billing Address,अवैध बिलिंग पता +Invalid Shipping Address,अवैध शिपिंग पता +Missing Currency Exchange Rates for {0},के लिए मुद्रा विनिमय दरें गुम {0} +Name is required,नाम आवश्यक है +Not Allowed,अनुमति नहीं +Paid,प्रदत्त +Partially Billed,आंशिक रूप से बिल +Partially Delivered,आंशिक रूप से वितरित +Please specify a Price List which is valid for Territory,राज्य क्षेत्र के लिए मान्य है जो एक मूल्य सूची निर्दिष्ट करें +Please specify currency in Company,कंपनी में मुद्रा निर्दिष्ट करें +Please write something,कुछ लिखें +Please write something in subject and message!,विषय और संदेश में कुछ लिखने के लिए धन्यवाद ! +Price List,कीमत सूची +Price List not configured.,मूल्य सूची कॉन्फ़िगर नहीं. +Quotation Series,कोटेशन सीरीज +Shipping Rule,नौवहन नियम +Shopping Cart,खरीदारी की टोकरी +Shopping Cart Price List,शॉपिंग कार्ट में मूल्य सूची +Shopping Cart Price Lists,शॉपिंग कार्ट में मूल्य सूची +Shopping Cart Settings,शॉपिंग कार्ट सेटिंग्स +Shopping Cart Shipping Rule,शॉपिंग कार्ट शिपिंग नियम +Shopping Cart Shipping Rules,शॉपिंग कार्ट शिपिंग नियम +Shopping Cart Taxes and Charges Master,शॉपिंग कार्ट में करों और शुल्कों मास्टर +Shopping Cart Taxes and Charges Masters,शॉपिंग कार्ट में करों और शुल्कों मास्टर्स +Something went wrong!,कुछ गलत हो गया! +Something went wrong.,कुछ गलत हो गया. +Tax Master,टैक्स मास्टर +To Pay,भुगतान करने के लिए +Updated,अद्यतित +You are not allowed to reply to this ticket.,आप इस टिकट का उत्तर देने की अनुमति नहीं है . +You need to be logged in to view your cart.,आप अपनी गाड़ी को देखने के लिए लॉग इन करना होगा. +You need to enable Shopping Cart,आप शॉपिंग कार्ट में सक्रिय करने की जरूरत +{0} cannot be purchased using Shopping Cart,{0} शॉपिंग कार्ट का उपयोग कर खरीदा नहीं जा सकता +{0} is required,{0} के लिए आवश्यक है +{0} {1} has a common territory {2},{0} {1} एक सामान्य क्षेत्र है {2} diff --git a/erpnext/translations/hr.csv b/erpnext/translations/hr.csv index 4f5c050325..70a8a90996 100644 --- a/erpnext/translations/hr.csv +++ b/erpnext/translations/hr.csv @@ -3329,3 +3329,49 @@ website page link,web stranica vode {0} {1} status is Unstopped,{0} {1} status Unstopped {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: troška je obvezno za točku {2} {0}: {1} not found in Invoice Details table,{0}: {1} nije pronađen u Pojedinosti dostavnice stolu +"Add / Edit"," Dodaj / Uredi < />" +"Add / Edit"," Dodaj / Uredi < />" +Billed,Naplaćeno +Company,Društvo +Currency is required for Price List {0},Valuta je potrebno za Cjenika {0} +Default Customer Group,Zadani Korisnik Grupa +Default Territory,Zadani Regija +Delivered,Isporučena +Enable Shopping Cart,Omogućite Košarica +Go ahead and add something to your cart.,Ići naprijed i dodati nešto u košaricu. +Hey! Go ahead and add an address,Hej! Ići naprijed i dodati adresu +Invalid Billing Address,Pogrešna adresa naplate +Invalid Shipping Address,Invalid Dostava Adresa +Missing Currency Exchange Rates for {0},Nedostaje Tečajne stope za {0} +Name is required,Ime je potrebno +Not Allowed,Not Allowed +Paid,plaćen +Partially Billed,djelomično Naplaćeno +Partially Delivered,djelomično Isporučeno +Please specify a Price List which is valid for Territory,Navedite cjenik koji vrijedi za teritoriju +Please specify currency in Company,Navedite valutu u Društvu +Please write something,Molimo napisati nešto +Please write something in subject and message!,Molimo napisati nešto u temi i poruke ! +Price List,Cjenik +Price List not configured.,Popis Cijena nije konfiguriran. +Quotation Series,Ponuda Serija +Shipping Rule,Dostava Pravilo +Shopping Cart,Košarica +Shopping Cart Price List,Košarica Cjenik +Shopping Cart Price Lists,Košarica cjenike +Shopping Cart Settings,Košarica Postavke +Shopping Cart Shipping Rule,Košarica Dostava Pravilo +Shopping Cart Shipping Rules,Košarica Dostava Pravila +Shopping Cart Taxes and Charges Master,Košarica poreze i troškove Master +Shopping Cart Taxes and Charges Masters,Košarica Porezi i naknade Masters +Something went wrong!,Nešto je pošlo po krivu! +Something went wrong.,Nešto je pošlo po zlu. +Tax Master,Porezna Master +To Pay,platiti +Updated,Obnovljeno +You are not allowed to reply to this ticket.,Vi ne smijete odgovoriti na ovu kartu. +You need to be logged in to view your cart.,Morate biti prijavljeni da biste vidjeli svoju košaricu. +You need to enable Shopping Cart,Morate omogućiti Košarica +{0} cannot be purchased using Shopping Cart,{0} ne može se kupiti pomoću Košarica +{0} is required,{0} je potrebno +{0} {1} has a common territory {2},{0} {1} ima zajednički teritorij {2} diff --git a/erpnext/translations/id.csv b/erpnext/translations/id.csv index dfd93cfdb7..025baa0250 100644 --- a/erpnext/translations/id.csv +++ b/erpnext/translations/id.csv @@ -3329,3 +3329,49 @@ website page link,tautan halaman situs web {0} {1} status is Unstopped,{0} {1} status unstopped {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Biaya Pusat adalah wajib untuk Item {2} {0}: {1} not found in Invoice Details table,{0}: {1} tidak ditemukan dalam Faktur Rincian table +"Add / Edit"," Add / Edit " +"Add / Edit"," Tambah / Edit " +Billed,Ditagih +Company,Perusahaan +Currency is required for Price List {0},Mata Uang diperlukan untuk Daftar Harga {0} +Default Customer Group,Bawaan Pelanggan Grup +Default Territory,Wilayah standar +Delivered,Disampaikan +Enable Shopping Cart,Aktifkan Keranjang Belanja +Go ahead and add something to your cart.,Pergi ke depan dan menambahkan sesuatu ke keranjang Anda. +Hey! Go ahead and add an address,Hei! Pergi ke depan dan menambahkan alamat +Invalid Billing Address,Alamat Penagihan valid +Invalid Shipping Address,Alamat Pengiriman valid +Missing Currency Exchange Rates for {0},Hilang Kurs mata uang Tarif untuk {0} +Name is required,Nama dibutuhkan +Not Allowed,Tidak Diizinkan +Paid,Terbayar +Partially Billed,Sebagian Ditagih +Partially Delivered,Sebagian Disampaikan +Please specify a Price List which is valid for Territory,Tentukan Daftar Harga yang berlaku untuk Wilayah +Please specify currency in Company,Silakan tentukan mata uang di Perusahaan +Please write something,Silahkan menulis sesuatu +Please write something in subject and message!,Silahkan menulis sesuatu dalam subjek dan pesan! +Price List,Daftar Harga +Price List not configured.,Daftar Harga belum dikonfigurasi. +Quotation Series,Quotation Series +Shipping Rule,Aturan Pengiriman +Shopping Cart,Daftar Belanja +Shopping Cart Price List,Daftar Belanja Daftar Harga +Shopping Cart Price Lists,Daftar Harga Daftar Belanja +Shopping Cart Settings,Pengaturan Keranjang Belanja +Shopping Cart Shipping Rule,Belanja Pengiriman Rule +Shopping Cart Shipping Rules,Daftar Belanja Pengiriman Aturan +Shopping Cart Taxes and Charges Master,Pajak Keranjang Belanja dan Biaya Guru +Shopping Cart Taxes and Charges Masters,Daftar Belanja Pajak dan Biaya Masters +Something went wrong!,Ada yang tidak beres! +Something went wrong.,Ada Sesuatu yang tidak beres. +Tax Master,Guru Pajak +To Pay,Untuk Bayar +Updated,Diperbarui +You are not allowed to reply to this ticket.,Anda tidak diizinkan untuk membalas tiket ini. +You need to be logged in to view your cart.,Anda harus login untuk melihat keranjang Anda. +You need to enable Shopping Cart,Anda harus mengaktifkan Keranjang Belanja +{0} cannot be purchased using Shopping Cart,{0} tidak dapat dibeli dengan menggunakan Keranjang Belanja +{0} is required,{0} diperlukan +{0} {1} has a common territory {2},{0} {1} memiliki wilayah umum {2} diff --git a/erpnext/translations/it.csv b/erpnext/translations/it.csv index 6ca5f9970c..f59fdd6df5 100644 --- a/erpnext/translations/it.csv +++ b/erpnext/translations/it.csv @@ -3329,3 +3329,49 @@ website page link,sito web link alla pagina {0} {1} status is Unstopped,{0} {1} stato è unstopped {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: centro di costo è obbligatoria per la voce {2} {0}: {1} not found in Invoice Details table,{0}: {1} non trovato in fattura tabella Dettagli +"Add / Edit"," Aggiungi / Modifica < / a>" +"Add / Edit"," Aggiungi / Modifica < / a>" +Billed,Addebbitato +Company,Azienda +Currency is required for Price List {0},È richiesto di valuta per il listino prezzi {0} +Default Customer Group,Gruppo Clienti Predefinito +Default Territory,Territorio Predefinito +Delivered,Consegnato +Enable Shopping Cart,Abilita Carello Acquisti +Go ahead and add something to your cart.,Vai avanti e aggiungere qualcosa al tuo carrello. +Hey! Go ahead and add an address,Ehi! Vai avanti e aggiungere un indirizzo +Invalid Billing Address,Valido indirizzo di fatturazione +Invalid Shipping Address,Valido Indirizzo di spedizione +Missing Currency Exchange Rates for {0},Manca valuta Tassi di cambio {0} +Name is required,Il nome è obbligatorio +Not Allowed,non sono ammessi +Paid,pagato +Partially Billed,parzialmente Fatturato +Partially Delivered,parzialmente Consegnato +Please specify a Price List which is valid for Territory,Si prega di specificare una lista di prezzi è valido per il Territorio +Please specify currency in Company,Si prega di specificare la valuta in Azienda +Please write something,Si prega di scrivere qualcosa +Please write something in subject and message!,Si prega di scrivere qualcosa in oggetto e il messaggio ! +Price List,Listino Prezzi +Price List not configured.,Prezzo di listino non è configurato. +Quotation Series,Serie Quotazione +Shipping Rule,Spedizione Rule +Shopping Cart,Carrello spesa +Shopping Cart Price List,Carrello Prezzo di listino +Shopping Cart Price Lists,Carrello Listini +Shopping Cart Settings,Carrello Impostazioni +Shopping Cart Shipping Rule,Carrello Spedizioni Rule +Shopping Cart Shipping Rules,Carrello Regole di Spedizione +Shopping Cart Taxes and Charges Master,Carrello Tasse e Spese master +Shopping Cart Taxes and Charges Masters,Carrello Tasse e Costi Masters +Something went wrong!,Qualcosa è andato storto! +Something went wrong.,Qualcosa è andato storto. +Tax Master,Tax Maestro +To Pay,To Pay +Updated,Aggiornato +You are not allowed to reply to this ticket.,Non sei autorizzato a rispondere a questo biglietto . +You need to be logged in to view your cart.,Devi essere loggato per vedere il tuo carrello. +You need to enable Shopping Cart,È necessario abilitare Carrello +{0} cannot be purchased using Shopping Cart,{0} non può essere acquistato tramite Carrello +{0} is required,{0} è richiesto +{0} {1} has a common territory {2},{0} {1} ha un territorio comune {2} diff --git a/erpnext/translations/ja.csv b/erpnext/translations/ja.csv index c779aa6fdc..e755a4a1ca 100644 --- a/erpnext/translations/ja.csv +++ b/erpnext/translations/ja.csv @@ -3335,3 +3335,49 @@ website page link,ウェブサイトのページリンク(ウェブサイト {0} {1} status is Unstopped,{0} {1}ステータスが塞がです {0} {1}: Cost Center is mandatory for Item {2},{0} {1}:コストセンターではアイテムのために必須である{2} {0}: {1} not found in Invoice Details table,{0}:{1}請求書詳細テーブルにない +"Add / Edit","もし、ごhref=""#Sales Browser/Customer Group"">追加/編集" +"Add / Edit","もし、ごhref=""#Sales Browser/Territory"">追加/編集" +Billed,課金 +Company,会社 +Currency is required for Price List {0},通貨は価格表{0}に必要です +Default Customer Group,デフォルトの顧客グループ +Default Territory,デフォルトの地域 +Delivered,配送 +Enable Shopping Cart,ショッピングカートを使用可能に +Go ahead and add something to your cart.,先に行くと、ショッピングカートに何かを追加。 +Hey! Go ahead and add an address,ハイ!先に行くとアドレスを追加 +Invalid Billing Address,無効な請求先住所 +Invalid Shipping Address,無効な配送先住所 +Missing Currency Exchange Rates for {0},{0}のために為替レートが不足して +Name is required,名前が必要です +Not Allowed,許可されていない +Paid,料金 +Partially Billed,部分的に銘打た +Partially Delivered,部分的に配信 +Please specify a Price List which is valid for Territory,地域で有効な価格表を指定してください +Please specify currency in Company,会社で通貨を指定してください +Please write something,何かを書いてください +Please write something in subject and message!,件名とメッセージで何かを書いてください! +Price List,価格リスト +Price List not configured.,価格表が構成されていません。 +Quotation Series,引用シリーズ +Shipping Rule,出荷ルール +Shopping Cart,カート +Shopping Cart Price List,ショッピングカート価格表 +Shopping Cart Price Lists,ショッピングカート価格表 +Shopping Cart Settings,ショッピングカートの設定 +Shopping Cart Shipping Rule,ショッピングカート配送ルール +Shopping Cart Shipping Rules,ショッピングカート配送ルール +Shopping Cart Taxes and Charges Master,ショッピングカートの税金、料金マスター +Shopping Cart Taxes and Charges Masters,ショッピングカートの税金、料金のマスターズ +Something went wrong!,何かが間違っていた! +Something went wrong.,エラーが発生しました。 +Tax Master,税金のマスター +To Pay,支払わなければ +Updated,更新日 +You are not allowed to reply to this ticket.,あなたは、このチケットに返信することはできません。 +You need to be logged in to view your cart.,あなたは買い物カゴを見るためにログインする必要があります。 +You need to enable Shopping Cart,あなたはショッピングカートを有効にする必要があります +{0} cannot be purchased using Shopping Cart,{0}ショッピングカートを使用して購入することはできません +{0} is required,{0}が必要である +{0} {1} has a common territory {2},{0} {1}は、共通の領土を持っている{2} diff --git a/erpnext/translations/kn.csv b/erpnext/translations/kn.csv index 8dae972f15..f01e48adfd 100644 --- a/erpnext/translations/kn.csv +++ b/erpnext/translations/kn.csv @@ -3329,3 +3329,49 @@ website page link,ವೆಬ್ಸೈಟ್ ಪುಟ ಲಿಂಕ್ {0} {1} status is Unstopped,{0} {1} ಸ್ಥಿತಿಯನ್ನು unstopped ಆಗಿದೆ {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: ವೆಚ್ಚ ಸೆಂಟರ್ ಐಟಂ ಕಡ್ಡಾಯ {2} {0}: {1} not found in Invoice Details table,{0}: {1} ಸರಕುಪಟ್ಟಿ ವಿವರಗಳು ಟೇಬಲ್ ಕಂಡುಬಂದಿಲ್ಲ +"Add / Edit","ಕವಿದ href=""#Sales Browser/Customer Group""> ಸೇರಿಸಿ / ಸಂಪಾದಿಸಿ " +"Add / Edit","ಕವಿದ href=""#Sales Browser/Territory""> ಸೇರಿಸಿ / ಸಂಪಾದಿಸಿ " +Billed,ಖ್ಯಾತವಾದ +Company,ಕಂಪನಿ +Currency is required for Price List {0},ಕರೆನ್ಸಿ ಬೆಲೆ ಪಟ್ಟಿ ಅಗತ್ಯವಿದೆ {0} +Default Customer Group,ಡೀಫಾಲ್ಟ್ ಗ್ರಾಹಕ ಗುಂಪಿನ +Default Territory,ಡೀಫಾಲ್ಟ್ ಪ್ರದೇಶ +Delivered,ತಲುಪಿಸಲಾಗಿದೆ +Enable Shopping Cart,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಸಕ್ರಿಯಗೊಳಿಸಿ +Go ahead and add something to your cart.,ಮುಂದೆ ಹೋಗಿ ಮತ್ತು ನಿಮ್ಮ ಕಾರ್ಟ್ ಏನಾದರೂ ಸೇರಿಸಿ. +Hey! Go ahead and add an address,ಹೇ! ಮುಂದೆ ಹೋಗಿ ಒಂದು ಸೇರಿಸಿ +Invalid Billing Address,ಅಮಾನ್ಯವಾದ ಬಿಲ್ಲಿಂಗ್ ವಿಳಾಸ +Invalid Shipping Address,ಅಮಾನ್ಯವಾದ ಶಿಪ್ಪಿಂಗ್ ವಿಳಾಸ +Missing Currency Exchange Rates for {0},ಕರೆನ್ಸಿ ವಿನಿಮಯ ದರಗಳು ಮಿಸ್ಸಿಂಗ್ {0} +Name is required,ಹೆಸರು ಅಗತ್ಯವಿದೆ +Not Allowed,ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ +Paid,ಪಾವತಿಸಿದ +Partially Billed,ಭಾಗಶಃ ಖ್ಯಾತವಾದ +Partially Delivered,ಭಾಗಶಃ ತಲುಪಿಸಲಾಗಿದೆ +Please specify a Price List which is valid for Territory,ಪ್ರದೇಶ ಮಾನ್ಯ ಬೆಲೆ ಪಟ್ಟಿ ಸೂಚಿಸಲು ದಯವಿಟ್ಟು +Please specify currency in Company,ಕಂಪನಿ ಕರೆನ್ಸಿ ಸೂಚಿಸಲು ದಯವಿಟ್ಟು +Please write something,ಏನೋ ಬರೆಯಲು ಮಾಡಿ +Please write something in subject and message!,ವಿಷಯ ಮತ್ತು ಸಂದೇಶದ ಏನೋ ಬರೆಯಲು ಮಾಡಿ ! +Price List,ಬೆಲೆ ಪಟ್ಟಿ +Price List not configured.,ಬೆಲೆ ಪಟ್ಟಿ ಕಾನ್ಫಿಗರ್. +Quotation Series,ನುಡಿಮುತ್ತುಗಳು ಸರಣಿ +Shipping Rule,ಶಿಪ್ಪಿಂಗ್ ರೂಲ್ +Shopping Cart,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ +Shopping Cart Price List,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಬೆಲೆ ಪಟ್ಟಿ +Shopping Cart Price Lists,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಬೆಲೆ ಪಟ್ಟಿ +Shopping Cart Settings,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಸೆಟ್ಟಿಂಗ್ಗಳು +Shopping Cart Shipping Rule,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಶಿಪ್ಪಿಂಗ್ ರೂಲ್ +Shopping Cart Shipping Rules,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಶಿಪ್ಪಿಂಗ್ ನಿಯಮಗಳು +Shopping Cart Taxes and Charges Master,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ತೆರಿಗೆಗಳು ಮತ್ತು ಶುಲ್ಕಗಳು ಮಾಸ್ಟರ್ +Shopping Cart Taxes and Charges Masters,ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ತೆರಿಗೆಗಳು ಮತ್ತು ಶುಲ್ಕಗಳು ಮಾಸ್ಟರ್ಸ್ +Something went wrong!,ಏನೋ ತಪ್ಪಾಗಿದೆ! +Something went wrong.,ಯಾವುದೋ ತಪ್ಪು ಸಂಭವಿಸಿದೆ. +Tax Master,ತೆರಿಗೆ ಮಾಸ್ಟರ್ +To Pay,ಪಾವತಿಸಲು +Updated,ನವೀಕರಿಸಲಾಗಿದೆ +You are not allowed to reply to this ticket.,ಈ ಟಿಕೆಟ್ ಪ್ರತ್ಯುತ್ತರ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ. +You need to be logged in to view your cart.,ನಿಮ್ಮ ಕಾರ್ಟ್ ಲಾಗಿನ್ ಅಗತ್ಯವಿದೆ. +You need to enable Shopping Cart,ನೀವು ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಸಕ್ರಿಯಗೊಳಿಸಬೇಕು +{0} cannot be purchased using Shopping Cart,{0} ಶಾಪಿಂಗ್ ಕಾರ್ಟ್ ಬಳಸಿ ಕೊಳ್ಳಬಹುದು ಸಾಧ್ಯವಿಲ್ಲ +{0} is required,{0} ಅಗತ್ಯವಿದೆ +{0} {1} has a common territory {2},{0} {1} ಸಾಮಾನ್ಯ ಪ್ರದೇಶವನ್ನು ಹೊಂದಿದೆ {2} diff --git a/erpnext/translations/ko.csv b/erpnext/translations/ko.csv index 34e7a44e24..4a7ea61d62 100644 --- a/erpnext/translations/ko.csv +++ b/erpnext/translations/ko.csv @@ -3329,3 +3329,49 @@ website page link,웹 사이트 페이지 링크 {0} {1} status is Unstopped,{0} {1} 상태 Unstopped입니다 {0} {1}: Cost Center is mandatory for Item {2},{0} {1} : 코스트 센터는 항목에 대해 필수입니다 {2} {0}: {1} not found in Invoice Details table,{0} {1} 송장 정보 테이블에서 찾을 수 없습니다 +"Add / Edit","만약 당신이 좋아 href=""#Sales Browser/Customer Group""> 추가 / 편집 " +"Add / Edit","만약 당신이 좋아 href=""#Sales Browser/Territory""> 추가 / 편집 " +Billed,청구 +Company,회사 +Currency is required for Price List {0},환율은 가격 목록에 필요한 {0} +Default Customer Group,기본 고객 그룹 +Default Territory,기본 지역 +Delivered,배달 +Enable Shopping Cart,쇼핑 카트를 사용 +Go ahead and add something to your cart.,가서 당신의 손수레로 뭔가를 추가 할 수 있습니다. +Hey! Go ahead and add an address,야!가서 주소를 추가 +Invalid Billing Address,잘못된 청구 주소 +Invalid Shipping Address,잘못된 배송 주소 +Missing Currency Exchange Rates for {0},를 위해 환율 누락 {0} +Name is required,이름이 필요합니다 +Not Allowed,허용하지 않음 +Paid,유료 +Partially Billed,일부 청구 +Partially Delivered,부분적으로 배달 +Please specify a Price List which is valid for Territory,지역에 유효한 가격 목록을 지정하십시오 +Please specify currency in Company,회사에 통화를 지정하십시오 +Please write something,뭔가를 작성 해주세요 +Please write something in subject and message!,제목과 메시지에 무언가를 써주세요! +Price List,가격리스트 +Price List not configured.,가격 목록이 구성되어 있지. +Quotation Series,견적 시리즈 +Shipping Rule,배송 규칙 +Shopping Cart,쇼핑 카트 +Shopping Cart Price List,쇼핑 카트의 가격 목록 +Shopping Cart Price Lists,쇼핑 카트의 가격 목록 +Shopping Cart Settings,쇼핑 카트 설정 +Shopping Cart Shipping Rule,장바구니 배송 규칙 +Shopping Cart Shipping Rules,장바구니 배송 규칙 +Shopping Cart Taxes and Charges Master,쇼핑 카트 세금과 요금 마스터 +Shopping Cart Taxes and Charges Masters,쇼핑 카트 세금과 요금의 석사 +Something went wrong!,문제가 발생했습니다! +Something went wrong.,문제가 발생했습니다. +Tax Master,세금 마스터 +To Pay,지불하는 +Updated,업데이트 +You are not allowed to reply to this ticket.,당신이 티켓에 회신 할 수 없습니다. +You need to be logged in to view your cart.,당신은 당신의 카트를 보려면 로그인해야합니다. +You need to enable Shopping Cart,당신은 쇼핑 카트를 활성화해야 +{0} cannot be purchased using Shopping Cart,{0} 쇼핑 카트를 사용하여 구입 할 수 없습니다 +{0} is required,{0}이 필요합니다 +{0} {1} has a common territory {2},{0} {1} 공통의 영토가 {2} diff --git a/erpnext/translations/nl.csv b/erpnext/translations/nl.csv index f8bc9875bf..94cab1d853 100644 --- a/erpnext/translations/nl.csv +++ b/erpnext/translations/nl.csv @@ -3329,3 +3329,49 @@ website page link,website Paginalink {0} {1} status is Unstopped,{0} {1} status ontsloten {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: kostenplaats is verplicht voor Item {2} {0}: {1} not found in Invoice Details table,{0}: {1} niet gevonden in Factuur Details tabel +"Add / Edit"," toevoegen / bewerken < / a>" +"Add / Edit"," toevoegen / bewerken < / a>" +Billed,Gefactureerd +Company,Vennootschap +Currency is required for Price List {0},Valuta is vereist voor prijslijst {0} +Default Customer Group,Standaard Klant Groep +Default Territory,Standaard Territory +Delivered,Geleverd +Enable Shopping Cart,Enable Winkelwagen +Go ahead and add something to your cart.,Ga je gang en iets toe te voegen aan uw winkelwagen. +Hey! Go ahead and add an address,Hé! Ga je gang en voeg een adres +Invalid Billing Address,Ongeldig Factuuradres +Invalid Shipping Address,Ongeldig verzendadres +Missing Currency Exchange Rates for {0},Ontbrekende wisselkoersen gedurende {0} +Name is required,Naam is vereist +Not Allowed,niet toegestaan +Paid,betaald +Partially Billed,gedeeltelijk gefactureerde +Partially Delivered,gedeeltelijk Geleverd +Please specify a Price List which is valid for Territory,Geef een prijslijst die geldig is voor het grondgebied +Please specify currency in Company,Specificeer munt in Bedrijf +Please write something,Iets schrijven aub +Please write something in subject and message!,Schrijf iets in het onderwerp en een bericht ! +Price List,Prijslijst +Price List not configured.,Prijslijst niet geconfigureerd. +Quotation Series,Offerte Series +Shipping Rule,Verzending Rule +Shopping Cart,Winkelwagen +Shopping Cart Price List,Winkelwagen Prijslijst +Shopping Cart Price Lists,Winkelwagen Prijslijsten +Shopping Cart Settings,Winkelwagen Instellingen +Shopping Cart Shipping Rule,Winkelwagen Scheepvaart Rule +Shopping Cart Shipping Rules,Winkelwagen Scheepvaart Regels +Shopping Cart Taxes and Charges Master,Winkelwagen en-heffingen Master +Shopping Cart Taxes and Charges Masters,Winkelwagen en-heffingen Masters +Something went wrong!,Er ging iets mis! +Something went wrong.,Er is iets fout gegaan +Tax Master,Fiscale Master +To Pay,te betalen +Updated,Bijgewerkt +You are not allowed to reply to this ticket.,Het is niet toegestaan ​​om te reageren op dit kaartje . +You need to be logged in to view your cart.,Je moet ingelogd zijn om uw winkelwagentje te bekijken. +You need to enable Shopping Cart,U moet Winkelwagen stellen +{0} cannot be purchased using Shopping Cart,{0} kan niet worden aangeschaft met Winkelwagen +{0} is required,{0} is verplicht +{0} {1} has a common territory {2},{0} {1} heeft een gemeenschappelijk grondgebied {2} diff --git a/erpnext/translations/pt-BR.csv b/erpnext/translations/pt-BR.csv index df558c57e7..77968420af 100644 --- a/erpnext/translations/pt-BR.csv +++ b/erpnext/translations/pt-BR.csv @@ -3377,3 +3377,49 @@ website page link,link da página do site {0} {1} status is Unstopped,{0} {1} status é abrirão {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Centro de Custo é obrigatória para item {2} {0}: {1} not found in Invoice Details table,{0}: {1} não foi encontrado na fatura Detalhes Mesa +"Add / Edit"," Adicionar / Editar " +"Add / Edit"," Adicionar / Editar " +Billed,Faturado +Company,Empresa +Currency is required for Price List {0},Moeda é necessário para Preço de {0} +Default Customer Group,Grupo de Clientes padrão +Default Territory,Território padrão +Delivered,Entregue +Enable Shopping Cart,Ativar Carrinho de Compras +Go ahead and add something to your cart.,Vá em frente e acrescentar algo ao seu carrinho. +Hey! Go ahead and add an address,Ei! Vá em frente e adicionar um endereço +Invalid Billing Address,Inválido Endereço de Cobrança +Invalid Shipping Address,Inválido envio Endereço +Missing Currency Exchange Rates for {0},Falta de câmbio de moeda para {0} +Name is required,Nome é obrigatório +Not Allowed,não Permitido +Paid,pago +Partially Billed,parcialmente faturado +Partially Delivered,parcialmente entregues +Please specify a Price List which is valid for Territory,"Por favor, especifique uma lista de preços que é válido para o território" +Please specify currency in Company,"Por favor, especificar a moeda em Empresa" +Please write something,"Por favor, escreva algo" +Please write something in subject and message!,"Por favor, escreva algo no assunto e uma mensagem !" +Price List,Lista de Preços +Price List not configured.,Lista de Preço não configurado. +Quotation Series,Série citação +Shipping Rule,Regra de envio +Shopping Cart,Carrinho de Compras +Shopping Cart Price List,Carrinho de Compras Lista de Preços +Shopping Cart Price Lists,Carrinho listas de preços +Shopping Cart Settings,Carrinho Configurações +Shopping Cart Shipping Rule,Carrinho de Compras Rule envio +Shopping Cart Shipping Rules,Carrinho Regras frete +Shopping Cart Taxes and Charges Master,Carrinho impostos e taxas Mestre +Shopping Cart Taxes and Charges Masters,Carrinho Impostos e Taxas de mestrado +Something went wrong!,Algo deu errado! +Something went wrong.,Algo deu errado. +Tax Master,Imposto de Mestre +To Pay,pagar +Updated,Atualizado +You are not allowed to reply to this ticket.,Você não tem permissão para responder a este bilhete . +You need to be logged in to view your cart.,Você precisa estar logado para ver seu carrinho. +You need to enable Shopping Cart,Você precisa habilitar o Carrinho de Compras +{0} cannot be purchased using Shopping Cart,{0} não pode ser comprado usando Carrinho de Compras +{0} is required,{0} é necessária +{0} {1} has a common territory {2},{0} {1} tem um território comum {2} diff --git a/erpnext/translations/pt.csv b/erpnext/translations/pt.csv index 18c46175a7..b4d9bd6937 100644 --- a/erpnext/translations/pt.csv +++ b/erpnext/translations/pt.csv @@ -3329,3 +3329,49 @@ website page link,link da página site {0} {1} status is Unstopped,{0} {1} status é abrirão {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Centro de Custo é obrigatória para item {2} {0}: {1} not found in Invoice Details table,{0}: {1} não foi encontrado na fatura Detalhes Mesa +"Add / Edit"," toevoegen / bewerken < / a>" +"Add / Edit"," toevoegen / bewerken < / a>" +Billed,Faturado +Company,Companhia +Currency is required for Price List {0},Moeda é necessário para Preço de {0} +Default Customer Group,Grupo de Clientes padrão +Default Territory,Território padrão +Delivered,Entregue +Enable Shopping Cart,Ativar Carrinho de Compras +Go ahead and add something to your cart.,Vá em frente e acrescentar algo ao seu carrinho. +Hey! Go ahead and add an address,Ei! Vá em frente e adicionar um endereço +Invalid Billing Address,Inválido Endereço de Cobrança +Invalid Shipping Address,Inválido envio Endereço +Missing Currency Exchange Rates for {0},Falta de câmbio de moeda para {0} +Name is required,Nome é obrigatório +Not Allowed,não Permitido +Paid,betaald +Partially Billed,gedeeltelijk gefactureerde +Partially Delivered,gedeeltelijk Geleverd +Please specify a Price List which is valid for Territory,"Por favor, especifique uma lista de preços que é válido para o território" +Please specify currency in Company,"Por favor, especificar a moeda em Empresa" +Please write something,Iets schrijven aub +Please write something in subject and message!,Schrijf iets in het onderwerp en een bericht ! +Price List,Lista de Preços +Price List not configured.,Lista de Preço não configurado. +Quotation Series,Série citação +Shipping Rule,Regra de envio +Shopping Cart,Carrinho de Compras +Shopping Cart Price List,Carrinho de Compras Lista de Preços +Shopping Cart Price Lists,Carrinho listas de preços +Shopping Cart Settings,Carrinho Configurações +Shopping Cart Shipping Rule,Carrinho de Compras Rule envio +Shopping Cart Shipping Rules,Carrinho Regras frete +Shopping Cart Taxes and Charges Master,Carrinho impostos e taxas Mestre +Shopping Cart Taxes and Charges Masters,Carrinho Impostos e Taxas de mestrado +Something went wrong!,Algo deu errado! +Something went wrong.,Algo deu errado. +Tax Master,Imposto de Mestre +To Pay,te betalen +Updated,Atualizado +You are not allowed to reply to this ticket.,Het is niet toegestaan ​​om te reageren op dit kaartje . +You need to be logged in to view your cart.,Você precisa estar logado para ver seu carrinho. +You need to enable Shopping Cart,Você precisa habilitar o Carrinho de Compras +{0} cannot be purchased using Shopping Cart,{0} não pode ser comprado usando Carrinho de Compras +{0} is required,{0} é necessária +{0} {1} has a common territory {2},{0} {1} tem um território comum {2} diff --git a/erpnext/translations/ro.csv b/erpnext/translations/ro.csv index fc6d6ce9ed..a5aa7c43cb 100644 --- a/erpnext/translations/ro.csv +++ b/erpnext/translations/ro.csv @@ -3329,3 +3329,49 @@ website page link,pagina site-ului link-ul {0} {1} status is Unstopped,{0} {1} statut este destupate {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Cost Center este obligatorie pentru postul {2} {0}: {1} not found in Invoice Details table,{0}: {1} nu a fost găsit în factură Detalii masă +"Add / Edit"," Add / Edit " +"Add / Edit"," Add / Edit " +Billed,Facturat +Company,Firma +Currency is required for Price List {0},Monedă este necesară pentru lista de prețuri {0} +Default Customer Group,Implicit Client Group +Default Territory,Implicit Teritoriul +Delivered,Livrat +Enable Shopping Cart,Activați Cosul de cumparaturi +Go ahead and add something to your cart.,Du-te și adaugă ceva la coș. +Hey! Go ahead and add an address,Hei! Du-te și adăugați o adresă +Invalid Billing Address,Adresa de facturare invalid +Invalid Shipping Address,Adresa Transport invalid +Missing Currency Exchange Rates for {0},Lipsește valutar Curs valutar pentru {0} +Name is required,Este necesar numele +Not Allowed,Nu este permis +Paid,Platit +Partially Billed,Parțial Taxat +Partially Delivered,Parțial livrate +Please specify a Price List which is valid for Territory,"Vă rugăm să specificați o listă de prețuri, care este valabil pentru teritoriul" +Please specify currency in Company,Vă rugăm să specificați în valută de companie +Please write something,Vă rugăm să scrieți ceva +Please write something in subject and message!,Vă rugăm să scrieți ceva în subiect și un mesaj! +Price List,Lista de prețuri +Price List not configured.,Lista de prețuri nu a fost configurat. +Quotation Series,Citat Series +Shipping Rule,Regula de transport maritim +Shopping Cart,Cosul de cumparaturi +Shopping Cart Price List,Cosul de cumparaturi Lista de prețuri +Shopping Cart Price Lists,Cosul de cumparaturi Liste de prețuri +Shopping Cart Settings,Setări Cosul de cumparaturi +Shopping Cart Shipping Rule,Cosul de cumparaturi Regula Transport +Shopping Cart Shipping Rules,Cosul de cumparaturi Reguli de expediere +Shopping Cart Taxes and Charges Master,Taxele coș de cumpărături și taxe de Master +Shopping Cart Taxes and Charges Masters,Cumpărături Impozite și taxe cos Masters +Something went wrong!,Ceva a mers prost! +Something went wrong.,Ceva nu a funcționat. +Tax Master,Taxa de Master +To Pay,Pentru a Pay +Updated,Actualizat +You are not allowed to reply to this ticket.,Nu vi se permite să răspundeți la acest bilet. +You need to be logged in to view your cart.,Ai nevoie să fii logat pentru a vedea cosul de cumparaturi. +You need to enable Shopping Cart,Ai nevoie pentru a permite Cosul de cumparaturi +{0} cannot be purchased using Shopping Cart,{0} nu pot fi achiziționate cu ajutorul Cosul de cumparaturi +{0} is required,{0} este necesară +{0} {1} has a common territory {2},{0} {1} are un teritoriu comun {2} diff --git a/erpnext/translations/ru.csv b/erpnext/translations/ru.csv index 09d409e0b6..d79039c428 100644 --- a/erpnext/translations/ru.csv +++ b/erpnext/translations/ru.csv @@ -3332,3 +3332,49 @@ website page link,сайт ссылку {0} {1} status is Unstopped,{0} {1} статус отверзутся {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: МВЗ является обязательным для п. {2} {0}: {1} not found in Invoice Details table,{0} {1} не найден в счете-фактуре таблице +"Add / Edit"," Добавить / Изменить " +"Add / Edit"," Добавить / Изменить " +Billed,Объявленный +Company,Организация +Currency is required for Price List {0},Валюта необходима для Прейскурантом {0} +Default Customer Group,По умолчанию Группа клиентов +Default Territory,По умолчанию Территория +Delivered,Доставлено +Enable Shopping Cart,Включить Корзина +Go ahead and add something to your cart.,Идем дальше и добавить что-то в корзину. +Hey! Go ahead and add an address,16.35 Эй! Идем дальше и добавить адрес +Invalid Billing Address,Неверный Адрес для выставления счета +Invalid Shipping Address,Неверный адрес пересылки +Missing Currency Exchange Rates for {0},Отсутствует валютный курс для {0} +Name is required,Имя обязательно +Not Allowed,Не разрешены +Paid,Оплачено +Partially Billed,Частично Объявленный +Partially Delivered,Частично Поставляются +Please specify a Price List which is valid for Territory,"Пожалуйста, сформулируйте прайс-лист, который действителен для территории" +Please specify currency in Company,"Пожалуйста, сформулируйте валюту в компании" +Please write something,"Пожалуйста, напишите что-нибудь" +Please write something in subject and message!,"Пожалуйста, напишите что-нибудь в тему и текст сообщения!" +Price List,Прайс-лист +Price List not configured.,Прайс-лист не настроен. +Quotation Series,Цитата серии +Shipping Rule,Правило Доставка +Shopping Cart,Корзина +Shopping Cart Price List,Корзина Прайс-лист +Shopping Cart Price Lists,Корзина Прайс-листы +Shopping Cart Settings,Корзина Настройки +Shopping Cart Shipping Rule,Корзина Правило Доставка +Shopping Cart Shipping Rules,Корзина Правила Доставка +Shopping Cart Taxes and Charges Master,Корзина Налоги и сборы Мастер +Shopping Cart Taxes and Charges Masters,Налоги Корзина Торговые и сборы Мастера +Something went wrong!,Что-то пошло не так! +Something went wrong.,Что-то пошло не так. +Tax Master,Налоговый Мастер +To Pay,Платить +Updated,Обновлено +You are not allowed to reply to this ticket.,Вы не можете отвечать на этот билет. +You need to be logged in to view your cart.,"Вы должны войти в систему, чтобы просмотреть свою корзину." +You need to enable Shopping Cart,Вам необходимо включить Корзина +{0} cannot be purchased using Shopping Cart,{0} не может быть приобретен с помощью Корзина +{0} is required,{0} требуется +{0} {1} has a common territory {2},{0} {1} имеет общую территорию {2} diff --git a/erpnext/translations/sr.csv b/erpnext/translations/sr.csv index 8ff80e0bf0..8a84ef7b33 100644 --- a/erpnext/translations/sr.csv +++ b/erpnext/translations/sr.csv @@ -3329,3 +3329,49 @@ website page link,веб страница веза {0} {1} status is Unstopped,{0} {1} статус отверзутся {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Трошкови Центар је обавезан за пункт {2} {0}: {1} not found in Invoice Details table,{0}: {1} није пронађен у табели Фактура Детаљи +"Add / Edit","<а хреф=""#Салес Бровсер/Цустомер Гроуп""> Додај / Уреди < />" +"Add / Edit","<а хреф=""#Салес Бровсер/Территори""> Додај / Уреди < />" +Billed,Изграђена +Company,Компанија +Currency is required for Price List {0},Валюта необходима для Прейскурантом {0} +Default Customer Group,Уобичајено групу потрошача +Default Territory,Уобичајено Територија +Delivered,Испоручено +Enable Shopping Cart,Омогући Корпа +Go ahead and add something to your cart.,Само напред и додати нешто у вашој корпи. +Hey! Go ahead and add an address,Хеј! Само напред и додај адресу +Invalid Billing Address,Неверный Адрес для выставления счета +Invalid Shipping Address,Неверный адрес пересылки +Missing Currency Exchange Rates for {0},Отсутствует валютный курс для {0} +Name is required,Име је обавезно +Not Allowed,Не разрешены +Paid,плаћен +Partially Billed,Делимично Изграђена +Partially Delivered,Делимично Испоручено +Please specify a Price List which is valid for Territory,Наведите ценовник који важи за територију +Please specify currency in Company,Наведите валуту у компанији +Please write something,Молимо вас да напишете нешто +Please write something in subject and message!,Молимо вас да напишете нешто у теми и поруци ! +Price List,Ценовник +Price List not configured.,Ценовник није подесио. +Quotation Series,Цитат серија +Shipping Rule,Достава Правило +Shopping Cart,Корпа +Shopping Cart Price List,Корпа Ценовник +Shopping Cart Price Lists,Корпа Ценовници +Shopping Cart Settings,Корпа Подешавања +Shopping Cart Shipping Rule,Корпа Достава Правило +Shopping Cart Shipping Rules,Корпа испоруке Правила +Shopping Cart Taxes and Charges Master,Корпа такси и накнада Мастер +Shopping Cart Taxes and Charges Masters,Корпа такси и накнада Мастерс +Something went wrong!,Нешто је пошло наопако! +Something went wrong.,Нешто је пошло наопако. +Tax Master,Пореска Мастер +To Pay,То Паи +Updated,Ажурирано +You are not allowed to reply to this ticket.,Нисте дозвољено да одговори на ову карту . +You need to be logged in to view your cart.,Морате бити пријављени да бисте видели вашу корпу. +You need to enable Shopping Cart,Вам необходимо включить Корзина +{0} cannot be purchased using Shopping Cart,{0} не может быть приобретен с помощью Корзина +{0} is required,{0} требуется +{0} {1} has a common territory {2},{0} {1} имеет общую территорию {2} diff --git a/erpnext/translations/ta.csv b/erpnext/translations/ta.csv index c32864bbd6..7717a7f8d6 100644 --- a/erpnext/translations/ta.csv +++ b/erpnext/translations/ta.csv @@ -3329,3 +3329,49 @@ website page link,இணைய பக்கம் இணைப்பு {0} {1} status is Unstopped,{0} {1} நிலையை ஐபோனில் இருக்கிறது {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: செலவு மையம் பொருள் கட்டாய {2} {0}: {1} not found in Invoice Details table,{0} {1} விலைப்பட்டியல் விவரம் அட்டவணையில் இல்லை +"Add / Edit","மிக href=""#Sales Browser/Customer Group""> சேர் / திருத்து " +"Add / Edit","மிக href=""#Sales Browser/Territory""> சேர் / திருத்து " +Billed,கட்டணம் +Company,நிறுவனம் +Currency is required for Price List {0},நாணய விலை பட்டியல் தேவை {0} +Default Customer Group,முன்னிருப்பு வாடிக்கையாளர் பிரிவு +Default Territory,முன்னிருப்பு மண்டலம் +Delivered,வழங்கினார் +Enable Shopping Cart,வணிக வண்டியில் செயல்படுத்த +Go ahead and add something to your cart.,முன்னோக்கி சென்று உங்கள் வண்டி ஒன்று சேர்க்க. +Hey! Go ahead and add an address,ஏய்! போய் ஒரு முகவரியை சேர்க்க +Invalid Billing Address,தவறான பில்லிங் முகவரி +Invalid Shipping Address,செல்லாத கப்பல் முகவரி +Missing Currency Exchange Rates for {0},ஐந்து நாணய மாற்று விகிதங்கள் காணவில்லை {0} +Name is required,பெயர் தேவை +Not Allowed,அனுமதி இல்லை +Paid,பணம் +Partially Billed,பகுதி கூறப்படுவது +Partially Delivered,பகுதியளவு வழங்கப்படுகிறது +Please specify a Price List which is valid for Territory,மண்டலம் செல்லுபடியாகும் ஒரு விலை பட்டியல் குறிப்பிடவும் +Please specify currency in Company,நிறுவனத்தின் நாணய குறிப்பிடவும் +Please write something,ஏதாவது எழுத கொள்ளவும் +Please write something in subject and message!,பொருள் மற்றும் செய்தி ஏதாவது எழுத கொள்ளவும் ! +Price List,விலை பட்டியல் +Price List not configured.,விலை பட்டியல் கட்டமைக்கப்பட்ட. +Quotation Series,மேற்கோள் தொடர் +Shipping Rule,கப்பல் விதி +Shopping Cart,வணிக வண்டி +Shopping Cart Price List,வணிக வண்டியில் விலை பட்டியல் +Shopping Cart Price Lists,வணிக வண்டியில் விலை பட்டியல்கள் +Shopping Cart Settings,வணிக வண்டியில் அமைப்புகள் +Shopping Cart Shipping Rule,வணிக வண்டியில் கப்பல் போக்குவரத்து விதி +Shopping Cart Shipping Rules,வணிக வண்டியில் கப்பல் போக்குவரத்து விதிகள் +Shopping Cart Taxes and Charges Master,வணிக வண்டியில் வரிகள் மற்றும் கட்டணங்கள் மாஸ்டர் +Shopping Cart Taxes and Charges Masters,வணிக வண்டியில் வரிகள் மற்றும் கட்டணங்கள் முதுநிலை +Something went wrong!,ஏதோ தவறு! +Something went wrong.,ஏதோ தவறு நடந்துவிட்டது. +Tax Master,வரி மாஸ்டர் +To Pay,பணம் +Updated,புதுப்பிக்கப்பட்ட +You are not allowed to reply to this ticket.,இந்த டிக்கெட் பதில் அனுமதி இல்லை . +You need to be logged in to view your cart.,உங்கள் வண்டி பார்வையிட உள்நுழைந்திருக்க வேண்டும். +You need to enable Shopping Cart,வணிக வண்டியில் செயல்படுத்த வேண்டும் +{0} cannot be purchased using Shopping Cart,{0} வணிக வண்டியில் பயன்படுத்தி வாங்க முடியாது +{0} is required,{0} தேவைப்படுகிறது +{0} {1} has a common territory {2},{0} {1} ஒரு பொதுவான பகுதியில் உள்ளது {2} diff --git a/erpnext/translations/th.csv b/erpnext/translations/th.csv index 8043ecaa12..7f59ef74a3 100644 --- a/erpnext/translations/th.csv +++ b/erpnext/translations/th.csv @@ -3329,3 +3329,49 @@ website page link,การเชื่อมโยงหน้าเว็บ {0} {1} status is Unstopped,{0} {1} สถานะ เบิก {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: ศูนย์ต้นทุนจำเป็นสำหรับรายการ {2} {0}: {1} not found in Invoice Details table,{0}: {1} ไม่พบในตารางรายละเอียดใบแจ้งหนี้ +"Add / Edit"," เพิ่ม / แก้ไข " +"Add / Edit"," เพิ่ม / แก้ไข " +Billed,เรียกเก็บเงิน +Company,บริษัท +Currency is required for Price List {0},สกุลเงิน เป็นสิ่งจำเป็นสำหรับ ราคาตามรายการ {0} +Default Customer Group,กลุ่มลูกค้าเริ่มต้น +Default Territory,ดินแดนเริ่มต้น +Delivered,ส่ง +Enable Shopping Cart,เปิดใช้งานรถเข็น +Go ahead and add something to your cart.,ไปข้างหน้าและเพิ่มสิ่งที่รถเข็นของคุณ +Hey! Go ahead and add an address,นี่ ไปข้างหน้าและเพิ่มที่อยู่ +Invalid Billing Address,ที่อยู่ การเรียกเก็บเงิน ไม่ถูกต้อง +Invalid Shipping Address,ที่อยู่ ในการจัดส่ง ที่ไม่ถูกต้อง +Missing Currency Exchange Rates for {0},หายไป สกุลเงิน อัตราแลกเปลี่ยน เพื่อ {0} +Name is required,ชื่อจะต้อง +Not Allowed,ไม่อนุญาตให้ +Paid,ต้องจ่าย +Partially Billed,ในจำนวน บางส่วน +Partially Delivered,ส่ง บางส่วน +Please specify a Price List which is valid for Territory,โปรดระบุรายชื่อราคาที่ถูกต้องสำหรับดินแดน +Please specify currency in Company,โปรดระบุสกุลเงินใน บริษัท +Please write something,กรุณาเขียน บางสิ่งบางอย่าง +Please write something in subject and message!,กรุณาเขียน อะไรบางอย่างใน เรื่อง และ ข้อความ ! +Price List,บัญชีแจ้งราคาสินค้า +Price List not configured.,ราคาไม่ได้กำหนดค่า +Quotation Series,ชุดใบเสนอราคา +Shipping Rule,กฎการจัดส่งสินค้า +Shopping Cart,รถเข็นช้อปปิ้ง +Shopping Cart Price List,รายการสินค้าราคาสินค้าในรถเข็น +Shopping Cart Price Lists,ช้อปปิ้งสินค้าราคา Lists +Shopping Cart Settings,การตั้งค่ารถเข็น +Shopping Cart Shipping Rule,ช้อปปิ้งรถเข็นกฎการจัดส่งสินค้า +Shopping Cart Shipping Rules,รถเข็นกฎการจัดส่งสินค้า +Shopping Cart Taxes and Charges Master,ภาษีรถเข็นและปริญญาโทค่าใช้จ่าย +Shopping Cart Taxes and Charges Masters,ภาษีรถเข็นช้อปปิ้งและปริญญาโทค่าใช้จ่าย +Something went wrong!,สิ่งที่ผิดพลาด! +Something went wrong.,สิ่งที่ผิดพลาด +Tax Master,ปริญญาโทภาษี +To Pay,การชำระเงิน +Updated,อัพเดต +You are not allowed to reply to this ticket.,คุณยังไม่ได้ รับอนุญาตให้ ตอบกลับ ตั๋ว นี้ +You need to be logged in to view your cart.,คุณต้องเข้าสู่ระบบเพื่อดูรถเข็นของคุณ +You need to enable Shopping Cart,คุณต้อง เปิดการใช้งาน รถเข็น +{0} cannot be purchased using Shopping Cart,{0} ไม่สามารถ ซื้อโดยใช้ รถเข็น +{0} is required,{0} จะต้อง +{0} {1} has a common territory {2},{0} {1} มีดินแดน ที่พบบ่อย {2} diff --git a/erpnext/translations/tr.csv b/erpnext/translations/tr.csv index 174c03f8f1..cf023dd259 100644 --- a/erpnext/translations/tr.csv +++ b/erpnext/translations/tr.csv @@ -3329,3 +3329,49 @@ website page link,web sayfa linki {0} {1} status is Unstopped,{0} {1} durumu Unstopped olduğunu {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Maliyet Merkezi Ürün için zorunludur {2} {0}: {1} not found in Invoice Details table,{0}: {1} Fatura Ayrıntıları tablosunda bulunamadı +"Add / Edit"," Ekle / Düzenle " +"Add / Edit"," Ekle / Düzenle " +Billed,Faturalanmış +Company,Şirket +Currency is required for Price List {0},Döviz Fiyat Listesi için gereklidir {0} +Default Customer Group,Varsayılan Müşteri Grubu +Default Territory,Standart Bölge +Delivered,Teslim Edildi +Enable Shopping Cart,Alışveriş sepeti etkinleştirin +Go ahead and add something to your cart.,Devam edin ve sepetinize şey eklemek. +Hey! Go ahead and add an address,Hey! Devam edin ve bir adres eklemek +Invalid Billing Address,Geçersiz Fatura Adresi +Invalid Shipping Address,Geçersiz Teslimat Adresi +Missing Currency Exchange Rates for {0},Döviz Kurların eksik {0} +Name is required,Adı gerekli +Not Allowed,İzin Verilmedi +Paid,Ödendi +Partially Billed,Kısmen Faturalı +Partially Delivered,Kısmen Teslim +Please specify a Price List which is valid for Territory,Territory için geçerli olan bir Fiyat Listesi belirtin +Please specify currency in Company,Şirket para birimi belirtiniz +Please write something,Bir şeyler yazınız +Please write something in subject and message!,Konu ve mesaj bir şeyler yazınız! +Price List,Fiyat listesi +Price List not configured.,Fiyat Listesi yapılandırılmamış. +Quotation Series,Teklif Serisi +Shipping Rule,Kargo Kural +Shopping Cart,Alışveriş Sepeti +Shopping Cart Price List,Alışveriş Sepeti Fiyat Listesi +Shopping Cart Price Lists,Alışveriş Sepeti Fiyat Listeleri +Shopping Cart Settings,Alışveriş sepeti Ayarları +Shopping Cart Shipping Rule,Alışveriş Sepeti Kargo Kural +Shopping Cart Shipping Rules,Alışveriş Sepeti Nakliye Kuralları +Shopping Cart Taxes and Charges Master,Alışveriş Sepeti Vergi ve Harçlar Usta +Shopping Cart Taxes and Charges Masters,Alışveriş Sepeti Vergi ve Harçlar Masters +Something went wrong!,Bir şeyler yanlış gitti! +Something went wrong.,Bir şeyler yanlış gitti. +Tax Master,Vergi Usta +To Pay,Ödeme +Updated,Güncellenmiş +You are not allowed to reply to this ticket.,Bu bilet için cevap izin verilmez. +You need to be logged in to view your cart.,Eğer sepeti görmek için oturum açmanız gerekir. +You need to enable Shopping Cart,Sen Alışveriş Sepeti etkinleştirmeniz gerekir +{0} cannot be purchased using Shopping Cart,{0} sepeti kullanarak satın alınamaz +{0} is required,{0} gereklidir +{0} {1} has a common territory {2},"{0} {1}, ortak bir bölge var {2}" diff --git a/erpnext/translations/vi.csv b/erpnext/translations/vi.csv index 3e714f5976..ab272e9641 100644 --- a/erpnext/translations/vi.csv +++ b/erpnext/translations/vi.csv @@ -3329,3 +3329,49 @@ website page link,liên kết trang web {0} {1} status is Unstopped,{0} {1} tình trạng là Unstopped {0} {1}: Cost Center is mandatory for Item {2},{0} {1}: Trung tâm chi phí là bắt buộc đối với hàng {2} {0}: {1} not found in Invoice Details table,{0}: {1} không tìm thấy trong hóa đơn chi tiết bảng +"Add / Edit",{0} là cần thiết +"Add / Edit",Tiền tệ là cần thiết cho Giá liệt kê {0} +Billed,Một cái gì đó đã đi sai! +Company,Giỏ hàng Giá liệt kê +Currency is required for Price List {0},Danh sách giá +Default Customer Group,Xin vui lòng viết một cái gì đó trong chủ đề và thông điệp! +Default Territory,Vui lòng ghi rõ tiền tệ tại Công ty +Delivered,"Nếu được chỉ định, gửi các bản tin sử dụng địa chỉ email này" +Enable Shopping Cart,Dòng báo giá +Go ahead and add something to your cart.,Được quảng cáo một phần +Hey! Go ahead and add an address,Một cái gì đó đã đi sai. +Invalid Billing Address,Thuế Thạc sĩ +Invalid Shipping Address,Để trả tiền +Missing Currency Exchange Rates for {0},Quy tắc vận chuyển +Name is required,{0} không thể mua được bằng Giỏ hàng +Not Allowed,Giỏ hàng Thuế và phí Thạc sĩ +Paid,Quy định vận chuyển Giỏ hàng +Partially Billed,Bạn cần phải kích hoạt Giỏ hàng +Partially Delivered,Địa chỉ thanh toán không hợp lệ +Please specify a Price List which is valid for Territory,Mặc định Territory +Please specify currency in Company,Giỏ hàng Vận chuyển Rule +Please write something,Giỏ hàng Chức năng Giá +Please write something in subject and message!,{0} {1} có một lãnh thổ chung {2} +Price List," Add / Edit " +Price List not configured.,Một phần Giao +Quotation Series,Giỏ hàng Thuế và phí Masters +Shipping Rule,Này ! Đi trước và thêm một địa chỉ +Shopping Cart," Add / Edit " +Shopping Cart Price List,Đã cập nhật +Shopping Cart Price Lists,Danh sách giá không được cấu hình. +Shopping Cart Settings,Mặc định khách hàng Nhóm +Shopping Cart Shipping Rule,Bạn cần phải đăng nhập để xem giỏ hàng của bạn. +Shopping Cart Shipping Rules,Không phép +Shopping Cart Taxes and Charges Master,Công ty +Shopping Cart Taxes and Charges Masters,Địa chỉ Vận chuyển không hợp lệ +Something went wrong!,Bạn không được phép trả lời vé này. +Something went wrong.,Đi trước và thêm một cái gì đó vào giỏ hàng của bạn. +Tax Master,Giao +To Pay,Thanh toán +Updated,Xin vui lòng viết một cái gì đó +You are not allowed to reply to this ticket.,Vui lòng xác định Bảng giá có giá trị trong lãnh thổ +You need to be logged in to view your cart.,Giỏ hàng +You need to enable Shopping Cart,Giỏ hàng mua sắm thiết lập +{0} cannot be purchased using Shopping Cart,Lập hóa đơn +{0} is required,Cho phép Giỏ hàng +{0} {1} has a common territory {2},Yêu cầu nhập tên diff --git a/erpnext/translations/zh-cn.csv b/erpnext/translations/zh-cn.csv index faef8220a9..36a4473be0 100644 --- a/erpnext/translations/zh-cn.csv +++ b/erpnext/translations/zh-cn.csv @@ -3377,3 +3377,49 @@ website page link,网站页面的链接 {0} {1} status is Unstopped,{0} {1}状态为开通 {0} {1}: Cost Center is mandatory for Item {2},{0} {1}:成本中心是强制性的项目{2} {0}: {1} not found in Invoice Details table,{0}:{1}不是在发票明细表中找到 +"Add / Edit","添加/编辑" +"Add / Edit","添加/编辑" +Billed,计费 +Company,公司 +Currency is required for Price List {0},货币需要价格表{0} +Default Customer Group,默认用户组 +Default Territory,默认领地 +Delivered,交付 +Enable Shopping Cart,启用的购物车 +Go ahead and add something to your cart.,来吧,讲一下你的车。 +Hey! Go ahead and add an address,嘿!来吧,添加一个地址 +Invalid Billing Address,无效的帐单地址 +Invalid Shipping Address,无效的送货地址 +Missing Currency Exchange Rates for {0},缺少货币汇率的{0} +Name is required,名称是必需的 +Not Allowed,不允许 +Paid,支付 +Partially Billed,部分帐单 +Partially Delivered,部分交付 +Please specify a Price List which is valid for Territory,请指定一个价格表,有效期为领地 +Please specify currency in Company,请公司指定的货币 +Please write something,请写东西 +Please write something in subject and message!,请写东西的主题和消息! +Price List,价格表 +Price List not configured.,未配置价格表。 +Quotation Series,系列报价 +Shipping Rule,送货规则 +Shopping Cart,购物车 +Shopping Cart Price List,购物车价格表 +Shopping Cart Price Lists,购物车价目表 +Shopping Cart Settings,购物车设置 +Shopping Cart Shipping Rule,购物车运费规则 +Shopping Cart Shipping Rules,购物车运费规则 +Shopping Cart Taxes and Charges Master,购物车税收和收费硕士 +Shopping Cart Taxes and Charges Masters,购物车税收和收费硕士 +Something went wrong!,出事了! +Something went wrong.,出事了。 +Tax Master,税务硕士 +To Pay,支付方式 +Updated,更新 +You are not allowed to reply to this ticket.,你不允许回复此票。 +You need to be logged in to view your cart.,您需要登录才能查看您的购物车。 +You need to enable Shopping Cart,您需要启用的购物车 +{0} cannot be purchased using Shopping Cart,{0}不能使用购物车购买 +{0} is required,{0}是必需的 +{0} {1} has a common territory {2},{0} {1}有一个共同的领土{2} diff --git a/erpnext/translations/zh-tw.csv b/erpnext/translations/zh-tw.csv index 29522e6112..609806b417 100644 --- a/erpnext/translations/zh-tw.csv +++ b/erpnext/translations/zh-tw.csv @@ -3377,3 +3377,49 @@ website page link,網站頁面的鏈接 {0} {1} status is Unstopped,{0} {1}狀態為開通 {0} {1}: Cost Center is mandatory for Item {2},{0} {1}:成本中心是強制性的項目{2} {0}: {1} not found in Invoice Details table,{0}:{1}不是在發票明細表中找到 +"Add / Edit","添加/編輯" +"Add / Edit","添加/編輯" +Billed,計費 +Company,公司 +Currency is required for Price List {0},貨幣需要價格表{0} +Default Customer Group,默認用戶組 +Default Territory,默認領地 +Delivered,交付 +Enable Shopping Cart,啟用的購物車 +Go ahead and add something to your cart.,來吧,講一下你的車。 +Hey! Go ahead and add an address,嘿!來吧,添加一個地址 +Invalid Billing Address,無效的帳單地址 +Invalid Shipping Address,無效的送貨地址 +Missing Currency Exchange Rates for {0},缺少貨幣匯率的{0} +Name is required,名稱是必需的 +Not Allowed,不允許 +Paid,支付 +Partially Billed,部分帳單 +Partially Delivered,部分交付 +Please specify a Price List which is valid for Territory,請指定一個價格表,有效期為領地 +Please specify currency in Company,請公司指定的貨幣 +Please write something,請寫東西 +Please write something in subject and message!,請寫東西的主題和消息! +Price List,價格表 +Price List not configured.,未配置價格表。 +Quotation Series,系列報價 +Shipping Rule,送貨規則 +Shopping Cart,購物車 +Shopping Cart Price List,購物車價格表 +Shopping Cart Price Lists,購物車價目表 +Shopping Cart Settings,購物車設置 +Shopping Cart Shipping Rule,購物車運費規則 +Shopping Cart Shipping Rules,購物車運費規則 +Shopping Cart Taxes and Charges Master,購物車稅收和收費碩士 +Shopping Cart Taxes and Charges Masters,購物車稅收和收費碩士 +Something went wrong!,出事了! +Something went wrong.,出事了。 +Tax Master,稅務碩士 +To Pay,支付方式 +Updated,更新 +You are not allowed to reply to this ticket.,你不允許回复此票。 +You need to be logged in to view your cart.,您需要登錄才能查看您的購物車。 +You need to enable Shopping Cart,您需要啟用的購物車 +{0} cannot be purchased using Shopping Cart,{0}不能使用購物車購買 +{0} is required,{0}是必需的 +{0} {1} has a common territory {2},{0} {1}有一個共同的領土{2}