(51) magento集成增加到款通知
这篇主要讲述如何二开增加自己的功能,我没有继承方式二开,习惯是不好的,直接改了原来的模块。
达到效果就这样,当在网站支付成功,会同步到ERP系统中。下面来讲述实现过程
建立文件 payment_notice.py
# -*- coding: utf-8 -*-
import logging
import xmlrpclib
from datetime import datetime, timedelta
import openerp.addons.decimal_precision as dp
from openerp import models, fields, api, _
from openerp.addons.connector.connector import ConnectorUnit
from openerp.addons.connector.exception import (NothingToDoJob,
FailedJobError,
IDMissingInBackend)
from openerp.addons.connector.queue.job import job
from openerp.addons.connector.unit.mapper import (mapping,
ImportMapper
)
from .unit.backend_adapter import (GenericAdapter,
MAGENTO_DATETIME_FORMAT,
)
from .unit.import_synchronizer import (DelayedBatchImporter,
MagentoImporter,
)
from .unit.mapper import normalize_datetime
from .backend import magento
from .connector import get_environment
from openerp.tools.float_utils import float_round
_logger = logging.getLogger(__name__)
class MagentoPaymentNotice(models.Model):
_name = 'magento.payment.notice'
_inherit = 'magento.binding'
_description = 'Magento Payment Notice'
_inherits = {'payment.notice': 'openerp_id'}
openerp_id = fields.Many2one(comodel_name='payment.notice',
string='Payment Notice',
required=True,
ondelete='cascade')
total_amount = fields.Float(
string='Total amount',
digits_compute=dp.get_precision('Account')
)
total_amount_tax = fields.Float(
string='Total amount w. tax',
digits_compute=dp.get_precision('Account')
)
magento_order_id = fields.Integer(string='Magento Order ID',
help="'order_id' field in Magento")
# when a sale order is modified, Magento creates a new one, cancels
# the parent order and link the new one to the canceled parent
magento_parent_id = fields.Many2one(comodel_name='magento.sale.order',
string='Parent Magento Order')
storeview_id = fields.Many2one(comodel_name='magento.storeview',
string='Magento Storeview')
store_id = fields.Many2one(related='storeview_id.store_id',
string='Storeview',
readonly=True)
class PaymentNotice(models.Model):
_inherit = 'payment.notice'
magento_bind_ids = fields.One2many(
comodel_name='magento.payment.notice',
inverse_name='openerp_id',
string="Magento Bindings",
)
@magento
class PaymentNoticeAdapter(GenericAdapter):
_model_name = 'magento.payment.notice'
_magento_model = 'sales_order'
_admin_path = '{model}/view/order_id/{id}'
def _call(self, method, arguments):
try:
return super(PaymentNoticeAdapter, self)._call(method, arguments)
except xmlrpclib.Fault as err:
# this is the error in the Magento API
# when the sales order does not exist
if err.faultCode == 100:
raise IDMissingInBackend
else:
raise
def search(self, filters=None, from_date=None, to_date=None,
magento_storeview_ids=None):
""" Search records according to some criteria
and returns a list of ids
:rtype: list
"""
if filters is None:
filters = {}
dt_fmt = MAGENTO_DATETIME_FORMAT
if from_date is not None:
filters.setdefault('created_at', {})
filters['created_at']['from'] = from_date.strftime(dt_fmt)
if to_date is not None:
filters.setdefault('created_at', {})
filters['created_at']['to'] = to_date.strftime(dt_fmt)
if magento_storeview_ids is not None:
filters['store_id'] = {'in': magento_storeview_ids}
arguments = {'imported': False,
# 'limit': 200,
'filters': filters,
}
return super(PaymentNoticeAdapter, self).search(arguments)
def read(self, id, attributes=None):
""" Returns the information of a record
:rtype: dict
"""
record = self._call('%s.info' % self._magento_model,
[id, attributes])
return record
@magento
class PaymentNoticeBatchImport(DelayedBatchImporter):
_model_name = ['magento.payment.notice']
def _import_record(self, record_id, description=None,**kwargs):
""" Import the record directly """
return super(PaymentNoticeBatchImport, self)._import_record(
record_id,description=description, max_retries=0, priority=5)
def run(self, filters=None):
""" Run the synchronization """
if filters is None:
filters = {}
filters['status'] = {'in': ['complete', 'processing', 'challenged']}
from_date = filters.pop('from_date', None)
to_date = filters.pop('to_date', None)
magento_storeview_ids = [filters.pop('magento_storeview_id')]
record_ids = self.backend_adapter.search(
filters,
from_date=from_date,
to_date=to_date,
magento_storeview_ids=magento_storeview_ids)
_logger.info('search for magento saleorders %s returned %s',
filters, record_ids)
for record_id in record_ids:
self._import_record(
record_id,
description='Import payment notice, Order# of website: %s' % self.backend_adapter.read(record_id).get('increment_id')
)
@magento
class PaymentNoticeImportRule(ConnectorUnit):
_model_name = ['magento.payment.notice']
def check(self, record):
""" Check whether the current sale order should be imported
or not. It will actually use the payment method configuration
and see if the choosed rule is fullfilled.
:returns: True if the sale order should be imported
:rtype: boolean
"""
payment_method = record['payment']['method']
method = self.env['payment.method'].search(
[('magento_payment_code', '=', payment_method)],
limit=1,
)
if not method:
raise FailedJobError(
"The configuration is missing for the Payment Method '%s'.\n\n"
"Resolution:\n"
"- Go to "
"'Sales > Configuration > Sales > Customer Payment Method\n"
"- Create a new Payment Method with name '%s'\n"
"-Eventually link the Payment Method to an existing Workflow "
"Process or create a new one." % (payment_method,
payment_method))
@magento
class PaymentNoticeImportMapper(ImportMapper):
_model_name = 'magento.payment.notice'
direct = [('increment_id', 'magento_id'),
('order_id', 'magento_order_id'),
('grand_total', 'total_amount'),
('tax_amount', 'total_amount_tax'),
('store_id', 'storeview_id'),
]
@mapping
def sale_order_site(self, record):
sale_order_site = record['increment_id']
return {'sale_order_site': sale_order_site}
@mapping
def amount(self, record):
amount = record['grand_total']
return {'amount': amount}
@mapping
def currency(self, record):
record_currency = record['order_currency_code']
currency = self.env['res.currency'].search(
[['name', '=', record_currency]],
limit=1,
)
assert currency, ("currency %s should exist because the import fails "
"in PaymentNoticeImporter._before_import when it is "
" missing" % record['order_currency_code'])
return {'currency_id': currency.id}
@mapping
def payment(self, record):
record_method = record['payment']['method']
method = self.env['payment.method'].search(
[['magento_payment_code', '=', record_method]],
limit=1,
)
assert method, ("method %s should exist because the import fails "
"in PaymentNoticeImporter._before_import when it is "
" missing" % record['payment']['method'])
return {'payment_method_id': method.id}
@mapping
def description(self, record):
order_date = normalize_datetime('created_at')(self, record, '')
dd=datetime.strptime(order_date, '%Y-%m-%d %H:%M:%S')
order_date_f=dd.strftime('%m/%d/%Y')
record_currency = record['order_currency_code']
billing_address = record['billing_address']
billing_name = billing_address['firstname']+' ' + billing_address['lastname']
paypal_id = record['payment']['last_trans_id'] and record['payment']['last_trans_id'] or ''
prec = self.env['decimal.precision'].precision_get('Account')
amount = str(float_round(float(record['grand_total']), prec))
payment_method = record['payment']['method']
if payment_method == 'paypal_standard' or payment_method =='paypal_express' :
description = order_date_f+' '+billing_name +' '+ record_currency+' '+amount+ ' ID: '+ paypal_id
else:
description = order_date_f + ' ' + billing_name + ' ' + record_currency + ' ' + amount
return {'description': description}
@mapping
def backend_id(self, record):
return {'backend_id': self.backend_record.id}
@magento
class PaymentNoticeImporter(MagentoImporter):
_model_name = ['magento.payment.notice']
_base_mapper = PaymentNoticeImportMapper
def _must_skip(self):
if self.binder.to_openerp(self.magento_id):
return _('Already imported')
def _before_import(self):
rules = self.unit_for(PaymentNoticeImportRule)
rules.check(self.magento_record)
def _get_storeview(self, record):
""" Return the tax inclusion setting for the appropriate storeview """
storeview_binder = self.binder_for('magento.storeview')
# we find storeview_id in store_id!
# (http://www.magentocommerce.com/bug-tracking/issue?issue=15886)
return storeview_binder.to_openerp(record['store_id'], browse=True)
def _get_magento_data(self):
""" Return the raw Magento data for ``self.magento_id`` """
record = super(PaymentNoticeImporter, self)._get_magento_data()
# sometimes we don't have website_id...
# we fix the record!
if not record.get('website_id'):
storeview = self._get_storeview(record)
# deduce it from the storeview
record['website_id'] = storeview.store_id.website_id.magento_id
return record
def _create_data(self, map_record, **kwargs):
storeview = self._get_storeview(map_record.source)
return super(PaymentNoticeImporter, self)._create_data(
map_record,
storeview=storeview,
**kwargs)
def _update_data(self, map_record, **kwargs):
storeview = self._get_storeview(map_record.source)
return super(PaymentNoticeImporter, self)._update_data(
map_record,
storeview=storeview,
**kwargs)
PaymentNoticeImporter = PaymentNoticeImporter # deprecated
@job(default_channel='root.magento')
def payment_notice_import_batch(session, model_name, backend_id, filters=None):
""" Prepare a batch import of sale order(payment notice) from Magento """
if filters is None:
filters = {}
assert 'magento_storeview_id' in filters, ('Missing information about '
'Magento Storeview')
env = get_environment(session, model_name, backend_id)
importer = env.get_connector_unit(PaymentNoticeBatchImport)
importer.run(filters)
在 __init__.py
在 unit/binder 下加入
在magento_model.py 加入
在_name = 'magento.storeview' 类中
@api.multi
def import_payment_notices(self):
session = ConnectorSession(self.env.cr, self.env.uid,
context=self.env.context)
import_start_time = datetime.now()
for storeview in self:
if storeview.no_payment_notice_sync:
_logger.debug("The storeview '%s' is active in Magento "
"but is configured not to import the "
"payment notices", storeview.name)
continue
backend_id = storeview.backend_id.id
if storeview.import_payment_notices_from_date:
from_string = fields.Datetime.from_string
from_date = from_string(storeview.import_payment_notices_from_date)
else:
from_date = None
payment_notice_import_batch.delay(
session,
'magento.payment.notice',
backend_id,
{'magento_storeview_id': storeview.magento_id,
'from_date': from_date,
'to_date': import_start_time},
priority=1,
) # executed as soon as possible
next_time = import_start_time - timedelta(seconds=IMPORT_DELTA_BUFFER)
next_time = fields.Datetime.to_string(next_time)
self.write({'import_payment_notices_from_date': next_time})
return True
在_name = 'magento.backend'
中
import_payment_notices_from_date = fields.Datetime(
string='Import payment notices from date',
help='do not consider non-imported payment notice before this date. '
'Leave empty to import all payment notice of sale orders',
)
@api.multi
def import_payment_notices(self):
""" Import sale orders from all store views """
storeview_obj = self.env['magento.storeview']
storeviews = storeview_obj.search([('backend_id', 'in', self.ids)])
storeviews.import_payment_notices()
return True
@api.model
def _scheduler_import_payment_notices(self, domain=None):
self._magento_backend('import_payment_notices', domain=domain)
在magentoerpconnect_data.xml 中加入
<record forcecreate="True" id="ir_cron_import_payment_notices" model="ir.cron">
<field name="name">Magento - Import Payment Notices</field>
<field eval="False" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'magento.backend'" name="model"/>
<field eval="'_scheduler_import_payment_notices'" name="function"/>
<field eval="'()'" name="args"/>
</record>
剩下来,就是界面的设定
这样就完成了。
(51) magento集成增加到款通知的更多相关文章
- magento currency magento头部增加币种切换选择
magento currency magento头部增加币种切换选择 默认magento 货币选择切换是显示在左边 有时候我们需要让其显示在头部 Step 1. Create a new file a ...
- 如何在magento后台增加一个自定义订单状态
magento后台订单状态(order status)只有Pending.Processing.On Hold.Closed.Canceled.Pending Payment 等等,如何在magent ...
- jenkins 集成钉钉机器人通知
公司使用钉钉做为公司内部的通讯工具,所以想通过Jenkins发布完成以后通过钉钉来通知大家,研究发现钉钉提供机器人,所以我把机器人集成进来通知相关人员. 1.创建通知人群组,添加机器人(钉钉默认自带了 ...
- (九十七)集成JPush实现远程通知和推送的发送
上节介绍了通过直接和APNS交互实现推送的方法,较为繁琐,最为重要的是发送推送需要特定的服务端,通过JPush,不仅可以简化客户端的接收,还可以通过控制台或者API实现通知的发送. 首先注册JPush ...
- (50)与magento集成
我对接的是 odoo8 和 magento1.9.x 准备工作: l 服务器 装上mangento 组件 : $ pip install magento 装上 requests 组件:$ pip ...
- APICloud首款全功能集成开发工具重磅发布,彰显云端一体理念
近日,APICloud重磅推出首款云端一体的全功能集成开发工具--APICloud Studio 2.为了更深入了解这款开发工具的特性及优势,APICloud CTO 邹达针对几个核心问题做出了解答. ...
- 持续集成 TeamCity 的配置与使用
环境:实现自动编译与自动化测试,发布到远程服务器,环境 VS2015 +WIN2008R2 什么是TeamCity TeamCity是由Jetbrains开发的一款功能强大的持续集成(Continue ...
- 10款无需编程的App DIY开发工具
10款无需编程的App DIY开发工具 你有一个很棒的创意但不会编程怎么办?外包.合伙开发还是从零学编程?这里提供另外一种方式--使用无需编程的App DIY开发工具.DIY开发工具不仅节省了开发时 ...
- 使用TeamCity对项目进行可持续集成管理
使用TeamCity对项目进行可持续集成管理 一.可持续集成管理 持续集成,CI:即Continuous integration. 可持续集成的概念是基于团队(小组)协作开发而提出来的,为了提高团 ...
随机推荐
- java web 初尝遇到的坑
1. 配置 tomcat 7 + Dynamic web model version 3 发现写 web.xml 导致 tomcat 不能启动. 解决办法:tomcat 7 之后有两种配置 servl ...
- C++操作符重载总结operator(小结 更新ing)
操作符重载一个原则是:被操作的数据类型中 至少有一个是自定义的类型(使用class定义类),如果被操作的变量都是基本类型,那么就不能定义操作符重载. 1.如果重载了new,则必须重载delete,因为 ...
- 递归树处理,配合vue的vueTreeselect组件使用
在项目中经常会使用到tree,并且需要对递归树进行操作. 在vue项目中,使用vue-treeselect插件(https://vue-treeselect.js.org/) 使用中遇到的问题: 1. ...
- Css学习总结(2)——60个有用CSS代码片段
1.垂直对齐 如果你用CSS,则你会有困惑:我该怎么垂直对齐容器中的元素?现在,利用CSS3的Transform,可以很优雅的解决这个困惑: .verticalcenter{ position: re ...
- 查看系统的I/O使用iostat命令而使用iotop能够依据I/O统计信息排序,追踪到详细的进程
当看到I/O等待时间所占CPU时间的比重非常高的时候,首先要检查的就是机器是否正在大量使用交换空间,由于硬盘操作的速度远远低于RAM.所以当系统内存耗尽,開始使用交换空间的时候.系统的性能会受到严重影 ...
- web服务启动spring自己主动运行ApplicationListener的使用方法
我们知道.一般来说一个项目启动时须要载入或者运行一些特殊的任务来初始化系统.通常的做法就是用servlet去初始化.可是servlet在使用spring bean时不能直接注入,还须要在web.xml ...
- @crossorigin注解跨域
在@controller中类的头部有一个@CrossOrigin注解. @CrossOrigin是用来处理跨域请求的注解 先来说一下什么是跨域: (站在巨人的肩膀上) 跨域,指的是浏览器不能执行其他网 ...
- HDU5411CRB and Puzzle(矩阵高速幂)
题目链接:传送门 题意: 一个图有n个顶点.已知邻接矩阵.问点能够反复用长度小于m的路径有多少. 分析: 首先我们知道了邻接矩阵A.那么A^k代表的就是长度为k的路径有多少个. 那么结果就是A^0+A ...
- 用了一天的时间,linux下expect实现ssh自己主动登录server记,歧视下网上各种抄来抄去残段子
由于要对客户方的快30个项目进行特别有顺序的重新启动,所以不得不想办法写个脚本,网上看了不少段子.真是残缺的能够. 没有一段是能够正常运行的.我来按顺序记录一下 脚本的本身 使用expect实现自己主 ...
- 十分钟掌握diff&patch用法
作为程序员,了解diff&patch命令是非常必要的.比如说我们发现某个项目有bug代码,而自己又没有svn的提交权限,那么此时最合适的解决方法就是用diff命令做一个补丁发给项目成员.项目成 ...