diff --git a/__manifest__.py b/__manifest__.py index 15e254f..b9842fc 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -30,6 +30,11 @@ 'demo': [ # 'demo/demo.xml', ], + 'assets': { + 'point_of_sale._assets_pos': [ + 'split_pendapatan_payment/static/src/app/**/*', + ], + }, 'installable': True, 'application': False, 'auto_install': False, diff --git a/models/pos_session.py b/models/pos_session.py index 87fdca3..96fa64a 100644 --- a/models/pos_session.py +++ b/models/pos_session.py @@ -154,6 +154,55 @@ class PosSession(models.Model): if float_is_zero(order_amount, precision_rounding=self.currency_id.rounding): continue + if not order.payment_ids: + # Assume cash payment method for 0-total orders to ensure proper routing and naming + cash_pm = self.payment_method_ids.filtered(lambda pm: pm.type == 'cash')[:1] + fallback_pm_id = cash_pm.id if cash_pm else False + + regular_part_amount = order_sale_amounts['regular_amount'] + discount_part_amount = order_sale_amounts['discount_amount'] + regular_part_amount_converted = order_sale_amounts['regular_amount_converted'] + discount_part_amount_converted = order_sale_amounts['discount_amount_converted'] + regular_part_tax = order_sale_amounts['regular_tax_amount'] + discount_part_tax = order_sale_amounts['discount_tax_amount'] + + def add_unsplit_entry(part_amount, part_amount_converted, part_tax_amount, is_discount_part): + if float_is_zero(part_amount, precision_rounding=self.currency_id.rounding): + return + + target_account_id = sale_key[0] + if fallback_pm_id and cash_pm: + original_account = self.env['account.account'].browse(target_account_id) + is_income_account = original_account.account_type in ('income', 'income_other') + if is_income_account: + if is_discount_part: + if cash_pm.discount_account_id: + target_account_id = cash_pm.discount_account_id.id + elif cash_pm.income_account_id: + target_account_id = cash_pm.income_account_id.id + else: + if cash_pm.income_account_id: + target_account_id = cash_pm.income_account_id.id + + if fallback_pm_id: + new_sale_key = ( + target_account_id, + sale_key[1], + fallback_pm_id, + sale_key[2], + sale_key[3], + ) + else: + new_sale_key = sale_key + + split_sales[new_sale_key]['amount'] += part_amount + split_sales[new_sale_key]['amount_converted'] += part_amount_converted + split_sales[new_sale_key]['tax_amount'] += part_tax_amount + + add_unsplit_entry(regular_part_amount, regular_part_amount_converted, regular_part_tax, False) + add_unsplit_entry(discount_part_amount, discount_part_amount_converted, discount_part_tax, True) + continue + for payment in order.payment_ids: #if float_is_zero(payment.amount, precision_rounding=order.currency_id.rounding): # continue @@ -191,14 +240,18 @@ class PosSession(models.Model): return target_account_id = sale_key[0] - if is_discount_part: - if payment.payment_method_id.discount_account_id: - target_account_id = payment.payment_method_id.discount_account_id.id - elif payment.payment_method_id.income_account_id: - target_account_id = payment.payment_method_id.income_account_id.id - else: - if payment.payment_method_id.income_account_id: - target_account_id = payment.payment_method_id.income_account_id.id + original_account = self.env['account.account'].browse(target_account_id) + is_income_account = original_account.account_type in ('income', 'income_other') + + if is_income_account: + if is_discount_part: + if payment.payment_method_id.discount_account_id: + target_account_id = payment.payment_method_id.discount_account_id.id + elif payment.payment_method_id.income_account_id: + target_account_id = payment.payment_method_id.income_account_id.id + else: + if payment.payment_method_id.income_account_id: + target_account_id = payment.payment_method_id.income_account_id.id if not target_account_id: raise UserError(_( @@ -242,7 +295,15 @@ class PosSession(models.Model): tax_ids = set(tax[0] for tax in tax_keys) if tax_keys else set() applied_taxes = self.env['account.tax'].browse(tax_ids) - title = _('Sales') if sign == 1 else _('Refund') + + if sign == 1: + title = _('Sales') + else: + account = self.env['account.account'].browse(account_id) + if account.account_type in ('income', 'income_other'): + title = _('Refund') + else: + title = account.name # Create name with payment method information if payment_method_name: diff --git a/static/src/app/pos_store.js b/static/src/app/pos_store.js new file mode 100644 index 0000000..238206f --- /dev/null +++ b/static/src/app/pos_store.js @@ -0,0 +1,28 @@ +/** @odoo-module */ + +import { patch } from "@web/core/utils/patch"; +import { PosStore } from "@point_of_sale/app/services/pos_store"; + +patch(PosStore.prototype, { + async addDownPaymentProductOrderlineToOrder(saleOrder, amount, isPercentage) { + const order = this.getOrder(); + const linesBefore = order.lines.length; + + // Call the original method to create the lines + await super.addDownPaymentProductOrderlineToOrder(...arguments); + + const linesAfter = order.lines.length; + const orderlines = order.lines; + const downPaymentProduct = this.config.down_payment_product_id; + + // Find the down payment lines that were just added and remove their taxes + for (let i = linesBefore; i < linesAfter; i++) { + let line = orderlines[i]; + if (line.get_product().id === downPaymentProduct.id) { + const priceWithTax = line.get_price_with_tax(); + line.tax_ids = []; + line.set_unit_price(priceWithTax); + } + } + } +});