mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-22 18:12:04 +02:00
19.0 vanilla
This commit is contained in:
parent
d1963a3c3a
commit
2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import base_partner_merge
|
||||
from . import loyalty_card_update_balance
|
||||
from . import loyalty_generate_wizard
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
from odoo import models
|
||||
|
||||
|
||||
class BasePartnerMergeAutomaticWizard(models.TransientModel):
|
||||
_inherit = 'base.partner.merge.automatic.wizard'
|
||||
|
||||
def _update_foreign_keys(self, src_partners, dst_partner):
|
||||
""" Override of base to merge corresponding nominative loyalty cards."""
|
||||
self._merge_loyalty_cards(src_partners, dst_partner)
|
||||
super()._update_foreign_keys(src_partners, dst_partner)
|
||||
|
||||
def _merge_loyalty_cards(self, src_partners, dst_partner):
|
||||
""" Merge nominative loyalty cards.
|
||||
|
||||
:param src_partners: recordset of source res.partner records to merge
|
||||
:param dst_partner: destination res.partner record
|
||||
"""
|
||||
LoyaltyCard = self.env['loyalty.card'].sudo()
|
||||
cards_per_program = dict(
|
||||
LoyaltyCard._read_group(
|
||||
domain=[
|
||||
('partner_id', 'in', src_partners.ids),
|
||||
'|',
|
||||
('program_id.applies_on', '=', 'both'),
|
||||
'&',
|
||||
('program_id.program_type', 'in', ('ewallet', 'loyalty')),
|
||||
('program_id.applies_on', '=', 'future'),
|
||||
],
|
||||
groupby=['program_id'],
|
||||
aggregates=['id:recordset'],
|
||||
)
|
||||
)
|
||||
for program, cards in cards_per_program.items():
|
||||
total_points = sum(card.points for card in cards)
|
||||
dst_card = LoyaltyCard.search([
|
||||
('partner_id', '=', dst_partner.id),
|
||||
('program_id', '=', program.id),
|
||||
], limit=1)
|
||||
if dst_card:
|
||||
final_card = dst_card
|
||||
total_points += dst_card.points
|
||||
else:
|
||||
final_card = cards[0]
|
||||
final_card.sudo().write({'partner_id': dst_partner.id, 'points': total_points})
|
||||
(cards - final_card).sudo().write({'points': 0, 'active': False})
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import _, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class LoyaltyCardUpdateBalance(models.TransientModel):
|
||||
_name = 'loyalty.card.update.balance'
|
||||
_description = "Update Loyalty Card Points"
|
||||
|
||||
card_id = fields.Many2one(
|
||||
comodel_name='loyalty.card',
|
||||
required=True,
|
||||
readonly=True,
|
||||
)
|
||||
old_balance = fields.Float(related='card_id.points')
|
||||
new_balance = fields.Float()
|
||||
description = fields.Char(required=True)
|
||||
|
||||
def action_update_card_point(self):
|
||||
if self.old_balance == self.new_balance or self.new_balance < 0:
|
||||
raise ValidationError(
|
||||
_("New Balance should be positive and different then old balance.")
|
||||
)
|
||||
difference = self.new_balance - self.old_balance
|
||||
used = 0
|
||||
issued = 0
|
||||
if difference > 0:
|
||||
issued = difference
|
||||
else:
|
||||
used = abs(difference)
|
||||
|
||||
self.env['loyalty.history'].create({
|
||||
'card_id': self.card_id.id,
|
||||
'description': self.description or _("Gift for customer"),
|
||||
'used': used,
|
||||
'issued': issued,
|
||||
})
|
||||
self.card_id.points = self.new_balance
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="loyalty_card_update_balance_form" model="ir.ui.view">
|
||||
<field name="name">loyalty.card.update.balance.view.form</field>
|
||||
<field name="model">loyalty.card.update.balance</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Update Balance">
|
||||
<sheet>
|
||||
<h3>You are about to change the balance of the card</h3>
|
||||
<group>
|
||||
<field name="card_id" invisible="1"/>
|
||||
<field name="old_balance"/>
|
||||
<field name="new_balance"/>
|
||||
<field name="description" placeholder="Example: Gift for customer"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button
|
||||
name="action_update_card_point"
|
||||
type="object"
|
||||
class="btn-primary"
|
||||
data-hotkey="s"
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
<button special="cancel" data-hotkey="x">Cancel</button>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -1,43 +1,56 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.osv import expression
|
||||
from odoo.fields import Domain
|
||||
|
||||
|
||||
class LoyaltyGenerateWizard(models.TransientModel):
|
||||
_name = 'loyalty.generate.wizard'
|
||||
_description = 'Generate Coupons'
|
||||
_description = "Generate Coupons"
|
||||
|
||||
program_id = fields.Many2one('loyalty.program', required=True, default=lambda self: self.env.context.get('active_id', False) or self.env.context.get('default_program_id', False))
|
||||
program_type = fields.Selection(related='program_id.program_type')
|
||||
|
||||
mode = fields.Selection([
|
||||
('anonymous', 'Anonymous Customers'),
|
||||
('selected', 'Selected Customers')],
|
||||
('anonymous', "Anonymous Customers"),
|
||||
('selected', "Selected Customers")],
|
||||
string='For', required=True, default='anonymous'
|
||||
)
|
||||
|
||||
customer_ids = fields.Many2many('res.partner', string='Customers')
|
||||
customer_tag_ids = fields.Many2many('res.partner.category', string='Customer Tags')
|
||||
|
||||
coupon_qty = fields.Integer('Quantity',
|
||||
coupon_qty = fields.Integer("Quantity",
|
||||
compute='_compute_coupon_qty', readonly=False, store=True)
|
||||
points_granted = fields.Float('Grant', required=True, default=1)
|
||||
points_name = fields.Char(related='program_id.portal_point_name', readonly=True)
|
||||
valid_until = fields.Date()
|
||||
will_send_mail = fields.Boolean(compute='_compute_will_send_mail')
|
||||
confirmation_message = fields.Char(compute='_compute_confirmation_message')
|
||||
description = fields.Text(string="Description")
|
||||
|
||||
def _get_partners(self):
|
||||
self.ensure_one()
|
||||
if self.mode != 'selected':
|
||||
return self.env['res.partner']
|
||||
domain = []
|
||||
domains = []
|
||||
if self.customer_ids:
|
||||
domain = [('id', 'in', self.customer_ids.ids)]
|
||||
domains.append([('id', 'in', self.customer_ids.ids)])
|
||||
if self.customer_tag_ids:
|
||||
domain = expression.OR([domain, [('category_id', 'in', self.customer_tag_ids.ids)]])
|
||||
return self.env['res.partner'].search(domain)
|
||||
domains.append([('category_id', 'in', self.customer_tag_ids.ids)])
|
||||
return self.env['res.partner'].search(Domain.OR(domains) if domains else Domain.TRUE)
|
||||
|
||||
@api.depends('program_type', 'points_granted', 'coupon_qty')
|
||||
def _compute_confirmation_message(self):
|
||||
self.confirmation_message = False
|
||||
for wizard in self:
|
||||
program_desc = dict(wizard._fields['program_type']._description_selection(wizard.env))
|
||||
wizard.confirmation_message = _("You're about to generate %(program_type)s with a value of %(value)s for %(customer_number)i customers",
|
||||
program_type=program_desc[wizard.program_type],
|
||||
value=wizard.points_granted,
|
||||
customer_number=wizard.coupon_qty,
|
||||
)
|
||||
|
||||
@api.depends('customer_ids', 'customer_tag_ids', 'mode')
|
||||
def _compute_coupon_qty(self):
|
||||
|
|
@ -71,5 +84,12 @@ class LoyaltyGenerateWizard(models.TransientModel):
|
|||
customers = wizard._get_partners() or range(wizard.coupon_qty)
|
||||
for partner in customers:
|
||||
coupon_create_vals.append(wizard._get_coupon_values(partner))
|
||||
self.env['loyalty.card'].create(coupon_create_vals)
|
||||
return True
|
||||
coupons = self.env['loyalty.card'].create(coupon_create_vals)
|
||||
self.env['loyalty.history'].create([
|
||||
{
|
||||
'description': self.description or _("Gift For Customer"),
|
||||
'card_id': coupon.id,
|
||||
'issued': self.points_granted,
|
||||
} for coupon in coupons
|
||||
])
|
||||
return coupons
|
||||
|
|
|
|||
|
|
@ -11,40 +11,47 @@
|
|||
<field name="program_id" invisible="1"/>
|
||||
<field name="will_send_mail" invisible="1"/>
|
||||
<field name="program_type" invisible="1"/>
|
||||
<field name="mode" widget="radio" attrs="{'invisible': [('program_type', '=', 'ewallet')]}"/>
|
||||
<field name="customer_ids" widget="many2many_tags" attrs="{'invisible': [('mode', '=', 'anonymous')]}"/>
|
||||
<field name="customer_tag_ids" widget="many2many_tags" attrs="{'invisible': [('mode', '=', 'anonymous')]}" options="{'color_field': 'color'}"/>
|
||||
<field name="coupon_qty" string="Quantity to generate" attrs="{'readonly': [('mode', '=', 'selected')], 'required': [('mode', '=', 'anonymous')]}"/>
|
||||
<label string="Coupon value" for="points_granted" groups="base.group_no_one" attrs="{'invisible': [('program_type', '!=', 'coupons')]}"/>
|
||||
<span class="d-inline-block" groups="base.group_no_one" attrs="{'invisible': [('program_type', '!=', 'coupons')]}">
|
||||
<field name="mode" widget="radio" invisible="program_type == 'ewallet'"/>
|
||||
<field name="customer_ids" widget="many2many_tags" placeholder="For all customers" invisible="mode == 'anonymous'"/>
|
||||
<field name="customer_tag_ids" widget="many2many_tags" invisible="mode == 'anonymous'" options="{'color_field': 'color'}"/>
|
||||
<field name="coupon_qty" string="Quantity to generate" readonly="mode == 'selected'" required="mode == 'anonymous'"/>
|
||||
<label string="Coupon value" for="points_granted" groups="base.group_no_one" invisible="program_type != 'coupons'"/>
|
||||
<span class="d-inline-block" groups="base.group_no_one" invisible="program_type != 'coupons'">
|
||||
<field name="points_granted" class="oe_inline"/>
|
||||
<field name="points_name" class="oe_inline"/>
|
||||
</span>
|
||||
<label string="Gift Card value" for="points_granted" attrs="{'invisible': [('program_type', '!=', 'gift_card')]}"/>
|
||||
<span class="d-inline-block" attrs="{'invisible': [('program_type', '!=', 'gift_card')]}">
|
||||
<label string="Gift Card value" for="points_granted" invisible="program_type != 'gift_card'"/>
|
||||
<span class="d-inline-block" invisible="program_type != 'gift_card'">
|
||||
<field name="points_granted" class="w-auto oe_inline me-1"/>
|
||||
<field name="points_name" class="d-inline" no_label="1"/>
|
||||
</span>
|
||||
<label string="eWallet value" for="points_granted" attrs="{'invisible': [('program_type', '!=', 'ewallet')]}"/>
|
||||
<span class="d-inline-block" attrs="{'invisible': [('program_type', '!=', 'ewallet')]}">
|
||||
<label string="eWallet value" for="points_granted" invisible="program_type != 'ewallet'"/>
|
||||
<span class="d-inline-block" invisible="program_type != 'ewallet'">
|
||||
<field name="points_granted" class="w-auto oe_inline me-1"/>
|
||||
<field name="points_name" class="d-inline" no_label="1"/>
|
||||
</span>
|
||||
<field name="valid_until"/>
|
||||
</group>
|
||||
<group class="d-flex flex-column">
|
||||
<div class="border-bottom w-100 fw-bold">Description</div>
|
||||
<field name="description" nolabel="1" placeholder="Example: Gift for customer" required="True"/>
|
||||
</group>
|
||||
</group>
|
||||
<div class="alert alert-warning text-center" invisible="customer_ids or mode == 'anonymous'" role="alert">
|
||||
<field name="confirmation_message"/>
|
||||
</div>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="generate_coupons" type="object" class="btn-primary" data-hotkey="q">
|
||||
<span attrs="{'invisible': [('will_send_mail', '=', False)]}">
|
||||
<span invisible="not will_send_mail">
|
||||
Generate and Send
|
||||
</span>
|
||||
<span attrs="{'invisible': [('will_send_mail', '=', True)]}">
|
||||
<span invisible="will_send_mail">
|
||||
Generate
|
||||
</span>
|
||||
<field name="program_type" nolabel="1"/>
|
||||
</button>
|
||||
<button special="cancel" data-hotkey="z" string="Cancel"/>
|
||||
<button special="cancel" data-hotkey="x" string="Cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue