Tower: upload laundry_management 19.0.19.0.4 (via marketplace)
This commit is contained in:
125
addons/laundry_management/models/laundry_commission.py
Normal file
125
addons/laundry_management/models/laundry_commission.py
Normal file
@@ -0,0 +1,125 @@
|
||||
from odoo import models, fields, api
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class LaundryCommission(models.Model):
|
||||
"""Staff commission tracking (PART 3).
|
||||
|
||||
States:
|
||||
pending — auto-created when order progresses; awaiting manager review
|
||||
confirmed — manager has verified and approved the commission
|
||||
paid — commission has been settled/paid to the staff member
|
||||
|
||||
The commission_account_id (from settings) is informational for now.
|
||||
Managers can bulk-confirm and bulk-mark-paid from the list view.
|
||||
"""
|
||||
_name = 'laundry.commission'
|
||||
_description = 'Laundry Staff Commission'
|
||||
_inherit = ['mail.thread']
|
||||
_order = 'date desc, id desc'
|
||||
|
||||
name = fields.Char(
|
||||
string='Reference',
|
||||
compute='_compute_name', store=True, readonly=True,
|
||||
)
|
||||
order_id = fields.Many2one(
|
||||
'sale.order', string='Order',
|
||||
required=True, ondelete='cascade', index=True,
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
related='order_id.company_id', store=True, index=True,
|
||||
)
|
||||
employee_id = fields.Many2one(
|
||||
'res.users', string='Staff Member',
|
||||
required=True, domain=[('share', '=', False)],
|
||||
tracking=True,
|
||||
)
|
||||
role = fields.Selection([
|
||||
('reception', 'Reception / Intake'),
|
||||
('processing', 'Processing / Cleaning'),
|
||||
('delivery', 'Delivery / Handover'),
|
||||
], string='Role', required=True, tracking=True)
|
||||
|
||||
commission_type = fields.Selection([
|
||||
('percentage', 'Percentage (%)'),
|
||||
('fixed', 'Fixed Amount'),
|
||||
], string='Type', required=True, default='percentage')
|
||||
|
||||
rate = fields.Float(string='Rate / Amount', digits=(10, 2))
|
||||
base_amount = fields.Float(string='Order Total', digits=(10, 2))
|
||||
commission_amount = fields.Float(
|
||||
string='Commission',
|
||||
compute='_compute_commission_amount', store=True, digits=(10, 2),
|
||||
)
|
||||
|
||||
date = fields.Date(string='Date', required=True, default=fields.Date.today)
|
||||
|
||||
state = fields.Selection([
|
||||
('pending', 'Pending'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('paid', 'Paid'),
|
||||
], default='pending', required=True, tracking=True, copy=False, index=True)
|
||||
|
||||
notes = fields.Text(string='Notes')
|
||||
|
||||
_ROLE_LABELS = {
|
||||
'reception': 'Reception',
|
||||
'processing': 'Processing',
|
||||
'delivery': 'Delivery',
|
||||
}
|
||||
|
||||
@api.depends('order_id', 'order_id.name', 'role')
|
||||
def _compute_name(self):
|
||||
for rec in self:
|
||||
order = rec.order_id.name or 'NEW'
|
||||
role = self._ROLE_LABELS.get(rec.role, rec.role or '')
|
||||
rec.name = f'COM/{order}/{role}'
|
||||
|
||||
@api.depends('commission_type', 'rate', 'base_amount')
|
||||
def _compute_commission_amount(self):
|
||||
for rec in self:
|
||||
if rec.commission_type == 'percentage':
|
||||
rec.commission_amount = rec.base_amount * rec.rate / 100.0
|
||||
else:
|
||||
rec.commission_amount = rec.rate
|
||||
|
||||
# ── State transitions ─────────────────────────────────────────────
|
||||
def action_confirm(self):
|
||||
"""Manager confirms commission is valid and approved."""
|
||||
for rec in self:
|
||||
if rec.state != 'pending':
|
||||
raise UserError(
|
||||
f'"{rec.name}" cannot be confirmed — current state: {rec.state}.'
|
||||
)
|
||||
rec.write({'state': 'confirmed'})
|
||||
rec.message_post(
|
||||
body=f'Commission confirmed by {self.env.user.name}. '
|
||||
f'Amount: {rec.commission_amount:.2f}'
|
||||
)
|
||||
|
||||
def action_mark_paid(self):
|
||||
"""Mark commission as settled/paid to staff."""
|
||||
for rec in self:
|
||||
if rec.state == 'paid':
|
||||
raise UserError(f'"{rec.name}" is already paid.')
|
||||
if rec.state == 'pending':
|
||||
# Allow paying directly from pending (manager shortcut)
|
||||
rec.write({'state': 'paid'})
|
||||
else:
|
||||
rec.write({'state': 'paid'})
|
||||
rec.message_post(
|
||||
body=f'Marked as paid by {self.env.user.name}.'
|
||||
)
|
||||
|
||||
def action_reset_pending(self):
|
||||
"""Reset commission back to pending (manager only)."""
|
||||
for rec in self:
|
||||
if rec.state == 'paid':
|
||||
raise UserError(
|
||||
f'Cannot reset "{rec.name}" — it has already been paid.'
|
||||
)
|
||||
rec.write({'state': 'pending'})
|
||||
rec.message_post(
|
||||
body=f'Reset to pending by {self.env.user.name}.'
|
||||
)
|
||||
Reference in New Issue
Block a user