This commit is contained in:
Suherdy Yacob 2025-08-25 16:49:52 +07:00
commit f615b9ca89
5 changed files with 179 additions and 23 deletions

133
.gitignore vendored Normal file
View File

@ -0,0 +1,133 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
Pipfile.lock
# poetry
poetry.lock
# PEP 582; used by pythonloc
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/

View File

@ -19,7 +19,7 @@
'version': '17.0.1.0.0', 'version': '17.0.1.0.0',
# any module necessary for this one to work correctly # any module necessary for this one to work correctly
'depends': ['point_of_sale'], 'depends': ['point_of_sale', 'pos_discount'],
# always loaded # always loaded
'data': [ 'data': [

View File

@ -11,3 +11,10 @@ class PosPaymentMethod(models.Model):
domain=[('deprecated', '=', False)], domain=[('deprecated', '=', False)],
help='Account used for income lines when splitting by payment method. ' help='Account used for income lines when splitting by payment method. '
'If empty, the default income account from the product will be used.') 'If empty, the default income account from the product will be used.')
discount_account_id = fields.Many2one(
'account.account',
string='Discount Account',
domain=[('deprecated', '=', False)],
help='Account used for discount product lines when splitting by payment method. '
'If empty, the default discount account from the product will be used.')

View File

@ -27,6 +27,9 @@ class PosSession(models.Model):
# Create new sales data structure split by payment method # Create new sales data structure split by payment method
split_sales = defaultdict(lambda: {'amount': 0.0, 'amount_converted': 0.0, 'tax_amount': 0.0}) split_sales = defaultdict(lambda: {'amount': 0.0, 'amount_converted': 0.0, 'tax_amount': 0.0})
# Get discount product ID from config
discount_product_id = self.config_id.discount_product_id.id if self.config_id.discount_product_id else None
# For each sale entry, we need to distribute it across payment methods # For each sale entry, we need to distribute it across payment methods
for sale_key, sale_amounts in sales.items(): for sale_key, sale_amounts in sales.items():
# Skip if this is a tax key (we only want to split actual sales) # Skip if this is a tax key (we only want to split actual sales)
@ -68,9 +71,21 @@ class PosSession(models.Model):
if float_is_zero(payment_amount, precision_rounding=self.currency_id.rounding): if float_is_zero(payment_amount, precision_rounding=self.currency_id.rounding):
continue continue
# Use the payment method's income account if specified, otherwise use original account # Determine the account to use based on whether this is a discount product
income_account_id = sale_key[0] # default account income_account_id = sale_key[0] # default account
if payment.payment_method_id.income_account_id and payment.payment_method_id.income_account_id.id:
# Check if this sale key corresponds to a discount product
# We need to check if the account in the sale_key matches the discount product account
if discount_product_id:
# Get the discount product's income account
discount_product = self.env['product.product'].browse(discount_product_id)
discount_account = discount_product._get_product_accounts()['income']
if discount_account and discount_account.id == sale_key[0]:
# This is a discount product, use discount account if configured
if payment.payment_method_id.discount_account_id:
income_account_id = payment.payment_method_id.discount_account_id.id
elif payment.payment_method_id.income_account_id:
# This is a regular product, use income account if configured
income_account_id = payment.payment_method_id.income_account_id.id income_account_id = payment.payment_method_id.income_account_id.id
# Ensure we have a valid account ID # Ensure we have a valid account ID

View File

@ -7,6 +7,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//group[@name='Payment methods']/group" position="inside"> <xpath expr="//group[@name='Payment methods']/group" position="inside">
<field name="income_account_id" domain="[('deprecated', '=', False)]"/> <field name="income_account_id" domain="[('deprecated', '=', False)]"/>
<field name="discount_account_id" domain="[('deprecated', '=', False)]"/>
</xpath> </xpath>
</field> </field>
</record> </record>