zoukankan      html  css  js  c++  java
  • (51) magento集成增加到款通知

    这篇主要讲述如何二开增加自己的功能,我没有继承方式二开,习惯是不好的,直接改了原来的模块。

    clip_image002

    clip_image004

    达到效果就这样,当在网站支付成功,会同步到ERP系统中。下面来讲述实现过程

    建立文件 payment_notice.py

    clip_image006

    # -*- 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'.
    "
                    "Resolution:
    "
                    "- Go to "
                    "'Sales > Configuration > Sales > Customer Payment Method
    "
                    "- Create a new Payment Method with name '%s'
    "
                    "-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

    clip_image008

    unit/binder 下加入

    clip_image010

    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>
     

     

    剩下来,就是界面的设定

    clip_image012

    clip_image014

    这样就完成了。

  • 相关阅读:
    洛谷 P2362 围栏木桩
    洛谷 P1926 小书童——刷题大军
    COGS 1913. AC自动机
    洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek
    洛谷 P2984 [USACO10FEB]给巧克力Chocolate Giving
    hdu 2896 病毒侵袭
    hdu 3065 病毒侵袭持续中
    JavaScipt30(第七个案例)(主要知识点:数组some,every,findIndex方法)
    JavaScipt30(第六个案例)(主要知识点:给数字加千分号的正则)
    JavaScipt30(第五个案例)(主要知识点:flex布局)
  • 原文地址:https://www.cnblogs.com/toby2chen/p/6395060.html
Copyright © 2011-2022 走看看