summaryrefslogtreecommitdiff
path: root/fixco_custom
diff options
context:
space:
mode:
Diffstat (limited to 'fixco_custom')
-rwxr-xr-xfixco_custom/models/__init__.py3
-rwxr-xr-xfixco_custom/models/detail_order.py1
-rw-r--r--fixco_custom/models/purchase_order.py20
-rwxr-xr-xfixco_custom/models/sale.py1
-rw-r--r--fixco_custom/models/shipment_group.py7
-rwxr-xr-xfixco_custom/models/stock_picking.py344
-rw-r--r--fixco_custom/models/stock_picking_return.py27
-rwxr-xr-xfixco_custom/security/ir.model.access.csv4
-rw-r--r--fixco_custom/views/purchase_order.xml2
-rw-r--r--fixco_custom/views/report_picking_list.xml24
-rwxr-xr-xfixco_custom/views/sale_order.xml19
-rwxr-xr-xfixco_custom/views/stock_picking.xml51
-rwxr-xr-xfixco_custom/views/webhook_ginee.xml1
13 files changed, 469 insertions, 35 deletions
diff --git a/fixco_custom/models/__init__.py b/fixco_custom/models/__init__.py
index 8316e53..f20c116 100755
--- a/fixco_custom/models/__init__.py
+++ b/fixco_custom/models/__init__.py
@@ -32,4 +32,5 @@ from . import invoice_reklas
from . import uangmuka_pembelian
from . import coretax_faktur
from . import token_log
-from . import purchase_pricelist_wizard \ No newline at end of file
+from . import purchase_pricelist_wizard
+from . import stock_picking_return \ No newline at end of file
diff --git a/fixco_custom/models/detail_order.py b/fixco_custom/models/detail_order.py
index 1211aad..6bb5429 100755
--- a/fixco_custom/models/detail_order.py
+++ b/fixco_custom/models/detail_order.py
@@ -167,6 +167,7 @@ class DetailOrder(models.Model):
'picking_policy': 'direct',
'carrier': json_data.get('data', {})[0].get('logisticsInfos')[0].get('logisticsProviderName'),
'invoice_mp': json_data.get('data', {})[0].get('externalOrderId'),
+ 'channel': json_data.get('data', {})[0].get('channel'),
}
return data
diff --git a/fixco_custom/models/purchase_order.py b/fixco_custom/models/purchase_order.py
index 61c4ef8..7646656 100644
--- a/fixco_custom/models/purchase_order.py
+++ b/fixco_custom/models/purchase_order.py
@@ -222,11 +222,21 @@ class PurchaseOrder(models.Model):
# ============================
# Isi Data SOO Ke Order
# ============================
- for soo in list_soo:
- order.soo_number = soo.get("no_soo")
- order.soo_price = soo.get("totalprice")
- order.soo_discount = soo.get("diskon")
- order.soo_tax = soo.get("ppn")
+ soo_numbers = [s.get("no_soo") for s in list_soo if s.get("no_soo")]
+ unique_soo = list(set(soo_numbers))
+ if len(unique_soo) == 1:
+ order.soo_number = unique_soo[0]
+ elif len(unique_soo) > 1:
+ order.soo_number = ", ".join(unique_soo)
+
+ else:
+ order.soo_number = False
+
+ if list_soo:
+ first_soo = list_soo[0]
+ order.soo_price = first_soo.get("totalprice")
+ order.soo_discount = first_soo.get("diskon")
+ order.soo_tax = first_soo.get("ppn")
order.order_altama_id = req_id
diff --git a/fixco_custom/models/sale.py b/fixco_custom/models/sale.py
index 11340eb..4a1b79e 100755
--- a/fixco_custom/models/sale.py
+++ b/fixco_custom/models/sale.py
@@ -9,6 +9,7 @@ class SaleOrder(models.Model):
invoice_mp = fields.Char(string='Invoice Marketplace', required=True)
order_reference = fields.Char(string='Order Reference', required=True)
address = fields.Char('Address')
+ channel = fields.Char('Channel')
note_by_buyer = fields.Char('Note By Buyer')
count_payment = fields.Integer('Count Payment', compute='_compute_count_payment')
diff --git a/fixco_custom/models/shipment_group.py b/fixco_custom/models/shipment_group.py
index ca3ef76..546251a 100644
--- a/fixco_custom/models/shipment_group.py
+++ b/fixco_custom/models/shipment_group.py
@@ -38,6 +38,13 @@ class ShipmentGroup(models.Model):
def sync_product_to_picking_line(self):
for shipment in self:
+ cancelled_picking = shipment.picking_lines.filtered(
+ lambda picking: picking.status == 'CANCELLED'
+ )
+ if cancelled_picking:
+ cancelled_names = "\n - " + "\n - ".join(cancelled_picking.mapped("name"))
+ raise UserError(f"Pickings berikut telah dibatalkan:{cancelled_names}")
+
for picking_line in shipment.picking_lines:
shipment_lines = self.env['shipment.group.line'].search([
('shipment_id', '=', shipment.id),
diff --git a/fixco_custom/models/stock_picking.py b/fixco_custom/models/stock_picking.py
index 916ac9f..7c9f0d9 100755
--- a/fixco_custom/models/stock_picking.py
+++ b/fixco_custom/models/stock_picking.py
@@ -19,7 +19,7 @@ from hashlib import sha256
_logger = logging.getLogger(__name__)
-Request_URI = '/openapi/order/v1/print'
+Request_URI = ['/openapi/order/v1/print', '/openapi/logistics/v1/get-shipping-parameter', '/openapi/order/v3/batchShipping']
ACCESS_KEY = '24bb6a1ec618ec6a'
SECRET_KEY = '32e4a78ad05ee230'
@@ -29,32 +29,48 @@ class StockPicking(models.Model):
check_product_lines = fields.One2many('check.product', 'picking_id', string='Check Product', auto_join=True, copy=False)
order_reference = fields.Char('Order Reference')
- provider_name = fields.Char('Provider Name')
- tracking_number = fields.Char('Tracking Number')
- invoice_number = fields.Char('Invoice Number')
- pdf_label_url = fields.Char('PDF Label URL')
- invoice_mp = fields.Char(string='Invoice Marketplace')
- address = fields.Char('Address')
- note_by_buyer = fields.Char('Note By Buyer')
- carrier = fields.Char(string='Shipping Method')
+ provider_name = fields.Char('Provider Name', tracking=True)
+ tracking_number = fields.Char('Tracking Number', tracking=True)
+ invoice_number = fields.Char('Invoice Number', tracking=True)
+ pdf_label_url = fields.Char('PDF Label URL', tracking=True)
+ invoice_mp = fields.Char(string='Invoice Marketplace', tracking=True)
+ address = fields.Char('Address', tracking=True)
+ note_by_buyer = fields.Char('Note By Buyer', tracking=True)
+ carrier = fields.Char(string='Shipping Method', tracking=True)
shipment_group_id = fields.Many2one('shipment.group', string='Shipment Group', copy=False)
pdf_label_preview = fields.Binary(
string="PDF Preview",
compute="_compute_pdf_binary",
- store=False
+ store=False, tracking=True
)
- is_printed = fields.Boolean(string="Sudah Dicetak", default=False)
+ is_printed = fields.Boolean(string="Sudah Dicetak", default=False, tracking=True)
is_return = fields.Boolean(
string="Is Return",
compute="_compute_is_return",
- store=True
+ store=True, tracking=True
)
+ channel = fields.Char('Channel')
+ ginee_delivery_type = fields.Char("Delivery Type", tracking=True)
+ ginee_tracking_no = fields.Char("Tracking Number", tracking=True)
+ ginee_invoice_no = fields.Char("Invoice Number", tracking=True)
+ ginee_shipping_task_id = fields.Char("Shipping Task ID", tracking=True)
+
+ ginee_provider_id = fields.Char("Provider ID", tracking=True)
+ ginee_provider_name = fields.Char("Provider Name", tracking=True)
+ ginee_address_id = fields.Char("Pickup Address ID", tracking=True)
+ ginee_address = fields.Char("Pickup Address", tracking=True)
+ ginee_pickup_time_id = fields.Char("Pickup Time ID", tracking=True)
+ ginee_task_id = fields.Char("Ginee Task ID", tracking=True)
+
+ soo_number = fields.Char(string='SOO Altama Number', related='purchase_id.soo_number')
+ type_sku = fields.Selection([('single', 'Single SKU'), ('multi', 'Multi SKU')], string='Type SKU')
+ list_product = fields.Char(string='List Product')
def button_validate(self):
- if len(self.check_product_lines) == 0:
- raise UserError(_(
- "Belum ada check product, gabisa validate"
- ))
+ origin = self.origin or ''
+ if any(prefix in origin for prefix in ['PO/', 'SO/']) and not self.check_product_lines:
+ raise UserError(_("Belum ada check product, gabisa validate"))
+
return super(StockPicking, self).button_validate()
@@ -203,9 +219,23 @@ class StockPicking(models.Model):
picking.order_reference = picking.sale_id.name
self.order_reference = picking.sale_id.order_reference
self.invoice_mp = picking.sale_id.invoice_mp
+ self.channel = picking.sale_id.channel
self.carrier = picking.sale_id.carrier
self.address = picking.sale_id.address
self.note_by_buyer = picking.sale_id.note_by_buyer
+ self.schema_multi_single_sku()
+
+ def schema_multi_single_sku(self):
+ for picking in self:
+ if len(picking.move_ids_without_package) > 1:
+ picking.type_sku = 'multi'
+ else:
+ picking.type_sku = 'single'
+
+ names = picking.move_ids_without_package.mapped('product_id.display_name')
+ picking.list_product = ", ".join(names)
+
+
def open_form_shipment_group(self):
return {
@@ -235,7 +265,7 @@ class StockPicking(models.Model):
try:
order_id = self.order_reference
- authorization = self.sign_request()
+ authorization = self.sign_request(0)
headers = {
'Content-Type': 'application/json',
'X-Advai-Country': 'ID',
@@ -275,14 +305,281 @@ class StockPicking(models.Model):
except Exception as e:
raise UserError(_("Error: %s") % str(e))
+
+ def get_shipping_parameter(self):
+ try:
+ order_id = self.order_reference
+
+ authorization = self.sign_request(1)
+ headers = {
+ 'Content-Type': 'application/json',
+ 'X-Advai-Country': 'ID',
+ 'Authorization': authorization
+ }
+
+ payload = {"orderId": order_id}
+ url = "https://api.ginee.com/openapi/logistics/v1/get-shipping-parameter"
+
+ response = requests.post(url, headers=headers, data=json.dumps(payload))
+ res = response.json()
+
+ if res.get("code") != "SUCCESS":
+ raise UserError("Ginee Error: %s" % res.get("message"))
+
+ data = res.get("data", {})
+
+ # ==============================
+ # Basic fields
+ # ==============================
+ self.ginee_delivery_type = data.get("deliveryType")
+ self.ginee_tracking_no = data.get("logisticsTrackingNumber")
+ self.ginee_invoice_no = data.get("invoiceNumber")
+
+ # ==============================
+ # FIND CORRECT PROVIDER
+ # ==============================
+ provider_id = None
+ provider_name = None
+ logistics_type = None
+
+ for lg in data.get("logistics", []):
+ details = lg.get("logisticDetailList") or []
+ if details:
+ # ambil pertama yang terisi
+ d = details[0]
+ provider_id = d.get("logisticsProviderId")
+ provider_name = d.get("logisticsProviderName")
+ logistics_type = lg.get("logisticsDeliveryType")
+ break # STOP di yang pertama terisi
+
+ # Simpan hasil ke field Odoo
+ self.ginee_provider_id = provider_id
+ self.ginee_provider_name = provider_name
+ self.ginee_delivery_type = logistics_type or self.ginee_delivery_type
+
+ # ==============================
+ # PICKUP ADDRESS (kalau ada)
+ # ==============================
+ addr = None
+ pickup_time = None
+
+ addresses = data.get("addresses") or []
+ if addresses:
+ # ambil address pertama paling relevan
+ first = addresses[0]
+ addr = first.get("address")
+ self.ginee_address = addr
+ self.ginee_address_id = first.get("addressId")
+
+ times = first.get("pickupTimeList") or []
+ if times:
+ pt = times[0]
+ self.ginee_pickup_time_id = pt.get("pickupTimeId")
+
+ except Exception as e:
+ raise UserError(_("Error: %s") % str(e))
+
- def sign_request(self):
- signData = '$'.join(['POST', Request_URI]) + '$'
+ def ship_order(self):
+ try:
+ order_id = self.order_reference
+
+ authorization = self.sign_request(2) # index 2 -> ship-order
+ headers = {
+ 'Content-Type': 'application/json',
+ 'X-Advai-Country': 'ID',
+ 'Authorization': authorization
+ }
+
+ # ==========================================================
+ # Ambil field dari GET SHIPPING PARAMETER
+ # ==========================================================
+ delivery_type = self.ginee_delivery_type
+ provider_name = self.ginee_provider_name
+ provider_id = self.ginee_provider_id
+ tracking_no = self.ginee_tracking_no
+ invoice_no = self.ginee_invoice_no
+ address_id = self.ginee_address_id
+ address = self.ginee_address
+ pickup_time_id = self.ginee_pickup_time_id
+
+ # ==========================================================
+ # Ambil platform dari channel (SHOPEE, LAZADA, dll)
+ # ==========================================================
+ platform = self._get_platform_from_channel() or ""
+
+ # ==========================================================
+ # Build order-level payload
+ # ==========================================================
+ order_data = {
+ "orderId": order_id,
+ "deliveryType": delivery_type
+ }
+
+ # ==========================================================
+ # PLATFORM RULES
+ # ==========================================================
+
+ # ----------------------------- SHOPEE -----------------------------
+ if platform == "SHOPEE":
+ if delivery_type == "PICK_UP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "pickupTimeId": pickup_time_id,
+ "addressId": address_id,
+ "address": address,
+ })
+ elif delivery_type == "DROP_OFF":
+ order_data.update({"shippingProvider": provider_name})
+ elif delivery_type == "MANUAL_SHIP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no,
+ })
+
+ # ----------------------------- TOKOPEDIA -----------------------------
+ elif platform == "TOKOPEDIA":
+ if delivery_type == "PICK_UP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no,
+ })
+ elif delivery_type == "DROP_OFF":
+ order_data.update({"shippingProvider": provider_name})
+ elif delivery_type == "MANUAL_SHIP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no
+ })
+
+ # ----------------------------- LAZADA -----------------------------
+ elif platform == "LAZADA":
+ if delivery_type == "PICK_UP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "address": address,
+ "addressId": address_id,
+ "pickupTimeId": pickup_time_id
+ })
+ elif delivery_type == "DROP_OFF":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "invoiceNumber": invoice_no
+ })
+
+ # ----------------------------- TIKTOK -----------------------------
+ elif platform == "TIKTOK":
+ if delivery_type == "PICK_UP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "pickupStartTime": pickup_time_id,
+ "pickupEndTime": pickup_time_id
+ })
+ elif delivery_type == "DROP_OFF":
+ order_data.update({"shippingProvider": provider_name})
+
+ # ----------------------------- ZALORA -----------------------------
+ elif platform == "ZALORA":
+ if delivery_type == "DROP_OFF":
+ order_data.update({
+ "trackingNo": tracking_no,
+ "invoiceNumber": invoice_no
+ })
+
+ # ----------------------------- AKULAKU -----------------------------
+ elif platform == "AKULAKU":
+ if delivery_type in ["PICK_UP", "DROP_OFF"]:
+ order_data.update({
+ "shippingProvider": provider_name,
+ "shippingProviderId": provider_id,
+ "addressId": address_id,
+ "address": address
+ })
+ elif delivery_type == "MANUAL_SHIP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "shippingProviderId": provider_id,
+ "trackingNo": tracking_no
+ })
+
+ # ----------------------------- BUKALAPAK -----------------------------
+ elif platform == "BUKALAPAK":
+ if delivery_type in ["PICK_UP", "DROP_OFF"]:
+ order_data.update({"shippingProvider": provider_name})
+ elif delivery_type == "MANUAL_SHIP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no
+ })
+
+ # ----------------------------- BLIBLI -----------------------------
+ elif platform == "BLIBLI":
+ if delivery_type == "PICK_UP":
+ order_data.update({"shippingProvider": provider_name})
+ elif delivery_type == "DROP_OFF":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no
+ })
+
+ # ----------------------------- DEFAULT FALLBACK -----------------------------
+ else:
+ if delivery_type == "PICK_UP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "pickupTimeId": pickup_time_id,
+ "addressId": address_id,
+ "address": address,
+ })
+ elif delivery_type == "DROP_OFF":
+ order_data.update({"shippingProvider": provider_name})
+ elif delivery_type == "MANUAL_SHIP":
+ order_data.update({
+ "shippingProvider": provider_name,
+ "trackingNo": tracking_no,
+ })
+
+ # ==========================================================
+ # FINAL PAYLOAD (dibungkus orderShips)
+ # ==========================================================
+ payload = {
+ "orderShips": [order_data]
+ }
+
+ # ==========================================================
+ # CALL API
+ # ==========================================================
+ url = "https://api.ginee.com/openapi/order/v3/batchShipping"
+
+ response = requests.post(url, headers=headers, data=json.dumps(payload))
+ res = response.json()
+
+ if res.get("code") != "SUCCESS":
+ raise UserError("Ship Order Error: %s" % res.get("message"))
+
+ self.ginee_task_id = res.get("data") or False
+
+ return True
+
+ except Exception as e:
+ raise UserError(_("Error: %s") % str(e))
+
+ def sign_request(self, array_num):
+ signData = '$'.join(['POST', Request_URI[array_num]]) + '$'
authorization = ACCESS_KEY + ':' + base64.b64encode(
hmac.new(SECRET_KEY.encode('utf-8'), signData.encode('utf-8'), digestmod=sha256).digest()
).decode('ascii')
return authorization
+ def _get_platform_from_channel(self):
+ if not self.channel:
+ return None
+ ch = (self.channel or "").upper().strip()
+ # remove suffix _ID / _CHOICE / etc
+ ch = ch.replace("_ID", "").replace("_CHOICE", "")
+ return ch
+
+
# def sync_qty_reserved_qty_done(self):
@@ -502,13 +799,8 @@ class PickingReportCustom(models.AbstractModel):
def _get_report_values(self, docids, data=None):
pickings = self.env['stock.picking'].browse(docids)
- already_printed = pickings.filtered(lambda p: p.is_printed)
- if already_printed:
- names = "\n- ".join(already_printed.mapped("name"))
- raise UserError(
- "Dokumen berikut sudah pernah di-print sebelumnya:\n\n- %s" % names
- )
+ was_printed_map = {p.id: p.is_printed for p in pickings}
pickings.write({'is_printed': True})
@@ -516,4 +808,6 @@ class PickingReportCustom(models.AbstractModel):
'doc_ids': docids,
'doc_model': 'stock.picking',
'docs': pickings,
+ 'was_printed_map': was_printed_map,
}
+
diff --git a/fixco_custom/models/stock_picking_return.py b/fixco_custom/models/stock_picking_return.py
new file mode 100644
index 0000000..69cc6ab
--- /dev/null
+++ b/fixco_custom/models/stock_picking_return.py
@@ -0,0 +1,27 @@
+from odoo.exceptions import UserError
+from odoo.tools.float_utils import float_round
+from odoo import models, fields, api, _
+import logging
+_logger = logging.getLogger(__name__)
+
+
+class ReturnPicking(models.TransientModel):
+ _inherit = 'stock.return.picking'
+
+class ReturnPickingLine(models.TransientModel):
+ _inherit = 'stock.return.picking.line'
+
+ @api.onchange('quantity')
+ def _onchange_quantity(self):
+ for rec in self:
+ if rec.move_id and rec.quantity > 0:
+ qty_done = rec.move_id.quantity_done
+
+ if qty_done == 0:
+ qty_done = rec.move_id.product_uom_qty
+
+ if rec.quantity > qty_done:
+ raise UserError(
+ _("Quantity yang Anda masukkan (%.2f) tidak boleh melebihi quantity done yaitu: %.2f untuk produk %s")
+ % (rec.quantity, qty_done, rec.product_id.name)
+ )
diff --git a/fixco_custom/security/ir.model.access.csv b/fixco_custom/security/ir.model.access.csv
index 4ed6857..f51c8ad 100755
--- a/fixco_custom/security/ir.model.access.csv
+++ b/fixco_custom/security/ir.model.access.csv
@@ -39,4 +39,6 @@ access_uangmuka_pembelian,access.uangmuka.pembelian,model_uangmuka_pembelian,,1,
access_coretax_faktur,access.coretax.faktur,model_coretax_faktur,,1,1,1,1
access_report.fixco_custom.report_picking_list_custom,access.report.fixco_custom.report_picking_list_custom,model_report_fixco_custom_report_picking_list_custom,,1,1,1,1
access_token_log,access.token.log,model_token_log,,1,1,1,1
-access_purchase_pricelist_wizard,access.token.log,model_purchase_pricelist_wizard,,1,1,1,1
+access_purchase_pricelist_wizard,purchase.pricelist.wizard,model_purchase_pricelist_wizard,,1,1,1,1
+access_stock_return_picking,stock.return.picking,model_stock_return_picking,,1,1,1,1
+access_stock_return_picking_line,stock.return.picking.line,model_stock_return_picking_line,,1,1,1,1
diff --git a/fixco_custom/views/purchase_order.xml b/fixco_custom/views/purchase_order.xml
index dc863bc..54b28f9 100644
--- a/fixco_custom/views/purchase_order.xml
+++ b/fixco_custom/views/purchase_order.xml
@@ -31,7 +31,7 @@
icon="fa-cloud-download"/>
</button>
<field name="fiscal_position_id" position="after">
- <field name="soo_number" invisible="1"/>
+ <field name="soo_number" readonly="1"/>
<field name="soo_price" readonly="1"/>
<field name="soo_discount" readonly="1"/>
<field name="soo_tax" readonly="1"/>
diff --git a/fixco_custom/views/report_picking_list.xml b/fixco_custom/views/report_picking_list.xml
index 109a780..bff1fc6 100644
--- a/fixco_custom/views/report_picking_list.xml
+++ b/fixco_custom/views/report_picking_list.xml
@@ -17,14 +17,36 @@
<t t-foreach="docs" t-as="o">
<t t-call="web.external_layout">
<div class="page" style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto;">
+ <t t-set="duplicate_stamp">
+ data:image/jpeg;base64,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
+ </t>
+ <!-- DUPLICATE WATERMARK IMG -->
+
<!-- Barcode Header -->
<div style="text-align: right; margin-bottom: -90px;">
- <img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('QR', o.invoice_mp, 100, 100)"
+ <img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('QR', o.name, 100, 100)"
style="width:100px;height:100px;" alt="QR Code"/>
</div>
<!-- Main Header -->
<div style="text-align: center; margin-bottom: 15px;">
+ <t t-if="was_printed_map.get(o.id)">
+ <div style="
+ position: absolute;
+ left: 25%;
+ right: 150%;
+ bottom: 500%;
+ top: 1%;
+ width: 500px;
+ height: 500px;
+ transform: translate(-50%, -50%) rotate(-20deg);
+ opacity: 0.50;
+ z-index: 9999;
+ pointer-events: none;
+ ">
+ <img t-att-src="duplicate_stamp" style="width:50%; height:50%;" />
+ </div>
+ </t>
<h1 style="margin: 0; font-size: 24px; font-weight: bold;" t-field="o.name"/>
<div style="font-size: 18px; font-weight: bold; margin-top: 5px;">
Web Service
diff --git a/fixco_custom/views/sale_order.xml b/fixco_custom/views/sale_order.xml
index 00234d9..5d702e5 100755
--- a/fixco_custom/views/sale_order.xml
+++ b/fixco_custom/views/sale_order.xml
@@ -36,6 +36,7 @@
<field name="client_order_ref" position="after">
<field name="order_reference" required="1"/>
<field name="invoice_mp" required="1"/>
+ <field name="channel" required="1"/>
<field name="note_by_buyer" readonly="1"/>
</field>
<field name="amount_total" position="after">
@@ -53,6 +54,24 @@
<field name="arch" type="xml">
<field name="amount_total" position="after">
<field name="remaining_down_payment" optional="hide"/>
+ <field name="order_reference" optional="hide"/>
+ <field name="invoice_mp" optional="hide"/>
+ </field>
+ </field>
+ </record>
+ </data>
+
+ <data>
+ <record id="sale_order_quotation_tree_inherit" model="ir.ui.view">
+ <field name="name">Quotations</field>
+ <field name="model">sale.order</field>
+ <field name="inherit_id" ref="sale.view_quotation_tree_with_onboarding"/>
+ <field name="arch" type="xml">
+ <field name="amount_total" position="after">
+ <field name="remaining_down_payment" optional="hide"/>
+ <field name="order_reference" optional="hide"/>
+ <field name="invoice_mp" optional="hide"/>
+ <field name="channel" optional="hide"/>
</field>
</field>
</record>
diff --git a/fixco_custom/views/stock_picking.xml b/fixco_custom/views/stock_picking.xml
index f8d0934..21ced7c 100755
--- a/fixco_custom/views/stock_picking.xml
+++ b/fixco_custom/views/stock_picking.xml
@@ -9,6 +9,8 @@
<field name="partner_id" position="after">
<field name="provider_name" optional="hide"/>
<field name="is_printed" optional="hide"/>
+ <field name="list_product" optional="hide"/>
+ <field name="type_sku" optional="hide"/>
</field>
</field>
</record>
@@ -24,6 +26,16 @@
type="object"
attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"
/>
+ <button name="get_shipping_parameter"
+ string="Get Shipping"
+ type="object"
+ attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"
+ />
+ <button name="ship_order"
+ string="Ship Order"
+ type="object"
+ attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}"
+ />
<button name="action_create_invoice_from_mr"
string="Create Bill"
type="object"
@@ -32,20 +44,35 @@
</button>
<group name="other_infos" position="after">
- <group string="Shipping Information" name="shipping_infos">
+ <group string="Receipt Information" name="shipping_infos">
<field name="order_reference" readonly="1"/>
<field name="provider_name" readonly="1"/>
<field name="tracking_number" readonly="1"/>
<field name="invoice_number" readonly="1"/>
<field name="invoice_mp" readonly="1"/>
+ <field name="channel" readonly="1"/>
+ <field name="ginee_task_id" readonly="1"/>
<field name="pdf_label_url" readonly="1" widget="url"/>
<field name="pdf_label_preview" widget="pdf_viewer"/>
</group>
+ <group string="Shipping" name="shipping_infos">
+ <field name="ginee_delivery_type" readonly="1"/>
+ <field name="ginee_tracking_no" readonly="1"/>
+ <field name="ginee_invoice_no" readonly="1"/>
+ <field name="ginee_shipping_task_id" readonly="1"/>
+ <field name="ginee_provider_id" readonly="1"/>
+ <field name="ginee_provider_name" readonly="1"/>
+ <field name="ginee_address_id" readonly="1"/>
+ <field name="ginee_address" readonly="1"/>
+ <field name="ginee_pickup_time_id" readonly="1"/>
+ </group>
</group>
<field name="location_id" position="after">
<field name="carrier"/>
<field name="shipment_group_id"/>
+ <field name="soo_number"/>
+ <field name="type_sku"/>
</field>
<page name="note" position="after">
@@ -96,5 +123,27 @@
</tree>
</field>
</record>
+
+ <record id="view_stock_picking_filter_inherit_name" model="ir.ui.view">
+ <field name="name">stock.picking.filter.name.extend</field>
+ <field name="model">stock.picking</field>
+ <field name="inherit_id" ref="stock.view_picking_internal_search"/>
+ <field name="arch" type="xml">
+
+ <xpath expr="(//search/field[@name='name'])[1]" position="attributes">
+ <attribute name="filter_domain">
+ ['|','|','|',
+ ('name', 'ilike', self),
+ ('origin', 'ilike', self),
+ ('invoice_mp', 'ilike', self),
+ ('order_reference', 'ilike', self)
+ ]
+ </attribute>
+ </xpath>
+
+ </field>
+ </record>
+
+
</data>
</odoo> \ No newline at end of file
diff --git a/fixco_custom/views/webhook_ginee.xml b/fixco_custom/views/webhook_ginee.xml
index acec9b7..3dda237 100755
--- a/fixco_custom/views/webhook_ginee.xml
+++ b/fixco_custom/views/webhook_ginee.xml
@@ -7,6 +7,7 @@
<tree default_order="create_date desc">
<field name="json_ginee"/>
<field name="execute_status"/>
+ <field name="create_date" optional="hide"/>
</tree>
</field>
</record>