Skip to content

Commit

Permalink
[ADD/IMP] added module for shipment sync + other improvements
Browse files Browse the repository at this point in the history
- Option added to hide payment methods based country
- Increse the request timeout (due to chages in the latest Mollie python SDK)
- Other bug fixes
  • Loading branch information
odoo-mvds committed Mar 31, 2021
1 parent c831b2d commit 06895df
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 7 deletions.
3 changes: 3 additions & 0 deletions mollie_shipment_sync/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import models
25 changes: 25 additions & 0 deletions mollie_shipment_sync/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-

{
'name': 'Mollie Shipment Sync',
'version': '14.0.0.0',
'description': '',
'summary': 'Sync shipment details to mollie payments',
'author': 'Mollie',
'maintainer': 'Applix',
'license': 'LGPL-3',
'category': '',
'depends': [
'sale_management',
'payment_mollie_official'
],
'data': [
'views/sale_order.xml',
'views/payment_acquirer.xml',
'data/cron.xml'
],

'images': [
'static/description/cover.png',
],
}
14 changes: 14 additions & 0 deletions mollie_shipment_sync/data/cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="sync_shipment_cron" model="ir.cron">
<field name="name">Mollie: sync shipment data</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="interval_number">1</field>
<field name="interval_type">hours</field>
<field name="numbercall">-1</field>
<field name="state">code</field>
<field name="code">model._cron_mollie_sync_shipment()</field>
</record>

</odoo>
4 changes: 4 additions & 0 deletions mollie_shipment_sync/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-

from . import sale_order
from . import payment_acquirer
22 changes: 22 additions & 0 deletions mollie_shipment_sync/models/payment_acquirer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-

from odoo import _, api, fields, models
from mollie.api.error import UnprocessableEntityError


class PaymentAcquirerMollie(models.Model):
_inherit = 'payment.acquirer'

mollie_auto_sync_shipment = fields.Boolean()

# -----------------------------------------------
# Methods that uses to mollie python lib
# -----------------------------------------------

def _api_mollie_sync_shipment(self, order_reference, shipment_data):
order = self._api_mollie_get_order(order_reference)
try:
shipment = order.create_shipment(shipment_data)
except UnprocessableEntityError as e:
return {'error': str(e)}
return shipment
59 changes: 59 additions & 0 deletions mollie_shipment_sync/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-

from odoo import _, api, fields, models


class SaleOrder(models.Model):
_inherit = 'sale.order'

mollie_payment = fields.Boolean(compute='_compute_mollie_payment')
mollie_need_shipment_sync = fields.Boolean(compute='_compute_mollie_need_shipment_sync', store=True)

def mollie_sync_shipment_data(self):
transaction = self._mollie_get_valid_transaction()
if transaction:
data = transaction.acquirer_id._mollie_get_payment_data(transaction.acquirer_reference)
shipment_lines = []
if data and data.get('lines'):
for mollie_line in data.get('lines'):
mollie_line_metadata = mollie_line.get('metadata')
if mollie_line_metadata:
order_line = self.order_line.filtered(lambda l: l.id == mollie_line_metadata.get('line_id'))
if order_line and order_line.qty_delivered > mollie_line['quantityShipped']:
qty_to_ship = order_line.qty_delivered - mollie_line['quantityShipped']
if qty_to_ship and mollie_line.get('shippableQuantity') >= qty_to_ship:
shipment_lines.append({
'id': mollie_line['id'],
'quantity': int(qty_to_ship) # mollie does not support float values
})
if shipment_lines:
transaction.acquirer_id._api_mollie_sync_shipment(transaction.acquirer_reference, {'lines': shipment_lines})

# For all the cases we will un-mark the sales orders
self.mollie_need_shipment_sync = False

def _compute_mollie_payment(self):
for order in self:
valid_transaction = order._mollie_get_valid_transaction()
order.mollie_payment = len(valid_transaction) >= 1

@api.depends('order_line.qty_delivered')
def _compute_mollie_need_shipment_sync(self):
for order in self:
if order.mollie_payment:
order.mollie_need_shipment_sync = True
else:
order.mollie_need_shipment_sync = False

def _mollie_get_valid_transaction(self):
self.ensure_one()
return self.transaction_ids.filtered(lambda t: t.acquirer_id.provider == 'mollie' and t.state in ['authorized', 'done'] and t.acquirer_reference.startswith("ord_"))

def _cron_mollie_sync_shipment(self):
mollie_acquirer = self.env.ref('payment_mollie_official.payment_acquirer_mollie')
if mollie_acquirer.mollie_auto_sync_shipment:
orders = self.search([('mollie_need_shipment_sync', '=', True)])
for order in orders:
order.mollie_sync_shipment_data()
self.env.cr.commit()
return True
Binary file added mollie_shipment_sync/static/description/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions mollie_shipment_sync/static/description/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<div class="row py-3">
<div class="col-md-6 py-3">
<img src="//apps.odoocdn.com/apps/assets/14.0/payment_mollie_official/img/icon-rect.png?5daf2f9">
<h1 style="color:#000; font-weight:bold">
Sync <b style="font-weight:bolder; color:#0077ff">shipment</b>
data from odoo to mollie.
</h1>
<div class="alert alert-warning">
<i class="fa fa-exclamation-triangle"></i> Make sure you are using <b>Mollie payment</b> module >= 14.0.0.5
</div>
</div>
<div class="col-md-6">
<img class="img img-fluid shadow" src="mollie_1.png" style="background-color:#f8f9fa; padding:9px 0px; border-radius:10px; border:1px solid #cccccc7a; padding-top:10px">
</div>
</div>
<h1 style="color:#000; font-weight:bold; font-size:50px" class="mt-5 text-center mb-0">How to configure</h1>
<div class="text-center text-muted" style="font-weight:400; margin-bottom:18px">
<span style="width:73px; height:10px; display:inline-block; border-radius:4px; background-color:#0077ff"> </span>
</div>
<h3>
<span class="badge badge-pill mr-2" style="background-color:#0077ff; color:#fff; padding:5px 17px; font-size:14px"> Step 1 </span>
<span style="display:inline-block; font-size:19px"> Download the module and place the module in apps folder and install the module. </span>
</h3>


<h1 style="color:#000; font-weight:bold; font-size:50px" class="mt-5 text-center mb-0">How to Use it</h1>
<div class="text-center text-muted" style="font-weight:400; margin-bottom:18px">
<span style="width:73px; height:10px; display:inline-block; border-radius:4px; background-color:#0077ff"> </span>
</div>
<h3>
<span class="badge badge-pill mr-2" style="background-color:#0077ff; color:#fff; padding:5px 17px; font-size:14px">
Step 1 </span>
<span style="display:inline-block; font-size:19px"> After installation, you will see the
<span style="color:#0077ff"> Sync Shipment </span> button on order (if it is paid with mollie)
</span>
</h3>
<h3>
<span class="badge badge-pill mr-2" style="background-color:#0077ff; color:#fff; padding:5px 17px; font-size:14px">
Step 2 </span>
<span style="display:inline-block; font-size:19px"> Clicking on <span style="color:#0077ff">Sync Shipment </span>
button will sync shipment data with mollie.
</h3>

<div class="alert alert-info mt-1 d-inline-block" style="margin-left: 95px;background-color: #dfeeff;color: #0077ff;">
You can enable, automatic shipment sync from the settings of mollie payment.
</div>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions mollie_shipment_sync/views/payment_acquirer.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="payment_acquirer_inh_view_form" model="ir.ui.view">
<field name="name">payment.acquirer.view.form</field>
<field name="model">payment.acquirer</field>
<field name="inherit_id" ref="payment_mollie_official.acquirer_form_view_mollie"/>
<field name="arch" type="xml">
<xpath expr="//group/small" position="after">
<field name="mollie_auto_sync_shipment" />
</xpath>
</field>
</record>

</odoo>
17 changes: 17 additions & 0 deletions mollie_shipment_sync/views/sale_order.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="sale_order_inh_view_form" model="ir.ui.view">
<field name="name">sale.order.view.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="state" position="before">
<button name="mollie_sync_shipment_data" attrs="{'invisible': [('mollie_payment', '=', False)]}" type="object" string="Sync Shipment"/>
<field name="mollie_payment" invisible="1"/>
<field name="mollie_need_shipment_sync" invisible="1"/>
</field>
</field>
</record>

</odoo>
2 changes: 1 addition & 1 deletion payment_mollie_official/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

{
'name': 'Mollie Payments',
'version': '14.0.0.4',
'version': '14.0.0.5',
'category': 'eCommerce',
'license': 'LGPL-3',
'author': 'Mollie',
Expand Down
13 changes: 12 additions & 1 deletion payment_mollie_official/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,18 @@ def mollie_process_refund(self):

def _find_valid_mollie_transactions(self):
self.ensure_one()
return self.reversed_entry_id.transaction_ids.filtered(lambda tx: tx.state == 'done' and tx.acquirer_id.provider == 'mollie')

# CASE 1: For the credit notes generated from invoice
transections = self.reversed_entry_id.transaction_ids.filtered(lambda tx: tx.state == 'done' and tx.acquirer_id.provider == 'mollie')

# CASE 2: For the credit note generated due to returns of delivery
# TODO: In this case credit note is generated from Sale order and so both invoice are not linked as reversal move.
# this module does not have direct dependencies on the sales module. We are checking fields in move line to check sale order is linked.
# and we get transections info from sale order. May be, we can create glue module for this.
if not transections and 'sale_line_ids' in self.invoice_line_ids._fields:
transections = self.invoice_line_ids.mapped('sale_line_ids.order_id.transaction_ids')

return transections

def _post(self, soft=True):
""" Vouchers might create extra payment record for reminder amount
Expand Down
6 changes: 4 additions & 2 deletions payment_mollie_official/models/mollie_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class MolliePaymentMethod(models.Model):
min_amount = fields.Float()
max_amount = fields.Float()

supports_order_api = fields.Boolean()
supports_payment_api = fields.Boolean()
supports_order_api = fields.Boolean(string="Supports Order API")
supports_payment_api = fields.Boolean(string="Supports Payment API")

payment_issuer_ids = fields.Many2many('mollie.payment.method.issuer', string='Issuers')

country_ids = fields.Many2many('res.country', string='Country Availability')
14 changes: 13 additions & 1 deletion payment_mollie_official/models/payment_acquirer.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ def mollie_get_active_methods(self, order=None):
if request and request.httprequest.path == '/website_payment/pay':
methods = methods.filtered(lambda m: m.supports_payment_api == True)

# Hide based on country
if request:
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
if country_code:
methods = methods.filtered(lambda m: not m.country_ids or country_code in m.country_ids.mapped('code'))

return methods

def mollie_form_generate_values(self, tx_values):
Expand Down Expand Up @@ -313,7 +319,7 @@ def _mollie_get_payment_data(self, transection_reference, force_payment=False):
# -----------------------------------------------

def _api_mollie_get_client(self):
mollie_client = MollieClient()
mollie_client = MollieClient(timeout=5)
# TODO: [PGA] Add partical validation for keys e.g. production key should start from live_

if self.state == 'enabled':
Expand Down Expand Up @@ -489,6 +495,12 @@ def _mollie_prepare_lines_common(self, line):
base_url = self.get_base_url()
product_data['productUrl'] = urls.url_join(base_url, line.product_id.website_url)

# Metadata - used to sync delivery data with shipment API
product_data['metadata'] = {
'line_id': line.id,
'product_id': line.product_id.id
}

return product_data

# -----------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions payment_mollie_official/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ <h1 style="color: #000;font-weight: bold;/* font-size: 50px; */" class="mt-5 tex
<div class="text-center text-muted" style="font-weight:400; margin-bottom:18px">
<span style="width:73px;height: 10px;display:inline-block;border-radius: 4px;background-color: #0077ff;"> </span>
</div>
<div class="card mx-auto w-md-75">
<div class="card-header bg-200">
<h4 class="m-0">v14.0.0.5</h4>
</div>
<div class="card-body">
<div> <b class="text-success"> NEW </b> Option to hide the payment methods based on country. </div>
<div> <b class="text-warning"> UPDATE </b> Send extra metadata for shipment API. </div>
<div> <b class="text-danger"> FIX </b> Increase the timeout request (due to python SDK change). </div>
<div> <b class="text-danger"> FIX </b> Minor bug fixes. </div>
</div>
</div>

<div class="card mx-auto w-md-75">
<div class="card-header bg-200">
Expand Down
10 changes: 8 additions & 2 deletions payment_mollie_official/views/payment_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
<field name="mollie_profile_id" attrs="{'required':[ ('provider', '=', 'mollie'), ('state', '=', 'enabled')]}" password="True"/>
<field name="mollie_voucher_enabled" invisible="1"/>
<label string=" " for="mollie_profile_id"> </label>
<small class="text-muted oe_edit_only"> Credit card option will not be displayed without profile ID. </small>
<small class="text-muted oe_edit_only"> Credit card option will not be displayed without profile ID.
<br/>
<b><a href="https://www.mollie.com/dashboard/developers/api-keys" target="_new"> Get your API keys <i class="fa fa-arrow-right"> </i> </a></b>
<br/>
<br/>
</small>
</group>
</xpath>
<page name="acquirer_credentials" position="after">
Expand All @@ -21,11 +26,12 @@
<tree create="0" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name" />
<field name="method_id_code"/>
<field name="method_id_code" optional="hide"/>
<field name="payment_icon_ids" widget="many2many_tags"/>
<field name="active" invisible="1"/>
<field name="journal_id" />
<field name="active_on_shop" widget="boolean_toggle"/>
<field name="country_ids" widget="many2many_tags" optional="hide"/>
<field name="min_amount" invisible="1"/>
<field name="min_amount" invisible="1"/>
<field name="supports_order_api" invisible="1"/>
Expand Down

0 comments on commit 06895df

Please sign in to comment.