itch
This commit is contained in:
parent
fa4f1b2b19
commit
57c938bb8d
5 changed files with 81 additions and 7 deletions
|
|
@ -2,10 +2,16 @@
|
||||||
{
|
{
|
||||||
'name': 'Customer Itch Cycle Management',
|
'name': 'Customer Itch Cycle Management',
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
'depends': ['base', 'sale'],
|
'depends': [
|
||||||
'author': 'Your Name',
|
'base',
|
||||||
|
'sale_stock'
|
||||||
|
],
|
||||||
|
'author': 'Benoit Vézina',
|
||||||
'category': 'Sales Management',
|
'category': 'Sales Management',
|
||||||
|
'summary': 'Manage customer itch cycles by product for proactive sales engagement.',
|
||||||
|
'website': 'https://www.bemade.org',
|
||||||
'description': "Manage customer itch cycles by product for proactive sales engagement.",
|
'description': "Manage customer itch cycles by product for proactive sales engagement.",
|
||||||
|
'license': 'AGPL-3',
|
||||||
'data': [
|
'data': [
|
||||||
'views/itch_cycle_product_partner_view.xml',
|
'views/itch_cycle_product_partner_view.xml',
|
||||||
'views/res_partner_view.xml',
|
'views/res_partner_view.xml',
|
||||||
|
|
|
||||||
|
|
@ -56,12 +56,58 @@ class ItchCycleProductPartner(models.Model):
|
||||||
store=True
|
store=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
manualy_set_cycle = fields.Integer(
|
||||||
|
string="Cycle moyen (jours) défini manuellement"
|
||||||
|
)
|
||||||
|
|
||||||
|
manualy_set_qty = fields.Float(
|
||||||
|
string="Quantité défini manuellement"
|
||||||
|
)
|
||||||
|
|
||||||
next_expected_date = fields.Date(
|
next_expected_date = fields.Date(
|
||||||
string="Prochaine vente prévue",
|
string="Prochaine vente prévue",
|
||||||
compute="_compute_next_expected_date",
|
compute="_compute_next_expected_date",
|
||||||
store=True
|
store=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
manualy_set_next_date = fields.Date(
|
||||||
|
string="Prochaine vente prévue défini manuellement"
|
||||||
|
)
|
||||||
|
|
||||||
|
calc_next_date = fields.Date(
|
||||||
|
string="Prochaine vente prévue calculée",
|
||||||
|
compute="_compute_next_expected_date",
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
|
calc_average_cycle = fields.Integer(
|
||||||
|
string="Cycle moyen (jours) calculé",
|
||||||
|
compute="_compute_itch_cycle_duration",
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
|
calc_average_qty = fields.Float(
|
||||||
|
string="Quantité moyenne calculée",
|
||||||
|
compute="_compute_mean_quantity_ordered",
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
|
@api.depends('manualy_set_cycle','average_cycle')
|
||||||
|
def _compute_itch_cycle_duration(self):
|
||||||
|
for record in self:
|
||||||
|
if record.manualy_set_cycle:
|
||||||
|
record.calc_average_cycle = record.manualy_set_cycle
|
||||||
|
else:
|
||||||
|
record.calc_average_cycle = record.average_cycle
|
||||||
|
|
||||||
|
@api.depends('manualy_set_qty','max_quantity_ordered')
|
||||||
|
def _compute_mean_quantity_ordered(self):
|
||||||
|
for record in self:
|
||||||
|
if record.manualy_set_qty:
|
||||||
|
record.calc_average_qty = record.manualy_set_qty
|
||||||
|
else:
|
||||||
|
record.calc_average_qty = record.max_quantity
|
||||||
|
|
||||||
prediction_status = fields.Selection(
|
prediction_status = fields.Selection(
|
||||||
selection=[
|
selection=[
|
||||||
('on_time', 'À l’heure'),
|
('on_time', 'À l’heure'),
|
||||||
|
|
@ -174,8 +220,8 @@ class ItchCycleProductPartner(models.Model):
|
||||||
sale_order_lines = self.env['sale.order.line'].search([
|
sale_order_lines = self.env['sale.order.line'].search([
|
||||||
('order_id.state', 'in', ['sale', 'done']), # Commandes confirmées ou terminées
|
('order_id.state', 'in', ['sale', 'done']), # Commandes confirmées ou terminées
|
||||||
('qty_delivered', '>', 0), # Quantité livrée supérieure à 0
|
('qty_delivered', '>', 0), # Quantité livrée supérieure à 0
|
||||||
('product_id', '!=', False), # Exclure les lignes sans produit
|
('product_id', '!=', False) # Exclure les lignes sans produit
|
||||||
('order_id.partner_id', '=', 5024659), # un client pour test
|
# ('order_id.partner_id', '=', 5024659), # un client pour test
|
||||||
])
|
])
|
||||||
|
|
||||||
# Carte pour regrouper par couple (client, produit)
|
# Carte pour regrouper par couple (client, produit)
|
||||||
|
|
@ -227,22 +273,27 @@ class ItchCycleProductPartner(models.Model):
|
||||||
})
|
})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@api.depends('sale_order_line_ids')
|
||||||
def _compute_quantity_total_ordered(self):
|
def _compute_quantity_total_ordered(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.quantity_total_ordered = sum(record.sale_order_line_ids.mapped('product_uom_qty'))
|
record.quantity_total_ordered = sum(record.sale_order_line_ids.mapped('product_uom_qty'))
|
||||||
|
|
||||||
|
@api.depends('sale_order_line_ids')
|
||||||
def _compute_quantity_of_orders(self):
|
def _compute_quantity_of_orders(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.quantity_of_orders = len(record.sale_order_line_ids)
|
record.quantity_of_orders = len(record.sale_order_line_ids)
|
||||||
|
|
||||||
|
@api.depends('sale_order_line_ids')
|
||||||
def _compute_min_quantity_ordered(self):
|
def _compute_min_quantity_ordered(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.min_quantity_ordered = min(record.sale_order_line_ids.mapped('product_uom_qty'))
|
record.min_quantity_ordered = min(record.sale_order_line_ids.mapped('product_uom_qty'))
|
||||||
|
|
||||||
|
@api.depends('sale_order_line_ids')
|
||||||
def _compute_max_quantity_ordered(self):
|
def _compute_max_quantity_ordered(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.max_quantity_ordered = max(record.sale_order_line_ids.mapped('product_uom_qty'))
|
record.max_quantity_ordered = max(record.sale_order_line_ids.mapped('product_uom_qty'))
|
||||||
|
|
||||||
|
@api.depends('sale_order_line_ids')
|
||||||
def _compute_mean_quantity_ordered(self):
|
def _compute_mean_quantity_ordered(self):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.mean_quantity_ordered = np.mean(record.sale_order_line_ids.mapped('product_uom_qty'))
|
record.mean_quantity_ordered = np.mean(record.sale_order_line_ids.mapped('product_uom_qty'))
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ class ResPartner(models.Model):
|
||||||
itch_cycle_product_ids = fields.One2many(
|
itch_cycle_product_ids = fields.One2many(
|
||||||
comodel_name='itch.cycle.product.partner',
|
comodel_name='itch.cycle.product.partner',
|
||||||
inverse_name='partner_id',
|
inverse_name='partner_id',
|
||||||
string="Itch Cycles Produits"
|
string="Itch Cycles Products"
|
||||||
)
|
)
|
||||||
|
|
||||||
reorder_cycle_product_ids = fields.One2many(
|
reorder_cycle_product_ids = fields.One2many(
|
||||||
comodel_name='itch.cycle.product.partner',
|
comodel_name='itch.cycle.product.partner',
|
||||||
inverse_name='partner_id',
|
inverse_name='partner_id',
|
||||||
string="Itch Cycles Produits",
|
string="Reorder Cycles Products",
|
||||||
domain=[('quantity_of_orders', '>', 1)]
|
domain=[('quantity_of_orders', '>', 1)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,18 @@ class SaleOrderLine(models.Model):
|
||||||
string="Cycle Produit/Partenaire"
|
string="Cycle Produit/Partenaire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
stock_move_ids = fields.One2many(
|
||||||
|
comodel_name='stock.move',
|
||||||
|
inverse_name='sale_line_id',
|
||||||
|
string="Mouvements de stock"
|
||||||
|
)
|
||||||
|
|
||||||
|
sale_date = fields.Datetime(
|
||||||
|
string="Date de vente",
|
||||||
|
related='order_id.date_order',
|
||||||
|
store=True
|
||||||
|
)
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
# Appeler le super pour créer les lignes
|
# Appeler le super pour créer les lignes
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,11 @@
|
||||||
<group string="Informations principales">
|
<group string="Informations principales">
|
||||||
<field name="partner_id"/>
|
<field name="partner_id"/>
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
|
<group string="Surchage manuelle">
|
||||||
|
<field name="manualy_set_cycle"/>
|
||||||
|
<field name="manualy_set_qty"/>
|
||||||
|
<field name="manualy_set_next_date"/>
|
||||||
|
</group>
|
||||||
</group>
|
</group>
|
||||||
<group string="Statistiques">
|
<group string="Statistiques">
|
||||||
<field name="itch_cycle_duration" readonly="1"/>
|
<field name="itch_cycle_duration" readonly="1"/>
|
||||||
|
|
@ -36,7 +41,6 @@
|
||||||
<field name="last_purchase_date" readonly="1"/>
|
<field name="last_purchase_date" readonly="1"/>
|
||||||
<field name="next_expected_date" readonly="1"/>
|
<field name="next_expected_date" readonly="1"/>
|
||||||
<field name="next_follow_up_date"/>
|
<field name="next_follow_up_date"/>
|
||||||
<field name="prediction_status" widget="statusbar" options="{'on_time': 'green', 'delayed': 'red'}"/>
|
|
||||||
<field name="quantity_of_orders" readonly="1"/>
|
<field name="quantity_of_orders" readonly="1"/>
|
||||||
<field name="quantity_total_ordered" readonly="1"/>
|
<field name="quantity_total_ordered" readonly="1"/>
|
||||||
<field name="min_quantity_ordered" readonly="1"/>
|
<field name="min_quantity_ordered" readonly="1"/>
|
||||||
|
|
@ -52,6 +56,7 @@
|
||||||
<field name="product_id"/>
|
<field name="product_id"/>
|
||||||
<field name="price_unit"/>
|
<field name="price_unit"/>
|
||||||
<field name="product_uom_qty"/>
|
<field name="product_uom_qty"/>
|
||||||
|
<field name="sale_date"/>
|
||||||
<field name="discount"/>
|
<field name="discount"/>
|
||||||
</tree>
|
</tree>
|
||||||
</field>
|
</field>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue