mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 21:59:13 +00:00
Merge branch 'version-13-hotfix' into accounts_receivable_multi_currency
This commit is contained in:
@@ -256,20 +256,18 @@ doc_events = {
|
|||||||
"validate": "erpnext.regional.india.utils.validate_tax_category"
|
"validate": "erpnext.regional.india.utils.validate_tax_category"
|
||||||
},
|
},
|
||||||
"Sales Invoice": {
|
"Sales Invoice": {
|
||||||
"after_insert": "erpnext.regional.saudi_arabia.utils.create_qr_code",
|
|
||||||
"on_submit": [
|
"on_submit": [
|
||||||
"erpnext.regional.create_transaction_log",
|
"erpnext.regional.create_transaction_log",
|
||||||
"erpnext.regional.italy.utils.sales_invoice_on_submit",
|
"erpnext.regional.italy.utils.sales_invoice_on_submit",
|
||||||
|
"erpnext.regional.saudi_arabia.utils.create_qr_code",
|
||||||
"erpnext.erpnext_integrations.taxjar_integration.create_transaction"
|
"erpnext.erpnext_integrations.taxjar_integration.create_transaction"
|
||||||
],
|
],
|
||||||
"on_cancel": [
|
"on_cancel": [
|
||||||
"erpnext.regional.italy.utils.sales_invoice_on_cancel",
|
"erpnext.regional.italy.utils.sales_invoice_on_cancel",
|
||||||
"erpnext.erpnext_integrations.taxjar_integration.delete_transaction"
|
"erpnext.erpnext_integrations.taxjar_integration.delete_transaction",
|
||||||
],
|
|
||||||
"on_trash": [
|
|
||||||
"erpnext.regional.check_deletion_permission",
|
|
||||||
"erpnext.regional.saudi_arabia.utils.delete_qr_code_file"
|
"erpnext.regional.saudi_arabia.utils.delete_qr_code_file"
|
||||||
],
|
],
|
||||||
|
"on_trash": "erpnext.regional.check_deletion_permission",
|
||||||
"validate": [
|
"validate": [
|
||||||
"erpnext.regional.india.utils.validate_document_name",
|
"erpnext.regional.india.utils.validate_document_name",
|
||||||
"erpnext.regional.india.utils.update_taxable_values"
|
"erpnext.regional.india.utils.update_taxable_values"
|
||||||
|
|||||||
@@ -96,15 +96,8 @@ class Employee(NestedSet):
|
|||||||
'user': self.user_id
|
'user': self.user_id
|
||||||
})
|
})
|
||||||
|
|
||||||
if employee_user_permission_exists: return
|
if employee_user_permission_exists:
|
||||||
|
return
|
||||||
employee_user_permission_exists = frappe.db.exists('User Permission', {
|
|
||||||
'allow': 'Employee',
|
|
||||||
'for_value': self.name,
|
|
||||||
'user': self.user_id
|
|
||||||
})
|
|
||||||
|
|
||||||
if employee_user_permission_exists: return
|
|
||||||
|
|
||||||
add_user_permission("Employee", self.name, self.user_id)
|
add_user_permission("Employee", self.name, self.user_id)
|
||||||
set_user_permission_if_allowed("Company", self.company, self.user_id)
|
set_user_permission_if_allowed("Company", self.company, self.user_id)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
# See license.txt
|
# See license.txt
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from datetime import date
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_days, getdate
|
from frappe.utils import add_days, getdate
|
||||||
@@ -12,16 +11,14 @@ from erpnext.hr.doctype.employee.test_employee import make_employee
|
|||||||
|
|
||||||
class TestEmployeeTransfer(unittest.TestCase):
|
class TestEmployeeTransfer(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
make_employee("employee2@transfers.com")
|
|
||||||
make_employee("employee3@transfers.com")
|
|
||||||
create_company()
|
create_company()
|
||||||
create_employee()
|
|
||||||
create_employee_transfer()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
def test_submit_before_transfer_date(self):
|
def test_submit_before_transfer_date(self):
|
||||||
|
make_employee("employee2@transfers.com")
|
||||||
|
|
||||||
transfer_obj = frappe.get_doc({
|
transfer_obj = frappe.get_doc({
|
||||||
"doctype": "Employee Transfer",
|
"doctype": "Employee Transfer",
|
||||||
"employee": frappe.get_value("Employee", {"user_id":"employee2@transfers.com"}, "name"),
|
"employee": frappe.get_value("Employee", {"user_id":"employee2@transfers.com"}, "name"),
|
||||||
@@ -43,6 +40,8 @@ class TestEmployeeTransfer(unittest.TestCase):
|
|||||||
self.assertEqual(transfer.docstatus, 1)
|
self.assertEqual(transfer.docstatus, 1)
|
||||||
|
|
||||||
def test_new_employee_creation(self):
|
def test_new_employee_creation(self):
|
||||||
|
make_employee("employee3@transfers.com")
|
||||||
|
|
||||||
transfer = frappe.get_doc({
|
transfer = frappe.get_doc({
|
||||||
"doctype": "Employee Transfer",
|
"doctype": "Employee Transfer",
|
||||||
"employee": frappe.get_value("Employee", {"user_id":"employee3@transfers.com"}, "name"),
|
"employee": frappe.get_value("Employee", {"user_id":"employee3@transfers.com"}, "name"),
|
||||||
@@ -63,60 +62,51 @@ class TestEmployeeTransfer(unittest.TestCase):
|
|||||||
self.assertEqual(frappe.get_value("Employee", transfer.employee, "status"), "Left")
|
self.assertEqual(frappe.get_value("Employee", transfer.employee, "status"), "Left")
|
||||||
|
|
||||||
def test_employee_history(self):
|
def test_employee_history(self):
|
||||||
name = frappe.get_value("Employee", {"first_name": "John", "company": "Test Company"}, "name")
|
employee = make_employee("employee4@transfers.com",
|
||||||
doc = frappe.get_doc("Employee",name)
|
company="Test Company",
|
||||||
|
date_of_birth=getdate("30-09-1980"),
|
||||||
|
date_of_joining=getdate("01-10-2021"),
|
||||||
|
department="Accounts - TC",
|
||||||
|
designation="Accountant"
|
||||||
|
)
|
||||||
|
transfer = create_employee_transfer(employee)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
department = ["Accounts - TC", "Management - TC"]
|
department = ["Accounts - TC", "Management - TC"]
|
||||||
designation = ["Accountant", "Manager"]
|
designation = ["Accountant", "Manager"]
|
||||||
dt = [getdate("01-10-2021"), date.today()]
|
dt = [getdate("01-10-2021"), getdate()]
|
||||||
|
|
||||||
for data in doc.internal_work_history:
|
employee = frappe.get_doc("Employee", employee)
|
||||||
|
for data in employee.internal_work_history:
|
||||||
self.assertEqual(data.department, department[count])
|
self.assertEqual(data.department, department[count])
|
||||||
self.assertEqual(data.designation, designation[count])
|
self.assertEqual(data.designation, designation[count])
|
||||||
self.assertEqual(data.from_date, dt[count])
|
self.assertEqual(data.from_date, dt[count])
|
||||||
count = count + 1
|
count = count + 1
|
||||||
|
|
||||||
data = frappe.db.get_list("Employee Transfer", filters={"employee":name}, fields=["*"])
|
transfer.cancel()
|
||||||
doc = frappe.get_doc("Employee Transfer", data[0]["name"])
|
employee.reload()
|
||||||
doc.cancel()
|
|
||||||
employee_doc = frappe.get_doc("Employee",name)
|
|
||||||
|
|
||||||
for data in employee_doc.internal_work_history:
|
for data in employee.internal_work_history:
|
||||||
self.assertEqual(data.designation, designation[0])
|
self.assertEqual(data.designation, designation[0])
|
||||||
self.assertEqual(data.department, department[0])
|
self.assertEqual(data.department, department[0])
|
||||||
self.assertEqual(data.from_date, dt[0])
|
self.assertEqual(data.from_date, dt[0])
|
||||||
|
|
||||||
def create_employee():
|
|
||||||
doc = frappe.get_doc({
|
|
||||||
"doctype": "Employee",
|
|
||||||
"first_name": "John",
|
|
||||||
"company": "Test Company",
|
|
||||||
"gender": "Male",
|
|
||||||
"date_of_birth": getdate("30-09-1980"),
|
|
||||||
"date_of_joining": getdate("01-10-2021"),
|
|
||||||
"department": "Accounts - TC",
|
|
||||||
"designation": "Accountant"
|
|
||||||
})
|
|
||||||
|
|
||||||
doc.save()
|
|
||||||
|
|
||||||
def create_company():
|
def create_company():
|
||||||
exists = frappe.db.exists("Company", "Test Company")
|
if not frappe.db.exists("Company", "Test Company"):
|
||||||
if not exists:
|
frappe.get_doc({
|
||||||
doc = frappe.get_doc({
|
|
||||||
"doctype": "Company",
|
"doctype": "Company",
|
||||||
"company_name": "Test Company",
|
"company_name": "Test Company",
|
||||||
"default_currency": "INR",
|
"default_currency": "INR",
|
||||||
"country": "India"
|
"country": "India"
|
||||||
})
|
}).insert()
|
||||||
|
|
||||||
doc.save()
|
|
||||||
|
|
||||||
def create_employee_transfer():
|
def create_employee_transfer(employee):
|
||||||
doc = frappe.get_doc({
|
doc = frappe.get_doc({
|
||||||
"doctype": "Employee Transfer",
|
"doctype": "Employee Transfer",
|
||||||
"employee": frappe.get_value("Employee", {"first_name": "John", "company": "Test Company"}, "name"),
|
"employee": employee,
|
||||||
"transfer_date": date.today(),
|
"transfer_date": getdate(),
|
||||||
"transfer_details": [
|
"transfer_details": [
|
||||||
{
|
{
|
||||||
"property": "Designation",
|
"property": "Designation",
|
||||||
@@ -135,3 +125,5 @@ def create_employee_transfer():
|
|||||||
|
|
||||||
doc.save()
|
doc.save()
|
||||||
doc.submit()
|
doc.submit()
|
||||||
|
|
||||||
|
return doc
|
||||||
@@ -19,8 +19,8 @@ class ShiftAssignment(Document):
|
|||||||
validate_active_employee(self.employee)
|
validate_active_employee(self.employee)
|
||||||
self.validate_overlapping_dates()
|
self.validate_overlapping_dates()
|
||||||
|
|
||||||
if self.end_date and self.end_date <= self.start_date:
|
if self.end_date:
|
||||||
frappe.throw(_("End Date must not be lesser than Start Date"))
|
self.validate_from_to_dates('start_date', 'end_date')
|
||||||
|
|
||||||
def validate_overlapping_dates(self):
|
def validate_overlapping_dates(self):
|
||||||
if not self.name:
|
if not self.name:
|
||||||
|
|||||||
@@ -178,8 +178,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "batch_size",
|
"fieldname": "batch_size",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Float",
|
||||||
"label": "Batch Size"
|
"label": "Batch Size",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "sequence_id",
|
"fieldname": "sequence_id",
|
||||||
@@ -200,7 +201,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-11-24 04:52:54.295168",
|
"modified": "2021-11-29 16:37:18.824489",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Manufacturing",
|
"module": "Manufacturing",
|
||||||
"name": "Work Order Operation",
|
"name": "Work Order Operation",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_days, getdate, nowdate
|
from frappe.utils import add_days, getdate
|
||||||
|
|
||||||
from erpnext.hr.doctype.employee.test_employee import make_employee
|
from erpnext.hr.doctype.employee.test_employee import make_employee
|
||||||
from erpnext.projects.doctype.timesheet.test_timesheet import (
|
from erpnext.projects.doctype.timesheet.test_timesheet import (
|
||||||
@@ -14,21 +14,26 @@ from erpnext.projects.report.project_profitability.project_profitability import
|
|||||||
|
|
||||||
|
|
||||||
class TestProjectProfitability(unittest.TestCase):
|
class TestProjectProfitability(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
frappe.db.sql('delete from `tabTimesheet`')
|
||||||
emp = make_employee('test_employee_9@salary.com', company='_Test Company')
|
emp = make_employee('test_employee_9@salary.com', company='_Test Company')
|
||||||
|
|
||||||
if not frappe.db.exists('Salary Component', 'Timesheet Component'):
|
if not frappe.db.exists('Salary Component', 'Timesheet Component'):
|
||||||
frappe.get_doc({'doctype': 'Salary Component', 'salary_component': 'Timesheet Component'}).insert()
|
frappe.get_doc({'doctype': 'Salary Component', 'salary_component': 'Timesheet Component'}).insert()
|
||||||
|
|
||||||
make_salary_structure_for_timesheet(emp, company='_Test Company')
|
make_salary_structure_for_timesheet(emp, company='_Test Company')
|
||||||
self.timesheet = make_timesheet(emp, simulate = True, is_billable=1)
|
date = getdate()
|
||||||
|
|
||||||
|
self.timesheet = make_timesheet(emp, is_billable=1)
|
||||||
self.salary_slip = make_salary_slip(self.timesheet.name)
|
self.salary_slip = make_salary_slip(self.timesheet.name)
|
||||||
holidays = self.salary_slip.get_holidays_for_employee(nowdate(), nowdate())
|
|
||||||
|
holidays = self.salary_slip.get_holidays_for_employee(date, date)
|
||||||
if holidays:
|
if holidays:
|
||||||
frappe.db.set_value('Payroll Settings', None, 'include_holidays_in_total_working_days', 1)
|
frappe.db.set_value('Payroll Settings', None, 'include_holidays_in_total_working_days', 1)
|
||||||
|
|
||||||
self.salary_slip.submit()
|
self.salary_slip.submit()
|
||||||
self.sales_invoice = make_sales_invoice(self.timesheet.name, '_Test Item', '_Test Customer')
|
self.sales_invoice = make_sales_invoice(self.timesheet.name, '_Test Item', '_Test Customer')
|
||||||
self.sales_invoice.due_date = nowdate()
|
self.sales_invoice.due_date = date
|
||||||
self.sales_invoice.submit()
|
self.sales_invoice.submit()
|
||||||
|
|
||||||
frappe.db.set_value('HR Settings', None, 'standard_working_hours', 8)
|
frappe.db.set_value('HR Settings', None, 'standard_working_hours', 8)
|
||||||
@@ -64,6 +69,4 @@ class TestProjectProfitability(unittest.TestCase):
|
|||||||
self.assertEqual(fractional_cost, row.fractional_cost)
|
self.assertEqual(fractional_cost, row.fractional_cost)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.get_doc("Sales Invoice", self.sales_invoice.name).cancel()
|
frappe.db.rollback()
|
||||||
frappe.get_doc("Salary Slip", self.salary_slip.name).cancel()
|
|
||||||
frappe.get_doc("Timesheet", self.timesheet.name).cancel()
|
|
||||||
|
|||||||
@@ -495,6 +495,11 @@
|
|||||||
font-size: var(--text-md);
|
font-size: var(--text-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .item-qty-total-container {
|
||||||
|
@extend .net-total-container;
|
||||||
|
padding: 5px 0px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
> .taxes-container {
|
> .taxes-container {
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -571,17 +571,17 @@ def get_item_list(data, doc, hsn_wise=False):
|
|||||||
}
|
}
|
||||||
item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
|
item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
|
||||||
hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True, hsn_wise=hsn_wise)
|
hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True, hsn_wise=hsn_wise)
|
||||||
for hsn_code, taxable_amount in hsn_taxable_amount.items():
|
for item_or_hsn, taxable_amount in hsn_taxable_amount.items():
|
||||||
item_data = frappe._dict()
|
item_data = frappe._dict()
|
||||||
if not hsn_code:
|
if not item_or_hsn:
|
||||||
frappe.throw(_('GST HSN Code does not exist for one or more items'))
|
frappe.throw(_('GST HSN Code does not exist for one or more items'))
|
||||||
item_data.hsnCode = int(hsn_code)
|
item_data.hsnCode = int(item_or_hsn) if hsn_wise else item_or_hsn
|
||||||
item_data.taxableAmount = taxable_amount
|
item_data.taxableAmount = taxable_amount
|
||||||
item_data.qtyUnit = ""
|
item_data.qtyUnit = ""
|
||||||
for attr in item_data_attrs:
|
for attr in item_data_attrs:
|
||||||
item_data[attr] = 0
|
item_data[attr] = 0
|
||||||
|
|
||||||
for account, tax_detail in hsn_wise_charges.get(hsn_code, {}).items():
|
for account, tax_detail in hsn_wise_charges.get(item_or_hsn, {}).items():
|
||||||
account_type = gst_accounts.get(account, '')
|
account_type = gst_accounts.get(account, '')
|
||||||
for tax_acc, attrs in tax_map.items():
|
for tax_acc, attrs in tax_map.items():
|
||||||
if account_type == tax_acc:
|
if account_type == tax_acc:
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,7 +1,10 @@
|
|||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
|
from base64 import b64encode
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils.data import add_to_date, get_time, getdate
|
||||||
from pyqrcode import create as qr_create
|
from pyqrcode import create as qr_create
|
||||||
|
|
||||||
from erpnext import get_region
|
from erpnext import get_region
|
||||||
@@ -28,24 +31,74 @@ def create_qr_code(doc, method):
|
|||||||
|
|
||||||
for field in meta.get_image_fields():
|
for field in meta.get_image_fields():
|
||||||
if field.fieldname == 'qr_code':
|
if field.fieldname == 'qr_code':
|
||||||
from urllib.parse import urlencode
|
''' TLV conversion for
|
||||||
|
1. Seller's Name
|
||||||
|
2. VAT Number
|
||||||
|
3. Time Stamp
|
||||||
|
4. Invoice Amount
|
||||||
|
5. VAT Amount
|
||||||
|
'''
|
||||||
|
tlv_array = []
|
||||||
|
# Sellers Name
|
||||||
|
|
||||||
# Creating public url to print format
|
seller_name = frappe.db.get_value(
|
||||||
default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value")
|
'Company',
|
||||||
|
doc.company,
|
||||||
|
'company_name_in_arabic')
|
||||||
|
|
||||||
# System Language
|
if not seller_name:
|
||||||
language = frappe.get_system_settings('language')
|
frappe.throw(_('Arabic name missing for {} in the company document').format(doc.company))
|
||||||
|
|
||||||
params = urlencode({
|
tag = bytes([1]).hex()
|
||||||
'format': default_print_format or 'Standard',
|
length = bytes([len(seller_name.encode('utf-8'))]).hex()
|
||||||
'_lang': language,
|
value = seller_name.encode('utf-8').hex()
|
||||||
'key': doc.get_signature()
|
tlv_array.append(''.join([tag, length, value]))
|
||||||
})
|
|
||||||
|
# VAT Number
|
||||||
|
tax_id = frappe.db.get_value('Company', doc.company, 'tax_id')
|
||||||
|
if not tax_id:
|
||||||
|
frappe.throw(_('Tax ID missing for {} in the company document').format(doc.company))
|
||||||
|
|
||||||
|
tag = bytes([2]).hex()
|
||||||
|
length = bytes([len(tax_id)]).hex()
|
||||||
|
value = tax_id.encode('utf-8').hex()
|
||||||
|
tlv_array.append(''.join([tag, length, value]))
|
||||||
|
|
||||||
|
# Time Stamp
|
||||||
|
posting_date = getdate(doc.posting_date)
|
||||||
|
time = get_time(doc.posting_time)
|
||||||
|
seconds = time.hour * 60 * 60 + time.minute * 60 + time.second
|
||||||
|
time_stamp = add_to_date(posting_date, seconds=seconds)
|
||||||
|
time_stamp = time_stamp.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
|
||||||
|
tag = bytes([3]).hex()
|
||||||
|
length = bytes([len(time_stamp)]).hex()
|
||||||
|
value = time_stamp.encode('utf-8').hex()
|
||||||
|
tlv_array.append(''.join([tag, length, value]))
|
||||||
|
|
||||||
|
# Invoice Amount
|
||||||
|
invoice_amount = str(doc.total)
|
||||||
|
tag = bytes([4]).hex()
|
||||||
|
length = bytes([len(invoice_amount)]).hex()
|
||||||
|
value = invoice_amount.encode('utf-8').hex()
|
||||||
|
tlv_array.append(''.join([tag, length, value]))
|
||||||
|
|
||||||
|
# VAT Amount
|
||||||
|
vat_amount = str(doc.total_taxes_and_charges)
|
||||||
|
|
||||||
|
tag = bytes([5]).hex()
|
||||||
|
length = bytes([len(vat_amount)]).hex()
|
||||||
|
value = vat_amount.encode('utf-8').hex()
|
||||||
|
tlv_array.append(''.join([tag, length, value]))
|
||||||
|
|
||||||
|
# Joining bytes into one
|
||||||
|
tlv_buff = ''.join(tlv_array)
|
||||||
|
|
||||||
|
# base64 conversion for QR Code
|
||||||
|
base64_string = b64encode(bytes.fromhex(tlv_buff)).decode()
|
||||||
|
|
||||||
# creating qr code for the url
|
|
||||||
url = f"{ frappe.utils.get_url() }/{ doc.doctype }/{ doc.name }?{ params }"
|
|
||||||
qr_image = io.BytesIO()
|
qr_image = io.BytesIO()
|
||||||
url = qr_create(url, error='L')
|
url = qr_create(base64_string, error='L')
|
||||||
url.png(qr_image, scale=2, quiet_zone=1)
|
url.png(qr_image, scale=2, quiet_zone=1)
|
||||||
|
|
||||||
# making file
|
# making file
|
||||||
|
|||||||
@@ -952,8 +952,7 @@
|
|||||||
"idx": 82,
|
"idx": 82,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"modified": "2021-11-30 01:33:21.106073",
|
||||||
"modified": "2021-08-27 20:10:07.864951",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation",
|
"name": "Quotation",
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ erpnext.PointOfSale.ItemCart = class {
|
|||||||
`<div class="add-discount-wrapper">
|
`<div class="add-discount-wrapper">
|
||||||
${this.get_discount_icon()} ${__('Add Discount')}
|
${this.get_discount_icon()} ${__('Add Discount')}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="item-qty-total-container">
|
||||||
|
<div class="item-qty-total-label">${__('Total Items')}</div>
|
||||||
|
<div class="item-qty-total-value">0.00</div>
|
||||||
|
</div>
|
||||||
<div class="net-total-container">
|
<div class="net-total-container">
|
||||||
<div class="net-total-label">${__("Net Total")}</div>
|
<div class="net-total-label">${__("Net Total")}</div>
|
||||||
<div class="net-total-value">0.00</div>
|
<div class="net-total-value">0.00</div>
|
||||||
@@ -142,6 +146,7 @@ erpnext.PointOfSale.ItemCart = class {
|
|||||||
|
|
||||||
this.$numpad_section.prepend(
|
this.$numpad_section.prepend(
|
||||||
`<div class="numpad-totals">
|
`<div class="numpad-totals">
|
||||||
|
<span class="numpad-item-qty-total"></span>
|
||||||
<span class="numpad-net-total"></span>
|
<span class="numpad-net-total"></span>
|
||||||
<span class="numpad-grand-total"></span>
|
<span class="numpad-grand-total"></span>
|
||||||
</div>`
|
</div>`
|
||||||
@@ -470,6 +475,7 @@ erpnext.PointOfSale.ItemCart = class {
|
|||||||
if (!frm) frm = this.events.get_frm();
|
if (!frm) frm = this.events.get_frm();
|
||||||
|
|
||||||
this.render_net_total(frm.doc.net_total);
|
this.render_net_total(frm.doc.net_total);
|
||||||
|
this.render_total_item_qty(frm.doc.items);
|
||||||
const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? frm.doc.grand_total : frm.doc.rounded_total;
|
const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? frm.doc.grand_total : frm.doc.rounded_total;
|
||||||
this.render_grand_total(grand_total);
|
this.render_grand_total(grand_total);
|
||||||
|
|
||||||
@@ -487,6 +493,21 @@ erpnext.PointOfSale.ItemCart = class {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render_total_item_qty(items) {
|
||||||
|
var total_item_qty = 0;
|
||||||
|
items.map((item) => {
|
||||||
|
total_item_qty = total_item_qty + item.qty;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$totals_section.find('.item-qty-total-container').html(
|
||||||
|
`<div>${__('Total Quantity')}</div><div>${total_item_qty}</div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
this.$numpad_section.find('.numpad-item-qty-total').html(
|
||||||
|
`<div>${__('Total Quantity')}: <span>${total_item_qty}</span></div>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render_grand_total(value) {
|
render_grand_total(value) {
|
||||||
const currency = this.events.get_frm().doc.currency;
|
const currency = this.events.get_frm().doc.currency;
|
||||||
this.$totals_section.find('.grand-total-container').html(
|
this.$totals_section.find('.grand-total-container').html(
|
||||||
|
|||||||
@@ -949,8 +949,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"max_attachments": 1,
|
"modified": "2021-11-30 01:33:06.572442",
|
||||||
"modified": "2021-09-10 12:23:07.277077",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item",
|
"name": "Item",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"actions": [],
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2013-03-28 10:35:31",
|
"creation": "2013-03-28 10:35:31",
|
||||||
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
|
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
|
||||||
@@ -153,11 +154,12 @@
|
|||||||
"icon": "fa fa-upload-alt",
|
"icon": "fa fa-upload-alt",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"max_attachments": 1,
|
"links": [],
|
||||||
"modified": "2020-04-08 17:02:47.196206",
|
"modified": "2021-11-30 01:33:51.437194",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Reconciliation",
|
"name": "Stock Reconciliation",
|
||||||
|
"naming_rule": "By \"Naming Series\" field",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ def get_basic_details(args, item, overwrite_warehouse=True):
|
|||||||
"warehouse": warehouse,
|
"warehouse": warehouse,
|
||||||
"income_account": get_default_income_account(args, item_defaults, item_group_defaults, brand_defaults),
|
"income_account": get_default_income_account(args, item_defaults, item_group_defaults, brand_defaults),
|
||||||
"expense_account": expense_account or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults) ,
|
"expense_account": expense_account or get_default_expense_account(args, item_defaults, item_group_defaults, brand_defaults) ,
|
||||||
"discount_account": None or get_default_discount_account(args, item_defaults),
|
"discount_account": get_default_discount_account(args, item_defaults),
|
||||||
"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults),
|
"cost_center": get_default_cost_center(args, item_defaults, item_group_defaults, brand_defaults),
|
||||||
'has_serial_no': item.has_serial_no,
|
'has_serial_no': item.has_serial_no,
|
||||||
'has_batch_no': item.has_batch_no,
|
'has_batch_no': item.has_batch_no,
|
||||||
@@ -318,6 +318,7 @@ def get_basic_details(args, item, overwrite_warehouse=True):
|
|||||||
"net_rate": 0.0,
|
"net_rate": 0.0,
|
||||||
"net_amount": 0.0,
|
"net_amount": 0.0,
|
||||||
"discount_percentage": 0.0,
|
"discount_percentage": 0.0,
|
||||||
|
"discount_amount": 0.0,
|
||||||
"supplier": get_default_supplier(args, item_defaults, item_group_defaults, brand_defaults),
|
"supplier": get_default_supplier(args, item_defaults, item_group_defaults, brand_defaults),
|
||||||
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
|
"update_stock": args.get("update_stock") if args.get('doctype') in ['Sales Invoice', 'Purchase Invoice'] else 0,
|
||||||
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
|
"delivered_by_supplier": item.delivered_by_supplier if args.get("doctype") in ["Sales Order", "Sales Invoice"] else 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user