diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/stock_dropshipping/models | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/stock_dropshipping/models')
| -rw-r--r-- | addons/stock_dropshipping/models/__init__.py | 7 | ||||
| -rw-r--r-- | addons/stock_dropshipping/models/purchase.py | 26 | ||||
| -rw-r--r-- | addons/stock_dropshipping/models/res_company.py | 117 | ||||
| -rw-r--r-- | addons/stock_dropshipping/models/sale.py | 31 | ||||
| -rw-r--r-- | addons/stock_dropshipping/models/stock.py | 30 |
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) |
