summaryrefslogtreecommitdiff
path: root/addons/stock_dropshipping/models
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/stock_dropshipping/models
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/stock_dropshipping/models')
-rw-r--r--addons/stock_dropshipping/models/__init__.py7
-rw-r--r--addons/stock_dropshipping/models/purchase.py26
-rw-r--r--addons/stock_dropshipping/models/res_company.py117
-rw-r--r--addons/stock_dropshipping/models/sale.py31
-rw-r--r--addons/stock_dropshipping/models/stock.py30
5 files changed, 211 insertions, 0 deletions
diff --git a/addons/stock_dropshipping/models/__init__.py b/addons/stock_dropshipping/models/__init__.py
new file mode 100644
index 00000000..9e307a98
--- /dev/null
+++ b/addons/stock_dropshipping/models/__init__.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import purchase
+from . import res_company
+from . import sale
+from . import stock
diff --git a/addons/stock_dropshipping/models/purchase.py b/addons/stock_dropshipping/models/purchase.py
new file mode 100644
index 00000000..faf50652
--- /dev/null
+++ b/addons/stock_dropshipping/models/purchase.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+
+
+class PurchaseOrderLine(models.Model):
+ _inherit = 'purchase.order.line'
+
+ def _prepare_stock_moves(self, picking):
+ res = super(PurchaseOrderLine, self)._prepare_stock_moves(picking)
+ for re in res:
+ re['sale_line_id'] = self.sale_line_id.id
+ return res
+
+ def _find_candidate(self, product_id, product_qty, product_uom, location_id, name, origin, company_id, values):
+ # if this is defined, this is a dropshipping line, so no
+ # this is to correctly map delivered quantities to the so lines
+ lines = self.filtered(lambda po_line: po_line.sale_line_id.id == values['sale_line_id']) if values.get('sale_line_id') else self
+ return super(PurchaseOrderLine, lines)._find_candidate(product_id, product_qty, product_uom, location_id, name, origin, company_id, values)
+
+ @api.model
+ def _prepare_purchase_order_line_from_procurement(self, product_id, product_qty, product_uom, company_id, values, po):
+ res = super()._prepare_purchase_order_line_from_procurement(product_id, product_qty, product_uom, company_id, values, po)
+ res['sale_line_id'] = values.get('sale_line_id', False)
+ return res
diff --git a/addons/stock_dropshipping/models/res_company.py b/addons/stock_dropshipping/models/res_company.py
new file mode 100644
index 00000000..8b069115
--- /dev/null
+++ b/addons/stock_dropshipping/models/res_company.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+
+
+class ResCompany(models.Model):
+ _inherit = 'res.company'
+
+ # -------------------------------------------------------------------------
+ # Sequences
+ # -------------------------------------------------------------------------
+ def _create_dropship_sequence(self):
+ dropship_vals = []
+ for company in self:
+ dropship_vals.append({
+ 'name': 'Dropship (%s)' % company.name,
+ 'code': 'stock.dropshipping',
+ 'company_id': company.id,
+ 'prefix': 'DS/',
+ 'padding': 5,
+ })
+ if dropship_vals:
+ self.env['ir.sequence'].create(dropship_vals)
+
+ @api.model
+ def create_missing_dropship_sequence(self):
+ company_ids = self.env['res.company'].search([])
+ company_has_dropship_seq = self.env['ir.sequence'].search([('code', '=', 'stock.dropshipping')]).mapped('company_id')
+ company_todo_sequence = company_ids - company_has_dropship_seq
+ company_todo_sequence._create_dropship_sequence()
+
+ def _create_per_company_sequences(self):
+ super(ResCompany, self)._create_per_company_sequences()
+ self._create_dropship_sequence()
+
+ # -------------------------------------------------------------------------
+ # Picking types
+ # -------------------------------------------------------------------------
+ def _create_dropship_picking_type(self):
+ dropship_vals = []
+ for company in self:
+ sequence = self.env['ir.sequence'].search([
+ ('code', '=', 'stock.dropshipping'),
+ ('company_id', '=', company.id),
+ ])
+ dropship_vals.append({
+ 'name': 'Dropship',
+ 'company_id': company.id,
+ 'warehouse_id': False,
+ 'sequence_id': sequence.id,
+ 'code': 'incoming',
+ 'default_location_src_id': self.env.ref('stock.stock_location_suppliers').id,
+ 'default_location_dest_id': self.env.ref('stock.stock_location_customers').id,
+ 'sequence_code': 'DS',
+ })
+ if dropship_vals:
+ self.env['stock.picking.type'].create(dropship_vals)
+
+ @api.model
+ def create_missing_dropship_picking_type(self):
+ company_ids = self.env['res.company'].search([])
+ company_has_dropship_picking_type = (
+ self.env['stock.picking.type']
+ .search([
+ ('default_location_src_id.usage', '=', 'supplier'),
+ ('default_location_dest_id.usage', '=', 'customer'),
+ ])
+ .mapped('company_id')
+ )
+ company_todo_picking_type = company_ids - company_has_dropship_picking_type
+ company_todo_picking_type._create_dropship_picking_type()
+
+ def _create_per_company_picking_types(self):
+ super(ResCompany, self)._create_per_company_picking_types()
+ self._create_dropship_picking_type()
+
+ # -------------------------------------------------------------------------
+ # Stock rules
+ # -------------------------------------------------------------------------
+ def _create_dropship_rule(self):
+ dropship_route = self.env.ref('stock_dropshipping.route_drop_shipping')
+ supplier_location = self.env.ref('stock.stock_location_suppliers')
+ customer_location = self.env.ref('stock.stock_location_customers')
+
+ dropship_vals = []
+ for company in self:
+ dropship_picking_type = self.env['stock.picking.type'].search([
+ ('company_id', '=', company.id),
+ ('default_location_src_id.usage', '=', 'supplier'),
+ ('default_location_dest_id.usage', '=', 'customer'),
+ ], limit=1, order='sequence')
+ dropship_vals.append({
+ 'name': '%s → %s' % (supplier_location.name, customer_location.name),
+ 'action': 'buy',
+ 'location_id': customer_location.id,
+ 'location_src_id': supplier_location.id,
+ 'procure_method': 'make_to_stock',
+ 'route_id': dropship_route.id,
+ 'picking_type_id': dropship_picking_type.id,
+ 'company_id': company.id,
+ })
+ if dropship_vals:
+ self.env['stock.rule'].create(dropship_vals)
+
+ @api.model
+ def create_missing_dropship_rule(self):
+ dropship_route = self.env.ref('stock_dropshipping.route_drop_shipping')
+
+ company_ids = self.env['res.company'].search([])
+ company_has_dropship_rule = self.env['stock.rule'].search([('route_id', '=', dropship_route.id)]).mapped('company_id')
+ company_todo_rule = company_ids - company_has_dropship_rule
+ company_todo_rule._create_dropship_rule()
+
+ def _create_per_company_rules(self):
+ super(ResCompany, self)._create_per_company_rules()
+ self._create_dropship_rule()
diff --git a/addons/stock_dropshipping/models/sale.py b/addons/stock_dropshipping/models/sale.py
new file mode 100644
index 00000000..520e7b53
--- /dev/null
+++ b/addons/stock_dropshipping/models/sale.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+
+
+class SaleOrderLine(models.Model):
+ _inherit = 'sale.order.line'
+
+ def _compute_is_mto(self):
+ super(SaleOrderLine, self)._compute_is_mto()
+ for line in self:
+ if not line.display_qty_widget or line.is_mto:
+ continue
+ product_routes = line.route_id or (line.product_id.route_ids + line.product_id.categ_id.total_route_ids)
+ for pull_rule in product_routes.mapped('rule_ids'):
+ if pull_rule.picking_type_id.sudo().default_location_src_id.usage == 'supplier' and\
+ pull_rule.picking_type_id.sudo().default_location_dest_id.usage == 'customer':
+ line.is_mto = True
+ break
+
+ def _get_qty_procurement(self, previous_product_uom_qty):
+ # People without purchase rights should be able to do this operation
+ purchase_lines_sudo = self.sudo().purchase_line_ids
+ if purchase_lines_sudo.filtered(lambda r: r.state != 'cancel'):
+ qty = 0.0
+ for po_line in purchase_lines_sudo.filtered(lambda r: r.state != 'cancel'):
+ qty += po_line.product_uom._compute_quantity(po_line.product_qty, self.product_uom, rounding_method='HALF-UP')
+ return qty
+ else:
+ return super(SaleOrderLine, self)._get_qty_procurement(previous_product_uom_qty=previous_product_uom_qty)
diff --git a/addons/stock_dropshipping/models/stock.py b/addons/stock_dropshipping/models/stock.py
new file mode 100644
index 00000000..c44fe2cc
--- /dev/null
+++ b/addons/stock_dropshipping/models/stock.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+
+
+class StockRule(models.Model):
+ _inherit = 'stock.rule'
+
+ @api.model
+ def _get_procurements_to_merge_groupby(self, procurement):
+ """ Do not group purchase order line if they are linked to different
+ sale order line. The purpose is to compute the delivered quantities.
+ """
+ return procurement.values.get('sale_line_id'), super(StockRule, self)._get_procurements_to_merge_groupby(procurement)
+
+ @api.model
+ def _get_procurements_to_merge_sorted(self, procurement):
+ return procurement.values.get('sale_line_id'), super(StockRule, self)._get_procurements_to_merge_sorted(procurement)
+
+
+class ProcurementGroup(models.Model):
+ _inherit = "procurement.group"
+
+ @api.model
+ def _get_rule_domain(self, location, values):
+ if 'sale_line_id' in values and values.get('company_id'):
+ return [('location_id', '=', location.id), ('action', '!=', 'push'), ('company_id', '=', values['company_id'].id)]
+ else:
+ return super(ProcurementGroup, self)._get_rule_domain(location, values)