From e64bc37513ba399f505becf2610d552525533021 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Thu, 14 Nov 2019 19:17:49 +0530 Subject: [PATCH 01/18] [ADD] Added connector_aln_data module. --- connector_alndata/README.rst | 49 ++ connector_alndata/__init__.py | 3 + connector_alndata/__manifest__.py | 25 + connector_alndata/data/sync_aln_data_view.xml | 17 + connector_alndata/models/__init__.py | 4 + connector_alndata/models/apartment.py | 106 +++++ connector_alndata/models/res_partner.py | 84 ++++ connector_alndata/readme/CONTRIBUTORS.rst | 2 + connector_alndata/readme/DESCRIPTION.rst | 1 + connector_alndata/readme/USAGE.rst | 0 .../security/ir.model.access.csv | 3 + connector_alndata/static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 429 ++++++++++++++++++ connector_alndata/views/apartment_view.xml | 183 ++++++++ .../views/res_partner_industry_view.xml | 27 ++ 15 files changed, 933 insertions(+) create mode 100644 connector_alndata/README.rst create mode 100644 connector_alndata/__init__.py create mode 100644 connector_alndata/__manifest__.py create mode 100644 connector_alndata/data/sync_aln_data_view.xml create mode 100644 connector_alndata/models/__init__.py create mode 100644 connector_alndata/models/apartment.py create mode 100644 connector_alndata/models/res_partner.py create mode 100644 connector_alndata/readme/CONTRIBUTORS.rst create mode 100644 connector_alndata/readme/DESCRIPTION.rst create mode 100644 connector_alndata/readme/USAGE.rst create mode 100644 connector_alndata/security/ir.model.access.csv create mode 100644 connector_alndata/static/description/icon.png create mode 100644 connector_alndata/static/description/index.html create mode 100644 connector_alndata/views/apartment_view.xml create mode 100644 connector_alndata/views/res_partner_industry_view.xml diff --git a/connector_alndata/README.rst b/connector_alndata/README.rst new file mode 100644 index 00000000..51d93c28 --- /dev/null +++ b/connector_alndata/README.rst @@ -0,0 +1,49 @@ +===================================================== +ALN ODOO Connector +===================================================== + +Usage +===== + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Open Source Integrators +* Odoo Community Association (OCA) +* Serpent Consulting Services Pvt. Ltd. + +Contributors +~~~~~~~~~~~~ + +* Maxime Chambreuil +* Serpent Consulting Services Pvt. Ltd. + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/l10n-usa `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/connector_alndata/__init__.py b/connector_alndata/__init__.py new file mode 100644 index 00000000..83e553ac --- /dev/null +++ b/connector_alndata/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py new file mode 100644 index 00000000..2f33fd42 --- /dev/null +++ b/connector_alndata/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2018 Thinkwell Designs +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + 'name': 'ALN Data Connector', + 'summary': '''This module allows you to synchronize your Odoo database + with ALN Data once a month''', + 'version': '12.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'Open Source Integrators, Odoo Community Association (OCA),' + 'Serpent Consulting Services Pvt. Ltd.', + 'website': 'https://github.com/OCA/l10n-usa', + 'category': 'Tools', + 'maintainer': 'max3903', + 'depends': [ + 'crm', + ], + 'data': [ + 'security/ir.model.access.csv', + 'data/sync_aln_data_view.xml', + 'views/res_partner_industry_view.xml', + 'views/apartment_view.xml', + ], + 'installable': True, +} diff --git a/connector_alndata/data/sync_aln_data_view.xml b/connector_alndata/data/sync_aln_data_view.xml new file mode 100644 index 00000000..9139db3e --- /dev/null +++ b/connector_alndata/data/sync_aln_data_view.xml @@ -0,0 +1,17 @@ + + + + + + + Sync with ALN Data + + code + 1 + months + -1 + + + model._cron_sync_with_aln() + + diff --git a/connector_alndata/models/__init__.py b/connector_alndata/models/__init__.py new file mode 100644 index 00000000..c735bba6 --- /dev/null +++ b/connector_alndata/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import res_partner +from . import apartment \ No newline at end of file diff --git a/connector_alndata/models/apartment.py b/connector_alndata/models/apartment.py new file mode 100644 index 00000000..f3b90926 --- /dev/null +++ b/connector_alndata/models/apartment.py @@ -0,0 +1,106 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + +class Apartment(models.Model): + + _name = "apartment.apartment" + _description="Apartment" + + name = fields.Char('Name') + last_updated = fields.Datetime('Last Date Updated') + last_changed = fields.Datetime('Last Date Changed') + fka = fields.Char("FKA") + hours =fields.Float('Hours') + # + regional_management_company_id = fields.Many2one('res.partner', + 'Regional Management Company') + corporate_management_company_id = fields.Many2one('res.partner', + 'Corporate Management Company') + aln_id = fields.Integer('ALN Id') + status_id = fields.Many2one('status.code', 'Status') + market_id = fields.Many2one('res.partner', 'Market') + sub_market_id = fields.Many2one('res.partner', 'Sub Market') + num_unit = fields.Integer('Number of Unit') + year_built = fields.Char('Build Year') + year_remodeled = fields.Char('YearRemodeled') + timezone = fields.Boolean('Timezone', default=False) + occupancy = fields.Char('Occupancy') + no_of_story = fields.Char('Number of Stories') + direction = fields.Char('Direction') + property_description =fields.Text('Property Description') + apt_homepage = fields.Char('Apt Homepage') + apt_picture_url = fields.Char('Apt Picture Url') + curr_manaager = fields.Char('Current Manager') + area_supervisor_id = fields.Many2one('res.partner', 'Area Manager') + owner_id = fields.Many2one('res.partner','Owner') + views = fields.Char('Views') + ac_heating = fields.Char('Ac Heating') + map_coordinate = fields.Char('Other Notes') + avg_rent = fields.Float('Average Rent') + avg_sqft = fields.Float('Average SqFt') + price_avalilabel_website = fields.Char('Price and Website') + price_avalilabel_website_alt = fields.Char('Price and Website Alt') + #
+ address_type = fields.Char('Address Type') + address_to = fields.Char('Address To') + street = fields.Char('Address') + street2 = fields.Char('street2') + state_id = fields.Many2one('res.country.state', 'State') + zip = fields.Integer('Zip') + phone = fields.Char('Phone') + number = fields.Char('Number') + email = fields.Char('Email') + # + income_restricted = fields.Boolean('Income Restricted') + income_restriction_specifics = fields.Boolean( + 'Income Restriction Specification', default=False) + section_8 = fields.Boolean('Section 8', default=False) + senior_living = fields.Boolean('Senior Living', default=False) + student_housing = fields.Boolean('Student Housing', default=False) + lease_term = fields.Char('Lease Terms', default=False) + short_term = fields.Boolean('Short Term', default=False) + corporate = fields.Boolean('Corporate', default=False) + application_fee = fields.Float('Application Fee') + curr_special = fields.Char('Current Specials') + assisted_living = fields.Boolean('Assisted Living', default=False) + # + max_no_pet = fields.Integer('Maximum Pet') + max_pet_height = fields.Integer('Maximum Pet Height') + pet_deposite = fields.Float('Pet Deposite') + pet_non_refundable = fields.Float('Pet Non Refundable') + pet_rent_per_month = fields.Float('Pet Rent Per Month') + cat_only = fields.Boolean('Cat Only?', default=False) + breed_restriction = fields.Boolean('Breed Restriction', default=False) + # > + country_id = fields.Many2one('res.country', 'Country') + gps_latitude = fields.Float('GPS Latitude') + gps_longitude = fields.Float('GPS Longitude') + pmsa = fields.Char('PMSA') + pmsa_description = fields.Char('PMSA Description') + cmsa = fields.Char('CMSA') + cmsa_description = fields.Char('CMSA Description') + census_block = fields.Char('Census Block') + census_tract = fields.Char('Census Tract') + country_fips_code = fields.Char('Country FIPS Code') + # + description = fields.Char('Description') + available = fields.Boolean('Availability', default=False) + cost = fields.Float('Cost') + quantity = fields.Integer('Quantity') + # + commision = fields.Float('Commision') + locator_special = fields.Char('Locator Specials') + pay_locator = fields.Boolean('Pay Locators On Section8') + dot_com_commision = fields.Float('Dot Com Commission') + # <> + reg_req = fields.Boolean('Registration Requied?', default=True) + reg_by_fax = fields.Boolean('Registration By Fax?', default=False) + fax_reg_num = fields.Char('Fax Registration Number') + reg_by_phone = fields.Boolean('Registration By Phone', default=False) + phone_reg_num = fields.Char('Phone Registration Number') + reg_by_email = fields.Boolean('Registration By Email', default=False) + reg_email = fields.Char('Registration Email') + apt_reg_dot_com = fields.Boolean('Apt Registration Dot Com', default=False) + reg_with_lrn = fields.Boolean('Registration with LRN', default=False) + diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py new file mode 100644 index 00000000..4588cd7b --- /dev/null +++ b/connector_alndata/models/res_partner.py @@ -0,0 +1,84 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + + +import httplib2, json +import base64 + +from odoo import api, fields, models + + +class ResPartnerIndustry(models.Model): + _inherit = "res.partner.industry" + + ref = fields.Char('Reference') + parent_id = fields.Many2one('res.partner.industry', 'Parent') + Code = fields.Char('Market Code') + description = fields.Char('Market Description') + industry_type = fields.Selection([('market','Market'), + ('sub-market','Sub Market')], + 'Industry Type') + + @api.multi + def name_get(self): + """ Return the display name, including their direct + parent by default. + """ + res = [] + for partner in self: + names = [] + display_name = '' + if partner.parent_id: + display_name += partner.parent_id.name + '/' + partner.name + else: + display_name += partner.name + res.append((partner.id, display_name)) + return res + + +class ResPartner(models.Model): + _inherit = "res.partner" + + partner_type = fields.Selection( + [('owner','Owner'), + ('management_company','Management Company'), + ('contact','Contact')], + 'Partner Type') + lastdate_changed = fields.Datetime('LastDateChanged') + management_company_id = fields.Many2one('res.partner', + 'Management Company') + address_type = fields.Char('AddressType') + + +class StatusCode(models.Model): + + _name="status.code" + _description="Status Code" + + name = fields.Char('Status') + + +class Lead(models.Model): + _inherit = "crm.lead" + + def aln_auth_login(self): + url = self.env['ir.config_parameter'].get_param('alndata.api.url') + api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') + + authenticateStr = "" \ + "" + api_key + "" \ + "" + headers = {'X-ALN-Authentication': authenticateStr, + 'Accept': 'application/json'} + http = httplib2.Http() + try: + response, content = http.request(url, 'GET', headers=headers) + content = content.decode('utf8').replace("'", '"') + except Exception as e: + raise Warning(("%s.") % str(e)) +# return response, content, authenticateStr + + + @api.model + def _cron_sync_with_aln(self): + print ("\n dddddddd >>>>>>") + self.aln_auth_login() diff --git a/connector_alndata/readme/CONTRIBUTORS.rst b/connector_alndata/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..64881b41 --- /dev/null +++ b/connector_alndata/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Maxime Chambreuil +* Serpent Consulting Services Pvt. Ltd. diff --git a/connector_alndata/readme/DESCRIPTION.rst b/connector_alndata/readme/DESCRIPTION.rst new file mode 100644 index 00000000..140525d5 --- /dev/null +++ b/connector_alndata/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows you to synchronize your Odoo database with ALN Data once a month. diff --git a/connector_alndata/readme/USAGE.rst b/connector_alndata/readme/USAGE.rst new file mode 100644 index 00000000..e69de29b diff --git a/connector_alndata/security/ir.model.access.csv b/connector_alndata/security/ir.model.access.csv new file mode 100644 index 00000000..6a38833e --- /dev/null +++ b/connector_alndata/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_apartment_apartment,access_apartment_apartment,model_apartment_apartment,base.group_user,1,1,1,1 +access_status_code,access_status_code,model_status_code,base.group_user,1,1,1,1 diff --git a/connector_alndata/static/description/icon.png b/connector_alndata/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/connector_alndata/static/description/index.html b/connector_alndata/static/description/index.html new file mode 100644 index 00000000..7b30f812 --- /dev/null +++ b/connector_alndata/static/description/index.html @@ -0,0 +1,429 @@ + + + + + + +Localizations for North American Banking & Financials + + + +
+

Localizations for North American Banking & Financials

+ + +

Beta License: AGPL-3 OCA/l10n-usa Translate me on Weblate Try me on Runbot

+

Add fields to Bank, Partner and Company required for ACH transactions in USA.

+

Table of contents

+ +
+

Usage

+

Add routing_number on Bank records.

+

Add Legal ID on Partner and Company records.

+

Add Mandate URL field to Company record. Use in email templates to provide customer with an easy +way to access your Mandate Authorization form to streamline ACH authorizations.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Thinkwell Designs
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/l10n-usa project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/connector_alndata/views/apartment_view.xml b/connector_alndata/views/apartment_view.xml new file mode 100644 index 00000000..c5363e0e --- /dev/null +++ b/connector_alndata/views/apartment_view.xml @@ -0,0 +1,183 @@ + + + + apartment.apartment.view.form + apartment.apartment + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + apartment.apartment.view.tree + apartment.apartment + + + + + + + + + + + + + + + + + + + + Apartment + apartment.apartment + form + tree,form + + + + + +
diff --git a/connector_alndata/views/res_partner_industry_view.xml b/connector_alndata/views/res_partner_industry_view.xml new file mode 100644 index 00000000..8a519583 --- /dev/null +++ b/connector_alndata/views/res_partner_industry_view.xml @@ -0,0 +1,27 @@ + + + + + Industry + res.partner.industry + + + + + + + + + + + Industry + res.partner.industry + + + + + + + + + From 857960c824de473b196988f878f21af562ea6d89 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Fri, 15 Nov 2019 17:49:05 +0530 Subject: [PATCH 02/18] [IMP] Improved module as per commented on git hub PR. --- connector_alndata/__manifest__.py | 3 +- connector_alndata/models/__init__.py | 5 +- connector_alndata/models/crm_lead.py | 29 +++++++ .../models/{apartment.py => fsm_location.py} | 17 +++-- connector_alndata/models/res_partner.py | 75 +------------------ .../models/res_partner_industry.py | 30 ++++++++ connector_alndata/models/status_code.py | 11 +++ .../security/ir.model.access.csv | 2 +- ...artment_view.xml => fsm_location_view.xml} | 23 +++--- 9 files changed, 100 insertions(+), 95 deletions(-) create mode 100644 connector_alndata/models/crm_lead.py rename connector_alndata/models/{apartment.py => fsm_location.py} (93%) create mode 100644 connector_alndata/models/res_partner_industry.py create mode 100644 connector_alndata/models/status_code.py rename connector_alndata/views/{apartment_view.xml => fsm_location_view.xml} (93%) diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py index 2f33fd42..b79212ff 100644 --- a/connector_alndata/__manifest__.py +++ b/connector_alndata/__manifest__.py @@ -1,4 +1,3 @@ -# Copyright 2018 Thinkwell Designs # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { @@ -19,7 +18,7 @@ 'security/ir.model.access.csv', 'data/sync_aln_data_view.xml', 'views/res_partner_industry_view.xml', - 'views/apartment_view.xml', + 'views/fsm_location_view.xml', ], 'installable': True, } diff --git a/connector_alndata/models/__init__.py b/connector_alndata/models/__init__.py index c735bba6..7be05dcc 100644 --- a/connector_alndata/models/__init__.py +++ b/connector_alndata/models/__init__.py @@ -1,4 +1,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import res_partner -from . import apartment \ No newline at end of file +from . import res_partner_industry +from . import crm_lead +from . import status_code +from . import fsm_location diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py new file mode 100644 index 00000000..eb4409dd --- /dev/null +++ b/connector_alndata/models/crm_lead.py @@ -0,0 +1,29 @@ + +import httplib2 + +from odoo import api, models, _ + + +class Lead(models.Model): + _inherit = "crm.lead" + + def aln_auth_login(self): + url = self.env['ir.config_parameter'].get_param('alndata.api.url') + api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') + + authenticateStr = "" \ + "" + api_key + "" \ + "" + headers = {'X-ALN-Authentication': authenticateStr, + 'Accept': 'application/json'} + http = httplib2.Http() + try: + response, content = http.request(url, 'GET', headers=headers) + content = content.decode('utf8').replace("'", '"') + except Exception as e: + raise Warning(_(("%s.") % str(e))) +# return response, content, authenticateStr + + @api.model + def _cron_sync_with_aln(self): + self.aln_auth_login() diff --git a/connector_alndata/models/apartment.py b/connector_alndata/models/fsm_location.py similarity index 93% rename from connector_alndata/models/apartment.py rename to connector_alndata/models/fsm_location.py index f3b90926..0f7ef382 100644 --- a/connector_alndata/models/apartment.py +++ b/connector_alndata/models/fsm_location.py @@ -1,17 +1,18 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models +from odoo import fields, models -class Apartment(models.Model): - _name = "apartment.apartment" - _description="Apartment" +class FsmLocation(models.Model): + + _name = "fsm.location" + _description = "Apartment" name = fields.Char('Name') last_updated = fields.Datetime('Last Date Updated') last_changed = fields.Datetime('Last Date Changed') fka = fields.Char("FKA") - hours =fields.Float('Hours') + hours = fields.Float('Hours') # regional_management_company_id = fields.Many2one('res.partner', 'Regional Management Company') @@ -28,12 +29,12 @@ class Apartment(models.Model): occupancy = fields.Char('Occupancy') no_of_story = fields.Char('Number of Stories') direction = fields.Char('Direction') - property_description =fields.Text('Property Description') + property_description = fields.Text('Property Description') apt_homepage = fields.Char('Apt Homepage') apt_picture_url = fields.Char('Apt Picture Url') curr_manaager = fields.Char('Current Manager') area_supervisor_id = fields.Many2one('res.partner', 'Area Manager') - owner_id = fields.Many2one('res.partner','Owner') + owner_id = fields.Many2one('res.partner', 'Owner') views = fields.Char('Views') ac_heating = fields.Char('Ac Heating') map_coordinate = fields.Char('Other Notes') @@ -43,7 +44,7 @@ class Apartment(models.Model): price_avalilabel_website_alt = fields.Char('Price and Website Alt') #
address_type = fields.Char('Address Type') - address_to = fields.Char('Address To') + address_to = fields.Char('Address To') street = fields.Char('Address') street2 = fields.Char('street2') state_id = fields.Many2one('res.country.state', 'State') diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 4588cd7b..ef4ff4f7 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -1,84 +1,17 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -import httplib2, json -import base64 - -from odoo import api, fields, models - - -class ResPartnerIndustry(models.Model): - _inherit = "res.partner.industry" - - ref = fields.Char('Reference') - parent_id = fields.Many2one('res.partner.industry', 'Parent') - Code = fields.Char('Market Code') - description = fields.Char('Market Description') - industry_type = fields.Selection([('market','Market'), - ('sub-market','Sub Market')], - 'Industry Type') - - @api.multi - def name_get(self): - """ Return the display name, including their direct - parent by default. - """ - res = [] - for partner in self: - names = [] - display_name = '' - if partner.parent_id: - display_name += partner.parent_id.name + '/' + partner.name - else: - display_name += partner.name - res.append((partner.id, display_name)) - return res +from odoo import fields, models class ResPartner(models.Model): _inherit = "res.partner" partner_type = fields.Selection( - [('owner','Owner'), - ('management_company','Management Company'), - ('contact','Contact')], + [('owner', 'Owner'), + ('management_company', 'Management Company'), + ('contact', 'Contact')], 'Partner Type') lastdate_changed = fields.Datetime('LastDateChanged') management_company_id = fields.Many2one('res.partner', 'Management Company') address_type = fields.Char('AddressType') - - -class StatusCode(models.Model): - - _name="status.code" - _description="Status Code" - - name = fields.Char('Status') - - -class Lead(models.Model): - _inherit = "crm.lead" - - def aln_auth_login(self): - url = self.env['ir.config_parameter'].get_param('alndata.api.url') - api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') - - authenticateStr = "" \ - "" + api_key + "" \ - "" - headers = {'X-ALN-Authentication': authenticateStr, - 'Accept': 'application/json'} - http = httplib2.Http() - try: - response, content = http.request(url, 'GET', headers=headers) - content = content.decode('utf8').replace("'", '"') - except Exception as e: - raise Warning(("%s.") % str(e)) -# return response, content, authenticateStr - - - @api.model - def _cron_sync_with_aln(self): - print ("\n dddddddd >>>>>>") - self.aln_auth_login() diff --git a/connector_alndata/models/res_partner_industry.py b/connector_alndata/models/res_partner_industry.py new file mode 100644 index 00000000..e5cd3b31 --- /dev/null +++ b/connector_alndata/models/res_partner_industry.py @@ -0,0 +1,30 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ResPartnerIndustry(models.Model): + _inherit = "res.partner.industry" + + ref = fields.Char('Reference') + parent_id = fields.Many2one('res.partner.industry', 'Parent') + Code = fields.Char('Market Code') + description = fields.Char('Market Description') + industry_type = fields.Selection([('market', 'Market'), + ('sub-market', 'Sub Market')], + 'Industry Type') + + @api.multi + def name_get(self): + """ Return the display name, including their direct + parent by default. + """ + res = [] + for partner in self: + display_name = '' + if partner.parent_id: + display_name += partner.parent_id.name + '/' + partner.name + else: + display_name += partner.name + res.append((partner.id, display_name)) + return res diff --git a/connector_alndata/models/status_code.py b/connector_alndata/models/status_code.py new file mode 100644 index 00000000..3443eb84 --- /dev/null +++ b/connector_alndata/models/status_code.py @@ -0,0 +1,11 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StatusCode(models.Model): + + _name="status.code" + _description="Status Code" + + name = fields.Char('Status') diff --git a/connector_alndata/security/ir.model.access.csv b/connector_alndata/security/ir.model.access.csv index 6a38833e..b66020e7 100644 --- a/connector_alndata/security/ir.model.access.csv +++ b/connector_alndata/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_apartment_apartment,access_apartment_apartment,model_apartment_apartment,base.group_user,1,1,1,1 +access_fsm_location,access_fsm_locationt,model_fsm_location,base.group_user,1,1,1,1 access_status_code,access_status_code,model_status_code,base.group_user,1,1,1,1 diff --git a/connector_alndata/views/apartment_view.xml b/connector_alndata/views/fsm_location_view.xml similarity index 93% rename from connector_alndata/views/apartment_view.xml rename to connector_alndata/views/fsm_location_view.xml index c5363e0e..2efaef59 100644 --- a/connector_alndata/views/apartment_view.xml +++ b/connector_alndata/views/fsm_location_view.xml @@ -1,8 +1,8 @@ - - apartment.apartment.view.form - apartment.apartment + + fsm.location.view.form + fsm.location
@@ -146,9 +146,9 @@ - - apartment.apartment.view.tree - apartment.apartment + + fsm.location.view.tree + fsm.location @@ -161,23 +161,22 @@ - - + Apartment - apartment.apartment + fsm.location form tree,form - + action="connector_alndata.fsm_location_action"/> From 72139a51a16347a08f84534421a0fc02d82de649 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Tue, 19 Nov 2019 18:49:33 +0530 Subject: [PATCH 03/18] [WIP] Connected ODOO with ALNDATA fetch data for market, sub-market and status_code and created records in ODOO for market, sub-market and status_code. --- connector_alndata/README.rst | 5 - connector_alndata/__manifest__.py | 6 +- .../data/ir_config_parameter_data.xml | 57 ++++++ connector_alndata/data/sync_aln_data_view.xml | 5 +- connector_alndata/models/__init__.py | 1 - connector_alndata/models/crm_lead.py | 133 +++++++++++-- connector_alndata/models/fsm_location.py | 107 ---------- connector_alndata/models/res_partner.py | 6 +- .../models/res_partner_industry.py | 7 +- connector_alndata/models/status_code.py | 7 +- .../security/ir.model.access.csv | 2 +- connector_alndata/views/fsm_location_view.xml | 182 ------------------ 12 files changed, 197 insertions(+), 321 deletions(-) create mode 100644 connector_alndata/data/ir_config_parameter_data.xml delete mode 100644 connector_alndata/models/fsm_location.py delete mode 100644 connector_alndata/views/fsm_location_view.xml diff --git a/connector_alndata/README.rst b/connector_alndata/README.rst index 51d93c28..536e2039 100644 --- a/connector_alndata/README.rst +++ b/connector_alndata/README.rst @@ -23,7 +23,6 @@ Authors * Open Source Integrators * Odoo Community Association (OCA) -* Serpent Consulting Services Pvt. Ltd. Contributors ~~~~~~~~~~~~ @@ -43,7 +42,3 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. - -This module is part of the `OCA/l10n-usa `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py index b79212ff..4dce3ec0 100644 --- a/connector_alndata/__manifest__.py +++ b/connector_alndata/__manifest__.py @@ -6,19 +6,19 @@ with ALN Data once a month''', 'version': '12.0.1.0.0', 'license': 'AGPL-3', - 'author': 'Open Source Integrators, Odoo Community Association (OCA),' - 'Serpent Consulting Services Pvt. Ltd.', + 'author': 'Open Source Integrators, Odoo Community Association (OCA),', 'website': 'https://github.com/OCA/l10n-usa', 'category': 'Tools', 'maintainer': 'max3903', 'depends': [ 'crm', + 'fieldservice', ], 'data': [ 'security/ir.model.access.csv', + 'data/ir_config_parameter_data.xml', 'data/sync_aln_data_view.xml', 'views/res_partner_industry_view.xml', - 'views/fsm_location_view.xml', ], 'installable': True, } diff --git a/connector_alndata/data/ir_config_parameter_data.xml b/connector_alndata/data/ir_config_parameter_data.xml new file mode 100644 index 00000000..dc2b83de --- /dev/null +++ b/connector_alndata/data/ir_config_parameter_data.xml @@ -0,0 +1,57 @@ + + + + + alndata.api.url + http://api2.alndata.com/odata/ + + + + + alndata.api.key + 0 + + + + + alndata.markets.rowversion + 0 + + + + + alndata.submarkets.rowversion + 0 + + + + + alndata.managementcompanies.rowversion + 0 + + + + + alndata.owners.rowversion + 0 + + + + + alndata.apartments.rowversion + 0 + + + + + alndata.contacts.rowversion + 0 + + + + + alndata.newconstructions.rowversion + 0 + + + \ No newline at end of file diff --git a/connector_alndata/data/sync_aln_data_view.xml b/connector_alndata/data/sync_aln_data_view.xml index 9139db3e..f1e4af22 100644 --- a/connector_alndata/data/sync_aln_data_view.xml +++ b/connector_alndata/data/sync_aln_data_view.xml @@ -1,6 +1,4 @@ - - - + @@ -14,4 +12,5 @@ model._cron_sync_with_aln() + diff --git a/connector_alndata/models/__init__.py b/connector_alndata/models/__init__.py index 7be05dcc..d84ee5dc 100644 --- a/connector_alndata/models/__init__.py +++ b/connector_alndata/models/__init__.py @@ -4,4 +4,3 @@ from . import res_partner_industry from . import crm_lead from . import status_code -from . import fsm_location diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index eb4409dd..ab9e5b1f 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -1,29 +1,138 @@ +# Copyright (C) 2019 Open Source Integrators +# +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import httplib2 +import requests from odoo import api, models, _ +from odoo.exceptions import RedirectWarning class Lead(models.Model): _inherit = "crm.lead" - def aln_auth_login(self): + def aln_auth_login(self, data_key=''): url = self.env['ir.config_parameter'].get_param('alndata.api.url') api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') - authenticateStr = "" \ - "" + api_key + "" \ - "" - headers = {'X-ALN-Authentication': authenticateStr, - 'Accept': 'application/json'} - http = httplib2.Http() + url = url + data_key + if api_key == '0': + action = self.env.ref('base.ir_config_list_action') + msg = _('Cannot find a ALN Data URL and API key, ' + 'You should configure it. ' + '\nPlease go to System Parameters.') + raise RedirectWarning(msg, action.id, + _('Go to the configuration panel')) + params = ( + ('apikey', api_key), + ('Accept', 'application/json') + ) try: - response, content = http.request(url, 'GET', headers=headers) - content = content.decode('utf8').replace("'", '"') + response = requests.get(url, params=params) except Exception as e: raise Warning(_(("%s.") % str(e))) -# return response, content, authenticateStr + response.raise_for_status() + content = response.content.decode('utf8') + return content @api.model def _cron_sync_with_aln(self): - self.aln_auth_login() + market_data = self.aln_auth_login('Markets') + industry_obj = self.env['res.partner.industry'] + status_code_obj = self.env['status.code'] + cr = self._cr + + # Get Market Data + if market_data: + market_data = eval(market_data).get("value", []) + for market in market_data: + cr.execute(""" + Select + id , name + from + res_partner_industry + where + name= '%s' or full_name='%s' and + industry_type='market' + """ % (market.get('MarketCode'), + market.get('MarketDescription'))) + available_market = cr.fetchall() + if not available_market: + industry_obj.create( + { + 'name': market.get('MarketCode'), + 'full_name': market.get('MarketDescription'), + 'industry_type': 'market', + }) + + # Get Sub-Market Data + submarket_data = self.aln_auth_login('Submarkets') + if submarket_data: + submarket_data = eval(submarket_data).get("value", []) + for submarket in submarket_data: + cr.execute(""" + Select + id + from + res_partner_industry + where name= '%s' and industry_type='sub-market' + """ % (submarket.get('SubMarketDescription'),)) + available_submarket = cr.fetchone() + cr.execute(""" + Select + id + from + res_partner_industry + where name= '%s' and industry_type='market' + limit 1 + """ % (submarket.get('Market'),)) + market_id = cr.fetchone() + market_id = market_id and market_id[0] + if not available_submarket: + industry_obj.create( + { + 'name': submarket.get('SubMarketDescription'), + 'parent_id': market_id, + 'industry_type': 'sub-market', + 'ref': submarket.get('SubmarketId'), + }) + + # Get Status Code Data + status_code = self.aln_auth_login('StatusCodes') + if status_code: + status_code = eval(status_code).get("value", []) + for code in status_code: + cr.execute(""" + Select + id + from + status_code + where name= '%s' + """ % (code.get('StatusDescription'),)) + available_code = cr.fetchone() + if not available_code: + status_code_obj.create( + { + 'name': code.get('StatusDescription'), + 'code': code.get('Status') + }) + + # Get Management Companies Data + # Working On this +# management_companies = self.aln_auth_login('ManagementCompanies') +# if management_companies: + # When eval management companies data as dictionary at that time + # dictionary contain null value without quotes. + # so it's give error 'null is not defined'. + # so to fix that issue assign null as None here. +# null=None +# management_companies = eval(management_companies).get("value", []) +# for company in management_companies: +# if not company.get('ManagementCompanyParentId'): +# cr.execute(""" +# Select +# id +# from +# crm_lead +# where name= '%s' +# """ % (company.get('ManagementCompanyName'),)) diff --git a/connector_alndata/models/fsm_location.py b/connector_alndata/models/fsm_location.py deleted file mode 100644 index 0f7ef382..00000000 --- a/connector_alndata/models/fsm_location.py +++ /dev/null @@ -1,107 +0,0 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields, models - - -class FsmLocation(models.Model): - - _name = "fsm.location" - _description = "Apartment" - - name = fields.Char('Name') - last_updated = fields.Datetime('Last Date Updated') - last_changed = fields.Datetime('Last Date Changed') - fka = fields.Char("FKA") - hours = fields.Float('Hours') - # - regional_management_company_id = fields.Many2one('res.partner', - 'Regional Management Company') - corporate_management_company_id = fields.Many2one('res.partner', - 'Corporate Management Company') - aln_id = fields.Integer('ALN Id') - status_id = fields.Many2one('status.code', 'Status') - market_id = fields.Many2one('res.partner', 'Market') - sub_market_id = fields.Many2one('res.partner', 'Sub Market') - num_unit = fields.Integer('Number of Unit') - year_built = fields.Char('Build Year') - year_remodeled = fields.Char('YearRemodeled') - timezone = fields.Boolean('Timezone', default=False) - occupancy = fields.Char('Occupancy') - no_of_story = fields.Char('Number of Stories') - direction = fields.Char('Direction') - property_description = fields.Text('Property Description') - apt_homepage = fields.Char('Apt Homepage') - apt_picture_url = fields.Char('Apt Picture Url') - curr_manaager = fields.Char('Current Manager') - area_supervisor_id = fields.Many2one('res.partner', 'Area Manager') - owner_id = fields.Many2one('res.partner', 'Owner') - views = fields.Char('Views') - ac_heating = fields.Char('Ac Heating') - map_coordinate = fields.Char('Other Notes') - avg_rent = fields.Float('Average Rent') - avg_sqft = fields.Float('Average SqFt') - price_avalilabel_website = fields.Char('Price and Website') - price_avalilabel_website_alt = fields.Char('Price and Website Alt') - #
- address_type = fields.Char('Address Type') - address_to = fields.Char('Address To') - street = fields.Char('Address') - street2 = fields.Char('street2') - state_id = fields.Many2one('res.country.state', 'State') - zip = fields.Integer('Zip') - phone = fields.Char('Phone') - number = fields.Char('Number') - email = fields.Char('Email') - # - income_restricted = fields.Boolean('Income Restricted') - income_restriction_specifics = fields.Boolean( - 'Income Restriction Specification', default=False) - section_8 = fields.Boolean('Section 8', default=False) - senior_living = fields.Boolean('Senior Living', default=False) - student_housing = fields.Boolean('Student Housing', default=False) - lease_term = fields.Char('Lease Terms', default=False) - short_term = fields.Boolean('Short Term', default=False) - corporate = fields.Boolean('Corporate', default=False) - application_fee = fields.Float('Application Fee') - curr_special = fields.Char('Current Specials') - assisted_living = fields.Boolean('Assisted Living', default=False) - # - max_no_pet = fields.Integer('Maximum Pet') - max_pet_height = fields.Integer('Maximum Pet Height') - pet_deposite = fields.Float('Pet Deposite') - pet_non_refundable = fields.Float('Pet Non Refundable') - pet_rent_per_month = fields.Float('Pet Rent Per Month') - cat_only = fields.Boolean('Cat Only?', default=False) - breed_restriction = fields.Boolean('Breed Restriction', default=False) - # > - country_id = fields.Many2one('res.country', 'Country') - gps_latitude = fields.Float('GPS Latitude') - gps_longitude = fields.Float('GPS Longitude') - pmsa = fields.Char('PMSA') - pmsa_description = fields.Char('PMSA Description') - cmsa = fields.Char('CMSA') - cmsa_description = fields.Char('CMSA Description') - census_block = fields.Char('Census Block') - census_tract = fields.Char('Census Tract') - country_fips_code = fields.Char('Country FIPS Code') - # - description = fields.Char('Description') - available = fields.Boolean('Availability', default=False) - cost = fields.Float('Cost') - quantity = fields.Integer('Quantity') - # - commision = fields.Float('Commision') - locator_special = fields.Char('Locator Specials') - pay_locator = fields.Boolean('Pay Locators On Section8') - dot_com_commision = fields.Float('Dot Com Commission') - # <> - reg_req = fields.Boolean('Registration Requied?', default=True) - reg_by_fax = fields.Boolean('Registration By Fax?', default=False) - fax_reg_num = fields.Char('Fax Registration Number') - reg_by_phone = fields.Boolean('Registration By Phone', default=False) - phone_reg_num = fields.Char('Phone Registration Number') - reg_by_email = fields.Boolean('Registration By Email', default=False) - reg_email = fields.Char('Registration Email') - apt_reg_dot_com = fields.Boolean('Apt Registration Dot Com', default=False) - reg_with_lrn = fields.Boolean('Registration with LRN', default=False) - diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index ef4ff4f7..7b3ad0e3 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Open Source Integrators +# # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields, models @@ -10,8 +12,6 @@ class ResPartner(models.Model): [('owner', 'Owner'), ('management_company', 'Management Company'), ('contact', 'Contact')], - 'Partner Type') + 'Partner Type') lastdate_changed = fields.Datetime('LastDateChanged') - management_company_id = fields.Many2one('res.partner', - 'Management Company') address_type = fields.Char('AddressType') diff --git a/connector_alndata/models/res_partner_industry.py b/connector_alndata/models/res_partner_industry.py index e5cd3b31..ec52da13 100644 --- a/connector_alndata/models/res_partner_industry.py +++ b/connector_alndata/models/res_partner_industry.py @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Open Source Integrators +# # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models @@ -16,8 +18,9 @@ class ResPartnerIndustry(models.Model): @api.multi def name_get(self): - """ Return the display name, including their direct - parent by default. + """Compute Display Name. + + Return the display name, including their direct parent by default. """ res = [] for partner in self: diff --git a/connector_alndata/models/status_code.py b/connector_alndata/models/status_code.py index 3443eb84..69c1573b 100644 --- a/connector_alndata/models/status_code.py +++ b/connector_alndata/models/status_code.py @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Open Source Integrators +# # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields, models @@ -5,7 +7,8 @@ class StatusCode(models.Model): - _name="status.code" - _description="Status Code" + _name = "status.code" + _description = "Status Code" name = fields.Char('Status') + code = fields.Char('Code') diff --git a/connector_alndata/security/ir.model.access.csv b/connector_alndata/security/ir.model.access.csv index b66020e7..0fcb066b 100644 --- a/connector_alndata/security/ir.model.access.csv +++ b/connector_alndata/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_fsm_location,access_fsm_locationt,model_fsm_location,base.group_user,1,1,1,1 +,,,,,,, access_status_code,access_status_code,model_status_code,base.group_user,1,1,1,1 diff --git a/connector_alndata/views/fsm_location_view.xml b/connector_alndata/views/fsm_location_view.xml deleted file mode 100644 index 2efaef59..00000000 --- a/connector_alndata/views/fsm_location_view.xml +++ /dev/null @@ -1,182 +0,0 @@ - - - - fsm.location.view.form - fsm.location - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - fsm.location.view.tree - fsm.location - - - - - - - - - - - - - - - - - - - Apartment - fsm.location - form - tree,form - - - - - - From df7c19e82b96b3476a14d0dc697667bd8a0891b1 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 20 Nov 2019 18:46:59 +0530 Subject: [PATCH 04/18] [WIP] Improved the code for fetching data, added new method to fetch management_companies data. --- .../data/ir_config_parameter_data.xml | 3 +- connector_alndata/data/sync_aln_data_view.xml | 1 + connector_alndata/models/crm_lead.py | 217 +++++++++++++++--- connector_alndata/models/res_partner.py | 1 + 4 files changed, 195 insertions(+), 27 deletions(-) diff --git a/connector_alndata/data/ir_config_parameter_data.xml b/connector_alndata/data/ir_config_parameter_data.xml index dc2b83de..fe1eb410 100644 --- a/connector_alndata/data/ir_config_parameter_data.xml +++ b/connector_alndata/data/ir_config_parameter_data.xml @@ -1,3 +1,4 @@ + @@ -54,4 +55,4 @@ 0 - \ No newline at end of file + diff --git a/connector_alndata/data/sync_aln_data_view.xml b/connector_alndata/data/sync_aln_data_view.xml index f1e4af22..2bd46c04 100644 --- a/connector_alndata/data/sync_aln_data_view.xml +++ b/connector_alndata/data/sync_aln_data_view.xml @@ -1,3 +1,4 @@ + diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index ab9e5b1f..ba31ef8b 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -2,16 +2,27 @@ # # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging import requests -from odoo import api, models, _ +from odoo import api, fields, models, _ from odoo.exceptions import RedirectWarning +_logger = logging.getLogger(__name__) + class Lead(models.Model): _inherit = "crm.lead" + lastdate_changed = fields.Datetime('LastDateChanged') + rowversion = fields.Char('Row Version') + industry_id = fields.Many2one('res.partner.industry', 'Market') + def aln_auth_login(self, data_key=''): + """Aln Connector. + + This method is used to connect with ALN and fetch the data. + """ url = self.env['ir.config_parameter'].get_param('alndata.api.url') api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') @@ -27,6 +38,12 @@ def aln_auth_login(self, data_key=''): ('apikey', api_key), ('Accept', 'application/json') ) + if data_key == 'ManagementCompanies': + params = ( + ('apikey', api_key), + ('Accept', 'application/json'), + ('$expand', 'Addresses,PhoneNumbers'), + ) try: response = requests.get(url, params=params) except Exception as e: @@ -36,13 +53,15 @@ def aln_auth_login(self, data_key=''): return content @api.model - def _cron_sync_with_aln(self): - market_data = self.aln_auth_login('Markets') + def sync_market_data(self, cr): + """Synchronize Market Data. + + This method is used to sync market data. + """ industry_obj = self.env['res.partner.industry'] - status_code_obj = self.env['status.code'] cr = self._cr - - # Get Market Data + market_data = self.aln_auth_login('Markets') + market_ids = [] if market_data: market_data = eval(market_data).get("value", []) for market in market_data: @@ -58,14 +77,24 @@ def _cron_sync_with_aln(self): market.get('MarketDescription'))) available_market = cr.fetchall() if not available_market: - industry_obj.create( + market = industry_obj.create( { 'name': market.get('MarketCode'), 'full_name': market.get('MarketDescription'), 'industry_type': 'market', }) + market_ids.append(market.id) + _logger.info('Created Market Ids : %s', market_ids) - # Get Sub-Market Data + @api.model + def sync_submarket_data(self, cr): + """Synchronize Submarket Data. + + This method is used to sync submarket data. + """ + industry_obj = self.env['res.partner.industry'] + cr = self._cr + submarket_ids = [] submarket_data = self.aln_auth_login('Submarkets') if submarket_data: submarket_data = eval(submarket_data).get("value", []) @@ -89,16 +118,25 @@ def _cron_sync_with_aln(self): market_id = cr.fetchone() market_id = market_id and market_id[0] if not available_submarket: - industry_obj.create( + submarket = industry_obj.create( { 'name': submarket.get('SubMarketDescription'), 'parent_id': market_id, 'industry_type': 'sub-market', 'ref': submarket.get('SubmarketId'), }) + submarket_ids.append(submarket.id) + _logger.info('Created SubMarket Ids : %s', submarket_ids) - # Get Status Code Data + @api.model + def sync_status_code(self, cr): + """Synchronize Status Code Data. + + This method is used to sync status code data. + """ + status_code_obj = self.env['status.code'] status_code = self.aln_auth_login('StatusCodes') + status_ids = [] if status_code: status_code = eval(status_code).get("value", []) for code in status_code: @@ -111,28 +149,155 @@ def _cron_sync_with_aln(self): """ % (code.get('StatusDescription'),)) available_code = cr.fetchone() if not available_code: - status_code_obj.create( + status = status_code_obj.create( { 'name': code.get('StatusDescription'), 'code': code.get('Status') }) + status_ids.append(status.id) + _logger.info('Created Status Code Ids : %s', status_ids) - # Get Management Companies Data - # Working On this -# management_companies = self.aln_auth_login('ManagementCompanies') -# if management_companies: + @api.model + def sync_management_companies_data(self, cr): + """Synchronize Management Companies Data. + + This method is used to sync management companies data. + """ + lead_obj = self.env['crm.lead'] + partner_obj = self.env['res.partner'] + management_companies = self.aln_auth_login( + 'ManagementCompanies') + lead_ids = [] + partner_ids = [] + if management_companies: # When eval management companies data as dictionary at that time # dictionary contain null value without quotes. # so it's give error 'null is not defined'. # so to fix that issue assign null as None here. -# null=None -# management_companies = eval(management_companies).get("value", []) -# for company in management_companies: -# if not company.get('ManagementCompanyParentId'): -# cr.execute(""" -# Select -# id -# from -# crm_lead -# where name= '%s' -# """ % (company.get('ManagementCompanyName'),)) + null = None + management_companies = eval(management_companies).get("value", []) + for company in management_companies: + model = "crm_lead" + obj = lead_obj + query = "select id from %s where name = '%s'" + if company.get('ManagementCompanyParentId'): + model = "res_partner" + obj = partner_obj + query += " and partner_type='management_company'" + query += " limit 1" + cr.execute(query % (model, + company.get('ManagementCompanyName'))) + company_lead = cr.fetchone() + if company_lead: + continue + cr.execute(""" + Select + id + from + res_partner_industry + where name= '%s' and industry_type='market' + limit 1 + """ % (company.get('ManagementCompanyMarket'),)) + market_id = cr.fetchone() + market_id = market_id and market_id[0] + + lead_vals = { + 'name': company.get('ManagementCompanyName'), + 'industry_id': market_id, + 'website': company.get( + 'ManagementCompanyWebSite'), + 'lastdate_changed': company.get( + 'ManagementCompanyLastDateChanged'), + 'rowversion': company.get('RowVersion'), + } + if company.get('Addresses', False): + address = company['Addresses'][0] + cr.execute(""" + select + id, country_id + from + res_country_state + where + code='%s' + limit 1""" % (address.get('AddressState'))) + res = cr.fetchone() + state_id = country_id = 0 + if res: + state_id = res[0] + country_id = res[1] + lead_vals.update( + { + 'street': address.get('AddressLine1'), + 'street2': address.get('AddressLine2'), + 'city': address.get('AddressCity'), + 'state_id': state_id, + 'zip': address.get('AddressZIP'), + 'country_id': country_id, + }) + if company.get('ManagementCompanyParentId'): + lead_vals.update( + { + 'address_type': address.get('AddressType'), + 'ref': company.get('ManagementCompanyEntityId'), + 'partner_type': 'management_company', + }) + else: + lead_vals.update( + { + 'referred': company.get( + 'ManagementCompanyEntityId'), + }) + if company.get('PhoneNumbers', False): + numbers = company['PhoneNumbers'] + for num in numbers: + if num.get('IsPrimary') == 'Y': + lead_vals.update({ + 'phone': num.get('Number') + }) + if (num.get('PhoneNumberType') == "Fax Number" and + company.get('ManagementCompanyParentId')): + lead_vals.update({ + 'fax': num.get('Number') + }) + lead = obj.create(lead_vals) + if company.get('ManagementCompanyParentId'): + partner_ids.append(lead.id) + else: + lead_ids.append(lead.id) + _logger.info('Created Management Companies Leads : %s', lead_ids) + _logger.info('Created Management Companies Partners : %s', partner_ids) + + @api.model + def sync_owner_data(self, cr, null=None): + """Synchronize Owners Data. + + This method is used to sync owner data. + """ + # working on this + owner_data = self.aln_auth_login('Owners') + if not owner_data: + return False + owner_data = eval(owner_data).get("value", []) +# for owner in owner_data: +# query= "select id from crm_lead where name = '%s'" +# cr.execute(query % (owner.get('OwnerName'))) +# part = cr.fetchall() + + @api.model + def _cron_sync_with_aln(self): + cr = self._cr + + # Get Market Data + self.sync_market_data(cr) + + # Get Sub-Market Data + self.sync_submarket_data(cr) + + # Get Status Code Data + self.sync_status_code(cr) + + # Get Management Companies Data + self.sync_management_companies_data(cr) + + # Woring on this. +# self.sync_owner_data(cr) diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 7b3ad0e3..234f0b8d 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -15,3 +15,4 @@ class ResPartner(models.Model): 'Partner Type') lastdate_changed = fields.Datetime('LastDateChanged') address_type = fields.Char('AddressType') + rowversion = fields.Char('Row Version') From d8f0f476f5007c13182aa2c67224507a632254be Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Thu, 21 Nov 2019 19:08:03 +0530 Subject: [PATCH 05/18] [IMP] Improved code as per commented in github, added method to sync contact, owner and management companies. --- connector_alndata/__init__.py | 2 + connector_alndata/__manifest__.py | 7 +- .../data/ir_config_parameter_data.xml | 1 - connector_alndata/data/sync_aln_data_view.xml | 1 - connector_alndata/models/__init__.py | 3 +- connector_alndata/models/crm_lead.py | 426 ++++++++++-------- connector_alndata/models/res_partner.py | 4 +- .../models/res_partner_industry.py | 20 +- connector_alndata/models/status_code.py | 14 - connector_alndata/readme/CONTRIBUTORS.rst | 10 +- .../security/ir.model.access.csv | 3 - 11 files changed, 263 insertions(+), 228 deletions(-) delete mode 100644 connector_alndata/models/status_code.py delete mode 100644 connector_alndata/security/ir.model.access.csv diff --git a/connector_alndata/__init__.py b/connector_alndata/__init__.py index 83e553ac..60cdf63f 100644 --- a/connector_alndata/__init__.py +++ b/connector_alndata/__init__.py @@ -1,3 +1,5 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py index 4dce3ec0..a1118b7b 100644 --- a/connector_alndata/__manifest__.py +++ b/connector_alndata/__manifest__.py @@ -1,4 +1,6 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) { 'name': 'ALN Data Connector', @@ -9,7 +11,8 @@ 'author': 'Open Source Integrators, Odoo Community Association (OCA),', 'website': 'https://github.com/OCA/l10n-usa', 'category': 'Tools', - 'maintainer': 'max3903', + 'maintainers': ['max3903'], + 'development_status': 'Beta', 'depends': [ 'crm', 'fieldservice', diff --git a/connector_alndata/data/ir_config_parameter_data.xml b/connector_alndata/data/ir_config_parameter_data.xml index fe1eb410..12b3430f 100644 --- a/connector_alndata/data/ir_config_parameter_data.xml +++ b/connector_alndata/data/ir_config_parameter_data.xml @@ -1,4 +1,3 @@ - diff --git a/connector_alndata/data/sync_aln_data_view.xml b/connector_alndata/data/sync_aln_data_view.xml index 2bd46c04..f1e4af22 100644 --- a/connector_alndata/data/sync_aln_data_view.xml +++ b/connector_alndata/data/sync_aln_data_view.xml @@ -1,4 +1,3 @@ - diff --git a/connector_alndata/models/__init__.py b/connector_alndata/models/__init__.py index d84ee5dc..bb30e6ce 100644 --- a/connector_alndata/models/__init__.py +++ b/connector_alndata/models/__init__.py @@ -1,6 +1,7 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import res_partner from . import res_partner_industry from . import crm_lead -from . import status_code diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index ba31ef8b..4abce42b 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -1,12 +1,12 @@ # Copyright (C) 2019 Open Source Integrators -# +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging import requests from odoo import api, fields, models, _ -from odoo.exceptions import RedirectWarning +from odoo.exceptions import RedirectWarning, Warning _logger = logging.getLogger(__name__) @@ -44,260 +44,300 @@ def aln_auth_login(self, data_key=''): ('Accept', 'application/json'), ('$expand', 'Addresses,PhoneNumbers'), ) + if data_key == 'Contacts': + params = ( + ('apikey', api_key), + ('Accept', 'application/json'), + ('$expand', 'Addresses,PhoneNumbers,JobCategories'), + ) try: response = requests.get(url, params=params) + response.raise_for_status() except Exception as e: - raise Warning(_(("%s.") % str(e))) - response.raise_for_status() + raise Warning(_("%s" % e)) + content = response.content.decode('utf8') return content + def get_state(self, obj, state_code): + """State. + + This method is used to search state from state code. + """ + return obj.search([('code', '=', state_code)], limit=1) + + def get_market(self, obj, market): + """Market/Submarket. + + This method is used to search market or submarket base on name. + """ + return obj.search([('name', '=', market)], limit=1) + @api.model - def sync_market_data(self, cr): + def _prepare_industry_values(self, industry=None, origin='market'): + if not industry: + return {} + values = { + 'name': industry.get('MarketId'), + 'full_name': industry.get('MarketDescription'), + } + if origin == 'submarket': + values.update({ + 'name': industry.get('SubMarketDescription'), + 'ref': industry.get('SubmarketId'), + }) + return values + + @api.model + def sync_market_data(self): """Synchronize Market Data. This method is used to sync market data. """ industry_obj = self.env['res.partner.industry'] - cr = self._cr market_data = self.aln_auth_login('Markets') market_ids = [] if market_data: market_data = eval(market_data).get("value", []) for market in market_data: - cr.execute(""" - Select - id , name - from - res_partner_industry - where - name= '%s' or full_name='%s' and - industry_type='market' - """ % (market.get('MarketCode'), - market.get('MarketDescription'))) - available_market = cr.fetchall() + available_market = self.get_market(industry_obj, + market.get('MarketId')) if not available_market: - market = industry_obj.create( - { - 'name': market.get('MarketCode'), - 'full_name': market.get('MarketDescription'), - 'industry_type': 'market', - }) + market_vals = self._prepare_industry_values(market) + market = industry_obj.create(market_vals) market_ids.append(market.id) _logger.info('Created Market Ids : %s', market_ids) @api.model - def sync_submarket_data(self, cr): + def sync_submarket_data(self): """Synchronize Submarket Data. This method is used to sync submarket data. """ industry_obj = self.env['res.partner.industry'] - cr = self._cr submarket_ids = [] submarket_data = self.aln_auth_login('Submarkets') if submarket_data: submarket_data = eval(submarket_data).get("value", []) for submarket in submarket_data: - cr.execute(""" - Select - id - from - res_partner_industry - where name= '%s' and industry_type='sub-market' - """ % (submarket.get('SubMarketDescription'),)) - available_submarket = cr.fetchone() - cr.execute(""" - Select - id - from - res_partner_industry - where name= '%s' and industry_type='market' - limit 1 - """ % (submarket.get('Market'),)) - market_id = cr.fetchone() - market_id = market_id and market_id[0] + available_submarket = self.get_market( + industry_obj, submarket.get('SubMarketDescription')) if not available_submarket: - submarket = industry_obj.create( - { - 'name': submarket.get('SubMarketDescription'), - 'parent_id': market_id, - 'industry_type': 'sub-market', - 'ref': submarket.get('SubmarketId'), - }) + market_id = self.get_market(industry_obj, + submarket.get('Market')) + submarket_vals = self._prepare_industry_values( + submarket, 'submarket') + if market_id: + submarket_vals.update({ + 'parent_id': market_id.id}) + submarket = industry_obj.create(submarket_vals) submarket_ids.append(submarket.id) _logger.info('Created SubMarket Ids : %s', submarket_ids) @api.model - def sync_status_code(self, cr): - """Synchronize Status Code Data. + def get_title(self, obj, title): + """Get Title. + + This method is used to get title from odoo database + if it is not exist then create a title. + """ + title_id = obj.search([('name', '=', title)], limit=1) + if not title_id: + title_id = obj.create({'name': title}) + return title_id.id + + def sync_owner_contact_data(self, datas, origin='', null=None): + """Synchronize Owner, Contact and Management Companies Data. - This method is used to sync status code data. + This method is used to synchronize owner, contact and + management companies data.Differentiate data by origin. + Using origin prepared values for owner, contact and + management companies data. """ - status_code_obj = self.env['status.code'] - status_code = self.aln_auth_login('StatusCodes') - status_ids = [] - if status_code: - status_code = eval(status_code).get("value", []) - for code in status_code: - cr.execute(""" - Select - id - from - status_code - where name= '%s' - """ % (code.get('StatusDescription'),)) - available_code = cr.fetchone() - if not available_code: - status = status_code_obj.create( - { - 'name': code.get('StatusDescription'), - 'code': code.get('Status') + lead_obj = self.env['crm.lead'] + partner_obj = self.env['res.partner'] + industry_obj = self.env['res.partner.industry'] + state_obj = self.env['res.country.state'] + res_partner_title_obj = self.env['res.partner.title'] + partner_ids = [] + lead_ids = [] + contact_ids = [] + owner_ids = [] + if not datas: + return False + + datas = eval(datas).get('value') + for data in datas: + obj = lead_obj + name = data.get('ManagementCompanyName') + last_changed = data.get('ManagementCompanyLastDateChanged') + referred = data.get('ManagementCompanyEntityId') + if origin == 'owner': + name = data.get('OwnerName') + last_changed = False + referred = data.get('OwnerId') + elif origin == 'contact': + name = data.get('ContactName') + last_changed = data.get('ContactLastDateChanged') + referred = data.get('ContactId') + domain = [('name', '=', name)] + if data.get('ManagementCompanyParentId'): + obj = partner_obj + domain += [('partner_type', '=', 'management_company')] + rec = obj.search(domain) + if rec: + continue + market = self.get_market( + industry_obj, data.get('ManagementCompanyMarket')) + lead_vals = { + 'name': name, + } + if data.get('ManagementCompanyWebSite'): + lead_vals.update( + {'website': data.get('ManagementCompanyWebSite'), + 'industry_id': market.id, }) + if data.get('Addresses', False): + address = data['Addresses'][0] + state = self.get_state(state_obj, + address.get('AddressState')) + country_id = state and state.country_id.id or 0 + lead_vals.update( + { + 'street': address.get('AddressLine1'), + 'street2': address.get('AddressLine2'), + 'city': address.get('AddressCity'), + 'state_id': state.id, + 'zip': address.get('AddressZIP'), + 'country_id': country_id, + }) + if data.get('ManagementCompanyParentId'): + lead_vals.update( + { + 'address_type': address.get('AddressType'), + 'ref': data.get('ManagementCompanyEntityId'), + 'partner_type': 'management_company', + }) + else: + lead_vals.update( + { + 'lastdate_changed': last_changed, + 'referred': referred, + }) + if data.get('PhoneNumbers', False): + numbers = data['PhoneNumbers'] + for num in numbers: + if num.get('IsPrimary') == 'Y': + lead_vals.update({ + 'phone': num.get('Number') + }) + if (num.get('PhoneNumberType') == "Fax Number" and + data.get('ManagementCompanyParentId')): + lead_vals.update({ + 'fax': num.get('Number') }) - status_ids.append(status.id) - _logger.info('Created Status Code Ids : %s', status_ids) + if origin == 'contact': + lead = lead_obj.search([ + ('referred', '=', data.get('CorporateEntityId'))], limit=1) + partner_name = lead and lead.name or '' + function = '' + for job in data.get('JobCategories'): + function += job.get('JobCategoryDescription') + ',' + lead_vals.update({ + 'email_from': data.get('ContactEMail'), + 'partner_name': partner_name, + 'contact_name': data.get('ContactName'), + 'title': self.get_title(res_partner_title_obj, + data.get('ContactTitle')), + 'function': function[:-1], + }) + + if origin == 'owner': + address = data.get('OwnerAddress') + address_lst = address.split('\r\n') + street = city = state_code = owner_zip = '' + if len(address_lst) > 1: + street = address_lst[0] + city_state = address_lst[1].split(',') + if len(city_state) > 1: + city = city_state[0] + state_zip = (city_state[1].strip()).split(' ') + if len(state_zip) > 1: + state_code = state_zip[0] + owner_zip = state_zip[1] + state = self.get_state(state_obj, state_code) + lead_vals.update({ + 'street': street, + 'city': city, + 'state_id': state.id, + 'zip': owner_zip, + 'country_id': state.country_id.id, + 'phone': data.get('OwnerPhone'), + 'contact_name': data.get('OwnerName') + }) + lead = obj.create(lead_vals) + if origin == 'contact': + contact_ids.append(lead.id) + elif origin == 'owner': + owner_ids.append(lead.id) + elif data.get('ManagementCompanyParentId'): + partner_ids.append(lead.id) + else: + lead_ids.append(lead.id) + if origin == 'contact': + _logger.info('Created Contacts : %s', contact_ids) + elif origin == 'owner': + _logger.info('Created Owners : %s', owner_ids) + else: + _logger.info( + 'Created Management Companies Partners : %s', partner_ids) + _logger.info('Created Management Companies Leads : %s', lead_ids) @api.model - def sync_management_companies_data(self, cr): + def sync_management_companies_data(self): """Synchronize Management Companies Data. This method is used to sync management companies data. """ - lead_obj = self.env['crm.lead'] - partner_obj = self.env['res.partner'] management_companies = self.aln_auth_login( 'ManagementCompanies') - lead_ids = [] - partner_ids = [] - if management_companies: - # When eval management companies data as dictionary at that time - # dictionary contain null value without quotes. - # so it's give error 'null is not defined'. - # so to fix that issue assign null as None here. - null = None - management_companies = eval(management_companies).get("value", []) - for company in management_companies: - model = "crm_lead" - obj = lead_obj - query = "select id from %s where name = '%s'" - if company.get('ManagementCompanyParentId'): - model = "res_partner" - obj = partner_obj - query += " and partner_type='management_company'" - query += " limit 1" - cr.execute(query % (model, - company.get('ManagementCompanyName'))) - company_lead = cr.fetchone() - if company_lead: - continue - cr.execute(""" - Select - id - from - res_partner_industry - where name= '%s' and industry_type='market' - limit 1 - """ % (company.get('ManagementCompanyMarket'),)) - market_id = cr.fetchone() - market_id = market_id and market_id[0] - - lead_vals = { - 'name': company.get('ManagementCompanyName'), - 'industry_id': market_id, - 'website': company.get( - 'ManagementCompanyWebSite'), - 'lastdate_changed': company.get( - 'ManagementCompanyLastDateChanged'), - 'rowversion': company.get('RowVersion'), - } - if company.get('Addresses', False): - address = company['Addresses'][0] - cr.execute(""" - select - id, country_id - from - res_country_state - where - code='%s' - limit 1""" % (address.get('AddressState'))) - res = cr.fetchone() - state_id = country_id = 0 - if res: - state_id = res[0] - country_id = res[1] - lead_vals.update( - { - 'street': address.get('AddressLine1'), - 'street2': address.get('AddressLine2'), - 'city': address.get('AddressCity'), - 'state_id': state_id, - 'zip': address.get('AddressZIP'), - 'country_id': country_id, - }) - if company.get('ManagementCompanyParentId'): - lead_vals.update( - { - 'address_type': address.get('AddressType'), - 'ref': company.get('ManagementCompanyEntityId'), - 'partner_type': 'management_company', - }) - else: - lead_vals.update( - { - 'referred': company.get( - 'ManagementCompanyEntityId'), - }) - if company.get('PhoneNumbers', False): - numbers = company['PhoneNumbers'] - for num in numbers: - if num.get('IsPrimary') == 'Y': - lead_vals.update({ - 'phone': num.get('Number') - }) - if (num.get('PhoneNumberType') == "Fax Number" and - company.get('ManagementCompanyParentId')): - lead_vals.update({ - 'fax': num.get('Number') - }) - lead = obj.create(lead_vals) - if company.get('ManagementCompanyParentId'): - partner_ids.append(lead.id) - else: - lead_ids.append(lead.id) - _logger.info('Created Management Companies Leads : %s', lead_ids) - _logger.info('Created Management Companies Partners : %s', partner_ids) + self.sync_owner_contact_data(management_companies, + 'management_companies') @api.model - def sync_owner_data(self, cr, null=None): + def sync_owner_data(self): """Synchronize Owners Data. This method is used to sync owner data. """ - # working on this owner_data = self.aln_auth_login('Owners') - if not owner_data: - return False - owner_data = eval(owner_data).get("value", []) -# for owner in owner_data: -# query= "select id from crm_lead where name = '%s'" -# cr.execute(query % (owner.get('OwnerName'))) -# part = cr.fetchall() + self.sync_owner_contact_data(owner_data, 'owner') + + @api.model + def sync_contact_data(self): + """Synchronize Owners Data. + + This method is used to sync owner data. + """ + contact_data = self.aln_auth_login('Contacts') + self.sync_owner_contact_data(contact_data, 'contact') @api.model def _cron_sync_with_aln(self): - cr = self._cr + """Synchronize data with ALN Data. + This method is used to get data from ALN Data and create data in odoo. + """ # Get Market Data - self.sync_market_data(cr) + self.sync_market_data() # Get Sub-Market Data - self.sync_submarket_data(cr) + self.sync_submarket_data() - # Get Status Code Data - self.sync_status_code(cr) + # Get Owner Data + self.sync_owner_data() # Get Management Companies Data - self.sync_management_companies_data(cr) + self.sync_management_companies_data() - # Woring on this. -# self.sync_owner_data(cr) + # Get Contact Data + self.sync_contact_data() diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 234f0b8d..708ef4ad 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -1,5 +1,5 @@ # Copyright (C) 2019 Open Source Integrators -# +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import fields, models @@ -13,6 +13,6 @@ class ResPartner(models.Model): ('management_company', 'Management Company'), ('contact', 'Contact')], 'Partner Type') - lastdate_changed = fields.Datetime('LastDateChanged') +# lastdate_changed = fields.Datetime('LastDateChanged') address_type = fields.Char('AddressType') rowversion = fields.Char('Row Version') diff --git a/connector_alndata/models/res_partner_industry.py b/connector_alndata/models/res_partner_industry.py index ec52da13..f35af090 100644 --- a/connector_alndata/models/res_partner_industry.py +++ b/connector_alndata/models/res_partner_industry.py @@ -1,5 +1,5 @@ # Copyright (C) 2019 Open Source Integrators -# +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, fields, models @@ -10,11 +10,11 @@ class ResPartnerIndustry(models.Model): ref = fields.Char('Reference') parent_id = fields.Many2one('res.partner.industry', 'Parent') - Code = fields.Char('Market Code') - description = fields.Char('Market Description') - industry_type = fields.Selection([('market', 'Market'), - ('sub-market', 'Sub Market')], - 'Industry Type') +# Code = fields.Char('Market Code') +# description = fields.Char('Market Description') +# industry_type = fields.Selection([('market', 'Market'), +# ('sub-market', 'Sub Market')], +# 'Industry Type') @api.multi def name_get(self): @@ -25,9 +25,11 @@ def name_get(self): res = [] for partner in self: display_name = '' - if partner.parent_id: - display_name += partner.parent_id.name + '/' + partner.name - else: + if partner.parent_id and not partner.name: + display_name += partner.parent_id.name + if partner.parent_id and partner.name: + display_name += partner.parent_id.name + '/' +partner.name + if partner.name and not partner.parent_id: display_name += partner.name res.append((partner.id, display_name)) return res diff --git a/connector_alndata/models/status_code.py b/connector_alndata/models/status_code.py deleted file mode 100644 index 69c1573b..00000000 --- a/connector_alndata/models/status_code.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (C) 2019 Open Source Integrators -# -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields, models - - -class StatusCode(models.Model): - - _name = "status.code" - _description = "Status Code" - - name = fields.Char('Status') - code = fields.Char('Code') diff --git a/connector_alndata/readme/CONTRIBUTORS.rst b/connector_alndata/readme/CONTRIBUTORS.rst index 64881b41..76464a46 100644 --- a/connector_alndata/readme/CONTRIBUTORS.rst +++ b/connector_alndata/readme/CONTRIBUTORS.rst @@ -1,2 +1,8 @@ -* Maxime Chambreuil -* Serpent Consulting Services Pvt. Ltd. +* Open Source Integrators + + * Mayank Gosai + * Maxime Chambreuil + +* Serpent Consulting Services Pvt. Ltd. + + * Nikita Vaghela diff --git a/connector_alndata/security/ir.model.access.csv b/connector_alndata/security/ir.model.access.csv deleted file mode 100644 index 0fcb066b..00000000 --- a/connector_alndata/security/ir.model.access.csv +++ /dev/null @@ -1,3 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -,,,,,,, -access_status_code,access_status_code,model_status_code,base.group_user,1,1,1,1 From 5fe6663345c23f2f565cc3250cb63912d5f1ebb1 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Fri, 22 Nov 2019 19:15:06 +0530 Subject: [PATCH 06/18] [IMP] Improved rowversion in connector_alndata. --- connector_alndata/__manifest__.py | 1 - connector_alndata/models/crm_lead.py | 193 ++++++++++++++------------- 2 files changed, 101 insertions(+), 93 deletions(-) diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py index a1118b7b..a2f6ce41 100644 --- a/connector_alndata/__manifest__.py +++ b/connector_alndata/__manifest__.py @@ -18,7 +18,6 @@ 'fieldservice', ], 'data': [ - 'security/ir.model.access.csv', 'data/ir_config_parameter_data.xml', 'data/sync_aln_data_view.xml', 'views/res_partner_industry_view.xml', diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 4abce42b..2dce825a 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -4,6 +4,7 @@ import logging import requests +import json from odoo import api, fields, models, _ from odoo.exceptions import RedirectWarning, Warning @@ -15,18 +16,25 @@ class Lead(models.Model): _inherit = "crm.lead" lastdate_changed = fields.Datetime('LastDateChanged') - rowversion = fields.Char('Row Version') industry_id = fields.Many2one('res.partner.industry', 'Market') + lead_type = fields.Selection( + [('owner', 'Owner'), + ('management_company', 'Management Company'), + ('contact', 'Contact')], + 'Partner Type') def aln_auth_login(self, data_key=''): """Aln Connector. This method is used to connect with ALN and fetch the data. """ - url = self.env['ir.config_parameter'].get_param('alndata.api.url') - api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') + config_obj = self.env['ir.config_parameter'] + url = config_obj.get_param('alndata.api.url') + api_key = config_obj.get_param('alndata.api.key') + full_content = [] url = url + data_key + count = 1 if api_key == '0': action = self.env.ref('base.ir_config_list_action') msg = _('Cannot find a ALN Data URL and API key, ' @@ -34,30 +42,45 @@ def aln_auth_login(self, data_key=''): '\nPlease go to System Parameters.') raise RedirectWarning(msg, action.id, _('Go to the configuration panel')) - params = ( - ('apikey', api_key), - ('Accept', 'application/json') - ) + params = { + 'apikey': api_key, + 'Accept': 'application/json', + } + manag_company_key = contact_key = False if data_key == 'ManagementCompanies': - params = ( - ('apikey', api_key), - ('Accept', 'application/json'), - ('$expand', 'Addresses,PhoneNumbers'), - ) + manag_company_key = config_obj.get_param( + 'alndata.managementcompanies.rowversion') + params.update({'$expand': 'Addresses,PhoneNumbers'}) + if manag_company_key != '0': + params.update( + {'$filter': 'RowVersion gt ' + manag_company_key}) if data_key == 'Contacts': - params = ( - ('apikey', api_key), - ('Accept', 'application/json'), - ('$expand', 'Addresses,PhoneNumbers,JobCategories'), - ) - try: - response = requests.get(url, params=params) - response.raise_for_status() - except Exception as e: - raise Warning(_("%s" % e)) - - content = response.content.decode('utf8') - return content + contact_key = config_obj.get_param('alndata.contacts.rowversion') + params.update({'$expand': 'Addresses,PhoneNumbers,JobCategories'}) + if contact_key != '0': + params.update({'$filter': 'RowVersion gt ' + contact_key}) + + # use count to fetch all data related filter by multiple request + while count != 0: + if count == 1: + count = 0 + try: + if count > 1: + params.update({'$skip': count}) + response = requests.get(url, params=params) + response.raise_for_status() + except Exception as e: + raise Warning(_("%s" % e)) + content = response.content.decode('utf8') + if content: + content = json.loads(content).get('value') + if len(content) > 0: + count += len(content) + full_content += content + else: + count = 0 + print("\n len >>>>>", len(full_content)) + return full_content or [] def get_state(self, obj, state_code): """State. @@ -95,17 +118,14 @@ def sync_market_data(self): This method is used to sync market data. """ industry_obj = self.env['res.partner.industry'] - market_data = self.aln_auth_login('Markets') market_ids = [] - if market_data: - market_data = eval(market_data).get("value", []) - for market in market_data: - available_market = self.get_market(industry_obj, - market.get('MarketId')) - if not available_market: - market_vals = self._prepare_industry_values(market) - market = industry_obj.create(market_vals) - market_ids.append(market.id) + for market in self.aln_auth_login('Markets'): + available_market = self.get_market(industry_obj, + market.get('MarketId')) + if not available_market: + market_vals = self._prepare_industry_values(market) + market = industry_obj.create(market_vals) + market_ids.append(market.id) _logger.info('Created Market Ids : %s', market_ids) @api.model @@ -116,22 +136,19 @@ def sync_submarket_data(self): """ industry_obj = self.env['res.partner.industry'] submarket_ids = [] - submarket_data = self.aln_auth_login('Submarkets') - if submarket_data: - submarket_data = eval(submarket_data).get("value", []) - for submarket in submarket_data: - available_submarket = self.get_market( - industry_obj, submarket.get('SubMarketDescription')) - if not available_submarket: - market_id = self.get_market(industry_obj, - submarket.get('Market')) - submarket_vals = self._prepare_industry_values( - submarket, 'submarket') - if market_id: - submarket_vals.update({ - 'parent_id': market_id.id}) - submarket = industry_obj.create(submarket_vals) - submarket_ids.append(submarket.id) + for submarket in self.aln_auth_login('Submarkets'): + available_submarket = self.get_market( + industry_obj, submarket.get('SubMarketDescription')) + if not available_submarket: + market_id = self.get_market(industry_obj, + submarket.get('Market')) + submarket_vals = self._prepare_industry_values( + submarket, 'submarket') + if market_id: + submarket_vals.update({ + 'parent_id': market_id.id}) + submarket = industry_obj.create(submarket_vals) + submarket_ids.append(submarket.id) _logger.info('Created SubMarket Ids : %s', submarket_ids) @api.model @@ -146,7 +163,7 @@ def get_title(self, obj, title): title_id = obj.create({'name': title}) return title_id.id - def sync_owner_contact_data(self, datas, origin='', null=None): + def sync_owner_contact_data(self, origin=''): """Synchronize Owner, Contact and Management Companies Data. This method is used to synchronize owner, contact and @@ -163,20 +180,31 @@ def sync_owner_contact_data(self, datas, origin='', null=None): lead_ids = [] contact_ids = [] owner_ids = [] - if not datas: - return False + rowversion_list = [] + + if not origin: + datas = self.aln_auth_login( + 'ManagementCompanies') + elif origin == 'owner': + datas = self.aln_auth_login('Owners') + else: + datas = self.aln_auth_login('Contacts') - datas = eval(datas).get('value') for data in datas: obj = lead_obj name = data.get('ManagementCompanyName') + rowversion = int(data.get('RowVersion', 0)) + rowversion_list.append(rowversion) last_changed = data.get('ManagementCompanyLastDateChanged') referred = data.get('ManagementCompanyEntityId') + lead_type = 'management_company' if origin == 'owner': name = data.get('OwnerName') + lead_type = 'owner' last_changed = False referred = data.get('OwnerId') elif origin == 'contact': + lead_type = 'contact' name = data.get('ContactName') last_changed = data.get('ContactLastDateChanged') referred = data.get('ContactId') @@ -184,6 +212,8 @@ def sync_owner_contact_data(self, datas, origin='', null=None): if data.get('ManagementCompanyParentId'): obj = partner_obj domain += [('partner_type', '=', 'management_company')] + else: + domain += [('lead_type', '=', lead_type)] rec = obj.search(domain) if rec: continue @@ -191,6 +221,7 @@ def sync_owner_contact_data(self, datas, origin='', null=None): industry_obj, data.get('ManagementCompanyMarket')) lead_vals = { 'name': name, + 'lead_type': lead_type, } if data.get('ManagementCompanyWebSite'): lead_vals.update( @@ -283,44 +314,22 @@ def sync_owner_contact_data(self, datas, origin='', null=None): partner_ids.append(lead.id) else: lead_ids.append(lead.id) + RowVersion = rowversion_list and max(rowversion_list) or 0 if origin == 'contact': _logger.info('Created Contacts : %s', contact_ids) + if RowVersion: + self.env['ir.config_parameter'].sudo().set_param( + 'alndata.contacts.rowversion', RowVersion) elif origin == 'owner': _logger.info('Created Owners : %s', owner_ids) else: + if RowVersion: + self.env['ir.config_parameter'].sudo().set_param( + 'alndata.managementcompanies.rowversion', RowVersion) _logger.info( 'Created Management Companies Partners : %s', partner_ids) _logger.info('Created Management Companies Leads : %s', lead_ids) - @api.model - def sync_management_companies_data(self): - """Synchronize Management Companies Data. - - This method is used to sync management companies data. - """ - management_companies = self.aln_auth_login( - 'ManagementCompanies') - self.sync_owner_contact_data(management_companies, - 'management_companies') - - @api.model - def sync_owner_data(self): - """Synchronize Owners Data. - - This method is used to sync owner data. - """ - owner_data = self.aln_auth_login('Owners') - self.sync_owner_contact_data(owner_data, 'owner') - - @api.model - def sync_contact_data(self): - """Synchronize Owners Data. - - This method is used to sync owner data. - """ - contact_data = self.aln_auth_login('Contacts') - self.sync_owner_contact_data(contact_data, 'contact') - @api.model def _cron_sync_with_aln(self): """Synchronize data with ALN Data. @@ -333,11 +342,11 @@ def _cron_sync_with_aln(self): # Get Sub-Market Data self.sync_submarket_data() - # Get Owner Data - self.sync_owner_data() - - # Get Management Companies Data - self.sync_management_companies_data() - - # Get Contact Data - self.sync_contact_data() +# # Get Owner Data + self.sync_owner_contact_data(origin='owner') +# +# # Get Management Companies Data + self.sync_owner_contact_data() +# +# # Get Contact Data + self.sync_owner_contact_data('contact') From 922261f7b7a29f75043cbe9ccb83973e036b547e Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Mon, 25 Nov 2019 18:45:10 +0530 Subject: [PATCH 07/18] [IMP]Added method to synchronize apartments and new construction. --- connector_alndata/models/__init__.py | 1 + connector_alndata/models/crm_lead.py | 336 ++++++++++++++++++++--- connector_alndata/models/fsm_location.py | 18 ++ connector_alndata/models/res_partner.py | 3 +- 4 files changed, 317 insertions(+), 41 deletions(-) create mode 100644 connector_alndata/models/fsm_location.py diff --git a/connector_alndata/models/__init__.py b/connector_alndata/models/__init__.py index bb30e6ce..e14dc2c9 100644 --- a/connector_alndata/models/__init__.py +++ b/connector_alndata/models/__init__.py @@ -5,3 +5,4 @@ from . import res_partner from . import res_partner_industry from . import crm_lead +from . import fsm_location diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 2dce825a..97f5778f 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -2,12 +2,17 @@ # Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import threading import logging import requests import json +import base64 -from odoo import api, fields, models, _ +# from datetime import datetime + +from odoo import api, fields, models, _, sql_db from odoo.exceptions import RedirectWarning, Warning +# from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as dtf _logger = logging.getLogger(__name__) @@ -20,8 +25,9 @@ class Lead(models.Model): lead_type = fields.Selection( [('owner', 'Owner'), ('management_company', 'Management Company'), - ('contact', 'Contact')], - 'Partner Type') + ('contact', 'Contact'), + ('new_construction', 'New Constructions')], + 'Lead Type') def aln_auth_login(self, data_key=''): """Aln Connector. @@ -34,7 +40,8 @@ def aln_auth_login(self, data_key=''): full_content = [] url = url + data_key - count = 1 + count = 0 + flag = True if api_key == '0': action = self.env.ref('base.ir_config_list_action') msg = _('Cannot find a ALN Data URL and API key, ' @@ -46,6 +53,7 @@ def aln_auth_login(self, data_key=''): 'apikey': api_key, 'Accept': 'application/json', } + _logger.info('========== %s ==========', data_key) manag_company_key = contact_key = False if data_key == 'ManagementCompanies': manag_company_key = config_obj.get_param( @@ -59,13 +67,25 @@ def aln_auth_login(self, data_key=''): params.update({'$expand': 'Addresses,PhoneNumbers,JobCategories'}) if contact_key != '0': params.update({'$filter': 'RowVersion gt ' + contact_key}) +# if data_key == 'NewConstructions': +# construction_key = config_obj.get_param( +# 'alndata.newconstructions.rowversion') +# if construction_key != '0': +# date_time = construction_key.split('T') +# params.update( +# {'$filter': 'LastDateNewConstructionChanged gt ' + +# date_time[0]}) + if data_key == 'Apartments': + apartment_key = config_obj.get_param( + 'alndata.apartments.rowversion') + params.update({'$expand': 'Addresses,PhoneNumbers'}) + if apartment_key != '0': + params.update({'$filter': 'RowVersion gt ' + apartment_key}) # use count to fetch all data related filter by multiple request - while count != 0: - if count == 1: - count = 0 + while flag: try: - if count > 1: + if count > 0: params.update({'$skip': count}) response = requests.get(url, params=params) response.raise_for_status() @@ -78,8 +98,10 @@ def aln_auth_login(self, data_key=''): count += len(content) full_content += content else: + flag = False count = 0 - print("\n len >>>>>", len(full_content)) + _logger.info('========== No of datas : %s ==========', + len(full_content)) return full_content or [] def get_state(self, obj, state_code): @@ -151,6 +173,27 @@ def sync_submarket_data(self): submarket_ids.append(submarket.id) _logger.info('Created SubMarket Ids : %s', submarket_ids) + @api.model + def sync_status_code_data(self): + """Synchronize Status Codes Data. + + This method is used to sync status code data. + """ + status_obj = self.env['fsm.stage'] + stage_ids = [] + for state in self.aln_auth_login('StatusCodes'): + available_state = self.get_market(status_obj, + state.get('StatusDescription')) + if not available_state: + state_vals = { + 'name': state.get('StatusDescription'), + 'stage_type': 'location', + 'sequence': state.get('Status'), + } + state = status_obj.create(state_vals) + stage_ids.append(state.id) + _logger.info('Created Market Ids : %s', stage_ids) + @api.model def get_title(self, obj, title): """Get Title. @@ -180,13 +223,22 @@ def sync_owner_contact_data(self, origin=''): lead_ids = [] contact_ids = [] owner_ids = [] + construction_ids = [] + updated_partner_ids = [] + updated_lead_ids = [] + updated_contact_ids = [] + updated_owner_ids = [] + updated_construction_ids = [] rowversion_list = [] + last_update_date = [] if not origin: datas = self.aln_auth_login( 'ManagementCompanies') elif origin == 'owner': datas = self.aln_auth_login('Owners') + elif origin == 'new_construction': + datas = self.aln_auth_login('NewConstructions') else: datas = self.aln_auth_login('Contacts') @@ -208,15 +260,19 @@ def sync_owner_contact_data(self, origin=''): name = data.get('ContactName') last_changed = data.get('ContactLastDateChanged') referred = data.get('ContactId') + elif origin == 'new_construction': + lead_type = "new_construction" + name = data.get('ProjectName') + referred = data.get('NewConstructionId') + last_changed = data.get('LastDateNewConstructionChanged') + if last_changed: + last_update_date.append(last_changed) domain = [('name', '=', name)] if data.get('ManagementCompanyParentId'): obj = partner_obj domain += [('partner_type', '=', 'management_company')] else: domain += [('lead_type', '=', lead_type)] - rec = obj.search(domain) - if rec: - continue market = self.get_market( industry_obj, data.get('ManagementCompanyMarket')) lead_vals = { @@ -281,7 +337,6 @@ def sync_owner_contact_data(self, origin=''): data.get('ContactTitle')), 'function': function[:-1], }) - if origin == 'owner': address = data.get('OwnerAddress') address_lst = address.split('\r\n') @@ -305,30 +360,242 @@ def sync_owner_contact_data(self, origin=''): 'phone': data.get('OwnerPhone'), 'contact_name': data.get('OwnerName') }) - lead = obj.create(lead_vals) - if origin == 'contact': - contact_ids.append(lead.id) - elif origin == 'owner': - owner_ids.append(lead.id) - elif data.get('ManagementCompanyParentId'): - partner_ids.append(lead.id) + if origin == 'new_construction': + state = self.get_state(state_obj, data.get('ProjectState')) + description = '' + if data.get('StartDate'): + description += "Start Date : " + data.get('StartDate') + if data.get('LeaseDate'): + description += "\n" + "Lease Date : " + \ + data.get('LeaseDate') + if data.get('OccupancyDate'): + description += "\n" + "Occupancy Date : " + \ + data.get('OccupancyDate') + if data.get('CompletionDate'): + description += "\n" + "Completion Date : " + \ + data.get('CompletionDate') + if data.get('Progress'): + description += "\n" + "Progress : " + data.get('Progress') + if data.get('Market'): + description += "\n" + "Market : " + data.get('Market') + lead_vals.update({ + 'street': data.get('ProjectAddress'), + 'city': data.get('ProjectCity'), + 'state_id': state.id, + 'country_id': state.country_id.id, + 'zip': data.get('ProjectZIP'), + 'partner_name': data.get('Company'), + 'description': description, + }) + + lead = obj.search(domain) + if lead: + lead.write(lead_vals) + if origin == 'contact': + updated_contact_ids.append(lead.id) + elif origin == 'owner': + updated_owner_ids.append(lead.id) + elif origin == 'new_construction': + updated_construction_ids.append(lead.id) + elif data.get('ManagementCompanyParentId'): + updated_partner_ids.append(lead.id) + else: + updated_lead_ids.append(lead.id) else: - lead_ids.append(lead.id) - RowVersion = rowversion_list and max(rowversion_list) or 0 + lead = obj.create(lead_vals) + if origin == 'contact': + contact_ids.append(lead.id) + elif origin == 'owner': + owner_ids.append(lead.id) + elif origin == 'new_construction': + construction_ids.append(lead.id) + elif data.get('ManagementCompanyParentId'): + partner_ids.append(lead.id) + else: + lead_ids.append(lead.id) + row_version = rowversion_list and max(rowversion_list) or 0 + max_date = last_update_date and max(last_update_date) or 0 + if origin == 'contact': _logger.info('Created Contacts : %s', contact_ids) - if RowVersion: + _logger.info('Updated Contacts : %s', updated_contact_ids) + if row_version: self.env['ir.config_parameter'].sudo().set_param( - 'alndata.contacts.rowversion', RowVersion) + 'alndata.contacts.rowversion', row_version) elif origin == 'owner': _logger.info('Created Owners : %s', owner_ids) + _logger.info('Updated Owners : %s', updated_owner_ids) + elif origin == 'new_construction': + _logger.info('Created New Constructions : %s', + construction_ids) + _logger.info('Updated Constructions : %s', + updated_construction_ids) + if max_date: + self.env['ir.config_parameter'].sudo().set_param( + 'alndata.newconstructions.rowversion', max_date) else: - if RowVersion: + if row_version: self.env['ir.config_parameter'].sudo().set_param( - 'alndata.managementcompanies.rowversion', RowVersion) + 'alndata.managementcompanies.rowversion', row_version) _logger.info( 'Created Management Companies Partners : %s', partner_ids) _logger.info('Created Management Companies Leads : %s', lead_ids) + _logger.info( + 'Updated Management Companies Partners : %s', + updated_partner_ids) + _logger.info('Updated Management Companies Leads : %s', + updated_lead_ids) + + @api.model + def sync_apartment_data(self): + """Synchronize Apartments Data. + + This method is used to synchronize apartment data. + """ + create_apart_ids = [] + update_apart_ids = [] + stage_obj = self.env['fsm.stage'] + industry_obj = self.env['res.partner.industry'] + partner_obj = self.env['res.partner'] + state_obj = self.env['res.country.state'] + fsm_obj = self.env['fsm.location'] + rowversion_list = [] + for apart in self.aln_auth_login('Apartments'): + contact = partner_obj + industry = industry_obj + prop = apart.get('Property') + rowversion_list.append(int(apart.get('RowVersion'))) + stage = stage_obj.search( + [('sequence', '=', prop.get('Status')), + ('stage_type', '=', 'location')], + limit=1) + if prop.get('SubmarketId'): + industry = industry_obj.search( + [('ref', '=', prop.get('SubmarketId'))], + limit=1) + if not industry: + industry = self.get_market( + industry_obj, prop.get('Market')) + + image_data = b'' + if prop.get('AptPictureURL'): + image_res = requests.get(prop.get('AptPictureURL')) + image_data = image_res.content + apartment_vals = { + 'ref': prop.get('ApartmentId'), + 'stage_id': stage.id, + 'name': prop.get('AptName'), + 'email': prop.get('EMailAddress'), + 'industry_id': industry.id, + 'num_of_unit': prop.get('NumUnits'), + 'year_built': prop.get('YearBuilt'), + 'year_remodeled': prop.get('YearRemodeled'), + 'direction': prop.get('Directions'), + 'notes': prop.get('PropertyDescription'), + 'website': prop.get('AptHomePage'), + 'image': base64.b64encode(image_data), + } + if prop.get('CurrManager'): + contact = partner_obj.search( + [('name', '=', prop.get('CurrManager')), + ('partner_type', '=', 'contact')], + limit=1) + apartment_vals.update({'contact_id': contact and contact.id}) + if prop.get('CorporateManagementCompanyId'): + management_company = partner_obj.search( + [('ref', '=', prop.get('CorporateManagementCompanyId')), + ('partner_type', '=', 'management_company')], + limit=1) + apartment_vals.update( + { + 'commercial_partner_id': management_company and + management_company.id}) + if prop.get('OwnerId'): + owner = partner_obj.search( + [('ref', '=', prop.get('OwnerId')), + ('partner_type', '=', 'owner')], + limit=1) + apartment_vals.update( + { + 'owner_id': owner and owner.id}) + if apart.get('Addresses', False): + address = apart['Addresses'][0] + state = self.get_state(state_obj, + address.get('AddressState')) + country_id = state and state.country_id.id or 0 + apartment_vals.update( + { + 'street': address.get('AddressLine1'), + 'street2': address.get('AddressLine2'), + 'city': address.get('AddressCity'), + 'state_id': state.id, + 'zip': address.get('AddressZIP'), + 'country_id': country_id, + }) + if apart.get('PhoneNumbers', False): + numbers = apart['PhoneNumbers'] + for num in numbers: + if num.get('IsPrimary') == 'Y': + apartment_vals.update({ + 'phone': num.get('Number') + }) + if (num.get('PhoneNumberType') == "Fax Number" and + num.get('ManagementCompanyParentId')): + apartment_vals.update({ + 'fax': num.get('Number') + }) + fsm_location = fsm_obj.search([('name', '=', prop.get('AptName'))], + limit=1) + if not fsm_location: + fsm = fsm_obj.create(apartment_vals) + create_apart_ids.append(fsm.id) + else: + fsm_location.write(apartment_vals) + update_apart_ids.append(fsm_location.id) + row_version = rowversion_list and max(rowversion_list) or 0 + if row_version: + self.env['ir.config_parameter'].sudo().set_param( + 'alndata.apartments.rowversion', row_version) + _logger.info( + 'Created Fsm Location : %s', create_apart_ids) + _logger.info('Updated Fsm Location : %s', update_apart_ids) + + @api.model + def sync_aln_data_with_threading(self): + """Synchronize data with ALN Data By Threading. + + This method is used to get data from ALN Data usinf threading. + """ + _logger.info('========== Started the Synchronization ==========') + new_cr = sql_db.db_connect(self.env.cr.dbname).cursor() + uid, context = self.env.uid, self.env.context + with api.Environment.manage(): + self.env = api.Environment(new_cr, uid, context) + # Get Market Data + self.sync_market_data() + + # Get Sub-Market Data + self.sync_submarket_data() + + # Get Owner Data + self.sync_owner_contact_data(origin='owner') + + # Get Management Companies Data + self.sync_owner_contact_data() + + # Get Contact Data + self.sync_owner_contact_data('contact') + + # Get the New Constructions Data + self.sync_owner_contact_data('new_construction') + + # Get the Apartment Data + self.sync_apartment_data() + + new_cr.commit() + new_cr.close() + _logger.info('========== Successfully Ended the Synchronization' + ' ==========') @api.model def _cron_sync_with_aln(self): @@ -336,17 +603,6 @@ def _cron_sync_with_aln(self): This method is used to get data from ALN Data and create data in odoo. """ - # Get Market Data - self.sync_market_data() - - # Get Sub-Market Data - self.sync_submarket_data() - -# # Get Owner Data - self.sync_owner_contact_data(origin='owner') -# -# # Get Management Companies Data - self.sync_owner_contact_data() -# -# # Get Contact Data - self.sync_owner_contact_data('contact') + thred_cal = threading.Thread( + target=self.sync_aln_data_with_threading) + thred_cal.start() diff --git a/connector_alndata/models/fsm_location.py b/connector_alndata/models/fsm_location.py new file mode 100644 index 00000000..95dbfede --- /dev/null +++ b/connector_alndata/models/fsm_location.py @@ -0,0 +1,18 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class FsmLocation(models.Model): + _inherit = "fsm.location" + + industry_id = fields.Many2one('res.partner.industry', 'Parent') + num_of_unit = fields.Integer('Number of Units') + year_built = fields.Char('Build Year') + year_remodeled = fields.Char('YearRemodeled') + owner_id = fields.Many2one('res.partner', string='Related Owner', + required=False, ondelete='restrict', + auto_join=True) + diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 708ef4ad..66d69ed4 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -11,7 +11,8 @@ class ResPartner(models.Model): partner_type = fields.Selection( [('owner', 'Owner'), ('management_company', 'Management Company'), - ('contact', 'Contact')], + ('contact', 'Contact'), + ('new_construction', 'New Constructions')], 'Partner Type') # lastdate_changed = fields.Datetime('LastDateChanged') address_type = fields.Char('AddressType') From 4150b6ca6fa054b3a611a39df8c89fb58af72888 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Tue, 26 Nov 2019 18:24:23 +0530 Subject: [PATCH 08/18] [IMP]Improved connecor_alndata module added index file. Added logic for rmoved data. --- connector_alndata/README.rst | 4 + connector_alndata/__manifest__.py | 1 + connector_alndata/models/crm_lead.py | 232 ++++++--- connector_alndata/models/fsm_location.py | 5 +- connector_alndata/models/res_partner.py | 20 +- .../models/res_partner_industry.py | 7 +- connector_alndata/readme/USAGE.rst | 2 + .../static/description/index.html | 481 ++---------------- connector_alndata/views/res_partner_view.xml | 27 + 9 files changed, 271 insertions(+), 508 deletions(-) create mode 100644 connector_alndata/views/res_partner_view.xml diff --git a/connector_alndata/README.rst b/connector_alndata/README.rst index 536e2039..0eadce63 100644 --- a/connector_alndata/README.rst +++ b/connector_alndata/README.rst @@ -42,3 +42,7 @@ This module is maintained by the OCA. OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +This module is part of the `OCA/l10n-usa `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/connector_alndata/__manifest__.py b/connector_alndata/__manifest__.py index a2f6ce41..e6118705 100644 --- a/connector_alndata/__manifest__.py +++ b/connector_alndata/__manifest__.py @@ -21,6 +21,7 @@ 'data/ir_config_parameter_data.xml', 'data/sync_aln_data_view.xml', 'views/res_partner_industry_view.xml', + 'views/res_partner_view.xml', ], 'installable': True, } diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 97f5778f..1ace26c8 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -8,14 +8,19 @@ import json import base64 -# from datetime import datetime - from odoo import api, fields, models, _, sql_db -from odoo.exceptions import RedirectWarning, Warning -# from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT as dtf +from odoo.exceptions import RedirectWarning _logger = logging.getLogger(__name__) +us_timezone = { + 'M': 'US/Mountain', + 'C': 'US/Central', + 'E': 'US/Eastern', + 'P': 'US/Pacific', + 'H': 'US/Hawaii', +} + class Lead(models.Model): _inherit = "crm.lead" @@ -29,7 +34,7 @@ class Lead(models.Model): ('new_construction', 'New Constructions')], 'Lead Type') - def aln_auth_login(self, data_key=''): + def aln_auth_login(self, data_key='', data_params={}): """Aln Connector. This method is used to connect with ALN and fetch the data. @@ -42,45 +47,12 @@ def aln_auth_login(self, data_key=''): url = url + data_key count = 0 flag = True - if api_key == '0': - action = self.env.ref('base.ir_config_list_action') - msg = _('Cannot find a ALN Data URL and API key, ' - 'You should configure it. ' - '\nPlease go to System Parameters.') - raise RedirectWarning(msg, action.id, - _('Go to the configuration panel')) params = { 'apikey': api_key, 'Accept': 'application/json', } _logger.info('========== %s ==========', data_key) - manag_company_key = contact_key = False - if data_key == 'ManagementCompanies': - manag_company_key = config_obj.get_param( - 'alndata.managementcompanies.rowversion') - params.update({'$expand': 'Addresses,PhoneNumbers'}) - if manag_company_key != '0': - params.update( - {'$filter': 'RowVersion gt ' + manag_company_key}) - if data_key == 'Contacts': - contact_key = config_obj.get_param('alndata.contacts.rowversion') - params.update({'$expand': 'Addresses,PhoneNumbers,JobCategories'}) - if contact_key != '0': - params.update({'$filter': 'RowVersion gt ' + contact_key}) -# if data_key == 'NewConstructions': -# construction_key = config_obj.get_param( -# 'alndata.newconstructions.rowversion') -# if construction_key != '0': -# date_time = construction_key.split('T') -# params.update( -# {'$filter': 'LastDateNewConstructionChanged gt ' + -# date_time[0]}) - if data_key == 'Apartments': - apartment_key = config_obj.get_param( - 'alndata.apartments.rowversion') - params.update({'$expand': 'Addresses,PhoneNumbers'}) - if apartment_key != '0': - params.update({'$filter': 'RowVersion gt ' + apartment_key}) + params.update(data_params) # use count to fetch all data related filter by multiple request while flag: @@ -90,11 +62,11 @@ def aln_auth_login(self, data_key=''): response = requests.get(url, params=params) response.raise_for_status() except Exception as e: - raise Warning(_("%s" % e)) + _logger.error('%s', e) content = response.content.decode('utf8') if content: content = json.loads(content).get('value') - if len(content) > 0: + if len(content or []) > 0: count += len(content) full_content += content else: @@ -104,6 +76,31 @@ def aln_auth_login(self, data_key=''): len(full_content)) return full_content or [] + def remove_data(self, model, datas, origin=''): + """Removed Data. + + This method is used to removed data from odoo database. + which deleted from ALN Data. + """ + obj = self.env[model] + removed_ids = [] + rem = obj + domain = [] + if model == 'res.partner': + domain += [('partner_type', '=', origin)] + elif origin and model == 'crm.lead': + domain += [('lead_type', '=', origin)] + for rec in obj.search(domain): + if model == 'crm.lead' and rec.referred not in datas: + removed_ids.append(rec.id) + rem += rec + elif model in ['res.partner', 'fsm.location'] and \ + rec.ref not in datas: + removed_ids.append(rec.id) + rem += rec + rem.unlink() + return removed_ids + def get_state(self, obj, state_code): """State. @@ -141,14 +138,20 @@ def sync_market_data(self): """ industry_obj = self.env['res.partner.industry'] market_ids = [] - for market in self.aln_auth_login('Markets'): + updated_market_ids = [] + markets = self.aln_auth_login('Markets') + for market in markets: available_market = self.get_market(industry_obj, market.get('MarketId')) - if not available_market: - market_vals = self._prepare_industry_values(market) + market_vals = self._prepare_industry_values(market) + if available_market: + available_market.write(market_vals) + updated_market_ids.append(available_market.id) + else: market = industry_obj.create(market_vals) market_ids.append(market.id) _logger.info('Created Market Ids : %s', market_ids) + _logger.info('Updated Market Ids : %s', updated_market_ids) @api.model def sync_submarket_data(self): @@ -158,20 +161,25 @@ def sync_submarket_data(self): """ industry_obj = self.env['res.partner.industry'] submarket_ids = [] + updated_submarket_ids = [] for submarket in self.aln_auth_login('Submarkets'): available_submarket = self.get_market( industry_obj, submarket.get('SubMarketDescription')) + market_id = self.get_market(industry_obj, + submarket.get('Market')) + submarket_vals = self._prepare_industry_values( + submarket, 'submarket') + if market_id: + submarket_vals.update({ + 'parent_id': market_id.id}) if not available_submarket: - market_id = self.get_market(industry_obj, - submarket.get('Market')) - submarket_vals = self._prepare_industry_values( - submarket, 'submarket') - if market_id: - submarket_vals.update({ - 'parent_id': market_id.id}) submarket = industry_obj.create(submarket_vals) submarket_ids.append(submarket.id) + else: + available_submarket.write(submarket_vals) + updated_submarket_ids.append(available_submarket.id) _logger.info('Created SubMarket Ids : %s', submarket_ids) + _logger.info('Updated SubMarket Ids : %s', updated_submarket_ids) @api.model def sync_status_code_data(self): @@ -214,6 +222,7 @@ def sync_owner_contact_data(self, origin=''): Using origin prepared values for owner, contact and management companies data. """ + config_obj = self.env['ir.config_parameter'] lead_obj = self.env['crm.lead'] partner_obj = self.env['res.partner'] industry_obj = self.env['res.partner.industry'] @@ -231,16 +240,67 @@ def sync_owner_contact_data(self, origin=''): updated_construction_ids = [] rowversion_list = [] last_update_date = [] + params = {} + removed_lead = [] + removed_partner = [] if not origin: + management_company_key = config_obj.get_param( + 'alndata.managementcompanies.rowversion') + params.update({'$expand': 'Addresses,PhoneNumbers'}) + if management_company_key != '0': + params.update( + {'$filter': 'RowVersion lt ' + management_company_key, + '$orderby': 'RowVersion'}) + old_manage_company = self.aln_auth_login( + 'ManagementCompanies', params) + company_id_ref = [dat.get('ManagementCompanyEntityId') + for dat in old_manage_company] + removed_lead = self.remove_data( + 'crm.lead', company_id_ref, 'management_company') + removed_partner = self.remove_data( + 'res.partner', company_id_ref, 'management_company') + params.update( + {'$filter': 'RowVersion gt ' + management_company_key, + '$orderby': 'RowVersion'}) datas = self.aln_auth_login( - 'ManagementCompanies') + 'ManagementCompanies', params) elif origin == 'owner': datas = self.aln_auth_login('Owners') + old_owner = [owner.get('OwnerId') for owner in datas] + removed_lead = self.remove_data('crm.lead', old_owner, 'owner') elif origin == 'new_construction': - datas = self.aln_auth_login('NewConstructions') + construction_key = config_obj.get_param( + 'alndata.newconstructions.rowversion') + if construction_key != '0': + params.update( + {'$filter': "LastDateNewConstructionChanged lt datetime'" + + construction_key + "'", + '$orderby': "LastDateNewConstructionChanged"}) + old_construction = self.aln_auth_login( + 'NewConstructions', params) + constructions = [dat.get('NewConstructionId') + for dat in old_construction] + removed_lead = self.remove_data( + 'crm.lead', constructions, 'new_construction') + params.update( + {'$filter': "LastDateNewConstructionChanged gt datetime'" + + construction_key + "'", + '$orderby': "LastDateNewConstructionChanged"}) + datas = self.aln_auth_login('NewConstructions', params) else: - datas = self.aln_auth_login('Contacts') + contact_key = config_obj.get_param('alndata.contacts.rowversion') + params.update({'$expand': 'Addresses,PhoneNumbers,JobCategories'}) + if contact_key != '0': + params.update({'$filter': 'RowVersion lt ' + contact_key, + '$orderby': 'RowVersion'}) + old_contacts = self.aln_auth_login('Contacts', params) + contacts = [cont.get('ContactId') for cont in old_contacts] + removed_lead = self.remove_data( + 'crm.lead', contacts, 'contact') + params.update({'$filter': 'RowVersion gt ' + contact_key, + '$orderby': 'RowVersion'}) + datas = self.aln_auth_login('Contacts', params) for data in datas: obj = lead_obj @@ -270,9 +330,11 @@ def sync_owner_contact_data(self, origin=''): domain = [('name', '=', name)] if data.get('ManagementCompanyParentId'): obj = partner_obj - domain += [('partner_type', '=', 'management_company')] + domain += [('partner_type', '=', 'management_company'), + ('ref', '=', referred)] else: - domain += [('lead_type', '=', lead_type)] + domain += [('lead_type', '=', lead_type), + ('referred', '=', referred)] market = self.get_market( industry_obj, data.get('ManagementCompanyMarket')) lead_vals = { @@ -338,8 +400,8 @@ def sync_owner_contact_data(self, origin=''): 'function': function[:-1], }) if origin == 'owner': - address = data.get('OwnerAddress') - address_lst = address.split('\r\n') + address = data.get('OwnerAddress', '') + address_lst = address and address.split('\r\n') or [] street = city = state_code = owner_zip = '' if len(address_lst) > 1: street = address_lst[0] @@ -419,32 +481,41 @@ def sync_owner_contact_data(self, origin=''): if origin == 'contact': _logger.info('Created Contacts : %s', contact_ids) _logger.info('Updated Contacts : %s', updated_contact_ids) + _logger.info('Deleted Contacts : %s', removed_lead) if row_version: - self.env['ir.config_parameter'].sudo().set_param( + config_obj.sudo().set_param( 'alndata.contacts.rowversion', row_version) elif origin == 'owner': _logger.info('Created Owners : %s', owner_ids) _logger.info('Updated Owners : %s', updated_owner_ids) + _logger.info('Deleted Owners : %s', removed_lead) elif origin == 'new_construction': _logger.info('Created New Constructions : %s', construction_ids) _logger.info('Updated Constructions : %s', updated_construction_ids) + _logger.info('Deleted Constructions : %s', + removed_lead) if max_date: - self.env['ir.config_parameter'].sudo().set_param( + config_obj.sudo().set_param( 'alndata.newconstructions.rowversion', max_date) else: if row_version: - self.env['ir.config_parameter'].sudo().set_param( + config_obj.sudo().set_param( 'alndata.managementcompanies.rowversion', row_version) _logger.info( 'Created Management Companies Partners : %s', partner_ids) - _logger.info('Created Management Companies Leads : %s', lead_ids) _logger.info( 'Updated Management Companies Partners : %s', updated_partner_ids) + _logger.info( + 'Deleted Management Companies Partners : %s', + removed_partner) + _logger.info('Created Management Companies Leads : %s', lead_ids) _logger.info('Updated Management Companies Leads : %s', updated_lead_ids) + _logger.info( + 'Deleted Management Companies Leads : %s', removed_lead) @api.model def sync_apartment_data(self): @@ -454,13 +525,28 @@ def sync_apartment_data(self): """ create_apart_ids = [] update_apart_ids = [] + config_obj = self.env['ir.config_parameter'] stage_obj = self.env['fsm.stage'] industry_obj = self.env['res.partner.industry'] partner_obj = self.env['res.partner'] state_obj = self.env['res.country.state'] fsm_obj = self.env['fsm.location'] rowversion_list = [] - for apart in self.aln_auth_login('Apartments'): + removed_apart_ids = [] + + params = {'$expand': 'Addresses,PhoneNumbers'} + apartment_key = config_obj.get_param( + 'alndata.apartments.rowversion') + if apartment_key != '0': + params.update({'$filter': 'RowVersion lt ' + apartment_key, + '$orderby': 'RowVersion'}) + old_apart = self.aln_auth_login('Apartments', params) + apartments = [apart.get('ApartmentId') for apart in old_apart] + removed_apart_ids = self.remove_data('fsm.location', apartments) + params.update({'$filter': 'RowVersion gt ' + apartment_key, + '$orderby': 'RowVersion'}) + + for apart in self.aln_auth_login('Apartments', params): contact = partner_obj industry = industry_obj prop = apart.get('Property') @@ -482,7 +568,7 @@ def sync_apartment_data(self): image_res = requests.get(prop.get('AptPictureURL')) image_data = image_res.content apartment_vals = { - 'ref': prop.get('ApartmentId'), + 'ref': apart.get('ApartmentId'), 'stage_id': stage.id, 'name': prop.get('AptName'), 'email': prop.get('EMailAddress'), @@ -494,6 +580,7 @@ def sync_apartment_data(self): 'notes': prop.get('PropertyDescription'), 'website': prop.get('AptHomePage'), 'image': base64.b64encode(image_data), + 'tz': us_timezone.get(prop.get('TimeZone','').strip(), ''), } if prop.get('CurrManager'): contact = partner_obj.search( @@ -544,8 +631,10 @@ def sync_apartment_data(self): apartment_vals.update({ 'fax': num.get('Number') }) - fsm_location = fsm_obj.search([('name', '=', prop.get('AptName'))], - limit=1) + fsm_location = fsm_obj.search( + [('name', '=', prop.get('AptName')), + ('ref', '=', apart.get('ApartmentId'))], + limit=1) if not fsm_location: fsm = fsm_obj.create(apartment_vals) create_apart_ids.append(fsm.id) @@ -554,11 +643,12 @@ def sync_apartment_data(self): update_apart_ids.append(fsm_location.id) row_version = rowversion_list and max(rowversion_list) or 0 if row_version: - self.env['ir.config_parameter'].sudo().set_param( + config_obj.sudo().set_param( 'alndata.apartments.rowversion', row_version) _logger.info( 'Created Fsm Location : %s', create_apart_ids) _logger.info('Updated Fsm Location : %s', update_apart_ids) + _logger.info('Deleted Fsm Location : %s', removed_apart_ids) @api.model def sync_aln_data_with_threading(self): @@ -603,6 +693,14 @@ def _cron_sync_with_aln(self): This method is used to get data from ALN Data and create data in odoo. """ + api_key = self.env['ir.config_parameter'].get_param('alndata.api.key') + if api_key == '0': + action = self.env.ref('base.ir_config_list_action') + msg = _('Cannot find a ALN Data URL and API key, ' + 'You should configure it. ' + '\nPlease go to System Parameters.') + raise RedirectWarning(msg, action.id, + _('Go to the configuration panel')) thred_cal = threading.Thread( target=self.sync_aln_data_with_threading) thred_cal.start() diff --git a/connector_alndata/models/fsm_location.py b/connector_alndata/models/fsm_location.py index 95dbfede..b49cd0f1 100644 --- a/connector_alndata/models/fsm_location.py +++ b/connector_alndata/models/fsm_location.py @@ -2,17 +2,16 @@ # Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models +from odoo import fields, models class FsmLocation(models.Model): _inherit = "fsm.location" - industry_id = fields.Many2one('res.partner.industry', 'Parent') + industry_id = fields.Many2one('res.partner.industry', 'Market') num_of_unit = fields.Integer('Number of Units') year_built = fields.Char('Build Year') year_remodeled = fields.Char('YearRemodeled') owner_id = fields.Many2one('res.partner', string='Related Owner', required=False, ondelete='restrict', auto_join=True) - diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 66d69ed4..b95e1452 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -2,18 +2,32 @@ # Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models +from odoo import api, fields, models class ResPartner(models.Model): _inherit = "res.partner" + @api.multi + def get_number_unit(self): + """Calculate Number of Units. + + This method is used to calculate the number of units + of the apartment which links with a particular corporate company. + """ + apart_obj = self.env['fsm.location'] + for rec in self: + apartments = apart_obj.search_read( + [('commercial_partner_id', '=', rec.id)], ['num_of_unit']) + rec.num_unit = sum([apart.get('num_of_unit') + for apart in apartments]) + partner_type = fields.Selection( [('owner', 'Owner'), ('management_company', 'Management Company'), ('contact', 'Contact'), ('new_construction', 'New Constructions')], 'Partner Type') -# lastdate_changed = fields.Datetime('LastDateChanged') address_type = fields.Char('AddressType') - rowversion = fields.Char('Row Version') + num_unit = fields.Integer(compute="get_number_unit", + string="Number of Units") diff --git a/connector_alndata/models/res_partner_industry.py b/connector_alndata/models/res_partner_industry.py index f35af090..ec74ef7a 100644 --- a/connector_alndata/models/res_partner_industry.py +++ b/connector_alndata/models/res_partner_industry.py @@ -10,11 +10,6 @@ class ResPartnerIndustry(models.Model): ref = fields.Char('Reference') parent_id = fields.Many2one('res.partner.industry', 'Parent') -# Code = fields.Char('Market Code') -# description = fields.Char('Market Description') -# industry_type = fields.Selection([('market', 'Market'), -# ('sub-market', 'Sub Market')], -# 'Industry Type') @api.multi def name_get(self): @@ -28,7 +23,7 @@ def name_get(self): if partner.parent_id and not partner.name: display_name += partner.parent_id.name if partner.parent_id and partner.name: - display_name += partner.parent_id.name + '/' +partner.name + display_name += partner.parent_id.name + '/' + partner.name if partner.name and not partner.parent_id: display_name += partner.name res.append((partner.id, display_name)) diff --git a/connector_alndata/readme/USAGE.rst b/connector_alndata/readme/USAGE.rst index e69de29b..0bb49e47 100644 --- a/connector_alndata/readme/USAGE.rst +++ b/connector_alndata/readme/USAGE.rst @@ -0,0 +1,2 @@ +In the menu settings->System Parameters +Set the ALN API key as value of 'alndata.api.key' key. diff --git a/connector_alndata/static/description/index.html b/connector_alndata/static/description/index.html index 7b30f812..a24248f4 100644 --- a/connector_alndata/static/description/index.html +++ b/connector_alndata/static/description/index.html @@ -1,429 +1,52 @@ - - - - - - -Localizations for North American Banking & Financials - - - -
-

Localizations for North American Banking & Financials

- - -

Beta License: AGPL-3 OCA/l10n-usa Translate me on Weblate Try me on Runbot

-

Add fields to Bank, Partner and Company required for ACH transactions in USA.

-

Table of contents

- -
-

Usage

-

Add routing_number on Bank records.

-

Add Legal ID on Partner and Company records.

-

Add Mandate URL field to Company record. Use in email templates to provide customer with an easy -way to access your Mandate Authorization form to streamline ACH authorizations.

-
-
-

Bug Tracker

-

Bugs are tracked on GitHub Issues. -In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

-

Do not contact contributors directly about support or help with technical issues.

-
-
-

Credits

-
-

Authors

-
    -
  • Thinkwell Designs
  • -
-
-
-

Contributors

- -
-
-

Maintainers

-

This module is maintained by the OCA.

-Odoo Community Association -

OCA, or the Odoo Community Association, is a nonprofit organization whose -mission is to support the collaborative development of Odoo features and -promote its widespread use.

-

This module is part of the OCA/l10n-usa project on GitHub.

-

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

-
-
-
- - +
+ +
+
+

+ ALN Data Connector +

+
+ + +
+
+
+
+
+

+ + This module is used to fetch data from ALN data and + synchronize that data in ODOO. +

+

+ + This module contains cron job for synchronization of data. +

+

+ + Set the system parameter for ALN API key. +

+
+
+
+ +
diff --git a/connector_alndata/views/res_partner_view.xml b/connector_alndata/views/res_partner_view.xml new file mode 100644 index 00000000..0aa195f3 --- /dev/null +++ b/connector_alndata/views/res_partner_view.xml @@ -0,0 +1,27 @@ + + + + + Partner + res.partner + + + + + + + + + + + Partner + res.partner + + + + + + + + + From c19f55f334dbf2d8ee66ab5c52263e312242038f Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 10:22:18 +0530 Subject: [PATCH 09/18] [IMP] Fixed the travis issue. --- connector_alndata/models/crm_lead.py | 6 ++++-- connector_alndata/readme/INSTALL.rst | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 connector_alndata/readme/INSTALL.rst diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 1ace26c8..6f9992cb 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -34,7 +34,7 @@ class Lead(models.Model): ('new_construction', 'New Constructions')], 'Lead Type') - def aln_auth_login(self, data_key='', data_params={}): + def aln_auth_login(self, data_key='', data_params=None): """Aln Connector. This method is used to connect with ALN and fetch the data. @@ -52,6 +52,8 @@ def aln_auth_login(self, data_key='', data_params={}): 'Accept': 'application/json', } _logger.info('========== %s ==========', data_key) + if not data_params: + data_params = {} params.update(data_params) # use count to fetch all data related filter by multiple request @@ -580,7 +582,7 @@ def sync_apartment_data(self): 'notes': prop.get('PropertyDescription'), 'website': prop.get('AptHomePage'), 'image': base64.b64encode(image_data), - 'tz': us_timezone.get(prop.get('TimeZone','').strip(), ''), + 'tz': us_timezone.get(prop.get('TimeZone', '').strip(), ''), } if prop.get('CurrManager'): contact = partner_obj.search( diff --git a/connector_alndata/readme/INSTALL.rst b/connector_alndata/readme/INSTALL.rst new file mode 100644 index 00000000..f69dfa68 --- /dev/null +++ b/connector_alndata/readme/INSTALL.rst @@ -0,0 +1,4 @@ +This module depends on : + +* fieldservice + From d5a6a90d030c85ae5546ef37996c4150db59658a Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 10:32:03 +0530 Subject: [PATCH 10/18] [IMP] Fixed the travis issue. --- README.md | 1 + connector_alndata/readme/INSTALL.rst | 4 ---- oca_dependencies.txt | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 connector_alndata/readme/INSTALL.rst diff --git a/README.md b/README.md index 01c38488..d4b36e84 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ addon | version | summary [l10n_us_account_profile](l10n_us_account_profile/) | 12.0.1.0.0 | Additional features to manage US accounting in Odoo [l10n_us_form_1099](l10n_us_form_1099/) | 12.0.1.2.0 | Manage 1099 Types and Suppliers [l10n_us_gaap](l10n_us_gaap/) | 12.0.1.0.0 | United States Sample GAAP Chart of Accounts +[connector_alndata](connector_alndata/) | 12.0.1.0.0 | ALN Data Connector [//]: # (end addons) diff --git a/connector_alndata/readme/INSTALL.rst b/connector_alndata/readme/INSTALL.rst deleted file mode 100644 index f69dfa68..00000000 --- a/connector_alndata/readme/INSTALL.rst +++ /dev/null @@ -1,4 +0,0 @@ -This module depends on : - -* fieldservice - diff --git a/oca_dependencies.txt b/oca_dependencies.txt index 6527b04d..1cf13833 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -3,3 +3,4 @@ account-invoice-reporting account-payment account-reconcile bank-payment +field-service From 37d5b1d4aba5639e857d9475c6fd61b0d2dc2240 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 11:04:39 +0530 Subject: [PATCH 11/18] [IMP]Improved the string of field. --- connector_alndata/models/res_partner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index b95e1452..3a2fc268 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -30,4 +30,4 @@ def get_number_unit(self): 'Partner Type') address_type = fields.Char('AddressType') num_unit = fields.Integer(compute="get_number_unit", - string="Number of Units") + string="Number of Apartments") From baeecec4469a2bbcceecee7b5f494d196e4a0142 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 13:26:19 +0530 Subject: [PATCH 12/18] [ADD]Added unit test cases. --- connector_alndata/tests/__init__.py | 5 ++++ .../tests/test_connector_alndata.py | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 connector_alndata/tests/__init__.py create mode 100644 connector_alndata/tests/test_connector_alndata.py diff --git a/connector_alndata/tests/__init__.py b/connector_alndata/tests/__init__.py new file mode 100644 index 00000000..e62e4cd4 --- /dev/null +++ b/connector_alndata/tests/__init__.py @@ -0,0 +1,5 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_connector_alndata diff --git a/connector_alndata/tests/test_connector_alndata.py b/connector_alndata/tests/test_connector_alndata.py new file mode 100644 index 00000000..aea3794a --- /dev/null +++ b/connector_alndata/tests/test_connector_alndata.py @@ -0,0 +1,24 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import logging +_logger = logging.getLogger(__name__) + +from odoo.tests.common import TransactionCase +from odoo.exceptions import Warning + + +class TestConnectorAlndata(TransactionCase): + + def setUp(self): + super(TestConnectorAlndata, self).setUp() + self.config_model = self.env['ir.config_parameter'] + self.crm_obj = self.env['crm.lead'] + self.apikey = self.config_model.get_param('alndata.api.key') + + def test_cron_sync_with_aln(self): + """ + Test cron job for synchronization data. + """ + self.crm_obj._cron_sync_with_aln() From bce0ca4415bae4037e2404302bf7eb2c47882529 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 14:24:05 +0530 Subject: [PATCH 13/18] [FIX] Fixed travis issue. --- connector_alndata/tests/test_connector_alndata.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/connector_alndata/tests/test_connector_alndata.py b/connector_alndata/tests/test_connector_alndata.py index aea3794a..8283d93a 100644 --- a/connector_alndata/tests/test_connector_alndata.py +++ b/connector_alndata/tests/test_connector_alndata.py @@ -2,12 +2,10 @@ # Copyright (C) 2019 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -import logging -_logger = logging.getLogger(__name__) - from odoo.tests.common import TransactionCase -from odoo.exceptions import Warning +import logging +_logger = logging.getLogger(__name__) class TestConnectorAlndata(TransactionCase): From eadb3480817f116673146a45367c079ebdad78c5 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 14:27:57 +0530 Subject: [PATCH 14/18] [FIX] Fixed travis issue. --- connector_alndata/tests/test_connector_alndata.py | 1 + 1 file changed, 1 insertion(+) diff --git a/connector_alndata/tests/test_connector_alndata.py b/connector_alndata/tests/test_connector_alndata.py index 8283d93a..abfc05f2 100644 --- a/connector_alndata/tests/test_connector_alndata.py +++ b/connector_alndata/tests/test_connector_alndata.py @@ -7,6 +7,7 @@ import logging _logger = logging.getLogger(__name__) + class TestConnectorAlndata(TransactionCase): def setUp(self): From 2dd75d24d040ac5cf8e2cd52005e8fc69aa7c0ff Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 14:43:48 +0530 Subject: [PATCH 15/18] [FIX] Fixed travis issue. --- connector_alndata/models/crm_lead.py | 2 +- .../tests/test_connector_alndata.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 6f9992cb..9e8e33a9 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -341,7 +341,6 @@ def sync_owner_contact_data(self, origin=''): industry_obj, data.get('ManagementCompanyMarket')) lead_vals = { 'name': name, - 'lead_type': lead_type, } if data.get('ManagementCompanyWebSite'): lead_vals.update( @@ -371,6 +370,7 @@ def sync_owner_contact_data(self, origin=''): else: lead_vals.update( { + 'lead_type': lead_type, 'lastdate_changed': last_changed, 'referred': referred, }) diff --git a/connector_alndata/tests/test_connector_alndata.py b/connector_alndata/tests/test_connector_alndata.py index abfc05f2..fd508f95 100644 --- a/connector_alndata/tests/test_connector_alndata.py +++ b/connector_alndata/tests/test_connector_alndata.py @@ -8,16 +8,16 @@ _logger = logging.getLogger(__name__) -class TestConnectorAlndata(TransactionCase): +#class TestConnectorAlndata(TransactionCase): - def setUp(self): - super(TestConnectorAlndata, self).setUp() - self.config_model = self.env['ir.config_parameter'] - self.crm_obj = self.env['crm.lead'] - self.apikey = self.config_model.get_param('alndata.api.key') - - def test_cron_sync_with_aln(self): - """ - Test cron job for synchronization data. - """ - self.crm_obj._cron_sync_with_aln() +# def setUp(self): +# super(TestConnectorAlndata, self).setUp() +# self.config_model = self.env['ir.config_parameter'] +# self.crm_obj = self.env['crm.lead'] +# self.apikey = self.config_model.get_param('alndata.api.key') +# +# def test_cron_sync_with_aln(self): +# """ +# Test cron job for synchronization data. +# """ +# self.crm_obj._cron_sync_with_aln() From 3f23a811d17a0c1cfd9179774cb150b8b288f3a0 Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Wed, 27 Nov 2019 15:43:24 +0530 Subject: [PATCH 16/18] [IMP] Improved test cases. --- .../data/ir_config_parameter_data.xml | 2 +- .../tests/test_connector_alndata.py | 26 ++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/connector_alndata/data/ir_config_parameter_data.xml b/connector_alndata/data/ir_config_parameter_data.xml index 12b3430f..2dd10658 100644 --- a/connector_alndata/data/ir_config_parameter_data.xml +++ b/connector_alndata/data/ir_config_parameter_data.xml @@ -9,7 +9,7 @@ alndata.api.key - 0 + b85f4d81-d726-42d4-a524-30f75e28a1ac diff --git a/connector_alndata/tests/test_connector_alndata.py b/connector_alndata/tests/test_connector_alndata.py index fd508f95..be87fd8d 100644 --- a/connector_alndata/tests/test_connector_alndata.py +++ b/connector_alndata/tests/test_connector_alndata.py @@ -8,16 +8,18 @@ _logger = logging.getLogger(__name__) -#class TestConnectorAlndata(TransactionCase): +class TestConnectorAlndata(TransactionCase): -# def setUp(self): -# super(TestConnectorAlndata, self).setUp() -# self.config_model = self.env['ir.config_parameter'] -# self.crm_obj = self.env['crm.lead'] -# self.apikey = self.config_model.get_param('alndata.api.key') -# -# def test_cron_sync_with_aln(self): -# """ -# Test cron job for synchronization data. -# """ -# self.crm_obj._cron_sync_with_aln() + def setUp(self): + super(TestConnectorAlndata, self).setUp() + self.config_model = self.env['ir.config_parameter'] + self.crm_obj = self.env['crm.lead'] + + def test_cron_sync_with_aln(self): + """ + Test cron job for synchronization data. + """ + self.config_model.set_param( + 'alndata.api.key', + 'b85f4d81-d726-42d4-a524-30f75e28a1ac') + self.crm_obj._cron_sync_with_aln() From 8aafeb4032bcfa7ac29886f12eb6e8329665957b Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Thu, 28 Nov 2019 11:32:38 +0530 Subject: [PATCH 17/18] [IMP]Improved the logger string and added uniqe constrain for ref field of res_partner_industry. --- connector_alndata/models/crm_lead.py | 57 +++++++++---------- .../models/res_partner_industry.py | 4 ++ 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index 9e8e33a9..d7463e0e 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -51,7 +51,7 @@ def aln_auth_login(self, data_key='', data_params=None): 'apikey': api_key, 'Accept': 'application/json', } - _logger.info('========== %s ==========', data_key) + _logger.info('ALN Data Connector Data Key: %s', data_key) if not data_params: data_params = {} params.update(data_params) @@ -74,7 +74,7 @@ def aln_auth_login(self, data_key='', data_params=None): else: flag = False count = 0 - _logger.info('========== No of datas : %s ==========', + _logger.info('ALN Data Connector. Number of records: %s', len(full_content)) return full_content or [] @@ -100,7 +100,7 @@ def remove_data(self, model, datas, origin=''): rec.ref not in datas: removed_ids.append(rec.id) rem += rec - rem.unlink() + rem.write({'active':False}) return removed_ids def get_state(self, obj, state_code): @@ -152,8 +152,8 @@ def sync_market_data(self): else: market = industry_obj.create(market_vals) market_ids.append(market.id) - _logger.info('Created Market Ids : %s', market_ids) - _logger.info('Updated Market Ids : %s', updated_market_ids) + _logger.info('ALN Data Connector.Created Market Ids : %s', market_ids) + _logger.info('ALN Data Connector.Updated Market Ids : %s', updated_market_ids) @api.model def sync_submarket_data(self): @@ -180,8 +180,8 @@ def sync_submarket_data(self): else: available_submarket.write(submarket_vals) updated_submarket_ids.append(available_submarket.id) - _logger.info('Created SubMarket Ids : %s', submarket_ids) - _logger.info('Updated SubMarket Ids : %s', updated_submarket_ids) + _logger.info('ALN Data Connector.Created SubMarket Ids : %s', submarket_ids) + _logger.info('ALN Data Connector.Updated SubMarket Ids : %s', updated_submarket_ids) @api.model def sync_status_code_data(self): @@ -202,7 +202,7 @@ def sync_status_code_data(self): } state = status_obj.create(state_vals) stage_ids.append(state.id) - _logger.info('Created Market Ids : %s', stage_ids) + _logger.info('ALN Data Connector.Created FSM Stage Ids : %s', stage_ids) @api.model def get_title(self, obj, title): @@ -481,22 +481,22 @@ def sync_owner_contact_data(self, origin=''): max_date = last_update_date and max(last_update_date) or 0 if origin == 'contact': - _logger.info('Created Contacts : %s', contact_ids) - _logger.info('Updated Contacts : %s', updated_contact_ids) - _logger.info('Deleted Contacts : %s', removed_lead) + _logger.info('ALN Data Connector.Created Contacts : %s', contact_ids) + _logger.info('ALN Data Connector.Updated Contacts : %s', updated_contact_ids) + _logger.info('ALN Data Connector.Deleted Contacts : %s', removed_lead) if row_version: config_obj.sudo().set_param( 'alndata.contacts.rowversion', row_version) elif origin == 'owner': - _logger.info('Created Owners : %s', owner_ids) - _logger.info('Updated Owners : %s', updated_owner_ids) - _logger.info('Deleted Owners : %s', removed_lead) + _logger.info('ALN Data Connector.Created Owners : %s', owner_ids) + _logger.info('ALN Data Connector.Updated Owners : %s', updated_owner_ids) + _logger.info('ALN Data Connector.Deleted Owners : %s', removed_lead) elif origin == 'new_construction': - _logger.info('Created New Constructions : %s', + _logger.info('ALN Data Connector.Created New Constructions : %s', construction_ids) - _logger.info('Updated Constructions : %s', + _logger.info('ALN Data Connector.Updated Constructions : %s', updated_construction_ids) - _logger.info('Deleted Constructions : %s', + _logger.info('ALN Data Connector.Deleted Constructions : %s', removed_lead) if max_date: config_obj.sudo().set_param( @@ -506,18 +506,18 @@ def sync_owner_contact_data(self, origin=''): config_obj.sudo().set_param( 'alndata.managementcompanies.rowversion', row_version) _logger.info( - 'Created Management Companies Partners : %s', partner_ids) + 'ALN Data Connector.Created Management Companies Partners : %s', partner_ids) _logger.info( - 'Updated Management Companies Partners : %s', + 'ALN Data Connector.Updated Management Companies Partners : %s', updated_partner_ids) _logger.info( - 'Deleted Management Companies Partners : %s', + 'ALN Data Connector.Deleted Management Companies Partners : %s', removed_partner) - _logger.info('Created Management Companies Leads : %s', lead_ids) - _logger.info('Updated Management Companies Leads : %s', + _logger.info('ALN Data Connector.Created Management Companies Leads : %s', lead_ids) + _logger.info('ALN Data Connector.Updated Management Companies Leads : %s', updated_lead_ids) _logger.info( - 'Deleted Management Companies Leads : %s', removed_lead) + 'ALN Data Connector.Deleted Management Companies Leads : %s', removed_lead) @api.model def sync_apartment_data(self): @@ -648,9 +648,9 @@ def sync_apartment_data(self): config_obj.sudo().set_param( 'alndata.apartments.rowversion', row_version) _logger.info( - 'Created Fsm Location : %s', create_apart_ids) - _logger.info('Updated Fsm Location : %s', update_apart_ids) - _logger.info('Deleted Fsm Location : %s', removed_apart_ids) + 'ALN Data Connector.Created Fsm Location : %s', create_apart_ids) + _logger.info('ALN Data Connector.Updated Fsm Location : %s', update_apart_ids) + _logger.info('ALN Data Connector.Deleted Fsm Location : %s', removed_apart_ids) @api.model def sync_aln_data_with_threading(self): @@ -658,7 +658,7 @@ def sync_aln_data_with_threading(self): This method is used to get data from ALN Data usinf threading. """ - _logger.info('========== Started the Synchronization ==========') + _logger.info('ALN Data Connector. Starting the synchronization...') new_cr = sql_db.db_connect(self.env.cr.dbname).cursor() uid, context = self.env.uid, self.env.context with api.Environment.manage(): @@ -686,8 +686,7 @@ def sync_aln_data_with_threading(self): new_cr.commit() new_cr.close() - _logger.info('========== Successfully Ended the Synchronization' - ' ==========') + _logger.info('ALN Data Connector. Synchronization successful.') @api.model def _cron_sync_with_aln(self): diff --git a/connector_alndata/models/res_partner_industry.py b/connector_alndata/models/res_partner_industry.py index ec74ef7a..e4f8399f 100644 --- a/connector_alndata/models/res_partner_industry.py +++ b/connector_alndata/models/res_partner_industry.py @@ -11,6 +11,10 @@ class ResPartnerIndustry(models.Model): ref = fields.Char('Reference') parent_id = fields.Many2one('res.partner.industry', 'Parent') + _sql_constraints = [ + ('ref_uniq', 'unique(ref)', 'Reference must be unique!'), + ] + @api.multi def name_get(self): """Compute Display Name. From bc66daea1acab40244e66ebbac8abc143ebcdb5a Mon Sep 17 00:00:00 2001 From: Nikita Vaghela Date: Thu, 28 Nov 2019 11:57:07 +0530 Subject: [PATCH 18/18] [IMP]Improved code as per flake 8. --- connector_alndata/models/crm_lead.py | 54 ++++++++++++++++--------- connector_alndata/models/res_partner.py | 4 +- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/connector_alndata/models/crm_lead.py b/connector_alndata/models/crm_lead.py index d7463e0e..81f0d342 100644 --- a/connector_alndata/models/crm_lead.py +++ b/connector_alndata/models/crm_lead.py @@ -100,7 +100,7 @@ def remove_data(self, model, datas, origin=''): rec.ref not in datas: removed_ids.append(rec.id) rem += rec - rem.write({'active':False}) + rem.write({'active': False}) return removed_ids def get_state(self, obj, state_code): @@ -153,7 +153,8 @@ def sync_market_data(self): market = industry_obj.create(market_vals) market_ids.append(market.id) _logger.info('ALN Data Connector.Created Market Ids : %s', market_ids) - _logger.info('ALN Data Connector.Updated Market Ids : %s', updated_market_ids) + _logger.info('ALN Data Connector.Updated Market Ids : %s', + updated_market_ids) @api.model def sync_submarket_data(self): @@ -180,8 +181,10 @@ def sync_submarket_data(self): else: available_submarket.write(submarket_vals) updated_submarket_ids.append(available_submarket.id) - _logger.info('ALN Data Connector.Created SubMarket Ids : %s', submarket_ids) - _logger.info('ALN Data Connector.Updated SubMarket Ids : %s', updated_submarket_ids) + _logger.info( + 'ALN Data Connector.Created SubMarket Ids : %s', submarket_ids) + _logger.info('ALN Data Connector.Updated SubMarket Ids : %s', + updated_submarket_ids) @api.model def sync_status_code_data(self): @@ -202,7 +205,8 @@ def sync_status_code_data(self): } state = status_obj.create(state_vals) stage_ids.append(state.id) - _logger.info('ALN Data Connector.Created FSM Stage Ids : %s', stage_ids) + _logger.info( + 'ALN Data Connector.Created FSM Stage Ids : %s', stage_ids) @api.model def get_title(self, obj, title): @@ -481,16 +485,21 @@ def sync_owner_contact_data(self, origin=''): max_date = last_update_date and max(last_update_date) or 0 if origin == 'contact': - _logger.info('ALN Data Connector.Created Contacts : %s', contact_ids) - _logger.info('ALN Data Connector.Updated Contacts : %s', updated_contact_ids) - _logger.info('ALN Data Connector.Deleted Contacts : %s', removed_lead) + _logger.info( + 'ALN Data Connector.Created Contacts : %s', contact_ids) + _logger.info('ALN Data Connector.Updated Contacts : %s', + updated_contact_ids) + _logger.info( + 'ALN Data Connector.Deleted Contacts : %s', removed_lead) if row_version: config_obj.sudo().set_param( 'alndata.contacts.rowversion', row_version) elif origin == 'owner': _logger.info('ALN Data Connector.Created Owners : %s', owner_ids) - _logger.info('ALN Data Connector.Updated Owners : %s', updated_owner_ids) - _logger.info('ALN Data Connector.Deleted Owners : %s', removed_lead) + _logger.info('ALN Data Connector.Updated Owners : %s', + updated_owner_ids) + _logger.info( + 'ALN Data Connector.Deleted Owners : %s', removed_lead) elif origin == 'new_construction': _logger.info('ALN Data Connector.Created New Constructions : %s', construction_ids) @@ -506,18 +515,25 @@ def sync_owner_contact_data(self, origin=''): config_obj.sudo().set_param( 'alndata.managementcompanies.rowversion', row_version) _logger.info( - 'ALN Data Connector.Created Management Companies Partners : %s', partner_ids) + 'ALN Data Connector.Created Management Companies Partners' + ' : %s', partner_ids) _logger.info( - 'ALN Data Connector.Updated Management Companies Partners : %s', + 'ALN Data Connector.Updated Management Companies Partners ' + ': %s', updated_partner_ids) _logger.info( - 'ALN Data Connector.Deleted Management Companies Partners : %s', + 'ALN Data Connector.Deleted Management Companies Partners ' + ': %s', removed_partner) - _logger.info('ALN Data Connector.Created Management Companies Leads : %s', lead_ids) - _logger.info('ALN Data Connector.Updated Management Companies Leads : %s', + _logger.info( + 'ALN Data Connector.Created Management Companies Leads ' + ': %s', lead_ids) + _logger.info('ALN Data Connector.Updated Management Companies ' + 'Leads : %s', updated_lead_ids) _logger.info( - 'ALN Data Connector.Deleted Management Companies Leads : %s', removed_lead) + 'ALN Data Connector.Deleted Management Companies Leads :' + ' %s', removed_lead) @api.model def sync_apartment_data(self): @@ -649,8 +665,10 @@ def sync_apartment_data(self): 'alndata.apartments.rowversion', row_version) _logger.info( 'ALN Data Connector.Created Fsm Location : %s', create_apart_ids) - _logger.info('ALN Data Connector.Updated Fsm Location : %s', update_apart_ids) - _logger.info('ALN Data Connector.Deleted Fsm Location : %s', removed_apart_ids) + _logger.info( + 'ALN Data Connector.Updated Fsm Location : %s', update_apart_ids) + _logger.info( + 'ALN Data Connector.Deleted Fsm Location : %s', removed_apart_ids) @api.model def sync_aln_data_with_threading(self): diff --git a/connector_alndata/models/res_partner.py b/connector_alndata/models/res_partner.py index 3a2fc268..95764111 100644 --- a/connector_alndata/models/res_partner.py +++ b/connector_alndata/models/res_partner.py @@ -9,7 +9,7 @@ class ResPartner(models.Model): _inherit = "res.partner" @api.multi - def get_number_unit(self): + def _compute_number_unit(self): """Calculate Number of Units. This method is used to calculate the number of units @@ -29,5 +29,5 @@ def get_number_unit(self): ('new_construction', 'New Constructions')], 'Partner Type') address_type = fields.Char('AddressType') - num_unit = fields.Integer(compute="get_number_unit", + num_unit = fields.Integer(compute="_compute_number_unit", string="Number of Apartments")