Guest User

Untitled

a guest
Mar 16th, 2018
1,511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.11 KB | None | 0 0
  1. import uuid
  2. import random
  3. import string
  4. import openerp.addons.decimal_precision as dp
  5. from openerp import models, api, fields
  6. from helpers import get_total_farmer_land_size, compute_forecast_data,\
  7. get_total_coop_land_size
  8. from passlib.context import CryptContext
  9.  
  10.  
  11. class VendorFarmer(models.Model):
  12. """ Non member farmer model """
  13. _name = 'vendor.farmer'
  14. _rec_name = 'name'
  15. _description = 'Vendor Farmer'
  16.  
  17. @api.multi
  18. @api.depends('vendor_land_ids')
  19. def get_total_land_plot_size(self):
  20. """
  21. Compute total land size for a given farmer
  22. """
  23. total = 0.0
  24. for a in self.vendor_land_ids:
  25. total += a.plot_size
  26. self.total_land_plot_size = total
  27. if total < 0.5:
  28. self.categ_total_land_plot_size = 'aless_0_5'
  29. elif total >= 0.5 and total < 1.0:
  30. self.categ_total_land_plot_size = 'bbtw_0_5_1'
  31. elif total >= 1.0:
  32. self.categ_total_land_plot_size = 'cmore_1'
  33.  
  34. name = fields.Char(string='Name', required=True)
  35. phone = fields.Char(string='Cell Phone', required=True)
  36. email = fields.Char(string='Email', required=True)
  37. address = fields.Char(string='Address')
  38. gender = fields.Selection([('male', 'Male'), ('female', 'Female')],
  39. string='Sex')
  40. # Demographics data
  41. head_of_household = fields.Boolean(string='Head of Household')
  42. num_household_members = fields.Integer(string='# of Household Members')
  43. spouse_firstname = fields.Char(string='Spouse First Name')
  44. spouse_lastname = fields.Char(string='Spouse Last Name')
  45. cellphone_alt = fields.Char(string='Cell phone (Alt)')
  46. cell_carrier = fields.Char(string='Cell Carrier')
  47. membership_id = fields.Char(string='Membership ID',
  48. default="%s" % (uuid.uuid4().int))
  49.  
  50. # Available Resources
  51. ar_tractors = fields.Boolean(string='Tractors')
  52. ar_harverster = fields.Boolean(string='Harvester')
  53. ar_dryer = fields.Boolean(string='Dryer')
  54. ar_thresher = fields.Boolean(string='Thresher')
  55. ar_safestorage = fields.Boolean(string='Safe storage')
  56. storage_details = fields.Char(string='Storage Details')
  57. ar_other = fields.Boolean(string='other')
  58. other_details = fields.Char(string='New resources')
  59.  
  60. # Main Water source
  61. mws_dam = fields.Boolean('Dam')
  62. mws_well = fields.Boolean('Well')
  63. mws_borehole = fields.Boolean('Borehole')
  64. mws_rs = fields.Boolean('River/Stream')
  65. mws_pb = fields.Boolean('Pipe-Borne')
  66. mws_irrigation = fields.Boolean('Irrigation')
  67. mws_none = fields.Boolean('None')
  68. mws_other = fields.Boolean('Other')
  69. other_water_source = fields.Char(string='Other Source')
  70.  
  71. total_land_plot_size = fields.Float(string='Total vendor land size of '
  72. + ' all maize arable plots in HA'
  73. + ' (rounded)',
  74. store=True,
  75. compute=get_total_land_plot_size)
  76. categ_total_land_plot_size = fields.Selection([('aless_0_5', '<0.5 ha'),
  77. ('bbtw_0_5_1', '0.5-1 ha'),
  78. ('cmore_1', '>1 ha')],
  79. 'Land Plot Size',
  80. store=True,
  81. compute=get_total_land_plot_size)
  82.  
  83. user_id = fields.Integer(string='User Id')
  84.  
  85. access_info_ids = fields.One2many('access.info.vendor',
  86. 'vendor_id',
  87. string='Access To Information')
  88. vendor_land_ids = fields.One2many('vendor.land',
  89. 'vendor_id',
  90. string='Vendor Land')
  91. forecast_vendor_ids = fields.One2many('forecast.vendor',
  92. 'vendor_id',
  93. string='Forecast Vendor')
  94. finance_data_ids = fields.One2many('finance.data.vendor',
  95. 'vendor_id',
  96. string='Finance Data Vendor')
  97. baseline_ids = fields.One2many('baseline.vendor',
  98. 'vendor_id',
  99. string='Baseline Vendor')
  100.  
  101. @api.model
  102. def create(self, vals):
  103. p_info = CryptContext(['pbkdf2_sha512']).encrypt('unwomen')
  104. partn_info = self.env['res.partner'] \
  105. .create({'name': vals['name'], 'email': vals['email']})
  106. # create and assign a user account to vendor with user id
  107. vendor_user = self.env['res.users'] \
  108. .create({'login': vals['phone'], 'password_crypt': p_info,
  109. 'alias_id': 1, 'company_id': 1,
  110. 'partner_id': partn_info.id})
  111.  
  112. # Add user id to vendor
  113. vals[u'user_id'] = vendor_user.id
  114. # Associate group to this account
  115. domain = [('name', 'like', 'Vendor')]
  116. group_info = self.env['res.groups'].search(domain)
  117. sql = "INSERT INTO res_groups_users_rel(gid, uid) VALUES({0}, {1})"
  118. sql = sql.format(group_info[1].id, vendor_user.id)
  119. self.env.cr.execute(sql)
  120. return super(VendorFarmer, self).create(vals)
  121.  
  122. @api.multi
  123. def send_credential(self):
  124. # get user id, set password (password_crypt) and send it via sms to
  125. user_gen_password = "".join(random.choice(string.ascii_uppercase
  126. + string.ascii_lowercase
  127. + string.digits)
  128. for x in range(10))
  129. pass_info = CryptContext(['pbkdf2_sha512']).encrypt(user_gen_password)
  130.  
  131. sql = "UPDATE res_users SET password_crypt = '{0}' WHERE id = {1}"
  132. sql = sql.format(pass_info, self.user_id)
  133. self.env.cr.execute(sql)
  134. # prepare sms
  135. msg = "Hi {0} this your credentials" \
  136. + " Login : {1}, password : {2}"
  137. msg = msg.format(self.name, self.phone, user_gen_password)
  138. tw_obj = self.env['twilio.message']
  139. tw_obj.send_sms(self.phone, msg)
  140.  
  141. sms_msg = 'Confirmation Message'
  142. return {
  143. 'name': sms_msg,
  144. 'type': 'ir.actions.act_window',
  145. 'res_model': 'web.modal',
  146. 'view_mode': 'form',
  147. 'view_type': 'form',
  148. 'target': 'new',
  149. }
  150.  
  151.  
  152. class AccessInfoVendor(models.Model):
  153.  
  154. """ Access Information Vendor """
  155.  
  156. _name = 'access.info.vendor'
  157. _description = 'Access to Information Vendor'
  158.  
  159. ar_aes = fields.Boolean(string='Agricultural extension services')
  160. ar_cri = fields.Boolean(string='Climate related information '
  161. + '(e.g. weather forecasts)')
  162. ar_seeds = fields.Boolean(string='Seeds')
  163. ar_of = fields.Boolean(string='Organic Fertilizers')
  164. ar_if = fields.Boolean(string='Inorganic Fertilizers')
  165. ar_labour = fields.Boolean(string='Labour')
  166. ar_iwp = fields.Boolean(string='Irrigation/water pumps')
  167. ar_ss = fields.Boolean(string='Spreaders or Sprayers')
  168. harvest_id = fields.Many2one('harvest.season', string='Harvest Season',
  169. required=True)
  170. vendor_id = fields.Many2one('vendor.farmer', string='Vendor',
  171. required=True)
  172.  
  173.  
  174. class VendorLand(models.Model):
  175.  
  176. """Vendor Land """
  177.  
  178. _name = 'vendor.land'
  179. _description = 'Vendor Land Data'
  180.  
  181. vendor_id = fields.Many2one('vendor.farmer', string='Vendor',
  182. required=True)
  183. plot_size = fields.Float(string='Plot Size (ha)',
  184. digits=dp.get_precision('Land Size'),
  185. required=True)
  186. lat = fields.Float(string='Latitude',
  187. digits=dp.get_precision('LatLng'))
  188. lng = fields.Float(string='Longitude',
  189. digits=dp.get_precision('LatLng'))
  190. harvest_id = fields.Many2one('harvest.season',
  191. string='Harvest Season',
  192. required=True)
  193.  
  194. @api.model
  195. def create(self, values):
  196. """
  197. Create new vendor land size
  198. """
  199. # Compute total land size of vendor x for a given season
  200. land_data = super(VendorLand, self).create(values)
  201. total_farmer_land_size = 0.0
  202. total_coop_land_size = 0.0
  203. land_size_farmer_query = """SELECT coalesce(sum(plot_size), 0.0) as total_land
  204. FROM farmer_land fl
  205. LEFT JOIN farmer f
  206. ON f.id = fl.vendor_id
  207. WHERE fl.vendor_id = %s AND fl.harvest_id = %s""" \
  208. % (values['vendor_id'], values['harvest_id'])
  209. self.env.cr.execute(land_size_farmer_query)
  210. res = self.env.cr.fetchone()
  211. if res:
  212. total_farmer_land_size = res[0]
  213.  
  214. # Compute appropriate variable base on the total size
  215. expected_production_in_mt = total_farmer_land_size * 2000
  216. forecasted_yield_mt = total_farmer_land_size * 2000 * 0.55
  217. forecasted_harvest_sale_value = total_farmer_land_size * 2000 * 0.10
  218.  
  219. # set farmer percentage land
  220. fpl = 0.0
  221. if total_coop_land_size != 0.0:
  222. fpl = (total_farmer_land_size / total_coop_land_size) * 100
  223. # (don't farget to update salesman_id to coop_id or vendor_id)
  224. lines = self.env['sale.order.contract.line'] \
  225. .search([('salesman_id', '=', values['vendor_id'])])
  226. current_ppp_commitment = 0.0
  227. for l in lines:
  228. current_ppp_commitment += l.product_uom_qty
  229.  
  230. farmer_contribution_ppp = (fpl / 100) * current_ppp_commitment * 2000
  231.  
  232. # Insert or Update on duplicate key
  233. update_farmer_data = """INSERT INTO forecast_vendor
  234. (expected_production_in_mt, forecasted_yield_mt,
  235. forecasted_harvest_sale_value, total_coop_land_size,
  236. farmer_percentage_land, current_ppp_commitment,
  237. farmer_contribution_ppp, farmer_id, harvest_id
  238. ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
  239. ON CONFLICT (harvest_id, farmer_id) DO UPDATE
  240. SET expected_production_in_mt = %s,
  241. forecasted_yield_mt = %s,
  242. forecasted_harvest_sale_value = %s,
  243. total_coop_land_size = %s,
  244. farmer_percentage_land = %s,
  245. current_ppp_commitment = %s,
  246. farmer_contribution_ppp = %s
  247. """ % (expected_production_in_mt, forecasted_yield_mt,
  248. forecasted_harvest_sale_value, total_coop_land_size,
  249. fpl, current_ppp_commitment, farmer_contribution_ppp,
  250. values['farmer_id'], values['harvest_id'],
  251. expected_production_in_mt, forecasted_yield_mt,
  252. forecasted_harvest_sale_value, total_coop_land_size,
  253. fpl, current_ppp_commitment, farmer_contribution_ppp)
  254.  
  255. # Execute query
  256. self.env.cr.execute(update_farmer_data)
  257. return land_data
  258.  
  259. @api.multi
  260. def write(self, values):
  261. """
  262. Update Vendor land size
  263. """
  264. # Compute old forecast data and expected yield
  265. # value base on the harvest id, farmer id and coop id
  266. tot_b_farmer_land_size = get_total_farmer_land_size(self)
  267. tot_b_coop_land_size = get_total_coop_land_size(self)
  268.  
  269. forecast_data_bef = compute_forecast_data(tot_b_farmer_land_size,
  270. tot_b_coop_land_size,
  271. self)
  272.  
  273. # update land information
  274. land_update_info = super(VendorLand, self).write(values)
  275.  
  276. # Compute new forecast data and expected yield
  277. # value base on the harvest id, farmer id and coop id
  278. tot_farmer_land_size = get_total_farmer_land_size(self)
  279. tot_coop_land_size = get_total_coop_land_size(self)
  280.  
  281. forecast_data_after = compute_forecast_data(tot_farmer_land_size,
  282. tot_coop_land_size,
  283. self)
  284.  
  285. # Deduct old forecast data and expected yield value
  286. deduct_old_val_query_forecast = """UPDATE forecast_vendor SET
  287. expected_production_in_mt =
  288. forecast_vendor.expected_production_in_mt - %s,
  289. forecasted_yield_mt =
  290. forecast_vendor.forecasted_yield_mt - %s,
  291. forecasted_harvest_sale_value =
  292. forecast_vendor.forecasted_harvest_sale_value - %s,
  293. total_coop_land_size =
  294. forecast_vendor.total_coop_land_size - %s,
  295. vendor_percentage_land =
  296. forecast_vendor.vendor_percentage_land - %s,
  297. current_ppp_commitment =
  298. forecast_vendor.current_ppp_commitment - %s,
  299. vendor_contribution_ppp =
  300. forecast_vendor.vendor_contribution_ppp - %s
  301. WHERE vendor_id = %s AND harvest_id = %s
  302. """ % (forecast_data_bef[0], forecast_data_bef[1],
  303. forecast_data_bef[2], tot_b_coop_land_size,
  304. forecast_data_bef[3], forecast_data_bef[4],
  305. forecast_data_bef[5], self.vendor_id.id, self.harvest_id.id)
  306. self.env.cr.execute(deduct_old_val_query_forecast)
  307.  
  308. # Add new forecast data and expected yield value
  309. add_new_val_query_forecast = """UPDATE forecast_vendor SET
  310. expected_production_in_mt =
  311. forecast_vendor.expected_production_in_mt + %s,
  312. forecasted_yield_mt =
  313. forecast_vendor.forecasted_yield_mt + %s,
  314. forecasted_harvest_sale_value =
  315. forecast_vendor.forecasted_harvest_sale_value + %s,
  316. total_coop_land_size =
  317. forecast_vendor.total_coop_land_size + %s,
  318. vendor_percentage_land =
  319. forecast_vendor.vendor_percentage_land + %s,
  320. current_ppp_commitment =
  321. forecast_vendor.current_ppp_commitment + %s,
  322. vendor_contribution_ppp =
  323. forecast_vendor.vendor_contribution_ppp + %s
  324. WHERE vendor_id = %s AND harvest_id = %s
  325. """ % (forecast_data_after[0], forecast_data_after[1],
  326. forecast_data_after[2], tot_coop_land_size,
  327. forecast_data_after[3], forecast_data_after[4],
  328. forecast_data_after[5], self.vendor_id.id, self.harvest_id.id)
  329. self.env.cr.execute(add_new_val_query_forecast)
  330.  
  331. return land_update_info
  332.  
  333. @api.multi
  334. def unlink(self):
  335. """
  336. Delete farmer land size
  337. """
  338. # Update farmer forecast data and expected yield for coop
  339. tot_farmer_land_size = get_total_farmer_land_size(self)
  340. tot_coop_land_size = get_total_coop_land_size(self)
  341.  
  342. forecast_data = compute_forecast_data(tot_farmer_land_size,
  343. tot_coop_land_size,
  344. self)
  345.  
  346. # Deduct old forecast data and expected yield value
  347. deduct_val_query_forecast = """UPDATE forecast_vendor SET
  348. expected_production_in_mt =
  349. forecast_vendor.expected_production_in_mt - %s,
  350. forecasted_yield_mt =
  351. forecast_vendor.forecasted_yield_mt - %s,
  352. forecasted_harvest_sale_value =
  353. forecast_vendor.forecasted_harvest_sale_value - %s,
  354. total_coop_land_size =
  355. forecast_vendor.total_coop_land_size - %s,
  356. vendor_percentage_land =
  357. forecast_vendor.vendor_percentage_land - %s,
  358. current_ppp_commitment =
  359. forecast_vendor.current_ppp_commitment - %s,
  360. vendor_contribution_ppp =
  361. forecast_vendor.vendor_contribution_ppp - %s
  362. WHERE vendor_id = %s AND harvest_id = %s
  363. """ % (forecast_data[0], forecast_data[1],
  364. forecast_data[2], tot_coop_land_size,
  365. forecast_data[3], forecast_data[4],
  366. forecast_data[5], self.vendor_id.id, self.harvest_id.id)
  367. self.env.cr.execute(deduct_val_query_forecast)
  368.  
  369. return super(VendorLand, self).unlink()
  370.  
  371.  
  372. class BaseLineVendor(models.Model):
  373.  
  374. """ BaseLine Vendor """
  375.  
  376. _name = 'baseline.vendor'
  377. _description = 'BaseLine Vendor'
  378.  
  379. seasona_harvest = fields.Float(string='Total production in KG')
  380. lost_harvest_total = fields.Float(string='Total Lost in KG')
  381. sold_harvest_total = fields.Float(string='Total Sold in KG')
  382. total_qty_coops = fields.Float(string='Total volume sold to your'
  383. + ' coop in KG')
  384. price_sold_coops = fields.Float(string='Price sold to the coop per KG')
  385. total_qty_middlemen = fields.Float(string='Total volume that was' +
  386. ' side-sold in KG')
  387. price_sold_middlemen = fields.Float(string='Price side-sold in KG')
  388. harvest_id = fields.Many2one('harvest.season', string='Harvest Season',
  389. required=True)
  390. vendor_id = fields.Many2one('vendor.farmer', string='Vendor',
  391. required=True)
  392.  
  393.  
  394. class ForecastVendor(models.Model):
  395.  
  396. """ Forecast Vendor """
  397.  
  398. _name = 'forecast.vendor'
  399. _description = 'Forecast Vendor'
  400. _sql_constraints = [('vendor_harv_season',
  401. 'unique(harvest_id, vendor_id)',
  402. 'Duplicate vendor id and harvest season')]
  403.  
  404. total_arable_land_plots = fields.Float(string='Total number of '
  405. + 'arable land plots'
  406. + ' for maize production',
  407. digits=(10, 0), default=0.0)
  408.  
  409. expected_production_in_mt = fields.Float(
  410. string='Expected Total Production in KG', readonly=True)
  411.  
  412. forecasted_yield_mt = fields.Float(
  413. string='Expected sales outside the FTMA', readonly=True)
  414. forecasted_harvest_sale_value = fields.Float(
  415. string='Expected postharvest loss in KG', readonly=True)
  416. total_coop_land_size = fields.Float(
  417. 'Total Coop Land Size (in HA)', readonly=True)
  418. vendor_percentage_land = fields.Float(string='Farmer % of total coop '
  419. + ' land size', readonly=True)
  420. current_ppp_commitment = fields.Integer(string='Current FTMA Commitment '
  421. + ' in kg', readonly=True)
  422. vendor_contribution_ppp = fields.Float(
  423. 'Farmer contribution towards FTMA commitment in KG', readonly=True)
  424. vendor_expected_min_ppp = fields.Float('Vendors expected minimum revenue'
  425. + ' from FTMA sale in RWF',
  426. default=7200,
  427. digits=(10, 0))
  428. minimum_flow_price = fields.Float("Minimum floor price per kg in RWF",
  429. default=215)
  430. harvest_id = fields.Many2one('harvest.season', string='Harvest Season',
  431. required=True)
  432. vendor_id = fields.Many2one('vendor.farmer', string='Vendor',
  433. required=True)
  434.  
  435.  
  436. class FinanceDataVendor(models.Model):
  437.  
  438. """ Finance Data Vendor """
  439.  
  440. _name = 'finance.data.vendor'
  441. _description = 'Finance Data Vendor'
  442.  
  443. outstanding_loan = fields.Boolean(string='Outstanding Loan')
  444. total_loan_amount = fields.Float(string='Total loan amount (in RWF)',
  445. group_operator="avg")
  446. total_outstanding = fields.Float(string='Total outstanding (in RWF)')
  447. interest_rate = fields.Float(string='Interest Rate (% in months)',
  448. group_operator="avg")
  449. duration = fields.Integer(string='Duration (in months)',
  450. group_operator="avg")
  451. loan_provider = fields.Selection([('bank', 'Bank'),
  452. ('cooperative', 'Cooperative'),
  453. ('sacco', 'Sacco'),
  454. ('other', 'Other')],
  455. string='Loan provider')
  456. # Loan Purpose
  457. loan_purpose_i = fields.Boolean(string='Input')
  458. loan_purpose_a = fields.Boolean(string='Aggregation')
  459. loan_purpose_o = fields.Boolean(string='Other')
  460. mobile_money_account = fields.Boolean(string='Mobile Money Acct')
  461. harvest_id = fields.Many2one('harvest.season', string='Harvest Season',
  462. required=True)
  463. vendor_id = fields.Many2one('vendor.farmer', string='Vendor',
  464. required=True)
Add Comment
Please, Sign In to add comment