You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

304 lines
9.6 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. import uuid
  2. from odoo import api, fields, models
  3. from odoo.exceptions import UserError, ValidationError
  4. from odoo.tools.translate import _
  5. class BeesdooProduct(models.Model):
  6. _inherit = "product.template"
  7. eco_label = fields.Many2one(
  8. "beesdoo.product.label", domain=[("type", "=", "eco")]
  9. )
  10. local_label = fields.Many2one(
  11. "beesdoo.product.label", domain=[("type", "=", "local")]
  12. )
  13. fair_label = fields.Many2one(
  14. "beesdoo.product.label", domain=[("type", "=", "fair")]
  15. )
  16. origin_label = fields.Many2one(
  17. "beesdoo.product.label", domain=[("type", "=", "delivery")]
  18. )
  19. main_seller_id = fields.Many2one(
  20. "res.partner",
  21. string="Main Seller",
  22. compute="_compute_main_seller_id",
  23. store=True,
  24. )
  25. display_unit = fields.Many2one("uom.uom")
  26. default_reference_unit = fields.Many2one("uom.uom")
  27. display_weight = fields.Float(
  28. compute="_compute_display_weight", store=True
  29. )
  30. total_with_vat = fields.Float(
  31. compute="_compute_total",
  32. store=True,
  33. string="Total Sales Price with VAT",
  34. )
  35. total_with_vat_by_unit = fields.Float(
  36. compute="_compute_total",
  37. store=True,
  38. string="Total Sales Price with VAT by Reference Unit",
  39. )
  40. total_deposit = fields.Float(
  41. compute="_compute_total", store=True, string="Deposit Price"
  42. )
  43. label_to_be_printed = fields.Boolean("Print label?")
  44. label_last_printed = fields.Datetime("Label last printed on")
  45. note = fields.Text("Comments")
  46. # S0023 : List_price = Price HTVA, so add a suggested price
  47. list_price = fields.Float(string="exVAT Price")
  48. suggested_price = fields.Float(
  49. string="Suggested exVAT Price", compute="_compute_cost", readOnly=True
  50. )
  51. deadline_for_sale = fields.Integer(string="Deadline for sale(days)")
  52. deadline_for_consumption = fields.Integer(
  53. string="Deadline for consumption(days)"
  54. )
  55. ingredients = fields.Char(string="Ingredient")
  56. scale_label_info_1 = fields.Char(string="Scale lable info 1")
  57. scale_label_info_2 = fields.Char(string="Scale lable info 2")
  58. scale_sale_unit = fields.Char(
  59. compute="_compute_scale_sale_uom", string="Scale sale unit", store=True
  60. )
  61. scale_category = fields.Many2one(
  62. "beesdoo.scale.category", string="Scale Category"
  63. )
  64. scale_category_code = fields.Integer(
  65. related="scale_category.code",
  66. string="Scale category code",
  67. readonly=True,
  68. store=True,
  69. )
  70. @api.depends("uom_id", "uom_id.category_id", "uom_id.category_id.type")
  71. @api.multi
  72. def _compute_scale_sale_uom(self):
  73. for product in self:
  74. if product.uom_id.category_id.type == "unit":
  75. product.scale_sale_unit = "F"
  76. elif product.uom_id.category_id.type == "weight":
  77. product.scale_sale_unit = "P"
  78. def _get_main_supplier_info(self):
  79. suppliers = self.seller_ids.sorted(
  80. key=lambda seller: seller.date_start, reverse=True
  81. )
  82. if suppliers:
  83. return suppliers[0]
  84. else:
  85. return suppliers
  86. @api.one
  87. def generate_barcode(self):
  88. if self.to_weight:
  89. seq_internal_code = self.env.ref(
  90. "beesdoo_product.seq_ean_product_internal_ref"
  91. )
  92. bc = ""
  93. if not self.default_code:
  94. rule = self.env["barcode.rule"].search(
  95. [
  96. (
  97. "name",
  98. "=",
  99. "Price Barcodes (Computed Weight) 2 Decimals",
  100. )
  101. ]
  102. )[0]
  103. default_code = seq_internal_code.next_by_id()
  104. while (
  105. self.search_count([("default_code", "=", default_code)])
  106. > 1
  107. ):
  108. default_code = seq_internal_code.next_by_id()
  109. self.default_code = default_code
  110. ean = "02" + self.default_code[0:5] + "000000"
  111. bc = ean[0:12] + str(
  112. self.env["barcode.nomenclature"].ean_checksum(ean)
  113. )
  114. else:
  115. rule = self.env["barcode.rule"].search(
  116. [("name", "=", "Beescoop Product Barcodes")]
  117. )[0]
  118. size = 13 - len(rule.pattern)
  119. ean = rule.pattern + str(uuid.uuid4().fields[-1])[:size]
  120. bc = ean[0:12] + str(
  121. self.env["barcode.nomenclature"].ean_checksum(ean)
  122. )
  123. # Make sure there is no other active member with the same barcode
  124. while self.search_count([("barcode", "=", bc)]) > 1:
  125. ean = rule.pattern + str(uuid.uuid4().fields[-1])[:size]
  126. bc = ean[0:12] + str(
  127. self.env["barcode.nomenclature"].ean_checksum(ean)
  128. )
  129. print("barcode :", bc)
  130. self.barcode = bc
  131. @api.one
  132. @api.depends("seller_ids", "seller_ids.date_start")
  133. def _compute_main_seller_id(self):
  134. # Calcule le vendeur associé qui a la date de début la plus récente et plus petite qu’aujourd’hui
  135. sellers_ids = (
  136. self._get_main_supplier_info()
  137. ) # self.seller_ids.sorted(key=lambda seller: seller.date_start, reverse=True)
  138. self.main_seller_id = sellers_ids and sellers_ids[0].name or False
  139. @api.one
  140. @api.depends(
  141. "taxes_id",
  142. "list_price",
  143. "taxes_id.amount",
  144. "taxes_id.tax_group_id",
  145. "display_weight",
  146. "weight",
  147. )
  148. def _compute_total(self):
  149. consignes_group = self.env.ref(
  150. "beesdoo_product.consignes_group_tax", raise_if_not_found=False
  151. )
  152. taxes_included = set(self.taxes_id.mapped("price_include"))
  153. if len(taxes_included) == 0:
  154. self.total_with_vat = self.list_price
  155. return True
  156. elif len(taxes_included) > 1:
  157. raise ValidationError(
  158. _("Several tax strategies (price_include) defined for %s")
  159. % self.name
  160. )
  161. elif taxes_included.pop():
  162. self.total_with_vat = self.list_price
  163. self.total_deposit = sum(
  164. [
  165. tax._compute_amount(self.list_price, self.list_price)
  166. for tax in self.taxes_id
  167. if tax.tax_group_id == consignes_group
  168. ]
  169. )
  170. else:
  171. tax_amount_sum = sum(
  172. [
  173. tax._compute_amount(self.list_price, self.list_price)
  174. for tax in self.taxes_id
  175. if tax.tax_group_id != consignes_group
  176. ]
  177. )
  178. self.total_with_vat = self.list_price + tax_amount_sum
  179. self.total_deposit = sum(
  180. [
  181. tax._compute_amount(self.list_price, self.list_price)
  182. for tax in self.taxes_id
  183. if tax.tax_group_id == consignes_group
  184. ]
  185. )
  186. if self.display_weight > 0:
  187. self.total_with_vat_by_unit = self.total_with_vat / self.weight
  188. @api.one
  189. @api.depends("weight", "display_unit")
  190. def _compute_display_weight(self):
  191. self.display_weight = self.weight * self.display_unit.factor
  192. @api.one
  193. @api.constrains("display_unit", "default_reference_unit")
  194. def _unit_same_category(self):
  195. if (
  196. self.display_unit.category_id
  197. != self.default_reference_unit.category_id
  198. ):
  199. raise UserError(
  200. _(
  201. "Reference Unit and Display Unit should belong to the same category"
  202. )
  203. )
  204. @api.one
  205. @api.depends("seller_ids")
  206. def _compute_cost(self):
  207. suppliers = self._get_main_supplier_info()
  208. if len(suppliers) > 0:
  209. self.suggested_price = (
  210. suppliers[0].price * self.uom_po_id.factor
  211. ) * (1 + suppliers[0].product_tmpl_id.categ_id.profit_margin / 100)
  212. class BeesdooScaleCategory(models.Model):
  213. _name = "beesdoo.scale.category"
  214. _description = "beesdoo.scale.category"
  215. name = fields.Char(string="Scale name category")
  216. code = fields.Integer(string="Category code")
  217. _sql_constraints = [
  218. (
  219. "code_scale_categ_uniq",
  220. "unique (code)",
  221. "The code of the scale category must be unique !",
  222. )
  223. ]
  224. class BeesdooProductLabel(models.Model):
  225. _name = "beesdoo.product.label"
  226. _description = "beesdoo.product.label"
  227. name = fields.Char()
  228. type = fields.Selection(
  229. [
  230. ("eco", "Écologique"),
  231. ("local", "Local"),
  232. ("fair", "Équitable"),
  233. ("delivery", "Distribution"),
  234. ]
  235. )
  236. color_code = fields.Char()
  237. active = fields.Boolean(default=True)
  238. class BeesdooProductCategory(models.Model):
  239. _inherit = "product.category"
  240. profit_margin = fields.Float(default="10.0", string="Product Margin [%]")
  241. @api.one
  242. @api.constrains("profit_margin")
  243. def _check_margin(self):
  244. if self.profit_margin < 0.0:
  245. raise UserError(_("Percentages for Profit Margin must > 0."))
  246. class BeesdooProductSupplierInfo(models.Model):
  247. _inherit = "product.supplierinfo"
  248. price = fields.Float("exVAT Price")
  249. class BeesdooUOMCateg(models.Model):
  250. _inherit = "uom.category"
  251. type = fields.Selection(
  252. [
  253. ("unit", "Unit"),
  254. ("weight", "Weight"),
  255. ("time", "Time"),
  256. ("distance", "Distance"),
  257. ("surface", "Surface"),
  258. ("volume", "Volume"),
  259. ("other", "Other"),
  260. ],
  261. string="Category type",
  262. default="unit",
  263. )